53 return std::equal( stra.begin(), stra.end(),
54 strb.begin(), strb.end(),
57 return std::tolower(a) == std::tolower(b);
79 if( std::isnan(
m_data[i] ) )
102 if( std::isnan(
m_data[i] ) )
125 if( std::isnan(
m_data[i] ) )
139 return std::memcmp( &aNumber, &
NA,
sizeof NA ) == 0;
146 if( std::isnan(
value[IBIS_CORNER::TYP] ) )
185 std::stringstream message;
246 std::stringstream message;
247 message <<
_(
"Checking component " ) <<
m_name;
287 status &=
pin.Check();
302 std::ostringstream ss;
303 ss.setf( std::ios_base::scientific, std::ios_base::floatfield );
309std::string
IVtable::Spice(
int aN,
const std::string& aPort1,
const std::string& aPort2,
310 const std::string& aModelName,
IBIS_CORNER aCorner )
const
312 std::string result =
"";
317 result += std::to_string( aN );
327 result += aModelName;
331 result += aModelName;
332 result +=
" pwl(\n+ x_array=[";
339 result +=
"]\n+ y_array=[";
346 result +=
"]\n+ input_domain=0.05 fraction=TRUE)\n\n";
359 return m_entries.back().I.value[aCorner];
364 return m_entries.at( 0 ).I.value[aCorner];
367 for(
size_t i = 1; i <
m_entries.size(); i++ )
371 return m_entries.at( i - 1 ).I.value[aCorner]
373 -
m_entries.at( i - 1 ).I.value[aCorner] )
394 if( std::isnan( entry.V ) )
401 if( !entry.I.Check() )
420 if( std::isnan(
value[IBIS_CORNER::TYP].m_dv ) )
422 if( std::isnan(
value[IBIS_CORNER::TYP].m_dt ) )
474 std::stringstream message;
475 message <<
_(
"Checking model " ) <<
m_name;
477 if(
m_type == IBIS_MODEL_TYPE::UNDEFINED)
596 if(
m_type != IBIS_MODEL_TYPE::INPUT_ECL &&
m_type != IBIS_MODEL_TYPE::INPUT_STD
597 &&
m_type != IBIS_MODEL_TYPE::TERMINATOR &&
m_type != IBIS_MODEL_TYPE::SERIES
598 &&
m_type != IBIS_MODEL_TYPE::SERIES_SWITCH )
612 std::stringstream message;
613 message <<
_(
"Checking Header..." );
653 if( !( !strcmp( ext.c_str(),
".ibs" ) || !strcmp( ext.c_str(),
".pkg" )
654 || !strcmp( ext.c_str(),
".ebd" ) || !strcmp( ext.c_str(),
".ims" ) ) )
677 std::stringstream message;
678 message <<
_(
"Checking package model " ) <<
m_name;
716 for(
size_t i = 0; i <
m_pins.size(); i++ )
718 if(
m_pins.at( i ).empty() )
801 std::stringstream err_msg;
803 std::ifstream ibisFile;
804 ibisFile.open( aFileName );
806 if( !ibisFile.is_open() )
808 err_msg <<
_(
"Cannot open file " ) << aFileName;
813 std::ostringstream ss;
814 ss << ibisFile.rdbuf();
815 const std::string& s = ss.str();
816 m_buffer = std::vector<char>( s.begin(), s.end() );
844 err_msg <<
_(
"Error on line " ) << std::to_string(
m_lineCounter );
848 if(
m_context == IBIS_PARSER_CONTEXT::END )
895 if( aString ==
"NA" )
905 for( i = 1; i < (int)aString.length(); i++ )
907 if( aString.at( i ) ==
'/' )
913 if( aString.at( i ) ==
'/' )
915 std::string str1 = aString.substr( 0, i );
916 std::string str2 = aString.substr( i + 1, aString.size() - i - 1 );
935 bool converted =
false;
937 std::string str = aStr;
951 result = std::stod( str, &size );
961 if( converted && ( size < str.length() ) )
963 switch(
static_cast<char>( str.at( size ) ) )
965 case 'T': result *= 1e12;
break;
966 case 'G': result *= 1e9;
break;
967 case 'M': result *= 1e6;
break;
968 case 'k': result *= 1e3;
break;
969 case 'm': result *= 1e-3;
break;
970 case 'u': result *= 1e-6;
break;
971 case 'n': result *= 1e-9;
break;
972 case 'p': result *= 1e-12;
break;
973 case 'f': result *= 1e-15;
break;
1017 while( c != 0 && c !=
'\n' )
1039 std::cout << std::endl;
1076 result = std::stoi( str, &size );
1091 if( size != str.size() )
1121 aDest = std::string( start, end );
1123 return ( aDest.size() > 0 );
1134 int len = aDest.length();
1142 char c = aDest[len - 1];
1145 while( isspace( c ) && ( i < len ) )
1147 c = aDest[len - 1 - i];
1150 aDest = aDest.substr( 0, len - i + 1 );
1163 m_continue = aMultiline ? IBIS_PARSER_CONTINUE::STRING : IBIS_PARSER_CONTINUE::NONE;
1175 std::string strChar =
"";
1183 if( !( c ==
'!' || c ==
'"' || c ==
'#' || c ==
'$' || c ==
'%' || c ==
'&' || c ==
'\''
1184 || c ==
'(' || c ==
')' || c ==
'*' || c ==
',' || c ==
':' || c ==
';' || c ==
'<'
1185 || c ==
'>' || c ==
'?' || c ==
'@' || c ==
'\\' || c ==
'^' || c ==
'`' || c ==
'{'
1186 || c ==
'|' || c ==
'}' || c ==
'~' || c ==
')' ) )
1193 while( ( !isspace( c ) ) && c != 0 && c !=
'\n' )
1199 if( strChar !=
"_char" )
1205 while( isspace( c ) && c != 0 && c !=
'\n' && c != d )
1210 if( ( !isspace( c ) ) && c != d )
1226 std::string keyword =
"";
1271 case IBIS_PARSER_CONTEXT::END:
1272 Report(
"Cannot change context after [END]" );
1276 default:
Report(
"Changing context from an undefined context" );
1288 m_context = IBIS_PARSER_CONTEXT::COMPONENT;
1296 m_context = IBIS_PARSER_CONTEXT::MODELSELECTOR;
1297 m_continue = IBIS_PARSER_CONTINUE::MODELSELECTOR;
1311 else if(
compareIbisWord( aKeyword.c_str(),
"Define_Package_Model" ) )
1318 PM.m_resistanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1319 PM.m_capacitanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1320 PM.m_inductanceMatrix->m_type = IBIS_MATRIX_TYPE::UNDEFINED;
1322 PM.m_resistanceMatrix->m_dim = -1;
1323 PM.m_capacitanceMatrix->m_dim = -1;
1324 PM.m_inductanceMatrix->m_dim = -1;
1330 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL;
1336 m_context = IBIS_PARSER_CONTEXT::COMPONENT;
1341 m_context = IBIS_PARSER_CONTEXT::HEADER;
1348 std::string context_string;
1352 case IBIS_PARSER_CONTEXT::HEADER: context_string +=
"HEADER";
break;
1353 case IBIS_PARSER_CONTEXT::COMPONENT: context_string +=
"COMPONENT";
break;
1354 case IBIS_PARSER_CONTEXT::MODELSELECTOR: context_string +=
"MODEL_SELECTOR";
break;
1355 case IBIS_PARSER_CONTEXT::MODEL: context_string +=
"MODEL";
break;
1356 case IBIS_PARSER_CONTEXT::PACKAGEMODEL: context_string +=
"PACKAGE_MODEL";
break;
1357 case IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA:
1358 context_string +=
"PACKAGE_MODEL_MODEL_DATA";
1360 default: context_string +=
"???";
break;
1363 std::stringstream message;
1364 message <<
_(
"Unknown keyword in " ) << context_string <<
_(
" context: " ) << aKeyword;
1420 if( !strcmp( str.c_str(),
"dV/dt_r" ) )
1424 else if( !strcmp( str.c_str(),
"dV/dt_f" ) )
1443 m_continue = IBIS_PARSER_CONTINUE::MODEL_SPEC;
1455 bool status =
false;
1470 status =
readWaveform(
nullptr, IBIS_WAVEFORM_TYPE::RISING );
1472 status =
readWaveform(
nullptr, IBIS_WAVEFORM_TYPE::FALLING );
1481 else if(
compareIbisWord( aKeyword.c_str(),
"POWER_Clamp_Reference" ) )
1502 m_continue = IBIS_PARSER_CONTINUE::PACKAGEMODEL_PINS;
1568 std::vector<std::string> values;
1572 for( i = 0; i < (int)values.size(); i++ )
1643 if( aDest !=
nullptr )
1645 if( aDest->m_type != IBIS_MATRIX_TYPE::BANDED && aDest->m_type != IBIS_MATRIX_TYPE::FULL
1646 && aDest->m_type != IBIS_MATRIX_TYPE::SPARSE )
1657 Report(
"Matrix pointer is null." );
1661 if(
m_continue != IBIS_PARSER_CONTINUE::MATRIX && status )
1672 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1680 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1689 aDest =
static_cast<std::shared_ptr<IBIS_MATRIX>
>( matrix );
1712 Report(
_(
" Matrix is already init. But m_continue was not set ( internal error )" ) );
1717 if( aDest !=
nullptr )
1720 switch( aDest->m_type )
1722 case IBIS_MATRIX_TYPE::BANDED:
1726 case IBIS_MATRIX_TYPE::FULL:
1730 case IBIS_MATRIX_TYPE::SPARSE:
1734 case IBIS_MATRIX_TYPE::UNDEFINED:
1738 Report(
_(
"Tried to read a row from an undefined matrix" ) );
1744 Report(
_(
"matrix pointer is null" ) );
1781 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL;
1810 m_context = IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA;
1840 std::string paramName;
1853 for(
size_t i = 0; i < aSubparam.size(); i++ )
1858 if( strcmp( paramName.c_str(), aSubparam.c_str() ) )
1905 std::string paramName;
1912 for(
size_t i = 0; i < aSubparam.size(); i++ )
1917 if( !strcmp( paramName.c_str(), aSubparam.c_str() ) )
1938 std::string subparam;
1943 case IBIS_PARSER_CONTINUE::MODEL:
1945 if( !strcmp( subparam.substr( 0, 10 ).c_str(),
"Model_type" ) )
1985 std::stringstream message;
1986 message <<
_(
"Unknown Model_type " ) << subparam;
1997 else if( !strcmp( subparam.substr( 0, 7 ).c_str(),
"Enable" ) )
2001 if( !strcmp( subparam.c_str(),
"Active-High" ) )
2003 else if( !strcmp( subparam.c_str(),
"Active-Low" ) )
2007 std::stringstream message;
2008 message <<
_(
"Unknown Enable: " ) << subparam;
2019 else if( subparam.substr( 0, 9 ) ==
"Polarity" )
2023 if( subparam ==
"Inverting" )
2025 else if( subparam ==
"Non-Inverting" )
2029 std::stringstream message;
2030 message <<
_(
"Unknown polarity " ) << subparam;
2067 Report(
_(
"Continued reading a model that did not begin. ( internal error )" ),
2184 if( str.size() > 0 )
2186 aDest.push_back( str );
2200 std::vector<std::string> fields;
2208 int extraArg = (
m_continue == IBIS_PARSER_CONTINUE::NONE ) ? 1 : 0;
2210 if( (
int)fields.size() == ( 4 + extraArg ) )
2214 if( fields.at( 0 ) ==
"R_pkg" )
2216 else if( fields.at( 0 ) ==
"L_pkg" )
2218 else if( fields.at( 0 ) ==
"C_pkg" )
2222 Report(
"Invalid field in [Package]" );
2225 status &=
parseDouble( cValue->
value[IBIS_CORNER::TYP], fields.at( 1 ),
true );
2232 if( fields.size() != 0 )
2238 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PACKAGE;
2248 std::vector<std::string> fields;
2255 if( ( fields.size() == 3 ) )
2257 if(
m_continue == IBIS_PARSER_CONTINUE::COMPONENT_PIN )
2259 pin.m_pinName = fields.at( 0 );
2260 pin.m_signalName = fields.at( 1 );
2261 pin.m_modelName = fields.at( 2 );
2275 if(
m_continue == IBIS_PARSER_CONTINUE::COMPONENT_PIN )
2277 pin.m_pinName = fields.at( 0 );
2278 pin.m_signalName = fields.at( 1 );
2279 pin.m_modelName = fields.at( 2 );
2285 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2287 Report(
_(
"Invalid pin entry: 6 values from a table with only 3." ),
2304 for(
int i = 3; i < 6; i++ )
2306 if( fields.at( i ) ==
"R_pin" )
2310 else if( fields.at( i ) ==
"L_pin" )
2314 else if( fields.at( i ) ==
"C_pin" )
2325 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2335 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PIN;
2346 std::vector<std::string> fields;
2352 if(
m_continue == IBIS_PARSER_CONTINUE::NONE )
2354 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_PINMAPPING;
2358 if( fields.size() != 0 )
2360 if( fields.size() > 6 || fields.size() < 3 )
2368 pinMapping.
m_PDref = fields.at( 1 );
2369 pinMapping.
m_PUref = fields.at( 2 );
2371 if( fields.size() > 3 )
2374 if( fields.size() > 4 )
2377 if( fields.size() > 5 )
2378 pinMapping.
m_extRef = fields.at( 5 );
2394 if(
m_continue == IBIS_PARSER_CONTINUE::NONE )
2396 m_continue = IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN;
2478 if(
m_continue != IBIS_PARSER_CONTINUE::WAVEFORM )
2492 if( aDest !=
nullptr )
2543 if( keyword.size() > 0 )
2546 if(
m_continue != IBIS_PARSER_CONTINUE::NONE )
2552 case IBIS_PARSER_CONTEXT::HEADER: status &=
parseHeader( keyword );
break;
2553 case IBIS_PARSER_CONTEXT::COMPONENT: status &=
parseComponent( keyword );
break;
2554 case IBIS_PARSER_CONTEXT::MODELSELECTOR: status &=
parseModelSelector( keyword );
break;
2555 case IBIS_PARSER_CONTEXT::MODEL: status &=
parseModel( keyword );
break;
2556 case IBIS_PARSER_CONTEXT::PACKAGEMODEL: status &=
parsePackageModel( keyword );
break;
2557 case IBIS_PARSER_CONTEXT::PACKAGEMODEL_MODELDATA:
2579 case IBIS_PARSER_CONTINUE::STRING:
2584 case IBIS_PARSER_CONTINUE::COMPONENT_PACKAGE: status &=
readPackage();
break;
2585 case IBIS_PARSER_CONTINUE::COMPONENT_PIN: status &=
readPin();
break;
2586 case IBIS_PARSER_CONTINUE::COMPONENT_PINMAPPING: status &=
readPinMapping();
break;
2587 case IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN: status &=
readDiffPin();
break;
2589 case IBIS_PARSER_CONTINUE::MODEL: status &=
readModel();
break;
2592 case IBIS_PARSER_CONTINUE::WAVEFORM:
2595 case IBIS_PARSER_CONTINUE::RAMP: status &=
readRamp();
break;
2596 case IBIS_PARSER_CONTINUE::MODEL_SPEC: status &=
readModelSpec();
break;
2599 case IBIS_PARSER_CONTINUE::NONE:
2608 while( ( c !=
'\n' ) && ( c != 0 ) )
void Report(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)