KiCad PCB EDA Suite
SIM_MODEL Class Reference

#include <sim_model.h>

Inheritance diagram for SIM_MODEL:
SIM_MODEL_BEHAVIORAL SIM_MODEL_IDEAL SIM_MODEL_KIBIS SIM_MODEL_L_MUTUAL SIM_MODEL_RAW_SPICE SIM_MODEL_R_POT SIM_MODEL_SOURCE SIM_MODEL_SPICE SIM_MODEL_SWITCH SIM_MODEL_TLINE SIM_MODEL_XSPICE

Classes

struct  PARAM
 
struct  PIN
 
struct  SPICE_INFO
 

Public Member Functions

 DEFINE_ENUM_CLASS_WITH_ITERATOR (DEVICE_T, NONE, R, C, L, TLINE, SW, D, NPN, PNP, NJFET, PJFET, NMES, PMES, NMOS, PMOS, V, I, SUBCKT, XSPICE, KIBIS, SPICE) struct DEVICE_INFO
 
 DEFINE_ENUM_CLASS_WITH_ITERATOR (TYPE, NONE, R, R_POT, R_BEHAVIORAL, C, C_BEHAVIORAL, L, L_MUTUAL, L_BEHAVIORAL, TLINE_Z0, TLINE_RLGC, SW_V, SW_I, D, NPN_VBIC, PNP_VBIC, NPN_GUMMELPOON, PNP_GUMMELPOON, NPN_HICUM2, PNP_HICUM2, NJFET_SHICHMANHODGES, PJFET_SHICHMANHODGES, NJFET_PARKERSKELLERN, PJFET_PARKERSKELLERN, NMES_STATZ, PMES_STATZ, NMES_YTTERDAL, PMES_YTTERDAL, NMES_HFET1, PMES_HFET1, NMES_HFET2, PMES_HFET2, NMOS_VDMOS, PMOS_VDMOS, NMOS_MOS1, PMOS_MOS1, NMOS_MOS2, PMOS_MOS2, NMOS_MOS3, PMOS_MOS3, NMOS_BSIM1, PMOS_BSIM1, NMOS_BSIM2, PMOS_BSIM2, NMOS_MOS6, PMOS_MOS6, NMOS_MOS9, PMOS_MOS9, NMOS_BSIM3, PMOS_BSIM3, NMOS_B4SOI, PMOS_B4SOI, NMOS_BSIM4, PMOS_BSIM4, NMOS_B3SOIFD, PMOS_B3SOIFD, NMOS_B3SOIDD, PMOS_B3SOIDD, NMOS_B3SOIPD, PMOS_B3SOIPD, NMOS_HISIM2, PMOS_HISIM2, NMOS_HISIMHV1, PMOS_HISIMHV1, NMOS_HISIMHV2, PMOS_HISIMHV2, V, V_SIN, V_PULSE, V_EXP, V_PWL, V_WHITENOISE, V_PINKNOISE, V_BURSTNOISE, V_RANDUNIFORM, V_RANDNORMAL, V_RANDEXP, V_BEHAVIORAL, I, I_SIN, I_PULSE, I_EXP, I_PWL, I_WHITENOISE, I_PINKNOISE, I_BURSTNOISE, I_RANDUNIFORM, I_RANDNORMAL, I_RANDEXP, I_BEHAVIORAL, SUBCKT, XSPICE, KIBIS_DEVICE, KIBIS_DRIVER_DC, KIBIS_DRIVER_RECT, KIBIS_DRIVER_PRBS, RAWSPICE) struct INFO
 
const SPICE_GENERATORSpiceGenerator () const
 
const SIM_MODEL_SERIALIZERSerializer () const
 
virtual ~SIM_MODEL ()
 
 SIM_MODEL ()=delete
 
 SIM_MODEL (const SIM_MODEL &aOther)=delete
 
 SIM_MODEL (SIM_MODEL &&aOther)=default
 
SIM_MODELoperator= (SIM_MODEL &&aOther)=delete
 
