Sim: Refactor SPICE_GENERATOR methods to accept a single SPICE_ITEM

This commit is contained in:
Mikolaj Wielgus 2022-10-11 01:23:00 +02:00
parent 57a6aeb86a
commit d9eb76eae0
28 changed files with 221 additions and 272 deletions

View File

@ -76,7 +76,7 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
for( const auto& item : m_circuitModel->GetItems() )
{
// Add all possible currents for the primitive.
for( const auto& currentName : item.model->SpiceGenerator().CurrentNames( item.refName ) )
for( const auto& currentName : item.model->SpiceGenerator().CurrentNames( item ) )
m_signals->Append( currentName );
}
}

View File

@ -399,10 +399,11 @@ void DIALOG_SIM_MODEL<T>::updateModelParamsTab()
template <typename T>
void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
{
wxString modelName = m_modelNameCombobox->GetStringSelection();
SPICE_ITEM item;
item.modelName = m_modelNameCombobox->GetStringSelection();
if( m_useInstanceModelRadioButton->GetValue() || modelName.IsEmpty() )
modelName = m_fields.at( REFERENCE_FIELD ).GetText();
if( m_useInstanceModelRadioButton->GetValue() || item.modelName == "" )
item.modelName = m_fields.at( REFERENCE_FIELD ).GetText();
m_codePreview->SetEditable( true ); // ???
@ -415,7 +416,7 @@ void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
wxTextFile file;
wxString text;
text << curModel().SpiceGenerator().Preview( std::string( modelName.ToUTF8() ) );
text << curModel().SpiceGenerator().Preview( item );
text << "\n";
text << "--- FILE SOURCE (" << path << ") ---\n";
text << "\n";
@ -433,7 +434,7 @@ void DIALOG_SIM_MODEL<T>::updateModelCodeTab()
}
}
else
m_codePreview->SetText( curModel().SpiceGenerator().Preview( std::string( modelName.ToUTF8() ) ) );
m_codePreview->SetText( curModel().SpiceGenerator().Preview( item ) );
m_codePreview->SetEditable( false ); // ???
m_wasCodePreviewUpdated = true;

View File

@ -205,7 +205,8 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
CreatePinList( symbol, &sheet, true );
ITEM spiceItem;
SPICE_ITEM spiceItem;
spiceItem.fields = &symbol->GetFields();
try
{
@ -242,10 +243,10 @@ void NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( std::string& aNetName )
std::string NETLIST_EXPORTER_SPICE::GetItemName( const std::string& aRefName ) const
{
const std::list<ITEM>& spiceItems = GetItems();
const std::list<SPICE_ITEM>& spiceItems = GetItems();
auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
[aRefName]( const ITEM& aItem )
[aRefName]( const SPICE_ITEM& aItem )
{
return aItem.refName == aRefName;
} );
@ -253,7 +254,9 @@ std::string NETLIST_EXPORTER_SPICE::GetItemName( const std::string& aRefName ) c
if( it == spiceItems.end() )
return "";
return it->model->SpiceGenerator().ItemName( aRefName );
SPICE_ITEM item;
item.refName = aRefName;
return it->model->SpiceGenerator().ItemName( item );
}
@ -263,14 +266,14 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
for( const SCH_SHEET_PATH& sheet : GetSheets( aNetlistOptions ) )
{
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
for( SCH_ITEM* SPICE_ITEM : sheet.LastScreen()->Items() )
{
wxString text;
if( item->Type() == SCH_TEXT_T )
text = static_cast<SCH_TEXT*>( item )->GetShownText();
else if( item->Type() == SCH_TEXTBOX_T )
text = static_cast<SCH_TEXTBOX*>( item )->GetShownText();
if( SPICE_ITEM->Type() == SCH_TEXT_T )
text = static_cast<SCH_TEXT*>( SPICE_ITEM )->GetShownText();
else if( SPICE_ITEM->Type() == SCH_TEXTBOX_T )
text = static_cast<SCH_TEXTBOX*>( SPICE_ITEM )->GetShownText();
else
continue;
@ -321,7 +324,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
ITEM& aItem,
SPICE_ITEM& aItem,
std::set<std::string>& aRefNames )
{
aItem.refName = aSymbol.GetRef( &aSheet );
@ -339,13 +342,14 @@ bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aS
}
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem )
void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
{
auto [baseModelName, model] = m_libMgr.CreateModel( aSymbol );
aItem.model = &model;
SIM_LIBRARY::MODEL libModel = m_libMgr.CreateModel( aSymbol );
std::string modelName = aItem.model->SpiceGenerator().ModelName( aItem.refName,
baseModelName );
aItem.baseModelName = libModel.name;
aItem.model = &libModel.model;
std::string modelName = aItem.model->SpiceGenerator().ModelName( aItem );
// Resolve model name collisions.
aItem.modelName = m_modelNameGenerator.Generate( modelName );
@ -377,7 +381,7 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
}
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
std::string modelData = spiceGenerator.IbisDevice( aSymbol.GetFields(), aItem.modelName );
std::string modelData = spiceGenerator.IbisDevice( aItem );
cacheFile.Write( wxString( modelData ) );
m_rawIncludes.insert( libraryPath );
@ -385,14 +389,14 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
}
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem )
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
{
for( const PIN_INFO& pin : m_sortedSymbolPinList )
aItem.pinNumbers.emplace_back( std::string( pin.num.ToUTF8() ) );
}
void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem,
void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
int& aNcCounter )
{
for( const PIN_INFO& pinInfo : m_sortedSymbolPinList )
@ -449,29 +453,24 @@ void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigne
void NETLIST_EXPORTER_SPICE::writeModels( OUTPUTFORMATTER& aFormatter )
{
for( const ITEM& item : m_items )
for( const SPICE_ITEM& item : m_items )
{
if( !item.model->IsEnabled() )
continue;
aFormatter.Print( 0, "%s",
item.model->SpiceGenerator().ModelLine( item.modelName ).c_str() );
aFormatter.Print( 0, "%s", item.model->SpiceGenerator().ModelLine( item ).c_str() );
}
}
void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter )
{
for( const ITEM& item : m_items )
for( const SPICE_ITEM& item : m_items )
{
if( !item.model->IsEnabled() )
continue;
aFormatter.Print( 0, "%s",
item.model->SpiceGenerator().ItemLine( item.refName,
item.modelName,
item.pinNumbers,
item.pinNetNames ).c_str() );
aFormatter.Print( 0, "%s", item.model->SpiceGenerator().ItemLine( item ).c_str() );
}
}

