Sim: Basic cleanup after KIBIS merge

- Some preliminary refactoring,
- Use multiple types for IBIS drivers instead of a wftype variable,
- Remove the m_requiresUIUpdate variable and its accessors.
This commit is contained in:
Mikolaj Wielgus 2022-09-30 14:29:44 +02:00
parent 62f89ba0d6
commit 0d369f700f
7 changed files with 314 additions and 353 deletions

View File

@ -45,7 +45,7 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
: DIALOG_SIM_MODEL_BASE( aParent ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_library( std::make_shared<SIM_LIBRARY_SPICE>() ),
m_library( nullptr ),
m_prevModel( nullptr ),
m_firstCategory( nullptr ),
m_prevParamGridSelection( nullptr ),
@ -114,7 +114,6 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, SCH_SYMBOL& aSymbol,
// Now all widgets have the size fixed, call FinishDialogSettings
finishDialogSettings();
setIbisMode( IsIbisLoaded() );
}
@ -264,15 +263,13 @@ void DIALOG_SIM_MODEL<T>::updateWidgets()
template <typename T>
void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
{
if( ( &curModel() != m_prevModel ) || curModel().RequiresUIUpdate() )
if( &curModel() != m_prevModel )
{
SIM_MODEL::DEVICE_TYPE_ deviceType = SIM_MODEL::TypeInfo( curModel().GetType() ).deviceType;
// Change the Type choice to match the current device type.
if( !m_prevModel || deviceType != m_prevModel->GetDeviceType()
|| curModel().RequiresUIUpdate() )
if( !m_prevModel || deviceType != m_prevModel->GetDeviceType() )
{
curModel().UIUpdated();
m_deviceTypeChoice->SetSelection( static_cast<int>( deviceType ) );
m_typeChoice->Clear();
@ -530,12 +527,16 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
SIM_MODEL::TYPE ibisType = SIM_MODEL::TYPE::KIBIS_DEVICE;
if( ibisTypeString == "IBISDRIVER" )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER;
else if( ibisTypeString == "IBISDIFFDRIVER" )
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDRIVER;
if( ibisTypeString == "IBISDRIVERDC" )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_DC;
else if( ibisTypeString == "IBISDRIVERRECT" )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_RECT;
else if( ibisTypeString == "IBISDRIVRPRBS" )
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS;
else if( ibisTypeString == "IBISDIFFDEVICE" )
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDEVICE;
else if( ibisTypeString == "IBISDIFFDRIVER" )
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDRIVER;
std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library )
->ReadFile( std::string( absolutePath.ToUTF8() ), ibisType );
@ -1029,9 +1030,12 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
&& typeDescription == SIM_MODEL::TypeInfo( type ).description )
{
if( IsIbisLoaded()
&& ( type == SIM_MODEL::TYPE::KIBIS_DEVICE || type == SIM_MODEL::TYPE::KIBIS_DRIVER
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE ) )
&& ( type == SIM_MODEL::TYPE::KIBIS_DEVICE
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_DC
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_RECT
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER ) )
{
std::shared_ptr<SIM_MODEL_KIBIS> kibismodel =
std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
@ -1061,25 +1065,6 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
template <typename T>
void DIALOG_SIM_MODEL<T>::onParamGridChanged( wxPropertyGridEvent& aEvent )
{
if( IsIbisLoaded() )
{
wxString propValue = "";
wxString propName = aEvent.GetPropertyName();
wxPGProperty* property = aEvent.GetProperty();
if( property && propName == "wftype" )
{
wxVariant variant = aEvent.GetPropertyValue();
propValue = property->ValueToString( variant );
std::shared_ptr<SIM_MODEL_KIBIS> kibismodel =
std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
m_libraryModels.at( m_modelNameCombobox->GetSelection() ) );
kibismodel->SetParameters( std::string( propValue.c_str() ) );
kibismodel->SetParamValue( "wftype", std::string( propValue.c_str() ) );
}
}
updateWidgets();
}

View File

@ -273,10 +273,14 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
switch( type )
{
case SIM_MODEL::TYPE::KIBIS_DEVICE:
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
case SIM_MODEL::TYPE::KIBIS_DRIVER_RECT:
case SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS:
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE:
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
case SIM_MODEL::TYPE::KIBIS_DEVICE:
case SIM_MODEL::TYPE::KIBIS_DRIVER: break;
break;
default:
wxLogTrace( "IBIS:", wxT( "Invalid ibis type: '%s'" ),
symbol->GetRef( &sheet ) );
@ -299,7 +303,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
KIBIS_PARAMETER kparams;
const SIM_MODEL::PARAM* mparam;
const SIM_MODEL::PARAM* mparam = nullptr;
mparam = spiceItem.model->FindParam( "vcc" );
@ -331,107 +335,110 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
case SIM_MODEL::TYPE::KIBIS_DEVICE:
kpin->writeSpiceDevice( &modelData, modelName, *kmodel, kparams );
break;
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE:
kpin->writeSpiceDiffDevice( &modelData, modelName, *kmodel, kparams );
break;
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
case SIM_MODEL::TYPE::KIBIS_DRIVER:
kpin->writeSpiceDiffDriver( &modelData, modelName, *kmodel, kparams );
break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
{
mparam = spiceItem.model->FindParam( "wftype" );
std::string paramValue = spiceItem.model->FindParam( "dc" )->value->ToString();
if( mparam )
if( paramValue == "hi-Z" )
{
std::string paramValue = mparam->value->ToString();
if( paramValue == "rect" )
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>(
new KIBIS_WAVEFORM_RECTANGULAR() );
mparam = spiceItem.model->FindParam( "ton" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_ton = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "toff" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_toff = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "delay" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_delay = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 0 ) );
}
if( paramValue == "prbs" )
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>(
new KIBIS_WAVEFORM_PRBS() );
mparam = spiceItem.model->FindParam( "bitrate" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_bitrate = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "nbits" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_bits = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "delay" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_delay = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 0 ) );
}
else if( paramValue == "stuck high" )
{
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH() );
}
else if( paramValue == "stuck low" )
{
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_LOW() );
}
else if( paramValue == "high Z" )
{
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z() );
}
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z() );
}
else if( paramValue == "low" )
{
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_LOW() );
}
else if( paramValue == "high" )
{
kparams.m_waveform =
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH() );
}
if( type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER )
kpin->writeSpiceDiffDriver( &modelData, modelName, *kmodel, kparams );
else
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
break;
}
default: continue;
case SIM_MODEL::TYPE::KIBIS_DRIVER_RECT:
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>(
new KIBIS_WAVEFORM_RECTANGULAR() );
mparam = spiceItem.model->FindParam( "ton" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_ton = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "toff" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_toff = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "delay" );
if( mparam )
static_cast<KIBIS_WAVEFORM_RECTANGULAR*>( kparams.m_waveform )
->m_delay = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 0 ) );
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
break;
}
case SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS:
{
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>(
new KIBIS_WAVEFORM_PRBS() );
mparam = spiceItem.model->FindParam( "f0" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_bitrate = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "bits" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_bits = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 1 ) );
mparam = spiceItem.model->FindParam( "delay" );
if( mparam )
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
->m_delay = static_cast<double>(
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
->Get()
.value_or( 0 ) );
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
break;
}
default:
continue;
}
cacheFile.Write( wxString( modelData ) );