template<typename T >
void ReadDataFields (const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
 
template<typename T >
void WriteFields (std::vector< T > &aFields) const
 
SPICE_INFO GetSpiceInfo () const
 
void AddPin (const PIN &aPin)
 
void ClearPins ()
 
int FindModelPinIndex (const std::string &aSymbolPinNumber)
 
void AddParam (const PARAM::INFO &aInfo)
 
DEVICE_INFO GetDeviceInfo () const
 
INFO GetTypeInfo () const
 
DEVICE_T GetDeviceType () const
 
TYPE GetType () const
 
const SIM_MODELGetBaseModel () const
 
virtual void SetBaseModel (const SIM_MODEL &aBaseModel)
 
virtual std::vector< std::string > GetPinNames () const
 
int GetPinCount () const
 
const PINGetPin (unsigned aIndex) const
 
std::vector< std::reference_wrapper< const PIN > > GetPins () const
 
void SetPinSymbolPinNumber (int aPinIndex, const std::string &aSymbolPinNumber)
 
virtual void SetPinSymbolPinNumber (const std::string &aPinName, const std::string &aSymbolPinNumber)
 
int GetParamCount () const
 
virtual const PARAMGetParam (unsigned aParamIndex) const
 
virtual const PARAMGetTunerParam () const
 
const PARAMFindParam (const std::string &aParamName) const
 
std::vector< std::reference_wrapper< const PARAM > > GetParams () const
 
const PARAMGetParamOverride (unsigned aParamIndex) const
 
const PARAMGetBaseParam (unsigned aParamIndex) const
 
void SetParamValue (int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
 
void SetParamValue (const std::string &aParamName, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
 
virtual bool HasAutofill () const
 
virtual bool HasPrimaryValue () const
 
void SetIsEnabled (bool aIsEnabled)
 
bool IsEnabled () const
 
void SetIsStoredInValue (bool aIsStoredInValue)
 
bool IsStoredInValue () const
 
virtual void SwitchSingleEndedDiff (bool aDiff)
 
template<>
void ReadDataFields (const std::vector< SCH_FIELD > *aFields, const std::vector< LIB_PIN * > &aPins)
 
template<>
void ReadDataFields (const std::vector< LIB_FIELD > *aFields, const std::vector< LIB_PIN * > &aPins)
 
template<>
void WriteFields (std::vector< SCH_FIELD > &aFields) const
 
template<>
void WriteFields (std::vector< LIB_FIELD > &aFields) const
 
template<>
std::string GetFieldValue (const std::vector< void > *aFields, const wxString &aFieldName, bool aResolve)
 

Static Public Member Functions

static DEVICE_INFO DeviceInfo (DEVICE_T aDeviceType)
 
static INFO TypeInfo (TYPE aType)
 
static SPICE_INFO SpiceInfo (TYPE aType)
 
template<typename T >
static TYPE ReadTypeFromFields (const std::vector< T > &aFields)
 
template<typename T >
static TYPE InferTypeFromLegacyFields (const std::vector< T > &aFields)
 
static std::unique_ptr< SIM_MODELCreate (TYPE aType, const std::vector< LIB_PIN * > &aPins, REPORTER *aReporter)
 
static std::unique_ptr< SIM_MODELCreate (const SIM_MODEL *aBaseModel, const std::vector< LIB_PIN * > &aPins, REPORTER *aReporter)
 
template<typename T >
static std::unique_ptr< SIM_MODELCreate (const SIM_MODEL *aBaseModel, const std::vector< LIB_PIN * > &aPins, const std::vector< T > &aFields, REPORTER *aReporter)
 
template<typename T >
static std::unique_ptr< SIM_MODELCreate (const std::vector< T > &aFields, const std::vector< LIB_PIN * > &aPins, bool aResolved, REPORTER *aReporter)
 
template<typename T >
static std::string GetFieldValue (const std::vector< T > *aFields, const wxString &aFieldName, bool aResolve=true)
 
template<typename T >
static void SetFieldValue (std::vector< T > &aFields, const wxString &aFieldName, const std::string &aValue)
 
template<class T_symbol , class T_field >
static bool InferSimModel (T_symbol &aSymbol, std::vector< T_field > *aFields, bool aResolve, SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString *aDeviceType, wxString *aModelType, wxString *aModelParams, wxString *aPinMap)
 
template<class T_symbol , class T_field >
static void MigrateSimModel (T_symbol &aSymbol, const PROJECT *aProject)
 

Protected Member Functions

 SIM_MODEL (TYPE aType)
 
 SIM_MODEL (TYPE aType, std::unique_ptr< SPICE_GENERATOR > aSpiceGenerator)
 
 SIM_MODEL (TYPE aType, std::unique_ptr< SPICE_GENERATOR > aSpiceGenerator, std::unique_ptr< SIM_MODEL_SERIALIZER > aSerializer)
 
void createPins (const std::vector< LIB_PIN * > &aSymbolPins)
 
virtual int doFindParam (const std::string &aParamName) const
 
virtual void doSetParamValue (int aParamIndex, const std::string &aValue)
 

Static Protected Member Functions

static std::unique_ptr< SIM_MODELCreate (TYPE aType)
 

Protected Attributes

std::vector< PARAMm_params
 
std::vector< PINm_pins
 
const SIM_MODELm_baseModel
 
std::unique_ptr< SIM_MODEL_SERIALIZERm_serializer
 

Private Member Functions

template<typename T >
void doReadDataFields (const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
 
template<typename T >
void doWriteFields (std::vector< T > &aFields) const
 
virtual bool requiresSpiceModelLine (const SPICE_ITEM &aItem) const
 

Private Attributes

std::unique_ptr< SPICE_GENERATORm_spiceGenerator
 
const TYPE m_type
 
bool m_isEnabled
 
bool m_isStoredInValue
 

Friends

class SPICE_GENERATOR
 
class NETLIST_EXPORTER_SPICE
 

Detailed Description

Definition at line 61 of file sim_model.h.

Constructor & Destructor Documentation

◆ ~SIM_MODEL()

SIM_MODEL::~SIM_MODEL ( )
virtualdefault

◆ SIM_MODEL() [1/6]

SIM_MODEL::SIM_MODEL ( )
delete

◆ SIM_MODEL() [2/6]

SIM_MODEL::SIM_MODEL ( const SIM_MODEL aOther)
delete

◆ SIM_MODEL() [3/6]

SIM_MODEL::SIM_MODEL ( SIM_MODEL &&  aOther)
default

◆ SIM_MODEL() [4/6]

SIM_MODEL::SIM_MODEL ( TYPE  aType)
protected

Definition at line 959 of file sim_model.cpp.

959 :
960 SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR>( *this ),
961 std::make_unique<SIM_MODEL_SERIALIZER>( *this ) )
962{
963}
SIM_MODEL()=delete

◆ SIM_MODEL() [5/6]

SIM_MODEL::SIM_MODEL ( TYPE  aType,
std::unique_ptr< SPICE_GENERATOR aSpiceGenerator 
)
protected

Definition at line 966 of file sim_model.cpp.

966 :
967 SIM_MODEL( aType, std::move( aSpiceGenerator ),
968 std::make_unique<SIM_MODEL_SERIALIZER>( *this ) )
969{
970}

References move.

◆ SIM_MODEL() [6/6]

SIM_MODEL::SIM_MODEL ( TYPE  aType,
std::unique_ptr< SPICE_GENERATOR aSpiceGenerator,
std::unique_ptr< SIM_MODEL_SERIALIZER aSerializer 
)
protected

Definition at line 973 of file sim_model.cpp.

974 :
975 m_baseModel( nullptr ),
976 m_serializer( std::move( aSerializer ) ),
977 m_spiceGenerator( std::move( aSpiceGenerator ) ),
978 m_type( aType ),
979 m_isEnabled( true ),
980 m_isStoredInValue( false )
981{
982}
std::unique_ptr< SPICE_GENERATOR > m_spiceGenerator
Definition: sim_model.h:537
bool m_isEnabled
Definition: sim_model.h:540
bool m_isStoredInValue
Definition: sim_model.h:541
std::unique_ptr< SIM_MODEL_SERIALIZER > m_serializer
Definition: sim_model.h:534
const TYPE m_type
Definition: sim_model.h:539
const SIM_MODEL * m_baseModel
Definition: sim_model.h:533

References move.

Member Function Documentation

◆ AddParam()

◆ AddPin()

void SIM_MODEL::AddPin ( const PIN aPin)

Definition at line 693 of file sim_model.cpp.

694{
695 m_pins.push_back( aPin );
696}
std::vector< PIN > m_pins
Definition: sim_model.h:532

References m_pins.

Referenced by createPins(), SPICE_MODEL_PARSER_SUBCKT::ReadModel(), SIM_MODEL_SUBCKT::SetBaseModel(), and SIM_MODEL_KIBIS::SwitchSingleEndedDiff().

◆ ClearPins()

void SIM_MODEL::ClearPins ( )

Definition at line 699 of file sim_model.cpp.

700{
701 m_pins.clear();
702}

References m_pins.

Referenced by SIM_MODEL_KIBIS::SwitchSingleEndedDiff().

◆ Create() [1/5]

template<typename T >
std::unique_ptr< SIM_MODEL > SIM_MODEL::Create ( const SIM_MODEL aBaseModel,
const std::vector< LIB_PIN * > &  aPins,
const std::vector< T > &  aFields,
REPORTER aReporter 
)
static

Definition at line 504 of file sim_model.cpp.

508{
509 TYPE type = ReadTypeFromFields( aFields );
510
511 // If the model has a specified type, it takes priority over the type of its base class.
512 if( type == TYPE::NONE && aBaseModel )
513 type = aBaseModel->GetType();
514
515 std::unique_ptr<SIM_MODEL> model;
516
517 // A null base model means the model wasn't found in the library, so create a fallback
518
519 if( !aBaseModel || dynamic_cast<const SIM_MODEL_SPICE_FALLBACK*>( aBaseModel ) )
520 model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
521 else if( dynamic_cast< const SIM_MODEL_RAW_SPICE*>( aBaseModel ) )
522 model = std::make_unique<SIM_MODEL_RAW_SPICE>();
523 else
524 model = Create( type );
525
526 try
527 {
528 if( aBaseModel )
529 model->SetBaseModel( *aBaseModel );
530
531 model->ReadDataFields( &aFields, aPins );
532 }
533 catch( IO_ERROR& err )
534 {
535 if( aReporter )
536 aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
537 else
538 DisplayErrorMessage( nullptr, err.What() );
539 }
540
541 return model;
542}
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:76
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
static std::unique_ptr< SIM_MODEL > Create(TYPE aType, const std::vector< LIB_PIN * > &aPins, REPORTER *aReporter)
Definition: sim_model.cpp:446
static TYPE ReadTypeFromFields(const std::vector< T > &aFields)
Definition: sim_model.cpp:368
TYPE GetType() const
Definition: sim_model.h:449
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
@ NONE
Definition: kibis.h:53
@ RPT_SEVERITY_ERROR
SIM_MODEL::TYPE TYPE
Definition: sim_model.cpp:54

References Create(), DisplayErrorMessage(), GetType(), NONE, ReadTypeFromFields(), REPORTER::Report(), RPT_SEVERITY_ERROR, and IO_ERROR::What().

◆ Create() [2/5]

std::unique_ptr< SIM_MODEL > SIM_MODEL::Create ( const SIM_MODEL aBaseModel,
const std::vector< LIB_PIN * > &  aPins,
REPORTER aReporter 
)
static

Definition at line 468 of file sim_model.cpp.

471{
472 TYPE type = aBaseModel ? aBaseModel->GetType() : TYPE::NONE;
473 std::unique_ptr<SIM_MODEL> model;
474
475 // A null base model means the model wasn't found in the library, so create a fallback
476
477 if( !aBaseModel || dynamic_cast<const SIM_MODEL_SPICE_FALLBACK*>( aBaseModel ) )
478 model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
479 else if( dynamic_cast< const SIM_MODEL_RAW_SPICE*>( aBaseModel ) )
480 model = std::make_unique<SIM_MODEL_RAW_SPICE>();
481 else
482 model = Create( type );
483
484 try
485 {
486 if( aBaseModel )
487 model->SetBaseModel( *aBaseModel );
488
489 model->ReadDataFields( static_cast<const std::vector<SCH_FIELD>*>( nullptr ), aPins );
490 }
491 catch( IO_ERROR& err )
492 {
493 if( aReporter )
494 aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
495 else
496 DisplayErrorMessage( nullptr, err.What() );
497 }
498
499 return model;
500}

References Create(), DisplayErrorMessage(), GetType(), NONE, REPORTER::Report(), RPT_SEVERITY_ERROR, and IO_ERROR::What().

◆ Create() [3/5]

template<typename T >
std::unique_ptr< SIM_MODEL > SIM_MODEL::Create ( const std::vector< T > &  aFields,
const std::vector< LIB_PIN * > &  aPins,
bool  aResolved,
REPORTER aReporter 
)
static

Definition at line 556 of file sim_model.cpp.

559{
560 TYPE type = ReadTypeFromFields( aFields );
561 std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
562
563 try
564 {
565 model->ReadDataFields( &aFields, aPins );
566 }
567 catch( const IO_ERROR& parse_err )
568 {
569 if( !aResolved )
570 {
571 aReporter->Report( parse_err.What(), RPT_SEVERITY_ERROR );
572 return model;
573 }
574
575 // Just because we can't parse it doesn't mean that a SPICE interpreter can't. Fall
576 // back to a raw spice code model.
577
578 std::string modelData = GetFieldValue( &aFields, SIM_PARAMS_FIELD );
579
580 if( modelData.empty() )
581 modelData = GetFieldValue( &aFields, SIM_VALUE_FIELD );
582
583 model = std::make_unique<SIM_MODEL_RAW_SPICE>( modelData );
584
585 try
586 {
587 model->createPins( aPins );
588 model->m_serializer->ParsePins( GetFieldValue( &aFields, SIM_PINS_FIELD ) );
589 }
590 catch( const IO_ERROR& err )
591 {
592 // We own the pin syntax, so if we can't parse it then there's an error, full stop.
593 if( aReporter )
594 aReporter->Report( err.Problem(), RPT_SEVERITY_ERROR );
595 else
596 THROW_IO_ERROR( err.Problem() );
597 }
598 }
599
600 return model;
601}
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:46
static std::string GetFieldValue(const std::vector< T > *aFields, const wxString &aFieldName, bool aResolve=true)
Definition: sim_model.cpp:612
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
#define SIM_PINS_FIELD
Definition: sim_model.h:54
#define SIM_PARAMS_FIELD
Definition: sim_model.h:55
#define SIM_VALUE_FIELD
Definition: sim_model.h:50

References Create(), GetFieldValue(), IO_ERROR::Problem(), ReadTypeFromFields(), REPORTER::Report(), RPT_SEVERITY_ERROR, SIM_PARAMS_FIELD, SIM_PINS_FIELD, SIM_VALUE_FIELD, THROW_IO_ERROR, and IO_ERROR::What().

◆ Create() [4/5]

std::unique_ptr< SIM_MODEL > SIM_MODEL::Create ( TYPE  aType)
staticprotected

Definition at line 878 of file sim_model.cpp.

879{
880 switch( aType )
881 {
882 case TYPE::R:
883 case TYPE::C:
884 case TYPE::L:
885 return std::make_unique<SIM_MODEL_IDEAL>( aType );
886
887 case TYPE::R_POT:
888 return std::make_unique<SIM_MODEL_R_POT>();
889
890 case TYPE::L_MUTUAL:
891 return std::make_unique<SIM_MODEL_L_MUTUAL>();
892
893 case TYPE::R_BEHAVIORAL:
894 case TYPE::C_BEHAVIORAL:
895 case TYPE::L_BEHAVIORAL:
896 case TYPE::V_BEHAVIORAL:
897 case TYPE::I_BEHAVIORAL:
898 return std::make_unique<SIM_MODEL_BEHAVIORAL>( aType );
899
900 case TYPE::TLINE_Z0:
901 case TYPE::TLINE_RLGC:
902 return std::make_unique<SIM_MODEL_TLINE>( aType );
903
904 case TYPE::SW_V:
905 case TYPE::SW_I:
906 return std::make_unique<SIM_MODEL_SWITCH>( aType );
907
908 case TYPE::V:
909 case TYPE::I:
910 case TYPE::V_SIN:
911 case TYPE::I_SIN:
912 case TYPE::V_PULSE:
913 case TYPE::I_PULSE:
914 case TYPE::V_EXP:
915 case TYPE::I_EXP:
916 /*case TYPE::V_SFAM:
917 case TYPE::I_SFAM:
918 case TYPE::V_SFFM:
919 case TYPE::I_SFFM:*/
920 case TYPE::V_PWL:
921 case TYPE::I_PWL:
922 case TYPE::V_WHITENOISE:
923 case TYPE::I_WHITENOISE:
924 case TYPE::V_PINKNOISE:
925 case TYPE::I_PINKNOISE:
926 case TYPE::V_BURSTNOISE:
927 case TYPE::I_BURSTNOISE:
928 case TYPE::V_RANDUNIFORM:
929 case TYPE::I_RANDUNIFORM:
930 case TYPE::V_RANDNORMAL:
931 case TYPE::I_RANDNORMAL:
932 case TYPE::V_RANDEXP:
933 case TYPE::I_RANDEXP:
934 //case TYPE::V_RANDPOISSON:
935 //case TYPE::I_RANDPOISSON:
936 return std::make_unique<SIM_MODEL_SOURCE>( aType );
937
938 case TYPE::SUBCKT:
939 return std::make_unique<SIM_MODEL_SUBCKT>();
940
941 case TYPE::XSPICE:
942 return std::make_unique<SIM_MODEL_XSPICE>( aType );
943
944 case TYPE::KIBIS_DEVICE:
945 case TYPE::KIBIS_DRIVER_DC:
946 case TYPE::KIBIS_DRIVER_RECT:
947 case TYPE::KIBIS_DRIVER_PRBS:
948 return std::make_unique<SIM_MODEL_KIBIS>( aType );
949
950 case TYPE::RAWSPICE:
951 return std::make_unique<SIM_MODEL_RAW_SPICE>();
952
953 default:
954 return std::make_unique<SIM_MODEL_NGSPICE>( aType );
955 }
956}
#define I(x, y, z)
Definition: md5_hash.cpp:18

References I.

◆ Create() [5/5]

std::unique_ptr< SIM_MODEL > SIM_MODEL::Create ( TYPE  aType,
const std::vector< LIB_PIN * > &  aPins,
REPORTER aReporter 
)
static

Definition at line 446 of file sim_model.cpp.

448{
449 std::unique_ptr<SIM_MODEL> model = Create( aType );
450
451 try
452 {
453 // Passing nullptr to ReadDataFields will make it act as if all fields were empty.
454 model->ReadDataFields( static_cast<const std::vector<SCH_FIELD>*>( nullptr ), aPins );
455 }
456 catch( IO_ERROR& err )
457 {
458 if( aReporter )
459 aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
460 else
461 DisplayErrorMessage( nullptr, err.What() );
462 }
463
464 return model;
465}

References Create(), DisplayErrorMessage(), REPORTER::Report(), RPT_SEVERITY_ERROR, and IO_ERROR::What().

Referenced by SIM_MODEL_SPICE::Create(), Create(), SIM_LIB_MGR::CreateModel(), SIM_MODEL_SPICE_FALLBACK::GetPinNames(), MigrateSimModel(), SIM_LIBRARY_KIBIS::ReadFile(), and SIM_MODEL_SPICE_FALLBACK::SIM_MODEL_SPICE_FALLBACK().

◆ createPins()

void SIM_MODEL::createPins ( const std::vector< LIB_PIN * > &  aSymbolPins)
protected

Definition at line 985 of file sim_model.cpp.

986{
987 // Default pin sequence: model pins are the same as symbol pins.
988 // Excess model pins are set as Not Connected.
989 // Note that intentionally nothing is added if `GetPinNames()` returns an empty vector.
990
991 // SIM_MODEL pins must be ordered by symbol pin numbers -- this is assumed by the code that
992 // accesses them.
993
994 std::vector<std::string> pinNames = GetPinNames();
995
996 for( unsigned modelPinIndex = 0; modelPinIndex < pinNames.size(); ++modelPinIndex )
997 {
998 wxString pinName = pinNames[ modelPinIndex ];
999 bool optional = false;
1000
1001 if( pinName.StartsWith( '<' ) && pinName.EndsWith( '>' ) )
1002 {
1003 pinName = pinName.Mid( 1, pinName.Length() - 2 );
1004 optional = true;
1005 }
1006
1007 if( modelPinIndex < aSymbolPins.size() )
1008 {
1009 AddPin( { pinNames.at( modelPinIndex ),
1010 aSymbolPins[ modelPinIndex ]->GetNumber().ToStdString() } );
1011 }
1012 else if( !optional )
1013 {
1014 AddPin( { pinNames.at( modelPinIndex ), "" } );
1015 }
1016 }
1017}
virtual std::vector< std::string > GetPinNames() const
Definition: sim_model.h:454
void AddPin(const PIN &aPin)
Definition: sim_model.cpp:693

References AddPin(), and GetPinNames().

Referenced by doReadDataFields().

◆ DEFINE_ENUM_CLASS_WITH_ITERATOR() [1/2]

SIM_MODEL::DEFINE_ENUM_CLASS_WITH_ITERATOR ( DEVICE_T  ,
NONE  ,
,
C  ,
,
TLINE  ,
SW  ,
D  ,
NPN  ,
PNP  ,
NJFET  ,
PJFET  ,
NMES  ,
PMES  ,
NMOS  ,
PMOS  ,
,
I  ,
SUBCKT  ,
XSPICE  ,
KIBIS  ,
SPICE   
)
inline

Definition at line 71 of file sim_model.h.

105 {
106 std::string fieldValue;
107 std::string description;
108 bool isBuiltin;
109 };

◆ DEFINE_ENUM_CLASS_WITH_ITERATOR() [2/2]

SIM_MODEL::DEFINE_ENUM_CLASS_WITH_ITERATOR ( TYPE  ,
NONE  ,
,
R_POT  ,
R_BEHAVIORAL  ,
C  ,
C_BEHAVIORAL  ,
,
L_MUTUAL  ,
L_BEHAVIORAL  ,
TLINE_Z0  ,
TLINE_RLGC  ,
SW_V  ,
SW_I  ,
D  ,
NPN_VBIC  ,
PNP_VBIC  ,
NPN_GUMMELPOON  ,
PNP_GUMMELPOON  ,
NPN_HICUM2  ,
PNP_HICUM2  ,
NJFET_SHICHMANHODGES  ,
PJFET_SHICHMANHODGES  ,
NJFET_PARKERSKELLERN  ,
PJFET_PARKERSKELLERN  ,
NMES_STATZ  ,
PMES_STATZ  ,
NMES_YTTERDAL  ,
PMES_YTTERDAL  ,
NMES_HFET1  ,
PMES_HFET1  ,
NMES_HFET2  ,
PMES_HFET2  ,
NMOS_VDMOS  ,
PMOS_VDMOS  ,
NMOS_MOS1  ,
PMOS_MOS1  ,
NMOS_MOS2  ,
PMOS_MOS2  ,
NMOS_MOS3  ,
PMOS_MOS3  ,
NMOS_BSIM1  ,
PMOS_BSIM1  ,
NMOS_BSIM2  ,
PMOS_BSIM2  ,
NMOS_MOS6  ,
PMOS_MOS6  ,
NMOS_MOS9  ,
PMOS_MOS9  ,
NMOS_BSIM3  ,
PMOS_BSIM3  ,
NMOS_B4SOI  ,
PMOS_B4SOI  ,
NMOS_BSIM4  ,
PMOS_BSIM4  ,
NMOS_B3SOIFD  ,
PMOS_B3SOIFD  ,
NMOS_B3SOIDD  ,
PMOS_B3SOIDD  ,
NMOS_B3SOIPD  ,
PMOS_B3SOIPD  ,
NMOS_HISIM2  ,
PMOS_HISIM2  ,
NMOS_HISIMHV1  ,
PMOS_HISIMHV1  ,
NMOS_HISIMHV2  ,
PMOS_HISIMHV2  ,
,
V_SIN  ,
V_PULSE  ,
V_EXP  ,
V_PWL  ,
V_WHITENOISE  ,
V_PINKNOISE  ,
V_BURSTNOISE  ,
V_RANDUNIFORM  ,
V_RANDNORMAL  ,
V_RANDEXP  ,
V_BEHAVIORAL  ,
I  ,
I_SIN  ,
I_PULSE  ,
I_EXP  ,
I_PWL  ,
I_WHITENOISE  ,
I_PINKNOISE  ,
I_BURSTNOISE  ,
I_RANDUNIFORM  ,
I_RANDNORMAL  ,
I_RANDEXP  ,
I_BEHAVIORAL  ,
SUBCKT  ,
XSPICE  ,
KIBIS_DEVICE  ,
KIBIS_DRIVER_DC  ,
KIBIS_DRIVER_RECT  ,
KIBIS_DRIVER_PRBS  ,
RAWSPICE   
)
inline

Definition at line 112 of file sim_model.h.

270 {
271 DEVICE_T deviceType;
272 std::string fieldValue;
273 std::string description;
274 };

◆ DeviceInfo()

SIM_MODEL::DEVICE_INFO SIM_MODEL::DeviceInfo ( DEVICE_T  aDeviceType)
static

Definition at line 57 of file sim_model.cpp.

58{
59 switch( aDeviceType )
60 {
61 case DEVICE_T::NONE: return { "", "", true };
62 case DEVICE_T::R: return { "R", "Resistor", true };
63 case DEVICE_T::C: return { "C", "Capacitor", true };
64 case DEVICE_T::L: return { "L", "Inductor", true };
65 case DEVICE_T::TLINE: return { "TLINE", "Transmission Line", true };
66 case DEVICE_T::SW: return { "SW", "Switch", true };
67
68 case DEVICE_T::D: return { "D", "Diode", true };
69 case DEVICE_T::NPN: return { "NPN", "NPN BJT", true };
70 case DEVICE_T::PNP: return { "PNP", "PNP BJT", true };
71
72 case DEVICE_T::NJFET: return { "NJFET", "N-channel JFET", true };
73 case DEVICE_T::PJFET: return { "PJFET", "P-channel JFET", true };
74
75 case DEVICE_T::NMOS: return { "NMOS", "N-channel MOSFET", true };
76 case DEVICE_T::PMOS: return { "PMOS", "P-channel MOSFET", true };
77 case DEVICE_T::NMES: return { "NMES", "N-channel MESFET", true };
78 case DEVICE_T::PMES: return { "PMES", "P-channel MESFET", true };
79
80 case DEVICE_T::V: return { "V", "Voltage Source", true };
81 case DEVICE_T::I: return { "I", "Current Source", true };
82
83 case DEVICE_T::KIBIS: return { "IBIS", "IBIS Model", false };
84
85 case DEVICE_T::SUBCKT: return { "SUBCKT", "Subcircuit", false };
86 case DEVICE_T::XSPICE: return { "XSPICE", "XSPICE Code Model", true };
87 case DEVICE_T::SPICE: return { "SPICE", "Raw Spice Element", true };
88
89 default: wxFAIL; return {};
90 }
91}

References I, and NONE.

Referenced by GetDeviceInfo(), MigrateSimModel(), DIALOG_SIM_MODEL< T_symbol, T_field >::onDeviceTypeChoice(), ReadTypeFromFields(), and DIALOG_SIM_MODEL< T_symbol, T_field >::updateInstanceWidgets().

◆ doFindParam()

int SIM_MODEL::doFindParam ( const std::string &  aParamName) const
protectedvirtual

Reimplemented in SIM_MODEL_NGSPICE, and SIM_MODEL_SPICE_FALLBACK.

Definition at line 798 of file sim_model.cpp.

799{
800 std::string lowerParamName = boost::to_lower_copy( aParamName );
801
802 std::vector<std::reference_wrapper<const PARAM>> params = GetParams();
803
804 for( int ii = 0; ii < (int) params.size(); ++ii )
805 {
806 if( params[ii].get().info.name == lowerParamName )
807 return ii;
808 }
809
810 return -1;
811}
std::vector< std::reference_wrapper< const PARAM > > GetParams() const
Definition: sim_model.cpp:822

References GetParams().

Referenced by FindParam(), and SetParamValue().

◆ doReadDataFields()

template<typename T >
void SIM_MODEL::doReadDataFields ( const std::vector< T > *  aFields,
const std::vector< LIB_PIN * > &  aPins 
)
private

Definition at line 1021 of file sim_model.cpp.

1023{
1024 bool diffMode = GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
1025 SwitchSingleEndedDiff( diffMode );
1026
1027 m_serializer->ParseEnable( GetFieldValue( aFields, SIM_ENABLE_FIELD ) );
1028
1029 createPins( aPins );
1030 m_serializer->ParsePins( GetFieldValue( aFields, SIM_PINS_FIELD ) );
1031
1032 std::string paramsField = GetFieldValue( aFields, SIM_PARAMS_FIELD );
1033
1034 if( !m_serializer->ParseParams( paramsField ) )
1035 m_serializer->ParseValue( GetFieldValue( aFields, SIM_VALUE_FIELD ) );
1036}
static constexpr auto DIFF_FIELD
void createPins(const std::vector< LIB_PIN * > &aSymbolPins)
Definition: sim_model.cpp:985
virtual void SwitchSingleEndedDiff(bool aDiff)
Definition: sim_model.h:498
#define SIM_ENABLE_FIELD
Definition: sim_model.h:56

References createPins(), SIM_LIBRARY_KIBIS::DIFF_FIELD, GetFieldValue(), m_serializer, SIM_ENABLE_FIELD, SIM_PARAMS_FIELD, SIM_PINS_FIELD, SIM_VALUE_FIELD, and SwitchSingleEndedDiff().

Referenced by ReadDataFields().

◆ doSetParamValue()

void SIM_MODEL::doSetParamValue ( int  aParamIndex,
const std::string &  aValue 
)
protectedvirtual

Reimplemented in SIM_MODEL_SOURCE.

Definition at line 848 of file sim_model.cpp.

849{
850 m_params.at( aParamIndex ).value = aValue;
851}

References m_params.

Referenced by SIM_MODEL_SOURCE::doSetParamValue(), and SetParamValue().

◆ doWriteFields()

template<typename T >
void SIM_MODEL::doWriteFields ( std::vector< T > &  aFields) const
private

Definition at line 1040 of file sim_model.cpp.

1041{
1042 SetFieldValue( aFields, SIM_DEVICE_TYPE_FIELD, m_serializer->GenerateDevice() );
1043 SetFieldValue( aFields, SIM_TYPE_FIELD, m_serializer->GenerateType() );
1044
1045 SetFieldValue( aFields, SIM_ENABLE_FIELD, m_serializer->GenerateEnable() );
1046 SetFieldValue( aFields, SIM_PINS_FIELD, m_serializer->GeneratePins() );
1047
1048 SetFieldValue( aFields, SIM_PARAMS_FIELD, m_serializer->GenerateParams() );
1049
1050 if( IsStoredInValue() )
1051 SetFieldValue( aFields, SIM_VALUE_FIELD, m_serializer->GenerateValue() );
1052}
bool IsStoredInValue() const
Definition: sim_model.h:496
static void SetFieldValue(std::vector< T > &aFields, const wxString &aFieldName, const std::string &aValue)
Definition: sim_model.cpp:643
#define SIM_DEVICE_TYPE_FIELD
Definition: sim_model.h:52
#define SIM_TYPE_FIELD
Definition: sim_model.h:53

References IsStoredInValue(), m_serializer, SetFieldValue(), SIM_DEVICE_TYPE_FIELD, SIM_ENABLE_FIELD, SIM_PARAMS_FIELD, SIM_PINS_FIELD, SIM_TYPE_FIELD, and SIM_VALUE_FIELD.

Referenced by WriteFields().

◆ FindModelPinIndex()

int SIM_MODEL::FindModelPinIndex ( const std::string &  aSymbolPinNumber)

Definition at line 705 of file sim_model.cpp.

706{
707 for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
708 {
709 if( GetPin( modelPinIndex ).symbolPinNumber == aSymbolPinNumber )
710 return modelPinIndex;
711 }
712
713 return PIN::NOT_CONNECTED;
714}
int GetPinCount() const
Definition: sim_model.h:456
const PIN & GetPin(unsigned aIndex) const
Definition: sim_model.h:457
std::string symbolPinNumber
Definition: sim_model.h:292
static constexpr auto NOT_CONNECTED
Definition: sim_model.h:294

References GetPin(), GetPinCount(), SIM_MODEL::PIN::NOT_CONNECTED, and SIM_MODEL::PIN::symbolPinNumber.

◆ FindParam()

const SIM_MODEL::PARAM * SIM_MODEL::FindParam ( const std::string &  aParamName) const

Definition at line 814 of file sim_model.cpp.

815{
816 int idx = doFindParam( aParamName );
817
818 return idx >= 0 ? &GetParam( idx ) : nullptr;
819}
virtual const PARAM & GetParam(unsigned aParamIndex) const
Definition: sim_model.cpp:789
virtual int doFindParam(const std::string &aParamName) const
Definition: sim_model.cpp:798

References doFindParam(), and GetParam().

Referenced by TEST_SIM_LIBRARY_SPICE_FIXTURE::CompareToUsualDiodeModel(), SPICE_GENERATOR_SOURCE::getParamValueString(), SIM_MODEL_R_POT::GetTunerParam(), SPICE_GENERATOR_KIBIS::IbisDevice(), SPICE_GENERATOR_SOURCE::ItemLine(), SPICE_GENERATOR_R_POT::ModelLine(), SPICE_GENERATOR_TLINE::ModelLine(), and TEST_SIM_LIBRARY_SPICE_FIXTURE::TestTransistor().

◆ GetBaseModel()

const SIM_MODEL * SIM_MODEL::GetBaseModel ( ) const
inline

Definition at line 451 of file sim_model.h.

451{ return m_baseModel; }

References m_baseModel.

Referenced by SPICE_GENERATOR_SPICE::Preview(), and SIM_MODEL_SUBCKT::SetBaseModel().

◆ GetBaseParam()

const SIM_MODEL::PARAM & SIM_MODEL::GetBaseParam ( unsigned  aParamIndex) const

Definition at line 839 of file sim_model.cpp.

840{
841 if( m_baseModel )
842 return m_baseModel->GetParam( aParamIndex );
843 else
844 return m_params.at( aParamIndex );
845}

References GetParam(), m_baseModel, and m_params.

◆ GetDeviceInfo()

DEVICE_INFO SIM_MODEL::GetDeviceInfo ( ) const
inline

◆ GetDeviceType()

DEVICE_T SIM_MODEL::GetDeviceType ( ) const
inline

Definition at line 448 of file sim_model.h.

448{ return GetTypeInfo().deviceType; }
INFO GetTypeInfo() const
Definition: sim_model.h:446

References GetTypeInfo().

Referenced by SIM_MODEL_NGSPICE::canSilentlyIgnoreParam(), GetDeviceInfo(), and DIALOG_SIM_MODEL< T_symbol, T_field >::updateInstanceWidgets().

◆ GetFieldValue() [1/2]

template<typename T >
std::string SIM_MODEL::GetFieldValue ( const std::vector< T > *  aFields,
const wxString &  aFieldName,
bool  aResolve = true 
)
static

Definition at line 612 of file sim_model.cpp.

614{
615 static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
616
617 if( !aFields )
618 return ""; // Should not happen, T=void specialization will be called instead.
619
620 for( const T& field : *aFields )
621 {
622 if( field.GetName() == aFieldName )
623 {
624 return aResolve ? field.GetShownText( 0, false ).ToStdString()
625 : field.GetText().ToStdString();
626 }
627 }
628
629 return "";
630}

Referenced by Create(), SIM_LIB_MGR::CreateModel(), doReadDataFields(), SPICE_GENERATOR_KIBIS::IbisDevice(), InferSimModel(), InferTypeFromLegacyFields(), DIALOG_SIM_MODEL< T_symbol, T_field >::loadLibrary(), ReadTypeFromFields(), DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataFromWindow(), DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataToWindow(), and DIALOG_SIM_MODEL< T_symbol, T_field >::updateWidgets().

◆ GetFieldValue() [2/2]

template<>
std::string SIM_MODEL::GetFieldValue ( const std::vector< void > *  aFields,
const wxString &  aFieldName,
bool  aResolve 
)

Definition at line 635 of file sim_model.cpp.

637{
638 return "";
639}

◆ GetParam()

◆ GetParamCount()

◆ GetParamOverride()

const SIM_MODEL::PARAM & SIM_MODEL::GetParamOverride ( unsigned  aParamIndex) const

Definition at line 833 of file sim_model.cpp.

834{
835 return m_params.at( aParamIndex );
836}

References m_params.

Referenced by TEST_SIM_LIBRARY_SPICE_FIXTURE::CompareToEmptyModel(), SIM_MODEL_SERIALIZER::GenerateParams(), and SIM_MODEL_SERIALIZER::GenerateValue().

◆ GetParams()

std::vector< std::reference_wrapper< const SIM_MODEL::PARAM > > SIM_MODEL::GetParams ( ) const

Definition at line 822 of file sim_model.cpp.

823{
824 std::vector<std::reference_wrapper<const PARAM>> params;
825
826 for( int i = 0; i < GetParamCount(); ++i )
827 params.emplace_back( GetParam( i ) );
828
829 return params;
830}
int GetParamCount() const
Definition: sim_model.h:466

References GetParam(), and GetParamCount().

Referenced by doFindParam(), SIM_MODEL_NGSPICE::doFindParam(), SIM_MODEL_SPICE_FALLBACK::doFindParam(), SPICE_GENERATOR::GetInstanceParams(), SPICE_GENERATOR_SOURCE::ItemLine(), SPICE_GENERATOR::ModelLine(), SIM_MODEL_SUBCKT::SetBaseModel(), SIM_MODEL_NGSPICE::SetParamFromSpiceCode(), and SIM_MODEL_KIBIS::SIM_MODEL_KIBIS().

◆ GetPin()

◆ GetPinCount()

◆ GetPinNames()

virtual std::vector< std::string > SIM_MODEL::GetPinNames ( ) const
inlinevirtual

◆ GetPins()

std::vector< std::reference_wrapper< const SIM_MODEL::PIN > > SIM_MODEL::GetPins ( ) const

Definition at line 749 of file sim_model.cpp.

750{
751 std::vector<std::reference_wrapper<const PIN>> pins;
752
753 for( int modelPinIndex = 0; modelPinIndex < GetPinCount(); ++modelPinIndex )
754 pins.emplace_back( GetPin( modelPinIndex ) );
755
756 return pins;
757}

References GetPin(), and GetPinCount().

Referenced by SIM_MODEL_SERIALIZER::GeneratePins(), SPICE_GENERATOR::GetPins(), SCH_EDIT_FRAME::RefreshOperatingPointDisplay(), and SIM_MODEL_SUBCKT::SetBaseModel().

◆ GetSpiceInfo()

◆ GetTunerParam()

virtual const PARAM * SIM_MODEL::GetTunerParam ( ) const
inlinevirtual

◆ GetType()

◆ GetTypeInfo()

INFO SIM_MODEL::GetTypeInfo ( ) const
inline

◆ HasAutofill()

virtual bool SIM_MODEL::HasAutofill ( ) const
inlinevirtual

Reimplemented in SIM_MODEL_SOURCE.

Definition at line 485 of file sim_model.h.

485{ return false; }

Referenced by DIALOG_SIM_MODEL< T_symbol, T_field >::updateModelParamsTab().

◆ HasPrimaryValue()

virtual bool SIM_MODEL::HasPrimaryValue ( ) const
inlinevirtual

◆ InferSimModel()

template<class T_symbol , class T_field >
template bool SIM_MODEL::InferSimModel< LIB_SYMBOL, LIB_FIELD > ( T_symbol &  aSymbol,
std::vector< T_field > *  aFields,
bool  aResolve,
SIM_VALUE_GRAMMAR::NOTATION  aNotation,
wxString *  aDeviceType,
wxString *  aModelType,
wxString *  aModelParams,
wxString *  aPinMap 
)
static

KiCad Spice PEGTL only handles ASCII Although these two look the same, they are U+03BC and U+00B5

Definition at line 1096 of file sim_model.cpp.

1099{
1100 // SPICE notation is case-insensitive and locale-insensitve. This means it uses "Meg" for
1101 // mega (as both 'M' and 'm' must mean milli), and "." (always) for a decimal separator.
1102 //
1103 // KiCad's GUI uses the SI-standard 'M' for mega and 'm' for milli, and a locale-dependent
1104 // decimal separator.
1105 //
1106 // KiCad's Sim.* fields are in-between, using SI notation but a fixed decimal separator.
1107 //
1108 // So where does that leave inferred value fields? Behavioural models must be passed in
1109 // straight, because we don't (at present) know how to parse them.
1110 //
1111 // However, behavioural models _look_ like SPICE code, so it's not a stretch to expect them
1112 // to _be_ SPICE code. A passive capacitor model on the other hand, just looks like a
1113 // capacitance. Some users might expect 3,3u to work, while others might expect 3,300uF to
1114 // work.
1115 //
1116 // Checking the locale isn't reliable because it assumes the current computer's locale is
1117 // the same as the locale the schematic was authored in -- something that isn't true, for
1118 // instance, when sharing designs over DIYAudio.com.
1119 //
1120 // However, even the E192 series of preferred values uses only 3 significant digits, so a ','
1121 // or '.' followed by 3 digits _could_ reasonably-reliably be interpreted as a thousands
1122 // separator.
1123 //
1124 // Or we could just say inferred values are locale-independent, with "." used as a decimal
1125 // separator and "," used as a thousands separator. 3,300uF works, but 3,3 does not.
1126
1127 auto convertNotation =
1128 [&]( const wxString& units ) -> wxString
1129 {
1132 if( units == wxS( "µ" ) || units == wxS( "μ" ) )
1133 return wxS( "u" );
1134
1135 if( aNotation == SIM_VALUE_GRAMMAR::NOTATION::SPICE )
1136 {
1137 if( units == wxT( "M" ) )
1138 return wxT( "Meg" );
1139 }
1140 else if( aNotation == SIM_VALUE_GRAMMAR::NOTATION::SI )
1141 {
1142 if( units.Capitalize() == wxT( "Meg" ) )
1143 return wxT( "M" );
1144 }
1145
1146 return units;
1147 };
1148
1149 auto convertSeparators =
1150 []( wxString* mantissa )
1151 {
1152 mantissa->Replace( wxS( " " ), wxEmptyString );
1153
1154 wxChar ambiguousSeparator = '?';
1155 wxChar thousandsSeparator = '?';
1156 bool thousandsSeparatorFound = false;
1157 wxChar decimalSeparator = '?';
1158 bool decimalSeparatorFound = false;
1159 int digits = 0;
1160
1161 for( int ii = (int) mantissa->length() - 1; ii >= 0; --ii )
1162 {
1163 wxChar c = mantissa->GetChar( ii );
1164
1165 if( c >= '0' && c <= '9' )
1166 {
1167 digits += 1;
1168 }
1169 else if( c == '.' || c == ',' )
1170 {
1171 if( decimalSeparator != '?' || thousandsSeparator != '?' )
1172 {
1173 // We've previously found a non-ambiguous separator...
1174
1175 if( c == decimalSeparator )
1176 {
1177 if( thousandsSeparatorFound )
1178 return false; // decimal before thousands
1179 else if( decimalSeparatorFound )
1180 return false; // more than one decimal
1181 else
1182 decimalSeparatorFound = true;
1183 }
1184 else if( c == thousandsSeparator )
1185 {
1186 if( digits != 3 )
1187 return false; // thousands not followed by 3 digits
1188 else
1189 thousandsSeparatorFound = true;
1190 }
1191 }
1192 else if( ambiguousSeparator != '?' )
1193 {
1194 // We've previously found a separator, but we don't know for sure
1195 // which...
1196
1197 if( c == ambiguousSeparator )
1198 {
1199 // They both must be thousands separators
1200 thousandsSeparator = ambiguousSeparator;
1201 thousandsSeparatorFound = true;
1202 decimalSeparator = c == '.' ? ',' : '.';
1203 }
1204 else
1205 {
1206 // The first must have been a decimal, and this must be a
1207 // thousands.
1208 decimalSeparator = ambiguousSeparator;
1209 decimalSeparatorFound = true;
1210 thousandsSeparator = c;
1211 thousandsSeparatorFound = true;
1212 }
1213 }
1214 else
1215 {
1216 // This is the first separator...
1217
1218 // If it's followed by 3 digits then it could be either.
1219 // Otherwise it -must- be a decimal separator (and the thousands
1220 // separator must be the other).
1221 if( digits == 3 )
1222 {
1223 ambiguousSeparator = c;
1224 }
1225 else
1226 {
1227 decimalSeparator = c;
1228 decimalSeparatorFound = true;
1229 thousandsSeparator = c == '.' ? ',' : '.';
1230 }
1231 }
1232
1233 digits = 0;
1234 }
1235 else
1236 {
1237 digits = 0;
1238 }
1239 }
1240
1241 // If we found nothing difinitive then we have to assume SPICE-native syntax
1242 if( decimalSeparator == '?' && thousandsSeparator == '?' )
1243 {
1244 decimalSeparator = '.';
1245 thousandsSeparator = ',';
1246 }
1247
1248 mantissa->Replace( thousandsSeparator, wxEmptyString );
1249 mantissa->Replace( decimalSeparator, '.' );
1250
1251 return true;
1252 };
1253
1254 wxString prefix = aSymbol.GetPrefix();
1255 wxString library = GetFieldValue( aFields, SIM_LIBRARY_FIELD, aResolve );
1256 wxString modelName = GetFieldValue( aFields, SIM_NAME_FIELD, aResolve );
1257 wxString value = GetFieldValue( aFields, SIM_VALUE_FIELD, aResolve );
1258 std::vector<LIB_PIN*> pins = aSymbol.GetAllLibPins();
1259
1260 *aDeviceType = GetFieldValue( aFields, SIM_DEVICE_TYPE_FIELD, aResolve );
1261 *aModelType = GetFieldValue( aFields, SIM_TYPE_FIELD, aResolve );
1262 *aModelParams = GetFieldValue( aFields, SIM_PARAMS_FIELD, aResolve );
1263 *aPinMap = GetFieldValue( aFields, SIM_PINS_FIELD, aResolve );
1264
1265 if( pins.size() != 2 )
1266 return false;
1267
1268 if( ( ( *aDeviceType == "R" || *aDeviceType == "L" || *aDeviceType == "C" )
1269 && aModelType->IsEmpty() )
1270 ||
1271 ( library.IsEmpty() && modelName.IsEmpty()
1272 && aDeviceType->IsEmpty()
1273 && aModelType->IsEmpty()
1274 && !value.IsEmpty()
1275 && ( prefix.StartsWith( "R" ) || prefix.StartsWith( "L" ) || prefix.StartsWith( "C" ) ) ) )
1276 {
1277 if( aModelParams->IsEmpty() )
1278 {
1279 wxRegEx idealVal( wxT( "^"
1280 "([0-9\\,\\. ]+)"
1281 "([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
1282 "([fFhHΩΩ𝛀𝛺𝝮rR]|ohm)?"
1283 "([-1-9 ]*)"
1284 "([fFhHΩΩ𝛀𝛺𝝮rR]|ohm)?"
1285 "$" ) );
1286
1287 if( idealVal.Matches( value ) ) // Ideal
1288 {
1289 wxString valueMantissa( idealVal.GetMatch( value, 1 ) );
1290 wxString valueExponent( idealVal.GetMatch( value, 2 ) );
1291 wxString valueFraction( idealVal.GetMatch( value, 6 ) );
1292
1293 if( !convertSeparators( &valueMantissa ) )
1294 return false;
1295
1296 if( valueMantissa.Contains( wxT( "." ) ) || valueFraction.IsEmpty() )
1297 {
1298 aModelParams->Printf( wxT( "%s=\"%s%s\"" ),
1299 prefix.Left(1).Lower(),
1300 valueMantissa,
1301 convertNotation( valueExponent ) );
1302 }
1303 else
1304 {
1305 aModelParams->Printf( wxT( "%s=\"%s.%s%s\"" ),
1306 prefix.Left(1).Lower(),
1307 valueMantissa,
1308 valueFraction,
1309 convertNotation( valueExponent ) );
1310 }
1311 }
1312 else // Behavioral
1313 {
1314 *aModelType = wxT( "=" );
1315 aModelParams->Printf( wxT( "%s=\"%s\"" ), prefix.Left(1).Lower(), value );
1316 }
1317 }
1318
1319 if( aDeviceType->IsEmpty() )
1320 *aDeviceType = prefix.Left( 1 );
1321
1322 if( aPinMap->IsEmpty() )
1323 aPinMap->Printf( wxT( "%s=+ %s=-" ), pins[0]->GetNumber(), pins[1]->GetNumber() );
1324
1325 return true;
1326 }
1327
1328 if( ( ( *aDeviceType == wxT( "V" ) || *aDeviceType == wxT( "I" ) )
1329 && aModelType->IsEmpty() )
1330 ||
1331 ( aDeviceType->IsEmpty()
1332 && aModelType->IsEmpty()
1333 && !value.IsEmpty()
1334 && ( prefix.StartsWith( "V" ) || prefix.StartsWith( "I" ) ) ) )
1335 {
1336 if( aModelParams->IsEmpty() && !value.IsEmpty() )
1337 {
1338 if( value.StartsWith( wxT( "DC " ) ) )
1339 value = value.Right( value.Length() - 3 );
1340
1341 wxRegEx sourceVal( wxT( "^"
1342 "([0-9\\,\\. ]+)"
1343 "([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
1344 "([vVaA])?"
1345 "([-1-9 ]*)"
1346 "([vVaA])?"
1347 "$" ) );
1348
1349 if( sourceVal.Matches( value ) )
1350 {
1351 wxString valueMantissa( sourceVal.GetMatch( value, 1 ) );
1352 wxString valueExponent( sourceVal.GetMatch( value, 2 ) );
1353 wxString valueFraction( sourceVal.GetMatch( value, 6 ) );
1354
1355 if( !convertSeparators( &valueMantissa ) )
1356 return false;
1357
1358 if( valueMantissa.Contains( wxT( "." ) ) || valueFraction.IsEmpty() )
1359 {
1360 aModelParams->Printf( wxT( "dc=\"%s%s\"" ),
1361 valueMantissa,
1362 convertNotation( valueExponent ) );
1363 }
1364 else
1365 {
1366 aModelParams->Printf( wxT( "dc=\"%s.%s%s\"" ),
1367 valueMantissa,
1368 valueFraction,
1369 convertNotation( valueExponent ) );
1370 }
1371 }
1372 else
1373 {
1374 aModelParams->Printf( wxT( "dc=\"%s\"" ), value );
1375 }
1376 }
1377
1378 if( aDeviceType->IsEmpty() )
1379 *aDeviceType = prefix.Left( 1 );
1380
1381 if( aModelType->IsEmpty() )
1382 *aModelType = wxT( "DC" );
1383
1384 if( aPinMap->IsEmpty() )
1385 aPinMap->Printf( wxT( "%s=+ %s=-" ), pins[0]->GetNumber(), pins[1]->GetNumber() );
1386
1387 return true;
1388 }
1389
1390 return false;
1391}
#define SIM_NAME_FIELD
Definition: sim_model.h:58
#define SIM_LIBRARY_FIELD
Definition: sim_model.h:57

References GetFieldValue(), library, SIM_VALUE_GRAMMAR::SI, SIM_DEVICE_TYPE_FIELD, SIM_LIBRARY_FIELD, SIM_NAME_FIELD, SIM_PARAMS_FIELD, SIM_PINS_FIELD, SIM_TYPE_FIELD, SIM_VALUE_FIELD, and SIM_VALUE_GRAMMAR::SPICE.

Referenced by BOOST_AUTO_TEST_CASE(), SIM_LIB_MGR::CreateModel(), and DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataToWindow().

◆ InferTypeFromLegacyFields()

template<typename T >
TYPE SIM_MODEL::InferTypeFromLegacyFields ( const std::vector< T > &  aFields)
static

Definition at line 400 of file sim_model.cpp.

401{
402 if( GetFieldValue( &aFields, SIM_MODEL_RAW_SPICE::LEGACY_TYPE_FIELD ) != ""
406 {
407 return TYPE::RAWSPICE;
408 }
409 else
410 {
411 return TYPE::NONE;
412 }
413}
static constexpr auto LEGACY_LIB_FIELD
static constexpr auto LEGACY_MODEL_FIELD
static constexpr auto LEGACY_ENABLED_FIELD

References GetFieldValue(), SIM_MODEL_RAW_SPICE::LEGACY_ENABLED_FIELD, SIM_MODEL_RAW_SPICE::LEGACY_LIB_FIELD, SIM_MODEL_RAW_SPICE::LEGACY_MODEL_FIELD, and NONE.

Referenced by ReadTypeFromFields().

◆ IsEnabled()

bool SIM_MODEL::IsEnabled ( ) const
inline

Definition at line 489 of file sim_model.h.

489{ return m_isEnabled; }

References m_isEnabled.

Referenced by SIM_MODEL_SERIALIZER::GenerateEnable().

◆ IsStoredInValue()

bool SIM_MODEL::IsStoredInValue ( ) const
inline

Definition at line 496 of file sim_model.h.

496{ return m_isStoredInValue; }

References m_isStoredInValue.

Referenced by doWriteFields(), and SIM_MODEL_SERIALIZER::GenerateParams().

◆ MigrateSimModel()

template<typename T_symbol , typename T_field >
template void SIM_MODEL::MigrateSimModel< LIB_SYMBOL, LIB_FIELD > ( T_symbol &  aSymbol,
const PROJECT aProject 
)
static

Definition at line 1413 of file sim_model.cpp.

1414{
1415 if( aSymbol.FindField( SIM_DEVICE_TYPE_FIELD )
1416 || aSymbol.FindField( SIM_TYPE_FIELD )
1417 || aSymbol.FindField( SIM_PINS_FIELD )
1418 || aSymbol.FindField( SIM_PARAMS_FIELD ) )
1419 {
1420 // Has a V7 model field.
1421
1422 // Up until 7.0RC2 we used '+' and '-' for potentiometer pins, which doesn't match
1423 // SPICE. Here we remap them to 'r0' and 'r1'.
1424 if( T_field* deviceType = aSymbol.FindField( SIM_TYPE_FIELD ) )
1425 {
1426 if( deviceType->GetShownText( 0, false ).Lower() == wxS( "pot" ) )
1427 {
1428 if( T_field* pins = aSymbol.FindField( SIM_PINS_FIELD ) )
1429 {
1430 wxString pinMap = pins->GetText();
1431 pinMap.Replace( wxS( "=+" ), wxS( "=r1" ) );
1432 pinMap.Replace( wxS( "=-" ), wxS( "=r0" ) );
1433 pins->SetText( pinMap );
1434 }
1435 }
1436 }
1437
1438 return;
1439 }
1440
1441 class FIELD_INFO
1442 {
1443 public:
1444 FIELD_INFO()
1445 {
1446 m_Attributes.m_Visible = false;
1447 m_Attributes.m_Size = VECTOR2I( DEFAULT_SIZE_TEXT * schIUScale.IU_PER_MILS,
1449 };
1450
1451 FIELD_INFO( const wxString& aText, T_field* aField ) :
1452 m_Text( aText ),
1453 m_Attributes( aField->GetAttributes() ),
1454 m_Pos( aField->GetPosition() )
1455 {}
1456
1457 bool IsEmpty() { return m_Text.IsEmpty(); }
1458
1459 T_field CreateField( T_symbol* aSymbol, const wxString& aFieldName )
1460 {
1461 T_field field( aSymbol, -1, aFieldName );
1462
1463 field.SetText( m_Text );
1464 field.SetAttributes( m_Attributes );
1465 field.SetPosition( m_Pos );
1466
1467 return field;
1468 }
1469
1470 public:
1471 wxString m_Text;
1472 TEXT_ATTRIBUTES m_Attributes;
1473 VECTOR2I m_Pos;
1474 };
1475
1476 auto getSIValue =
1477 []( T_field* aField )
1478 {
1479 if( !aField ) // no, not really, but it keeps Coverity happy
1480 return wxString( wxEmptyString );
1481
1482 wxRegEx regex( wxT( "([^a-z])(M)(e|E)(g|G)($|[^a-z])" ) );
1483 wxString value = aField->GetText();
1484
1485 // Keep prefix, M, and suffix, but drop e|E and g|G
1486 regex.ReplaceAll( &value, wxT( "\\1\\2\\5" ) );
1487
1488 return value;
1489 };
1490
1491 auto generateDefaultPinMapFromSymbol =
1492 []( const std::vector<LIB_PIN*>& sourcePins )
1493 {
1494 wxString pinMap;
1495
1496 // If we're creating the pinMap from the symbol it means we don't know what the
1497 // SIM_MODEL's pin names are, so just use indexes.
1498
1499 for( unsigned ii = 0; ii < sourcePins.size(); ++ii )
1500 {
1501 if( ii > 0 )
1502 pinMap.Append( wxS( " " ) );
1503
1504 pinMap.Append( wxString::Format( wxT( "%s=%u" ),
1505 sourcePins[ii]->GetNumber(),
1506 ii + 1 ) );
1507 }
1508
1509 return pinMap;
1510 };
1511
1512 wxString prefix = aSymbol.GetPrefix();
1513 T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
1514 std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
1515
1516 std::sort( sourcePins.begin(), sourcePins.end(),
1517 []( const LIB_PIN* lhs, const LIB_PIN* rhs )
1518 {
1519 return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
1520 } );
1521
1522 FIELD_INFO spiceDeviceInfo;
1523 FIELD_INFO spiceModelInfo;
1524 FIELD_INFO spiceTypeInfo;
1525 FIELD_INFO spiceLibInfo;
1526 FIELD_INFO spiceParamsInfo;
1527 FIELD_INFO pinMapInfo;
1528 bool modelFromValueField = false;
1529
1530 if( aSymbol.FindField( wxT( "Spice_Primitive" ) )
1531 || aSymbol.FindField( wxT( "Spice_Node_Sequence" ) )
1532 || aSymbol.FindField( wxT( "Spice_Model" ) )
1533 || aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) )
1534 || aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
1535 {
1536 if( T_field* primitiveField = aSymbol.FindField( wxT( "Spice_Primitive" ) ) )
1537 {
1538 spiceDeviceInfo = FIELD_INFO( primitiveField->GetText(), primitiveField );
1539 aSymbol.RemoveField( primitiveField );
1540 }
1541
1542 if( T_field* nodeSequenceField = aSymbol.FindField( wxT( "Spice_Node_Sequence" ) ) )
1543 {
1544 const wxString delimiters( "{:,; }" );
1545 const wxString& nodeSequence = nodeSequenceField->GetText();
1546 wxString pinMap;
1547
1548 if( nodeSequence != "" )
1549 {
1550 wxStringTokenizer tkz( nodeSequence, delimiters );
1551
1552 for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
1553 {
1554 long symbolPinNumber = 1;
1555 tkz.GetNextToken().ToLong( &symbolPinNumber );
1556
1557 if( modelPinNumber != 1 )
1558 pinMap.Append( " " );
1559
1560 pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
1561 }
1562 }
1563
1564 pinMapInfo = FIELD_INFO( pinMap, nodeSequenceField );
1565 aSymbol.RemoveField( nodeSequenceField );
1566 }
1567
1568 if( T_field* modelField = aSymbol.FindField( wxT( "Spice_Model" ) ) )
1569 {
1570 spiceModelInfo = FIELD_INFO( getSIValue( modelField ), modelField );
1571 aSymbol.RemoveField( modelField );
1572 }
1573 else
1574 {
1575 spiceModelInfo = FIELD_INFO( getSIValue( valueField ), valueField );
1576 modelFromValueField = true;
1577 }
1578
1579 if( T_field* netlistEnabledField = aSymbol.FindField( wxT( "Spice_Netlist_Enabled" ) ) )
1580 {
1581 wxString netlistEnabled = netlistEnabledField->GetText().Lower();
1582
1583 if( netlistEnabled.StartsWith( wxT( "0" ) )
1584 || netlistEnabled.StartsWith( wxT( "n" ) )
1585 || netlistEnabled.StartsWith( wxT( "f" ) ) )
1586 {
1587 netlistEnabledField->SetName( SIM_ENABLE_FIELD );
1588 netlistEnabledField->SetText( wxT( "0" ) );
1589 }
1590 else
1591 {
1592 aSymbol.RemoveField( netlistEnabledField );
1593 }
1594 }
1595
1596 if( T_field* libFileField = aSymbol.FindField( wxT( "Spice_Lib_File" ) ) )
1597 {
1598 spiceLibInfo = FIELD_INFO( libFileField->GetText(), libFileField );
1599 aSymbol.RemoveField( libFileField );
1600 }
1601 }
1602 else
1603 {
1604 // Auto convert some legacy fields used in the middle of 7.0 development...
1605
1606 if( T_field* legacyType = aSymbol.FindField( wxT( "Sim_Type" ) ) )
1607 {
1608 legacyType->SetName( SIM_TYPE_FIELD );
1609 }
1610
1611 if( T_field* legacyDevice = aSymbol.FindField( wxT( "Sim_Device" ) ) )
1612 {
1613 legacyDevice->SetName( SIM_DEVICE_TYPE_FIELD );
1614 }
1615
1616 if( T_field* legacyPins = aSymbol.FindField( wxT( "Sim_Pins" ) ) )
1617 {
1618 bool isPassive = prefix.StartsWith( wxT( "R" ) )
1619 || prefix.StartsWith( wxT( "L" ) )
1620 || prefix.StartsWith( wxT( "C" ) );
1621
1622 // Migrate pins from array of indexes to name-value-pairs
1623 wxString pinMap;
1624 wxArrayString pinIndexes;
1625
1626 wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
1627
1628 if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
1629 {
1630 if( pinIndexes[0] == wxT( "2" ) )
1631 {
1632 pinMap.Printf( wxT( "%s=- %s=+" ),
1633 sourcePins[0]->GetNumber(),
1634 sourcePins[1]->GetNumber() );
1635 }
1636 else
1637 {
1638 pinMap.Printf( wxT( "%s=+ %s=-" ),
1639 sourcePins[0]->GetNumber(),
1640 sourcePins[1]->GetNumber() );
1641 }
1642 }
1643 else
1644 {
1645 for( unsigned ii = 0; ii < pinIndexes.size(); ++ii )
1646 {
1647 if( ii > 0 )
1648 pinMap.Append( wxS( " " ) );
1649
1650 pinMap.Append( wxString::Format( wxT( "%s=%s" ),
1651 sourcePins[ii]->GetNumber(),
1652 pinIndexes[ ii ] ) );
1653 }
1654 }
1655
1656 legacyPins->SetName( SIM_PINS_FIELD );
1657 legacyPins->SetText( pinMap );
1658 }
1659
1660 if( T_field* legacyParams = aSymbol.FindField( wxT( "Sim_Params" ) ) )
1661 {
1662 legacyParams->SetName( SIM_PARAMS_FIELD );
1663 }
1664
1665 return;
1666 }
1667
1668 wxString spiceDeviceType = spiceDeviceInfo.m_Text.Trim( true ).Trim( false );
1669 wxString spiceLib = spiceLibInfo.m_Text.Trim( true ).Trim( false );
1670 wxString spiceModel = spiceModelInfo.m_Text.Trim( true ).Trim( false );
1671
1672 bool libraryModel = false;
1673 bool inferredModel = false;
1674 bool internalModel = false;
1675
1676 if( !spiceLib.IsEmpty() )
1677 {
1678 wxString msg;
1679 WX_STRING_REPORTER reporter( &msg );
1680 SIM_LIB_MGR libMgr( aProject, &reporter );
1681 std::vector<T_field> emptyFields;
1682
1683 SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
1684 emptyFields, sourcePins );
1685
1686 if( reporter.HasMessage() )
1687 libraryModel = false; // Fall back to raw spice model
1688 else
1689 libraryModel = true;
1690
1691 if( pinMapInfo.IsEmpty() )
1692 {
1693 // Try to generate a default pin map from the SIM_MODEL's pins; if that fails,
1694 // generate one from the symbol's pins
1695
1696 model.model.SIM_MODEL::createPins( sourcePins );
1697 pinMapInfo.m_Text = wxString( model.model.Serializer().GeneratePins() );
1698
1699 if( pinMapInfo.IsEmpty() )
1700 pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
1701 }
1702 }
1703 else if( ( spiceDeviceType == "R" || spiceDeviceType == "L" || spiceDeviceType == "C" )
1704 && prefix.StartsWith( spiceDeviceType )
1705 && modelFromValueField )
1706 {
1707 inferredModel = true;
1708 }
1709 else
1710 {
1711 // See if we have a SPICE model such as "sin(0 1 60)" or "sin 0 1 60" that can be handled
1712 // by a built-in SIM_MODEL.
1713
1714 wxStringTokenizer tokenizer( spiceModel, wxT( "() " ), wxTOKEN_STRTOK );
1715
1716 if( tokenizer.HasMoreTokens() )
1717 {
1718 spiceTypeInfo.m_Text = tokenizer.GetNextToken();
1719 spiceTypeInfo.m_Text.MakeUpper();
1720
1721 for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
1722 {
1723 if( spiceDeviceType == SIM_MODEL::SpiceInfo( type ).itemType
1724 && spiceTypeInfo.m_Text == SIM_MODEL::SpiceInfo( type ).inlineTypeString )
1725 {
1726 try
1727 {
1728 std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
1729
1730 if( spiceTypeInfo.m_Text == wxT( "DC" ) && tokenizer.CountTokens() == 1 )
1731 {
1732 wxCHECK( valueField, /* void */ );
1733 valueField->SetText( tokenizer.GetNextToken() );
1734 modelFromValueField = false;
1735 }
1736 else
1737 {
1738 for( int ii = 0; tokenizer.HasMoreTokens(); ++ii )
1739 {
1740 model->SetParamValue( ii, tokenizer.GetNextToken().ToStdString(),
1742 }
1743
1744 spiceTypeInfo.m_Text = SIM_MODEL::TypeInfo( type ).fieldValue;
1745
1746 spiceParamsInfo = spiceModelInfo;
1747 spiceParamsInfo.m_Text = wxString( model->Serializer().GenerateParams() );
1748 }
1749
1750 internalModel = true;
1751
1752 if( pinMapInfo.IsEmpty() )
1753 {
1754 // Generate a default pin map from the SIM_MODEL's pins
1755 model->createPins( sourcePins );
1756 pinMapInfo.m_Text = wxString( model->Serializer().GeneratePins() );
1757 }
1758 }
1759 catch( ... )
1760 {
1761 // Fall back to raw spice model
1762 }
1763
1764 break;
1765 }
1766 }
1767 }
1768 }
1769
1770 if( libraryModel )
1771 {
1772 T_field libraryField = spiceLibInfo.CreateField( &aSymbol, SIM_LIBRARY_FIELD );
1773 aSymbol.AddField( libraryField );
1774
1775 T_field nameField = spiceModelInfo.CreateField( &aSymbol, SIM_NAME_FIELD );
1776 aSymbol.AddField( nameField );
1777
1778 // Don't write a paramsField unless we actually have overrides
1779 if( !spiceParamsInfo.IsEmpty() )
1780 {
1781 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol, SIM_PARAMS_FIELD );
1782 aSymbol.AddField( paramsField );
1783 }
1784
1785 if( modelFromValueField )
1786 valueField->SetText( wxT( "${SIM.NAME}" ) );
1787 }
1788 else if( inferredModel )
1789 {
1790 // DeviceType is left in the reference designator and Model is left in the value field,
1791 // so there's nothing to do here....
1792 }
1793 else if( internalModel )
1794 {
1795 T_field deviceField = spiceDeviceInfo.CreateField( &aSymbol, SIM_DEVICE_TYPE_FIELD );
1796 aSymbol.AddField( deviceField );
1797
1798 T_field typeField = spiceTypeInfo.CreateField( &aSymbol, SIM_TYPE_FIELD );
1799 aSymbol.AddField( typeField );
1800
1801 if( !spiceParamsInfo.IsEmpty() )
1802 {
1803 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol, SIM_PARAMS_FIELD );
1804 aSymbol.AddField( paramsField );
1805 }
1806
1807 if( modelFromValueField )
1808 valueField->SetText( wxT( "${SIM.PARAMS}" ) );
1809 }
1810 else // Insert a raw spice model as a substitute.
1811 {
1812 if( spiceDeviceType.IsEmpty() && spiceLib.IsEmpty() )
1813 {
1814 spiceParamsInfo = spiceModelInfo;
1815 }
1816 else
1817 {
1818 spiceParamsInfo.m_Text.Printf( wxT( "type=\"%s\" model=\"%s\" lib=\"%s\"" ),
1819 spiceDeviceType, spiceModel, spiceLib );
1820 }
1821
1822 spiceDeviceInfo.m_Text = SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_T::SPICE ).fieldValue;
1823
1824 T_field deviceField = spiceDeviceInfo.CreateField( &aSymbol, SIM_DEVICE_TYPE_FIELD );
1825 aSymbol.AddField( deviceField );
1826
1827 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol, SIM_PARAMS_FIELD );
1828 aSymbol.AddField( paramsField );
1829
1830 if( modelFromValueField )
1831 {
1832 // Get the current Value field, after previous changes.
1833 valueField = aSymbol.FindField( wxT( "Value" ) );
1834
1835 if( valueField )
1836 valueField->SetText( wxT( "${SIM.PARAMS}" ) );
1837 }
1838
1839 // We know nothing about the SPICE model here, so we've got no choice but to generate
1840 // the default pin map from the symbol's pins.
1841
1842 if( pinMapInfo.IsEmpty() )
1843 pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
1844 }
1845
1846 if( !pinMapInfo.IsEmpty() )
1847 {
1848 T_field pinsField = pinMapInfo.CreateField( &aSymbol, SIM_PINS_FIELD );
1849 aSymbol.AddField( pinsField );
1850 }
1851}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
std::string GeneratePins() const
const SIM_MODEL_SERIALIZER & Serializer() const
Definition: sim_model.h:420
A wrapper for reporting to a wxString object.
Definition: reporter.h:164
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
Definition: eda_text.h:61
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
const double IU_PER_MILS
Definition: base_units.h:78
SIM_MODEL & model
Definition: sim_library.h:41
std::string inlineTypeString
Definition: sim_model.h:281
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590

References Create(), SIM_LIB_MGR::CreateModel(), DEFAULT_SIZE_TEXT, DeviceInfo(), Format(), SIM_MODEL_SERIALIZER::GeneratePins(), WX_STRING_REPORTER::HasMessage(), SIM_MODEL::SPICE_INFO::inlineTypeString, EDA_IU_SCALE::IU_PER_MILS, SIM_LIBRARY::MODEL::model, schIUScale, Serializer(), SIM_DEVICE_TYPE_FIELD, SIM_ENABLE_FIELD, SIM_LIBRARY_FIELD, SIM_NAME_FIELD, SIM_PARAMS_FIELD, SIM_PINS_FIELD, SIM_TYPE_FIELD, SIM_VALUE_GRAMMAR::SPICE, SpiceInfo(), TypeInfo(), and wxStringSplit().

◆ operator=()

SIM_MODEL & SIM_MODEL::operator= ( SIM_MODEL &&  aOther)
delete

◆ ReadDataFields() [1/3]

template<>
void SIM_MODEL::ReadDataFields ( const std::vector< LIB_FIELD > *  aFields,
const std::vector< LIB_PIN * > &  aPins 
)

Definition at line 425 of file sim_model.cpp.

427{
428 doReadDataFields( aFields, aPins );
429}
void doReadDataFields(const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
Definition: sim_model.cpp:1021

References doReadDataFields().

◆ ReadDataFields() [2/3]

template<>
void SIM_MODEL::ReadDataFields ( const std::vector< SCH_FIELD > *  aFields,
const std::vector< LIB_PIN * > &  aPins 
)

Definition at line 417 of file sim_model.cpp.

419{
420 doReadDataFields( aFields, aPins );
421}

References doReadDataFields().

◆ ReadDataFields() [3/3]

template<typename T >
void SIM_MODEL::ReadDataFields ( const std::vector< T > *  aFields,
const std::vector< LIB_PIN * > &  aPins 
)

◆ ReadTypeFromFields()

template<typename T >
TYPE SIM_MODEL::ReadTypeFromFields ( const std::vector< T > &  aFields)
static

Definition at line 368 of file sim_model.cpp.

369{
370 std::string deviceTypeFieldValue = GetFieldValue( &aFields, SIM_DEVICE_TYPE_FIELD );
371 std::string typeFieldValue = GetFieldValue( &aFields, SIM_TYPE_FIELD );
372
373 if( deviceTypeFieldValue != "" )
374 {
375 for( TYPE type : TYPE_ITERATOR() )
376 {
377 if( typeFieldValue == TypeInfo( type ).fieldValue )
378 {
379 if( deviceTypeFieldValue == DeviceInfo( TypeInfo( type ).deviceType ).fieldValue )
380 return type;
381 }
382 }
383 }
384
385 if( typeFieldValue != "" )
386 return TYPE::NONE;
387
388 // No type information. Look for legacy (pre-V7) fields.
389
390 TYPE typeFromLegacyFields = InferTypeFromLegacyFields( aFields );
391
392 if( typeFromLegacyFields != TYPE::NONE )
393 return typeFromLegacyFields;
394
395 return TYPE::NONE;
396}
static TYPE InferTypeFromLegacyFields(const std::vector< T > &aFields)
Definition: sim_model.cpp:400

References DeviceInfo(), GetFieldValue(), InferTypeFromLegacyFields(), NONE, SIM_DEVICE_TYPE_FIELD, SIM_TYPE_FIELD, and TypeInfo().

Referenced by Create(), and DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataToWindow().

◆ requiresSpiceModelLine()

bool SIM_MODEL::requiresSpiceModelLine ( const SPICE_ITEM aItem) const
privatevirtual

Reimplemented in SIM_MODEL_KIBIS, SIM_MODEL_RAW_SPICE, and SIM_MODEL_SWITCH.

Definition at line 1055 of file sim_model.cpp.

1056{
1057 // Model must be written if there's no base model or the base model is an internal model
1058 if( !m_baseModel || aItem.baseModelName == "" )
1059 return true;
1060
1061 for( int ii = 0; ii < GetParamCount(); ++ii )
1062 {
1063 const PARAM& param = m_params[ii];
1064
1065 // Instance parameters are written in item lines
1066 if( param.info.isSpiceInstanceParam )
1067 continue;
1068
1069 // Empty parameters are interpreted as default-value
1070 if ( param.value == "" )
1071 continue;
1072
1073 const SIM_MODEL* baseModel = dynamic_cast<const SIM_MODEL*>( m_baseModel );
1074
1075 wxCHECK( baseModel, false );
1076
1077 std::string baseValue = baseModel->m_params[ii].value;
1078
1079 if( param.value == baseValue )
1080 continue;
1081
1082 // One more check for equivalence, mostly for early 7.0 files which wrote all parameters
1083 // to the Sim.Params field in normalized format
1084 if( param.value == SIM_VALUE::Normalize( SIM_VALUE::ToDouble( baseValue ) ) )
1085 continue;
1086
1087 // Overrides must be written
1088 return true;
1089 }
1090
1091 return false;
1092}
static std::string Normalize(double aValue)
Definition: sim_value.cpp:398
static double ToDouble(const std::string &aString, double aDefault=NAN)
Definition: sim_value.cpp:411
std::string baseModelName

References SPICE_ITEM::baseModelName, GetParamCount(), SIM_MODEL::PARAM::info, SIM_MODEL::PARAM::INFO::isSpiceInstanceParam, m_baseModel, m_params, SIM_VALUE::Normalize(), SIM_VALUE::ToDouble(), and SIM_MODEL::PARAM::value.

Referenced by SPICE_GENERATOR::ModelLine(), and SPICE_GENERATOR::ModelName().

◆ Serializer()

const SIM_MODEL_SERIALIZER & SIM_MODEL::Serializer ( ) const
inline

Definition at line 420 of file sim_model.h.

420{ return *m_serializer; }

References m_serializer.

Referenced by MigrateSimModel().

◆ SetBaseModel()

void SIM_MODEL::SetBaseModel ( const SIM_MODEL aBaseModel)
virtual

Reimplemented in SIM_MODEL_KIBIS, and SIM_MODEL_SUBCKT.

Definition at line 727 of file sim_model.cpp.

728{
729 auto describe =
730 []( const SIM_MODEL* aModel )
731 {
732 return fmt::format( "{} ({})",
733 aModel->GetDeviceInfo().fieldValue,
734 aModel->GetTypeInfo().description );
735 };
736
737 if( GetType() != aBaseModel.GetType() )
738 {
739 THROW_IO_ERROR( wxString::Format( _( "Simulation model type must be the same as of its "
740 "base class: '%s', but is '%s'" ),
741 describe( &aBaseModel ),
742 describe( this ) ) );
743 }
744
745 m_baseModel = &aBaseModel;
746}
#define _(s)

References _, Format(), GetType(), m_baseModel, and THROW_IO_ERROR.

Referenced by SIM_MODEL_SUBCKT::SetBaseModel().

◆ SetFieldValue()

template<typename T >
template void SIM_MODEL::SetFieldValue< LIB_FIELD > ( std::vector< T > &  aFields,
const wxString &  aFieldName,
const std::string &  aValue 
)
static

Definition at line 643 of file sim_model.cpp.

645{
646 static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
647
648 auto fieldIt = std::find_if( aFields.begin(), aFields.end(),
649 [&]( const T& f )
650 {
651 return f.GetName() == aFieldName;
652 } );
653
654 if( fieldIt != aFields.end() )
655 {
656 if( aValue == "" )
657 aFields.erase( fieldIt );
658 else
659 fieldIt->SetText( aValue );
660
661 return;
662 }
663
664 if( aValue == "" )
665 return;
666
667 if constexpr( std::is_same<T, SCH_FIELD>::value )
668 {
669 wxASSERT( aFields.size() >= 1 );
670
671 SCH_ITEM* parent = static_cast<SCH_ITEM*>( aFields.at( 0 ).GetParent() );
672 aFields.emplace_back( VECTOR2I(), aFields.size(), parent, aFieldName );
673 }
674 else if constexpr( std::is_same<T, LIB_FIELD>::value )
675 {
676 aFields.emplace_back( aFields.size(), aFieldName );
677 }
678
679 aFields.back().SetText( aValue );
680}
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147

Referenced by doWriteFields(), and DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataFromWindow().

◆ SetIsEnabled()

void SIM_MODEL::SetIsEnabled ( bool  aIsEnabled)
inline

Definition at line 488 of file sim_model.h.

488{ m_isEnabled = aIsEnabled; }

References m_isEnabled.

Referenced by SIM_MODEL_SERIALIZER::ParseEnable().

◆ SetIsStoredInValue()

void SIM_MODEL::SetIsStoredInValue ( bool  aIsStoredInValue)
inline

Definition at line 491 of file sim_model.h.

492 {
493 if( HasPrimaryValue() )
494 m_isStoredInValue = aIsStoredInValue;
495 }
virtual bool HasPrimaryValue() const
Definition: sim_model.h:486

References HasPrimaryValue(), and m_isStoredInValue.

Referenced by SIM_LIB_MGR::CreateModel(), and SIM_MODEL_SERIALIZER::ParseValue().

◆ SetParamValue() [1/2]

void SIM_MODEL::SetParamValue ( const std::string &  aParamName,
const std::string &  aValue,
SIM_VALUE::NOTATION  aNotation = SIM_VALUE::NOTATION::SI 
)

Definition at line 866 of file sim_model.cpp.

868{
869 int idx = doFindParam( aParamName );
870
871 if( idx < 0 )
872 THROW_IO_ERROR( wxString::Format( "Unknown simulation model parameter '%s'", aParamName ) );
873
874 SetParamValue( idx, aValue, aNotation );
875}
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
Definition: sim_model.cpp:854

References doFindParam(), Format(), SetParamValue(), and THROW_IO_ERROR.

◆ SetParamValue() [2/2]

void SIM_MODEL::SetParamValue ( int  aParamIndex,
const std::string &  aValue,
SIM_VALUE::NOTATION  aNotation = SIM_VALUE::NOTATION::SI 
)

◆ SetPinSymbolPinNumber() [1/2]

void SIM_MODEL::SetPinSymbolPinNumber ( const std::string &  aPinName,
const std::string &  aSymbolPinNumber 
)
virtual

Reimplemented in SIM_MODEL_RAW_SPICE, and SIM_MODEL_SPICE_FALLBACK.

Definition at line 766 of file sim_model.cpp.

768{
769 for( PIN& pin : m_pins )
770 {
771 if( pin.name == aPinName )
772 {
773 pin.symbolPinNumber = aSymbolPinNumber;
774 return;
775 }
776 }
777
778 // If aPinName wasn't in fact a name, see if it's a raw (1-based) index. This is required
779 // for legacy files which didn't use pin names.
780 int aPinIndex = (int) strtol( aPinName.c_str(), nullptr, 10 );
781
782 if( aPinIndex < 1 || aPinIndex > (int) m_pins.size() )
783 THROW_IO_ERROR( wxString::Format( _( "Unknown simulation model pin '%s'" ), aPinName ) );
784
785 m_pins[ --aPinIndex /* convert to 0-based */ ].symbolPinNumber = aSymbolPinNumber;
786}

References _, Format(), m_pins, pin, and THROW_IO_ERROR.

◆ SetPinSymbolPinNumber() [2/2]

void SIM_MODEL::SetPinSymbolPinNumber ( int  aPinIndex,
const std::string &  aSymbolPinNumber 
)

Definition at line 759 of file sim_model.cpp.

760{
761 if( aPinIndex >= 0 && aPinIndex < (int) m_pins.size() )
762 m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
763}

References m_pins.

Referenced by SIM_MODEL_SERIALIZER::ParsePins(), DIALOG_SIM_MODEL< T_symbol, T_field >::removeOrphanedPinAssignments(), and SIM_MODEL_SPICE_FALLBACK::SetPinSymbolPinNumber().

◆ SpiceGenerator()

◆ SpiceInfo()

SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo ( TYPE  aType)
static

Definition at line 230 of file sim_model.cpp.

231{
232 switch( aType )
233 {
234 case TYPE::R: return { "R", "" };
235 case TYPE::R_POT: return { "A", "" };
236 case TYPE::R_BEHAVIORAL: return { "R", "", "", "0", false, true };
237
238 case TYPE::C: return { "C", "" };
239 case TYPE::C_BEHAVIORAL: return { "C", "", "", "0", false, true };
240
241 case TYPE::L: return { "L", "" };
242 case TYPE::L_MUTUAL: return { "K", "" };
243 case TYPE::L_BEHAVIORAL: return { "L", "", "", "0", false, true };
244
245 //case TYPE::TLINE_Z0: return { "T" };
246 case TYPE::TLINE_Z0: return { "O", "LTRA" };
247 case TYPE::TLINE_RLGC: return { "O", "LTRA" };
248
249 case TYPE::SW_V: return { "S", "SW" };
250 case TYPE::SW_I: return { "W", "CSW" };
251
252 case TYPE::D: return { "D", "D" };
253
254 case TYPE::NPN_VBIC: return { "Q", "NPN", "", "4" };
255 case TYPE::PNP_VBIC: return { "Q", "PNP", "", "4" };
256 case TYPE::NPN_GUMMELPOON: return { "Q", "NPN", "", "1", true };
257 case TYPE::PNP_GUMMELPOON: return { "Q", "PNP", "", "1", true };
258 case TYPE::NPN_HICUM2: return { "Q", "NPN", "", "8" };
259 case TYPE::PNP_HICUM2: return { "Q", "PNP", "", "8" };
260
261 case TYPE::NJFET_SHICHMANHODGES: return { "J", "NJF", "", "1", true };
262 case TYPE::PJFET_SHICHMANHODGES: return { "J", "PJF", "", "1", true };
263 case TYPE::NJFET_PARKERSKELLERN: return { "J", "NJF", "", "2" };
264 case TYPE::PJFET_PARKERSKELLERN: return { "J", "PJF", "", "2" };
265
266 case TYPE::NMES_STATZ: return { "Z", "NMF", "", "1", true };
267 case TYPE::PMES_STATZ: return { "Z", "PMF", "", "1", true };
268 case TYPE::NMES_YTTERDAL: return { "Z", "NMF", "", "2" };
269 case TYPE::PMES_YTTERDAL: return { "Z", "PMF", "", "2" };
270 case TYPE::NMES_HFET1: return { "Z", "NMF", "", "5" };
271 case TYPE::PMES_HFET1: return { "Z", "PMF", "", "5" };
272 case TYPE::NMES_HFET2: return { "Z", "NMF", "", "6" };
273 case TYPE::PMES_HFET2: return { "Z", "PMF", "", "6" };
274
275 case TYPE::NMOS_VDMOS: return { "M", "VDMOS NCHAN", };
276 case TYPE::PMOS_VDMOS: return { "M", "VDMOS PCHAN", };
277 case TYPE::NMOS_MOS1: return { "M", "NMOS", "", "1", true };
278 case TYPE::PMOS_MOS1: return { "M", "PMOS", "", "1", true };
279 case TYPE::NMOS_MOS2: return { "M", "NMOS", "", "2" };
280 case TYPE::PMOS_MOS2: return { "M", "PMOS", "", "2" };
281 case TYPE::NMOS_MOS3: return { "M", "NMOS", "", "3" };
282 case TYPE::PMOS_MOS3: return { "M", "PMOS", "", "3" };
283 case TYPE::NMOS_BSIM1: return { "M", "NMOS", "", "4" };
284 case TYPE::PMOS_BSIM1: return { "M", "PMOS", "", "4" };
285 case TYPE::NMOS_BSIM2: return { "M", "NMOS", "", "5" };
286 case TYPE::PMOS_BSIM2: return { "M", "PMOS", "", "5" };
287 case TYPE::NMOS_MOS6: return { "M", "NMOS", "", "6" };
288 case TYPE::PMOS_MOS6: return { "M", "PMOS", "", "6" };
289 case TYPE::NMOS_BSIM3: return { "M", "NMOS", "", "8" };
290 case TYPE::PMOS_BSIM3: return { "M", "PMOS", "", "8" };
291 case TYPE::NMOS_MOS9: return { "M", "NMOS", "", "9" };
292 case TYPE::PMOS_MOS9: return { "M", "PMOS", "", "9" };
293 case TYPE::NMOS_B4SOI: return { "M", "NMOS", "", "10" };
294 case TYPE::PMOS_B4SOI: return { "M", "PMOS", "", "10" };
295 case TYPE::NMOS_BSIM4: return { "M", "NMOS", "", "14" };
296 case TYPE::PMOS_BSIM4: return { "M", "PMOS", "", "14" };
297 //case TYPE::NMOS_EKV2_6: return {};
298 //case TYPE::PMOS_EKV2_6: return {};
299 //case TYPE::NMOS_PSP: return {};
300 //case TYPE::PMOS_PSP: return {};
301 case TYPE::NMOS_B3SOIFD: return { "M", "NMOS", "", "55" };
302 case TYPE::PMOS_B3SOIFD: return { "M", "PMOS", "", "55" };
303 case TYPE::NMOS_B3SOIDD: return { "M", "NMOS", "", "56" };
304 case TYPE::PMOS_B3SOIDD: return { "M", "PMOS", "", "56" };
305 case TYPE::NMOS_B3SOIPD: return { "M", "NMOS", "", "57" };
306 case TYPE::PMOS_B3SOIPD: return { "M", "PMOS", "", "57" };
307 //case TYPE::NMOS_STAG: return {};
308 //case TYPE::PMOS_STAG: return {};
309 case TYPE::NMOS_HISIM2: return { "M", "NMOS", "", "68" };
310 case TYPE::PMOS_HISIM2: return { "M", "PMOS", "", "68" };
311 case TYPE::NMOS_HISIMHV1: return { "M", "NMOS", "", "73", false, false, "1.2.4" };
312 case TYPE::PMOS_HISIMHV1: return { "M", "PMOS", "", "73", false, false, "1.2.4" };
313 case TYPE::NMOS_HISIMHV2: return { "M", "NMOS", "", "73", false, false, "2.2.0" };
314 case TYPE::PMOS_HISIMHV2: return { "M", "PMOS", "", "73", false, false, "2.2.0" };
315
316 case TYPE::V: return { "V", "", "DC" };
317 case TYPE::V_SIN: return { "V", "", "SIN" };
318 case TYPE::V_PULSE: return { "V", "", "PULSE" };
319 case TYPE::V_EXP: return { "V", "", "EXP" };
320 //case TYPE::V_SFAM: return { "V", "", "AM" };
321 //case TYPE::V_SFFM: return { "V", "", "SFFM" };
322 case TYPE::V_PWL: return { "V", "", "PWL" };
323 case TYPE::V_WHITENOISE: return { "V", "", "TRNOISE" };
324 case TYPE::V_PINKNOISE: return { "V", "", "TRNOISE" };
325 case TYPE::V_BURSTNOISE: return { "V", "", "TRNOISE" };
326 case TYPE::V_RANDUNIFORM: return { "V", "", "TRRANDOM" };
327 case TYPE::V_RANDNORMAL: return { "V", "", "TRRANDOM" };
328 case TYPE::V_RANDEXP: return { "V", "", "TRRANDOM" };
329 //case TYPE::V_RANDPOISSON: return { "V", "", "TRRANDOM" };
330 case TYPE::V_BEHAVIORAL: return { "B" };
331
332 case TYPE::I: return { "I", "", "DC" };
333 case TYPE::I_PULSE: return { "I", "", "PULSE" };
334 case TYPE::I_SIN: return { "I", "", "SIN" };
335 case TYPE::I_EXP: return { "I", "", "EXP" };
336 //case TYPE::I_SFAM: return { "V", "", "AM" };
337 //case TYPE::I_SFFM: return { "V", "", "SFFM" };
338 case TYPE::I_PWL: return { "I", "", "PWL" };
339 case TYPE::I_WHITENOISE: return { "I", "", "TRNOISE" };
340 case TYPE::I_PINKNOISE: return { "I", "", "TRNOISE" };
341 case TYPE::I_BURSTNOISE: return { "I", "", "TRNOISE" };
342 case TYPE::I_RANDUNIFORM: return { "I", "", "TRRANDOM" };
343 case TYPE::I_RANDNORMAL: return { "I", "", "TRRANDOM" };
344 case TYPE::I_RANDEXP: return { "I", "", "TRRANDOM" };
345 //case TYPE::I_RANDPOISSON: return { "I", "", "TRRANDOM" };
346 case TYPE::I_BEHAVIORAL: return { "B" };
347
348 case TYPE::SUBCKT: return { "X" };
349 case TYPE::XSPICE: return { "A" };
350
351 case TYPE::KIBIS_DEVICE: return { "X" };
352 case TYPE::KIBIS_DRIVER_DC: return { "X" };
353 case TYPE::KIBIS_DRIVER_RECT: return { "X" };
354 case TYPE::KIBIS_DRIVER_PRBS: return { "X" };
355
356 case TYPE::NONE:
357 case TYPE::RAWSPICE: return {};
358
359 default: wxFAIL; return {};
360 }
361}

References I, and NONE.

Referenced by GetSpiceInfo(), MigrateSimModel(), and SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings().

◆ SwitchSingleEndedDiff()

virtual void SIM_MODEL::SwitchSingleEndedDiff ( bool  aDiff)
inlinevirtual

Reimplemented in SIM_MODEL_KIBIS.

Definition at line 498 of file sim_model.h.

498{ };

Referenced by doReadDataFields().

◆ TypeInfo()

SIM_MODEL::INFO SIM_MODEL::TypeInfo ( TYPE  aType)
static

Definition at line 94 of file sim_model.cpp.

95{
96 switch( aType )
97 {
98 case TYPE::NONE: return { DEVICE_T::NONE, "", "" };
99
100 case TYPE::R: return { DEVICE_T::R, "", "Ideal" };
101 case TYPE::R_POT: return { DEVICE_T::R, "POT", "Potentiometer" };
102 case TYPE::R_BEHAVIORAL: return { DEVICE_T::R, "=", "Behavioral" };
103
104 case TYPE::C: return { DEVICE_T::C, "", "Ideal" };
105 case TYPE::C_BEHAVIORAL: return { DEVICE_T::C, "=", "Behavioral" };
106
107 case TYPE::L: return { DEVICE_T::L, "", "Ideal" };
108 case TYPE::L_MUTUAL: return { DEVICE_T::L, "MUTUAL", "Mutual" };
109 case TYPE::L_BEHAVIORAL: return { DEVICE_T::L, "=", "Behavioral" };
110
111 case TYPE::TLINE_Z0: return { DEVICE_T::TLINE, "", "Characteristic impedance" };
112 case TYPE::TLINE_RLGC: return { DEVICE_T::TLINE, "RLGC", "RLGC" };
113
114 case TYPE::SW_V: return { DEVICE_T::SW, "V", "Voltage-controlled" };
115 case TYPE::SW_I: return { DEVICE_T::SW, "I", "Current-controlled" };
116
117 case TYPE::D: return { DEVICE_T::D, "", "" };
118
119 case TYPE::NPN_VBIC: return { DEVICE_T::NPN, "VBIC", "VBIC" };
120 case TYPE::PNP_VBIC: return { DEVICE_T::PNP, "VBIC", "VBIC" };
121 case TYPE::NPN_GUMMELPOON: return { DEVICE_T::NPN, "GUMMELPOON", "Gummel-Poon" };
122 case TYPE::PNP_GUMMELPOON: return { DEVICE_T::PNP, "GUMMELPOON", "Gummel-Poon" };
123 //case TYPE::BJT_MEXTRAM: return {};
124 case TYPE::NPN_HICUM2: return { DEVICE_T::NPN, "HICUML2", "HICUM level 2" };
125 case TYPE::PNP_HICUM2: return { DEVICE_T::PNP, "HICUML2", "HICUM level 2" };
126 //case TYPE::BJT_HICUM_L0: return {};
127
128 case TYPE::NJFET_SHICHMANHODGES: return { DEVICE_T::NJFET, "SHICHMANHODGES", "Shichman-Hodges" };
129 case TYPE::PJFET_SHICHMANHODGES: return { DEVICE_T::PJFET, "SHICHMANHODGES", "Shichman-Hodges" };
130 case TYPE::NJFET_PARKERSKELLERN: return { DEVICE_T::NJFET, "PARKERSKELLERN", "Parker-Skellern" };
131 case TYPE::PJFET_PARKERSKELLERN: return { DEVICE_T::PJFET, "PARKERSKELLERN", "Parker-Skellern" };
132
133 case TYPE::NMES_STATZ: return { DEVICE_T::NMES, "STATZ", "Statz" };
134 case TYPE::PMES_STATZ: return { DEVICE_T::PMES, "STATZ", "Statz" };
135 case TYPE::NMES_YTTERDAL: return { DEVICE_T::NMES, "YTTERDAL", "Ytterdal" };
136 case TYPE::PMES_YTTERDAL: return { DEVICE_T::PMES, "YTTERDAL", "Ytterdal" };
137 case TYPE::NMES_HFET1: return { DEVICE_T::NMES, "HFET1", "HFET1" };
138 case TYPE::PMES_HFET1: return { DEVICE_T::PMES, "HFET1", "HFET1" };
139 case TYPE::NMES_HFET2: return { DEVICE_T::NMES, "HFET2", "HFET2" };
140 case TYPE::PMES_HFET2: return { DEVICE_T::PMES, "HFET2", "HFET2" };
141
142 case TYPE::NMOS_VDMOS: return { DEVICE_T::NMOS, "VDMOS", "VDMOS" };
143 case TYPE::PMOS_VDMOS: return { DEVICE_T::PMOS, "VDMOS", "VDMOS" };
144 case TYPE::NMOS_MOS1: return { DEVICE_T::NMOS, "MOS1", "Classical quadratic (MOS1)" };
145 case TYPE::PMOS_MOS1: return { DEVICE_T::PMOS, "MOS1", "Classical quadratic (MOS1)" };
146 case TYPE::NMOS_MOS2: return { DEVICE_T::NMOS, "MOS2", "Grove-Frohman (MOS2)" };
147 case TYPE::PMOS_MOS2: return { DEVICE_T::PMOS, "MOS2", "Grove-Frohman (MOS2)" };
148 case TYPE::NMOS_MOS3: return { DEVICE_T::NMOS, "MOS3", "MOS3" };
149 case TYPE::PMOS_MOS3: return { DEVICE_T::PMOS, "MOS3", "MOS3" };
150 case TYPE::NMOS_BSIM1: return { DEVICE_T::NMOS, "BSIM1", "BSIM1" };
151 case TYPE::PMOS_BSIM1: return { DEVICE_T::PMOS, "BSIM1", "BSIM1" };
152 case TYPE::NMOS_BSIM2: return { DEVICE_T::NMOS, "BSIM2", "BSIM2" };
153 case TYPE::PMOS_BSIM2: return { DEVICE_T::PMOS, "BSIM2", "BSIM2" };
154 case TYPE::NMOS_MOS6: return { DEVICE_T::NMOS, "MOS6", "MOS6" };
155 case TYPE::PMOS_MOS6: return { DEVICE_T::PMOS, "MOS6", "MOS6" };
156 case TYPE::NMOS_BSIM3: return { DEVICE_T::NMOS, "BSIM3", "BSIM3" };
157 case TYPE::PMOS_BSIM3: return { DEVICE_T::PMOS, "BSIM3", "BSIM3" };
158 case TYPE::NMOS_MOS9: return { DEVICE_T::NMOS, "MOS9", "MOS9" };
159 case TYPE::PMOS_MOS9: return { DEVICE_T::PMOS, "MOS9", "MOS9" };
160 case TYPE::NMOS_B4SOI: return { DEVICE_T::NMOS, "B4SOI", "BSIM4 SOI (B4SOI)" };
161 case TYPE::PMOS_B4SOI: return { DEVICE_T::PMOS, "B4SOI", "BSIM4 SOI (B4SOI)" };
162 case TYPE::NMOS_BSIM4: return { DEVICE_T::NMOS, "BSIM4", "BSIM4" };
163 case TYPE::PMOS_BSIM4: return { DEVICE_T::PMOS, "BSIM4", "BSIM4" };
164 //case TYPE::NMOS_EKV2_6: return {};
165 //case TYPE::PMOS_EKV2_6: return {};
166 //case TYPE::NMOS_PSP: return {};
167 //case TYPE::PMOS_PSP: return {};
168 case TYPE::NMOS_B3SOIFD: return { DEVICE_T::NMOS, "B3SOIFD", "B3SOIFD (BSIM3 FD-SOI)" };
169 case TYPE::PMOS_B3SOIFD: return { DEVICE_T::PMOS, "B3SOIFD", "B3SOIFD (BSIM3 FD-SOI)" };
170 case TYPE::NMOS_B3SOIDD: return { DEVICE_T::NMOS, "B3SOIDD", "B3SOIDD (BSIM3 SOI)" };
171 case TYPE::PMOS_B3SOIDD: return { DEVICE_T::PMOS, "B3SOIDD", "B3SOIDD (BSIM3 SOI)" };
172 case TYPE::NMOS_B3SOIPD: return { DEVICE_T::NMOS, "B3SOIPD", "B3SOIPD (BSIM3 PD-SOI)" };
173 case TYPE::PMOS_B3SOIPD: return { DEVICE_T::PMOS, "B3SOIPD", "B3SOIPD (BSIM3 PD-SOI)" };
174 //case TYPE::NMOS_STAG: return {};
175 //case TYPE::PMOS_STAG: return {};
176 case TYPE::NMOS_HISIM2: return { DEVICE_T::NMOS, "HISIM2", "HiSIM2" };
177 case TYPE::PMOS_HISIM2: return { DEVICE_T::PMOS, "HISIM2", "HiSIM2" };
178 case TYPE::NMOS_HISIMHV1: return { DEVICE_T::NMOS, "HISIMHV1", "HiSIM_HV1" };
179 case TYPE::PMOS_HISIMHV1: return { DEVICE_T::PMOS, "HISIMHV1", "HiSIM_HV1" };
180 case TYPE::NMOS_HISIMHV2: return { DEVICE_T::NMOS, "HISIMHV2", "HiSIM_HV2" };
181 case TYPE::PMOS_HISIMHV2: return { DEVICE_T::PMOS, "HISIMHV2", "HiSIM_HV2" };
182
183 case TYPE::V: return { DEVICE_T::V, "DC", "DC", };
184 case TYPE::V_SIN: return { DEVICE_T::V, "SIN", "Sine" };
185 case TYPE::V_PULSE: return { DEVICE_T::V, "PULSE", "Pulse" };
186 case TYPE::V_EXP: return { DEVICE_T::V, "EXP", "Exponential" };
187 //case TYPE::V_SFAM: return { DEVICE_TYPE::V, "SFAM", "Single-frequency AM" };
188 //case TYPE::V_SFFM: return { DEVICE_TYPE::V, "SFFM", "Single-frequency FM" };
189 case TYPE::V_PWL: return { DEVICE_T::V, "PWL", "Piecewise linear" };
190 case TYPE::V_WHITENOISE: return { DEVICE_T::V, "WHITENOISE", "White noise" };
191 case TYPE::V_PINKNOISE: return { DEVICE_T::V, "PINKNOISE", "Pink noise (1/f)" };
192 case TYPE::V_BURSTNOISE: return { DEVICE_T::V, "BURSTNOISE", "Burst noise" };
193 case TYPE::V_RANDUNIFORM: return { DEVICE_T::V, "RANDUNIFORM", "Random uniform" };
194 case TYPE::V_RANDNORMAL: return { DEVICE_T::V, "RANDNORMAL", "Random normal" };
195 case TYPE::V_RANDEXP: return { DEVICE_T::V, "RANDEXP", "Random exponential" };
196 //case TYPE::V_RANDPOISSON: return { DEVICE_TYPE::V, "RANDPOISSON", "Random Poisson" };
197 case TYPE::V_BEHAVIORAL: return { DEVICE_T::V, "=", "Behavioral" };
198
199 case TYPE::I: return { DEVICE_T::I, "DC", "DC", };
200 case TYPE::I_SIN: return { DEVICE_T::I, "SIN", "Sine" };
201 case TYPE::I_PULSE: return { DEVICE_T::I, "PULSE", "Pulse" };
202 case TYPE::I_EXP: return { DEVICE_T::I, "EXP", "Exponential" };
203 //case TYPE::I_SFAM: return { DEVICE_TYPE::I, "SFAM", "Single-frequency AM" };
204 //case TYPE::I_SFFM: return { DEVICE_TYPE::I, "SFFM", "Single-frequency FM" };
205 case TYPE::I_PWL: return { DEVICE_T::I, "PWL", "Piecewise linear" };
206 case TYPE::I_WHITENOISE: return { DEVICE_T::I, "WHITENOISE", "White noise" };
207 case TYPE::I_PINKNOISE: return { DEVICE_T::I, "PINKNOISE", "Pink noise (1/f)" };
208 case TYPE::I_BURSTNOISE: return { DEVICE_T::I, "BURSTNOISE", "Burst noise" };
209 case TYPE::I_RANDUNIFORM: return { DEVICE_T::I, "RANDUNIFORM", "Random uniform" };
210 case TYPE::I_RANDNORMAL: return { DEVICE_T::I, "RANDNORMAL", "Random normal" };
211 case TYPE::I_RANDEXP: return { DEVICE_T::I, "RANDEXP", "Random exponential" };
212 //case TYPE::I_RANDPOISSON: return { DEVICE_TYPE::I, "RANDPOISSON", "Random Poisson" };
213 case TYPE::I_BEHAVIORAL: return { DEVICE_T::I, "=", "Behavioral" };
214
215 case TYPE::SUBCKT: return { DEVICE_T::SUBCKT, "", "Subcircuit" };
216 case TYPE::XSPICE: return { DEVICE_T::XSPICE, "", "" };
217
218 case TYPE::KIBIS_DEVICE: return { DEVICE_T::KIBIS, "DEVICE", "Device" };
219 case TYPE::KIBIS_DRIVER_DC: return { DEVICE_T::KIBIS, "DCDRIVER", "DC driver" };
220 case TYPE::KIBIS_DRIVER_RECT: return { DEVICE_T::KIBIS, "RECTDRIVER", "Rectangular wave driver" };
221 case TYPE::KIBIS_DRIVER_PRBS: return { DEVICE_T::KIBIS, "PRBSDRIVER", "PRBS driver" };
222
223 case TYPE::RAWSPICE: return { DEVICE_T::SPICE, "", "" };
224
225 default: wxFAIL; return {};
226 }
227}

References I, and NONE.

Referenced by GetTypeInfo(), MigrateSimModel(), DIALOG_SIM_MODEL< T_symbol, T_field >::onTypeChoice(), ReadTypeFromFields(), DIALOG_SIM_MODEL< T_symbol, T_field >::TransferDataToWindow(), and DIALOG_SIM_MODEL< T_symbol, T_field >::updateInstanceWidgets().

◆ WriteFields() [1/3]

template<>
void SIM_MODEL::WriteFields ( std::vector< LIB_FIELD > &  aFields) const

Definition at line 440 of file sim_model.cpp.

441{
442 doWriteFields( aFields );
443}
void doWriteFields(std::vector< T > &aFields) const
Definition: sim_model.cpp:1040

References doWriteFields().

◆ WriteFields() [2/3]

template<>
void SIM_MODEL::WriteFields ( std::vector< SCH_FIELD > &  aFields) const

Definition at line 433 of file sim_model.cpp.

434{
435 doWriteFields( aFields );
436}

References doWriteFields().

◆ WriteFields() [3/3]

template<typename T >
void SIM_MODEL::WriteFields ( std::vector< T > &  aFields) const

Friends And Related Function Documentation

◆ NETLIST_EXPORTER_SPICE

friend class NETLIST_EXPORTER_SPICE
friend

Definition at line 65 of file sim_model.h.

◆ SPICE_GENERATOR

friend class SPICE_GENERATOR
friend

Definition at line 64 of file sim_model.h.

Member Data Documentation

◆ m_baseModel

◆ m_isEnabled

bool SIM_MODEL::m_isEnabled
private

Definition at line 540 of file sim_model.h.

Referenced by IsEnabled(), and SetIsEnabled().

◆ m_isStoredInValue

bool SIM_MODEL::m_isStoredInValue
private

Definition at line 541 of file sim_model.h.

Referenced by IsStoredInValue(), and SetIsStoredInValue().

◆ m_params

◆ m_pins

◆ m_serializer

std::unique_ptr<SIM_MODEL_SERIALIZER> SIM_MODEL::m_serializer
protected

Definition at line 534 of file sim_model.h.

Referenced by doReadDataFields(), doWriteFields(), and Serializer().

◆ m_spiceGenerator

std::unique_ptr<SPICE_GENERATOR> SIM_MODEL::m_spiceGenerator
private

Definition at line 537 of file sim_model.h.

Referenced by SpiceGenerator().

◆ m_type

const TYPE SIM_MODEL::m_type
private

Definition at line 539 of file sim_model.h.

Referenced by GetType().


The documentation for this class was generated from the following files: