Sim: Make Sim.Pins have key-value pairs instead of a sequence

Moreover, upgrade models on schematic load instead of on model load
This commit is contained in:
Mikolaj Wielgus 2022-11-25 05:31:03 +01:00
parent f5ebd6fb47
commit a65b35107d
10 changed files with 241 additions and 260 deletions

View File

@ -1280,75 +1280,154 @@ void SCH_SHEET_LIST::MigrateSimModelNameFields()
continue;
}
if( symbol->FindField( "Spice_Primitive" )
|| symbol->FindField( "Spice_Node_Sequence" )
|| symbol->FindField( "Spice_Model" )
|| symbol->FindField( "Spice_Netlist_Enabled" )
|| symbol->FindField( "Spice_Lib_File" ) )
{
// Has a legacy raw (plaintext) model -- this is handled in the SIM_MODEL class.
continue;
}
if( symbol->FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|| symbol->FindField( SIM_MODEL::TYPE_FIELD )
|| symbol->FindField( SIM_MODEL::PINS_FIELD )
|| symbol->FindField( SIM_MODEL::PARAMS_FIELD ) )
{
// Has a V7 model field - skip.
continue;
}
// Insert a plaintext model as a substitute.
wxString refdes = symbol->GetRef( &at( sheetIndex ), true );
if( refdes.Length() == 0 )
continue; // No refdes? We need the first character to determine type. Skip.
wxString value = symbol->GetValue( &at( sheetIndex ), true );
if( refdes.StartsWith( "R" )
|| refdes.StartsWith( "C" )
|| refdes.StartsWith( "L" ) )
{
// This is taken from the former Spice exporter.
wxRegEx passiveVal(
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
if( passiveVal.Matches( value ) )
{
wxString prefix( passiveVal.GetMatch( value, 1 ) );
wxString unit( passiveVal.GetMatch( value, 2 ) );
wxString suffix( passiveVal.GetMatch( value, 6 ) );
prefix.Trim(); prefix.Trim( false );
unit.Trim(); unit.Trim( false );
suffix.Trim(); suffix.Trim( false );
// Make 'mega' units comply with the Spice expectations
if( unit == "M" )
unit = "Meg";
std::unique_ptr<SIM_VALUE> simValue =
SIM_VALUE::Create( SIM_VALUE::TYPE_FLOAT );
simValue->FromString( std::string( ( prefix + unit + suffix ).ToUTF8() ),
SIM_VALUE::NOTATION::SPICE );
}
}
SCH_FIELD deviceTypeField( VECTOR2I( 0, 0 ), symbol->GetFieldCount(), symbol,
SIM_MODEL::DEVICE_TYPE_FIELD );
deviceTypeField.SetText(
SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_TYPE_::SPICE ).fieldValue );
symbol->AddField( deviceTypeField );
SCH_FIELD modelParamsField( VECTOR2I( 0, 0 ), symbol->GetFieldCount(), symbol,
SIM_MODEL::PARAMS_FIELD );
modelParamsField.SetText( wxString::Format( "type=%s model=\"%s\"",
refdes.Left( 1 ),
value ) );
symbol->AddField( modelParamsField );
migrateSimModel( *symbol, sheetIndex );
}
}
}
void SCH_SHEET_LIST::migrateSimModel( SCH_SYMBOL& aSymbol, unsigned aSheetIndex )
{
if( aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|| aSymbol.FindField( SIM_MODEL::TYPE_FIELD )
|| aSymbol.FindField( SIM_MODEL::PINS_FIELD )
|| aSymbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
{
// Has a V7 model field -- skip.
return;
}
wxString ref = aSymbol.GetRef( &at( aSheetIndex ), true );
wxString value = aSymbol.GetValue( &at( aSheetIndex ), true );
wxString spiceType;
wxString spiceModel;
wxString spiceLib;
wxString pinMap;
if( aSymbol.FindField( "Spice_Primitive" )
|| aSymbol.FindField( "Spice_Node_Sequence" )
|| aSymbol.FindField( "Spice_Model" )
|| aSymbol.FindField( "Spice_Netlist_Enabled" )
|| aSymbol.FindField( "Spice_Lib_File" ) )
{
if( SCH_FIELD* primitiveField = aSymbol.FindField( "Spice_Primitive" ) )
{
spiceType = primitiveField->GetText();
aSymbol.RemoveField( "Spice_Primitive" );
}
if( SCH_FIELD* nodeSequenceField = aSymbol.FindField( "Spice_Node_Sequence" ) )
{
const wxString delimiters( "{:,; }" );
const wxString& nodeSequence = nodeSequenceField->GetText();
if( nodeSequence != "" )
{
wxStringTokenizer tkz( nodeSequence, delimiters );
for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
{
long symbolPinNumber = 1;
tkz.GetNextToken().ToLong( &symbolPinNumber );
if( modelPinNumber != 1 )
pinMap.Append( " " );
pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
}
}
aSymbol.RemoveField( "Spice_Node_Sequence" );
}
if( SCH_FIELD* modelField = aSymbol.FindField( "Spice_Model" ) )
{
spiceModel = modelField->GetText();
aSymbol.RemoveField( "Spice_Model" );
}
else
spiceModel = aSymbol.FindField( "Value" )->GetText();
if( SCH_FIELD* netlistEnabledField = aSymbol.FindField( "Spice_Netlist_Enabled" ) )
{
wxString netlistEnabled = netlistEnabledField->GetText().Lower();
if( netlistEnabled.StartsWith( "0" )
|| netlistEnabled.StartsWith( "n" )
|| netlistEnabled.StartsWith( "f" ) )
{
SCH_FIELD enableField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
SIM_MODEL::ENABLE_FIELD );
}
}
if( SCH_FIELD* libFileField = aSymbol.FindField( "Spice_Lib_File" ) )
{
spiceLib = libFileField->GetText();
aSymbol.RemoveField( "Spice_Lib_File" );
}
}
else if( ref.StartsWith( "R" ) || ref.StartsWith( "L" ) || ref.StartsWith( "C" ) )
{
wxRegEx passiveVal(
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
if( !passiveVal.Matches( value ) )
return;
wxString prefix( passiveVal.GetMatch( value, 1 ) );
wxString unit( passiveVal.GetMatch( value, 2 ) );
wxString suffix( passiveVal.GetMatch( value, 6 ) );
if( unit == "M" )
unit = "Meg";
spiceModel = prefix + unit;
}
else if( ref.StartsWith( "V" ) || ref.StartsWith( "I" ) )
spiceModel = value;
else
return;
// Insert a plaintext model as a substitute.
SCH_FIELD deviceTypeField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
SIM_MODEL::DEVICE_TYPE_FIELD );
deviceTypeField.SetText(
SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_TYPE_::SPICE ).fieldValue );
aSymbol.AddField( deviceTypeField );
SCH_FIELD paramsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
SIM_MODEL::PARAMS_FIELD );
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
spiceType, spiceModel, spiceLib ) );
aSymbol.AddField( paramsField );
// Legacy models by default get linear pin mapping.
if( pinMap != "" )
{
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
SIM_MODEL::PINS_FIELD );
pinsField.SetText( pinMap );
aSymbol.AddField( pinsField );
}
else
{
wxString pins;
for( unsigned i = 0; i < aSymbol.GetLibPins().size(); ++i )
{
if( i != 0 )
pins.Append( " " );
pins.Append( wxString::Format( "%u=%u", i + 1, i + 1 ) );
}
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
SIM_MODEL::PINS_FIELD );
pinsField.SetText( pins );
aSymbol.AddField( pinsField );
}
}