View File

@ -98,7 +98,7 @@ SIM_MODEL::DEVICE_INFO SIM_MODEL::DeviceTypeInfo( DEVICE_TYPE_ aDeviceType )
case DEVICE_TYPE_::V: return { "V", "Voltage Source" };
case DEVICE_TYPE_::I: return { "I", "Current Source" };
case DEVICE_TYPE_::KIBIS: return { "IBIS", "Ibis model" };
case DEVICE_TYPE_::KIBIS: return { "IBIS", "Ibis Model" };
case DEVICE_TYPE_::SUBCKT: return { "SUBCKT", "Subcircuit" };
case DEVICE_TYPE_::XSPICE: return { "XSPICE", "XSPICE Code Model" };
@ -197,7 +197,7 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
case TYPE::NMOS_HISIMHV2: return { DEVICE_TYPE_::NMOS, "HISIMHV2", "HiSIM_HV2" };
case TYPE::PMOS_HISIMHV2: return { DEVICE_TYPE_::PMOS, "HISIMHV2", "HiSIM_HV2" };
case TYPE::V: return { DEVICE_TYPE_::V, "DC", "DC", };
case TYPE::V: return { DEVICE_TYPE_::V, "DC", "DC", };
case TYPE::V_SIN: return { DEVICE_TYPE_::V, "SIN", "Sine" };
case TYPE::V_PULSE: return { DEVICE_TYPE_::V, "PULSE", "Pulse" };
case TYPE::V_EXP: return { DEVICE_TYPE_::V, "EXP", "Exponential" };
@ -213,7 +213,7 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
//case TYPE::V_RANDPOISSON: return { DEVICE_TYPE::V, "RANDPOISSON", "Random Poisson" };
case TYPE::V_BEHAVIORAL: return { DEVICE_TYPE_::V, "=", "Behavioral" };
case TYPE::I: return { DEVICE_TYPE_::I, "DC", "DC", };
case TYPE::I: return { DEVICE_TYPE_::I, "DC", "DC", };
case TYPE::I_SIN: return { DEVICE_TYPE_::I, "SIN", "Sine" };
case TYPE::I_PULSE: return { DEVICE_TYPE_::I, "PULSE", "Pulse" };
case TYPE::I_EXP: return { DEVICE_TYPE_::I, "EXP", "Exponential" };
@ -229,15 +229,19 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
//case TYPE::I_RANDPOISSON: return { DEVICE_TYPE::I, "RANDPOISSON", "Random Poisson" };
case TYPE::I_BEHAVIORAL: return { DEVICE_TYPE_::I, "=", "Behavioral" };
case TYPE::KIBIS_DRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDRIVER", "Driver" };
case TYPE::KIBIS_DEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDEVICE", "Device" };
case TYPE::KIBIS_DIFFDRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDRIVER", "Differential driver" };
case TYPE::KIBIS_DIFFDEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDEVICE", "Differential device" };
case TYPE::SUBCKT: return { DEVICE_TYPE_::SUBCKT, "", "" };
case TYPE::XSPICE: return { DEVICE_TYPE_::XSPICE, "", "" };
case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" };
case TYPE::_ENUM_END: break;
case TYPE::KIBIS_DEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDEVICE", "Device" };
case TYPE::KIBIS_DRIVER_DC: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERDC", "DC driver" };
case TYPE::KIBIS_DRIVER_RECT: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERRECT", "Rectangular wave driver" };
case TYPE::KIBIS_DRIVER_PRBS: return { DEVICE_TYPE_::KIBIS, "IBISDRIVERPRBS", "PRBS driver" };
case TYPE::KIBIS_DIFFDEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDEVICE", "Differential device" };
case TYPE::KIBIS_DIFFDRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDRIVER", "Differential driver" };
case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" };
case TYPE::_ENUM_END: break;
}
wxFAIL;
@ -366,7 +370,9 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
case TYPE::XSPICE: return { "A" };
case TYPE::KIBIS_DEVICE: return { "X" };
case TYPE::KIBIS_DRIVER: return { "X" };
case TYPE::KIBIS_DRIVER_DC: return { "X" };
case TYPE::KIBIS_DRIVER_RECT: return { "X" };
case TYPE::KIBIS_DRIVER_PRBS: return { "X" };
case TYPE::KIBIS_DIFFDEVICE: return { "X" };
case TYPE::KIBIS_DIFFDRIVER: return { "X" };
@ -952,8 +958,10 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
case TYPE::XSPICE:
return std::make_unique<SIM_MODEL_XSPICE>( aType );
case TYPE::KIBIS_DRIVER:
case TYPE::KIBIS_DEVICE:
case TYPE::KIBIS_DRIVER_DC:
case TYPE::KIBIS_DRIVER_RECT:
case TYPE::KIBIS_DRIVER_PRBS:
case TYPE::KIBIS_DIFFDEVICE:
case TYPE::KIBIS_DIFFDRIVER:
return std::make_unique<SIM_MODEL_KIBIS>( aType );
@ -973,7 +981,7 @@ SIM_MODEL::SIM_MODEL( TYPE aType ) :
}
SIM_MODEL::SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
SIM_MODEL::SIM_MODEL( TYPE aType, std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator ) :
m_baseModel( nullptr ),
m_spiceGenerator( std::move( aSpiceGenerator ) ),
m_type( aType ),

View File

@ -140,10 +140,11 @@ public:
V,
I,
KIBIS,
SUBCKT,
XSPICE,
KIBIS,
SPICE
)
@ -296,13 +297,16 @@ public:
//I_RANDPOISSON,
I_BEHAVIORAL,
KIBIS_DRIVER,
SUBCKT,
XSPICE,
KIBIS_DEVICE,
KIBIS_DRIVER_DC,
KIBIS_DRIVER_RECT,
KIBIS_DRIVER_PRBS,
KIBIS_DIFFDEVICE,
KIBIS_DIFFDRIVER,
SUBCKT,
XSPICE,
RAWSPICE
)
@ -504,7 +508,7 @@ public:
DEVICE_TYPE_ GetDeviceType() const { return GetTypeInfo().deviceType; }
TYPE GetType() const { return m_type; }
virtual const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
@ -545,9 +549,6 @@ public:
void SetIsEnabled( bool aIsEnabled ) { m_isEnabled = aIsEnabled; }
bool IsEnabled() const { return m_isEnabled; }
bool RequiresUIUpdate() { return m_requiresUIUpdate; };
void UIUpdated() { m_requiresUIUpdate = false; };
protected:
static std::unique_ptr<SIM_MODEL> Create( TYPE aType );
@ -572,7 +573,6 @@ protected:
bool aAllowOnlyFirstValue = false,
bool aAllowParamValuePairs = true );
std::vector<PARAM> m_params;
bool m_requiresUIUpdate = false;
const SIM_MODEL* m_baseModel;
private:

View File

@ -47,17 +47,35 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const std::string&
std::vector<std::string> currentNames;
for( const SIM_MODEL::PIN& pin : GetPins() )
{
currentNames.push_back( fmt::format( "I({:s}:{:s})", ItemName( aRefName ), pin.name ) );
}
currentNames.push_back( fmt::format( "I({}:{})", ItemName( aRefName ), pin.name ) );
return currentNames;
}
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, std::string aWfType ) :
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) :
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR_KIBIS>( *this ) )
{
SetParameters( aType, aWfType );
static std::vector<PARAM::INFO> device = makeParamInfos( TYPE::KIBIS_DEVICE );
static std::vector<PARAM::INFO> dcDriver = makeParamInfos( TYPE::KIBIS_DRIVER_DC );
static std::vector<PARAM::INFO> rectDriver = makeParamInfos( TYPE::KIBIS_DRIVER_RECT );
static std::vector<PARAM::INFO> prbsDriver = makeParamInfos( TYPE::KIBIS_DRIVER_PRBS );
std::vector<PARAM::INFO>* paramInfos = nullptr;
switch( aType )
{
case SIM_MODEL::TYPE::KIBIS_DEVICE: paramInfos = &device; break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC: paramInfos = &dcDriver; break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_RECT: paramInfos = &rectDriver; break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_PRBS: paramInfos = &prbsDriver; break;
default:
wxFAIL;
return;
}
for( const PARAM::INFO& paramInfo : *paramInfos )
AddParam( paramInfo );
if( aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER )
{
@ -106,80 +124,6 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource,
ReadDataFields( 2, &aFields );
}
void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
{
static std::vector<PARAM::INFO> kibisparam_device =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DEVICE, "Dummy" );
static std::vector<PARAM::INFO> kibisparam_driver_rect =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_RECT );
static std::vector<PARAM::INFO> kibisparam_driver_stuckh =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_STUCKH );
static std::vector<PARAM::INFO> kibisparam_driver_stuckl =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_STUCKL );
static std::vector<PARAM::INFO> kibisparam_driver_highz =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_HIGHZ );
static std::vector<PARAM::INFO> kibisparam_driver_prbs =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_PRBS );
static std::vector<PARAM::INFO> kibisparam_driver_allParams =
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::JOCKER );
m_requiresUIUpdate = true;
static std::vector<PARAM::INFO>* params;
switch( aType )
{
case SIM_MODEL::TYPE::KIBIS_DEVICE:
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE: params = &kibisparam_device; break;
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
case SIM_MODEL::TYPE::KIBIS_DRIVER:
if( aWfType == SIM_MODEL_KIBIS::DRIVER_RECT )
params = &kibisparam_driver_rect;
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_STUCKH )
params = &kibisparam_driver_stuckh;
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_STUCKL )
params = &kibisparam_driver_stuckl;
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_HIGHZ )
params = &kibisparam_driver_highz;
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_PRBS )
params = &kibisparam_driver_prbs;
else
params = &kibisparam_driver_allParams;
// All params allow for a newly created model to read any parameter
break;
default: wxFAIL; return;
}
m_params.clear();
/*
if( m_params.empty() )
{
for( const PARAM::INFO& paramInfo : *params )
AddParam( paramInfo );
}
for( PARAM& param : m_params )
{
// We don't erase other params because we don't want to reset their values
if( param.info.category == PARAM::CATEGORY::WAVEFORM )
{
m_params.pop_back(); // waveform parameters are at the end of the vector
}
}
*/
for( const PARAM::INFO& paramInfo : *params )
AddParam( paramInfo );
}
void SIM_MODEL_KIBIS::SetParameters( std::string aWfType )
{
SetParameters( GetType(), aWfType );
}
void SIM_MODEL_KIBIS::CreatePins( unsigned aSymbolPinCount )
{
SIM_MODEL::CreatePins( aSymbolPinCount );
@ -191,8 +135,28 @@ void SIM_MODEL_KIBIS::CreatePins( unsigned aSymbolPinCount )
}
const std::vector<SIM_MODEL::PARAM::INFO>
SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
bool SIM_MODEL_KIBIS::ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber )
{
KIBIS_COMPONENT* kcomp = aLib.m_kibis.GetComponent( std::string( GetComponentName() ) );
if( !kcomp )
return false;
KIBIS_PIN* kpin = kcomp->GetPin( std::string( aPinNumber.c_str() ) );
if( !kpin )
return false;
m_ibisModels.clear();
for( KIBIS_MODEL* kmodel : kpin->m_models )
m_ibisModels.push_back( kmodel->m_name );
return true;
}
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makeParamInfos( TYPE aType )
{
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
@ -218,7 +182,7 @@ SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
paramInfos.push_back( paramInfo );
paramInfo.name = "lpin";
paramInfo.type = SIM_VALUE::TYPE_STRING;
paramInfo.type = SIM_VALUE::TYPE_STRING;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
paramInfo.defaultValue = "TYP";
@ -236,109 +200,107 @@ SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
paramInfo.spiceModelName = "";
paramInfo.enumValues = { "TYP", "MIN", "MAX" };
paramInfos.push_back( paramInfo );
std::vector<PARAM::INFO> dc = makeDcWaveformParamInfos();
std::vector<PARAM::INFO> rect = makeRectWaveformParamInfos();
std::vector<PARAM::INFO> prbs = makePrbsWaveformParamInfos();
if( aType == SIM_MODEL::TYPE::KIBIS_DEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE )
return paramInfos; // Devices have no waveform parameters
paramInfo.name = "wftype";
paramInfo.type = SIM_VALUE::TYPE_STRING;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = DRIVER_HIGHZ;
paramInfo.description = _( "Waveform" );
paramInfo.spiceModelName = "";
paramInfo.enumValues = { DRIVER_RECT, DRIVER_STUCKH, DRIVER_STUCKL, DRIVER_HIGHZ, DRIVER_PRBS };
paramInfos.push_back( paramInfo );
if( aWfType == DRIVER_STUCKH || aWfType == DRIVER_STUCKL || aWfType == DRIVER_HIGHZ )
switch( aType )
{
return paramInfos;
}
case TYPE::KIBIS_DRIVER_DC:
for( const PARAM::INFO& param : makeDcWaveformParamInfos() )
paramInfos.push_back( param );
break;
paramInfo.name = "ac";
paramInfo.type = SIM_VALUE::TYPE_STRING;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "normal";
paramInfo.description = _( "Modeling accuracy" );
paramInfo.spiceModelName = "";
paramInfo.enumValues = { "low", "normal", "high" };
paramInfos.push_back( paramInfo );
case TYPE::KIBIS_DRIVER_RECT:
for( const PARAM::INFO& param : makeRectWaveformParamInfos() )
paramInfos.push_back( param );
break;
if ( aWfType == DRIVER_RECT || aWfType == JOCKER )
case TYPE::KIBIS_DRIVER_PRBS:
for( const PARAM::INFO& param : makePrbsWaveformParamInfos() )
paramInfos.push_back( param );
break;
{
paramInfo.name = "ton";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "ON time" );
paramInfo.spiceModelName = "";
paramInfos.push_back( paramInfo );
paramInfo.name = "toff";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "OFF time" );
paramInfo.spiceModelName = "";
paramInfos.push_back( paramInfo );
paramInfo.name = "delay";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "0";
paramInfo.description = _( "Delay" );
paramInfo.spiceModelName = "";
paramInfos.push_back( paramInfo );
}
if ( ( aWfType == DRIVER_PRBS ) || ( aWfType == JOCKER ) )
{
paramInfo.name = "f0";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "Bitrate" );
paramInfo.spiceModelName = "";
paramInfos.push_back( paramInfo );
paramInfo.name = "bits";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "Number of bits" );
paramInfo.spiceModelName = "";
paramInfos.push_back( paramInfo );
default:
break;
}
return paramInfos;
}
bool SIM_MODEL_KIBIS::ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber )
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makeDcWaveformParamInfos()
{
KIBIS_COMPONENT* kcomp = aLib.m_kibis.GetComponent( std::string( GetComponentName() ) );
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
if( !kcomp )
return false;
paramInfo.name = "dc";
paramInfo.type = SIM_VALUE::TYPE_STRING;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "hi-Z";
paramInfo.description = _( "DC Value" );
paramInfo.enumValues = { "hi-Z", "low", "high" };
paramInfos.push_back( paramInfo );
KIBIS_PIN* kpin = kcomp->GetPin( std::string( aPinNumber.c_str() ) );
return paramInfos;
}
if( !kpin )
return false;
m_ibisModels.clear();
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makeRectWaveformParamInfos()
{
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
for( KIBIS_MODEL* kmodel : kpin->m_models )
m_ibisModels.push_back( kmodel->m_name );
paramInfo.name = "ton";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "ON time" );
paramInfos.push_back( paramInfo );
return true;
}
paramInfo.name = "toff";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "OFF time" );
paramInfos.push_back( paramInfo );
paramInfo.name = "delay";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "s";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "0";
paramInfo.description = _( "Delay" );
paramInfos.push_back( paramInfo );
return paramInfos;
}
std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makePrbsWaveformParamInfos()
{
std::vector<PARAM::INFO> paramInfos;
PARAM::INFO paramInfo;
paramInfo.name = "f0";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "Hz";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "Bitrate" );
paramInfos.push_back( paramInfo );
paramInfo.name = "bits";
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
paramInfo.unit = "";
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
paramInfo.defaultValue = "";
paramInfo.description = _( "Number of bits" );
paramInfos.push_back( paramInfo );
return paramInfos;
}

View File

@ -51,10 +51,9 @@ class SIM_MODEL_KIBIS : public SIM_MODEL
static constexpr auto DRIVER_STUCKL = "stuck low";
static constexpr auto DRIVER_HIGHZ = "high Z";
static constexpr auto DRIVER_PRBS = "prbs";
static constexpr auto JOCKER = "kicadjocker"; // Gets all parameters
public:
SIM_MODEL_KIBIS( TYPE aType, std::string aWfType = "NoInit" );
SIM_MODEL_KIBIS( TYPE aType );
// @brief Special copy constructor
// creates a a model with aType, but tries to match parameters from aSource.
@ -63,9 +62,6 @@ public:
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<LIB_FIELD>& aFields );
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<SCH_FIELD>& aFields );
void SetParameters( TYPE aType, std::string aWfType ); // To change between device / driver
void SetParameters( std::string aWfType ); // To change between device / driver
std::vector<std::pair<std::string, std::string>> GetIbisPins() const
{
return GetBaseModel()
@ -96,9 +92,12 @@ protected:
private:
bool requiresSpiceModelLine() const override { return true; }
static const std::vector<PARAM::INFO> makeKibisParamInfos( TYPE aType, std::string aWfType );
std::vector<std::unique_ptr<PARAM::INFO>> m_paramInfos;
static std::vector<PARAM::INFO> makeParamInfos( TYPE aType );
static std::vector<PARAM::INFO> makeDcWaveformParamInfos();
static std::vector<PARAM::INFO> makeRectWaveformParamInfos();
static std::vector<PARAM::INFO> makePrbsWaveformParamInfos();
std::vector<std::string> m_ibisModels;
};

