From a65b35107d1829f51abe2418a71672e4915ebc7e Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 25 Nov 2022 05:31:03 +0100 Subject: [PATCH] Sim: Make Sim.Pins have key-value pairs instead of a sequence Moreover, upgrade models on schematic load instead of on model load --- eeschema/sch_sheet_path.cpp | 217 ++++++++++++++++-------- eeschema/sch_sheet_path.h | 15 +- eeschema/sim/sim_model.cpp | 29 +++- eeschema/sim/sim_model.h | 8 +- eeschema/sim/sim_model_kibis.cpp | 2 +- eeschema/sim/sim_model_ngspice_data.cpp | 52 +++--- eeschema/sim/sim_model_raw_spice.cpp | 110 +----------- eeschema/sim/sim_model_raw_spice.h | 15 -- eeschema/sim/sim_serde.cpp | 40 ++--- eeschema/sim/sim_serde.h | 13 +- 10 files changed, 241 insertions(+), 260 deletions(-) diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 7bed8a0add..2fc594a95b 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -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 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 ); + } +} diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 8f1f098325..0de5d6e7fe 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -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; }; diff --git a/eeschema/sim/sim_model.cpp b/eeschema/sim/sim_model.cpp index 5cd5f1605a..c77af6f49f 100644 --- a/eeschema/sim/sim_model.cpp +++ b/eeschema/sim/sim_model.cpp @@ -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> 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> 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( it - pins.begin() ), aSymbolPinNumber ); +} + const SIM_MODEL::PARAM& SIM_MODEL::GetParam( unsigned aParamIndex ) const { diff --git a/eeschema/sim/sim_model.h b/eeschema/sim/sim_model.h index bcde4e6b94..a3a50bdf1b 100644 --- a/eeschema/sim/sim_model.h +++ b/eeschema/sim/sim_model.h @@ -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> 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( m_params.size() ); } diff --git a/eeschema/sim/sim_model_kibis.cpp b/eeschema/sim/sim_model_kibis.cpp index 1b166fe338..e0afa33616 100644 --- a/eeschema/sim/sim_model_kibis.cpp +++ b/eeschema/sim/sim_model_kibis.cpp @@ -252,7 +252,7 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) : void SIM_MODEL_KIBIS::SwitchSingleEndedDiff( bool aDiff ) { - DeletePins(); + ClearPins(); if( aDiff ) { diff --git a/eeschema/sim/sim_model_ngspice_data.cpp b/eeschema/sim/sim_model_ngspice_data.cpp index c83a278d19..7ba4c16890 100644 --- a/eeschema/sim/sim_model_ngspice_data.cpp +++ b/eeschema/sim/sim_model_ngspice_data.cpp @@ -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, "", "", "" ); diff --git a/eeschema/sim/sim_model_raw_spice.cpp b/eeschema/sim/sim_model_raw_spice.cpp index fef3089d6d..2289f047c9 100644 --- a/eeschema/sim/sim_model_raw_spice.cpp +++ b/eeschema/sim/sim_model_raw_spice.cpp @@ -123,45 +123,10 @@ SIM_MODEL_RAW_SPICE::SIM_MODEL_RAW_SPICE() : } -void SIM_MODEL_RAW_SPICE::ReadDataSchFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields ); - readLegacyDataFields( aSymbolPinCount, aFields ); -} - - -void SIM_MODEL_RAW_SPICE::ReadDataLibFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields ); - readLegacyDataFields( aSymbolPinCount, aFields ); -} - - -void SIM_MODEL_RAW_SPICE::WriteDataSchFields( std::vector& 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& 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_RAW_SPICE::makeParamInfos() return paramInfos; } - - -template -void SIM_MODEL_RAW_SPICE::readLegacyDataFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - // Fill in the blanks with the legacy parameters. - - if( GetParam( static_cast( SPICE_PARAM::TYPE ) ).value->ToString() == "" ) - { - SetParamValue( static_cast( SPICE_PARAM::TYPE ), - GetFieldValue( aFields, LEGACY_TYPE_FIELD ) ); - } - - if( GetFieldValue( aFields, PINS_FIELD ) == "" ) - parseLegacyPinsField( aSymbolPinCount, GetFieldValue( aFields, LEGACY_PINS_FIELD ) ); - - if( GetParam( static_cast( SPICE_PARAM::MODEL ) ).value->ToString() == "" ) - { - SetParamValue( static_cast( SPICE_PARAM::MODEL ), - GetFieldValue( aFields, LEGACY_MODEL_FIELD ) ); - } - - // If model param is still empty, then use Value field. - if( GetParam( static_cast( SPICE_PARAM::MODEL ) ).value->ToString() == "" ) - { - SetParamValue( static_cast( SPICE_PARAM::MODEL ), - GetFieldValue( aFields, SIM_MODEL::VALUE_FIELD ) ); - } - - if( GetParam( static_cast( SPICE_PARAM::LIB ) ).value->ToString() == "" ) - { - SetParamValue( static_cast( 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( modelPinIndex ), "" ); - - tao::pegtl::string_input<> in( aLegacyPinsField, PINS_FIELD ); - std::unique_ptr root; - - try - { - root = tao::pegtl::parse_tree::parse - ( in ); - } - catch( const tao::pegtl::parse_error& e ) - { - THROW_IO_ERROR( e.what() ); - } - - for( int pinIndex = 0; pinIndex < static_cast( root->children.size() ); ++pinIndex ) - { - std::string symbolPinStr = root->children.at( pinIndex )->string(); - int symbolPinIndex = std::stoi( symbolPinStr ) - 1; - - if( symbolPinIndex < 0 || symbolPinIndex >= static_cast( aSymbolPinCount ) ) - THROW_IO_ERROR( wxString::Format( _( "Invalid symbol pin index: '%s'" ), symbolPinStr ) ); - - SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() ); - } -} diff --git a/eeschema/sim/sim_model_raw_spice.h b/eeschema/sim/sim_model_raw_spice.h index 97c4c2f0de..958c21d637 100644 --- a/eeschema/sim/sim_model_raw_spice.h +++ b/eeschema/sim/sim_model_raw_spice.h @@ -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* aFields ) override; - void ReadDataLibFields( unsigned aSymbolPinCount, const std::vector* aFields ) override; - - void WriteDataSchFields( std::vector& aFields ) const override; - void WriteDataLibFields( std::vector& aFields ) const override; - protected: void CreatePins( unsigned aSymbolPinCount ) override; private: static std::vector makeParamInfos(); - - template - void readLegacyDataFields( unsigned aSymbolPinCount, const std::vector* aFields ); - - void parseLegacyPinsField( unsigned aSymbolPinCount, const std::string& aLegacyPinsField ); - bool requiresSpiceModelLine() const override { return false; } - std::vector> m_paramInfos; }; diff --git a/eeschema/sim/sim_serde.cpp b/eeschema/sim/sim_serde.cpp index 7f3c8da58b..163c08db1e 100644 --- a/eeschema/sim/sim_serde.cpp +++ b/eeschema/sim/sim_serde.cpp @@ -42,7 +42,9 @@ namespace SIM_SERDE_PARSER template struct pinSequenceSelector : std::false_type {}; - template <> struct pinSequenceSelector : std::true_type {}; + template <> struct pinSequenceSelector : std::true_type {}; + template <> struct pinSequenceSelector : std::true_type {}; + template <> struct pinSequenceSelector : std::true_type {}; template struct fieldInferValueSelector : std::false_type {}; template <> struct fieldInferValueSelector> : 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( 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( root->children.size() ); ++pinIndex ) - { - if( root->children.at( pinIndex )->string() == "~" ) - m_model.SetPinSymbolPinNumber( pinIndex, "" ); - else - m_model.SetPinSymbolPinNumber( pinIndex, root->children.at( pinIndex )->string() ); - } } diff --git a/eeschema/sim/sim_serde.h b/eeschema/sim/sim_serde.h index 6780df2337..73c284bfb3 100644 --- a/eeschema/sim/sim_serde.h +++ b/eeschema/sim/sim_serde.h @@ -42,8 +42,13 @@ namespace SIM_SERDE_GRAMMAR tao::pegtl::eof> {}; - struct pinNumber : plus, any> {}; - struct pinSequence : list {}; + struct pinSymbolPinNumber : plus, not_one<'='>> {}; + struct pinName : plus, any> {}; + struct pinAssignment : seq