54 return std::equal( stra.begin(), stra.end(),
55 strb.begin(), strb.end(),
58 return std::tolower(a) == std::tolower(b);
71 for(
size_t i = 0; i <
m_data.size(); i++ )
73 if( std::isnan(
m_data[i] ) )
87 return std::memcmp( &aNumber, &
NA,
sizeof NA ) == 0;
163 std::stringstream message;
229 std::stringstream message;
230 message <<
_(
"Checking component " ) <<
m_name;
269 status &=
pin.Check();
283 std::ostringstream ss;
284 ss.setf( std::ios_base::scientific, std::ios_base::floatfield );
290std::string
IVtable::Spice(
int aN,
const std::string& aPort1,
const std::string& aPort2,
bool aNegateI,
291 const std::string& aModelName,
IBIS_CORNER aCorner )
const
298 result += std::to_string( aN );
304 result += aNegateI ? aPort2 : aPort1;
306 result += aNegateI ? aPort1 : aPort2;
313 result +=
" pwl(\n+ x_array=[";
324 result +=
"]\n+ y_array=[";
335 result +=
"]\n+ input_domain=0.05 fraction=TRUE)\n\n";
347 return m_entries.back().I.value[aCorner];
350 return m_entries.at( 0 ).I.value[aCorner];
352 for(
size_t i = 1; i <
m_entries.size(); i++ )
356 return m_entries.at( i - 1 ).I.value[aCorner]
358 -
m_entries.at( i - 1 ).I.value[aCorner] )
381 if( std::isnan( entry.V ) )
388 if( !entry.I.Check() )
466 std::stringstream message;
467 message <<
_(
"Checking model " ) <<
m_name;
715 std::stringstream message;
716 message <<
_(
"Checking submodel " ) <<
m_name;
788 std::stringstream err_msg;
793 default: wxLogMessage(
"Invalid submodel type: %i", (
int)
m_type );
return false;
795 err_msg <<
_(
" submodels are not yet supported." );
812 std::stringstream message;
813 message <<
_(
"Checking Header..." );
853 if( !( !strcmp( ext.c_str(),
".ibs" ) || !strcmp( ext.c_str(),
".pkg" )
854 || !strcmp( ext.c_str(),
".ebd" ) || !strcmp( ext.c_str(),
".ims" ) ) )
876 std::stringstream message;
877 message <<
_(
"Checking package model " ) <<
m_name;
989 std::stringstream err_msg;
991 std::ifstream ibisFile;
992 ibisFile.open( aFileName );
994 if( !ibisFile.is_open() )
996 err_msg <<
_(
"Cannot open file " ) << aFileName;
1001 std::ostringstream ss;
1002 ss << ibisFile.rdbuf();
1003 const std::string& s = ss.str();
1004 m_buffer = std::vector<char>( s.begin(), s.end() );
1030 err_msg <<
_(
"Error on line " ) << std::to_string(
m_lineCounter );
1048 err_msg << submodel.
m_name <<
_(
" submodel not found." );
1098 if( aString ==
"NA" )
1108 for( i = 1; i < (int)aString.length(); i++ )
1110 if( aString.at( i ) ==
'/' )
1114 if( aString.at( i ) ==
'/' )
1116 std::string str1 = aString.substr( 0, i );
1117 std::string str2 = aString.substr( i + 1, aString.size() - i - 1 );
1136 std::stringstream message;
1137 message << str <<
_(
" is not a valid dV/dt value." );
1159 bool converted =
false;
1161 std::string str = aStr;
1175 result = std::stod( str, &size );
1185 if( converted && ( size < str.length() ) )
1187 switch(
static_cast<char>( str.at( size ) ) )
1189 case 'T':
result *= 1e12;
break;
1190 case 'G':
result *= 1e9;
break;
1191 case 'M':
result *= 1e6;
break;
1192 case 'k':
result *= 1e3;
break;
1193 case 'm':
result *= 1e-3;
break;
1194 case 'u':
result *= 1e-6;
break;
1195 case 'n':
result *= 1e-9;
break;
1196 case 'p':
result *= 1e-12;
break;
1197 case 'f':
result *= 1e-15;
break;
1242 while( c != 0 && c !=
'\n' )
1261 std::cout << std::endl;
1298 result = std::stoi( str, &size );
1313 if( size != str.size() )
1341 aDest = std::string( start,
end );
1343 return ( aDest.size() > 0 );
1352 int len = aDest.length();
1357 char c = aDest[len - 1];
1360 while( isspace( c ) && ( i < len ) )
1362 c = aDest[len - 1 - i];
1366 aDest = aDest.substr( 0, len - i + 1 );
1391 std::string strChar =
"";
1399 if( !( c ==
'!' || c ==
'"' || c ==
'#' || c ==
'$' || c ==
'%' || c ==
'&' || c ==
'\''
1400 || c ==
'(' || c ==
')' || c ==
'*' || c ==
',' || c ==
':' || c ==
';' || c ==
'<'
1401 || c ==
'>' || c ==
'?' || c ==
'@' || c ==
'\\' || c ==
'^' || c ==
'`' || c ==
'{'
1402 || c ==
'|' || c ==
'}' || c ==
'~' || c ==
')' ) )
1409 while( ( !isspace( c ) ) && c != 0 && c !=
'\n' )
1415 if( strChar !=
"_char" )
1421 while( isspace( c ) && c != 0 && c !=
'\n' && c != d )
1424 if( ( !isspace( c ) ) && c != d )
1439 std::string keyword =
"";
1485 Report(
"Cannot change context after [END]" );
1489 Report(
"Changing context from an undefined context" );
1532 std::stringstream message;
1533 message <<
_(
"Submodel name is not unique: " ) <<
model.m_name;
1542 else if(
compareIbisWord( aKeyword.c_str(),
"Define_Package_Model" ) )
1571 std::string context_string;
1581 default: context_string +=
"???";
break;
1584 std::stringstream message;
1585 message <<
_(
"Unknown keyword in " ) << context_string <<
_(
" context: " ) << aKeyword;
1635 wxLogMessage(
"Invalid context for ramp: %i.", (
int)
m_context );
1645 if( !strcmp( str.c_str(),
"dV/dt_r" ) )
1649 else if( !strcmp( str.c_str(),
"dV/dt_f" ) )
1733 Report(
_(
"The submodel name is missing." ) );
1740 Report(
_(
"The submodel mode is missing." ) );
1745 if( !strcmp( str.c_str(),
"All" ) )
1749 else if( !strcmp( str.c_str(),
"Driving" ) )
1753 else if( !strcmp( str.c_str(),
"Non-Driving" ) )
1759 std::stringstream message;
1760 message << str <<
_(
" is not a recognised submodel mode." );
1774 bool status =
false;
1808 else if(
compareIbisWord( aKeyword.c_str(),
"POWER_Clamp_Reference" ) )
1844 std::string subparam;
1847 if( !strcmp( subparam.c_str(),
"Off_delay" ) )
1849 else if( !strcmp( subparam.c_str(),
"V_trigger_r" ) )
1851 else if( !strcmp( subparam.c_str(),
"V_trigger_f" ) )
1855 std::stringstream message;
1856 message << subparam <<
_(
" is not a recognised Submodel Spec subparameter." );
1868 bool status =
false;
1915 Report(
_(
"Missing pin name/number for matrix row." ) );
1921 Report(
_(
"Invalid pin name/number in matrix row." ) );
1924 aDest =
pin->second;
1959 std::stringstream message;
1960 message << str <<
_(
" is not a recognised matrix type." );
1987 bool status =
readInt( bandwidth );
2030 std::vector<std::string> values;
2033 for(
size_t i = 0; i < values.size(); i++ )
2096 wxLogMessage(
"Invalid matrix type: %i", (
int)
m_currentMatrix->m_type );
2102 wxLogMessage(
"Matrix pointer is null" );
2188 std::string paramName;
2200 for(
size_t i = 0; i < aSubparam.size(); i++ )
2203 if( strcmp( paramName.c_str(), aSubparam.c_str() ) )
2248 std::string paramName;
2255 for(
size_t i = 0; i < aSubparam.size(); i++ )
2274 std::string subparam;
2282 if( !strcmp( subparam.substr( 0, 10 ).c_str(),
"Model_type" ) )
2322 std::stringstream message;
2323 message <<
_(
"Unknown Model_type " ) << subparam;
2334 else if( !strcmp( subparam.substr( 0, 7 ).c_str(),
"Enable" ) )
2338 if( !strcmp( subparam.c_str(),
"Active-High" ) )
2340 else if( !strcmp( subparam.c_str(),
"Active-Low" ) )
2344 std::stringstream message;
2345 message <<
_(
"Unknown Enable: " ) << subparam;
2356 else if( subparam.substr( 0, 9 ) ==
"Polarity" )
2360 if( subparam ==
"Inverting" )
2362 else if( subparam ==
"Non-Inverting" )
2366 std::stringstream message;
2367 message <<
_(
"Unknown polarity " ) << subparam;
2413 Report(
_(
"Continued reading a model that did not begin. ( internal error )" ),
2426 std::string subparam;
2429 if( !strcmp( subparam.c_str(),
"Submodel_type" ) )
2433 if( !strcmp( subparam.c_str(),
"Dynamic_clamp" ) )
2435 else if( !strcmp( subparam.c_str(),
"Bus_hold" ) )
2437 else if( !strcmp( subparam.c_str(),
"Fall_back" ) )
2441 std::stringstream message;
2442 message << subparam <<
_(
" is not a recognised submodel type." );
2455 std::stringstream message;
2456 message << subparam <<
_(
" is not a recognised Submodel subparameter." );
2568 if( str.size() > 0 )
2569 aDest.push_back( str );
2582 std::vector<std::string> fields;
2592 if( (
int)fields.size() == ( 4 + extraArg ) )
2596 if( fields.at( 0 ) ==
"R_pkg" )
2598 else if( fields.at( 0 ) ==
"L_pkg" )
2600 else if( fields.at( 0 ) ==
"C_pkg" )
2604 Report(
"Invalid field in [Package]" );
2614 if( fields.size() != 0 )
2631 std::vector<std::string> fields;
2638 if( ( fields.size() == 3 ) )
2642 pin.m_pinName = fields.at( 0 );
2643 pin.m_signalName = fields.at( 1 );
2644 pin.m_modelName = fields.at( 2 );
2658 pin.m_pinName = fields.at( 0 );
2659 pin.m_signalName = fields.at( 1 );
2660 pin.m_modelName = fields.at( 2 );
2666 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2668 Report(
_(
"Invalid pin entry: 6 values from a table with only 3." ),
2685 for(
int i = 3; i < 6; i++ )
2687 if( fields.at( i ) ==
"R_pin" )
2691 else if( fields.at( i ) ==
"L_pin" )
2695 else if( fields.at( i ) ==
"C_pin" )
2706 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2728 std::vector<std::string> fields;
2740 if( fields.size() != 0 )
2742 if( fields.size() > 6 || fields.size() < 3 )
2750 pinMapping.
m_PDref = fields.at( 1 );
2751 pinMapping.
m_PUref = fields.at( 2 );
2753 if( fields.size() > 3 )
2756 if( fields.size() > 4 )
2759 if( fields.size() > 5 )
2760 pinMapping.
m_extRef = fields.at( 5 );
2873 wxLogMessage(
"Invalid waveform type: %i", (
int) aType );
2887 wxLogMessage(
"Invalid waveform type: %i", (
int) aType );
2892 wxLogMessage(
"Invalid context for waveform: %i", (
int)
m_context );
2898 if( aDest !=
nullptr )
2948 if( keyword.size() > 0 )
3065 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.
double InterpolatedI(double aV, IBIS_CORNER aCorner) const
Interpolate the IV table.
std::string Spice(int aN, const std::string &aPort1, const std::string &aPort2, bool aNegateI, const std::string &aModelName, IBIS_CORNER aCorner) const
Interpolate the IV table.
std::vector< IVtableEntry > m_entries
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
IbisComponentPackage m_package
bool Check() override
Check if the data held by the object is valid.
std::vector< IbisComponentPin > m_pins
bool Check() override
Check if the data held by the object is valid.
TypMinMaxValue m_C_comp_pullup
TypMinMaxValue m_C_comp_power_clamp
TypMinMaxValue m_pullupReference
TypMinMaxValue m_C_comp_pulldown
TypMinMaxValue m_C_comp_gnd_clamp
bool Check() override
Check if the data held by the object is valid.
TypMinMaxValue m_POWERClampReference
IVtable m_compositeCurrent
TypMinMaxValue m_temperatureRange
TypMinMaxValue m_pulldownReference
TypMinMaxValue m_GNDClampReference
TypMinMaxValue m_voltageRange
std::map< std::string, int > 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::shared_ptr< IBIS_MATRIX > m_capacitanceMatrix
std::string m_manufacturer
bool parseSubmodel(std::string &aKeyword)
Parse a single keyword in the submodel context.
std::vector< char > m_buffer
bool readAlgorithmicModel()
bool readMatrixBandedOrFull()
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 context.
VTtable * m_currentVTtable
bool readMatrixBandwidth()
bool parsePackageModelModelData(std::string &aKeyword)
Parse a single keyword in the package model model data context.
bool isLineEmptyFromCursor()
void printLine()
Print the current line.
bool changeContext(std::string &aKeyword)
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
bool readDvdt(dvdt &aDest)
IbisComponent * m_currentComponent
std::shared_ptr< IBIS_MATRIX > m_currentMatrix
IbisSubmodel * m_currentSubmodel
bool ParseFile(const std::string &aFileName)
Parse a file.
bool readMatrixType(std::shared_ptr< IBIS_MATRIX > &aDest)
std::string * m_continuingString
IbisModel * m_currentModel
bool parseDvdt(dvdt &aDest, std::string &aStr)
Parse a dV/dt value according to the ibis standard.
IbisPackageModel * m_currentPackageModel
bool readDouble(double &aDest)
IbisModelSelector * m_currentModelSelector
bool parsePackageModel(std::string &aKeyword)
Parse a single keyword in the package model context.
bool readString(std::string &aDest)
bool readTypMinMaxValueSubparam(const std::string &aSubparam, TypMinMaxValue &aDest)
bool parseAlgorithmicModel(std::string &aKeyword)
Parse a single keyword in the algorithmic model context.
bool readNumericSubparam(const std::string &aSubparam, double &aDest)
bool readMatrixPinIndex(int &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 model selector context.
bool readReceiverThresholds()
bool storeString(std::string &aDest, bool aMultiline)
bool readPackageModelPins()
bool readRampdvdt(dvdtTypMinMax &aDest)
bool readTableLine(std::vector< std::string > &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.
TypMinMaxValue m_VtriggerR
bool Check() override
Check if the data held by the object is valid.
IBIS_SUBMODEL_TYPE m_type
TypMinMaxValue m_offDelay
TypMinMaxValue m_VtriggerF
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
TypMinMaxValue(REPORTER *aReporter)
bool Check() override
Check if the data held by the object is valid.
void Add(const TypMinMaxValue &aValue)
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)
wxString result
Test unit parsing edge cases and error handling.