Ibis: Coverity issues

This commit is contained in:
Fabien Corona 2022-06-13 19:31:57 +00:00 committed by Seth Hillbrand
parent 9fd5ee5a2f
commit bf62d6e9ee
4 changed files with 281 additions and 275 deletions

View File

@ -144,17 +144,17 @@ bool IbisComponentPackage::Check()
{ {
bool status = true; bool status = true;
if( !m_Rpkg->Check() ) if( !m_Rpkg.Check() )
{ {
Report( _( "Invalid R_pkg value." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid R_pkg value." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_Lpkg->Check() ) if( !m_Lpkg.Check() )
{ {
Report( _( "Invalid L_pkg value." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid L_pkg value." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_Cpkg->Check() ) if( !m_Cpkg.Check() )
{ {
Report( _( "Invalid C_pkg value." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid C_pkg value." ), RPT_SEVERITY_ERROR );
status = false; status = false;
@ -298,7 +298,7 @@ std::string IVtable::Spice( int aN, std::string aPort1, std::string aPort2, std:
for( IVtableEntry& entry : m_entries ) for( IVtableEntry& entry : m_entries )
{ {
result += doubleToString( entry.I->value[aCorner] ); result += doubleToString( entry.I.value[aCorner] );
result += " "; result += " ";
} }
result += "]\n+ input_domain=0.05 fraction=TRUE)\n\n"; result += "]\n+ input_domain=0.05 fraction=TRUE)\n\n";
@ -314,21 +314,21 @@ double IVtable::InterpolatedI( double aV, IBIS_CORNER aCorner )
{ {
if( aV >= m_entries.back().V ) if( aV >= m_entries.back().V )
{ {
return m_entries.back().I->value[aCorner]; return m_entries.back().I.value[aCorner];
} }
if( aV <= m_entries.at( 0 ).V ) if( aV <= m_entries.at( 0 ).V )
{ {
return m_entries.at( 0 ).I->value[aCorner]; return m_entries.at( 0 ).I.value[aCorner];
} }
for( int i = 1; i < m_entries.size(); i++ ) for( int i = 1; i < m_entries.size(); i++ )
{ {
if( m_entries.at( i ).V > aV ) if( m_entries.at( i ).V > aV )
{ {
return m_entries.at( i - 1 ).I->value[aCorner] return m_entries.at( i - 1 ).I.value[aCorner]
+ ( m_entries.at( i ).I->value[aCorner] + ( m_entries.at( i ).I.value[aCorner]
- m_entries.at( i - 1 ).I->value[aCorner] ) - m_entries.at( i - 1 ).I.value[aCorner] )
/ ( m_entries.at( i ).V - m_entries.at( i - 1 ).V ) / ( m_entries.at( i ).V - m_entries.at( i - 1 ).V )
* ( aV - m_entries.at( i - 1 ).V ); * ( aV - m_entries.at( i - 1 ).V );
} }
@ -356,7 +356,7 @@ bool IVtable::Check()
break; break;
} }
if( !entry.I->Check() ) if( !entry.I.Check() )
{ {
Report( _( "There is an invalid current in an IV table" ), RPT_SEVERITY_ERROR ); Report( _( "There is an invalid current in an IV table" ), RPT_SEVERITY_ERROR );
status = false; status = false;
@ -403,12 +403,12 @@ bool IbisRamp::Check()
status = false; status = false;
Report( _( "Invalid R_load." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid R_load." ), RPT_SEVERITY_ERROR );
} }
if( !m_falling->Check() ) if( !m_falling.Check() )
{ {
Report( _( "Invalid falling dv/dt." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid falling dv/dt." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_rising->Check() ) if( !m_rising.Check() )
{ {
Report( _( "Invalid rising dv/dt." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid rising dv/dt." ), RPT_SEVERITY_ERROR );
status = false; status = false;
@ -469,33 +469,33 @@ bool IbisModel::Check()
Report( _( "Invalid V_meas value." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid V_meas value." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_C_comp->Check() ) if( !m_C_comp.Check() )
{ {
Report( _( "C_comp is invalid." ), RPT_SEVERITY_ERROR ); Report( _( "C_comp is invalid." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_temperatureRange->Check() ) if( !m_temperatureRange.Check() )
{ {
Report( _( "Temperature Range is invalid." ), RPT_SEVERITY_ERROR ); Report( _( "Temperature Range is invalid." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_voltageRange->Check() ) if( !m_voltageRange.Check() )
{ {
// If the voltage range is not valid, it's ok, only if we have pulls and clamps // If the voltage range is not valid, it's ok, only if we have pulls and clamps
if( !m_pulldownReference->Check() ) if( !m_pulldownReference.Check() )
{ {
status = false; status = false;
} }
if( !m_pullupReference->Check() ) if( !m_pullupReference.Check() )
{ {
status = false; status = false;
} }
if( !m_GNDClampReference->Check() ) if( !m_GNDClampReference.Check() )
{ {
status = false; status = false;
} }
if( !m_POWERClampReference->Check() ) if( !m_POWERClampReference.Check() )
{ {
status = false; status = false;
} }
@ -505,22 +505,22 @@ bool IbisModel::Check()
} }
status = false; status = false;
} }
if( !m_pulldown->Check() ) if( !m_pulldown.Check() )
{ {
Report( _( "Invalid pulldown." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid pulldown." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_pullup->Check() ) if( !m_pullup.Check() )
{ {
Report( _( "Invalid pullup." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid pullup." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_POWERClamp->Check() ) if( !m_POWERClamp.Check() )
{ {
Report( _( "Invalid POWER clamp." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid POWER clamp." ), RPT_SEVERITY_ERROR );
status = false; status = false;
} }
if( !m_GNDClamp->Check() ) if( !m_GNDClamp.Check() )
{ {
Report( _( "Invalid GND clamp." ), RPT_SEVERITY_ERROR ); Report( _( "Invalid GND clamp." ), RPT_SEVERITY_ERROR );
status = false; status = false;
@ -529,7 +529,7 @@ bool IbisModel::Check()
&& m_type != IBIS_MODEL_TYPE::TERMINATOR && m_type != IBIS_MODEL_TYPE::SERIES && m_type != IBIS_MODEL_TYPE::TERMINATOR && m_type != IBIS_MODEL_TYPE::SERIES
&& m_type != IBIS_MODEL_TYPE::SERIES_SWITCH ) && m_type != IBIS_MODEL_TYPE::SERIES_SWITCH )
{ {
if( !m_ramp->Check() ) if( !m_ramp.Check() )
{ {
Report( _( "Invalid Ramp" ), RPT_SEVERITY_ERROR ); Report( _( "Invalid Ramp" ), RPT_SEVERITY_ERROR );
} }
@ -1152,7 +1152,7 @@ bool IbisParser::changeContext( std::string& aKeyword )
{ {
switch( m_context ) switch( m_context )
{ {
case IBIS_PARSER_CONTEXT::HEADER: status &= m_ibisFile.m_header->Check(); break; case IBIS_PARSER_CONTEXT::HEADER: status &= m_ibisFile.m_header.Check(); break;
case IBIS_PARSER_CONTEXT::COMPONENT: status &= m_currentComponent->Check(); break; case IBIS_PARSER_CONTEXT::COMPONENT: status &= m_currentComponent->Check(); break;
case IBIS_PARSER_CONTEXT::MODEL: status &= m_currentModel->Check(); break; case IBIS_PARSER_CONTEXT::MODEL: status &= m_currentModel->Check(); break;
case IBIS_PARSER_CONTEXT::MODELSELECTOR: status &= m_currentModelSelector->Check(); break; case IBIS_PARSER_CONTEXT::MODELSELECTOR: status &= m_currentModelSelector->Check(); break;
@ -1171,10 +1171,9 @@ bool IbisParser::changeContext( std::string& aKeyword )
//New context //New context
if( compareIbisWord( aKeyword.c_str(), "Component" ) ) if( compareIbisWord( aKeyword.c_str(), "Component" ) )
{ {
IbisComponent comp( m_reporter ); m_ibisFile.m_components.push_back( IbisComponent( m_reporter ) );
storeString( comp.m_name, false );
m_ibisFile.m_components.push_back( comp );
m_currentComponent = &( m_ibisFile.m_components.back() ); m_currentComponent = &( m_ibisFile.m_components.back() );
storeString( m_currentComponent->m_name, false );
m_context = IBIS_PARSER_CONTEXT::COMPONENT; m_context = IBIS_PARSER_CONTEXT::COMPONENT;
} }
else if( compareIbisWord( aKeyword.c_str(), "Model_Selector" ) ) else if( compareIbisWord( aKeyword.c_str(), "Model_Selector" ) )
@ -1189,9 +1188,9 @@ bool IbisParser::changeContext( std::string& aKeyword )
else if( compareIbisWord( aKeyword.c_str(), "Model" ) ) else if( compareIbisWord( aKeyword.c_str(), "Model" ) )
{ {
IbisModel model( m_reporter ); IbisModel model( m_reporter );
model.m_temperatureRange->value[IBIS_CORNER::MIN] = 0; model.m_temperatureRange.value[IBIS_CORNER::MIN] = 0;
model.m_temperatureRange->value[IBIS_CORNER::TYP] = 50; model.m_temperatureRange.value[IBIS_CORNER::TYP] = 50;
model.m_temperatureRange->value[IBIS_CORNER::MAX] = 100; model.m_temperatureRange.value[IBIS_CORNER::MAX] = 100;
storeString( model.m_name, false ); storeString( model.m_name, false );
m_ibisFile.m_models.push_back( model ); m_ibisFile.m_models.push_back( model );
m_currentModel = &( m_ibisFile.m_models.back() ); m_currentModel = &( m_ibisFile.m_models.back() );
@ -1303,7 +1302,7 @@ bool IbisParser::readRamp()
std::string keyword = std::string( "R_load " ); std::string keyword = std::string( "R_load " );
if( !readNumericSubparam( std::string( "R_load " ), m_currentModel->m_ramp->m_Rload ) ) if( !readNumericSubparam( std::string( "R_load " ), m_currentModel->m_ramp.m_Rload ) )
{ {
std::string str; std::string str;
@ -1311,11 +1310,11 @@ bool IbisParser::readRamp()
{ {
if( !strcmp( str.c_str(), "dV/dt_r" ) ) if( !strcmp( str.c_str(), "dV/dt_r" ) )
{ {
readRampdvdt( *( m_currentModel->m_ramp->m_rising ) ); readRampdvdt( m_currentModel->m_ramp.m_rising );
} }
else if( !strcmp( str.c_str(), "dV/dt_f" ) ) else if( !strcmp( str.c_str(), "dV/dt_f" ) )
{ {
readRampdvdt( *( m_currentModel->m_ramp->m_falling ) ); readRampdvdt( m_currentModel->m_ramp.m_falling );
} }
else else
{ {
@ -1333,17 +1332,17 @@ bool IbisParser::parseModel( std::string& aKeyword )
bool status = false; bool status = false;
if( compareIbisWord( aKeyword.c_str(), "Voltage_Range" ) ) if( compareIbisWord( aKeyword.c_str(), "Voltage_Range" ) )
status = readTypMinMaxValue( *( m_currentModel->m_voltageRange ) ); status = readTypMinMaxValue( m_currentModel->m_voltageRange );
else if( compareIbisWord( aKeyword.c_str(), "Temperature_Range" ) ) else if( compareIbisWord( aKeyword.c_str(), "Temperature_Range" ) )
status = readTypMinMaxValue( *( m_currentModel->m_temperatureRange ) ); status = readTypMinMaxValue( m_currentModel->m_temperatureRange );
else if( compareIbisWord( aKeyword.c_str(), "GND_Clamp" ) ) else if( compareIbisWord( aKeyword.c_str(), "GND_Clamp" ) )
status = readIVtableEntry( *( m_currentModel->m_GNDClamp ) ); status = readIVtableEntry( m_currentModel->m_GNDClamp );
else if( compareIbisWord( aKeyword.c_str(), "POWER_Clamp" ) ) else if( compareIbisWord( aKeyword.c_str(), "POWER_Clamp" ) )
status = readIVtableEntry( *( m_currentModel->m_POWERClamp ) ); status = readIVtableEntry( m_currentModel->m_POWERClamp );
else if( compareIbisWord( aKeyword.c_str(), "Pulldown" ) ) else if( compareIbisWord( aKeyword.c_str(), "Pulldown" ) )
status = readIVtableEntry( *( m_currentModel->m_pulldown ) ); status = readIVtableEntry( m_currentModel->m_pulldown );
else if( compareIbisWord( aKeyword.c_str(), "Pullup" ) ) else if( compareIbisWord( aKeyword.c_str(), "Pullup" ) )
status = readIVtableEntry( *( m_currentModel->m_pullup ) ); status = readIVtableEntry( m_currentModel->m_pullup );
else if( compareIbisWord( aKeyword.c_str(), "Rising_Waveform" ) ) else if( compareIbisWord( aKeyword.c_str(), "Rising_Waveform" ) )
status = readWaveform( nullptr, IBIS_WAVEFORM_TYPE::RISING ); status = readWaveform( nullptr, IBIS_WAVEFORM_TYPE::RISING );
else if( compareIbisWord( aKeyword.c_str(), "Falling_Waveform" ) ) else if( compareIbisWord( aKeyword.c_str(), "Falling_Waveform" ) )
@ -1351,21 +1350,21 @@ bool IbisParser::parseModel( std::string& aKeyword )
else if( compareIbisWord( aKeyword.c_str(), "Ramp" ) ) else if( compareIbisWord( aKeyword.c_str(), "Ramp" ) )
status = readRamp(); status = readRamp();
else if( compareIbisWord( aKeyword.c_str(), "Pullup_Reference" ) ) else if( compareIbisWord( aKeyword.c_str(), "Pullup_Reference" ) )
status = readTypMinMaxValue( *( m_currentModel->m_pullupReference ) ); status = readTypMinMaxValue( m_currentModel->m_pullupReference );
else if( compareIbisWord( aKeyword.c_str(), "Pulldown_Reference" ) ) else if( compareIbisWord( aKeyword.c_str(), "Pulldown_Reference" ) )
status = readTypMinMaxValue( *( m_currentModel->m_pulldownReference ) ); status = readTypMinMaxValue( m_currentModel->m_pulldownReference );
else if( compareIbisWord( aKeyword.c_str(), "POWER_Clamp_Reference" ) ) else if( compareIbisWord( aKeyword.c_str(), "POWER_Clamp_Reference" ) )
status = readTypMinMaxValue( *( m_currentModel->m_POWERClampReference ) ); status = readTypMinMaxValue( m_currentModel->m_POWERClampReference );
else if( compareIbisWord( aKeyword.c_str(), "GND_Clamp_Reference" ) ) else if( compareIbisWord( aKeyword.c_str(), "GND_Clamp_Reference" ) )
status = readTypMinMaxValue( *( m_currentModel->m_GNDClampReference ) ); status = readTypMinMaxValue( m_currentModel->m_GNDClampReference );
else if( compareIbisWord( aKeyword.c_str(), "Rac" ) ) else if( compareIbisWord( aKeyword.c_str(), "Rac" ) )
status = readTypMinMaxValue( *( m_currentModel->m_Rac ) ); status = readTypMinMaxValue( m_currentModel->m_Rac );
else if( compareIbisWord( aKeyword.c_str(), "Cac" ) ) else if( compareIbisWord( aKeyword.c_str(), "Cac" ) )
status = readTypMinMaxValue( *( m_currentModel->m_Cac ) ); status = readTypMinMaxValue( m_currentModel->m_Cac );
else if( compareIbisWord( aKeyword.c_str(), "Rpower" ) ) else if( compareIbisWord( aKeyword.c_str(), "Rpower" ) )
status = readTypMinMaxValue( *( m_currentModel->m_Rpower ) ); status = readTypMinMaxValue( m_currentModel->m_Rpower );
else if( compareIbisWord( aKeyword.c_str(), "Rgnd" ) ) else if( compareIbisWord( aKeyword.c_str(), "Rgnd" ) )
status = readTypMinMaxValue( *( m_currentModel->m_Rgnd ) ); status = readTypMinMaxValue( m_currentModel->m_Rgnd );
else else
{ {
status = changeContext( aKeyword ); status = changeContext( aKeyword );
@ -1931,7 +1930,7 @@ bool IbisParser::readModel()
else if( readNumericSubparam( std::string( "Vmeas" ), m_currentModel->m_vmeas ) ) else if( readNumericSubparam( std::string( "Vmeas" ), m_currentModel->m_vmeas ) )
; ;
else if( readTypMinMaxValueSubparam( std::string( "C_comp" ), else if( readTypMinMaxValueSubparam( std::string( "C_comp" ),
*( m_currentModel->m_C_comp ) ) ) m_currentModel->m_C_comp ) )
; ;
else else
{ {
@ -1958,7 +1957,7 @@ bool IbisParser::parseHeader( std::string& aKeyword )
if( compareIbisWord( aKeyword.c_str(), "IBIS_Ver" ) ) if( compareIbisWord( aKeyword.c_str(), "IBIS_Ver" ) )
{ {
status &= readDouble( m_ibisFile.m_header->m_ibisVersion ); status &= readDouble( m_ibisFile.m_header.m_ibisVersion );
} }
else if( compareIbisWord( aKeyword.c_str(), "Comment_char" ) ) else if( compareIbisWord( aKeyword.c_str(), "Comment_char" ) )
{ {
@ -1966,31 +1965,31 @@ bool IbisParser::parseHeader( std::string& aKeyword )
} }
else if( compareIbisWord( aKeyword.c_str(), "File_Name" ) ) else if( compareIbisWord( aKeyword.c_str(), "File_Name" ) )
{ {
storeString( m_ibisFile.m_header->m_fileName, false ); storeString( m_ibisFile.m_header.m_fileName, false );
} }
else if( compareIbisWord( aKeyword.c_str(), "File_Rev" ) ) else if( compareIbisWord( aKeyword.c_str(), "File_Rev" ) )
{ {
status &= readDouble( m_ibisFile.m_header->m_fileRevision ); status &= readDouble( m_ibisFile.m_header.m_fileRevision );
} }
else if( compareIbisWord( aKeyword.c_str(), "Source" ) ) else if( compareIbisWord( aKeyword.c_str(), "Source" ) )
{ {
storeString( m_ibisFile.m_header->m_source, true ); storeString( m_ibisFile.m_header.m_source, true );
} }
else if( compareIbisWord( aKeyword.c_str(), "Notes" ) ) else if( compareIbisWord( aKeyword.c_str(), "Notes" ) )
{ {
storeString( m_ibisFile.m_header->m_notes, true ); storeString( m_ibisFile.m_header.m_notes, true );
} }
else if( compareIbisWord( aKeyword.c_str(), "Disclaimer" ) ) else if( compareIbisWord( aKeyword.c_str(), "Disclaimer" ) )
{ {
storeString( m_ibisFile.m_header->m_disclaimer, true ); storeString( m_ibisFile.m_header.m_disclaimer, true );
} }
else if( compareIbisWord( aKeyword.c_str(), "Copyright" ) ) else if( compareIbisWord( aKeyword.c_str(), "Copyright" ) )
{ {
storeString( m_ibisFile.m_header->m_copyright, true ); storeString( m_ibisFile.m_header.m_copyright, true );
} }
else if( compareIbisWord( aKeyword.c_str(), "Date" ) ) else if( compareIbisWord( aKeyword.c_str(), "Date" ) )
{ {
storeString( m_ibisFile.m_header->m_date, false ); storeString( m_ibisFile.m_header.m_date, false );
} }
else else
{ {
@ -2078,9 +2077,9 @@ bool IbisParser::readPackage()
std::vector<std::string> fields; std::vector<std::string> fields;
TypMinMaxValue* R = m_currentComponent->m_package.m_Rpkg; TypMinMaxValue* R = &( m_currentComponent->m_package.m_Rpkg );
TypMinMaxValue* L = m_currentComponent->m_package.m_Lpkg; TypMinMaxValue* L = &( m_currentComponent->m_package.m_Lpkg );
TypMinMaxValue* C = m_currentComponent->m_package.m_Cpkg; TypMinMaxValue* C = &( m_currentComponent->m_package.m_Cpkg );
readTableLine( fields ); readTableLine( fields );
@ -2300,7 +2299,7 @@ bool IbisParser::readDiffPin()
} }
if( status && readWord( entry.pinB ) ) if( status && readWord( entry.pinB ) )
{ {
m_currentComponent->m_diffPin->m_entries.push_back( entry ); m_currentComponent->m_diffPin.m_entries.push_back( entry );
} }
} }
return status; return status;
@ -2321,7 +2320,7 @@ bool IbisParser::readIVtableEntry( IVtable& aDest )
status &= readDouble( entry.V ); status &= readDouble( entry.V );
if( status && readTypMinMaxValue( *( entry.I ) ) ) if( status && readTypMinMaxValue( entry.I ) )
{ {
aDest.m_entries.push_back( entry ); aDest.m_entries.push_back( entry );
} }
@ -2345,7 +2344,7 @@ bool IbisParser::readVTtableEntry( VTtable& aDest )
{ {
std::string str; std::string str;
status &= readDouble( entry.t ); status &= readDouble( entry.t );
status &= readTypMinMaxValue( *( entry.V ) ); status &= readTypMinMaxValue( entry.V );
} }
m_continue = IBIS_PARSER_CONTINUE::IV_TABLE; m_continue = IBIS_PARSER_CONTINUE::IV_TABLE;
@ -2410,7 +2409,7 @@ bool IbisParser::readWaveform( IbisWaveform* aDest, IBIS_WAVEFORM_TYPE aType )
else if( readNumericSubparam( std::string( "C_dut" ), wf->m_C_fixture ) ) else if( readNumericSubparam( std::string( "C_dut" ), wf->m_C_fixture ) )
; ;
// The line is not a subparameter, then let's try to read a VT table entry // The line is not a subparameter, then let's try to read a VT table entry
else if( !readVTtableEntry( *( m_currentWaveform->m_table ) ) ) else if( !readVTtableEntry( m_currentWaveform->m_table ) )
{ {
status = false; status = false;
} }
@ -2473,12 +2472,8 @@ bool IbisParser::onNewLine()
case IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN: status &= readDiffPin(); break; case IBIS_PARSER_CONTINUE::COMPONENT_DIFFPIN: status &= readDiffPin(); break;
case IBIS_PARSER_CONTINUE::MODELSELECTOR: status &= readModelSelector(); break; case IBIS_PARSER_CONTINUE::MODELSELECTOR: status &= readModelSelector(); break;
case IBIS_PARSER_CONTINUE::MODEL: status &= readModel(); break; case IBIS_PARSER_CONTINUE::MODEL: status &= readModel(); break;
case IBIS_PARSER_CONTINUE::IV_TABLE: case IBIS_PARSER_CONTINUE::IV_TABLE: status &= readIVtableEntry( *m_currentIVtable ); break;
status &= readIVtableEntry( *( m_currentIVtable ) ); case IBIS_PARSER_CONTINUE::VT_TABLE: status &= readVTtableEntry( *m_currentVTtable ); break;
break;
case IBIS_PARSER_CONTINUE::VT_TABLE:
status &= readVTtableEntry( *( m_currentVTtable ) );
break;
case IBIS_PARSER_CONTINUE::WAVEFORM: case IBIS_PARSER_CONTINUE::WAVEFORM:
status &= readWaveform( m_currentWaveform, m_currentWaveform->m_type ); status &= readWaveform( m_currentWaveform, m_currentWaveform->m_type );
break; break;

View File

@ -205,15 +205,16 @@ public:
class IbisComponentPackage : public IBIS_INPUT class IbisComponentPackage : public IBIS_INPUT
{ {
public: public:
IbisComponentPackage( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisComponentPackage( IBIS_REPORTER* aReporter ) :
{ IBIS_INPUT( aReporter ),
m_Rpkg = new TypMinMaxValue( m_reporter ); m_Rpkg( aReporter ),
m_Lpkg = new TypMinMaxValue( m_reporter ); m_Lpkg( aReporter ),
m_Cpkg = new TypMinMaxValue( m_reporter ); m_Cpkg( aReporter )
}; {};
TypMinMaxValue* m_Rpkg;
TypMinMaxValue* m_Lpkg; TypMinMaxValue m_Rpkg;
TypMinMaxValue* m_Cpkg; TypMinMaxValue m_Lpkg;
TypMinMaxValue m_Cpkg;
bool Check() override; bool Check() override;
}; };
@ -252,22 +253,19 @@ public:
std::string m_POWERClampRef; std::string m_POWERClampRef;
std::string m_extRef; std::string m_extRef;
bool m_virtual; bool m_virtual = false;
}; };
class IbisDiffPinEntry : public IBIS_INPUT class IbisDiffPinEntry : public IBIS_INPUT
{ {
public: public:
IbisDiffPinEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisDiffPinEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), tdelay( aReporter ){};
{
tdelay = new TypMinMaxValue( aReporter );
};
std::string pinA; std::string pinA;
std::string pinB; std::string pinB;
double Vdiff = 0.2; // ignored for input double Vdiff = 0.2; // ignored for input
TypMinMaxValue* tdelay; // ignored for outputs TypMinMaxValue tdelay; // ignored for outputs
}; };
@ -281,10 +279,11 @@ public:
class IbisComponent : public IBIS_INPUT class IbisComponent : public IBIS_INPUT
{ {
public: public:
IbisComponent( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_package( aReporter ) IbisComponent( IBIS_REPORTER* aReporter ) :
{ IBIS_INPUT( aReporter ),
m_diffPin = new IbisDiffPin( m_reporter ); m_package( aReporter ),
}; m_diffPin( aReporter )
{};
std::string m_name = ""; std::string m_name = "";
std::string m_manufacturer = ""; std::string m_manufacturer = "";
@ -294,7 +293,7 @@ public:
std::string m_packageModel; std::string m_packageModel;
std::string m_busLabel; std::string m_busLabel;
std::string m_dieSupplyPads; std::string m_dieSupplyPads;
IbisDiffPin* m_diffPin; IbisDiffPin m_diffPin;
bool Check() override; bool Check() override;
}; };
@ -322,12 +321,9 @@ public:
class IVtableEntry : public IBIS_INPUT class IVtableEntry : public IBIS_INPUT
{ {
public: public:
IVtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IVtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), I( aReporter ){};
{ double V = 0;
I = new TypMinMaxValue( m_reporter ); TypMinMaxValue I;
};
double V;
TypMinMaxValue* I;
}; };
@ -370,12 +366,9 @@ private:
class VTtableEntry : public IBIS_INPUT class VTtableEntry : public IBIS_INPUT
{ {
public: public:
VTtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) VTtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), V( aReporter ){};
{ double t = 0;
V = new TypMinMaxValue( m_reporter ); TypMinMaxValue V;
};
double t;
TypMinMaxValue* V;
}; };
class VTtable : public IBIS_INPUT class VTtable : public IBIS_INPUT
@ -424,8 +417,8 @@ enum class IBIS_MODEL_ENABLE
class dvdt class dvdt
{ {
public: public:
double m_dv; double m_dv = 1;
double m_dt; double m_dt = 1;
}; };
class dvdtTypMinMax : public IBIS_INPUT class dvdtTypMinMax : public IBIS_INPUT
@ -441,14 +434,14 @@ public:
class IbisRamp : public IBIS_INPUT class IbisRamp : public IBIS_INPUT
{ {
public: public:
IbisRamp( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisRamp( IBIS_REPORTER* aReporter ) :
{ IBIS_INPUT( aReporter ),
m_falling = new dvdtTypMinMax( m_reporter ); m_falling( aReporter ),
m_rising = new dvdtTypMinMax( m_reporter ); m_rising( aReporter )
}; {};
dvdtTypMinMax* m_falling; dvdtTypMinMax m_falling;
dvdtTypMinMax* m_rising; dvdtTypMinMax m_rising;
double m_Rload = 50; // The R_load subparameter is optional if the default 50 ohm load is used double m_Rload = 50; // The R_load subparameter is optional if the default 50 ohm load is used
bool Check() override; bool Check() override;
@ -463,15 +456,13 @@ enum class IBIS_WAVEFORM_TYPE
class IbisWaveform : public IBIS_INPUT class IbisWaveform : public IBIS_INPUT
{ {
public: public:
IbisWaveform( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisWaveform( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_table( aReporter ){};
{
m_table = new VTtable( m_reporter ); VTtable m_table;
}; IBIS_WAVEFORM_TYPE m_type = IBIS_WAVEFORM_TYPE::RISING;
VTtable* m_table; double m_R_dut = 0;
IBIS_WAVEFORM_TYPE m_type; double m_C_dut = 0;
double m_R_dut; double m_L_dut = 0;
double m_C_dut;
double m_L_dut;
double m_R_fixture = 0; double m_R_fixture = 0;
double m_C_fixture = 0; double m_C_fixture = 0;
double m_L_fixture = 0; double m_L_fixture = 0;
@ -490,25 +481,24 @@ enum class IBIS_MODEL_POLARITY
class IbisModel : IBIS_INPUT class IbisModel : IBIS_INPUT
{ {
public: public:
IbisModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ),
{ m_C_comp( aReporter ),
m_C_comp = new TypMinMaxValue( m_reporter ); m_voltageRange( aReporter ),
m_voltageRange = new TypMinMaxValue( m_reporter ); m_temperatureRange( aReporter ),
m_temperatureRange = new TypMinMaxValue( m_reporter ); m_pullupReference( aReporter ),
m_pullupReference = new TypMinMaxValue( m_reporter ); m_pulldownReference( aReporter ),
m_pulldownReference = new TypMinMaxValue( m_reporter ); m_GNDClampReference( aReporter ),
m_GNDClampReference = new TypMinMaxValue( m_reporter ); m_POWERClampReference( aReporter ),
m_POWERClampReference = new TypMinMaxValue( m_reporter ); m_Rgnd( aReporter ),
m_Rgnd = new TypMinMaxValue( m_reporter ); m_Rpower( aReporter ),
m_Rpower = new TypMinMaxValue( m_reporter ); m_Rac( aReporter ),
m_Rac = new TypMinMaxValue( m_reporter ); m_Cac( aReporter ),
m_Cac = new TypMinMaxValue( m_reporter ); m_GNDClamp( aReporter ),
m_GNDClamp = new IVtable( m_reporter ); m_POWERClamp( aReporter ),
m_POWERClamp = new IVtable( m_reporter ); m_pullup( aReporter ),
m_pullup = new IVtable( m_reporter ); m_pulldown( aReporter ),
m_pulldown = new IVtable( m_reporter ); m_ramp( aReporter )
m_ramp = new IbisRamp( m_reporter ); {};
};
std::string m_name; std::string m_name;
IBIS_MODEL_TYPE m_type = IBIS_MODEL_TYPE::UNDEFINED; IBIS_MODEL_TYPE m_type = IBIS_MODEL_TYPE::UNDEFINED;
@ -524,24 +514,24 @@ public:
IBIS_MODEL_POLARITY m_polarity = IBIS_MODEL_POLARITY::UNDEFINED; IBIS_MODEL_POLARITY m_polarity = IBIS_MODEL_POLARITY::UNDEFINED;
// End of optional subparameters // End of optional subparameters
TypMinMaxValue* m_C_comp; TypMinMaxValue m_C_comp;
TypMinMaxValue* m_voltageRange; TypMinMaxValue m_voltageRange;
TypMinMaxValue* m_temperatureRange; TypMinMaxValue m_temperatureRange;
TypMinMaxValue* m_pullupReference; TypMinMaxValue m_pullupReference;
TypMinMaxValue* m_pulldownReference; TypMinMaxValue m_pulldownReference;
TypMinMaxValue* m_GNDClampReference; TypMinMaxValue m_GNDClampReference;
TypMinMaxValue* m_POWERClampReference; TypMinMaxValue m_POWERClampReference;
TypMinMaxValue* m_Rgnd; TypMinMaxValue m_Rgnd;
TypMinMaxValue* m_Rpower; TypMinMaxValue m_Rpower;
TypMinMaxValue* m_Rac; TypMinMaxValue m_Rac;
TypMinMaxValue* m_Cac; TypMinMaxValue m_Cac;
IVtable* m_GNDClamp; IVtable m_GNDClamp;
IVtable* m_POWERClamp; IVtable m_POWERClamp;
IVtable* m_pullup; IVtable m_pullup;
IVtable* m_pulldown; IVtable m_pulldown;
std::vector<IbisWaveform*> m_risingWaveforms; std::vector<IbisWaveform*> m_risingWaveforms;
std::vector<IbisWaveform*> m_fallingWaveforms; std::vector<IbisWaveform*> m_fallingWaveforms;
IbisRamp* m_ramp; IbisRamp m_ramp;
bool Check() override; bool Check() override;
}; };
@ -556,7 +546,7 @@ public:
std::string m_manufacturer; std::string m_manufacturer;
std::string m_OEM; std::string m_OEM;
std::string m_description; std::string m_description;
int m_numberOfPins; int m_numberOfPins = 0;
std::vector<std::string> m_pins; std::vector<std::string> m_pins;
std::shared_ptr<IBIS_MATRIX> m_resistanceMatrix; std::shared_ptr<IBIS_MATRIX> m_resistanceMatrix;
@ -569,12 +559,9 @@ public:
class IbisFile : public IBIS_INPUT class IbisFile : public IBIS_INPUT
{ {
public: public:
IbisFile( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ) IbisFile( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_header( aReporter ){};
{
m_header = new IbisHeader( m_reporter );
};
IbisHeader* m_header; IbisHeader m_header;
std::vector<IbisComponent> m_components; std::vector<IbisComponent> m_components;
std::vector<IbisModelSelector> m_modelSelectors; std::vector<IbisModelSelector> m_modelSelectors;
std::vector<IbisModel> m_models; std::vector<IbisModel> m_models;
@ -619,25 +606,25 @@ public:
bool m_parrot = true; // Write back all lines. bool m_parrot = true; // Write back all lines.
long m_lineCounter; long m_lineCounter = 0;
char m_commentChar = '|'; char m_commentChar = '|';
std::vector<char> m_buffer; std::vector<char> m_buffer;
int m_bufferIndex; int m_bufferIndex = 0;
int m_lineOffset; int m_lineOffset = 0;
int m_lineIndex; int m_lineIndex = 0;
int m_lineLength; int m_lineLength = 0;
IbisFile m_ibisFile; IbisFile m_ibisFile;
IbisComponent* m_currentComponent; IbisComponent* m_currentComponent = nullptr;
IbisModelSelector* m_currentModelSelector; IbisModelSelector* m_currentModelSelector = nullptr;
IbisModel* m_currentModel; IbisModel* m_currentModel = nullptr;
IbisPackageModel* m_currentPackageModel; IbisPackageModel* m_currentPackageModel = nullptr;
std::shared_ptr<IBIS_MATRIX> m_currentMatrix; std::shared_ptr<IBIS_MATRIX> m_currentMatrix;
int m_currentMatrixRow; int m_currentMatrixRow;
int m_currentMatrixRowIndex; int m_currentMatrixRowIndex;
IVtable* m_currentIVtable; IVtable* m_currentIVtable = nullptr;
VTtable* m_currentVTtable; VTtable* m_currentVTtable = nullptr;
IbisWaveform* m_currentWaveform; IbisWaveform* m_currentWaveform = nullptr;
/** @brief Parse a file /** @brief Parse a file
* *

View File

@ -94,18 +94,20 @@ KIBIS::KIBIS( std::string aFileName ) : KIBIS_ANY( this ), m_file( this )
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( IbisParser& aParser )
{ {
bool status = true; bool status = true;
m_fileName = aParser.m_ibisFile.m_header->m_fileName; m_fileName = aParser.m_ibisFile.m_header.m_fileName;
m_fileRev = aParser.m_ibisFile.m_header->m_fileRevision; m_fileRev = aParser.m_ibisFile.m_header.m_fileRevision;
m_ibisVersion = aParser.m_ibisFile.m_header->m_ibisVersion; m_ibisVersion = aParser.m_ibisFile.m_header.m_ibisVersion;
m_date = aParser.m_ibisFile.m_header->m_date; m_date = aParser.m_ibisFile.m_header.m_date;
m_notes = aParser.m_ibisFile.m_header->m_notes; m_notes = aParser.m_ibisFile.m_header.m_notes;
m_disclaimer = aParser.m_ibisFile.m_header->m_disclaimer; m_disclaimer = aParser.m_ibisFile.m_header.m_disclaimer;
m_copyright = aParser.m_ibisFile.m_header->m_copyright; m_copyright = aParser.m_ibisFile.m_header.m_copyright;
m_valid = status; m_valid = status;
@ -115,15 +117,17 @@ bool KIBIS_FILE::Init( IbisParser& aParser )
KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPackage& aPackage, KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPackage& aPackage,
IbisParser& aParser, KIBIS_COMPONENT* aParent, IbisParser& aParser, KIBIS_COMPONENT* aParent,
std::vector<KIBIS_MODEL>& aModels ) : std::vector<KIBIS_MODEL>& aModels ) :
KIBIS_ANY( aTopLevel ) KIBIS_ANY( aTopLevel ),
m_Rpin( aTopLevel->m_reporter ), m_Lpin( aTopLevel->m_reporter ),
m_Cpin( aTopLevel->m_reporter )
{ {
m_signalName = aPin.m_signalName; m_signalName = aPin.m_signalName;
m_pinNumber = aPin.m_pinName; m_pinNumber = aPin.m_pinName;
m_parent = aParent; m_parent = aParent;
R_pin = aPackage.m_Rpkg; m_Rpin = aPackage.m_Rpkg;
L_pin = aPackage.m_Lpkg; m_Lpin = aPackage.m_Lpkg;
C_pin = aPackage.m_Cpkg; m_Cpin = aPackage.m_Cpkg;
// The values listed in the [Pin] description section override the default // The values listed in the [Pin] description section override the default
// values defined in [Package] // values defined in [Package]
@ -133,21 +137,21 @@ KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPac
if( !isnan( aPin.m_Lpin ) ) if( !isnan( aPin.m_Lpin ) )
{ {
R_pin->value[IBIS_CORNER::TYP] = aPin.m_Rpin; m_Rpin.value[IBIS_CORNER::TYP] = aPin.m_Rpin;
R_pin->value[IBIS_CORNER::MIN] = aPin.m_Rpin; m_Rpin.value[IBIS_CORNER::MIN] = aPin.m_Rpin;
R_pin->value[IBIS_CORNER::MAX] = aPin.m_Rpin; m_Rpin.value[IBIS_CORNER::MAX] = aPin.m_Rpin;
} }
if( !isnan( aPin.m_Lpin ) ) if( !isnan( aPin.m_Lpin ) )
{ {
L_pin->value[IBIS_CORNER::TYP] = aPin.m_Lpin; m_Lpin.value[IBIS_CORNER::TYP] = aPin.m_Lpin;
L_pin->value[IBIS_CORNER::MIN] = aPin.m_Lpin; m_Lpin.value[IBIS_CORNER::MIN] = aPin.m_Lpin;
L_pin->value[IBIS_CORNER::MAX] = aPin.m_Lpin; m_Lpin.value[IBIS_CORNER::MAX] = aPin.m_Lpin;
} }
if( !isnan( aPin.m_Cpin ) ) if( !isnan( aPin.m_Cpin ) )
{ {
C_pin->value[IBIS_CORNER::TYP] = aPin.m_Cpin; m_Cpin.value[IBIS_CORNER::TYP] = aPin.m_Cpin;
C_pin->value[IBIS_CORNER::MIN] = aPin.m_Cpin; m_Cpin.value[IBIS_CORNER::MIN] = aPin.m_Cpin;
C_pin->value[IBIS_CORNER::MAX] = aPin.m_Cpin; m_Cpin.value[IBIS_CORNER::MAX] = aPin.m_Cpin;
} }
bool modelSelected = false; bool modelSelected = false;
@ -184,7 +188,15 @@ KIBIS_PIN::KIBIS_PIN( KIBIS* aTopLevel, IbisComponentPin& aPin, IbisComponentPac
} }
KIBIS_MODEL::KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aParser ) : KIBIS_MODEL::KIBIS_MODEL( KIBIS* aTopLevel, IbisModel& aSource, IbisParser& aParser ) :
KIBIS_ANY( aTopLevel ) 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; bool status = true;
@ -336,34 +348,34 @@ std::string KIBIS_MODEL::SpiceDie( IBIS_CORNER aSupply, IBIS_CORNER aParasitics,
result = "\n"; result = "\n";
result += "VPWR POWER GND "; result += "VPWR POWER GND ";
result += doubleToString( m_voltageRange->value[aSupply] ); result += doubleToString( m_voltageRange.value[aSupply] );
result += "\n"; result += "\n";
result += "CCPOMP " + DIE + " GND "; result += "CCPOMP " + DIE + " GND ";
result += doubleToString( m_C_comp->value[aParasitics] ); result += doubleToString( m_C_comp.value[aParasitics] );
result += "\n"; result += "\n";
if( HasGNDClamp() ) if( HasGNDClamp() )
{ {
result += m_GNDClamp->Spice( aIndex * 4 + 1, DIE, GC_GND, GC, aSupply ); result += m_GNDClamp.Spice( aIndex * 4 + 1, DIE, GC_GND, GC, aSupply );
result += "VmeasGC GND " + GC_GND + " 0\n"; result += "VmeasGC GND " + GC_GND + " 0\n";
} }
if( HasPOWERClamp() ) if( HasPOWERClamp() )
{ {
result += m_POWERClamp->Spice( aIndex * 4 + 2, "POWER", DIE, PC, aSupply ); result += m_POWERClamp.Spice( aIndex * 4 + 2, "POWER", DIE, PC, aSupply );
result += "VmeasPC POWER " + PC_PWR + " 0\n"; result += "VmeasPC POWER " + PC_PWR + " 0\n";
} }
if( HasPulldown() ) if( HasPulldown() )
{ {
result += m_pulldown->Spice( aIndex * 4 + 3, DIEBUFF, PD_GND, PD, aSupply ); result += m_pulldown.Spice( aIndex * 4 + 3, DIEBUFF, PD_GND, PD, aSupply );
result += "VmeasPD GND " + PD_GND + " 0\n"; result += "VmeasPD GND " + PD_GND + " 0\n";
result += "BKD GND " + DIE + " i=( -i(VmeasPU) * v(KU) )\n"; result += "BKD GND " + DIE + " i=( -i(VmeasPU) * v(KU) )\n";
} }
if( HasPullup() ) if( HasPullup() )
{ {
result += m_pullup->Spice( aIndex * 4 + 4, PU_PWR, DIEBUFF, PU, aSupply ); result += m_pullup.Spice( aIndex * 4 + 4, PU_PWR, DIEBUFF, PU, aSupply );
result += "VmeasPU POWER " + PU_PWR + " 0\n"; result += "VmeasPU POWER " + PU_PWR + " 0\n";
result += "BKU POWER " + DIE + " i=( i(VmeasPD) * v(KD) )\n"; result += "BKU POWER " + DIE + " i=( i(VmeasPD) * v(KD) )\n";
} }
@ -377,7 +389,7 @@ IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
{ {
IbisWaveform out( aIn.m_reporter ); IbisWaveform out( aIn.m_reporter );
int nbPoints = aIn.m_table->m_entries.size(); int nbPoints = aIn.m_table.m_entries.size();
if( nbPoints < 2 ) if( nbPoints < 2 )
{ {
@ -385,33 +397,30 @@ IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
return out; return out;
} }
double DCtyp = aIn.m_table->m_entries[0].V->value[IBIS_CORNER::TYP]; 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 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]; double DCmax = aIn.m_table.m_entries[0].V.value[IBIS_CORNER::MAX];
if( nbPoints == 2 ) if( nbPoints == 2 )
{ {
return out; return out;
} }
out.m_table->m_entries.clear(); out.m_table.m_entries.clear();
bool kept = false; bool kept = false;
for( int i = 0; i < nbPoints; i++ ) for( int i = 0; i < nbPoints; i++ )
{ {
VTtableEntry entry( out.m_reporter ); VTtableEntry entry( out.m_reporter );
entry.t = aIn.m_table->m_entries.at( i ).t; entry.t = aIn.m_table.m_entries.at( i ).t;
entry.V->value[IBIS_CORNER::TYP] = entry.V.value[IBIS_CORNER::TYP] = aIn.m_table.m_entries.at( i ).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::MIN] = entry.V.value[IBIS_CORNER::MAX] = aIn.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MAX];
aIn.m_table->m_entries.at( i ).V->value[IBIS_CORNER::MIN]; out.m_table.m_entries.push_back( entry );
entry.V->value[IBIS_CORNER::MAX] = out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::TYP] -= DCtyp;
aIn.m_table->m_entries.at( i ).V->value[IBIS_CORNER::MAX]; out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MIN] -= DCmin;
out.m_table->m_entries.push_back( entry ); out.m_table.m_entries.at( i ).V.value[IBIS_CORNER::MAX] -= DCmax;
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;
} }
return out; return out;
@ -419,19 +428,19 @@ IbisWaveform KIBIS_MODEL::TrimWaveform( IbisWaveform& aIn )
bool KIBIS_MODEL::HasPulldown() bool KIBIS_MODEL::HasPulldown()
{ {
return m_pulldown->m_entries.size() > 0; return m_pulldown.m_entries.size() > 0;
} }
bool KIBIS_MODEL::HasPullup() bool KIBIS_MODEL::HasPullup()
{ {
return m_pullup->m_entries.size() > 0; return m_pullup.m_entries.size() > 0;
} }
bool KIBIS_MODEL::HasGNDClamp() bool KIBIS_MODEL::HasGNDClamp()
{ {
return m_GNDClamp->m_entries.size() > 0; return m_GNDClamp.m_entries.size() > 0;
} }
bool KIBIS_MODEL::HasPOWERClamp() bool KIBIS_MODEL::HasPOWERClamp()
{ {
return m_POWERClamp->m_entries.size() > 0; return m_POWERClamp.m_entries.size() > 0;
} }
std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNode2, std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNode2,
@ -444,10 +453,10 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
IbisWaveform risingWF = TrimWaveform( *( aPair.first ) ); IbisWaveform risingWF = TrimWaveform( *( aPair.first ) );
IbisWaveform fallingWF = TrimWaveform( *( aPair.second ) ); IbisWaveform fallingWF = TrimWaveform( *( aPair.second ) );
double deltaR = risingWF.m_table->m_entries.back().V->value[aSupply] double deltaR = risingWF.m_table.m_entries.back().V.value[aSupply]
- risingWF.m_table->m_entries.at( 0 ).V->value[aSupply]; - risingWF.m_table.m_entries.at( 0 ).V.value[aSupply];
double deltaF = fallingWF.m_table->m_entries.back().V->value[aSupply] double deltaF = fallingWF.m_table.m_entries.back().V.value[aSupply]
- fallingWF.m_table->m_entries.at( 0 ).V->value[aSupply]; - fallingWF.m_table.m_entries.at( 0 ).V.value[aSupply];
// Ideally, delta should be equal to zero. // Ideally, delta should be equal to zero.
// It can be different from zero if the falling waveform does not start were the rising one ended. // It can be different from zero if the falling waveform does not start were the rising one ended.
@ -475,8 +484,8 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
if( i != 0 ) if( i != 0 )
{ {
simul += "0 0 "; simul += "0 0 ";
VTtableEntry entry0 = WF->m_table->m_entries.at( 0 ); VTtableEntry entry0 = WF->m_table.m_entries.at( 0 );
VTtableEntry entry1 = WF->m_table->m_entries.at( 1 ); VTtableEntry entry1 = WF->m_table.m_entries.at( 1 );
double deltaT = entry1.t - entry0.t; double deltaT = entry1.t - entry0.t;
simul += doubleToString( entry0.t + timing - deltaT ); simul += doubleToString( entry0.t + timing - deltaT );
@ -485,11 +494,11 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
simul += " "; simul += " ";
} }
for( VTtableEntry& entry : WF->m_table->m_entries ) for( VTtableEntry& entry : WF->m_table.m_entries )
{ {
simul += doubleToString( entry.t + timing ); simul += doubleToString( entry.t + timing );
simul += " "; simul += " ";
simul += doubleToString( entry.V->value[aSupply] - delta ); simul += doubleToString( entry.V.value[aSupply] - delta );
simul += " "; simul += " ";
} }
simul += ")\n"; simul += ")\n";
@ -514,11 +523,11 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
// The DC value we add is the first value of the first bit. // The DC value we add is the first value of the first bit.
if( aBits[0].first == 0 ) if( aBits[0].first == 0 )
{ {
simul += doubleToString( aPair.second->m_table->m_entries.at( 0 ).V->value[aSupply] ); simul += doubleToString( aPair.second->m_table.m_entries.at( 0 ).V.value[aSupply] );
} }
else else
{ {
simul += doubleToString( aPair.first->m_table->m_entries.at( 0 ).V->value[aSupply] ); simul += doubleToString( aPair.first->m_table.m_entries.at( 0 ).V.value[aSupply] );
} }
simul += ")\n"; simul += ")\n";
@ -554,22 +563,22 @@ std::string KIBIS_PIN::addDie( KIBIS_MODEL& aModel, IBIS_CORNER aSupply, int aIn
if( aModel.HasGNDClamp() ) if( aModel.HasGNDClamp() )
{ {
simul += aModel.m_GNDClamp->Spice( aIndex * 4 + 1, DIE, GC_GND, GC, aSupply ); simul += aModel.m_GNDClamp.Spice( aIndex * 4 + 1, DIE, GC_GND, GC, aSupply );
} }
if( aModel.HasPOWERClamp() ) if( aModel.HasPOWERClamp() )
{ {
simul += aModel.m_POWERClamp->Spice( aIndex * 4 + 2, PC_PWR, DIE, PC, aSupply ); simul += aModel.m_POWERClamp.Spice( aIndex * 4 + 2, PC_PWR, DIE, PC, aSupply );
} }
if( aModel.HasPulldown() ) if( aModel.HasPulldown() )
{ {
simul += aModel.m_pulldown->Spice( aIndex * 4 + 3, DIE, PD_GND, PD, aSupply ); simul += aModel.m_pulldown.Spice( aIndex * 4 + 3, DIE, PD_GND, PD, aSupply );
} }
if( aModel.HasPullup() ) if( aModel.HasPullup() )
{ {
simul += aModel.m_pullup->Spice( aIndex * 4 + 4, PU_PWR, DIE, PU, aSupply ); simul += aModel.m_pullup.Spice( aIndex * 4 + 4, PU_PWR, DIE, PU, aSupply );
} }
return simul; return simul;
@ -581,8 +590,15 @@ void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
// that's not the best way to do, but ¯\_(ツ)_/¯ // that's not the best way to do, but ¯\_(ツ)_/¯
std::ifstream in( "temp_input.spice" ); std::ifstream in( "temp_input.spice" );
std::remove( "temp_input.spice" ); if( std::remove( "temp_input.spice" ) )
std::remove( "temp_output.spice" ); {
Report( _( "Cannot remove temporary input file" ), RPT_SEVERITY_WARNING );
}
if( std::remove( "temp_ouput.spice" ) )
{
Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING );
}
std::ofstream file( "temp_input.spice" ); std::ofstream file( "temp_input.spice" );
@ -635,8 +651,16 @@ void KIBIS_PIN::getKuKdFromFile( std::string* aSimul )
{ {
Report( _( "Error while creating temporary file" ), RPT_SEVERITY_ERROR ); Report( _( "Error while creating temporary file" ), RPT_SEVERITY_ERROR );
} }
std::remove( "temp_input.spice" );
std::remove( "temp_output.spice" ); if( std::remove( "temp_input.spice" ) )
{
Report( _( "Cannot remove temporary input file" ), RPT_SEVERITY_WARNING );
}
if( std::remove( "temp_ouput.spice" ) )
{
Report( _( "Cannot remove temporary output file" ), RPT_SEVERITY_WARNING );
}
// @TODO : this is the end of the dirty code // @TODO : this is the end of the dirty code
@ -685,7 +709,7 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
simul += "\n"; simul += "\n";
simul += "CCPOMP 2 GND "; simul += "CCPOMP 2 GND ";
simul += doubleToString( aModel.m_C_comp->value[aParasitics] ); //@TODO: Check the corner ? simul += doubleToString( aModel.m_C_comp.value[aParasitics] ); //@TODO: Check the corner ?
simul += "\n"; simul += "\n";
switch( aWave->GetType() ) switch( aWave->GetType() )
{ {
@ -697,12 +721,12 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
IbisWaveform* risingWF = aPair.first; IbisWaveform* risingWF = aPair.first;
IbisWaveform* fallingWF = aPair.second; IbisWaveform* fallingWF = aPair.second;
if( rectWave->m_ton < risingWF->m_table->m_entries.back().t ) if( rectWave->m_ton < risingWF->m_table.m_entries.back().t )
{ {
Report( _( "Rising edge is longer than on time." ), RPT_SEVERITY_WARNING ); Report( _( "Rising edge is longer than on time." ), RPT_SEVERITY_WARNING );
} }
if( rectWave->m_toff < fallingWF->m_table->m_entries.back().t ) if( rectWave->m_toff < fallingWF->m_table.m_entries.back().t )
{ {
Report( _( "Falling edge is longer than off time." ), RPT_SEVERITY_WARNING ); Report( _( "Falling edge is longer than off time." ), RPT_SEVERITY_WARNING );
} }
@ -727,7 +751,7 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
{ {
IbisWaveform* fallingWF = aPair.second; IbisWaveform* fallingWF = aPair.second;
simul += "Vsig DIE0 GND "; simul += "Vsig DIE0 GND ";
simul += doubleToString( fallingWF->m_table->m_entries.at( 0 ).V->value[aSupply] ); simul += doubleToString( fallingWF->m_table.m_entries.at( 0 ).V.value[aSupply] );
simul += "\n"; simul += "\n";
break; break;
} }
@ -735,7 +759,7 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
{ {
IbisWaveform* risingWF = aPair.first; IbisWaveform* risingWF = aPair.first;
simul += "Vsig DIE0 GND "; simul += "Vsig DIE0 GND ";
simul += doubleToString( risingWF->m_table->m_entries.at( 0 ).V->value[aSupply] ); simul += doubleToString( risingWF->m_table.m_entries.at( 0 ).V.value[aSupply] );
simul += "\n"; simul += "\n";
break; break;
} }
@ -772,7 +796,7 @@ void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aMod
simul += "\n x1 3 0 1 DRIVER0 \n"; simul += "\n x1 3 0 1 DRIVER0 \n";
simul += "VCC 3 0 "; simul += "VCC 3 0 ";
simul += doubleToString( aModel.m_voltageRange->value[aSupply] ); simul += doubleToString( aModel.m_voltageRange.value[aSupply] );
simul += "\n"; simul += "\n";
//simul += "Vpin x1.DIE 0 1 \n" //simul += "Vpin x1.DIE 0 1 \n"
simul += "Lfixture 1 4 "; simul += "Lfixture 1 4 ";
@ -859,7 +883,7 @@ void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_WAVEFORM* aWave, I
ku.push_back( 1 ); ku.push_back( 1 );
kd.push_back( 0 ); kd.push_back( 0 );
t.push_back( ( rectWave->m_ton + rectWave->m_toff ) * i t.push_back( ( rectWave->m_ton + rectWave->m_toff ) * i
+ aModel.m_ramp->m_rising->value[aSupply].m_dt + aModel.m_ramp.m_rising.value[aSupply].m_dt
/ 0.6 ); // 0.6 because ibis only gives 20%-80% time / 0.6 ); // 0.6 because ibis only gives 20%-80% time
ku.push_back( 1 ); ku.push_back( 1 );
kd.push_back( 0 ); kd.push_back( 0 );
@ -867,7 +891,7 @@ void KIBIS_PIN::getKuKdNoWaveform( KIBIS_MODEL& aModel, KIBIS_WAVEFORM* aWave, I
ku.push_back( 0 ); ku.push_back( 0 );
kd.push_back( 1 ); kd.push_back( 1 );
t.push_back( ( rectWave->m_ton + rectWave->m_toff ) * i + rectWave->m_toff t.push_back( ( rectWave->m_ton + rectWave->m_toff ) * i + rectWave->m_toff
+ aModel.m_ramp->m_falling->value[aSupply].m_dt / 0.6 ); + aModel.m_ramp.m_falling.value[aSupply].m_dt / 0.6 );
} }
break; break;
} }
@ -923,7 +947,7 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
simul += "\n x1 3 0 1 DRIVER0 \n"; simul += "\n x1 3 0 1 DRIVER0 \n";
simul += "VCC 3 0 "; simul += "VCC 3 0 ";
simul += doubleToString( aModel.m_voltageRange->value[aSupply] ); simul += doubleToString( aModel.m_voltageRange.value[aSupply] );
simul += "\n"; simul += "\n";
//simul += "Vpin x1.DIE 0 1 \n" //simul += "Vpin x1.DIE 0 1 \n"
simul += "Lfixture0 1 4 "; simul += "Lfixture0 1 4 ";
@ -1067,13 +1091,13 @@ bool KIBIS_PIN::writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_M
result += "\n"; result += "\n";
result += "RPIN 1 PIN "; result += "RPIN 1 PIN ";
result += doubleToString( R_pin->value[aParasitics] ); result += doubleToString( m_Rpin.value[aParasitics] );
result += "\n"; result += "\n";
result += "LPIN DIE0 1 "; result += "LPIN DIE0 1 ";
result += doubleToString( L_pin->value[aParasitics] ); result += doubleToString( m_Lpin.value[aParasitics] );
result += "\n"; result += "\n";
result += "CPIN PIN GND "; result += "CPIN PIN GND ";
result += doubleToString( C_pin->value[aParasitics] ); result += doubleToString( m_Cpin.value[aParasitics] );
result += "\n"; result += "\n";
std::vector<std::pair<IbisWaveform*, IbisWaveform*>> wfPairs = aModel.waveformPairs(); std::vector<std::pair<IbisWaveform*, IbisWaveform*>> wfPairs = aModel.waveformPairs();
@ -1162,13 +1186,13 @@ bool KIBIS_PIN::writeSpiceDevice( std::string* aDest, std::string aName, KIBIS_M
result += "\n"; result += "\n";
result += "\n"; result += "\n";
result += "RPIN 1 PIN "; result += "RPIN 1 PIN ";
result += doubleToString( R_pin->value[aParasitics] ); result += doubleToString( m_Rpin.value[aParasitics] );
result += "\n"; result += "\n";
result += "LPIN DIE 1 "; result += "LPIN DIE 1 ";
result += doubleToString( L_pin->value[aParasitics] ); result += doubleToString( m_Lpin.value[aParasitics] );
result += "\n"; result += "\n";
result += "CPIN PIN GND "; result += "CPIN PIN GND ";
result += doubleToString( C_pin->value[aParasitics] ); result += doubleToString( m_Cpin.value[aParasitics] );
result += "\n"; result += "\n";

View File

@ -73,9 +73,9 @@ class KIBIS_WAVEFORM_RECTANGULAR : public KIBIS_WAVEFORM
{ {
public: public:
KIBIS_WAVEFORM_RECTANGULAR() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::RECTANGULAR; }; KIBIS_WAVEFORM_RECTANGULAR() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::RECTANGULAR; };
double m_ton; double m_ton = 1;
double m_toff; double m_toff = 1;
int m_cycles; int m_cycles = 1;
double m_delay = 0; double m_delay = 0;
}; };
@ -171,24 +171,24 @@ public:
IBIS_MODEL_POLARITY m_polarity = IBIS_MODEL_POLARITY::UNDEFINED; IBIS_MODEL_POLARITY m_polarity = IBIS_MODEL_POLARITY::UNDEFINED;
// End of optional subparameters // End of optional subparameters
TypMinMaxValue* m_C_comp; TypMinMaxValue m_C_comp;
TypMinMaxValue* m_voltageRange; TypMinMaxValue m_voltageRange;
TypMinMaxValue* m_temperatureRange; TypMinMaxValue m_temperatureRange;
TypMinMaxValue* m_pullupReference; TypMinMaxValue m_pullupReference;
TypMinMaxValue* m_pulldownReference; TypMinMaxValue m_pulldownReference;
TypMinMaxValue* m_GNDClampReference; TypMinMaxValue m_GNDClampReference;
TypMinMaxValue* m_POWERClampReference; TypMinMaxValue m_POWERClampReference;
TypMinMaxValue* m_Rgnd; TypMinMaxValue m_Rgnd;
TypMinMaxValue* m_Rpower; TypMinMaxValue m_Rpower;
TypMinMaxValue* m_Rac; TypMinMaxValue m_Rac;
TypMinMaxValue* m_Cac; TypMinMaxValue m_Cac;
IVtable* m_GNDClamp; IVtable m_GNDClamp;
IVtable* m_POWERClamp; IVtable m_POWERClamp;
IVtable* m_pullup; IVtable m_pullup;
IVtable* m_pulldown; IVtable m_pulldown;
std::vector<IbisWaveform*> m_risingWaveforms; std::vector<IbisWaveform*> m_risingWaveforms;
std::vector<IbisWaveform*> m_fallingWaveforms; std::vector<IbisWaveform*> m_fallingWaveforms;
IbisRamp* m_ramp; IbisRamp m_ramp;
/** @brief Return true if the model has a pulldown transistor */ /** @brief Return true if the model has a pulldown transistor */
bool HasPulldown(); bool HasPulldown();
@ -262,11 +262,11 @@ public:
std::string m_pinNumber; std::string m_pinNumber;
/** @brief Resistance from die to pin */ /** @brief Resistance from die to pin */
TypMinMaxValue* R_pin; TypMinMaxValue m_Rpin;
/** @brief Inductance from die to pin */ /** @brief Inductance from die to pin */
TypMinMaxValue* L_pin; TypMinMaxValue m_Lpin;
/** @brief Capacitance from pin to GND */ /** @brief Capacitance from pin to GND */
TypMinMaxValue* C_pin; TypMinMaxValue m_Cpin;
KIBIS_COMPONENT* m_parent; KIBIS_COMPONENT* m_parent;