50std::vector<std::pair<int, double>>
53 std::vector<std::pair<int, double>> result;
56 for(
const std::pair<int, double>& bit : bits )
58 if( prevbit != bit.first )
59 result.push_back( bit );
73 IBIS_ANY( aReporter ), m_topLevel( aTopLevel ), m_valid( false )
94 KIBIS_ANY( this, aReporter ), m_file( *this )
117 pin.m_parent = &kComponent;
164 KIBIS_ANY( &aTopLevel ), m_Rpin( aTopLevel.m_reporter ), m_Lpin( aTopLevel.m_reporter ),
165 m_Cpin( aTopLevel.m_reporter )
181 if( !std::isnan( aPin.
m_Rpin ) )
188 if( !std::isnan( aPin.
m_Lpin ) )
195 if( !std::isnan( aPin.
m_Cpin ) )
202 bool modelSelected =
false;
203 std::vector<std::string> listOfModels;
213 modelSelected =
true;
223 for(
const std::string& modelName : listOfModels )
227 if( !strcmp( model.m_name.c_str(), modelName.c_str() ) )
239 KIBIS_ANY( &aTopLevel ), m_C_comp( aTopLevel.m_reporter ),
240 m_voltageRange( aTopLevel.m_reporter ), m_temperatureRange( aTopLevel.m_reporter ),
241 m_pullupReference( aTopLevel.m_reporter ), m_pulldownReference( aTopLevel.m_reporter ),
242 m_GNDClampReference( aTopLevel.m_reporter ), m_POWERClampReference( aTopLevel.m_reporter ),
243 m_Rgnd( aTopLevel.m_reporter ), m_Rpower( aTopLevel.m_reporter ),
244 m_Rac( aTopLevel.m_reporter ), m_Cac( aTopLevel.m_reporter ),
245 m_GNDClamp( aTopLevel.m_reporter ), m_POWERClamp( aTopLevel.m_reporter ),
246 m_pullup( aTopLevel.m_reporter ), m_pulldown( aTopLevel.m_reporter ),
247 m_ramp( aTopLevel.m_reporter )
331 if(
pin.m_pinNumber == aPinNumber )
342 std::vector<std::pair<IbisWaveform*, IbisWaveform*>> pairs;
358 pairs.emplace_back( wf1, wf2 );
371 std::string GC_GND =
"GC_GND";
372 std::string PC_PWR =
"PC_PWR";
373 std::string PU_PWR =
"PU_PWR";
374 std::string PD_GND =
"PD_GND";
375 std::string DIE =
"DIE";
376 std::string DIEBUFF =
"DIEBUFF";
381 GC_GND += std::to_string( aIndex );
382 PC_PWR += std::to_string( aIndex );
383 PU_PWR += std::to_string( aIndex );
384 PD_GND += std::to_string( aIndex );
385 DIE += std::to_string( aIndex );
386 DIEBUFF += std::to_string( aIndex );
389 std::string GC =
"GC";
390 std::string PC =
"PC";
391 std::string PU =
"PU";
392 std::string PD =
"PD";
394 GC += std::to_string( aIndex );
395 PC += std::to_string( aIndex );
396 PU += std::to_string( aIndex );
397 PD += std::to_string( aIndex );
400 result +=
"VPWR POWER GND ";
403 result +=
"CCPOMP " + DIE +
" GND ";
410 result +=
"VmeasGC GND " + GC_GND +
" 0\n";
416 result +=
"VmeasPC POWER " + PC_PWR +
" 0\n";
421 result +=
m_pulldown.
Spice( aIndex * 4 + 3, DIEBUFF, PD_GND, PD, supply );
422 result +=
"VmeasPD GND " + PD_GND +
" 0\n";
423 result +=
"BKD GND " + DIE +
" i=( i(VmeasPD) * v(KD) )\n";
428 result +=
m_pullup.
Spice( aIndex * 4 + 4, PU_PWR, DIEBUFF, PU, supply );
429 result +=
"VmeasPU POWER " + PU_PWR +
" 0\n";
430 result +=
"BKU POWER " + DIE +
" i=( -i(VmeasPU) * v(KU) )\n";
434 result +=
"BDIEBUFF " + DIEBUFF +
" GND v=v(" + DIE +
")\n";
463 for(
int i = 0; i < nbPoints; i++ )
468 outEntry.
t = inEntry.
t;
469 outEntry.
V.
value[IBIS_CORNER::TYP] = inEntry.
V.
value[IBIS_CORNER::TYP] - DCtyp;
470 outEntry.
V.
value[IBIS_CORNER::MIN] = inEntry.
V.
value[IBIS_CORNER::MIN] - DCmin;
471 outEntry.
V.
value[IBIS_CORNER::MAX] = inEntry.
V.
value[IBIS_CORNER::MAX] - DCmax;
503 const std::vector<std::pair<int, double>>& aBits,
504 const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
509 std::vector<int> stimuliIndex;
521 double delta = deltaR + deltaF;
527 for(
const std::pair<int, double>& bit : aBits )
530 double timing = bit.second;
533 if ( bit.first != prevBit )
540 stimuliIndex.push_back( i );
543 simul += std::to_string( i );
545 simul += std::to_string( i );
548 simul +=
" pwl ( \n+";
555 double deltaT = entry1.
t - entry0.
t;
583 for(
int ii: stimuliIndex )
585 simul +=
" v( stimuli";
586 simul += std::to_string( ii );
592 if( ( aBits.size() > 0 ) && ( aBits[0].first == 0 ) )
594 simul +=
doubleToString( aPair.second->m_table.m_entries.at( 0 ).V.value[supply] );
598 simul +=
doubleToString( aPair.first->m_table.m_entries.at( 0 ).V.value[supply] );
611 std::string GC_GND =
"GC_GND";
612 std::string PC_PWR =
"PC_PWR";
613 std::string PU_PWR =
"PU_PWR";
614 std::string PD_GND =
"PD_GND";
615 std::string DIE =
"DIE";
617 GC_GND += std::to_string( aIndex );
618 PC_PWR += std::to_string( aIndex );
619 PU_PWR += std::to_string( aIndex );
620 PD_GND += std::to_string( aIndex );
621 DIE += std::to_string( aIndex );
624 std::string GC =
"GC";
625 std::string PC =
"PC";
626 std::string PU =
"PU";
627 std::string PD =
"PD";
629 GC += std::to_string( aIndex );
630 PC += std::to_string( aIndex );
631 PU += std::to_string( aIndex );
632 PD += std::to_string( aIndex );
636 simul += aModel.
m_GNDClamp.
Spice( aIndex * 4 + 1, DIE, GC_GND, GC, supply );
646 simul += aModel.
m_pulldown.
Spice( aIndex * 4 + 3, DIE, PD_GND, PD, supply );
651 simul += aModel.
m_pullup.
Spice( aIndex * 4 + 4, PU_PWR, DIE, PU, supply );
662 if( std::remove( outputFileName.c_str() ) )
671 throw std::runtime_error(
"Could not create simulator instance" );
675 ng->LoadNetlist( aSimul );
677 std::ifstream KuKdfile;
678 KuKdfile.open( outputFileName );
680 std::vector<double>
ku, kd, t;
685 for(
int i = 0; i < 11; i++ )
687 std::getline( KuKdfile, line );
691 double t_v, ku_v, kd_v;
695 std::getline( KuKdfile, line );
705 line = line.substr( line.find_first_of(
"\t" ) + 1 );
706 t_v = std::stod( line );
708 case 1: ku_v = std::stod( line );
break;
710 kd_v = std::stod( line );
711 ku.push_back( ku_v );
712 kd.push_back( kd_v );
720 std::getline( KuKdfile, line );
727 if( std::remove( outputFileName.c_str() ) )
739 const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
746 std::string simul =
"";
748 simul +=
"*THIS IS NOT A VALID SPICE MODEL.\n";
749 simul +=
"*This part is intended to be executed by Kibis internally.\n";
750 simul +=
"*You should not be able to read this.\n\n";
752 simul +=
".SUBCKT DRIVER";
753 simul += std::to_string( aIndex );
754 simul +=
" POWER GND PIN \n";
756 simul +=
"Vdummy 2 PIN 0\n";
758 if( ( aPair.first->m_R_dut != 0 ) || ( aPair.first->m_L_dut != 0 )
759 || ( aPair.first->m_C_dut != 0 ) )
761 Report(
_(
"Kibis does not support DUT values yet. "
762 "https://ibis.org/summits/nov16a/chen.pdf" ),
767 simul +=
"CCPOMP 2 GND ";
776 case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
777 case KIBIS_WAVEFORM_TYPE::PRBS:
779 wave->
Check( risingWF, fallingWF );
785 case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
788 simul +=
"Vsig DIE0 GND ";
793 case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
796 simul +=
"Vsig DIE0 GND ";
801 case KIBIS_WAVEFORM_TYPE::NONE:
802 case KIBIS_WAVEFORM_TYPE::HIGH_Z:
805 simul +=
addDie( aModel, aParam, 0 );
807 simul +=
"\n.ENDS DRIVER\n\n";
813 const std::pair<IbisWaveform*, IbisWaveform*>& aPair,
819 std::string simul =
"";
824 if( wave->
GetType() == KIBIS_WAVEFORM_TYPE::NONE )
827 std::vector<double>
ku, kd, t;
837 simul +=
KuKdDriver( aModel, aPair, aParam, 0 );
838 simul +=
"\n x1 3 0 1 DRIVER0 \n";
844 simul +=
"Lfixture 1 4 ";
847 simul +=
"Rfixture 4 5 ";
850 simul +=
"Cfixture 4 0 ";
853 simul +=
"Vfixture 5 0 ";
856 simul +=
"VmeasIout x1.DIE0 x1.2 0\n";
857 simul +=
"VmeasPD 0 x1.PD_GND0 0\n";
858 simul +=
"VmeasPU x1.PU_PWR0 3 0\n";
859 simul +=
"VmeasPC x1.PC_PWR0 3 0\n";
860 simul +=
"VmeasGC 0 x1.GC_GND0 0\n";
864 Report(
_(
"Model has only one waveform pair, reduced accuracy" ),
866 simul +=
"Bku KU 0 v=( (i(VmeasIout)-i(VmeasPC)-i(VmeasGC)-i(VmeasPD) "
867 ")/(i(VmeasPU)-i(VmeasPD)))\n";
868 simul +=
"Bkd KD 0 v=(1-v(KU))\n";
873 simul +=
"Bku KD 0 v=( ( i(VmeasIout)+i(VmeasPC)+i(VmeasGC) )/(i(VmeasPD)))\n";
874 simul +=
"Bkd KU 0 v=0\n";
879 simul +=
"Bku KU 0 v=( ( i(VmeasIout)+i(VmeasPC)+i(VmeasGC) )/(i(VmeasPU)))\n";
880 simul +=
"Bkd KD 0 v=0\n";
889 case KIBIS_WAVEFORM_TYPE::PRBS:
890 case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
893 simul +=
".tran 0.1n ";
898 case KIBIS_WAVEFORM_TYPE::HIGH_Z:
899 case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
900 case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
901 default: simul +=
".tran 0.5 1 \n";
904 simul +=
".control run \n";
905 simul +=
"set filetype=ascii\n";
911 simul +=
"write '" + outputFileName +
"' v(KU) v(KD)\n";
923 std::vector<double>
ku, kd, t;
934 case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
935 case KIBIS_WAVEFORM_TYPE::PRBS:
941 for(
const std::pair<int, double>& bit : bits )
943 ku.push_back( bit.first ? 0 : 1 );
944 kd.push_back( bit.first ? 1 : 0 );
945 t.push_back( bit.second );
946 ku.push_back( bit.first ? 1 : 0 );
947 kd.push_back( bit.first ? 0 : 1 );
948 t.push_back( bit.second
956 case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
959 kd.push_back( wave->
inverted ? 1 : 0 );
963 case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
966 kd.push_back( wave->
inverted ? 0 : 1 );
970 case KIBIS_WAVEFORM_TYPE::HIGH_Z:
971 case KIBIS_WAVEFORM_TYPE::NONE:
984 const std::pair<IbisWaveform*, IbisWaveform*>& aPair1,
985 const std::pair<IbisWaveform*, IbisWaveform*>& aPair2,
988 std::string simul =
"";
995 if( wave->
GetType() == KIBIS_WAVEFORM_TYPE::NONE )
998 std::vector<double>
ku, kd, t;
1008 simul +=
KuKdDriver( aModel, aPair1, aParam, 0 );
1009 simul +=
KuKdDriver( aModel, aPair2, aParam, 1 );
1010 simul +=
"\n x1 3 0 1 DRIVER0 \n";
1012 simul +=
"VCC 3 0 ";
1016 simul +=
"Lfixture0 1 4 ";
1019 simul +=
"Rfixture0 4 5 ";
1022 simul +=
"Cfixture0 4 0 ";
1025 simul +=
"Vfixture0 5 0 ";
1028 simul +=
"VmeasIout0 x1.2 x1.DIE0 0\n";
1029 simul +=
"VmeasPD0 0 x1.PD_GND0 0\n";
1030 simul +=
"VmeasPU0 x1.PU_PWR0 3 0\n";
1031 simul +=
"VmeasPC0 x1.PC_PWR0 3 0\n";
1032 simul +=
"VmeasGC0 0 x1.GC_GND0 0\n";
1035 simul +=
"\n x2 3 0 7 DRIVER1 \n";
1037 simul +=
"Lfixture1 7 8 ";
1040 simul +=
"Rfixture1 8 9 ";
1043 simul +=
"Cfixture1 8 0 ";
1046 simul +=
"Vfixture1 9 0 ";
1049 simul +=
"VmeasIout1 x2.2 x2.DIE0 0\n";
1050 simul +=
"VmeasPD1 0 x2.PD_GND0 0\n";
1051 simul +=
"VmeasPU1 x2.PU_PWR0 3 0\n";
1052 simul +=
"VmeasPC1 x2.PC_PWR0 3 0\n";
1053 simul +=
"VmeasGC1 0 x2.GC_GND0 0\n";
1058 "Bku KU 0 v=( ( i(VmeasPD1) * ( i(VmeasIout0) + i(VmeasPC0) + i(VmeasGC0) ) - "
1059 "i(VmeasPD0) * ( i(VmeasIout1) + i(VmeasPC1) + i(VmeasGC1) ) )/ ( i(VmeasPU1) "
1061 "i(VmeasPD0) - i(VmeasPU0) * i(VmeasPD1) ) )\n";
1063 "Bkd KD 0 v=( ( i(VmeasPU1) * ( i(VmeasIout0) + i(VmeasPC0) + i(VmeasGC0) ) - "
1064 "i(VmeasPU0) * ( i(VmeasIout1) + i(VmeasPC1) + i(VmeasGC1) ) )/ ( i(VmeasPD1) "
1066 "i(VmeasPU0) - i(VmeasPD0) * i(VmeasPU1) ) )\n";
1072 Report(
_(
"There are two waveform pairs, but only one transistor. More equations than "
1075 simul +=
"Bku KD 0 v=( ( i(VmeasIout0)+i(VmeasPC0)+i(VmeasGC0) )/(i(VmeasPD0)))\n";
1076 simul +=
"Bkd KU 0 v=0\n";
1081 Report(
_(
"There are two waveform pairs, but only one transistor. More equations than "
1084 simul +=
"Bku KU 0 v=( ( i(VmeasIout)+i(VmeasPC)+i(VmeasGC) )/(i(VmeasPU)))\n";
1085 simul +=
"Bkd KD 0 v=0\n";
1094 case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
1095 case KIBIS_WAVEFORM_TYPE::PRBS:
1098 simul +=
".tran 0.1n ";
1103 case KIBIS_WAVEFORM_TYPE::HIGH_Z:
1104 case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
1105 case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
1106 default: simul +=
".tran 0.5 1 \n";
1109 simul +=
".control run \n";
1110 simul +=
"set filetype=ascii\n";
1112 simul +=
"plot v(KU) v(KD)\n";
1115 simul +=
"write '" + outputFileName +
"' v(KU) v(KD)\n";
1117 simul +=
".endc \n";
1132 case IBIS_MODEL_TYPE::OUTPUT:
1133 case IBIS_MODEL_TYPE::IO:
1134 case IBIS_MODEL_TYPE::THREE_STATE:
1135 case IBIS_MODEL_TYPE::OPEN_DRAIN:
1136 case IBIS_MODEL_TYPE::IO_OPEN_DRAIN:
1137 case IBIS_MODEL_TYPE::OPEN_SINK:
1138 case IBIS_MODEL_TYPE::IO_OPEN_SINK:
1139 case IBIS_MODEL_TYPE::OPEN_SOURCE:
1140 case IBIS_MODEL_TYPE::IO_OPEN_SOURCE:
1141 case IBIS_MODEL_TYPE::OUTPUT_ECL:
1142 case IBIS_MODEL_TYPE::IO_ECL:
1143 case IBIS_MODEL_TYPE::THREE_STATE_ECL:
1148 result =
"\n*Driver model generated by Kicad using Ibis data. ";
1149 result +=
"\n*Component: ";
1155 result +=
"\n*Manufacturer: ";
1161 result +=
"\n*Pin number: ";
1163 result +=
"\n*Signal name: ";
1165 result +=
"\n*Model: ";
1167 result +=
"\n.SUBCKT ";
1169 result +=
" GND PIN \n";
1172 result +=
"RPIN 1 PIN ";
1175 result +=
"LPIN DIE0 1 ";
1178 result +=
"CPIN PIN GND ";
1182 std::vector<std::pair<IbisWaveform*, IbisWaveform*>> wfPairs = aModel.
waveformPairs();
1185 if( wfPairs.size() < 1 || accuracy <= KIBIS_ACCURACY::LEVEL_0 )
1187 if( accuracy > KIBIS_ACCURACY::LEVEL_0 )
1189 Report(
_(
"Model has no waveform pair, using [Ramp] instead, poor accuracy" ),
1194 else if( wfPairs.size() == 1 || accuracy <= KIBIS_ACCURACY::LEVEL_1 )
1200 if( wfPairs.size() > 2 || accuracy <= KIBIS_ACCURACY::LEVEL_2 )
1202 Report(
_(
"Model has more than 2 waveform pairs, using the first two." ),
1208 result +=
"Vku KU GND pwl ( ";
1210 for(
size_t i = 0; i <
m_t.size(); i++ )
1221 result +=
"Vkd KD GND pwl ( ";
1223 for(
size_t i = 0; i <
m_t.size(); i++ )
1233 result += aModel.
SpiceDie( aParam, 0 );
1235 result +=
"\n.ENDS DRIVER\n\n";
1254 case IBIS_MODEL_TYPE::INPUT_STD:
1255 case IBIS_MODEL_TYPE::IO:
1256 case IBIS_MODEL_TYPE::IO_OPEN_DRAIN:
1257 case IBIS_MODEL_TYPE::IO_OPEN_SINK:
1258 case IBIS_MODEL_TYPE::IO_OPEN_SOURCE:
1259 case IBIS_MODEL_TYPE::IO_ECL:
1264 result =
"*Device model generated by Kicad using Ibis data.";
1265 result +=
"\n.SUBCKT ";
1267 result +=
" GND PIN\n";
1270 result +=
"RPIN 1 PIN ";
1273 result +=
"LPIN DIE0 1 ";
1276 result +=
"CPIN PIN GND ";
1281 result +=
"Vku KU GND pwl ( 0 0 )\n";
1282 result +=
"Vkd KD GND pwl ( 0 0 )\n";
1284 result += aModel.
SpiceDie( aParam, 0 );
1286 result +=
"\n.ENDS DRIVER\n\n";
1288 aDest = std::move( result );
1308 result =
"\n*Differential driver model generated by Kicad using Ibis data. ";
1309 result +=
"\n*Component: ";
1315 result +=
"\n*Manufacturer: ";
1322 result +=
"\n.SUBCKT ";
1324 result +=
" GND PIN_P PIN_N\n";
1334 result +=
"x1 GND PIN_P " + aName +
"_P \n";
1335 result +=
"x2 GND PIN_N " + aName +
"_N \n";
1338 result +=
"\n.ENDS " + aName +
"\n\n";
1355 result =
"\n*Differential device model generated by Kicad using Ibis data. ";
1356 result +=
"\n*Component: ";
1362 result +=
"\n*Manufacturer: ";
1369 result +=
"\n.SUBCKT ";
1371 result +=
" GND PIN_P PIN_N\n";
1378 result +=
"x1 GND PIN_P " + aName +
"_P \n";
1379 result +=
"x2 GND PIN_N " + aName +
"_N \n";
1382 result +=
"\n.ENDS " + aName +
"\n\n";
1397 if( model.m_name == aName )
1408 if( cmp.m_name == aName )
1417 if( aString ==
"MIN" )
1418 aCorner = IBIS_CORNER::MIN;
1419 else if( aString ==
"MAX" )
1420 aCorner = IBIS_CORNER::MAX;
1422 aCorner = IBIS_CORNER::TYP;
1428 std::vector<std::pair<int, double>> bits;
1429 std::pair<int, double> bit;
1438 std::vector<std::pair<int, double>> bits;
1439 std::pair<int, double> bit;
1447 std::vector<std::pair<int, double>> bits;
1453 std::vector<std::pair<int, double>> bits;
1455 for(
int i = 0; i <
m_cycles; i++ )
1457 std::pair<int, double> bit;
1460 bits.push_back( bit );
1464 bits.push_back( bit );
1472 std::vector<std::pair<int, double>> bitSequence;
1473 uint8_t polynomial = 0b1100000;
1477 uint8_t seed = 0x12;
1478 uint8_t lfsr = seed;
1491 uint8_t lsb = lfsr & 0x01;
1492 bitSequence.emplace_back( (
static_cast<uint8_t
>(
inverted ) ^ lsb ? 1 : 0 ), t );
1500 }
while ( ++bits <
m_bits );
1530 if( m_ton < aRisingWf->m_table.m_entries.back().t )
1539 if( m_toff < aFallingWf->m_table.m_entries.back().t )
1546 status &= aRisingWf && aFallingWf;
1614 + aFallingRp.
value[IBIS_CORNER::TYP].
m_dt / 0.6 ) )
1616 + aFallingRp.
value[IBIS_CORNER::TYP].
m_dt / 0.6 ) )
1618 + aFallingRp.
value[IBIS_CORNER::TYP].
m_dt / 0.6 ) ) )
1644 if(
m_bitrate && aRisingWf && aFallingWf
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< 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.
std::string m_manufacturer
IbisComponentPackage m_package
std::vector< IbisComponentPin > m_pins
std::vector< IbisDiffPinEntry > m_entries
std::vector< IbisComponent > m_components
std::vector< IbisModel > m_models
std::vector< IbisModelSelector > m_modelSelectors
std::string m_modelDescription
std::vector< IbisModelSelectorEntry > m_models
TypMinMaxValue m_pullupReference
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
bool ParseFile(const std::string &aFileName)
Parse a file.
KIBIS_ANY(KIBIS *aTopLevel)
KIBIS_COMPONENT(KIBIS &aToplevel, const IbisComponent &aSource, IbisParser &aParser)
std::vector< KIBIS_PIN > m_pins
std::string m_manufacturer
Name of the manufacturer.
std::string m_name
Name of the component.
KIBIS_PIN * GetPin(const std::string &aPinNumber)
Get a pin by its number ( 1, 2, A1, A2, ... )
KIBIS_FILE(KIBIS &aTopLevel)
bool Init(const IbisParser &aParser)
std::vector< IbisWaveform * > m_fallingWaveforms
IbisWaveform TrimWaveform(const IbisWaveform &aIn) const
Copy a waveform, and substract the first value to all samples.
IBIS_MODEL_ENABLE m_enable
bool HasPOWERClamp() const
Return true if the model has a clamp diode to the power net.
std::vector< IbisWaveform * > m_risingWaveforms
bool HasPullup() const
Return true if the model has a pullup transistor.
bool HasGNDClamp() const
Return true if the model has a clamp diode to the gnd net.
TypMinMaxValue m_pulldownReference
TypMinMaxValue m_GNDClampReference
bool HasPulldown() const
Return true if the model has a pulldown transistor.
IBIS_MODEL_POLARITY m_polarity
std::string generateSquareWave(const std::string &aNode1, const std::string &aNode2, const std::vector< std::pair< int, double > > &aBits, const std::pair< IbisWaveform *, IbisWaveform * > &aPair, const KIBIS_PARAMETER &aParam)
Generate a square waveform.
TypMinMaxValue m_temperatureRange
TypMinMaxValue m_voltageRange
std::string m_description
KIBIS_MODEL(KIBIS &aTopLevel, const IbisModel &aSource, IbisParser &aParser)
TypMinMaxValue m_pullupReference
std::vector< std::pair< IbisWaveform *, IbisWaveform * > > waveformPairs()
Create waveform pairs.
TypMinMaxValue m_POWERClampReference
std::string SpiceDie(const KIBIS_PARAMETER &aParam, int aIndex) const
Generate the spice directive to simulate the die.
KIBIS_ACCURACY m_accuracy
void SetCornerFromString(IBIS_CORNER &aCorner, const std::string &aString)
KIBIS_WAVEFORM * m_waveform
TypMinMaxValue m_Rpin
Resistance from die to pin.
bool writeSpiceDiffDriver(std::string &aDest, const std::string &aName, KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam)
TypMinMaxValue m_Lpin
Inductance from die to pin.
void getKuKdFromFile(const std::string &aSimul)
Update m_Ku, m_Kd using with two waveform inputs.
KIBIS_COMPONENT * m_parent
std::vector< double > m_Ku
std::string m_pinNumber
Pin Number Examples : 1, 2, 3 ( or for BGA ), A1, A2, A3, etc...
std::string addDie(KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam, int aIndex)
Generate the spice directive to simulate the die for Ku/Kd estimation.
bool writeSpiceDevice(std::string &aDest, const std::string &aName, KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam)
std::vector< KIBIS_MODEL * > m_models
std::vector< double > m_t
TypMinMaxValue m_Cpin
Capacitance from pin to GND.
std::string m_signalName
Name of the pin Examples : "VCC", "GPIOA", "CLK", etc...
void getKuKdTwoWaveforms(KIBIS_MODEL &aModel, const std::pair< IbisWaveform *, IbisWaveform * > &aPair1, const std::pair< IbisWaveform *, IbisWaveform * > &aPair2, const KIBIS_PARAMETER &aParam)
Update m_Ku, m_Kd using with two waveform inputs.
void getKuKdOneWaveform(KIBIS_MODEL &aModel, const std::pair< IbisWaveform *, IbisWaveform * > &aPair, const KIBIS_PARAMETER &aParam)
Update m_Ku, m_Kd using with a single waveform input.
bool writeSpiceDiffDevice(std::string &aDest, const std::string &aName, KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam)
std::string KuKdDriver(KIBIS_MODEL &aModel, const std::pair< IbisWaveform *, IbisWaveform * > &aPair, const KIBIS_PARAMETER &aParam, int aIndex)
Update m_Ku, m_Kd using with two waveform inputs.
KIBIS_PIN(KIBIS &aTopLevel, const IbisComponentPin &aPin, const IbisComponentPackage &aPackage, IbisParser &aParser, KIBIS_COMPONENT *aParent, std::vector< KIBIS_MODEL > &aModels)
std::vector< double > m_Kd
bool writeSpiceDriver(std::string &aDest, const std::string &aName, KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam)
KIBIS_PIN * m_complementaryPin
void getKuKdNoWaveform(KIBIS_MODEL &aModel, const KIBIS_PARAMETER &aParam)
Update m_Ku, m_Kd using no falling / rising waveform inputs ( low accuracy )
std::vector< KIBIS_MODEL > m_models
KIBIS()
Constructor for unitialized KIBIS members.
std::vector< KIBIS_COMPONENT > m_components
KIBIS_MODEL * GetModel(const std::string &aName)
Return the model with name aName .
KIBIS_COMPONENT * GetComponent(const std::string &aName)
Return the component with name aName .
std::string m_cacheDir
Absolute path of the directory that will be used for caching.
A pure virtual class used to derive REPORTER objects from.
static std::shared_ptr< SPICE_SIMULATOR > CreateInstance(const std::string &aName)
std::vector< VTtableEntry > m_entries
std::vector< std::pair< int, double > > SimplifyBitSequence(const std::vector< std::pair< int, double > > &bits)
IBIS_CORNER ReverseLogic(IBIS_CORNER aIn)
KIBIS_ACCURACY
Accuracy level.