Migrate more V6 SPICE syntax to V7.
Also fixes various bugs if symbols contained non-indexed pin numbers. We really need to know the actual pin names when creating models, rather than just assuming 1, 2... etc. Fixes https://gitlab.com/kicad/code/kicad/issues/13183
This commit is contained in:
parent
1047e7143a
commit
6b70c679cf
|
@ -240,14 +240,22 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
|||
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields );
|
||||
}
|
||||
|
||||
std::vector<LIB_PIN*> sourcePins = m_symbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
|
||||
m_builtinModelsMgr.CreateModel( m_fields, m_symbol.GetFullPinCount() );
|
||||
m_builtinModelsMgr.CreateModel( m_fields, sourcePins );
|
||||
else
|
||||
m_builtinModelsMgr.CreateModel( type, m_symbol.GetFullPinCount() );
|
||||
m_builtinModelsMgr.CreateModel( type, sourcePins );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
|
@ -656,6 +664,14 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<LIB_PIN*> sourcePins = m_symbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
try
|
||||
{
|
||||
std::string modelName = SIM_MODEL::GetFieldValue( &m_fields, SIM_LIBRARY::NAME_FIELD );
|
||||
|
@ -663,9 +679,9 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
|
|||
for( auto& [baseModelName, baseModel] : library()->GetModels() )
|
||||
{
|
||||
if( baseModelName == modelName )
|
||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetFullPinCount(), m_fields );
|
||||
m_libraryModelsMgr.CreateModel( baseModel, sourcePins, m_fields );
|
||||
else
|
||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetFullPinCount() );
|
||||
m_libraryModelsMgr.CreateModel( baseModel, sourcePins );
|
||||
}
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <pgm_base.h>
|
||||
#include <string>
|
||||
#include <string_utils.h>
|
||||
#include <common.h>
|
||||
#include <functional>
|
||||
#include <sch_symbol.h>
|
||||
|
@ -143,31 +144,35 @@ SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath, REPORTER* aR
|
|||
}
|
||||
|
||||
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount )
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( SIM_MODEL::TYPE aType, const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aType, aSymbolPinCount ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aType, aPins ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount )
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aSymbolPinCount ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount,
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aSymbolPinCount, aFields ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins, aFields ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount,
|
||||
template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<SCH_FIELD>& aFields );
|
||||
template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount,
|
||||
template SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<LIB_FIELD>& aFields );
|
||||
|
||||
|
||||
|
@ -220,37 +225,47 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
|
|||
}
|
||||
}
|
||||
|
||||
return CreateModel( fields, static_cast<int>( aSymbol.GetRawPins().size() ) );
|
||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
return CreateModel( fields, sourcePins );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<T>& aFields, int aSymbolPinCount )
|
||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
std::string libraryPath = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||
std::string baseModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD );
|
||||
|
||||
if( libraryPath != "" )
|
||||
{
|
||||
return CreateModel( libraryPath, baseModelName, aFields, aSymbolPinCount );
|
||||
return CreateModel( libraryPath, baseModelName, aFields, aPins );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aSymbolPinCount, aFields ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aFields, aPins ) );
|
||||
return { baseModelName, *m_models.back() };
|
||||
}
|
||||
}
|
||||
|
||||
template SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<SCH_FIELD>& aFields,
|
||||
int aSymbolPinCount );
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
template SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<LIB_FIELD>& aFields,
|
||||
int aSymbolPinCount );
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
||||
const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields,
|
||||
int aSymbolPinCount )
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||
SIM_LIBRARY* library = nullptr;
|
||||
|
@ -286,7 +301,7 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
|||
path ) );
|
||||
}
|
||||
|
||||
m_models.push_back( SIM_MODEL::Create( *baseModel, aSymbolPinCount, aFields ) );
|
||||
m_models.push_back( SIM_MODEL::Create( *baseModel, aPins, aFields ) );
|
||||
|
||||
return { aBaseModelName, *m_models.back() };
|
||||
}
|
||||
|
|
|
@ -48,23 +48,26 @@ public:
|
|||
SIM_LIBRARY& AddLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
SIM_LIBRARY& SetLibrary( const wxString& aLibraryPath, REPORTER* aReporter );
|
||||
|
||||
SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, int aSymbolPinCount );
|
||||
SIM_MODEL& CreateModel( SIM_MODEL::TYPE aType, const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount );
|
||||
SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
template <typename T>
|
||||
SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, int aSymbolPinCount,
|
||||
SIM_MODEL& CreateModel( const SIM_MODEL& aBaseModel, const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields );
|
||||
|
||||
// TODO: The argument can be made const.
|
||||
SIM_LIBRARY::MODEL CreateModel( const SCH_SHEET_PATH* aSheetPath, SCH_SYMBOL& aSymbol );
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL CreateModel( const std::vector<T>& aFields, int aSymbolPinCount );
|
||||
SIM_LIBRARY::MODEL CreateModel( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
template <typename T>
|
||||
SIM_LIBRARY::MODEL CreateModel( const wxString& aLibraryPath, const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields, int aSymbolPinCount );
|
||||
SIM_LIBRARY::MODEL CreateModel( const wxString& aLibraryPath,
|
||||
const std::string& aBaseModelName,
|
||||
const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
void SetModel( int aIndex, std::unique_ptr<SIM_MODEL> aModel );
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <locale_io.h>
|
||||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
#include <lib_pin.h>
|
||||
|
||||
|
||||
void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath )
|
||||
|
@ -36,16 +37,17 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath )
|
|||
m_kibis = KIBIS( aFilePath, m_reporter );
|
||||
|
||||
if( !m_kibis.m_valid )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( "Invalid ibis file" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned pinNumber = 2;
|
||||
LIB_PIN pinA( nullptr );
|
||||
LIB_PIN pinB( nullptr );
|
||||
pinA.SetNumber( wxT( "1" ) );
|
||||
pinB.SetNumber( wxT( "2" ) );
|
||||
std::vector<LIB_PIN*> pins = { &pinA, &pinB };
|
||||
|
||||
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pinNumber ) );
|
||||
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pins ) );
|
||||
m_modelNames.emplace_back( kcomp.m_name );
|
||||
|
||||
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
||||
|
|
|
@ -179,7 +179,7 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
|
|||
case TYPE::NMOS_HISIMHV2: return { DEVICE_T::NMOS, "HISIMHV2", "HiSIM_HV2" };
|
||||
case TYPE::PMOS_HISIMHV2: return { DEVICE_T::PMOS, "HISIMHV2", "HiSIM_HV2" };
|
||||
|
||||
case TYPE::V: return { DEVICE_T::V, "", "DC", };
|
||||
case TYPE::V: return { DEVICE_T::V, "DC", "DC", };
|
||||
case TYPE::V_SIN: return { DEVICE_T::V, "SIN", "Sine" };
|
||||
case TYPE::V_PULSE: return { DEVICE_T::V, "PULSE", "Pulse" };
|
||||
case TYPE::V_EXP: return { DEVICE_T::V, "EXP", "Exponential" };
|
||||
|
@ -195,7 +195,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_T::V, "=", "Behavioral" };
|
||||
|
||||
case TYPE::I: return { DEVICE_T::I, "", "DC", };
|
||||
case TYPE::I: return { DEVICE_T::I, "DC", "DC", };
|
||||
case TYPE::I_SIN: return { DEVICE_T::I, "SIN", "Sine" };
|
||||
case TYPE::I_PULSE: return { DEVICE_T::I, "PULSE", "Pulse" };
|
||||
case TYPE::I_EXP: return { DEVICE_T::I, "EXP", "Exponential" };
|
||||
|
@ -312,12 +312,12 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
|||
case TYPE::NMOS_HISIMHV2: return { "M", "NMOS", "", "73", true, false, "2.2.0" };
|
||||
case TYPE::PMOS_HISIMHV2: return { "M", "PMOS", "", "73", true, false, "2.2.0" };
|
||||
|
||||
case TYPE::V: return { "V", "" };
|
||||
case TYPE::V: return { "V", "", "DC" };
|
||||
case TYPE::V_SIN: return { "V", "", "SIN" };
|
||||
case TYPE::V_PULSE: return { "V", "", "PULSE" };
|
||||
case TYPE::V_EXP: return { "V", "", "EXP" };
|
||||
/*case TYPE::V_SFAM: return { "V", "", "AM" };
|
||||
case TYPE::V_SFFM: return { "V", "", "SFFM" };*/
|
||||
//case TYPE::V_SFAM: return { "V", "", "AM" };
|
||||
//case TYPE::V_SFFM: return { "V", "", "SFFM" };
|
||||
case TYPE::V_PWL: return { "V", "", "PWL" };
|
||||
case TYPE::V_WHITENOISE: return { "V", "", "TRNOISE" };
|
||||
case TYPE::V_PINKNOISE: return { "V", "", "TRNOISE" };
|
||||
|
@ -325,15 +325,15 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
|||
case TYPE::V_RANDUNIFORM: return { "V", "", "TRRANDOM" };
|
||||
case TYPE::V_RANDNORMAL: return { "V", "", "TRRANDOM" };
|
||||
case TYPE::V_RANDEXP: return { "V", "", "TRRANDOM" };
|
||||
//case TYPE::V_RANDPOISSON: return { "V", "", "TRRANDOM" };
|
||||
//case TYPE::V_RANDPOISSON: return { "V", "", "TRRANDOM" };
|
||||
case TYPE::V_BEHAVIORAL: return { "B" };
|
||||
|
||||
case TYPE::I: return { "I", "" };
|
||||
case TYPE::I: return { "I", "", "DC" };
|
||||
case TYPE::I_PULSE: return { "I", "", "PULSE" };
|
||||
case TYPE::I_SIN: return { "I", "", "SIN" };
|
||||
case TYPE::I_EXP: return { "I", "", "EXP" };
|
||||
/*case TYPE::I_SFAM: return { "V", "", "AM" };
|
||||
case TYPE::I_SFFM: return { "V", "", "SFFM" };*/
|
||||
//case TYPE::I_SFAM: return { "V", "", "AM" };
|
||||
//case TYPE::I_SFFM: return { "V", "", "SFFM" };
|
||||
case TYPE::I_PWL: return { "I", "", "PWL" };
|
||||
case TYPE::I_WHITENOISE: return { "I", "", "TRNOISE" };
|
||||
case TYPE::I_PINKNOISE: return { "I", "", "TRNOISE" };
|
||||
|
@ -341,7 +341,7 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
|||
case TYPE::I_RANDUNIFORM: return { "I", "", "TRRANDOM" };
|
||||
case TYPE::I_RANDNORMAL: return { "I", "", "TRRANDOM" };
|
||||
case TYPE::I_RANDEXP: return { "I", "", "TRRANDOM" };
|
||||
//case TYPE::I_RANDPOISSON: return { "I", "", "TRRANDOM" };
|
||||
//case TYPE::I_RANDPOISSON: return { "I", "", "TRRANDOM" };
|
||||
case TYPE::I_BEHAVIORAL: return { "B" };
|
||||
|
||||
case TYPE::SUBCKT: return { "X" };
|
||||
|
@ -412,83 +412,62 @@ TYPE SIM_MODEL::InferTypeFromLegacyFields( const std::vector<T>& aFields )
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SIM_MODEL::ReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields )
|
||||
{
|
||||
doReadDataFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void SIM_MODEL::ReadDataFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields )
|
||||
{
|
||||
ReadDataSchFields( aSymbolPinCount, aFields );
|
||||
doReadDataFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void SIM_MODEL::ReadDataFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields )
|
||||
{
|
||||
ReadDataLibFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields )
|
||||
{
|
||||
doReadDataFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields )
|
||||
template <>
|
||||
void SIM_MODEL::ReadDataFields( const std::vector<SCH_FIELD>* aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
doReadDataFields( aSymbolPinCount, aFields );
|
||||
doReadDataFields( aFields, aPins );
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SIM_MODEL::WriteFields( std::vector<T>& aFields ) const
|
||||
template <>
|
||||
void SIM_MODEL::ReadDataFields( const std::vector<LIB_FIELD>* aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
doWriteFields( aFields );
|
||||
doReadDataFields( aFields, aPins );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void SIM_MODEL::WriteFields( std::vector<SCH_FIELD>& aFields ) const
|
||||
{
|
||||
WriteDataSchFields( aFields );
|
||||
doWriteFields( aFields );
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void SIM_MODEL::WriteFields( std::vector<LIB_FIELD>& aFields ) const
|
||||
{
|
||||
WriteDataLibFields( aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const
|
||||
{
|
||||
doWriteFields( aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL::WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const
|
||||
{
|
||||
doWriteFields( aFields );
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, unsigned aSymbolPinCount )
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
std::unique_ptr<SIM_MODEL> model = Create( aType );
|
||||
|
||||
// Passing nullptr to ReadDataFields will make it act as if all fields were empty.
|
||||
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
||||
model->ReadDataFields( static_cast<const std::vector<SCH_FIELD>*>( nullptr ), aPins );
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount )
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins)
|
||||
{
|
||||
std::unique_ptr<SIM_MODEL> model = Create( aBaseModel.GetType() );
|
||||
|
||||
|
@ -501,13 +480,14 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsig
|
|||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
|
||||
model->ReadDataFields( aSymbolPinCount, static_cast<const std::vector<void>*>( nullptr ) );
|
||||
model->ReadDataFields( static_cast<const std::vector<SCH_FIELD>*>( nullptr ), aPins );
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields )
|
||||
{
|
||||
TYPE type = ReadTypeFromFields( aFields );
|
||||
|
@ -526,34 +506,35 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel, unsig
|
|||
{
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
model->ReadDataFields( aSymbolPinCount, &aFields );
|
||||
|
||||
model->ReadDataFields( &aFields, aPins );
|
||||
return model;
|
||||
}
|
||||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
unsigned aSymbolPinCount,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<SCH_FIELD>& aFields );
|
||||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
unsigned aSymbolPinCount,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<LIB_FIELD>& aFields );
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||
const std::vector<T>& aFields )
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
TYPE type = ReadTypeFromFields( aFields );
|
||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
||||
|
||||
model->ReadDataFields( aSymbolPinCount, &aFields );
|
||||
model->ReadDataFields( &aFields, aPins );
|
||||
return model;
|
||||
}
|
||||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||
const std::vector<SCH_FIELD>& aFields );
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( unsigned aSymbolPinCount,
|
||||
const std::vector<LIB_FIELD>& aFields );
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<SCH_FIELD>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<LIB_FIELD>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
|
||||
template <typename T>
|
||||
|
@ -619,12 +600,21 @@ void SIM_MODEL::SetFieldValue( std::vector<T>& aFields, const std::string& aFiel
|
|||
aFields.emplace_back( wxPoint(), aFields.size(), parent, aFieldName );
|
||||
}
|
||||
else if constexpr( std::is_same<T, LIB_FIELD>::value )
|
||||
{
|
||||
aFields.emplace_back( aFields.size(), aFieldName );
|
||||
}
|
||||
|
||||
aFields.back().SetText( aValue );
|
||||
}
|
||||
|
||||
|
||||
template void SIM_MODEL::SetFieldValue<SCH_FIELD>( std::vector<SCH_FIELD>& aFields,
|
||||
const std::string& aFieldName,
|
||||
const std::string& aValue );
|
||||
template void SIM_MODEL::SetFieldValue<LIB_FIELD>( std::vector<LIB_FIELD>& aFields,
|
||||
const std::string& aFieldName,
|
||||
const std::string& aValue );
|
||||
|
||||
SIM_MODEL::~SIM_MODEL() = default;
|
||||
|
||||
|
||||
|
@ -1012,9 +1002,39 @@ void SIM_MODEL::CreatePins( unsigned aSymbolPinCount )
|
|||
}
|
||||
|
||||
|
||||
void SIM_MODEL::CreatePins( const std::vector<LIB_PIN*> aSymbolPins )
|
||||
{
|
||||
// Default pin sequence: model pins are the same as symbol pins.
|
||||
// Excess model pins are set as Not Connected.
|
||||
// Note that intentionally nothing is added if `getPinNames()` returns an empty vector.
|
||||
|
||||
// SIM_MODEL pins must be ordered by symbol pin numbers -- this is assumed by the code that
|
||||
// accesses them.
|
||||
|
||||
for( unsigned modelPinIndex = 0; modelPinIndex < getPinNames().size(); ++modelPinIndex )
|
||||
{
|
||||
if( modelPinIndex < aSymbolPins.size() )
|
||||
{
|
||||
AddPin( { getPinNames().at( modelPinIndex ),
|
||||
aSymbolPins[ modelPinIndex ]->GetNumber().ToStdString() } );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPin( { getPinNames().at( modelPinIndex ), "" } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: remove this API. If we have symbol fields, then we have symbol pins and we should be
|
||||
// creating a model with the real symbol pin names, not indexes...
|
||||
|
||||
template <typename T>
|
||||
void SIM_MODEL::doReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields )
|
||||
{
|
||||
bool diffMode = GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
SwitchSingleEndedDiff( diffMode );
|
||||
|
||||
try
|
||||
{
|
||||
m_serde->ParseEnable( GetFieldValue( aFields, ENABLE_FIELD ) );
|
||||
|
@ -1034,6 +1054,32 @@ void SIM_MODEL::doReadDataFields( unsigned aSymbolPinCount, const std::vector<T>
|
|||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SIM_MODEL::doReadDataFields( const std::vector<T>* aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
bool diffMode = GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
SwitchSingleEndedDiff( diffMode );
|
||||
|
||||
try
|
||||
{
|
||||
m_serde->ParseEnable( GetFieldValue( aFields, ENABLE_FIELD ) );
|
||||
|
||||
CreatePins( aPins );
|
||||
m_serde->ParsePins( GetFieldValue( aFields, PINS_FIELD ) );
|
||||
|
||||
std::string paramsField = GetFieldValue( aFields, PARAMS_FIELD );
|
||||
|
||||
if( !m_serde->ParseParams( paramsField ) )
|
||||
m_serde->ParseValue( GetFieldValue( aFields, VALUE_FIELD ) );
|
||||
}
|
||||
catch( IO_ERROR& err )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void SIM_MODEL::doWriteFields( std::vector<T>& aFields ) const
|
||||
{
|
||||
|
@ -1173,9 +1219,6 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
return;
|
||||
}
|
||||
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
|
||||
|
||||
auto getSIValue =
|
||||
[]( T_field* aField )
|
||||
{
|
||||
|
@ -1191,13 +1234,23 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
return value;
|
||||
};
|
||||
|
||||
wxString spiceType;
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
T_field* valueField = aSymbol.FindField( wxT( "Value" ) );
|
||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
wxString spiceDeviceType;
|
||||
wxString spiceModel;
|
||||
wxString spiceType;
|
||||
wxString spiceLib;
|
||||
wxString pinMap;
|
||||
wxString spiceParams;
|
||||
bool modelFromValueField = false;
|
||||
bool modelFromLib = false;
|
||||
|
||||
if( aSymbol.FindField( wxT( "Spice_Primitive" ) )
|
||||
|| aSymbol.FindField( wxT( "Spice_Node_Sequence" ) )
|
||||
|
@ -1207,7 +1260,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
{
|
||||
if( T_field* primitiveField = aSymbol.FindField( wxT( "Spice_Primitive" ) ) )
|
||||
{
|
||||
spiceType = primitiveField->GetText();
|
||||
spiceDeviceType = primitiveField->GetText();
|
||||
aSymbol.RemoveField( primitiveField );
|
||||
}
|
||||
|
||||
|
@ -1237,7 +1290,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
|
||||
if( T_field* modelField = aSymbol.FindField( wxT( "Spice_Model" ) ) )
|
||||
{
|
||||
spiceModel = modelField->GetText();
|
||||
spiceModel = getSIValue( modelField );
|
||||
aSymbol.RemoveField( modelField );
|
||||
}
|
||||
else
|
||||
|
@ -1267,14 +1320,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
{
|
||||
spiceLib = libFileField->GetText();
|
||||
aSymbol.RemoveField( libFileField );
|
||||
modelFromLib = true;
|
||||
}
|
||||
}
|
||||
else if( prefix == wxT( "V" ) || prefix == wxT( "I" ) )
|
||||
{
|
||||
spiceModel = getSIValue( valueField );
|
||||
modelFromValueField = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto convert some legacy fields used in the middle of 7.0 development...
|
||||
|
@ -1300,8 +1347,6 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
|
||||
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
||||
|
||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||
|
||||
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
|
||||
{
|
||||
if( pinIndexes[0] == wxT( "2" ) )
|
||||
|
@ -1342,7 +1387,10 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
return;
|
||||
}
|
||||
|
||||
if( modelFromLib )
|
||||
bool libraryModel = false;
|
||||
bool internalModel = false;
|
||||
|
||||
if( !spiceLib.IsEmpty() )
|
||||
{
|
||||
SIM_LIB_MGR libMgr( aProject );
|
||||
|
||||
|
@ -1350,18 +1398,78 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
{
|
||||
std::vector<T_field> emptyFields;
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
|
||||
emptyFields, aSymbol.GetFullPinCount() );
|
||||
emptyFields, sourcePins );
|
||||
|
||||
spiceParams = wxString( model.model.GetBaseModel()->Serde().GenerateParams() );
|
||||
libraryModel = true;
|
||||
|
||||
if( pinMap.IsEmpty() )
|
||||
{
|
||||
// Generate a default pin map
|
||||
model.model.CreatePins( sourcePins );
|
||||
pinMap = wxString( model.model.Serde().GeneratePins() );
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Fall back to raw spice model
|
||||
modelFromLib = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert functional SPICE model syntax to name=value pairs. For instance, "dc(1)"
|
||||
// needs to go to "dc=1", while "sin(0, 1, 60)" needs to go to "dc=0 ampl=1 f=60".
|
||||
|
||||
wxRegEx regex( wxT( "^[a-z]+\\(.*\\)$" ) );
|
||||
|
||||
if( regex.Matches( spiceModel ) )
|
||||
{
|
||||
wxString paramSet;
|
||||
|
||||
spiceType = spiceModel.BeforeFirst( '(', ¶mSet );
|
||||
paramSet = paramSet.BeforeLast( ')' );
|
||||
|
||||
wxStringTokenizer tokenizer( paramSet, wxT( " " ), wxTOKEN_STRTOK );
|
||||
|
||||
spiceType.MakeUpper();
|
||||
|
||||
for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() )
|
||||
{
|
||||
if( spiceDeviceType == SIM_MODEL::SpiceInfo( type ).itemType
|
||||
&& spiceType == SIM_MODEL::SpiceInfo( type ).inlineTypeString )
|
||||
{
|
||||
try
|
||||
{
|
||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
||||
|
||||
for( int ii = 0; tokenizer.HasMoreTokens(); ++ii )
|
||||
{
|
||||
model->SetParamValue( ii, tokenizer.GetNextToken().ToStdString(),
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SPICE );
|
||||
}
|
||||
|
||||
spiceParams = wxString( model->Serde().GenerateParams() );
|
||||
internalModel = true;
|
||||
|
||||
if( pinMap.IsEmpty() )
|
||||
{
|
||||
// Generate a default pin map
|
||||
model->CreatePins( sourcePins );
|
||||
pinMap = wxString( model->Serde().GeneratePins() );
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Fall back to raw spice model
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( modelFromLib )
|
||||
if( libraryModel )
|
||||
{
|
||||
T_field libraryField( &aSymbol, -1, SIM_MODEL::LIBRARY_FIELD );
|
||||
libraryField.SetText( spiceLib );
|
||||
|
@ -1378,18 +1486,33 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
if( modelFromValueField )
|
||||
valueField->SetText( wxT( "${SIM.NAME}" ) );
|
||||
}
|
||||
else
|
||||
else if( internalModel )
|
||||
{
|
||||
// Insert a raw spice model as a substitute.
|
||||
T_field deviceTypeField( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
deviceTypeField.SetText( spiceDeviceType );
|
||||
aSymbol.AddField( deviceTypeField );
|
||||
|
||||
if( spiceType.IsEmpty() && spiceLib.IsEmpty() )
|
||||
T_field typeField( &aSymbol, -1, SIM_MODEL::TYPE_FIELD );
|
||||
typeField.SetText( spiceType );
|
||||
aSymbol.AddField( typeField );
|
||||
|
||||
T_field paramsField( &aSymbol, -1, SIM_MODEL::PARAMS_FIELD );
|
||||
paramsField.SetText( spiceParams );
|
||||
aSymbol.AddField( paramsField );
|
||||
|
||||
if( modelFromValueField )
|
||||
valueField->SetText( wxT( "${SIM.PARAMS}" ) );
|
||||
}
|
||||
else // Insert a raw spice model as a substitute.
|
||||
{
|
||||
if( spiceDeviceType.IsEmpty() && spiceLib.IsEmpty() )
|
||||
{
|
||||
spiceParams = spiceModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceParams.Printf( wxT( "type=\"%s\" model=\"%s\" lib=\"%s\"" ),
|
||||
spiceType, spiceModel, spiceLib );
|
||||
spiceDeviceType, spiceModel, spiceLib );
|
||||
}
|
||||
|
||||
T_field deviceTypeField( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
|
@ -1408,41 +1531,25 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
if( valueField )
|
||||
valueField->SetText( wxT( "${SIM.PARAMS}" ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( !pinMap.IsEmpty() )
|
||||
{
|
||||
T_field pinsField( &aSymbol, -1, SIM_MODEL::PINS_FIELD );
|
||||
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate a 1:1 pin map. We don't necessarily know the SPICE model pinNames, so just
|
||||
// use indexes.
|
||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||
|
||||
std::sort( sourcePins.begin(), sourcePins.end(),
|
||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||
{
|
||||
return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
|
||||
} );
|
||||
|
||||
for( unsigned ii = 0; ii < sourcePins.size(); ++ii )
|
||||
if( pinMap.IsEmpty() )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pinMap.Append( wxS( " " ) );
|
||||
// Generate a 1:1 pin map. We don't know the SPICE model pinNames, so just use indexes.
|
||||
for( unsigned ii = 0; ii < sourcePins.size(); ++ii )
|
||||
{
|
||||
if( ii > 0 )
|
||||
pinMap.Append( wxS( " " ) );
|
||||
|
||||
pinMap.Append( wxString::Format( wxT( "%s=%u" ),
|
||||
sourcePins[ii]->GetNumber(),
|
||||
ii + 1 ) );
|
||||
pinMap.Append( wxString::Format( wxT( "%s=%u" ),
|
||||
sourcePins[ii]->GetNumber(),
|
||||
ii + 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
T_field pinsField( &aSymbol, aSymbol.GetFieldCount(), SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
|
||||
T_field pinsField( &aSymbol, -1, SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -400,16 +400,19 @@ public:
|
|||
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
||||
|
||||
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, unsigned aSymbolPinCount );
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount );
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel, unsigned aSymbolPinCount,
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields );
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( unsigned aSymbolPinCount,
|
||||
const std::vector<T>& aFields );
|
||||
static std::unique_ptr<SIM_MODEL> Create( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
template <typename T>
|
||||
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName );
|
||||
|
@ -433,18 +436,12 @@ public:
|
|||
template <typename T>
|
||||
void ReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
|
||||
|
||||
virtual void ReadDataSchFields( unsigned aSymbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields );
|
||||
virtual void ReadDataLibFields( unsigned aSymbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields );
|
||||
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;
|
||||
|
||||
virtual void WriteDataSchFields( std::vector<SCH_FIELD>& aFields ) const;
|
||||
virtual void WriteDataLibFields( std::vector<LIB_FIELD>& aFields ) const;
|
||||
|
||||
|
||||
virtual bool HasToIncludeSpiceLibrary() const { return GetBaseModel() && !HasOverrides(); }
|
||||
|
||||
SPICE_INFO GetSpiceInfo() const { return SpiceInfo( GetType() ); }
|
||||
|
@ -522,6 +519,8 @@ public:
|
|||
}
|
||||
bool IsStoredInValue() const { return m_isStoredInValue; }
|
||||
|
||||
virtual void SwitchSingleEndedDiff( bool aDiff ) { };
|
||||
|
||||
template <class T>
|
||||
static bool InferPassiveSimModel( T& aSymbol, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString* aModelType,
|
||||
|
@ -539,11 +538,15 @@ protected:
|
|||
std::unique_ptr<SIM_SERDE> aSerde );
|
||||
|
||||
virtual void CreatePins( unsigned aSymbolPinCount );
|
||||
virtual void CreatePins( const std::vector<LIB_PIN*> aSymbolPins );
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
void doReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -499,20 +499,3 @@ std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_KIBIS::makePrbsWaveformParamInfos(
|
|||
return paramInfos;
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_KIBIS::ReadDataSchFields( unsigned aSymbolPinCount, const std::vector<SCH_FIELD>* aFields )
|
||||
{
|
||||
bool diffMode = SIM_MODEL::GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
SwitchSingleEndedDiff( diffMode );
|
||||
|
||||
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
||||
|
||||
void SIM_MODEL_KIBIS::ReadDataLibFields( unsigned aSymbolPinCount, const std::vector<LIB_FIELD>* aFields )
|
||||
{
|
||||
bool diffMode = SIM_MODEL::GetFieldValue( aFields, SIM_LIBRARY_KIBIS::DIFF_FIELD ) == "1";
|
||||
SwitchSingleEndedDiff( diffMode );
|
||||
|
||||
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
|
||||
}
|
||||
|
|
|
@ -87,15 +87,10 @@ public:
|
|||
|
||||
void SetBaseModel( const SIM_MODEL& aBaseModel ) override;
|
||||
|
||||
void SwitchSingleEndedDiff( bool aDiff );
|
||||
void SwitchSingleEndedDiff( bool aDiff ) override;
|
||||
bool CanDifferential() const { return m_enableDiff; } ;
|
||||
bool m_enableDiff;
|
||||
|
||||
void ReadDataSchFields( unsigned aSymbolPinCount,
|
||||
const std::vector<SCH_FIELD>* aFields ) override;
|
||||
void ReadDataLibFields( unsigned aSymbolPinCount,
|
||||
const std::vector<LIB_FIELD>* aFields ) override;
|
||||
|
||||
protected:
|
||||
void CreatePins( unsigned aSymbolPinCount ) override;
|
||||
|
||||
|
|
|
@ -185,10 +185,14 @@ std::string SPICE_GENERATOR_SOURCE::ItemLine( const SPICE_ITEM& aItem ) const
|
|||
break;
|
||||
}
|
||||
|
||||
item.modelName.append( fmt::format( "{}( {})", m_model.GetSpiceInfo().inlineTypeString, args ) );
|
||||
item.modelName.append( fmt::format( "{}( {})",
|
||||
m_model.GetSpiceInfo().inlineTypeString,
|
||||
args ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
item.modelName.append( m_model.GetParam( 0 ).value->ToSpiceString() );
|
||||
}
|
||||
|
||||
return SPICE_GENERATOR::ItemLine( item );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue