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." );
2572 if( str.size() > 0 )
2573 aDest.push_back( str );
2586 std::vector<std::string> fields;
2596 if( (
int)fields.size() == ( 4 + extraArg ) )
2600 if( fields.at( 0 ) ==
"R_pkg" )
2602 else if( fields.at( 0 ) ==
"L_pkg" )
2604 else if( fields.at( 0 ) ==
"C_pkg" )
2608 Report(
"Invalid field in [Package]" );
2618 if( fields.size() != 0 )
2635 std::vector<std::string> fields;
2642 if( ( fields.size() == 3 ) )
2646 pin.m_pinName = fields.at( 0 );
2647 pin.m_signalName = fields.at( 1 );
2648 pin.m_modelName = fields.at( 2 );
2662 pin.m_pinName = fields.at( 0 );
2663 pin.m_signalName = fields.at( 1 );
2664 pin.m_modelName = fields.at( 2 );
2670 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2672 Report(
_(
"Invalid pin entry: 6 values from a table with only 3." ),
2689 for(
int i = 3; i < 6; i++ )
2691 if( fields.at( i ) ==
"R_pin" )
2695 else if( fields.at( i ) ==
"L_pin" )
2699 else if( fields.at( i ) ==
"C_pin" )
2710 if(
pin.m_Rcol == 0 ||
pin.m_Lcol == 0 ||
pin.m_Ccol == 0 )
2732 std::vector<std::string> fields;
2744 if( fields.size() != 0 )
2746 if( fields.size() > 6 || fields.size() < 3 )
2754 pinMapping.
m_PDref = fields.at( 1 );
2755 pinMapping.
m_PUref = fields.at( 2 );
2757 if( fields.size() > 3 )
2760 if( fields.size() > 4 )
2763 if( fields.size() > 5 )
2764 pinMapping.
m_extRef = fields.at( 5 );
2815 std::vector<std::string> fields;
2822 else if( !fields.empty() )
2826 if( fields.size() >= 3 )
2828 mapping.
m_pin1 = fields.at( 0 );
2829 mapping.
m_pin2 = fields.at( 1 );
2832 if( fields.size() > 3 )
2917 wxLogMessage(
"Invalid waveform type: %i", (
int) aType );
2931 wxLogMessage(
"Invalid waveform type: %i", (
int) aType );
2936 wxLogMessage(
"Invalid context for waveform: %i", (
int)
m_context );
2942 if( aDest !=
nullptr )
2992 if( keyword.size() > 0 )
3112 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.
One row of a [Series Pin Mapping] table (IBIS 4.1+).
std::string m_functionTableGroup
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 readSeriesPinMapping()
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)
@ COMPONENT_SERIES_PIN_MAPPING
#define IBIS_MAX_LINE_LENGTH
static std::string strValue(double aValue)
wxString result
Test unit parsing edge cases and error handling.