View File

@ -30,6 +30,7 @@
#include <sim/sim_lib_mgr.h>
#include <sim/sim_library.h>
#include <sim/sim_model.h>
#include <sim/spice_generator.h>
class NAME_GENERATOR
@ -58,15 +59,6 @@ public:
| OPTION_SAVE_ALL_CURRENTS
};
struct ITEM
{
std::string refName;
std::vector<std::string> pinNumbers;
std::vector<std::string> pinNetNames;
const SIM_MODEL* model;
std::string modelName;
};
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic );
/**
@ -122,7 +114,7 @@ public:
/**
* Return the list of items representing schematic components in the Spice world.
*/
const std::list<ITEM>& GetItems() const { return m_items; }
const std::list<SPICE_ITEM>& GetItems() const { return m_items; }
const std::vector<std::string>& GetDirectives() { return m_directives; }
@ -138,11 +130,11 @@ protected:
SCH_SHEET_LIST GetSheets( unsigned aNetlistOptions = 0 ) const;
private:
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem,
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
std::set<std::string>& aRefNames );
void readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem );
void readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem );
void readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem, int& aNcCounter );
void readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
void readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
void readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& aNcCounter );
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
const std::string& aPath );
@ -159,7 +151,7 @@ private:
//std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
std::set<std::string> m_rawIncludes; ///< include directives found in symbols
std::set<std::string> m_nets;
std::list<ITEM> m_items; ///< Items representing schematic symbols in Spice world
std::list<SPICE_ITEM> m_items; ///< Items representing schematic symbols in Spice world
};

View File

