diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 9532886e93..75c6d6aeae 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -287,6 +287,7 @@ set( EESCHEMA_SRCS sim/sim_model_ngspice_data.cpp sim/sim_model_spice.cpp sim/sim_model_source.cpp + sim/sim_model_switch.cpp sim/sim_model_subckt.cpp sim/sim_model_tline.cpp sim/sim_value.cpp diff --git a/eeschema/dialogs/dialog_sim_model.cpp b/eeschema/dialogs/dialog_sim_model.cpp index ed8eb6bed1..38dbf54ddf 100644 --- a/eeschema/dialogs/dialog_sim_model.cpp +++ b/eeschema/dialogs/dialog_sim_model.cpp @@ -37,7 +37,7 @@ using CATEGORY = SIM_MODEL::PARAM::CATEGORY; template DIALOG_SIM_MODEL::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, - std::vector& aFields ) + std::vector& aFields ) : DIALOG_SIM_MODEL_BASE( aParent ), m_symbol( aSymbol ), m_fields( aFields ), @@ -50,8 +50,8 @@ DIALOG_SIM_MODEL::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, m_modelNameCombobox->SetValidator( m_modelNameValidator ); m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) ); - m_sortedLibPins = m_symbol.GetLibPins(); - std::sort( m_sortedLibPins.begin(), m_sortedLibPins.end(), + m_sortedSymbolPins = m_symbol.GetLibPins(); + std::sort( m_sortedSymbolPins.begin(), m_sortedSymbolPins.end(), []( const LIB_PIN* lhs, const LIB_PIN* rhs ) { // We sort by StrNumCmp because SIM_MODEL_BASE sorts with it too. @@ -60,7 +60,7 @@ DIALOG_SIM_MODEL::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol, for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() ) { - m_models.push_back( SIM_MODEL::Create( type, m_sortedLibPins.size() ) ); + m_models.push_back( SIM_MODEL::Create( type, m_sortedSymbolPins.size() ) ); SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( type ).deviceType; @@ -138,7 +138,7 @@ bool DIALOG_SIM_MODEL::TransferDataToWindow() try { m_models.at( static_cast( SIM_MODEL::ReadTypeFromFields( m_fields ) ) ) = - SIM_MODEL::Create( m_sortedLibPins.size(), m_fields ); + SIM_MODEL::Create( m_sortedSymbolPins.size(), m_fields ); } catch( const IO_ERROR& e ) { @@ -194,7 +194,7 @@ void DIALOG_SIM_MODEL::updateWidgets() { updateModelParamsTab(); updateModelCodeTab(); - updatePinAssignmentsTab(); + updatePinAssignments(); m_prevModel = &curModel(); } @@ -333,12 +333,14 @@ void DIALOG_SIM_MODEL::updateModelCodeTab() template -void DIALOG_SIM_MODEL::updatePinAssignmentsTab() +void DIALOG_SIM_MODEL::updatePinAssignments() { - // First reset the grid. + removeOrphanedPinAssignments(); + + // Reset the grid. m_pinAssignmentsGrid->ClearRows(); - m_pinAssignmentsGrid->AppendRows( static_cast( m_sortedLibPins.size() ) ); + m_pinAssignmentsGrid->AppendRows( static_cast( m_sortedSymbolPins.size() ) ); for( int row = 0; row < m_pinAssignmentsGrid->GetNumberRows(); ++row ) { @@ -355,8 +357,6 @@ void DIALOG_SIM_MODEL::updatePinAssignmentsTab() continue; wxString modelPinString = getModelPinString( modelPinIndex ); - wxArrayString choices; - m_pinAssignmentsGrid->SetCellValue( findSymbolPinRow( symbolPinNumber ), static_cast( PIN_COLUMN::MODEL ), modelPinString ); @@ -378,7 +378,7 @@ void DIALOG_SIM_MODEL::updatePinAssignmentsTab() wxArrayString actualModelPinChoices( modelPinChoices ); - if( curModelPinString != "Not Connected" ) + if( curModelPinString != _( "Not Connected" ) ) actualModelPinChoices.Insert( curModelPinString, 0 ); // Using `new` here shouldn't cause a memory leak because `SetCellEditor()` calls @@ -392,6 +392,29 @@ void DIALOG_SIM_MODEL::updatePinAssignmentsTab() } +template +void DIALOG_SIM_MODEL::removeOrphanedPinAssignments() +{ + for( int i = 0; i < curModel().GetPinCount(); ++i ) + { + const SIM_MODEL::PIN& modelPin = curModel().GetPin( i ); + bool isOrphaned = true; + + for( const LIB_PIN* symbolPin : m_sortedSymbolPins ) + { + if( modelPin.symbolPinNumber == symbolPin->GetNumber() ) + { + isOrphaned = false; + break; + } + } + + if( isOrphaned ) + curModel().SetPinSymbolPinNumber( i, "" ); + } +} + + template void DIALOG_SIM_MODEL::loadLibrary( const wxString& aFilePath ) { @@ -428,11 +451,11 @@ void DIALOG_SIM_MODEL::loadLibrary( const wxString& aFilePath ) //TODO: it's not cur model. m_libraryModels.push_back( - SIM_MODEL::Create( baseModel, m_sortedLibPins.size(), m_fields ) ); + SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size(), m_fields ) ); } else { - m_libraryModels.push_back( SIM_MODEL::Create( baseModel, m_sortedLibPins.size() ) ); + m_libraryModels.push_back( SIM_MODEL::Create( baseModel, m_sortedSymbolPins.size() ) ); } } } @@ -561,8 +584,8 @@ wxPGProperty* DIALOG_SIM_MODEL::newParamProperty( int aParamIndex ) const // break; case SIM_VALUE::TYPE_STRING: - prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library, curModelSharedPtr(), - aParamIndex, SIM_VALUE::TYPE_STRING ); + prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library, + curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING ); break; default: @@ -609,9 +632,9 @@ wxPGProperty* DIALOG_SIM_MODEL::newParamProperty( int aParamIndex ) const template int DIALOG_SIM_MODEL::findSymbolPinRow( const wxString& aSymbolPinNumber ) const { - for( int row = 0; row < static_cast( m_sortedLibPins.size() ); ++row ) + for( int row = 0; row < static_cast( m_sortedSymbolPins.size() ); ++row ) { - LIB_PIN* pin = m_sortedLibPins[row]; + LIB_PIN* pin = m_sortedSymbolPins[row]; if( pin->GetNumber() == aSymbolPinNumber ) return row; @@ -644,7 +667,7 @@ std::shared_ptr DIALOG_SIM_MODEL::curModelSharedPtr() const template wxString DIALOG_SIM_MODEL::getSymbolPinString( int symbolPinIndex ) const { - LIB_PIN* pin = m_sortedLibPins.at( symbolPinIndex ); + LIB_PIN* pin = m_sortedSymbolPins.at( symbolPinIndex ); wxString number; wxString name; @@ -699,7 +722,6 @@ template wxArrayString DIALOG_SIM_MODEL::getModelPinChoices() const { wxArrayString modelPinChoices; - bool isFirst = true; for( int i = 0; i < curModel().GetPinCount(); ++i ) { @@ -708,16 +730,10 @@ wxArrayString DIALOG_SIM_MODEL::getModelPinChoices() const if( modelPin.symbolPinNumber != "" ) continue; - if( isFirst ) - { - modelPinChoices.Add( getModelPinString( i ) ); - isFirst = false; - } - else - modelPinChoices.Add( getModelPinString( i ) ); + modelPinChoices.Add( getModelPinString( i ) ); } - modelPinChoices.Add( "Not Connected" ); + modelPinChoices.Add( _( "Not Connected" ) ); return modelPinChoices; } @@ -845,10 +861,10 @@ void DIALOG_SIM_MODEL::onPinAssignmentsGridCellChange( wxGridEvent& aEvent ) if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED ) { curModel().SetPinSymbolPinNumber( modelPinIndex, - m_sortedLibPins.at( symbolPinIndex )->GetShownNumber() ); + m_sortedSymbolPins.at( symbolPinIndex )->GetShownNumber() ); } - updatePinAssignmentsTab(); + updatePinAssignments(); aEvent.Skip(); } diff --git a/eeschema/dialogs/dialog_sim_model.h b/eeschema/dialogs/dialog_sim_model.h index 846c91d75d..fb21963179 100644 --- a/eeschema/dialogs/dialog_sim_model.h +++ b/eeschema/dialogs/dialog_sim_model.h @@ -77,8 +77,9 @@ private: void updateWidgets(); void updateModelParamsTab(); void updateModelCodeTab(); - void updatePinAssignmentsTab(); - //void updatePinAssignmentsGridEditors(); + void updatePinAssignments(); + + void removeOrphanedPinAssignments(); void loadLibrary( const wxString& aFilePath ); @@ -124,7 +125,7 @@ private: std::vector& m_fields; std::vector> m_models; - std::vector m_sortedLibPins; + std::vector m_sortedSymbolPins; std::map m_curModelTypeOfDeviceType; SIM_MODEL::TYPE m_curModelType = SIM_MODEL::TYPE::NONE; diff --git a/eeschema/sim/sim_model.cpp b/eeschema/sim/sim_model.cpp index a97505f496..58740bb78c 100644 --- a/eeschema/sim/sim_model.cpp +++ b/eeschema/sim/sim_model.cpp @@ -22,8 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include - #include #include #include @@ -31,6 +29,7 @@ #include #include #include +#include #include #include @@ -40,6 +39,8 @@ #include #include +#include + using DEVICE_TYPE = SIM_MODEL::DEVICE_TYPE_; using TYPE = SIM_MODEL::TYPE; @@ -269,8 +270,8 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType ) case TYPE::TLINE_Z0: return { "T" }; case TYPE::TLINE_RLGC: return { "O", "ltra" }; - case TYPE::SW_V: return { "S", "switch" }; - case TYPE::SW_I: return { "W", "cswitch" }; + case TYPE::SW_V: return { "S", "sw" }; + case TYPE::SW_I: return { "W", "csw" }; case TYPE::D: return { "D", "d" }; @@ -485,7 +486,7 @@ TYPE SIM_MODEL::ReadTypeFromFields( const std::vector& aFields ) } } - if( !typeFieldValue.IsEmpty() ) + if( typeFieldValue != "" ) return TYPE::NONE; // No type information. Look for legacy (pre-V7) fields. @@ -912,7 +913,7 @@ wxString SIM_MODEL::GenerateSpiceModelLine( const wxString& aModelName ) const { LOCALE_IO toggle; - if( !HasSpiceNonInstanceOverrides() || !requiresSpiceModel() ) + if( !HasSpiceNonInstanceOverrides() && !requiresSpiceModel() ) return ""; wxString result = ""; @@ -925,12 +926,14 @@ wxString SIM_MODEL::GenerateSpiceModelLine( const wxString& aModelName ) const if( param.info.isSpiceInstanceParam ) continue; - wxString valueStr = param.value->ToSpiceString(); + wxString name = ( param.info.spiceModelName == "" ) ? + param.info.name : param.info.spiceModelName; + wxString value = param.value->ToSpiceString(); - if( valueStr == "" ) + if( value == "" ) continue; - wxString appendix = " " + param.info.name + "=" + valueStr; + wxString appendix = " " + name + "=" + value; if( line.Length() + appendix.Length() > 60 ) { @@ -955,6 +958,26 @@ wxString SIM_MODEL::GenerateSpiceItemName( const wxString& aRefName ) const } +wxString SIM_MODEL::GenerateSpiceItemParamValuePair( const PARAM& aParam, bool& aIsFirst ) const +{ + wxString result; + + if( aIsFirst ) + aIsFirst = false; + else + result << " "; + + wxString name = ( aParam.info.spiceInstanceName == "" ) ? + aParam.info.name : aParam.info.spiceInstanceName; + wxString value = aParam.value->ToSpiceString(); + + if( value != "" ) + result << name << "=" << value; + + return result; +} + + wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const { @@ -987,15 +1010,14 @@ wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName, const std::vector& aSymbolPinNumbers, const std::vector& aPinNetNames ) const { - wxString result = ""; + wxString result; result << GenerateSpiceItemName( aRefName ) << " "; int ncCounter = 0; - for( const PIN& pin : GetPins() ) + for( const PIN& pin : GetSpicePins() ) { - auto it = std::find( aSymbolPinNumbers.begin(), - aSymbolPinNumbers.end(), + auto it = std::find( aSymbolPinNumbers.begin(), aSymbolPinNumbers.end(), pin.symbolPinNumber ); if( it == aSymbolPinNumbers.end() ) @@ -1006,24 +1028,22 @@ wxString SIM_MODEL::GenerateSpiceItemLine( const wxString& aRefName, else { long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it ); - result << aPinNetNames.at( symbolPinIndex ) << " "; + wxString netName = aPinNetNames.at( symbolPinIndex ); + result << netName << " "; } } if( requiresSpiceModel() ) result << aModelName << " "; + bool isFirst = false; + for( const PARAM& param : GetParams() ) { if( !param.info.isSpiceInstanceParam ) continue; - wxString name = ( param.info.spiceInstanceName == "" ) ? - param.info.name : param.info.spiceInstanceName; - wxString value = param.value->ToSpiceString(); - - if( value != "" ) - result << name << "=" << value << " "; + result << GenerateSpiceItemParamValuePair( param, isFirst ); } result << "\n"; @@ -1266,7 +1286,7 @@ void SIM_MODEL::WriteInferredDataFields( std::vector& aFields, const wxString wxString SIM_MODEL::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const { - wxString result = ""; + wxString result; if( aIsFirst ) aIsFirst = false; @@ -1290,8 +1310,8 @@ wxString SIM_MODEL::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst wxString SIM_MODEL::GenerateParamsField( const wxString& aPairSeparator ) const { + wxString result; bool isFirst = true; - wxString result = ""; for( const PARAM& param : m_params ) { @@ -1438,6 +1458,10 @@ std::unique_ptr SIM_MODEL::create( TYPE aType ) case TYPE::TLINE_RLGC: return std::make_unique( aType ); + case TYPE::SW_V: + case TYPE::SW_I: + return std::make_unique( aType ); + case TYPE::V: case TYPE::I: case TYPE::V_SIN: @@ -1519,9 +1543,15 @@ TYPE SIM_MODEL::readTypeFromSpiceStrings( const wxString& aTypeString, template void SIM_MODEL::doReadDataFields( unsigned aSymbolPinCount, const std::vector* aFields ) { - ParsePinsField( aSymbolPinCount, GetFieldValue( aFields, PINS_FIELD ) ); - ParseParamsField( GetFieldValue( aFields, PARAMS_FIELD ) ); ParseDisabledField( GetFieldValue( aFields, DISABLED_FIELD ) ); + + if( GetFieldValue( aFields, PARAMS_FIELD ) != "" ) + { + ParsePinsField( aSymbolPinCount, GetFieldValue( aFields, PINS_FIELD ) ); + ParseParamsField( GetFieldValue( aFields, PARAMS_FIELD ) ); + } + else + InferredReadDataFields( aSymbolPinCount, aFields, true ); } diff --git a/eeschema/sim/sim_model.h b/eeschema/sim/sim_model.h index 1bf8301649..185f09c8e4 100644 --- a/eeschema/sim/sim_model.h +++ b/eeschema/sim/sim_model.h @@ -365,7 +365,7 @@ public: struct INFO { - wxString name; + wxString name = ""; unsigned id = 0; // Legacy (don't remove). DIR dir = DIR_INOUT; SIM_VALUE::TYPE type = SIM_VALUE::TYPE_FLOAT; @@ -377,6 +377,7 @@ public: wxString description = ""; bool isSpiceInstanceParam = false; bool isInstanceParam = false; + wxString spiceModelName = ""; wxString spiceInstanceName = ""; // TODO: Stop using brace-initializers, use this constructor for all info structs. @@ -392,6 +393,7 @@ public: const wxString& aDescription = "", bool aIsSpiceInstanceParam = false, bool aIsInstanceParam = false, + wxString aSpiceModelName = "", wxString aSpiceInstanceName = "" ) : name( aName ), id( aId ), @@ -491,9 +493,10 @@ public: virtual wxString GenerateSpiceModelLine( const wxString& aModelName ) const; virtual wxString GenerateSpiceItemName( const wxString& aRefName ) const; + virtual wxString GenerateSpiceItemParamValuePair( const PARAM& aParam, bool& aIsFirst ) const; + wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName ) const; - wxString GenerateSpiceItemLine( const wxString& aRefName, - const wxString& aModelName, + wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName, const std::vector& aSymbolPinNumbers ) const; virtual wxString GenerateSpiceItemLine( const wxString& aRefName, const wxString& aModelName, @@ -524,6 +527,10 @@ public: const PIN& GetPin( unsigned aIndex ) const { return m_pins.at( aIndex ); } std::vector> GetPins() const; + virtual std::vector> GetSpicePins() const + { + return GetPins(); + } void SetPinSymbolPinNumber( int aPinIndex, const wxString& aSymbolPinNumber ) { diff --git a/eeschema/sim/sim_model_ideal.cpp b/eeschema/sim/sim_model_ideal.cpp index 1568e8c928..35426a8a05 100644 --- a/eeschema/sim/sim_model_ideal.cpp +++ b/eeschema/sim/sim_model_ideal.cpp @@ -26,8 +26,6 @@ #include #include -using PARAM = SIM_MODEL::PARAM; - SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType ) : SIM_MODEL( aType ), @@ -118,7 +116,8 @@ void SIM_MODEL_IDEAL::inferredWriteDataFields( std::vector& aFields ) const } -PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( wxString aName, wxString aDescription, wxString aUnit ) +SIM_MODEL::PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( wxString aName, wxString aDescription, + wxString aUnit ) { SIM_MODEL::PARAM::INFO paramInfo = {}; diff --git a/eeschema/sim/sim_model_ngspice.cpp b/eeschema/sim/sim_model_ngspice.cpp index 3263adef6c..1f4196910c 100644 --- a/eeschema/sim/sim_model_ngspice.cpp +++ b/eeschema/sim/sim_model_ngspice.cpp @@ -152,8 +152,6 @@ SIM_MODEL_NGSPICE::MODEL_TYPE SIM_MODEL_NGSPICE::getModelType() const switch( GetType() ) { case TYPE::NONE: return MODEL_TYPE::NONE; - case TYPE::SW_V: return MODEL_TYPE::SWITCH; - case TYPE::SW_I: return MODEL_TYPE::CSWITCH; case TYPE::D: return MODEL_TYPE::DIODE; case TYPE::NPN_GUMMELPOON: diff --git a/eeschema/sim/sim_model_ngspice.h b/eeschema/sim/sim_model_ngspice.h index 39c718e853..9d6f180a72 100644 --- a/eeschema/sim/sim_model_ngspice.h +++ b/eeschema/sim/sim_model_ngspice.h @@ -51,8 +51,8 @@ protected: //TRANLINE, //URC, //TRANSLINE, - SWITCH, - CSWITCH, + //SWITCH, + //CSWITCH, DIODE, BJT, VBIC, diff --git a/eeschema/sim/sim_model_ngspice_data.cpp b/eeschema/sim/sim_model_ngspice_data.cpp index 98b91f524c..c83a278d19 100644 --- a/eeschema/sim/sim_model_ngspice_data.cpp +++ b/eeschema/sim/sim_model_ngspice_data.cpp @@ -67,7 +67,7 @@ struct MODEL_INFO_MAP MODEL_INFO_MAP() { modelInfos[MODEL_TYPE::NONE] = {}; - modelInfos[MODEL_TYPE::SWITCH] = { "Switch", "SW", "", { "+", "-", "Ctrl+", "Ctrl-" }, "Ideal voltage controlled switch", {}, {} }; + /*modelInfos[MODEL_TYPE::SWITCH] = { "Switch", "SW", "", { "+", "-", "Ctrl+", "Ctrl-" }, "Ideal voltage controlled switch", {}, {} }; // Model parameters modelInfos[MODEL_TYPE::SWITCH].modelParams.emplace_back( "sw", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "NaN", "", "Switch model" ); modelInfos[MODEL_TYPE::SWITCH].modelParams.emplace_back( "vt", 104, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, U(), "V", SIM_MODEL::PARAM::CATEGORY::PRINCIPAL, "0", "", "Threshold voltage" ); @@ -96,13 +96,13 @@ struct MODEL_INFO_MAP modelInfos[MODEL_TYPE::CSWITCH].modelParams.emplace_back( "gon", 106, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, U(), "", SIM_MODEL::PARAM::CATEGORY::PRINCIPAL, "", "", "Closed conductance" ); modelInfos[MODEL_TYPE::CSWITCH].modelParams.emplace_back( "goff", 107, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, U(), "", SIM_MODEL::PARAM::CATEGORY::PRINCIPAL, "", "", "Open conductance" ); // Instance parameters - modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "control", 1, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_STRING /*SIM_VALUE::TYPE::INSTANCE*/, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Name of controlling source", true ); + modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "control", 1, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_STRING /SIM_VALUE::TYPE::INSTANCE/, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Name of controlling source", true ); modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "on", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initially closed", true ); modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "off", 3, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, SIM_MODEL::PARAM::FLAGS(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initially open", true ); modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "pos_node", 4, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Positive node of switch", true ); modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "neg_node", 5, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, U(), "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Negative node of switch", true ); modelInfos[MODEL_TYPE::CSWITCH].instanceParams.emplace_back( "i", 6, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, SIM_MODEL::PARAM::FLAGS(), "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Switch current", true ); - 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::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", {}, {} }; diff --git a/eeschema/sim/sim_model_source.cpp b/eeschema/sim/sim_model_source.cpp index df14be98c9..9a017e155e 100644 --- a/eeschema/sim/sim_model_source.cpp +++ b/eeschema/sim/sim_model_source.cpp @@ -25,8 +25,7 @@ #include #include #include - -using PARAM = SIM_MODEL::PARAM; +#include namespace SIM_MODEL_SOURCE_PARSER @@ -43,31 +42,11 @@ SIM_MODEL_SOURCE::SIM_MODEL_SOURCE( TYPE aType ) : SIM_MODEL( aType ), m_isInferred( false ) { - for( const PARAM::INFO& paramInfo : makeParamInfos( aType ) ) + for( const SIM_MODEL::PARAM::INFO& paramInfo : makeParamInfos( aType ) ) AddParam( paramInfo ); } -void SIM_MODEL_SOURCE::ReadDataSchFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - if( GetFieldValue( aFields, PARAMS_FIELD ) != "" ) - SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields ); - else - InferredReadDataFields( aSymbolPinCount, aFields, true ); -} - - -void SIM_MODEL_SOURCE::ReadDataLibFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - if( GetFieldValue( aFields, PARAMS_FIELD ) != "" ) - SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields ); - else - InferredReadDataFields( aSymbolPinCount, aFields, true ); -} - - void SIM_MODEL_SOURCE::WriteDataSchFields( std::vector& aFields ) const { SIM_MODEL::WriteDataSchFields( aFields ); @@ -97,6 +76,7 @@ wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName, const std::vector& aSymbolPinNumbers, const std::vector& aPinNetNames ) const { + LOCALE_IO toggle; wxString model; wxString ac = FindParam( "ac" )->value->ToSpiceString(); @@ -229,7 +209,7 @@ wxString SIM_MODEL_SOURCE::GenerateSpiceItemLine( const wxString& aRefName, model << wxString::Format( "%s( %s)", GetSpiceInfo().inlineTypeString, args ); } else - model << GetParam( 0 ).value->ToString( SIM_VALUE_GRAMMAR::NOTATION::SPICE ); + model << GetParam( 0 ).value->ToSpiceString(); return SIM_MODEL::GenerateSpiceItemLine( aRefName, model, aSymbolPinNumbers, aPinNetNames ); } @@ -283,12 +263,6 @@ void SIM_MODEL_SOURCE::inferredWriteDataFields( std::vector& aFields ) const } -std::vector SIM_MODEL_SOURCE::getPinNames() const -{ - return { "+", "-" }; -} - - wxString SIM_MODEL_SOURCE::getParamValueString( const wxString& aParamName, const wxString& aDefaultValue ) const { @@ -301,49 +275,49 @@ wxString SIM_MODEL_SOURCE::getParamValueString( const wxString& aParamName, } -const std::vector& SIM_MODEL_SOURCE::makeParamInfos( TYPE aType ) +const std::vector& SIM_MODEL_SOURCE::makeParamInfos( TYPE aType ) { - static std::vector vdc = makeDcParamInfos( "y", "V" ); - static std::vector idc = makeDcParamInfos( "y", "A" ); + static std::vector vdc = makeDcParamInfos( "y", "V" ); + static std::vector idc = makeDcParamInfos( "y", "A" ); - static std::vector vsin = makeSinParamInfos( "y", "V" ); - static std::vector isin = makeSinParamInfos( "y", "A" ); + static std::vector vsin = makeSinParamInfos( "y", "V" ); + static std::vector isin = makeSinParamInfos( "y", "A" ); - static std::vector vpulse = makePulseParamInfos( "y", "V" ); - static std::vector ipulse = makePulseParamInfos( "y", "A" ); + static std::vector vpulse = makePulseParamInfos( "y", "V" ); + static std::vector ipulse = makePulseParamInfos( "y", "A" ); - static std::vector vexp = makeExpParamInfos( "y", "V" ); - static std::vector iexp = makeExpParamInfos( "y", "A" ); + static std::vector vexp = makeExpParamInfos( "y", "V" ); + static std::vector iexp = makeExpParamInfos( "y", "A" ); - /*static std::vector vsfam = makeSfamParamInfos( "y", "V" ); - static std::vector isfam = makeSfamParamInfos( "y", "A" ); + /*static std::vector vsfam = makeSfamParamInfos( "y", "V" ); + static std::vector isfam = makeSfamParamInfos( "y", "A" ); - static std::vector vsffm = makeSffmParamInfos( "y", "V" ); - static std::vector isffm = makeSffmParamInfos( "y", "A" );*/ + static std::vector vsffm = makeSffmParamInfos( "y", "V" ); + static std::vector isffm = makeSffmParamInfos( "y", "A" );*/ - static std::vector vpwl = makePwlParamInfos( "y", "Voltage", "V" ); - static std::vector ipwl = makePwlParamInfos( "y", "Current", "A" ); + static std::vector vpwl = makePwlParamInfos( "y", "Voltage", "V" ); + static std::vector ipwl = makePwlParamInfos( "y", "Current", "A" ); - static std::vector vwhitenoise = makeWhiteNoiseParamInfos( "y", "V" ); - static std::vector iwhitenoise = makeWhiteNoiseParamInfos( "y", "A" ); + static std::vector vwhitenoise = makeWhiteNoiseParamInfos( "y", "V" ); + static std::vector iwhitenoise = makeWhiteNoiseParamInfos( "y", "A" ); - static std::vector vpinknoise = makePinkNoiseParamInfos( "y", "V" ); - static std::vector ipinknoise = makePinkNoiseParamInfos( "y", "A" ); + static std::vector vpinknoise = makePinkNoiseParamInfos( "y", "V" ); + static std::vector ipinknoise = makePinkNoiseParamInfos( "y", "A" ); - static std::vector vburstnoise = makeBurstNoiseParamInfos( "y", "V" ); - static std::vector iburstnoise = makeBurstNoiseParamInfos( "y", "A" ); + static std::vector vburstnoise = makeBurstNoiseParamInfos( "y", "V" ); + static std::vector iburstnoise = makeBurstNoiseParamInfos( "y", "A" ); - static std::vector vrandomuniform = makeRandomUniformParamInfos( "y", "V" ); - static std::vector irandomuniform = makeRandomUniformParamInfos( "y", "A" ); + static std::vector vrandomuniform = makeRandomUniformParamInfos( "y", "V" ); + static std::vector irandomuniform = makeRandomUniformParamInfos( "y", "A" ); - static std::vector vrandomnormal = makeRandomNormalParamInfos( "y", "V" ); - static std::vector irandomnormal = makeRandomNormalParamInfos( "y", "A" ); + static std::vector vrandomnormal = makeRandomNormalParamInfos( "y", "V" ); + static std::vector irandomnormal = makeRandomNormalParamInfos( "y", "A" ); - static std::vector vrandomexp = makeRandomExpParamInfos( "y", "V" ); - static std::vector irandomexp = makeRandomExpParamInfos( "y", "A" ); + static std::vector vrandomexp = makeRandomExpParamInfos( "y", "V" ); + static std::vector irandomexp = makeRandomExpParamInfos( "y", "A" ); - static std::vector vrandompoisson = makeRandomPoissonParamInfos( "y", "V" ); - static std::vector irandompoisson = makeRandomPoissonParamInfos( "y", "A" ); + static std::vector vrandompoisson = makeRandomPoissonParamInfos( "y", "V" ); + static std::vector irandompoisson = makeRandomPoissonParamInfos( "y", "A" ); switch( aType ) { @@ -377,13 +351,14 @@ const std::vector& SIM_MODEL_SOURCE::makeParamInfos( TYPE aType ) //case TYPE::I_RANDPOISSON: return irandompoisson; default: wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SOURCE" ); - static std::vector empty; + static std::vector empty; return empty; } } -std::vector SIM_MODEL_SOURCE::makeDcParamInfos( wxString aPrefix, wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeDcParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -401,7 +376,8 @@ std::vector SIM_MODEL_SOURCE::makeDcParamInfos( wxString aPrefix, w } -std::vector SIM_MODEL_SOURCE::makeSinParamInfos( wxString aPrefix, wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeSinParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -461,7 +437,8 @@ std::vector SIM_MODEL_SOURCE::makeSinParamInfos( wxString aPrefix, } -std::vector SIM_MODEL_SOURCE::makePulseParamInfos( wxString aPrefix, wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makePulseParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -537,7 +514,8 @@ std::vector SIM_MODEL_SOURCE::makePulseParamInfos( wxString aPrefix } -std::vector SIM_MODEL_SOURCE::makeExpParamInfos( wxString aPrefix, wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeExpParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -595,7 +573,7 @@ std::vector SIM_MODEL_SOURCE::makeExpParamInfos( wxString aPrefix, } -/*std::vector SIM_MODEL_SOURCE::makeSfamParamInfos( wxString aPrefix, wxString aUnit ) +/*std::vector SIM_MODEL_SOURCE::makeSfamParamInfos( wxString aPrefix, wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -644,7 +622,7 @@ std::vector SIM_MODEL_SOURCE::makeExpParamInfos( wxString aPrefix, } -std::vector SIM_MODEL_SOURCE::makeSffmParamInfos( wxString aPrefix, wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeSffmParamInfos( wxString aPrefix, wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -710,8 +688,9 @@ std::vector SIM_MODEL_SOURCE::makeSffmParamInfos( wxString aPrefix, }*/ -std::vector SIM_MODEL_SOURCE::makePwlParamInfos( wxString aPrefix, wxString aQuantity, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makePwlParamInfos( wxString aPrefix, + wxString aQuantity, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -783,8 +762,8 @@ std::vector SIM_MODEL_SOURCE::makePwlParamInfos( wxString aPrefix, } -std::vector SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -810,8 +789,8 @@ std::vector SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( wxString aP } -std::vector SIM_MODEL_SOURCE::makePinkNoiseParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makePinkNoiseParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -845,8 +824,8 @@ std::vector SIM_MODEL_SOURCE::makePinkNoiseParamInfos( wxString aPr } -std::vector SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -880,8 +859,8 @@ std::vector SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( wxString aP } -std::vector SIM_MODEL_SOURCE::makeRandomUniformParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeRandomUniformParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -923,8 +902,8 @@ std::vector SIM_MODEL_SOURCE::makeRandomUniformParamInfos( wxString } -std::vector SIM_MODEL_SOURCE::makeRandomNormalParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeRandomNormalParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -966,8 +945,8 @@ std::vector SIM_MODEL_SOURCE::makeRandomNormalParamInfos( wxString } -std::vector SIM_MODEL_SOURCE::makeRandomExpParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeRandomExpParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; @@ -1009,8 +988,8 @@ std::vector SIM_MODEL_SOURCE::makeRandomExpParamInfos( wxString aPr } -std::vector SIM_MODEL_SOURCE::makeRandomPoissonParamInfos( wxString aPrefix, - wxString aUnit ) +std::vector SIM_MODEL_SOURCE::makeRandomPoissonParamInfos( wxString aPrefix, + wxString aUnit ) { std::vector paramInfos; PARAM::INFO paramInfo; diff --git a/eeschema/sim/sim_model_source.h b/eeschema/sim/sim_model_source.h index 5d6bcee29f..30b7d2ac26 100644 --- a/eeschema/sim/sim_model_source.h +++ b/eeschema/sim/sim_model_source.h @@ -48,11 +48,6 @@ class SIM_MODEL_SOURCE : public SIM_MODEL public: SIM_MODEL_SOURCE( TYPE aType ); - 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; @@ -75,7 +70,7 @@ private: template void inferredWriteDataFields( std::vector& aFields ) const; - std::vector getPinNames() const override; + std::vector getPinNames() const override { return { "+", "-" }; } wxString getParamValueString( const wxString& aParamName, const wxString& aDefaultValue ) const; diff --git a/eeschema/sim/sim_model_tline.cpp b/eeschema/sim/sim_model_tline.cpp index 47dbb8584d..797f15c436 100644 --- a/eeschema/sim/sim_model_tline.cpp +++ b/eeschema/sim/sim_model_tline.cpp @@ -31,8 +31,8 @@ SIM_MODEL_TLINE::SIM_MODEL_TLINE( TYPE aType ) : SIM_MODEL( aType ), m_isInferred( false ) { - static std::vector z0 = makeZ0ParamInfo(); - static std::vector rlgc = makeRlgcParamInfo(); + static std::vector z0 = makeZ0ParamInfos(); + static std::vector rlgc = makeRlgcParamInfos(); switch( aType ) { @@ -52,26 +52,6 @@ SIM_MODEL_TLINE::SIM_MODEL_TLINE( TYPE aType ) } -void SIM_MODEL_TLINE::ReadDataSchFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - if( GetFieldValue( aFields, PARAMS_FIELD ) != "" ) - SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields ); - else - InferredReadDataFields( aSymbolPinCount, aFields ); -} - - -void SIM_MODEL_TLINE::ReadDataLibFields( unsigned aSymbolPinCount, - const std::vector* aFields ) -{ - if( GetFieldValue( aFields, PARAMS_FIELD ) != "" ) - SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields ); - else - InferredReadDataFields( aSymbolPinCount, aFields ); -} - - void SIM_MODEL_TLINE::WriteDataSchFields( std::vector& aFields ) const { SIM_MODEL::WriteDataSchFields( aFields ); @@ -102,7 +82,7 @@ void SIM_MODEL_TLINE::inferredWriteDataFields( std::vector& aFields ) const } -std::vector SIM_MODEL_TLINE::makeZ0ParamInfo() +std::vector SIM_MODEL_TLINE::makeZ0ParamInfos() { std::vector paramInfos; PARAM::INFO paramInfo = {}; @@ -131,7 +111,7 @@ std::vector SIM_MODEL_TLINE::makeZ0ParamInfo() } -std::vector SIM_MODEL_TLINE::makeRlgcParamInfo() +std::vector SIM_MODEL_TLINE::makeRlgcParamInfos() { std::vector paramInfos; PARAM::INFO paramInfo = {}; @@ -188,9 +168,3 @@ std::vector SIM_MODEL_TLINE::makeRlgcParamInfo() return paramInfos; } - - -bool SIM_MODEL_TLINE::requiresSpiceModel() const -{ - return GetType() == TYPE::TLINE_RLGC; -} diff --git a/eeschema/sim/sim_model_tline.h b/eeschema/sim/sim_model_tline.h index 1cc47f5345..29869c04cd 100644 --- a/eeschema/sim/sim_model_tline.h +++ b/eeschema/sim/sim_model_tline.h @@ -33,11 +33,6 @@ class SIM_MODEL_TLINE : public SIM_MODEL public: SIM_MODEL_TLINE( TYPE aType ); - 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; @@ -48,13 +43,13 @@ private: template void inferredWriteDataFields( std::vector& aFields ) const; - static std::vector makeZ0ParamInfo(); - static std::vector makeRlgcParamInfo(); - std::vector getPinNames() const override { return { "1+", "1-", "2+", "2-" }; } // Subcircuits require models even when they have no Spice instance parameters. - bool requiresSpiceModel() const override; + bool requiresSpiceModel() const override { return GetType() == TYPE::TLINE_RLGC; } + + static std::vector makeZ0ParamInfos(); + static std::vector makeRlgcParamInfos(); bool m_isInferred; }; diff --git a/eeschema/sim/sim_value.cpp b/eeschema/sim/sim_value.cpp index 1138b45dca..5cb185d117 100644 --- a/eeschema/sim/sim_value.cpp +++ b/eeschema/sim/sim_value.cpp @@ -657,6 +657,8 @@ bool SIM_VALUE_INST::operator==( const T& aOther ) const template <> bool SIM_VALUE_INST::operator==( const bool& aOther ) const { + // Note that we take nullopt as the same as false here. + if( !m_value ) return false == aOther; diff --git a/qa/unittests/eeschema/sim/test_sim_model_ngspice.cpp b/qa/unittests/eeschema/sim/test_sim_model_ngspice.cpp index 244e78f711..570e92491c 100644 --- a/qa/unittests/eeschema/sim/test_sim_model_ngspice.cpp +++ b/qa/unittests/eeschema/sim/test_sim_model_ngspice.cpp @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE( Models ) BOOST_CHECK_EQUAL( instanceParamCount, 3 ); break;*/ - case MODEL_TYPE::SWITCH: + /*case MODEL_TYPE::SWITCH: BOOST_CHECK_EQUAL( modelParamCount, 7 ); BOOST_CHECK_EQUAL( instanceParamCount, 8 ); break; @@ -93,7 +93,7 @@ BOOST_AUTO_TEST_CASE( Models ) case MODEL_TYPE::CSWITCH: BOOST_CHECK_EQUAL( modelParamCount, 7 ); BOOST_CHECK_EQUAL( instanceParamCount, 7 ); - break; + break;*/ case MODEL_TYPE::DIODE: BOOST_CHECK_EQUAL( modelParamCount, 76 );