View File

@ -277,47 +277,47 @@ void SIM_MODEL_SOURCE::inferredWriteDataFields( std::vector<T>& aFields ) const
const std::vector<SIM_MODEL::PARAM::INFO>& SIM_MODEL_SOURCE::makeParamInfos( TYPE aType )
{
static std::vector<SIM_MODEL::PARAM::INFO> vdc = makeDcParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> idc = makeDcParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vdc = makeDcParamInfos( "y", "V" );
static std::vector<PARAM::INFO> idc = makeDcParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vsin = makeSinParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> isin = makeSinParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vsin = makeSinParamInfos( "y", "V" );
static std::vector<PARAM::INFO> isin = makeSinParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vpulse = makePulseParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> ipulse = makePulseParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vpulse = makePulseParamInfos( "y", "V" );
static std::vector<PARAM::INFO> ipulse = makePulseParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vexp = makeExpParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> iexp = makeExpParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vexp = makeExpParamInfos( "y", "V" );
static std::vector<PARAM::INFO> iexp = makeExpParamInfos( "y", "A" );
/*static std::vector<SIM_MODEL::PARAM::INFO> vsfam = makeSfamParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> isfam = makeSfamParamInfos( "y", "A" );
/*static std::vector<PARAM::INFO> vsfam = makeSfamParamInfos( "y", "V" );
static std::vector<PARAM::INFO> isfam = makeSfamParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vsffm = makeSffmParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> isffm = makeSffmParamInfos( "y", "A" );*/
static std::vector<PARAM::INFO> vsffm = makeSffmParamInfos( "y", "V" );
static std::vector<PARAM::INFO> isffm = makeSffmParamInfos( "y", "A" );*/
static std::vector<SIM_MODEL::PARAM::INFO> vpwl = makePwlParamInfos( "y", "Voltage", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> ipwl = makePwlParamInfos( "y", "Current", "A" );
static std::vector<PARAM::INFO> vpwl = makePwlParamInfos( "y", "Voltage", "V" );
static std::vector<PARAM::INFO> ipwl = makePwlParamInfos( "y", "Current", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vwhitenoise = makeWhiteNoiseParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> iwhitenoise = makeWhiteNoiseParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vwhitenoise = makeWhiteNoiseParamInfos( "y", "V" );
static std::vector<PARAM::INFO> iwhitenoise = makeWhiteNoiseParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vpinknoise = makePinkNoiseParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> ipinknoise = makePinkNoiseParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vpinknoise = makePinkNoiseParamInfos( "y", "V" );
static std::vector<PARAM::INFO> ipinknoise = makePinkNoiseParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vburstnoise = makeBurstNoiseParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> iburstnoise = makeBurstNoiseParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vburstnoise = makeBurstNoiseParamInfos( "y", "V" );
static std::vector<PARAM::INFO> iburstnoise = makeBurstNoiseParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vrandomuniform = makeRandomUniformParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> irandomuniform = makeRandomUniformParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vrandomuniform = makeRandomUniformParamInfos( "y", "V" );
static std::vector<PARAM::INFO> irandomuniform = makeRandomUniformParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vrandomnormal = makeRandomNormalParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> irandomnormal = makeRandomNormalParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vrandomnormal = makeRandomNormalParamInfos( "y", "V" );
static std::vector<PARAM::INFO> irandomnormal = makeRandomNormalParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vrandomexp = makeRandomExpParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> irandomexp = makeRandomExpParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vrandomexp = makeRandomExpParamInfos( "y", "V" );
static std::vector<PARAM::INFO> irandomexp = makeRandomExpParamInfos( "y", "A" );
static std::vector<SIM_MODEL::PARAM::INFO> vrandompoisson = makeRandomPoissonParamInfos( "y", "V" );
static std::vector<SIM_MODEL::PARAM::INFO> irandompoisson = makeRandomPoissonParamInfos( "y", "A" );
static std::vector<PARAM::INFO> vrandompoisson = makeRandomPoissonParamInfos( "y", "V" );
static std::vector<PARAM::INFO> irandompoisson = makeRandomPoissonParamInfos( "y", "A" );
switch( aType )
{