View File

@ -651,11 +651,6 @@ public:
*/
void SetInitialPageNumbers();
/**
* Migrate V6 simulator models to V7. Must be called only after UpdateSymbolInstances().
*/
void MigrateSimModelNameFields();
/**
* Attempt to add new symbol instances for all symbols in this list of sheet paths prefixed
* with \a aPrefixSheetPath.
@ -671,7 +666,17 @@ public:
void RemoveSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
/**
* Migrate V6 simulator models to V7. Must be called only after UpdateSymbolInstances().
*/
void MigrateSimModelNameFields();
private:
/**
* Migrate a single V6 simulator model to V7. Must be called only after UpdateSymbolInstances().
*/
void migrateSimModel( SCH_SYMBOL& aSymbol, unsigned aSheetIndex );
SCH_SHEET_PATH m_currentSheetPath;
};

View File

@ -627,7 +627,7 @@ void SIM_MODEL::AddPin( const PIN& aPin )
m_pins.push_back( aPin );
}
void SIM_MODEL::DeletePins()
void SIM_MODEL::ClearPins()
{
m_pins.clear();
}
@ -661,6 +661,33 @@ std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> SIM_MODEL::GetPins() c
return pins;
}
void SIM_MODEL::SetPinSymbolPinNumber( int aPinIndex, const std::string& aSymbolPinNumber )
{
m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
}
void SIM_MODEL::SetPinSymbolPinNumber( const std::string& aPinName,
const std::string& aSymbolPinNumber )
{
const std::vector<std::reference_wrapper<const PIN>> pins = GetPins();
auto it = std::find_if( pins.begin(), pins.end(),
[aPinName]( const PIN& aPin )
{
return aPin.name == aPinName;
} );
if( it == pins.end() )
{
THROW_IO_ERROR( wxString::Format( _( "Could not find a pin named '%s' in simulation model of type '%s'" ),
aPinName,
GetTypeInfo().fieldValue ) );
}
SetPinSymbolPinNumber( static_cast<int>( it - pins.begin() ), aSymbolPinNumber );
}
const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const
{

View File

@ -443,7 +443,7 @@ public:
SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); }
void AddPin( const PIN& aPin );
void DeletePins();
void ClearPins();
int FindModelPinIndex( const std::string& aSymbolPinNumber );
void AddParam( const PARAM::INFO& aInfo, bool aIsOtherVariant = false );
@ -473,10 +473,8 @@ public:
std::vector<std::reference_wrapper<const PIN>> GetPins() const;
void SetPinSymbolPinNumber( int aPinIndex, const std::string& aSymbolPinNumber )
{
m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
}
void SetPinSymbolPinNumber( int aPinIndex, const std::string& aSymbolPinNumber );
void SetPinSymbolPinNumber( const std::string& aPinName, const std::string& aSymbolPinNumber );
int GetParamCount() const { return static_cast<int>( m_params.size() ); }