@ -29,40 +29,38 @@
#include <fmt/core.h>
std::string SPICE_GENERATOR_BEHAVIORAL::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_BEHAVIORAL::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
std::string SPICE_GENERATOR_BEHAVIORAL::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR_BEHAVIORAL::ItemLine( const SPICE_ITEM& aItem ) const
{
switch( m_model.GetType() )
{
case SIM_MODEL::TYPE::R_BEHAVIORAL:
case SIM_MODEL::TYPE::C_BEHAVIORAL:
case SIM_MODEL::TYPE::L_BEHAVIORAL:
return SPICE_GENERATOR::ItemLine( aRefName,
m_model.GetParam( 0 ).value->ToString(),
aSymbolPinNumbers,
aPinNetNames );
{
SPICE_ITEM item = aItem;
item.modelName = m_model.GetParam( 0 ).value->ToSpiceString();
return SPICE_GENERATOR::ItemLine( item );
}
case SIM_MODEL::TYPE::V_BEHAVIORAL:
return SPICE_GENERATOR::ItemLine( aRefName,
fmt::format( "V={0}",
m_model.GetParam( 0 ).value->ToString() ),
aSymbolPinNumbers,
aPinNetNames );
{
SPICE_ITEM item = aItem;
item.modelName = fmt::format( "V={}", m_model.GetParam( 0 ).value->ToSpiceString() );
return SPICE_GENERATOR::ItemLine( item );
}
case SIM_MODEL::TYPE::I_BEHAVIORAL:
return SPICE_GENERATOR::ItemLine( aRefName,
fmt::format( "I={0}",
m_model.GetParam( 0 ).value->ToString() ),
aSymbolPinNumbers,
aPinNetNames );
{
SPICE_ITEM item = aItem;
item.modelName = fmt::format( "I={}", m_model.GetParam( 0 ).value->ToSpiceString() );
return SPICE_GENERATOR::ItemLine( item );
}
default:
wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_BEHAVIORAL" );

View File

@ -34,11 +34,8 @@ class SPICE_GENERATOR_BEHAVIORAL : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::string ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::string ItemLine( const SPICE_ITEM& aItem ) const override;
};

View File

@ -27,22 +27,19 @@
#include <pegtl/contrib/parse_tree.hpp>
std::string SPICE_GENERATOR_IDEAL::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_IDEAL::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
std::string SPICE_GENERATOR_IDEAL::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR_IDEAL::ItemLine( const SPICE_ITEM& aItem ) const
{
std::string valueStr = m_model.GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE );
SPICE_ITEM item = aItem;
item.modelName = m_model.GetParam( 0 ).value->ToString( SIM_VALUE::NOTATION::SPICE );
if( valueStr != "" )
return SPICE_GENERATOR::ItemLine( aRefName, valueStr, aSymbolPinNumbers,
aPinNetNames );
if( item.modelName != "" )
return SPICE_GENERATOR::ItemLine( item );
else
return "";
}

View File

@ -34,11 +34,8 @@ class SPICE_GENERATOR_IDEAL : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::string ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::string ItemLine( const SPICE_ITEM& aItem ) const override;
};

View File

