Browse Source

IBIS: Constness and skipping copies

Lot of things can be const which makes the interface
a bit more legible and safe to use - lots of things are
accessing pointers that if they changed, would have wierd
and unpredicatable effects.

Probably of minor concern in practice, but a lot of strings
and vectors are being copied when they don't have to be.
Very crude profiling indicates this could save 30-50% of the time in
KIBIS::KIBIS after ParseFile, but this is incidental to
clarifying the API of the classes.

Report is const as it doesn't change the logical state of the
IBIS_ANY object (if m_reporter were a ref, it'd be mutable).

If a T* isn't null-checked inside a function, pass as ref
to show that the function expects and requires non-nullity.
jobs
John Beard 1 year ago
parent
commit
0d2371c9c3
  1. 16
      eeschema/sim/kibis/ibis_parser.cpp
  2. 16
      eeschema/sim/kibis/ibis_parser.h
  3. 269
      eeschema/sim/kibis/kibis.cpp
  4. 141
      eeschema/sim/kibis/kibis.h
  5. 36
      eeschema/sim/sim_model_ibis.cpp
  6. 4
      eeschema/sim/sim_model_ibis.h
  7. 4
      qa/tools/ibis/qaIbisParser.cpp

16
eeschema/sim/kibis/ibis_parser.cpp

@ -306,8 +306,8 @@ std::string IBIS_ANY::doubleToString( double aNumber )
}
std::string IVtable::Spice( int aN, std::string aPort1, std::string aPort2, std::string aModelName,
IBIS_CORNER aCorner )
std::string IVtable::Spice( int aN, const std::string& aPort1, const std::string& aPort2,
const std::string& aModelName, IBIS_CORNER aCorner ) const
{
std::string result = "";
@ -331,14 +331,14 @@ std::string IVtable::Spice( int aN, std::string aPort1, std::string aPort2, std:
result += aModelName;
result += " pwl(\n+ x_array=[";
for( IVtableEntry& entry : m_entries )
for( const IVtableEntry& entry : m_entries )
{
result += doubleToString( entry.V );
result += "\n+";
}
result += "]\n+ y_array=[";
for( IVtableEntry& entry : m_entries )
for( const IVtableEntry& entry : m_entries )
{
result += doubleToString( entry.I.value[aCorner] );
result += "\n+";
@ -348,7 +348,7 @@ std::string IVtable::Spice( int aN, std::string aPort1, std::string aPort2, std:
return result;
}
double IVtable::InterpolatedI( double aV, IBIS_CORNER aCorner )
double IVtable::InterpolatedI( double aV, IBIS_CORNER aCorner ) const
{
// @TODO change this algorithm
@ -796,7 +796,7 @@ bool IbisPackageModel::Check()
}
bool IbisParser::ParseFile( std::string& aFileName )
bool IbisParser::ParseFile( const std::string& aFileName )
{
std::stringstream err_msg;
@ -1835,7 +1835,7 @@ bool IbisParser::readModelSelector()
return status;
}
bool IbisParser::readNumericSubparam( std::string aSubparam, double& aDest )
bool IbisParser::readNumericSubparam( const std::string& aSubparam, double& aDest )
{
std::string paramName;
bool status = true;
@ -1900,7 +1900,7 @@ bool IbisParser::readTypMinMaxValue( TypMinMaxValue& aDest )
return status;
}
bool IbisParser::readTypMinMaxValueSubparam( std::string aSubparam, TypMinMaxValue& aDest )
bool IbisParser::readTypMinMaxValueSubparam( const std::string& aSubparam, TypMinMaxValue& aDest )
{
std::string paramName;
bool status = true;

16
eeschema/sim/kibis/ibis_parser.h

@ -62,7 +62,7 @@ public:
* @param aMsg Message
* @param aSeverity Message sevirity
*/
void Report( std::string aMsg, SEVERITY aSeverity = RPT_SEVERITY_INFO )
void Report( std::string aMsg, SEVERITY aSeverity = RPT_SEVERITY_INFO ) const
{
if( m_reporter )
m_reporter->Report( aMsg, aSeverity );
@ -74,7 +74,7 @@ protected:
* @param aNumber Number
* @return Output string
*/
std::string doubleToString( double aNumber );
static std::string doubleToString( double aNumber );
};
@ -368,7 +368,7 @@ public:
* @param aCorner Power supply corner
* @return current
*/
double InterpolatedI( double aV, IBIS_CORNER aCorner );
double InterpolatedI( double aV, IBIS_CORNER aCorner ) const;
/** @brief Interpolate the IV table
*
@ -382,8 +382,8 @@ public:
* @param aCorner Power supply corner
* @return Multline spice directives
*/
std::string Spice( int aN, std::string aPort1, std::string aPort2, std::string aModelName,
IBIS_CORNER aCorner );
std::string Spice( int aN, const std::string& aPort1, const std::string& aPort2,
const std::string& aModelName, IBIS_CORNER aCorner ) const;
private:
};
@ -684,7 +684,7 @@ public:
* @param aFileName input file name
* @return True in case of success
*/
bool ParseFile( std::string& aFileName );
bool ParseFile( const std::string& aFileName );
private:
std::string* m_continuingString = nullptr;
@ -778,11 +778,11 @@ private:
bool storeString( std::string& aDest, bool aMultiline );
bool readTableLine( std::vector<std::string>& aDest );
bool readNumericSubparam( std::string aSubparam, double& aDest );
bool readNumericSubparam( const std::string& aSubparam, double& aDest );
bool readIVtableEntry( IVtable& aTable );
bool readVTtableEntry( VTtable& aTable );
bool readTypMinMaxValue( TypMinMaxValue& aDest );
bool readTypMinMaxValueSubparam( std::string aSubparam, TypMinMaxValue& aDest );
bool readTypMinMaxValueSubparam( const std::string& aSubparam, TypMinMaxValue& aDest );
//bool ReadDieSupplyPads();
bool readPackage();

269
eeschema/sim/kibis/kibis.cpp

@ -47,12 +47,13 @@
#endif
std::vector<std::pair<int, double>> SimplifyBitSequence( std::vector<std::pair<int, double>> bits )
std::vector<std::pair<int, double>>
SimplifyBitSequence( const std::vector<std::pair<int, double>>& bits )
{
std::vector<std::pair<int, double>> result;
int prevbit = -1;
for( std::pair<int, double> bit : bits )
for( const std::pair<int, double>& bit : bits )
{
if( prevbit != bit.first )
result.push_back( bit );
@ -89,8 +90,8 @@ IBIS_CORNER ReverseLogic( IBIS_CORNER aIn )
return out;
}
KIBIS::KIBIS( std::string aFileName, REPORTER* aReporter ) :
KIBIS_ANY( this, aReporter ), m_file( this )
KIBIS::KIBIS( const std::string& aFileName, REPORTER* aReporter ) :
KIBIS_ANY( this, aReporter ), m_file( *this )
{
IbisParser parser( m_reporter );
bool status = true;
@ -98,32 +99,28 @@ KIBIS::KIBIS( std::string aFileName, REPORTER* aReporter ) :
parser.m_parrot = false;
status &= parser.ParseFile( aFileName );
status &= m_file.Init( parser );
for( IbisModel& iModel : parser.m_ibisFile.m_models )
for( const IbisModel& iModel : parser.m_ibisFile.m_models )
{
KIBIS_MODEL kModel( this, iModel, parser );
KIBIS_MODEL& kModel = m_models.emplace_back( *this, iModel, parser );
status &= kModel.m_valid;
m_models.push_back( kModel );
}
for( IbisComponent& iComponent : parser.m_ibisFile.m_components )
for( const IbisComponent& iComponent : parser.m_ibisFile.m_components )
{
KIBIS_COMPONENT kComponent( this, iComponent, parser );
KIBIS_COMPONENT& kComponent = m_components.emplace_back( *this, iComponent, parser );
status &= kComponent.m_valid;
m_components.push_back( kComponent );
for( KIBIS_PIN& pin : m_components.back().m_pins )
for( KIBIS_PIN& pin : kComponent.m_pins )
{
pin.m_parent = &( m_components.back() );
pin.m_parent = &kComponent;
}
for( IbisDiffPinEntry dpEntry : iComponent.m_diffPin.m_entries )
for( const IbisDiffPinEntry& dpEntry : iComponent.m_diffPin.m_entries )
{
KIBIS_PIN* pinA = m_components.back().GetPin( dpEntry.pinA );
KIBIS_PIN* pinB = m_components.back().GetPin( dpEntry.pinB );
KIBIS_PIN* pinA = kComponent.GetPin( dpEntry.pinA );
KIBIS_PIN* pinB = kComponent.GetPin( dpEntry.pinB );
if( pinA && pinB )
{
@ -137,14 +134,14 @@ KIBIS::KIBIS( std::string aFileName, REPORTER* aReporter ) :
}
KIBIS_FILE::KIBIS_FILE( KIBIS* aTopLevel ) : KIBIS_ANY( aTopLevel )
KIBIS_FILE::KIBIS_FILE( KIBIS& aTopLevel ) : KIBIS_ANY( &aTopLevel )
{
m_fileRev = -1;
m_ibisVersion = -1;
}
bool KIBIS_FILE::Init( IbisParser& aParser )
bool KIBIS_FILE::Init( const IbisParser& aParser )
{
bool status = true;
m_fileName = aParser.m_ibisFile.m_header.m_fileName;
@ -161,12 +158,11 @@ bool KIBIS_FILE::Init( IbisParser& aParser )
}
KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPackage& aPackage,
IbisParser& aParser, KIBIS_COMPONENT* aParent,
std::vector<KIBIS_MODEL>& aModels ) :
KIBIS_ANY( aTopLevel ),
m_Rpin( aTopLevel->m_reporter ), m_Lpin( aTopLevel->m_reporter ),
m_Cpin( aTopLevel->m_reporter )
KIBIS_PIN::KIBIS_PIN( KIBIS& aTopLevel, const IbisComponentPin& aPin,
const IbisComponentPackage& aPackage, IbisParser& aParser,
KIBIS_COMPONENT* aParent, std::vector<KIBIS_MODEL>& aModels ) :
KIBIS_ANY( &aTopLevel ), m_Rpin( aTopLevel.m_reporter ), m_Lpin( aTopLevel.m_reporter ),
m_Cpin( aTopLevel.m_reporter )
{
m_signalName = aPin.m_signalName;
m_pinNumber = aPin.m_pinName;
@ -206,11 +202,11 @@ KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPac
bool modelSelected = false;
std::vector<std::string> listOfModels;
for( IbisModelSelector modelSelector : aParser.m_ibisFile.m_modelSelectors )
for( const IbisModelSelector& modelSelector : aParser.m_ibisFile.m_modelSelectors )
{
if( !strcmp( modelSelector.m_name.c_str(), aPin.m_modelName.c_str() ) )
{
for( IbisModelSelectorEntry model : modelSelector.m_models )
for( const IbisModelSelectorEntry& model : modelSelector.m_models )
{
listOfModels.push_back( model.m_modelName );
}
@ -224,7 +220,7 @@ KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPac
listOfModels.push_back( aPin.m_modelName );
}
for( std::string modelName : listOfModels )
for( const std::string& modelName : listOfModels )
{
for( KIBIS_MODEL& model : aModels )
{
@ -239,16 +235,16 @@ KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPac
}
KIBIS_MODEL::KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aParser ) :
KIBIS_ANY( aTopLevel ), m_C_comp( aTopLevel->m_reporter ),
m_voltageRange( aTopLevel->m_reporter ), m_temperatureRange( aTopLevel->m_reporter ),
m_pullupReference( aTopLevel->m_reporter ), m_pulldownReference( aTopLevel->m_reporter ),
m_GNDClampReference( aTopLevel->m_reporter ),
m_POWERClampReference( aTopLevel->m_reporter ), m_Rgnd( aTopLevel->m_reporter ),
m_Rpower( aTopLevel->m_reporter ), m_Rac( aTopLevel->m_reporter ),
m_Cac( aTopLevel->m_reporter ), m_GNDClamp( aTopLevel->m_reporter ),
m_POWERClamp( aTopLevel->m_reporter ), m_pullup( aTopLevel->m_reporter ),
m_pulldown( aTopLevel->m_reporter ), m_ramp( aTopLevel->m_reporter )
KIBIS_MODEL::KIBIS_MODEL( KIBIS& aTopLevel, const IbisModel& aSource, IbisParser& aParser ) :
KIBIS_ANY( &aTopLevel ), m_C_comp( aTopLevel.m_reporter ),
m_voltageRange( aTopLevel.m_reporter ), m_temperatureRange( aTopLevel.m_reporter ),
m_pullupReference( aTopLevel.m_reporter ), m_pulldownReference( aTopLevel.m_reporter ),
m_GNDClampReference( aTopLevel.m_reporter ), m_POWERClampReference( aTopLevel.m_reporter ),
m_Rgnd( aTopLevel.m_reporter ), m_Rpower( aTopLevel.m_reporter ),
m_Rac( aTopLevel.m_reporter ), m_Cac( aTopLevel.m_reporter ),
m_GNDClamp( aTopLevel.m_reporter ), m_POWERClamp( aTopLevel.m_reporter ),
m_pullup( aTopLevel.m_reporter ), m_pulldown( aTopLevel.m_reporter ),
m_ramp( aTopLevel.m_reporter )
{
bool status = true;
@ -257,9 +253,9 @@ KIBIS_MODEL::KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aPar
m_description = std::string( "No description available." );
for( IbisModelSelector modelSelector : aParser.m_ibisFile.m_modelSelectors )
for( const IbisModelSelector& modelSelector : aParser.m_ibisFile.m_modelSelectors )
{
for( IbisModelSelectorEntry entry : modelSelector.m_models )
for( const IbisModelSelectorEntry& entry : modelSelector.m_models )
{
if( !strcmp( entry.m_modelName.c_str(), m_name.c_str() ) )
{
@ -303,16 +299,15 @@ KIBIS_MODEL::KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aPar
}
KIBIS_COMPONENT::KIBIS_COMPONENT( KIBIS* aTopLevel, IbisComponent& aSource, IbisParser& aParser ) :
KIBIS_ANY( aTopLevel )
KIBIS_COMPONENT::KIBIS_COMPONENT( KIBIS& aTopLevel, const IbisComponent& aSource,
IbisParser& aParser ) : KIBIS_ANY( &aTopLevel )
{
bool status = true;
m_name = aSource.m_name;
m_manufacturer = aSource.m_manufacturer;
m_topLevel = aTopLevel;
for( IbisComponentPin& iPin : aSource.m_pins )
for( const IbisComponentPin& iPin : aSource.m_pins )
{
if( iPin.m_dummy )
{
@ -329,7 +324,7 @@ KIBIS_COMPONENT::KIBIS_COMPONENT( KIBIS* aTopLevel, IbisComponent& aSource, Ibis
}
KIBIS_PIN* KIBIS_COMPONENT::GetPin( std::string aPinNumber )
KIBIS_PIN* KIBIS_COMPONENT::GetPin( const std::string& aPinNumber )
{
for( KIBIS_PIN& pin : m_pins )
{
@ -360,10 +355,7 @@ std::vector<std::pair<IbisWaveform*, IbisWaveform*>> KIBIS_MODEL::waveformPairs(
&& wf1->m_V_fixture_min == wf2->m_V_fixture_min
&& wf1->m_V_fixture_max == wf2->m_V_fixture_max )
{
std::pair<IbisWaveform*, IbisWaveform*> p;
p.first = wf1;
p.second = wf2;
pairs.push_back( p );
pairs.emplace_back( wf1, wf2 );
}
}
}
@ -372,7 +364,7 @@ std::vector<std::pair<IbisWaveform*, IbisWaveform*>> KIBIS_MODEL::waveformPairs(
}
std::string KIBIS_MODEL::SpiceDie( KIBIS_PARAMETER& aParam, int aIndex )
std::string KIBIS_MODEL::SpiceDie( const KIBIS_PARAMETER& aParam, int aIndex ) const
{
std::string result;
@ -445,11 +437,11 @@ std::string KIBIS_MODEL::SpiceDie( KIBIS_PARAMETER& aParam, int aIndex )
}
IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
IbisWaveform KIBIS_MODEL::TrimWaveform( const IbisWaveform& aIn ) const
{
IbisWaveform out( aIn.m_reporter );
int nbPoints = aIn.m_table.m_entries.size();
const int nbPoints = aIn.m_table.m_entries.size();
if( nbPoints < 2 )
{
@ -457,9 +449,9 @@ IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
return out;
}
double DCtyp = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::TYP];
double DCmin = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::MIN];
double DCmax = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::MAX];
const double DCtyp = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::TYP];
const double DCmin = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::MIN];
const double DCmax = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::MAX];
if( nbPoints == 2 )
{
@ -470,54 +462,51 @@ IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
for( int i = 0; i < nbPoints; i++ )
{
VTtableEntry entry( out.m_reporter );
const VTtableEntry& inEntry = aIn.m_table.m_entries.at( i );
VTtableEntry& outEntry = out.m_table.m_entries.emplace_back( out.m_reporter );
entry.t = aIn.m_table.m_entries.at( i ).t;
entry.V.value[IBIS_CORNER::TYP] = aIn.m_table.m_entries.at( i ).V.value[IBIS_CORNER::TYP];
entry.V.value[IBIS_CORNER::MIN] = aIn.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MIN];
entry.V.value[IBIS_CORNER::MAX] = aIn.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MAX];
out.m_table.m_entries.push_back( entry );
out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::TYP] -= DCtyp;
out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MIN] -= DCmin;
out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MAX] -= DCmax;
outEntry.t = inEntry.t;
outEntry.V.value[IBIS_CORNER::TYP] = inEntry.V.value[IBIS_CORNER::TYP] - DCtyp;
outEntry.V.value[IBIS_CORNER::MIN] = inEntry.V.value[IBIS_CORNER::MIN] - DCmin;
outEntry.V.value[IBIS_CORNER::MAX] = inEntry.V.value[IBIS_CORNER::MAX] - DCmax;
}
return out;
}
bool KIBIS_MODEL::HasPulldown()
bool KIBIS_MODEL::HasPulldown() const
{
return m_pulldown.m_entries.size() > 0;
}
bool KIBIS_MODEL::HasPullup()
bool KIBIS_MODEL::HasPullup() const
{
return m_pullup.m_entries.size() > 0;
}
bool KIBIS_MODEL::HasGNDClamp()
bool KIBIS_MODEL::HasGNDClamp() const
{
return m_GNDClamp.m_entries.size() > 0;
}
bool KIBIS_MODEL::HasPOWERClamp()
bool KIBIS_MODEL::HasPOWERClamp() const
{
return m_POWERClamp.m_entries.size() > 0;
}
std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNode2,
std::vector<std::pair<int, double>> aBits,
std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam )
std::string KIBIS_MODEL::generateSquareWave( const std::string& aNode1, const std::string& aNode2,
const std::vector<std::pair<int, double>>& aBits,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam )
{
IBIS_CORNER supply = aParam.m_supply;
std::string simul;
std::vector<int>stimuliIndex;
const IBIS_CORNER supply = aParam.m_supply;
std::string simul;
std::vector<int> stimuliIndex;
IbisWaveform risingWF = TrimWaveform( *( aPair.first ) );
IbisWaveform fallingWF = TrimWaveform( *( aPair.second ) );
@ -535,7 +524,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
int prevBit = 2;
for( std::pair<int, double> bit : aBits )
for( const std::pair<int, double>& bit : aBits )
{
IbisWaveform* WF;
double timing = bit.second;
@ -571,7 +560,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
simul += "\n+";
}
for( VTtableEntry& entry : WF->m_table.m_entries )
for( const VTtableEntry& entry : WF->m_table.m_entries )
{
simul += doubleToString( entry.t + timing );
simul += " ";
@ -614,9 +603,9 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
}
std::string KIBIS_PIN::addDie( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam, int aIndex )
std::string KIBIS_PIN::addDie( KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam, int aIndex )
{
IBIS_CORNER supply = aParam.m_supply;
const IBIS_CORNER supply = aParam.m_supply;
std::string simul;
std::string GC_GND = "GC_GND";
@ -666,9 +655,9 @@ std::string KIBIS_PIN::addDie( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam, int
}
void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
void KIBIS_PIN::getKuKdFromFile( const std::string& aSimul )
{
std::string outputFileName = m_topLevel->m_cacheDir + "temp_output.spice";
const std::string outputFileName = m_topLevel->m_cacheDir + "temp_output.spice";
if( std::remove( outputFileName.c_str() ) )
{
@ -683,7 +672,7 @@ void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
return;
}
ng->Init();
ng->LoadNetlist( *aSimul );
ng->LoadNetlist( aSimul );
std::ifstream KuKdfile;
KuKdfile.open( outputFileName );
@ -746,9 +735,9 @@ void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
}
std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aModel,
std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam, int aIndex )
std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam, int aIndex )
{
IBIS_CORNER supply = aParam.m_supply;
IBIS_CORNER ccomp = aParam.m_Ccomp;
@ -779,8 +768,8 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
simul += doubleToString( aModel.m_C_comp.value[ccomp] ); //@TODO: Check the corner ?
simul += "\n";
IbisWaveform* risingWF = aPair.first;
IbisWaveform* fallingWF = aPair.second;
const IbisWaveform* risingWF = aPair.first;
const IbisWaveform* fallingWF = aPair.second;
switch( wave->GetType() )
{
@ -795,7 +784,7 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
}
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
{
IbisWaveform* waveform = wave->inverted ? risingWF : fallingWF;
const IbisWaveform* waveform = wave->inverted ? risingWF : fallingWF;
simul += "Vsig DIE0 GND ";
simul += doubleToString( waveform->m_table.m_entries.at( 0 ).V.value[supply] );
simul += "\n";
@ -803,7 +792,7 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
}
case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
{
IbisWaveform* waveform = wave->inverted ? fallingWF : risingWF;
const IbisWaveform* waveform = wave->inverted ? fallingWF : risingWF;
simul += "Vsig DIE0 GND ";
simul += doubleToString( waveform->m_table.m_entries.at( 0 ).V.value[supply] );
simul += "\n";
@ -820,12 +809,12 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
}
void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aModel,
std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam )
void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam )
{
IBIS_CORNER supply = aParam.m_supply;
KIBIS_WAVEFORM* wave = aParam.m_waveform;
IBIS_CORNER supply = aParam.m_supply;
const KIBIS_WAVEFORM* wave = aParam.m_waveform;
std::string simul = "";
@ -924,16 +913,16 @@ void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aMod
simul += ".endc \n";
simul += ".end \n";
getKuKdFromFile( &simul );
getKuKdFromFile( simul );
}
}
void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam )
void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam )
{
std::vector<double> ku, kd, t;
KIBIS_WAVEFORM* wave = aParam.m_waveform;
IBIS_CORNER& supply = aParam.m_supply;
std::vector<double> ku, kd, t;
const KIBIS_WAVEFORM* wave = aParam.m_waveform;
const IBIS_CORNER& supply = aParam.m_supply;
if( !wave )
{
@ -949,7 +938,7 @@ void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam
std::vector<std::pair<int, double>> bits = wave->GenerateBitSequence();
bits = SimplifyBitSequence( bits );
for( std::pair<int, double> bit : bits )
for( const std::pair<int, double>& bit : bits )
{
ku.push_back( bit.first ? 0 : 1 );
kd.push_back( bit.first ? 1 : 0 );
@ -991,14 +980,14 @@ void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam
}
void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aModel,
std::pair<IbisWaveform*, IbisWaveform*> aPair1,
std::pair<IbisWaveform*, IbisWaveform*> aPair2,
KIBIS_PARAMETER& aParam )
void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair1,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair2,
const KIBIS_PARAMETER& aParam )
{
std::string simul = "";
IBIS_CORNER supply = aParam.m_supply;
KIBIS_WAVEFORM* wave = aParam.m_waveform;
std::string simul = "";
const IBIS_CORNER supply = aParam.m_supply;
const KIBIS_WAVEFORM* wave = aParam.m_waveform;
if( !wave )
return;
@ -1128,13 +1117,13 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
simul += ".endc \n";
simul += ".end \n";
getKuKdFromFile( &simul );
getKuKdFromFile( simul );
}
}
bool KIBIS_PIN::writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam )
bool KIBIS_PIN::writeSpiceDriver( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam )
{
bool status = true;
@ -1245,7 +1234,7 @@ bool KIBIS_PIN::writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_M
result += "\n.ENDS DRIVER\n\n";
*aDest += result;
aDest += result;
break;
}
default: Report( _( "Invalid model type for a driver." ), RPT_SEVERITY_ERROR ); status = false;
@ -1255,8 +1244,8 @@ bool KIBIS_PIN::writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_M
}
bool KIBIS_PIN::writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam )
bool KIBIS_PIN::writeSpiceDevice( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam )
{
bool status = true;
@ -1270,7 +1259,6 @@ bool KIBIS_PIN::writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_M
case IBIS_MODEL_TYPE::IO_ECL:
{
std::string result;
std::string tmp;
result += "\n";
result = "*Device model generated by Kicad using Ibis data.";
@ -1297,7 +1285,7 @@ bool KIBIS_PIN::writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_M
result += "\n.ENDS DRIVER\n\n";
*aDest = result;
aDest = std::move( result );
break;
}
default: Report( _( "Invalid model type for a device" ), RPT_SEVERITY_ERROR ); status = false;
@ -1307,8 +1295,8 @@ bool KIBIS_PIN::writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_M
}
bool KIBIS_PIN::writeSpiceDiffDriver( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam )
bool KIBIS_PIN::writeSpiceDiffDriver( std::string& aDest, const std::string& aName,
KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam )
{
bool status = true;
KIBIS_WAVEFORM* wave = aParam.m_waveform;
@ -1336,9 +1324,9 @@ bool KIBIS_PIN::writeSpiceDiffDriver( std::string* aDest, std::string aName, KIB
result += " GND PIN_P PIN_N\n";
result += "\n";
status &= writeSpiceDriver( &result, aName + "_P", aModel, aParam );
status &= writeSpiceDriver( result, aName + "_P", aModel, aParam );
wave->inverted = !wave->inverted;
status &= writeSpiceDriver( &result, aName + "_N", aModel, aParam );
status &= writeSpiceDriver( result, aName + "_N", aModel, aParam );
wave->inverted = !wave->inverted;
@ -1351,15 +1339,15 @@ bool KIBIS_PIN::writeSpiceDiffDriver( std::string* aDest, std::string aName, KIB
if( status )
{
*aDest += result;
aDest += result;
}
return status;
}
bool KIBIS_PIN::writeSpiceDiffDevice( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam )
bool KIBIS_PIN::writeSpiceDiffDevice( std::string& aDest, const std::string& aName,
KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam )
{
bool status = true;
@ -1383,8 +1371,8 @@ bool KIBIS_PIN::writeSpiceDiffDevice( std::string* aDest, std::string aName, KIB
result += " GND PIN_P PIN_N\n";
result += "\n";
status &= writeSpiceDevice( &result, aName + "_P", aModel, aParam );
status &= writeSpiceDevice( &result, aName + "_N", aModel, aParam );
status &= writeSpiceDevice( result, aName + "_P", aModel, aParam );
status &= writeSpiceDevice( result, aName + "_N", aModel, aParam );
result += "\n";
result += "x1 GND PIN_P " + aName + "_P \n";
@ -1395,14 +1383,14 @@ bool KIBIS_PIN::writeSpiceDiffDevice( std::string* aDest, std::string aName, KIB
if( status )
{
*aDest += result;
aDest += result;
}
return status;
}
KIBIS_MODEL* KIBIS::GetModel( std::string aName )
KIBIS_MODEL* KIBIS::GetModel( const std::string& aName )
{
for( KIBIS_MODEL& model : m_models )
{
@ -1413,7 +1401,7 @@ KIBIS_MODEL* KIBIS::GetModel( std::string aName )
}
KIBIS_COMPONENT* KIBIS::GetComponent( std::string aName )
KIBIS_COMPONENT* KIBIS::GetComponent( const std::string& aName )
{
for( KIBIS_COMPONENT& cmp : m_components )
{
@ -1424,7 +1412,7 @@ KIBIS_COMPONENT* KIBIS::GetComponent( std::string aName )
}
void KIBIS_PARAMETER::SetCornerFromString( IBIS_CORNER& aCorner, std::string aString )
void KIBIS_PARAMETER::SetCornerFromString( IBIS_CORNER& aCorner, const std::string& aString )
{
if( aString == "MIN" )
aCorner = IBIS_CORNER::MIN;
@ -1435,7 +1423,7 @@ void KIBIS_PARAMETER::SetCornerFromString( IBIS_CORNER& aCorner, std::string aSt
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_HIGH::GenerateBitSequence()
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_HIGH::GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bits;
std::pair<int, double> bit;
@ -1445,7 +1433,7 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_HIGH::GenerateBitSequen
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_LOW::GenerateBitSequence()
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_LOW::GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bits;
std::pair<int, double> bit;
@ -1454,13 +1442,13 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_STUCK_LOW::GenerateBitSequenc
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_HIGH_Z::GenerateBitSequence()
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_HIGH_Z::GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bits;
return bits;
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_RECTANGULAR::GenerateBitSequence()
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_RECTANGULAR::GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bits;
@ -1479,7 +1467,7 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_RECTANGULAR::GenerateBitSeque
}
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bitSequence;
uint8_t polynomial = 0b1100000;
@ -1494,7 +1482,8 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
double period = 1/m_bitrate;
double t = 0;
m_bits = abs( m_bits ); // Just to be sure.
wxASSERT( m_bits > 0 );
int bits = 0;
do
@ -1513,7 +1502,8 @@ std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
return bitSequence;
}
bool KIBIS_WAVEFORM_RECTANGULAR::Check( IbisWaveform* aRisingWf, IbisWaveform* aFallingWf )
bool KIBIS_WAVEFORM_RECTANGULAR::Check( const IbisWaveform* aRisingWf,
const IbisWaveform* aFallingWf ) const
{
bool status = true;
@ -1559,7 +1549,8 @@ bool KIBIS_WAVEFORM_RECTANGULAR::Check( IbisWaveform* aRisingWf, IbisWaveform* a
}
bool KIBIS_WAVEFORM_RECTANGULAR::Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFallingRp )
bool KIBIS_WAVEFORM_RECTANGULAR::Check( const dvdtTypMinMax& aRisingRp,
const dvdtTypMinMax& aFallingRp ) const
{
bool status = true;
@ -1601,7 +1592,8 @@ bool KIBIS_WAVEFORM_RECTANGULAR::Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax a
}
bool KIBIS_WAVEFORM_PRBS::Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFallingRp )
bool KIBIS_WAVEFORM_PRBS::Check( const dvdtTypMinMax& aRisingRp,
const dvdtTypMinMax& aFallingRp ) const
{
bool status = true;
@ -1632,7 +1624,8 @@ bool KIBIS_WAVEFORM_PRBS::Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFalling
return status;
}
bool KIBIS_WAVEFORM_PRBS::Check( IbisWaveform* aRisingWf, IbisWaveform* aFallingWf )
bool KIBIS_WAVEFORM_PRBS::Check( const IbisWaveform* aRisingWf,
const IbisWaveform* aFallingWf ) const
{
bool status = true;

141
eeschema/sim/kibis/kibis.h

@ -71,22 +71,28 @@ enum class KIBIS_WAVEFORM_TYPE
class KIBIS_WAVEFORM : public KIBIS_ANY
{
public:
KIBIS_WAVEFORM( KIBIS* aTopLevel ) : KIBIS_ANY{ aTopLevel } { m_valid = true; };
KIBIS_WAVEFORM_TYPE GetType() { return m_type; };
virtual double GetDuration() { return 1; };
KIBIS_WAVEFORM( KIBIS& aTopLevel ) : KIBIS_ANY{ &aTopLevel } { m_valid = true; };
KIBIS_WAVEFORM_TYPE GetType() const { return m_type; };
virtual double GetDuration() const { return 1; };
bool inverted = false; // Used for differential drivers
virtual ~KIBIS_WAVEFORM(){};
virtual ~KIBIS_WAVEFORM() {};
virtual std::vector<std::pair<int, double>> GenerateBitSequence()
virtual std::vector<std::pair<int, double>> GenerateBitSequence() const
{
std::vector<std::pair<int, double>> bits;
return bits;
};
// Check fuction if using waveform data
virtual bool Check( IbisWaveform* aRisingWf, IbisWaveform* aFallingWf ) { return true; };
// Check fuction if using ramp data
virtual bool Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFallingRp ) { return true; };
// Check function if using waveform data
virtual bool Check( const IbisWaveform* aRisingWf, const IbisWaveform* aFallingWf ) const
{
return true;
};
// Check function if using ramp data
virtual bool Check( const dvdtTypMinMax& aRisingRp, const dvdtTypMinMax& aFallingRp ) const
{
return true;
};
protected:
KIBIS_WAVEFORM_TYPE m_type = KIBIS_WAVEFORM_TYPE::NONE;
@ -95,7 +101,7 @@ protected:
class KIBIS_WAVEFORM_RECTANGULAR : public KIBIS_WAVEFORM
{
public:
KIBIS_WAVEFORM_RECTANGULAR( KIBIS* aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
KIBIS_WAVEFORM_RECTANGULAR( KIBIS& aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
{
m_type = KIBIS_WAVEFORM_TYPE::RECTANGULAR;
};
@ -105,18 +111,18 @@ public:
int m_cycles = 1;
std::vector<std::pair<int, double>> GenerateBitSequence() override;
bool Check( IbisWaveform* aRisingWf, IbisWaveform* aFallingWf ) override;
bool Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFallingRp ) override;
std::vector<std::pair<int, double>> GenerateBitSequence() const override;
bool Check( const IbisWaveform* aRisingWf, const IbisWaveform* aFallingWf ) const override;
bool Check( const dvdtTypMinMax& aRisingRp, const dvdtTypMinMax& aFallingRp ) const override;
double GetDuration() override { return ( m_ton + m_toff ) * m_cycles; };
double GetDuration() const override { return ( m_ton + m_toff ) * m_cycles; };
};
// For now, we only support PRBS7
class KIBIS_WAVEFORM_PRBS : public KIBIS_WAVEFORM
{
public:
KIBIS_WAVEFORM_PRBS( KIBIS* aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
KIBIS_WAVEFORM_PRBS( KIBIS& aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
{
m_type = KIBIS_WAVEFORM_TYPE::PRBS;
};
@ -124,41 +130,43 @@ public:
double m_delay = 0;
int m_bits = 10;
std::vector<std::pair<int, double>> GenerateBitSequence() override;
bool Check( IbisWaveform* aRisingWf, IbisWaveform* aFallingWf ) override;
bool Check( dvdtTypMinMax aRisingRp, dvdtTypMinMax aFallingRp ) override;
std::vector<std::pair<int, double>> GenerateBitSequence() const override;
bool Check( const IbisWaveform* aRisingWf, const IbisWaveform* aFallingWf ) const override;
bool Check( const dvdtTypMinMax& aRisingRp, const dvdtTypMinMax& aFallingRp ) const override;
void SetBits( int aBits ) { m_bits = std::abs( aBits ); };
double GetDuration() override { return m_bits / m_bitrate ; };
double GetDuration() const override { return m_bits / m_bitrate; };
};
class KIBIS_WAVEFORM_STUCK_HIGH : public KIBIS_WAVEFORM
{
public:
KIBIS_WAVEFORM_STUCK_HIGH( KIBIS* aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
KIBIS_WAVEFORM_STUCK_HIGH( KIBIS& aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
{
m_type = KIBIS_WAVEFORM_TYPE::STUCK_HIGH;
};
std::vector<std::pair<int, double>> GenerateBitSequence() override;
std::vector<std::pair<int, double>> GenerateBitSequence() const override;
};
class KIBIS_WAVEFORM_STUCK_LOW : public KIBIS_WAVEFORM
{
public:
KIBIS_WAVEFORM_STUCK_LOW( KIBIS* aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
KIBIS_WAVEFORM_STUCK_LOW( KIBIS& aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
{
m_type = KIBIS_WAVEFORM_TYPE::STUCK_LOW;
};
std::vector<std::pair<int, double>> GenerateBitSequence() override;
std::vector<std::pair<int, double>> GenerateBitSequence() const override;
};
class KIBIS_WAVEFORM_HIGH_Z : public KIBIS_WAVEFORM
{
public:
KIBIS_WAVEFORM_HIGH_Z( KIBIS* aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
KIBIS_WAVEFORM_HIGH_Z( KIBIS& aTopLevel ) : KIBIS_WAVEFORM( aTopLevel )
{
m_type = KIBIS_WAVEFORM_TYPE::HIGH_Z;
};
std::vector<std::pair<int, double>> GenerateBitSequence() override;
std::vector<std::pair<int, double>> GenerateBitSequence() const override;
};
/** Accuracy level.
@ -198,14 +206,14 @@ public:
KIBIS_WAVEFORM* m_waveform = nullptr;
KIBIS_ACCURACY m_accuracy = KIBIS_ACCURACY::LEVEL_2;
void SetCornerFromString( IBIS_CORNER& aCorner, std::string aString );
void SetCornerFromString( IBIS_CORNER& aCorner, const std::string& aString );
};
class KIBIS_FILE : KIBIS_ANY
{
public:
KIBIS_FILE( KIBIS* aTopLevel );
KIBIS_FILE( KIBIS& aTopLevel );
std::string m_fileName;
double m_fileRev;
@ -216,13 +224,13 @@ public:
std::string m_disclaimer;
std::string m_copyright;
bool Init( IbisParser& aParser );
bool Init( const IbisParser& aParser );
};
class KIBIS_MODEL : public KIBIS_ANY
{
public:
KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aParser );
KIBIS_MODEL( KIBIS& aTopLevel, const IbisModel& aSource, IbisParser& aParser );
std::string m_name;
std::string m_description;
@ -259,13 +267,13 @@ public:
IbisRamp m_ramp;
/** @brief Return true if the model has a pulldown transistor */
bool HasPulldown();
bool HasPulldown() const;
/** @brief Return true if the model has a pullup transistor */
bool HasPullup();
bool HasPullup() const;
/** @brief Return true if the model has a clamp diode to the gnd net */
bool HasGNDClamp();
bool HasGNDClamp() const;
/** @brief Return true if the model has a clamp diode to the power net */
bool HasPOWERClamp();
bool HasPOWERClamp() const;
/** @brief Generate the spice directive to simulate the die
*
@ -273,7 +281,7 @@ public:
* @param aIndex Index used to offset spice nodes / directives
* @return A multiline string with spice directives
*/
std::string SpiceDie( KIBIS_PARAMETER& aParam, int aIndex );
std::string SpiceDie( const KIBIS_PARAMETER& aParam, int aIndex ) const;
/** @brief Create waveform pairs
*
@ -299,10 +307,10 @@ public:
* @param aParam Parameters
* @return A multiline string with spice directives
*/
std::string generateSquareWave( std::string aNode1, std::string aNode2,
std::vector<std::pair<int, double>> aBits,
std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam );
std::string generateSquareWave( const std::string& aNode1, const std::string& aNode2,
const std::vector<std::pair<int, double>>& aBits,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam );
/** @brief Copy a waveform, and substract the first value to all samples
@ -311,13 +319,13 @@ public:
* @param aIn Input waveform
* @return Output waveform
*/
IbisWaveform TrimWaveform( IbisWaveform& aIn );
IbisWaveform TrimWaveform( const IbisWaveform& aIn ) const;
};
class KIBIS_PIN : public KIBIS_ANY
{
public:
KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPackage& aPackage,
KIBIS_PIN( KIBIS& aTopLevel, const IbisComponentPin& aPin, const IbisComponentPackage& aPackage,
IbisParser& aParser, KIBIS_COMPONENT* aParent, std::vector<KIBIS_MODEL>& aModels );
/** @brief Name of the pin
* Examples : "VCC", "GPIOA", "CLK", etc...
@ -341,28 +349,29 @@ public:
std::vector<KIBIS_MODEL*> m_models;
bool writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam );
bool writeSpiceDiffDriver( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam );
bool writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam );
bool writeSpiceDiffDevice( std::string* aDest, std::string aName, KIBIS_MODEL& aModel,
KIBIS_PARAMETER& aParam );
bool writeSpiceDriver( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam );
bool writeSpiceDiffDriver( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam );
bool writeSpiceDevice( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam );
bool writeSpiceDiffDevice( std::string& aDest, const std::string& aName, KIBIS_MODEL& aModel,
const KIBIS_PARAMETER& aParam );
/** @brief Update m_Ku, m_Kd using no falling / rising waveform inputs ( low accuracy )
* @param aModel Model to be used
* @param aParam Parameters
*/
void getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam );
void getKuKdNoWaveform( KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam );
/** @brief Update m_Ku, m_Kd using with a single waveform input
* @param aModel Model to be used
* @param aPair @see waveformPairs()
* @param aParam Parameters
*/
void getKuKdOneWaveform( KIBIS_MODEL& aModel, std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam );
void getKuKdOneWaveform( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam );
/** @brief Update m_Ku, m_Kd using with two waveform inputs
*
@ -373,9 +382,10 @@ public:
* @param aParam Parameters
* @param aIndex Index for numbering spice .SUBCKT
*/
void getKuKdTwoWaveforms( KIBIS_MODEL& aModel, std::pair<IbisWaveform*, IbisWaveform*> aPair1,
std::pair<IbisWaveform*, IbisWaveform*> aPair2,
KIBIS_PARAMETER& aParam );
void getKuKdTwoWaveforms( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair1,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair2,
const KIBIS_PARAMETER& aParam );
/** @brief Update m_Ku, m_Kd using with two waveform inputs
*
@ -387,8 +397,9 @@ public:
*
* @return A multiline string with spice directives
*/
std::string KuKdDriver( KIBIS_MODEL& aModel, std::pair<IbisWaveform*, IbisWaveform*> aPair,
KIBIS_PARAMETER& aParam, int aIndex );
std::string KuKdDriver( KIBIS_MODEL& aModel,
const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
const KIBIS_PARAMETER& aParam, int aIndex );
/** @brief Generate the spice directive to simulate the die for Ku/Kd estimation
*
@ -400,7 +411,7 @@ public:
* @param aIndex Index for numbering ports
* @return A multiline string with spice directives
*/
std::string addDie( KIBIS_MODEL& aModel, KIBIS_PARAMETER& aParam, int aIndex );
std::string addDie( KIBIS_MODEL& aModel, const KIBIS_PARAMETER& aParam, int aIndex );
/** @brief Update m_Ku, m_Kd using with two waveform inputs
@ -411,17 +422,17 @@ public:
*
* @param aSimul The simulation to run, multiline spice directives
*/
void getKuKdFromFile( std::string* aSimul );
void getKuKdFromFile( const std::string& aSimul );
KIBIS_PIN* m_complementaryPin = nullptr;
bool isDiffPin() { return m_complementaryPin != nullptr; };
bool isDiffPin() const { return m_complementaryPin != nullptr; };
};
class KIBIS_COMPONENT : public KIBIS_ANY
{
public:
KIBIS_COMPONENT( KIBIS* aToplevel, IbisComponent& aSource, IbisParser& aParser );
KIBIS_COMPONENT( KIBIS& aToplevel, const IbisComponent& aSource, IbisParser& aParser );
/** @brief Name of the component */
std::string m_name;
/** @brief Name of the manufacturer */
@ -434,16 +445,16 @@ public:
* @param aPinNumber pin number
* @return pointer to a KIBIS_PIN, or nullptr if there is no matching pin
*/
KIBIS_PIN* GetPin( std::string aPinNumber );
KIBIS_PIN* GetPin( const std::string& aPinNumber );
};
class KIBIS : public KIBIS_ANY
{
public:
/** @brief Constructor for unitialized KIBIS members */
KIBIS() : KIBIS_ANY( this, nullptr ), m_file( this ) {};
KIBIS() : KIBIS_ANY( this, nullptr ), m_file( *this ) {};
KIBIS( std::string aFileName, REPORTER* aReporter = nullptr );
KIBIS( const std::string& aFileName, REPORTER* aReporter = nullptr );
std::vector<KIBIS_COMPONENT> m_components;
std::vector<KIBIS_MODEL> m_models;
@ -453,9 +464,9 @@ public:
std::string m_cacheDir = "";
/** @brief Return the model with name aName . Nullptr if not found */
KIBIS_MODEL* GetModel( std::string aName );
KIBIS_MODEL* GetModel( const std::string& aName );
/** @brief Return the component with name aName . Nullptr if not found */
KIBIS_COMPONENT* GetComponent( std::string aName );
KIBIS_COMPONENT* GetComponent( const std::string& aName );
};
#endif

36
eeschema/sim/sim_model_ibis.cpp

@ -111,7 +111,7 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, const PRO
if( const SIM_MODEL::PARAM* vcc = m_model.FindParam( "vcc" ) )
kparams.SetCornerFromString( kparams.m_supply, vcc->value );
if( const SIM_MODEL::PARAM* rpin = m_model.FindParam( "rpin" ) )
kparams.SetCornerFromString( kparams.m_Rpin, rpin->value );
@ -129,9 +129,9 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, const PRO
{
case SIM_MODEL::TYPE::KIBIS_DEVICE:
if( diffMode )
kpin->writeSpiceDiffDevice( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDiffDevice( result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDevice( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDevice( result, aItem.modelName, *kmodel, kparams );
break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
@ -143,27 +143,27 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, const PRO
if( paramValue == "hi-Z" )
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z( &kibis ) );
kparams.m_waveform = new KIBIS_WAVEFORM_HIGH_Z( kibis );
}
else if( paramValue == "low" )
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_LOW( &kibis ) );
kparams.m_waveform = new KIBIS_WAVEFORM_STUCK_LOW( kibis );
}
else if( paramValue == "high" )
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH( &kibis ) );
kparams.m_waveform = new KIBIS_WAVEFORM_STUCK_HIGH( kibis );
}
if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDiffDriver( result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDriver( result, aItem.modelName, *kmodel, kparams );
break;
}
case SIM_MODEL::TYPE::KIBIS_DRIVER_RECT:
{
KIBIS_WAVEFORM_RECTANGULAR* waveform = new KIBIS_WAVEFORM_RECTANGULAR( &kibis );
KIBIS_WAVEFORM_RECTANGULAR* waveform = new KIBIS_WAVEFORM_RECTANGULAR( kibis );
if( const SIM_MODEL::PARAM* ton = m_model.FindParam( "ton" ) )
waveform->m_ton = SIM_VALUE::ToDouble( ton->value, 0 );
@ -180,15 +180,15 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, const PRO
kparams.m_waveform = waveform;
if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDiffDriver( result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDriver( result, aItem.modelName, *kmodel, kparams );
break;
}
case SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS:
{
KIBIS_WAVEFORM_PRBS* waveform = new KIBIS_WAVEFORM_PRBS( &kibis );
KIBIS_WAVEFORM_PRBS* waveform = new KIBIS_WAVEFORM_PRBS( kibis );
if( const SIM_MODEL::PARAM* f0 = m_model.FindParam( "f0" ) )
waveform->m_bitrate = SIM_VALUE::ToDouble( f0->value, 0 );
@ -197,14 +197,14 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, const PRO
waveform->m_delay = SIM_VALUE::ToDouble( td->value, 0 );
if( const SIM_MODEL::PARAM* n = m_model.FindParam( "n" ) )
waveform->m_bits = SIM_VALUE::ToInt( n->value, 0 );
waveform->SetBits( SIM_VALUE::ToInt( n->value, 0 ) );
kparams.m_waveform = waveform;
if( diffMode )
kpin->writeSpiceDiffDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDiffDriver( result, aItem.modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
kpin->writeSpiceDriver( result, aItem.modelName, *kmodel, kparams );
break;
}
@ -283,19 +283,19 @@ SIM_MODEL_IBIS::SIM_MODEL_IBIS( TYPE aType, const SIM_MODEL_IBIS& aSource ) :
m_ibisPins = aSource.GetIbisPins();
m_ibisModels = aSource.GetIbisModels();
m_enableDiff = aSource.CanDifferential();
}
bool SIM_MODEL_IBIS::ChangePin( const SIM_LIBRARY_IBIS& aLib, std::string aPinNumber )
bool SIM_MODEL_IBIS::ChangePin( const SIM_LIBRARY_IBIS& aLib, const std::string& aPinNumber )
{
KIBIS_COMPONENT* kcomp = aLib.m_kibis.GetComponent( std::string( GetComponentName() ) );
if( !kcomp )
return false;
KIBIS_PIN* kpin = kcomp->GetPin( std::string( aPinNumber.c_str() ) );
KIBIS_PIN* kpin = kcomp->GetPin( aPinNumber );
if( !kpin )
return false;

4
eeschema/sim/sim_model_ibis.h

@ -75,10 +75,10 @@ public:
return m_params.at( aParamIndex );
};
/**
/**
* @brief update the list of available models based on the pin number.
*/
bool ChangePin( const SIM_LIBRARY_IBIS& aLib, std::string aPinNumber );
bool ChangePin( const SIM_LIBRARY_IBIS& aLib, const std::string& aPinNumber );
void SetBaseModel( const SIM_MODEL& aBaseModel ) override;

4
qa/tools/ibis/qaIbisParser.cpp

@ -45,11 +45,11 @@ int main( void )
params.m_waveform = new KIBIS_WAVEFORM_RECTANGULAR();
pin2->writeSpiceDevice( tmp4, "device_typ", *( pin2->m_models.at( 0 ) ), params );
pin2->writeSpiceDevice( *tmp4, "device_typ", *( pin2->m_models.at( 0 ) ), params );
KIBIS_MODEL* model1 = pin1->m_models.at( 0 );
std::cout << "Model used for driver: " << model1->m_name << std::endl;
pin1->writeSpiceDiffDriver( tmp1, "driver_typ", *( model1 ), params );
pin1->writeSpiceDiffDriver( *tmp1, "driver_typ", *( model1 ), params );
wxTextFile file( "output.sp" );
if( file.Exists() )

Loading…
Cancel
Save