Sim: Implement "enum" model parameters for switches

Displayed in Sim Model Dialog parameter grid as a dropdown
(wxEnumProperty).
This commit is contained in:
Mikolaj Wielgus 2022-08-30 09:00:52 +02:00
parent 8dddc07f26
commit bd6c153ad9
8 changed files with 111 additions and 22 deletions

View File

@ -553,11 +553,9 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::newParamProperty( int aParamIndex ) const
wxString paramDescription;
if( param.info.description == "" )
paramDescription = wxString::Format( "%s (%s)",
param.info.description,
param.info.name );
else
paramDescription = wxString::Format( "%s", param.info.name );
else
paramDescription = wxString::Format( "%s (%s)", param.info.description, param.info.name );
wxPGProperty* prop = nullptr;
@ -584,8 +582,16 @@ wxPGProperty* DIALOG_SIM_MODEL<T>::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 );
if( param.info.enumValues.empty() )
{
prop = new SIM_STRING_PROPERTY( paramDescription, param.info.name, m_library,
curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING );
}
else
{
prop = new SIM_ENUM_PROPERTY( paramDescription, param.info.name, m_library,
curModelSharedPtr(), aParamIndex, SIM_VALUE::TYPE_STRING );
}
break;
default:

View File

@ -57,7 +57,6 @@ public:
wxString IsValid( const wxString& aStr ) const override
{
//if( !IsIncluded( aStr ) )
if( m_includes.Index( aStr ) == wxNOT_FOUND )
return wxString::Format( _( "No model named '%s' in library." ), aStr );

View File

@ -27,6 +27,7 @@
#include <wx/string.h>
#include <map>
#include <utility>
#include <sch_field.h>
#include <lib_field.h>
@ -379,6 +380,7 @@ public:
bool isInstanceParam = false;
wxString spiceModelName = "";
wxString spiceInstanceName = "";
std::vector<wxString> enumValues = {};
// TODO: Stop using brace-initializers, use this constructor for all info structs.
INFO( wxString aName = "",
@ -393,8 +395,9 @@ public:
const wxString& aDescription = "",
bool aIsSpiceInstanceParam = false,
bool aIsInstanceParam = false,
wxString aSpiceModelName = "",
wxString aSpiceInstanceName = "" ) :
const wxString& aSpiceModelName = "",
const wxString& aSpiceInstanceName = "",
std::vector<wxString> aEnumValues = {} ) :
name( aName ),
id( aId ),
dir( aDir ),
@ -407,7 +410,9 @@ public:
description( aDescription ),
isSpiceInstanceParam( aIsSpiceInstanceParam ),
isInstanceParam( aIsInstanceParam ),
spiceInstanceName( aSpiceInstanceName )
spiceModelName( aSpiceModelName ),
spiceInstanceName( aSpiceInstanceName ),
enumValues( std::move( aEnumValues ) )
{
}
};
@ -527,10 +532,6 @@ public:
const PIN& GetPin( unsigned aIndex ) const { return m_pins.at( aIndex ); }
std::vector<std::reference_wrapper<const PIN>> GetPins() const;
virtual std::vector<std::reference_wrapper<const PIN>> GetSpicePins() const
{
return GetPins();
}
void SetPinSymbolPinNumber( int aPinIndex, const wxString& aSymbolPinNumber )
{
@ -581,6 +582,11 @@ protected:
void ParsePinsField( unsigned aSymbolPinCount, const wxString& aPinsField );
void ParseDisabledField( const wxString& aDisabledField );
virtual std::vector<std::reference_wrapper<const PIN>> GetSpicePins() const
{
return GetPins();
}
virtual bool SetParamFromSpiceCode( const wxString& aParamName, const wxString& aParamValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation
= SIM_VALUE_GRAMMAR::NOTATION::SPICE );

View File

@ -46,6 +46,8 @@ SIM_MODEL_SWITCH::SIM_MODEL_SWITCH( TYPE aType ) : SIM_MODEL( aType )
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SWITCH" );
break;
}
SetParamValue( "ic", "none" );
}
@ -53,7 +55,12 @@ wxString SIM_MODEL_SWITCH::GenerateSpiceItemParamValuePair( const PARAM& aParam,
bool& aIsFirst ) const
{
// The only instance param is "ic", which is positional.
return aParam.value->ToSpiceString();
wxString value = aParam.value->ToSpiceString();
if( value == "none" )
return "";
else
return value;
}
@ -94,6 +101,17 @@ wxString SIM_MODEL_SWITCH::GenerateSpiceItemLine( const wxString& aRefName,
}
wxString SIM_MODEL_SWITCH::GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const
{
if( aParam.info.name == "ic" && aParam.value->ToString() == "none" )
{
return "";
}
return SIM_MODEL::GenerateParamValuePair( aParam, aIsFirst );
}
std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> SIM_MODEL_SWITCH::GetSpicePins() const
{
switch( GetType() )
@ -124,6 +142,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
paramInfo.description = "Threshold voltage";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "vt";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "his";
@ -134,6 +153,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
paramInfo.description = "Hysteresis voltage";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "vh";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "ron";
@ -144,6 +164,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
paramInfo.description = "Resistance when open";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "roff";
@ -154,6 +175,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
paramInfo.description = "Resistance when closed";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "ic";
@ -161,9 +183,10 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwVParamInfos()
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1";
paramInfo.description = "Initial state (1=on, 0=off)";
paramInfo.description = "Initial state";
paramInfo.isSpiceInstanceParam = true;
paramInfo.spiceModelName = "";
paramInfo.enumValues = { "none", "off", "on" };
paramInfos.push_back( paramInfo );
return paramInfos;
@ -183,6 +206,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
paramInfo.description = "Threshold current";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "it";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "his";
@ -193,6 +217,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
paramInfo.description = "Hysteresis current";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "ih";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "ron";
@ -203,6 +228,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
paramInfo.description = "Resistance when open";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "roff";
@ -213,6 +239,7 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
paramInfo.description = "Resistance when closed";
paramInfo.isSpiceInstanceParam = false;
paramInfo.spiceModelName = "";
paramInfo.enumValues = {};
paramInfos.push_back( paramInfo );
paramInfo.name = "ic";
@ -220,9 +247,10 @@ const std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SWITCH::makeSwIParamInfos()
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "1";
paramInfo.description = "Initial state (1=on, 0=off)";
paramInfo.description = "Initial state";
paramInfo.isSpiceInstanceParam = true;
paramInfo.spiceModelName = "";
paramInfo.enumValues = { "none", "off", "on" };
paramInfos.push_back( paramInfo );
return paramInfos;

View File

@ -38,6 +38,8 @@ public:
const std::vector<wxString>& aSymbolPinNumbers,
const std::vector<wxString>& aPinNetNames ) const override;
protected:
wxString GenerateParamValuePair( const PARAM& aParam, bool& aIsFirst ) const override;
std::vector<std::reference_wrapper<const PIN>> GetSpicePins() const override;
private:

View File

@ -369,18 +369,19 @@ wxValidator* SIM_STRING_PROPERTY::DoGetValidator() const
}
bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aText,
int aArgFlags ) const
{
wxString paramValueStr = m_model->GetBaseParam( m_paramIndex ).value->ToString();
wxString baseParamValue = m_model->GetBaseParam( m_paramIndex ).value->ToString();
aVariant = aText;
// TODO: Don't use string comparison.
if( m_model->GetBaseModel() && ( aText == "" || aText == paramValueStr ) )
if( m_model->GetBaseModel() && ( aText == "" || aText == baseParamValue ) )
{
if( !m_model->SetParamValue( m_paramIndex, "" ) ) // Nullify.
return false;
aVariant = paramValueStr; // Use the inherited value (if it exists) if null.
aVariant = baseParamValue; // Use the inherited value (if it exists) if null.
}
else
{
@ -390,3 +391,29 @@ bool SIM_STRING_PROPERTY::StringToValue( wxVariant& aVariant, const wxString& aT
return true;
}
SIM_ENUM_PROPERTY::SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
std::shared_ptr<SIM_LIBRARY> aLibrary,
std::shared_ptr<SIM_MODEL> aModel,
int aParamIndex,
SIM_VALUE::TYPE aValueType,
SIM_VALUE_GRAMMAR::NOTATION aNotation )
: wxEnumProperty( aLabel, aName,
wxArrayString( aModel->GetParam( aParamIndex ).info.enumValues.size(),
&aModel->GetParam( aParamIndex ).info.enumValues[0] ) ),
m_library( aLibrary ),
m_model( aModel ),
m_paramIndex( aParamIndex )
{
auto it = std::find( GetParam().info.enumValues.begin(), GetParam().info.enumValues.end(),
GetParam().value->ToString() );
SetValue( std::distance( GetParam().info.enumValues.begin(), it ) );
}
bool SIM_ENUM_PROPERTY::IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags ) const
{
m_model->SetParamValue( m_paramIndex, GetParam().info.enumValues.at( aNumber ) );
return wxEnumProperty::IntToValue( aVariant, aNumber, aArgFlags );
}

View File

@ -135,4 +135,25 @@ protected:
int m_paramIndex;
};
class SIM_ENUM_PROPERTY : public wxEnumProperty
{
public:
SIM_ENUM_PROPERTY( const wxString& aLabel, const wxString& aName,
std::shared_ptr<SIM_LIBRARY> aLibrary,
std::shared_ptr<SIM_MODEL> aModel,
int aParamIndex,
SIM_VALUE::TYPE aValueType = SIM_VALUE::TYPE_FLOAT,
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI );
bool IntToValue( wxVariant& aVariant, int aNumber, int aArgFlags = 0 ) const override;
const SIM_MODEL::PARAM& GetParam() const { return m_model->GetParam( m_paramIndex ); }
protected:
std::shared_ptr<SIM_LIBRARY> m_library;
std::shared_ptr<SIM_MODEL> m_model;
int m_paramIndex;
};
#endif // SIM_PROPERTY_H

View File

@ -726,7 +726,7 @@
(property "Sim_Pins" "1 6 3 5" (id 6) (at 163.83 83.82 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Params" "thr=500m his=0 ron=100m roff=1T ic=on" (id 7) (at 163.83 83.82 0)
(property "Sim_Params" "thr=500m his=0 ron=100m roff=1T" (id 7) (at 163.83 83.82 0)
(effects (font (size 1.27 1.27)) hide)
)
(pin "1" (uuid 985f68da-ac8b-4dfe-a794-ff843a4dcef6))