@ -28,14 +28,13 @@
#include <fmt/core.h>
std::string SPICE_GENERATOR_KIBIS::ModelName( const std::string& aRefName,
const std::string& aBaseModelName ) const
std::string SPICE_GENERATOR_KIBIS::ModelName( const SPICE_ITEM& aItem ) const
{
return fmt::format( "{}.{}", aRefName, aBaseModelName );
return fmt::format( "{}.{}", aItem.refName, aItem.baseModelName );
}
std::string SPICE_GENERATOR_KIBIS::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_KIBIS::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
@ -47,24 +46,23 @@ std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> SPICE_GENERATOR_KIBI
}
std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const std::string& aRefName ) const
std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM& aItem ) const
{
std::vector<std::string> currentNames;
for( const SIM_MODEL::PIN& pin : GetPins() )
currentNames.push_back( fmt::format( "I({}:{})", ItemName( aRefName ), pin.name ) );
currentNames.push_back( fmt::format( "I({}:{})", ItemName( aItem ), pin.name ) );
return currentNames;
}
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFields,
const std::string& aModelName ) const
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem ) const
{
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::LIBRARY_FIELD );
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD );
std::string ibisPinName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY_KIBIS::PIN_FIELD );
std::string ibisModelName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
std::string ibisCompName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY::NAME_FIELD );
std::string ibisPinName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::PIN_FIELD );
std::string ibisModelName = SIM_MODEL::GetFieldValue( aItem.fields, SIM_LIBRARY_KIBIS::MODEL_FIELD );
KIBIS kibis( ibisLibFilename );
KIBIS_COMPONENT* kcomp = kibis.GetComponent( std::string( ibisCompName ) );
@ -109,7 +107,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFi
switch( m_model.GetType() )
{
case SIM_MODEL::TYPE::KIBIS_DEVICE:
kpin->writeSpiceDevice( &result, aModelName, *kmodel, kparams );
kpin->writeSpiceDevice( &result, aItem.modelName, *kmodel, kparams );
break;
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
@ -132,7 +130,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFi
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_STUCK_HIGH() );
}
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break;
}
@ -145,7 +143,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFi
waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 );
kparams.m_waveform = waveform;
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break;
}
@ -158,7 +156,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFi
waveform->m_delay = static_cast<SIM_VALUE_FLOAT&>( *m_model.FindParam( "delay" )->value ).Get().value_or( 0 );
kparams.m_waveform = waveform;
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
kpin->writeSpiceDriver( &result, aItem.modelName, *kmodel, kparams );
break;
}
@ -172,7 +170,8 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFi
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType ) :
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR_KIBIS>( *this ) )
SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR_KIBIS>( *this ) ),
m_sourceModel( nullptr )
{
static std::vector<PARAM::INFO> device = makeParamInfos( TYPE::KIBIS_DEVICE );
static std::vector<PARAM::INFO> dcDriver = makeParamInfos( TYPE::KIBIS_DRIVER_DC );

View File

@ -37,13 +37,11 @@ class SPICE_GENERATOR_KIBIS : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelName( const std::string& aRefName,
const std::string& aBaseModelName ) const override;
std::string ModelLine( const std::string& aModelName ) const override;
std::vector<std::string> CurrentNames( const std::string& aRefName ) const override;
std::string ModelName( const SPICE_ITEM& aItem ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
std::string IbisDevice( const std::vector<SCH_FIELD>& aFields,
const std::string& aModelName ) const;
std::string IbisDevice( const SPICE_ITEM& aItem ) const;
protected:
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;

View File

@ -28,15 +28,15 @@
#include <fmt/core.h>
std::vector<std::string> SPICE_GENERATOR_NGSPICE::CurrentNames( const std::string& aRefName ) const
std::vector<std::string> SPICE_GENERATOR_NGSPICE::CurrentNames( const SPICE_ITEM& aItem ) const
{
switch( m_model.GetTypeInfo().deviceType )
{
case SIM_MODEL::DEVICE_TYPE_::NPN:
case SIM_MODEL::DEVICE_TYPE_::PNP:
return { fmt::format( "I({}:c)", aRefName ),
fmt::format( "I({}:b)", aRefName ),
fmt::format( "I({}:e)", aRefName ) };
return { fmt::format( "I({}:c)", aItem.refName ),
fmt::format( "I({}:b)", aItem.refName ),
fmt::format( "I({}:e)", aItem.refName ) };
case SIM_MODEL::DEVICE_TYPE_::NJFET:
case SIM_MODEL::DEVICE_TYPE_::PJFET:
@ -44,15 +44,15 @@ std::vector<std::string> SPICE_GENERATOR_NGSPICE::CurrentNames( const std::strin
case SIM_MODEL::DEVICE_TYPE_::PMES:
case SIM_MODEL::DEVICE_TYPE_::NMOS:
case SIM_MODEL::DEVICE_TYPE_::PMOS:
return { fmt::format( "I({}:d)", aRefName ),
fmt::format( "I({}:g)", aRefName ),
fmt::format( "I({}:s)", aRefName ) };
return { fmt::format( "I({}:d)", aItem.refName ),
fmt::format( "I({}:g)", aItem.refName ),
fmt::format( "I({}:s)", aItem.refName ) };
case SIM_MODEL::DEVICE_TYPE_::R:
case SIM_MODEL::DEVICE_TYPE_::C:
case SIM_MODEL::DEVICE_TYPE_::L:
case SIM_MODEL::DEVICE_TYPE_::D:
return SPICE_GENERATOR::CurrentNames( aRefName );
return SPICE_GENERATOR::CurrentNames( aItem );
default:
wxFAIL_MSG( "Unhandled model device type in SIM_MODEL_NGSPICE" );

View File

@ -34,7 +34,7 @@ class SPICE_GENERATOR_NGSPICE : public SPICE_GENERATOR_SPICE
public:
using SPICE_GENERATOR_SPICE::SPICE_GENERATOR_SPICE;
std::vector<std::string> CurrentNames( const std::string& aRefName ) const override;
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
};

View File

@ -39,40 +39,37 @@ namespace SIM_MODEL_RAW_SPICE_PARSER
}
std::string SPICE_GENERATOR_RAW_SPICE::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_RAW_SPICE::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
std::string SPICE_GENERATOR_RAW_SPICE::ItemName( const std::string& aRefName ) const
std::string SPICE_GENERATOR_RAW_SPICE::ItemName( const SPICE_ITEM& aItem ) const
{
std::string elementType = m_model.GetParam(
static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::TYPE ) ).value->ToString();
if( aRefName != "" && boost::starts_with( aRefName, elementType ) )
return aRefName;
if( aItem.refName != "" && boost::starts_with( aItem.refName, elementType ) )
return aItem.refName;
else
return elementType + aRefName;
return fmt::format( "{}{}", elementType, aItem.refName );
}
std::string SPICE_GENERATOR_RAW_SPICE::ItemPins( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR_RAW_SPICE::ItemPins( const SPICE_ITEM& aItem ) const
{
std::string result;
for( const SIM_MODEL::PIN& pin : GetPins() )
{
auto it = std::find( aSymbolPinNumbers.begin(), aSymbolPinNumbers.end(),
auto it = std::find( aItem.pinNumbers.begin(), aItem.pinNumbers.end(),
pin.symbolPinNumber );
if( it != aSymbolPinNumbers.end() )
if( it != aItem.pinNumbers.end() )
{
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
result.append( " " + aPinNetNames.at( symbolPinIndex ) );
long symbolPinIndex = std::distance( aItem.pinNumbers.begin(), it );
result.append( fmt::format( " {}", aItem.pinNetNames.at( symbolPinIndex ) ) );
}
}
@ -80,7 +77,7 @@ std::string SPICE_GENERATOR_RAW_SPICE::ItemPins( const std::string& aRefName,
}
std::string SPICE_GENERATOR_RAW_SPICE::ItemModelName( const std::string& aModelName ) const
std::string SPICE_GENERATOR_RAW_SPICE::ItemModelName( const SPICE_ITEM& aItem ) const
{
return "";
}
@ -100,18 +97,18 @@ std::string SPICE_GENERATOR_RAW_SPICE::ItemParams() const
}
std::string SPICE_GENERATOR_RAW_SPICE::Preview( const std::string& aModelName ) const
std::string SPICE_GENERATOR_RAW_SPICE::Preview( const SPICE_ITEM& aItem ) const
{
std::vector<std::string> pinNumbers;
std::vector<std::string> pinNetNames;
SPICE_ITEM item = aItem;
item.refName = "";
for( int i = 0; i < m_model.GetPinCount(); ++i )
{
pinNumbers.push_back( fmt::format( "{0}", i + 1 ) );
pinNetNames.push_back( fmt::format( "{0}", i + 1 ) );
item.pinNumbers.push_back( fmt::format( "{}", i + 1 ) );
item.pinNetNames.push_back( fmt::format( "{}", i + 1 ) );
}
return ItemLine( "", aModelName, pinNumbers, pinNetNames );
return ItemLine( item );
}

View File

@ -34,17 +34,14 @@ class SPICE_GENERATOR_RAW_SPICE : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::string ItemName( const std::string& aRefName ) const override;
std::string ItemPins( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const override;
std::string ItemModelName( const std::string& aModelName ) const override;
std::string ItemName( const SPICE_ITEM& aItem ) const override;
std::string ItemPins( const SPICE_ITEM& aItem ) const override;
std::string ItemModelName( const SPICE_ITEM& aItem ) const override;
std::string ItemParams() const override;
std::string Preview( const std::string& aModelName ) const override;
std::string Preview( const SPICE_ITEM& aItem ) const override;
};

View File

@ -39,24 +39,22 @@ namespace SIM_MODEL_SOURCE_PARSER
}
std::string SPICE_GENERATOR_SOURCE::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_SOURCE::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
std::string SPICE_GENERATOR_SOURCE::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR_SOURCE::ItemLine( const SPICE_ITEM& aItem ) const
{
std::string model;
SPICE_ITEM item = aItem;
item.modelName = "";
std::string ac = m_model.FindParam( "ac" )->value->ToSpiceString();
std::string ph = m_model.FindParam( "ph" )->value->ToSpiceString();
if( ac != "" )
model.append( fmt::format( "AC {} {} ", ac, ph ) );
item.modelName.append( fmt::format( "AC {} {} ", ac, ph ) );
if( m_model.GetSpiceInfo().inlineTypeString != "" )
{
@ -179,12 +177,12 @@ std::string SPICE_GENERATOR_SOURCE::ItemLine( const std::string& aRefName,
break;
}
model.append( fmt::format( "{}( {})", m_model.GetSpiceInfo().inlineTypeString, args ) );
item.modelName.append( fmt::format( "{}( {})", m_model.GetSpiceInfo().inlineTypeString, args ) );
}
else
model.append( m_model.GetParam( 0 ).value->ToSpiceString() );
item.modelName.append( m_model.GetParam( 0 ).value->ToSpiceString() );
return SPICE_GENERATOR::ItemLine( aRefName, model, aSymbolPinNumbers, aPinNetNames );
return SPICE_GENERATOR::ItemLine( item );
}

View File

@ -49,11 +49,8 @@ class SPICE_GENERATOR_SOURCE : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::string ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::string ItemLine( const SPICE_ITEM& aItem ) const override;
private:
std::string getParamValueString( const std::string& aParamName,

View File

@ -31,9 +31,9 @@
#include <boost/algorithm/string/trim.hpp>
std::string SPICE_GENERATOR_SPICE::Preview( const std::string& aModelName ) const
std::string SPICE_GENERATOR_SPICE::Preview( const SPICE_ITEM& aItem ) const
{
std::string spiceCode = ModelLine( aModelName );
std::string spiceCode = ModelLine( aItem );
if( spiceCode == "" )
spiceCode = static_cast<const SIM_MODEL_SPICE&>( m_model ).m_spiceCode;
@ -41,7 +41,9 @@ std::string SPICE_GENERATOR_SPICE::Preview( const std::string& aModelName ) cons
if( spiceCode == "" && m_model.GetBaseModel() )
spiceCode = static_cast<const SIM_MODEL_SPICE*>( m_model.GetBaseModel() )->m_spiceCode;
std::string itemLine = ItemLine( "", aModelName );
SPICE_ITEM item = aItem;
item.refName = "";
std::string itemLine = ItemLine( item );
if( spiceCode != "" )
spiceCode.append( "\n" );

View File

@ -37,7 +37,7 @@ class SPICE_GENERATOR_SPICE : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string Preview( const std::string& aModelName ) const override;
std::string Preview( const SPICE_ITEM& aItem ) const override;
};

View File

@ -48,18 +48,18 @@ namespace SIM_MODEL_SUBCKT_SPICE_PARSER
}
std::string SPICE_GENERATOR_SUBCKT::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_SUBCKT::ModelLine( const SPICE_ITEM& aItem ) const
{
return "";
}
std::vector<std::string> SPICE_GENERATOR_SUBCKT::CurrentNames( const std::string& aRefName ) const
std::vector<std::string> SPICE_GENERATOR_SUBCKT::CurrentNames( const SPICE_ITEM& aItem ) const
{
std::vector<std::string> currentNames;
for( const SIM_MODEL::PIN& pin : GetPins() )
currentNames.push_back( fmt::format( "I({:s}:{:s})", ItemName( aRefName ), pin.name ) );
currentNames.push_back( fmt::format( "I({}:{})", ItemName( aItem ), pin.name ) );
return currentNames;
}

View File

@ -34,8 +34,8 @@ class SPICE_GENERATOR_SUBCKT : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::vector<std::string> CurrentNames( const std::string& aRefName ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
};

View File

@ -26,10 +26,7 @@
#include <fmt/core.h>
std::string SPICE_GENERATOR_SWITCH::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR_SWITCH::ItemLine( const SPICE_ITEM& aItem ) const
{
std::string result;
@ -37,19 +34,20 @@ std::string SPICE_GENERATOR_SWITCH::ItemLine( const std::string& aRefName,
{
case SIM_MODEL::TYPE::SW_V:
{
result = SPICE_GENERATOR::ItemLine( aRefName, aModelName, aSymbolPinNumbers, aPinNetNames );
result = SPICE_GENERATOR::ItemLine( aItem );
break;
}
case SIM_MODEL::TYPE::SW_I:
{
std::string vsourceName = "V__" + aRefName;
std::string vsourceName = fmt::format( "V__{}", aItem.refName );
// Current switches measure input current through a voltage source.
result.append( fmt::format( "{0} {1} 0\n", aPinNetNames[0], aPinNetNames[1] ) );
result.append( SPICE_GENERATOR::ItemLine( aRefName, fmt::format( "{0} {1}",
vsourceName, aModelName ),
aSymbolPinNumbers, aPinNetNames ) );
result.append( fmt::format( "{0} {1} 0\n", aItem.pinNetNames[0], aItem.pinNetNames[1] ) );
SPICE_ITEM item = aItem;
item.modelName = fmt::format( "{0} {1}", vsourceName, aItem.modelName );
result.append( SPICE_GENERATOR::ItemLine( item ) );
break;
}

View File

@ -34,9 +34,7 @@ class SPICE_GENERATOR_SWITCH : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ItemLine( const std::string& aRefName, const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const override;
std::string ItemLine( const SPICE_ITEM& aItem ) const override;
std::string ItemParams() const override;
std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const override;
};

View File

@ -29,7 +29,7 @@
using PARAM = SIM_MODEL::PARAM;
std::string SPICE_GENERATOR_TLINE::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR_TLINE::ModelLine( const SPICE_ITEM& aItem ) const
{
std::string r, l, g, c, len;
@ -41,7 +41,7 @@ std::string SPICE_GENERATOR_TLINE::ModelLine( const std::string& aModelName ) co
auto td = static_cast<const SIM_VALUE_FLOAT&>( *m_model.FindParam( "td" )->value );
if( !z0.HasValue() || !td.HasValue() )
return fmt::format( ".model {} LTRA()\n", aModelName );
return fmt::format( ".model {} LTRA()\n", aItem.modelName );
r = SIM_VALUE_FLOAT( 0 ).ToSpiceString();
l = ( td * z0 ).ToSpiceString();
@ -65,7 +65,7 @@ std::string SPICE_GENERATOR_TLINE::ModelLine( const std::string& aModelName ) co
}
return fmt::format( ".model {} LTRA( r={} l={} g={} c={} len={} )\n",
aModelName, r, l, g, c, len );
aItem.modelName, r, l, g, c, len );
}

View File

@ -34,7 +34,7 @@ class SPICE_GENERATOR_TLINE : public SPICE_GENERATOR
public:
using SPICE_GENERATOR::SPICE_GENERATOR;
std::string ModelLine( const std::string& aModelName ) const override;
std::string ModelLine( const SPICE_ITEM& aItem ) const override;
};

View File

@ -897,7 +897,7 @@ void SIM_PLOT_FRAME::updateTuners()
const wxString& ref = (*it)->GetComponentName();
if( std::find_if( spiceItems.begin(), spiceItems.end(),
[&]( const NETLIST_EXPORTER_SPICE::ITEM& item )
[&]( const SPICE_ITEM& item )
{
return item.refName == ref;
}) == spiceItems.end() )

View File

@ -29,28 +29,27 @@
#include <fmt/core.h>
std::string SPICE_GENERATOR::ModelName( const std::string& aRefName,
const std::string& aBaseModelName ) const
std::string SPICE_GENERATOR::ModelName( const SPICE_ITEM& aItem ) const
{
if( aBaseModelName == "" )
return fmt::format( "__{}", aRefName );
if( aItem.baseModelName == "" )
return fmt::format( "__{}", aItem.refName );
// FIXME: This ModelLine() call is relatively expensive.
if( ModelLine( aBaseModelName ) != "" )
return fmt::format( "{}.{}", aRefName, aBaseModelName );
if( ModelLine( aItem ) != "" )
return fmt::format( "{}.{}", aItem.refName, aItem.baseModelName );
return aBaseModelName;
return aItem.baseModelName;
}
std::string SPICE_GENERATOR::ModelLine( const std::string& aModelName ) const
std::string SPICE_GENERATOR::ModelLine( const SPICE_ITEM& aItem ) const
{
if( !m_model.HasSpiceNonInstanceOverrides() && !m_model.requiresSpiceModelLine() )
return "";
std::string result = "";
result.append( fmt::format( ".model {} ", aModelName ) );
result.append( fmt::format( ".model {} ", aItem.modelName ) );
size_t indentLength = result.length();
result.append( fmt::format( "{}\n", m_model.GetSpiceInfo().modelType ) );
@ -75,76 +74,57 @@ std::string SPICE_GENERATOR::ModelLine( const std::string& aModelName ) const
}
std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const std::string& aModelName ) const
std::string SPICE_GENERATOR::ItemLine( const SPICE_ITEM& aItem ) const
{
// Use linear symbol pin numbers enumeration. Used in model preview.
SPICE_ITEM item = aItem;
std::vector<std::string> pinNumbers;
if( item.pinNumbers.empty() )
{
for( int i = 0; i < m_model.GetPinCount(); ++i )
item.pinNumbers.push_back( fmt::format( "{}", i + 1 ) );
}
for( int i = 0; i < m_model.GetPinCount(); ++i )
pinNumbers.push_back( fmt::format( "{}", i + 1 ) );
if( item.pinNetNames.empty() )
{
for( const SIM_MODEL::PIN& pin : GetPins() )
item.pinNetNames.push_back( pin.name );
}
return ItemLine( aRefName, aModelName, pinNumbers );
}
std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers ) const
{
std::vector<std::string> pinNetNames;
for( const SIM_MODEL::PIN& pin : GetPins() )
pinNetNames.push_back( pin.name );
return ItemLine( aRefName, aModelName, aSymbolPinNumbers, pinNetNames );
}
std::string SPICE_GENERATOR::ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
{
std::string result;
result.append( ItemName( aRefName ) );
result.append( ItemPins( aRefName, aModelName, aSymbolPinNumbers, aPinNetNames ) );
result.append( ItemModelName( aModelName ) );
result.append( ItemName( aItem ) );
result.append( ItemPins( aItem ) );
result.append( ItemModelName( aItem ) );
result.append( ItemParams() );
result.append( "\n" );
return result;
}
std::string SPICE_GENERATOR::ItemName( const std::string& aRefName ) const
std::string SPICE_GENERATOR::ItemName( const SPICE_ITEM& aItem ) const
{
if( aRefName != "" && boost::starts_with( aRefName, m_model.GetSpiceInfo().itemType ) )
return aRefName;
if( aItem.refName != "" && boost::starts_with( aItem.refName, m_model.GetSpiceInfo().itemType ) )
return aItem.refName;
else
return m_model.GetSpiceInfo().itemType + aRefName;
return fmt::format( "{}{}", m_model.GetSpiceInfo().itemType, aItem.refName );
}
std::string SPICE_GENERATOR::ItemPins( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const
std::string SPICE_GENERATOR::ItemPins( const SPICE_ITEM& aItem ) const
{
std::string result;
int ncCounter = 0;
for( const SIM_MODEL::PIN& pin : GetPins() )
{
auto it = std::find( aSymbolPinNumbers.begin(), aSymbolPinNumbers.end(),
auto it = std::find( aItem.pinNumbers.begin(), aItem.pinNumbers.end(),
pin.symbolPinNumber );
if( it == aSymbolPinNumbers.end() )
result.append( fmt::format( " NC-{}-{}", aRefName, ncCounter++ ) );
if( it == aItem.pinNumbers.end() )
result.append( fmt::format( " NC-{}-{}", aItem.refName, ncCounter++ ) );
else
{
long symbolPinIndex = std::distance( aSymbolPinNumbers.begin(), it );
result.append( " " + aPinNetNames.at( symbolPinIndex ) );
long symbolPinIndex = std::distance( aItem.pinNumbers.begin(), it );
result.append( fmt::format( " {}", aItem.pinNetNames.at( symbolPinIndex ) ) );
}
}
@ -152,9 +132,9 @@ std::string SPICE_GENERATOR::ItemPins( const std::string& aRefName,
}
std::string SPICE_GENERATOR::ItemModelName( const std::string& aModelName ) const
std::string SPICE_GENERATOR::ItemModelName( const SPICE_ITEM& aItem ) const
{
return " " + aModelName;
return fmt::format( " {}", aItem.modelName );
}
@ -176,24 +156,24 @@ std::string SPICE_GENERATOR::ItemParams() const
}
std::string SPICE_GENERATOR::TuningLine( const std::string& aSymbol ) const
std::string SPICE_GENERATOR::TuningLine( const SPICE_ITEM& aItem ) const
{
// TODO.
return "";
}
std::vector<std::string> SPICE_GENERATOR::CurrentNames( const std::string& aRefName ) const
std::vector<std::string> SPICE_GENERATOR::CurrentNames( const SPICE_ITEM& aItem ) const
{
return { fmt::format( "I({})", ItemName( aRefName ) ) };
return { fmt::format( "I({})", ItemName( aItem ) ) };
}
std::string SPICE_GENERATOR::Preview( const std::string& aModelName ) const
std::string SPICE_GENERATOR::Preview( const SPICE_ITEM& aItem ) const
{
std::string spiceCode = ModelLine( aModelName );
std::string spiceCode = ModelLine( aItem );
std::string itemLine = ItemLine( "", aModelName );
std::string itemLine = ItemLine( aItem );
if( spiceCode != "" )
spiceCode.append( "\n" );

View File

@ -27,39 +27,42 @@
#include <sim/sim_model.h>
class SCH_FIELD;
struct SPICE_ITEM
{
std::string refName;
std::vector<std::string> pinNumbers;
std::vector<std::string> pinNetNames;
std::string baseModelName;
std::string modelName;
const SIM_MODEL* model = nullptr;
const std::vector<SCH_FIELD>* fields = nullptr;
};
class SPICE_GENERATOR
{
public:
SPICE_GENERATOR( const SIM_MODEL& aModel ) : m_model( aModel ) {}
virtual ~SPICE_GENERATOR() = default;
virtual std::string ModelName( const std::string& aRefName,
const std::string& aBaseModelName ) const;
virtual std::string ModelLine( const std::string& aModelName ) const;
virtual std::string ModelName( const SPICE_ITEM& aItem ) const;
virtual std::string ModelLine( const SPICE_ITEM& aItem ) const;
std::string ItemLine( const std::string& aRefName,
const std::string& aModelName ) const;
std::string ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers ) const;
virtual std::string ItemLine( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const;
virtual std::string ItemName( const std::string& aRefName ) const;
virtual std::string ItemPins( const std::string& aRefName,
const std::string& aModelName,
const std::vector<std::string>& aSymbolPinNumbers,
const std::vector<std::string>& aPinNetNames ) const;
virtual std::string ItemModelName( const std::string& aModelName ) const;
virtual std::string ItemLine( const SPICE_ITEM& aItem ) const;
virtual std::string ItemName( const SPICE_ITEM& aItem ) const;
virtual std::string ItemPins( const SPICE_ITEM& aItem ) const;
virtual std::string ItemModelName( const SPICE_ITEM& aItem ) const;
virtual std::string ItemParams() const;
virtual std::string TuningLine( const std::string& aSymbol ) const;
virtual std::string TuningLine( const SPICE_ITEM& aItem ) const;
virtual std::vector<std::string> CurrentNames( const std::string& aRefName ) const;
virtual std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const;
virtual std::string Preview( const std::string& aModelName ) const;
virtual std::string Preview( const SPICE_ITEM& aItem ) const;
protected:
virtual std::vector<std::reference_wrapper<const SIM_MODEL::PIN>> GetPins() const

View File

@ -889,9 +889,10 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
SIM_LIB_MGR mgr( m_frame->Prj() );
SIM_MODEL& model = mgr.CreateModel( *symbol ).model;
auto ref = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
SPICE_ITEM spiceItem;
spiceItem.refName = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
std::vector<std::string> currentNames =
model.SpiceGenerator().CurrentNames( ref );
model.SpiceGenerator().CurrentNames( spiceItem );
if( currentNames.size() == 0 )
return true;