View File

@ -252,7 +252,7 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) :
void SIM_MODEL_KIBIS::SwitchSingleEndedDiff( bool aDiff )
{
DeletePins();
ClearPins();
if( aDiff )
{

View File

@ -105,7 +105,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instantaneous power", true );*/
modelInfos[MODEL_TYPE::DIODE] = { "Diode", "D", "", { "Anode", "Cathode" }, "Junction Diode model", {}, {} };
modelInfos[MODEL_TYPE::DIODE] = { "Diode", "D", "", { "A", "K" }, "Junction Diode model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::DIODE].modelParams.emplace_back( "level", 100, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1", "", "Diode level selector" );
modelInfos[MODEL_TYPE::DIODE].modelParams.emplace_back( "is", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "A", SIM_MODEL::PARAM::CATEGORY::DC, "1e-14", "", "Saturation current" );
@ -216,7 +216,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::DIODE].instanceParams.emplace_back( "sens_cplx", 16, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity", true );
modelInfos[MODEL_TYPE::BJT] = { "BJT", "NPN", "PNP", { "Collector", "Base", "Emitter" }, "Bipolar Junction Transistor", {}, {} };
modelInfos[MODEL_TYPE::BJT] = { "BJT", "NPN", "PNP", { "C", "B", "E" }, "Bipolar Junction Transistor", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::BJT].modelParams.emplace_back( "type", 309, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "npn", "pnp", "NPN or PNP" );
modelInfos[MODEL_TYPE::BJT].modelParams.emplace_back( "npn", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "NaN", "NaN", "NPN type device" );
@ -426,7 +426,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::BJT].instanceParams.emplace_back( "dtemp", 8, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, U(), "°C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "instance temperature delta from circuit", true );
modelInfos[MODEL_TYPE::VBIC] = { "VBIC", "NPN", "PNP", { "Collector", "Base", "Emitter" }, "Vertical Bipolar Inter-Company Model", {}, {} };
modelInfos[MODEL_TYPE::VBIC] = { "VBIC", "NPN", "PNP", { "C", "B", "E" }, "Vertical Bipolar Inter-Company Model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::VBIC].modelParams.emplace_back( "type", 305, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "npn", "pnp", "NPN or PNP" );
modelInfos[MODEL_TYPE::VBIC].modelParams.emplace_back( "npn", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "NaN", "NaN", "NPN type device" );
@ -593,7 +593,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::VBIC].instanceParams.emplace_back( "cqbx", 249, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, U(), "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Cap. due to charge storage in B-X jct.", true );
modelInfos[MODEL_TYPE::HICUM2] = { "hicum2", "NPN", "PNP", { "Collector", "Base", "Emitter" }, "High Current Model for BJT" , {}, {} };
modelInfos[MODEL_TYPE::HICUM2] = { "hicum2", "NPN", "PNP", { "C", "B", "E" }, "High Current Model for BJT" , {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HICUM2].modelParams.emplace_back( "type", 305, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "npn", "pnp", "For transistor type NPN(+1) or PNP (-1)" );
modelInfos[MODEL_TYPE::HICUM2].modelParams.emplace_back( "npn", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "NaN", "NaN", "NPN type device" );
@ -808,7 +808,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HICUM2].instanceParams.emplace_back( "p", 305, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipation", true );
modelInfos[MODEL_TYPE::JFET] = { "JFET", "NJF", "PJF", { "Drain", "Gate", "Source" }, "Junction Field effect transistor", {}, {} };
modelInfos[MODEL_TYPE::JFET] = { "JFET", "NJF", "PJF", { "D", "G", "S" }, "Junction Field effect transistor", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "type", 305, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "njf", "pjf", "N-type or P-type JFET model" );
modelInfos[MODEL_TYPE::JFET].modelParams.emplace_back( "njf", 111, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "N type JFET model" );
@ -869,7 +869,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::JFET].instanceParams.emplace_back( "p", 320, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the JFET", true );
modelInfos[MODEL_TYPE::JFET2] = { "JFET2", "NJF", "PJF", { "Drain", "Gate", "Source" }, "Short channel field effect transistor", {}, {} };
modelInfos[MODEL_TYPE::JFET2] = { "JFET2", "NJF", "PJF", { "D", "G", "S" }, "Short channel field effect transistor", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "type", 305, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "njf", "pjf", "N-type or P-type JFET2 model" );
modelInfos[MODEL_TYPE::JFET2].modelParams.emplace_back( "njf", 102, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "NaN", "NaN", "N type JFET2 model" );
@ -950,7 +950,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::JFET2].instanceParams.emplace_back( "vpave", 322, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Quiescent power dissipation", true );
modelInfos[MODEL_TYPE::MES] = { "MES", "NMF", "PMF", { "Drain", "Gate", "Source" }, "GaAs MESFET model", {}, {} };
modelInfos[MODEL_TYPE::MES] = { "MES", "NMF", "PMF", { "D", "G", "S" }, "GaAs MESFET model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MES].modelParams.emplace_back( "type", 305, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "-693161728", "116101380", "N-type or P-type MESfet model" );
modelInfos[MODEL_TYPE::MES].modelParams.emplace_back( "nmf", 113, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "N type MESfet model" );
@ -1002,7 +1002,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MES].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true );
modelInfos[MODEL_TYPE::MESA] = { "MESA", "NMF", "PMF", { "Drain", "Gate", "Source" }, "GaAs MESFET model", {}, {} };
modelInfos[MODEL_TYPE::MESA] = { "MESA", "NMF", "PMF", { "D", "G", "S" }, "GaAs MESFET model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MESA].modelParams.emplace_back( "type", 165, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmf", "nmf", "N-type or P-type MESfet model" );
modelInfos[MODEL_TYPE::MESA].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "-1.26", "-1.26", "Pinch-off voltage" );
@ -1108,7 +1108,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MESA].instanceParams.emplace_back( "p", 10, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true );
modelInfos[MODEL_TYPE::HFET1] = { "HFET1", "NMF", "PMF", { "Drain", "Gate", "Source", "Bulk" }, "HFET1 Model", {}, {} };
modelInfos[MODEL_TYPE::HFET1] = { "HFET1", "NMF", "PMF", { "D", "G", "S", "B" }, "HFET1 Model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HFET1].modelParams.emplace_back( "vt0", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "Pinch-off voltage" );
modelInfos[MODEL_TYPE::HFET1].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, R(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "n.a." );
@ -1210,7 +1210,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HFET1].instanceParams.emplace_back( "p", 9, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true );
modelInfos[MODEL_TYPE::HFET2] = { "HFET2", "NMF", "PMF", { "Drain", "Gate", "Source", "Bulk" }, "HFET2 Model", {}, {} };
modelInfos[MODEL_TYPE::HFET2] = { "HFET2", "NMF", "PMF", { "D", "G", "S", "B" }, "HFET2 Model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HFET2].modelParams.emplace_back( "type", 139, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "664639780", "-1511458520", "NHFET or PHFET" );
modelInfos[MODEL_TYPE::HFET2].modelParams.emplace_back( "nhfet", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "N type HFET model" );
@ -1283,7 +1283,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HFET2].instanceParams.emplace_back( "p", 8, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true );
modelInfos[MODEL_TYPE::MOS1] = { "Mos1", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Level 1 MOSfet model with Meyer capacitance model", {}, {} };
modelInfos[MODEL_TYPE::MOS1] = { "Mos1", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 1 MOSfet model with Meyer capacitance model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MOS1].modelParams.emplace_back( "type", 133, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmos", "pmos", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::MOS1].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Threshold voltage" );
@ -1399,7 +1399,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MOS1].instanceParams.emplace_back( "sens_w_cplx", 255, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity wrt width", true );
modelInfos[MODEL_TYPE::MOS2] = { "Mos2", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Level 2 MOSfet model with Meyer capacitance model", {}, {} };
modelInfos[MODEL_TYPE::MOS2] = { "Mos2", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 2 MOSfet model with Meyer capacitance model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MOS2].modelParams.emplace_back( "type", 141, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmos", "pmos", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::MOS2].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Threshold voltage" );
@ -1522,7 +1522,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MOS2].instanceParams.emplace_back( "sens_w_cplx", 69, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity wrt width", true );
modelInfos[MODEL_TYPE::MOS3] = { "Mos3", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Level 3 MOSfet model with Meyer capacitance model", {}, {} };
modelInfos[MODEL_TYPE::MOS3] = { "Mos3", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 3 MOSfet model with Meyer capacitance model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MOS3].modelParams.emplace_back( "type", 144, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmos", "pmos", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::MOS3].modelParams.emplace_back( "nmos", 133, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "N type MOSfet model" );
@ -1656,7 +1656,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MOS3].instanceParams.emplace_back( "sens_w_cplx", 69, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity wrt width", true );
modelInfos[MODEL_TYPE::BSIM1] = { "BSIM1", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley Short Channel IGFET Model", {}, {} };
modelInfos[MODEL_TYPE::BSIM1] = { "BSIM1", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley Short Channel IGFET Model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::BSIM1].modelParams.emplace_back( "vfb", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Flat band voltage" );
modelInfos[MODEL_TYPE::BSIM1].modelParams.emplace_back( "lvfb", 102, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "m", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Length dependence of vfb" );
@ -1756,7 +1756,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::BSIM1].instanceParams.emplace_back( "ic", 13, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR /*SIM_VALUE::TYPE::VECTOR*/, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of DS,GS,BS initial voltages", true );
modelInfos[MODEL_TYPE::BSIM2] = { "BSIM2", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley Short Channel IGFET Model", {}, {} };
modelInfos[MODEL_TYPE::BSIM2] = { "BSIM2", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley Short Channel IGFET Model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::BSIM2].modelParams.emplace_back( "vfb", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "-1", "-1", "Flat band voltage" );
modelInfos[MODEL_TYPE::BSIM2].modelParams.emplace_back( "lvfb", 102, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "m", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Length dependence of vfb" );
@ -1912,7 +1912,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::BSIM2].instanceParams.emplace_back( "ic", 13, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR /*SIM_VALUE::TYPE::VECTOR*/, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of DS,GS,BS initial voltages", true );
modelInfos[MODEL_TYPE::MOS6] = { "Mos6", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Level 6 MOSfet model with Meyer capacitance model", {}, {} };
modelInfos[MODEL_TYPE::MOS6] = { "Mos6", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 6 MOSfet model with Meyer capacitance model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MOS6].modelParams.emplace_back( "type", 140, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmos", "pmos", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::MOS6].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Threshold voltage" );
@ -2037,7 +2037,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MOS6].instanceParams.emplace_back( "sens_w_cplx", 255, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity wrt width", true );
modelInfos[MODEL_TYPE::BSIM3] = { "BSIM3", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley Short Channel IGFET Model Version-3", {}, {} };
modelInfos[MODEL_TYPE::BSIM3] = { "BSIM3", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley Short Channel IGFET Model Version-3", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::BSIM3].modelParams.emplace_back( "capmod", 100, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "3", "3", "Capacitance model selector" );
modelInfos[MODEL_TYPE::BSIM3].modelParams.emplace_back( "mobmod", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Mobility model selector" );
@ -2517,7 +2517,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::BSIM3].instanceParams.emplace_back( "capbs", 781, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capbs", true );
modelInfos[MODEL_TYPE::MOS9] = { "Mos9", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Modified Level 3 MOSfet model", {}, {} };
modelInfos[MODEL_TYPE::MOS9] = { "Mos9", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Modified Level 3 MOSfet model", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::MOS9].modelParams.emplace_back( "type", 144, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "nmos", "pmos", "N-channel or P-channel MOS" );
modelInfos[MODEL_TYPE::MOS9].modelParams.emplace_back( "nmos", 133, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "N type MOSfet model" );
@ -2651,7 +2651,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::MOS9].instanceParams.emplace_back( "sens_w_cplx", 69, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_COMPLEX, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "ac sensitivity wrt width", true );
modelInfos[MODEL_TYPE::B4SOI] = { "B4SOI", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley SOI MOSFET model version 4.4.0", {}, {} };
modelInfos[MODEL_TYPE::B4SOI] = { "B4SOI", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley SOI MOSFET model version 4.4.0", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::B4SOI].modelParams.emplace_back( "mtrlmod", 100, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "parameter for non-silicon substrate or metal gate selector" );
modelInfos[MODEL_TYPE::B4SOI].modelParams.emplace_back( "vgstcvmod", 1224, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Improved VgsteffCV selector" );
@ -3645,7 +3645,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::B4SOI].instanceParams.emplace_back( "rbodymod", 34, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Body R model selector", true );
modelInfos[MODEL_TYPE::BSIM4] = { "BSIM4", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley Short Channel IGFET Model-4", {}, {} };
modelInfos[MODEL_TYPE::BSIM4] = { "BSIM4", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley Short Channel IGFET Model-4", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::BSIM4].modelParams.emplace_back( "cvchargemod", 76, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "0", "0", "Capacitance Charge model selector" );
modelInfos[MODEL_TYPE::BSIM4].modelParams.emplace_back( "capmod", 92, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "2", "2", "Capacitance model selector" );
@ -4626,7 +4626,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::BSIM4].instanceParams.emplace_back( "gtau", 1014, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gtau", true );
modelInfos[MODEL_TYPE::B3SOIFD] = { "B3SOIFD", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley SOI MOSFET (FD) model version 2.1", {}, {} };
modelInfos[MODEL_TYPE::B3SOIFD] = { "B3SOIFD", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley SOI MOSFET (FD) model version 2.1", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::B3SOIFD].modelParams.emplace_back( "capmod", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "2", "2", "Capacitance model selector" );
modelInfos[MODEL_TYPE::B3SOIFD].modelParams.emplace_back( "mobmod", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Mobility model selector" );
@ -5051,7 +5051,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::B3SOIFD].instanceParams.emplace_back( "nrb", 18, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of squares in body", true );
modelInfos[MODEL_TYPE::B3SOIDD] = { "B3SOIDD", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley SOI MOSFET (DD) model version 2.1", {}, {} };
modelInfos[MODEL_TYPE::B3SOIDD] = { "B3SOIDD", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley SOI MOSFET (DD) model version 2.1", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::B3SOIDD].modelParams.emplace_back( "capmod", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "2", "2", "Capacitance model selector" );
modelInfos[MODEL_TYPE::B3SOIDD].modelParams.emplace_back( "mobmod", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Mobility model selector" );
@ -5476,7 +5476,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::B3SOIDD].instanceParams.emplace_back( "nrb", 18, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of squares in body", true );
modelInfos[MODEL_TYPE::B3SOIPD] = { "B3SOIPD", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Berkeley SOI (PD) MOSFET model version 2.2.3", {}, {} };
modelInfos[MODEL_TYPE::B3SOIPD] = { "B3SOIPD", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Berkeley SOI (PD) MOSFET model version 2.2.3", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::B3SOIPD].modelParams.emplace_back( "capmod", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::CAPACITANCE, "2", "2", "Capacitance model selector" );
modelInfos[MODEL_TYPE::B3SOIPD].modelParams.emplace_back( "mobmod", 103, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "1", "1", "Mobility model selector" );
@ -5987,7 +5987,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::B3SOIPD].instanceParams.emplace_back( "tnodeout", 29, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Flag indicating external temp node", true );
modelInfos[MODEL_TYPE::HISIM2] = { "HiSIM2", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Hiroshima University STARC IGFET Model 2.8.0", {}, {} };
modelInfos[MODEL_TYPE::HISIM2] = { "HiSIM2", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Hiroshima University STARC IGFET Model 2.8.0", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HISIM2].modelParams.emplace_back( "info", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "information level (for debug, etc.)" );
modelInfos[MODEL_TYPE::HISIM2].modelParams.emplace_back( "noise", 5, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_INT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::NOISE, "1", "1", "noise model selector" );
@ -6537,7 +6537,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HISIM2].instanceParams.emplace_back( "capbs", 371, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capbs", true );
modelInfos[MODEL_TYPE::HISIMHV1] = { "HiSIMHV1", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Hiroshima University STARC IGFET Model - HiSIM_HV v.1", {}, {} };
modelInfos[MODEL_TYPE::HISIMHV1] = { "HiSIMHV1", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Hiroshima University STARC IGFET Model - HiSIM_HV v.1", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HISIMHV1].modelParams.emplace_back( "nmos", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "" );
modelInfos[MODEL_TYPE::HISIMHV1].modelParams.emplace_back( "pmos", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "" );
@ -7224,7 +7224,7 @@ struct MODEL_INFO_MAP
modelInfos[MODEL_TYPE::HISIMHV1].instanceParams.emplace_back( "capbs", 371, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capbs", true );
modelInfos[MODEL_TYPE::HISIMHV2] = { "HiSIMHV2", "NMOS", "PMOS", { "Drain", "Gate", "Source", "Bulk" }, "Hiroshima University STARC IGFET Model - HiSIM_HV v.2", {}, {} };
modelInfos[MODEL_TYPE::HISIMHV2] = { "HiSIMHV2", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Hiroshima University STARC IGFET Model - HiSIM_HV v.2", {}, {} };
// Model parameters
modelInfos[MODEL_TYPE::HISIMHV2].modelParams.emplace_back( "nmos", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "" );
modelInfos[MODEL_TYPE::HISIMHV2].modelParams.emplace_back( "pmos", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "" );

View File

@ -123,45 +123,10 @@ SIM_MODEL_RAW_SPICE::SIM_MODEL_RAW_SPICE() :
}
void SIM_MODEL_RAW_SPICE::ReadDataSchFields( unsigned aSymbolPinCount,
const std::vector<SCH_FIELD>* aFields )
{
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
readLegacyDataFields( aSymbolPinCount, aFields );
}
void SIM_MODEL_RAW_SPICE::ReadDataLibFields( unsigned aSymbolPinCount,
const std::vector<LIB_FIELD>* aFields )
{
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
readLegacyDataFields( aSymbolPinCount, aFields );
}
void SIM_MODEL_RAW_SPICE::WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const
{
SIM_MODEL::WriteDataSchFields( aFields );
// Erase the legacy fields.
SetFieldValue( aFields, LEGACY_TYPE_FIELD, "" );
SetFieldValue( aFields, LEGACY_PINS_FIELD, "" );
SetFieldValue( aFields, LEGACY_MODEL_FIELD, "" );
SetFieldValue( aFields, LEGACY_ENABLED_FIELD, "" );
SetFieldValue( aFields, LEGACY_LIB_FIELD, "" );
}
void SIM_MODEL_RAW_SPICE::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const
{
SIM_MODEL::WriteDataLibFields( aFields );
}
void SIM_MODEL_RAW_SPICE::CreatePins( unsigned aSymbolPinCount )
{
for( unsigned symbolPinIndex = 0; symbolPinIndex < aSymbolPinCount; ++symbolPinIndex )
AddPin( { "", fmt::format( "{}", symbolPinIndex + 1 ) } );
AddPin( { fmt::format( "{}", symbolPinIndex + 1 ), "" } );
}
@ -218,76 +183,3 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_RAW_SPICE::makeParamInfos()
return paramInfos;
}
template <typename T>
void SIM_MODEL_RAW_SPICE::readLegacyDataFields( unsigned aSymbolPinCount,
const std::vector<T>* aFields )
{
// Fill in the blanks with the legacy parameters.
if( GetParam( static_cast<int>( SPICE_PARAM::TYPE ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::TYPE ),
GetFieldValue( aFields, LEGACY_TYPE_FIELD ) );
}
if( GetFieldValue( aFields, PINS_FIELD ) == "" )
parseLegacyPinsField( aSymbolPinCount, GetFieldValue( aFields, LEGACY_PINS_FIELD ) );
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::MODEL ),
GetFieldValue( aFields, LEGACY_MODEL_FIELD ) );
}
// If model param is still empty, then use Value field.
if( GetParam( static_cast<int>( SPICE_PARAM::MODEL ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::MODEL ),
GetFieldValue( aFields, SIM_MODEL::VALUE_FIELD ) );
}
if( GetParam( static_cast<int>( SPICE_PARAM::LIB ) ).value->ToString() == "" )
{
SetParamValue( static_cast<int>( SPICE_PARAM::LIB ),
GetFieldValue( aFields, LEGACY_LIB_FIELD ) );
}
}
void SIM_MODEL_RAW_SPICE::parseLegacyPinsField( unsigned aSymbolPinCount,
const std::string& aLegacyPinsField )
{
if( aLegacyPinsField == "" )
return;
// Initially set all pins to Not Connected to match the legacy behavior.
for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
SetPinSymbolPinNumber( static_cast<int>( modelPinIndex ), "" );
tao::pegtl::string_input<> in( aLegacyPinsField, PINS_FIELD );
std::unique_ptr<tao::pegtl::parse_tree::node> root;
try
{
root = tao::pegtl::parse_tree::parse<SIM_MODEL_RAW_SPICE_PARSER::legacyPinSequenceGrammar,
SIM_MODEL_RAW_SPICE_PARSER::legacyPinSequenceSelector>
( in );
}
catch( const tao::pegtl::parse_error& e )
{
THROW_IO_ERROR( e.what() );
}
for( int pinIndex = 0; pinIndex < static_cast<int>( root->children.size() ); ++pinIndex )
{
std::string symbolPinStr = root->children.at( pinIndex )->string();
int symbolPinIndex = std::stoi( symbolPinStr ) - 1;
if( symbolPinIndex < 0 || symbolPinIndex >= static_cast<int>( aSymbolPinCount ) )
THROW_IO_ERROR( wxString::Format( _( "Invalid symbol pin index: '%s'" ), symbolPinStr ) );
SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() );
}
}

View File

@ -62,30 +62,15 @@ public:
static constexpr auto LEGACY_ENABLED_FIELD = "Spice_Netlist_Enabled";
static constexpr auto LEGACY_LIB_FIELD = "Spice_Lib_File";
SIM_MODEL_RAW_SPICE();
//bool ReadSpiceCode( const std::string& aSpiceCode ) override;
void ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields ) override;
void ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields ) override;
void WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const override;
void WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const override;
protected:
void CreatePins( unsigned aSymbolPinCount ) override;
private:
static std::vector<PARAM::INFO> makeParamInfos();
template <typename T>
void readLegacyDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
void parseLegacyPinsField( unsigned aSymbolPinCount, const std::string& aLegacyPinsField );
bool requiresSpiceModelLine() const override { return false; }
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
};

View File

@ -42,7 +42,9 @@ namespace SIM_SERDE_PARSER
template <typename Rule> struct pinSequenceSelector : std::false_type {};
template <> struct pinSequenceSelector<pinNumber> : std::true_type {};
template <> struct pinSequenceSelector<pinAssignment> : std::true_type {};
template <> struct pinSequenceSelector<pinSymbolPinNumber> : std::true_type {};
template <> struct pinSequenceSelector<pinName> : std::true_type {};
template <typename Rule> struct fieldInferValueSelector : std::false_type {};
template <> struct fieldInferValueSelector<number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>> : std::true_type {};
@ -113,13 +115,13 @@ std::string SIM_SERDE::GeneratePins() const
{
const SIM_MODEL::PIN& pin = m_model.GetPin( i );
if( i != 0 )
result.append( " " );
if( pin.symbolPinNumber != "" )
{
if( i != 0 )
result.append( " " );
if( pin.symbolPinNumber == "" )
result.append( "~" );
else
result.append( pin.symbolPinNumber );
result.append( fmt::format( "{}={}", pin.symbolPinNumber, pin.name ) );
}
}
return result;
@ -251,27 +253,19 @@ void SIM_SERDE::ParsePins( const std::string& aPins )
SIM_SERDE_PARSER::pinSequenceSelector,
tao::pegtl::nothing,
SIM_SERDE_PARSER::control>( in );
for( const auto& node : root->children )
{
std::string symbolPinNumber = node->children.at( 0 )->string();
std::string pinName = node->children.at( 1 )->string();
m_model.SetPinSymbolPinNumber( pinName, symbolPinNumber );
}
}
catch( const tao::pegtl::parse_error& e )
{
THROW_IO_ERROR( e.what() );
}
if( static_cast<int>( root->children.size() ) != m_model.GetPinCount() )
{
THROW_IO_ERROR( wxString::Format( _( "%s describes %lu pins, expected %u" ),
PINS_FIELD,
root->children.size(),
m_model.GetPinCount() ) );
}
for( int pinIndex = 0; pinIndex < static_cast<int>( root->children.size() ); ++pinIndex )
{
if( root->children.at( pinIndex )->string() == "~" )
m_model.SetPinSymbolPinNumber( pinIndex, "" );
else
m_model.SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() );
}
}

View File

@ -42,8 +42,13 @@ namespace SIM_SERDE_GRAMMAR
tao::pegtl::eof> {};
struct pinNumber : plus<not_at<sep>, any> {};
struct pinSequence : list<pinNumber, sep> {};
struct pinSymbolPinNumber : plus<not_at<sep>, not_one<'='>> {};
struct pinName : plus<not_at<sep>, any> {};
struct pinAssignment : seq<pinSymbolPinNumber,
one<'='>,
pinName> {};
struct pinSequence : list<pinAssignment,
sep> {};
struct pinSequenceGrammar : must<opt<sep>,
opt<pinSequence>,
opt<sep>,
@ -134,10 +139,6 @@ public:
void ParsePins( const std::string& aPins );
void ParseEnable( const std::string& aEnable );
static SIM_MODEL::TYPE InferTypeFromRefAndValue( const std::string& aRef,
const std::string& aValue,
int aSymbolPinCount );
protected:
virtual std::string GenerateParamValuePair( const SIM_MODEL::PARAM& aParam ) const;