53 return std::equal( stra.begin(), stra.end(),
54 strb.begin(), strb.end(),
57 return std::tolower(a) == std::tolower(b);
80 if( std::isnan(
m_data[i] ) )
103 if( std::isnan(
m_data[i] ) )
126 if( std::isnan(
m_data[i] ) )
140 return std::memcmp( &aNumber, &
NA,
sizeof NA ) == 0;
148 if( std::isnan(
value[IBIS_CORNER::TYP] ) )
193 std::stringstream message;
259 std::stringstream message;
260 message <<
_(
"Checking component " ) <<
m_name;
299 status &=
pin.Check();
313 std::ostringstream ss;
314 ss.setf( std::ios_base::scientific, std::ios_base::floatfield );
320std::string
IVtable::Spice(
int aN,
const std::string& aPort1,
const std::string& aPort2,
321 const std::string& aModelName,
IBIS_CORNER aCorner )
const
323 std::string result =
"";
328 result += std::to_string( aN );
338 result += aModelName;
342 result += aModelName;
343 result +=
" pwl(\n+ x_array=[";
351 result +=
"]\n+ y_array=[";
359 result +=
"]\n+ input_domain=0.05 fraction=TRUE)\n\n";
371 return m_entries.back().I.value[aCorner];
374 return m_entries.at( 0 ).I.value[aCorner];
376 for(
size_t i = 1; i <
m_entries.size(); i++ )
380 return m_entries.at( i - 1 ).I.value[aCorner]
382 -
m_entries.at( i - 1 ).I.value[aCorner] )
405 if( std::isnan( entry.V ) )
412 if( !entry.I.Check() )
432 if( std::isnan(
value[IBIS_CORNER::TYP].m_dv ) )
435 if( std::isnan(
value[IBIS_CORNER::TYP].m_dt ) )
490 std::stringstream message;
491 message <<
_(
"Checking model " ) <<
m_name;
493 if(
m_type == IBIS_MODEL_TYPE::UNDEFINED)
619 if(
m_type != IBIS_MODEL_TYPE::INPUT_ECL &&
m_type != IBIS_MODEL_TYPE::INPUT_STD
620 &&
m_type != IBIS_MODEL_TYPE::TERMINATOR &&
m_type != IBIS_MODEL_TYPE::SERIES
621 &&
m_type != IBIS_MODEL_TYPE::SERIES_SWITCH )
634 std::stringstream message;
635 message <<
_(
"Checking Header..." );
675 if( !( !strcmp( ext.c_str(),
".ibs" ) || !strcmp( ext.c_str(),
".pkg" )
676 || !strcmp( ext.c_str(),
".ebd" ) || !strcmp( ext.c_str(),
".ims" ) ) )
698 std::stringstream message;
699 message <<
_(
"Checking package model " ) <<
m_name;
737 for(
size_t i = 0; i <
m_pins.size(); i++ )
739 if(
m_pins.at( i ).empty() )
822 std::stringstream err_msg;
824 std::ifstream ibisFile;
825 ibisFile.open( aFileName );
827 if( !ibisFile.is_open() )
829 err_msg <<
_(
"Cannot open file " ) << aFileName;
834 std::ostringstream ss;
835 ss << ibisFile.rdbuf();
836 const std::string& s = ss.str();
837 m_buffer = std::vector<char>( s.begin(), s.end() );
863 err_msg <<
_(
"Error on line " ) << std::to_string(
m_lineCounter );
868 if(
m_context == IBIS_PARSER_CONTEXT::END )
912 if( aString ==
"NA" )
922 for( i = 1; i < (int)aString.length(); i++ )
924 if( aString.at( i ) ==
'/' )
928 if( aString.at( i ) ==
'/' )
930 std::string str1 = aString.substr( 0, i );
931 std::string str2 = aString.substr( i + 1, aString.size() - i - 1 );
948 bool converted =
false;
950 std::string str = aStr;
964 result = std::stod( str, &size );
974 if( converted && ( size < str.length() ) )
976 switch(
static_cast<char>( str.at( size ) ) )
978 case 'T': result *= 1e12;
break;
979 case 'G': result *= 1e9;
break;
980 case 'M': result *= 1e6;
break;
981 case 'k': result *= 1e3;
break;
982 case 'm': result *= 1e-3;
break;
983 case 'u': result *= 1e-6;
break;
984 case 'n': result *= 1e-9;
break;
985 case 'p': result *= 1e-12;
break;
986 case 'f': result *= 1e-15;
break;
1031 while( c != 0 && c !=
'\n' )
1050 std::cout << std::endl;
1087 result = std::stoi( str, &size );
1102 if( size != str.size() )
1130 aDest = std::string( start,
end );
1132 return ( aDest.size() > 0 );
1141 int len = aDest.length();
1146 char c = aDest[len - 1];
1149 while( isspace( c ) && ( i < len ) )
1151 c = aDest[len - 1 - i];
1155 aDest = aDest.substr( 0, len - i + 1 );
1168 m_continue = aMultiline ? IBIS_PARSER_CONTINUE::STRING : IBIS_PARSER_CONTINUE::NONE;
1180 std::string strChar =
"";
1188 if( !( c ==
'!' || c ==
'"' || c ==
'#' || c ==
'$' || c ==
'%' || c ==
'&' || c ==
'\''
1189 || c ==
'(' || c ==
')' || c ==
'*' || c ==
',' || c ==
':' || c ==
';' || c ==
'<'
1190 || c ==
'>' || c ==
'?' || c ==
'@' || c ==
'\\' || c ==
'^' || c ==
'`' || c ==
'{'
1191 || c ==
'|' || c ==
'}' || c ==
'~' || c ==
')' ) )
1198 while( ( !isspace( c ) ) && c != 0 && c !=
'\n' )
1204 if( strChar !=
"_char" )
1210 while( isspace( c ) && c != 0 && c !=
'\n' && c != d )
1213 if( ( !isspace( c ) ) && c != d )
1228 std::string keyword =
"";
1272 case IBIS_PARSER_CONTEXT::END:
1273 Report(
"Cannot change context after [END]" );
1277 Report(
"Changing context from an undefined context" );
1289 m_context = IBIS_PARSER_CONTEXT::COMPONENT;
1297 m_context = IBIS_PARSER_CONTEXT::MODELSELECTOR;
1298 m_continue = IBIS_PARSER_CONTINUE::MODELSELECTOR;
1312 else if(
compareIbisWord( aKeyword.c_str(),
"Define_Package_Model" ) )
1319 PM.m_resistanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1320 PM.m_capacitanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1321 PM.m_inductanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1323 PM.m_resistanceMatrix->m_dim = -1;
1324 PM.m_capacitanceMatrix->m_dim = -1;
1325 PM.m_inductanceMatrix->m_dim = -1;
1331 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL;
1337 m_context = IBIS_PARSER_CONTEXT::COMPONENT;
1342 m_context = IBIS_PARSER_CONTEXT::HEADER;
1349 std::string context_string;
1353 case IBIS_PARSER_CONTEXT::HEADER: context_string +=
"HEADER";
break;
1354 case IBIS_PARSER_CONTEXT::COMPONENT: context_string +=
"COMPONENT";
break;
1355 case IBIS_PARSER_CONTEXT::MODELSELECTOR: context_string +=
"MODEL_SELECTOR";
break;
1356 case IBIS_PARSER_CONTEXT::MODEL: context_string +=
"MODEL";
break;
1357 case IBIS_PARSER_CONTEXT::PACKAGEMODEL: context_string +=
"PACKAGE_MODEL";
break;
1358 case IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA: context_string +=
"PACKAGE_MODEL_MODEL_DATA";
break;
1359 default: context_string +=
"???";
break;
1362 std::stringstream message;
1363 message <<
_(
"Unknown keyword in " ) << context_string <<
_(
" context: " ) << aKeyword;
1417 if( !strcmp( str.c_str(),
"dV/dt_r" ) )
1421 else if( !strcmp( str.c_str(),
"dV/dt_f" ) )
1441 m_continue = IBIS_PARSER_CONTINUE::MODEL_SPEC;
1453 bool status =
false;
1468 status =
readWaveform(
nullptr, IBIS_WAVEFORM_TYPE::RISING );
1470 status =
readWaveform(
nullptr, IBIS_WAVEFORM_TYPE::FALLING );
1479 else if(
compareIbisWord( aKeyword.c_str(),
"POWER_Clamp_Reference" ) )
1499 m_continue = IBIS_PARSER_CONTINUE::PACKAGEMODEL_PINS;
1566 std::vector<std::string> values;
1571 for( i = 0; i < (int)values.size(); i++ )
1641 if( aDest !=
nullptr )
1643 if( aDest->m_type != IBIS_MATRIX_TYPE::BANDED && aDest->m_type != IBIS_MATRIX_TYPE::FULL
1644 && aDest->m_type != IBIS_MATRIX_TYPE::SPARSE )
1655 Report(
"Matrix pointer is null." );
1659 if(
m_continue != IBIS_PARSER_CONTINUE::MATRIX && status )
1670 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1678 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1687 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1710 Report(
_(
" Matrix is already init. But m_continue was not set ( internal error )" ) );
1715 if( aDest !=
nullptr )
1718 switch( aDest->m_type )
1720 case IBIS_MATRIX_TYPE::BANDED:
1724 case IBIS_MATRIX_TYPE::FULL:
1728 case IBIS_MATRIX_TYPE::SPARSE:
1732 case IBIS_MATRIX_TYPE::UNDEFINED:
1735 Report(
_(
"Tried to read a row from an undefined matrix" ) );
1740 Report(
_(
"matrix pointer is null" ) );
1779 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL;
1806 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA;
1834 std::string paramName;
1846 for(
size_t i = 0; i < aSubparam.size(); i++ )
1849 if( strcmp( paramName.c_str(), aSubparam.c_str() ) )
1894 std::string paramName;
1901 for(
size_t i = 0; i < aSubparam.size(); i++ )
1904 if( !strcmp( paramName.c_str(), aSubparam.c_str() ) )
1920 std::string subparam;
1926 case IBIS_PARSER_CONTINUE::MODEL:
1928 if( !strcmp( subparam.substr( 0, 10 ).c_str(),
"Model_type" ) )
1968 std::stringstream message;
1969 message <<
_(
"Unknown Model_type " ) << subparam;
1980 else if( !strcmp( subparam.substr( 0, 7 ).c_str(),
"Enable" ) )
1984 if( !strcmp( subparam.c_str(),
"Active-High" ) )
1986 else if( !strcmp( subparam.c_str(),
"Active-Low" ) )
1990 std::stringstream message;
1991 message <<
_(
"Unknown Enable: " ) << subparam;
2002 else if( subparam.substr( 0, 9 ) ==
"Polarity" )
2006 if( subparam ==
"Inverting" )
2008 else if( subparam ==
"Non-Inverting" )
2012 std::stringstream message;
2013 message <<
_(
"Unknown polarity " ) << subparam;
2047 Report(
_(
"Continued reading a model that did not begin. ( internal error )" ),
2158 if( str.size() > 0 )
2159 aDest.push_back( str );
2172 std::vector<std::string> fields;
2180 int extraArg = (
m_continue == IBIS_PARSER_CONTINUE::NONE ) ? 1 : 0;
2182 if( (
int)fields.size() == ( 4 + extraArg ) )
2186 if( fields.at( 0 ) ==
"R_pkg" )
2188 else if( fields.at( 0 ) ==
"L_pkg" )
2190 else if( fields.at( 0 ) ==
"C_pkg" )
2194 Report(
"Invalid field in [Package]" );
2197 status &=
parseDouble( cValue->
value[IBIS_CORNER::TYP], fields.at( 1 ),
true );
2204 if( fields.size() != 0 )
2211 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PACKAGE;
2221 std::vector<std::string> fields;
2228 if( ( fields.size() == 3 ) )
2230 if(
m_continue == IBIS_PARSER_CONTINUE::COMPONENT_PIN )
2232 pin.m_pinName = fields.at( 0 );
2233 pin.m_signalName = fields.at( 1 );
2234 pin.m_modelName = fields.at( 2 );
2248 if(
m_continue == IBIS_PARSER_CONTINUE::COMPONENT_PIN )
2250 pin.m_pinName = fields.at( 0 );
2251 pin.m_signalName = fields.at( 1 );
2252 pin.m_modelName = fields.at( 2 );
2258 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2260 Report(
_(
"Invalid pin entry: 6 values from a table with only 3." ),
2277 for(
int i = 3; i < 6; i++ )
2279 if( fields.at( i ) ==
"R_pin" )
2283 else if( fields.at( i ) ==
"L_pin" )
2287 else if( fields.at( i ) ==
"C_pin" )
2298 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2309 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PIN;
2320 std::vector<std::string> fields;
2326 if(
m_continue == IBIS_PARSER_CONTINUE::NONE )
2328 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PINMAPPING;
2332 if( fields.size() != 0 )
2334 if( fields.size() > 6 || fields.size() < 3 )
2342 pinMapping.
m_PDref = fields.at( 1 );
2343 pinMapping.
m_PUref = fields.at( 2 );
2345 if( fields.size() > 3 )
2348 if( fields.size() > 4 )
2351 if( fields.size() > 5 )
2352 pinMapping.
m_extRef = fields.at( 5 );
2369 if(
m_continue == IBIS_PARSER_CONTINUE::NONE )
2371 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN;
2448 if(
m_continue != IBIS_PARSER_CONTINUE::WAVEFORM )
2455 case IBIS_WAVEFORM_TYPE::FALLING:
2458 case IBIS_WAVEFORM_TYPE::RISING:
2468 if( aDest !=
nullptr )
2518 if( keyword.size() > 0 )
2520 if(
m_continue != IBIS_PARSER_CONTINUE::NONE )
2525 case IBIS_PARSER_CONTEXT::HEADER:
2528 case IBIS_PARSER_CONTEXT::COMPONENT:
2531 case IBIS_PARSER_CONTEXT::MODELSELECTOR:
2534 case IBIS_PARSER_CONTEXT::MODEL:
2537 case IBIS_PARSER_CONTEXT::PACKAGEMODEL:
2540 case IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA:
2560 case IBIS_PARSER_CONTINUE::STRING:
2565 case IBIS_PARSER_CONTINUE::COMPONENT_PACKAGE:
2568 case IBIS_PARSER_CONTINUE::COMPONENT_PIN:
2571 case IBIS_PARSER_CONTINUE::COMPONENT_PINMAPPING:
2574 case IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN:
2577 case IBIS_PARSER_CONTINUE::MODELSELECTOR:
2580 case IBIS_PARSER_CONTINUE::MODEL:
2583 case IBIS_PARSER_CONTINUE::IV_TABLE:
2586 case IBIS_PARSER_CONTINUE::VT_TABLE:
2589 case IBIS_PARSER_CONTINUE::WAVEFORM:
2592 case IBIS_PARSER_CONTINUE::RAMP:
2595 case IBIS_PARSER_CONTINUE::MODEL_SPEC:
2598 case IBIS_PARSER_CONTINUE::PACKAGEMODEL_PINS:
2601 case IBIS_PARSER_CONTINUE::MATRIX:
2604 case IBIS_PARSER_CONTINUE::NONE:
2614 while( ( c !=
'\n' ) && ( c != 0 ) )
void Report(const std::string &aMsg, SEVERITY aSeverity=RPT_SEVERITY_INFO) const
Print a message.
static std::string doubleToString(double aNumber)
Convert a double to string using scientific notation.
std::vector< double > m_data
bool Check() override
Check if the data held by the object is valid.
bool Check() override
Check if the data held by the object is valid.
std::vector< double > m_data
bool Check() override
Check if the data held by the object is valid.
std::vector< double > m_data
bool Check() override
Check if the data held by the object is valid.
double InterpolatedI(double aV, IBIS_CORNER aCorner) const
Interpolate the IV table.
std::vector< IVtableEntry > m_entries
std::string Spice(int aN, const std::string &aPort1, const std::string &aPort2, const std::string &aModelName, IBIS_CORNER aCorner) const
Interpolate the IV table.
bool Check() override
Check if the data held by the object is valid.
std::string m_GNDClampRef
std::string m_POWERClampRef
bool Check() override
Check if the data held by the object is valid.
std::string m_manufacturer
std::string m_packageModel
std::vector< IbisComponentPinMapping > m_pinMappings
IbisComponentPackage m_package
bool Check() override
Check if the data held by the object is valid.
std::vector< IbisComponentPin > m_pins
std::vector< IbisDiffPinEntry > m_entries
std::vector< IbisComponent > m_components
std::vector< IbisPackageModel > m_packageModels
std::vector< IbisModel > m_models
std::vector< IbisModelSelector > m_modelSelectors
std::string m_modelDescription
bool Check() override
Check if the data held by the object is valid.
std::vector< IbisModelSelectorEntry > m_models
TypMinMaxValue m_pullupReference
bool Check() override
Check if the data held by the object is valid.
std::vector< IbisWaveform * > m_risingWaveforms
TypMinMaxValue m_POWERClampReference
IBIS_MODEL_POLARITY m_polarity
IBIS_MODEL_ENABLE m_enable
TypMinMaxValue m_temperatureRange
std::vector< IbisWaveform * > m_fallingWaveforms
TypMinMaxValue m_pulldownReference
TypMinMaxValue m_GNDClampReference
TypMinMaxValue m_voltageRange
std::vector< std::string > m_pins
std::shared_ptr< IBIS_MATRIX > m_resistanceMatrix
std::shared_ptr< IBIS_MATRIX > m_inductanceMatrix
bool Check() override
Check if the data held by the object is valid.
std::string m_description
std::shared_ptr< IBIS_MATRIX > m_capacitanceMatrix
std::string m_manufacturer
std::vector< char > m_buffer
IBIS_PARSER_CONTINUE m_continue
bool changeCommentChar()
Ibis can change the character used for comments.
bool getNextLine()
Load the next line.
bool parseComponent(std::string &aKeyword)
Parse a single keyword in the component context.
bool parseModel(std::string &aKeyword)
Parse a single keyword in the model selector context.
bool readMatrixFull(std::string, IBIS_MATRIX_FULL &aDest)
VTtable * m_currentVTtable
bool isLineEmptyFromCursor()
void printLine()
Print the current line.
bool changeContext(std::string &aKeyword)
int m_currentMatrixRowIndex
bool parseDouble(double &aDest, std::string &aStr, bool aAllowModifiers=false)
Parse a double according to the ibis standard.
bool onNewLine()
Parse the current line.
bool readWord(std::string &aDest)
bool readTypMinMaxValue(TypMinMaxValue &aDest)
bool compareIbisWord(const std::string &a, const std::string &b)
compare two strings without being case sensitive
IbisComponent * m_currentComponent
std::shared_ptr< IBIS_MATRIX > m_currentMatrix
bool readDvdt(std::string &aString, dvdt &aDest)
bool ParseFile(const std::string &aFileName)
Parse a file.
std::string * m_continuingString
IbisModel * m_currentModel
bool parsePackageModelModelData(std::string &)
Parse a single keyword in the package model context.
IbisPackageModel * m_currentPackageModel
bool readDouble(double &aDest)
IbisModelSelector * m_currentModelSelector
bool parsePackageModel(std::string &aKeyword)
Parse a single keyword in the model context.
bool readString(std::string &aDest)
bool readTypMinMaxValueSubparam(const std::string &aSubparam, TypMinMaxValue &aDest)
bool readMatrixBanded(std::string, IBIS_MATRIX_BANDED &aDest)
bool readNumericSubparam(const std::string &aSubparam, double &aDest)
bool readMatrix(std::shared_ptr< IBIS_MATRIX > aDest)
IBIS_PARSER_CONTEXT m_context
IVtable * m_currentIVtable
bool readIVtableEntry(IVtable &aTable)
bool readVTtableEntry(VTtable &aTable)
bool parseModelSelector(std::string &aKeyword)
Parse a single keyword in the component context.
bool storeString(std::string &aDest, bool aMultiline)
bool readPackageModelPins()
bool readRampdvdt(dvdtTypMinMax &aDest)
bool readTableLine(std::vector< std::string > &aDest)
bool readMatrixSparse(std::string, IBIS_MATRIX_SPARSE &aDest)
bool parseHeader(std::string &aKeyword)
Parse a single keyword in the header context.
bool readWaveform(IbisWaveform *aDest, IBIS_WAVEFORM_TYPE aType)
IbisWaveform * m_currentWaveform
bool Check() override
Check if the data held by the object is valid.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
bool Check() override
Check if the data held by the object is valid.
std::vector< VTtableEntry > m_entries
bool Check() override
Check if the data held by the object is valid.
bool isNumberNA(double aNumber)
#define IBIS_MAX_LINE_LENGTH
static std::string strValue(double aValue)