Sim: Use the new library manager class in Spice netlist exporter
Temporarily comment out IBIS processing.
This commit is contained in:
parent
0a620816a8
commit
b95f4ec6bb
|
@ -74,6 +74,13 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
|
|||
}
|
||||
|
||||
|
||||
NETLIST_EXPORTER_SPICE::NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) :
|
||||
NETLIST_EXPORTER_BASE( aSchematic ),
|
||||
m_libMgr( aSchematic->Prj() )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
FILE_OUTPUTFORMATTER formatter( aOutFileName, wxT( "wt" ), '\'' );
|
||||
|
@ -181,7 +188,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
ITEM spiceItem;
|
||||
|
||||
// @TODO This is to be removed once ngspice gets ibis support
|
||||
if( SIM_MODEL::GetFieldValue( &( symbol->GetFields() ), SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
/*if( SIM_MODEL::GetFieldValue( &( symbol->GetFields() ), SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
== "IBIS" )
|
||||
{
|
||||
if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
|
||||
|
@ -433,23 +440,26 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
|
||||
m_items.push_back( std::move( spiceItem ) );
|
||||
continue;
|
||||
}*/
|
||||
|
||||
try
|
||||
{
|
||||
if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
|
||||
return false;
|
||||
|
||||
readModel( *symbol, spiceItem );
|
||||
|
||||
readPinNumbers( *symbol, spiceItem );
|
||||
readPinNetNames( *symbol, spiceItem, ncCounter );
|
||||
|
||||
// TODO: transmission line handling?
|
||||
|
||||
m_items.push_back( std::move( spiceItem ) );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, e.What() );
|
||||
}
|
||||
|
||||
if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
|
||||
return false;
|
||||
|
||||
readLibraryField( *symbol, spiceItem );
|
||||
readNameField( *symbol, spiceItem );
|
||||
|
||||
if( !readModel( *symbol, spiceItem ) )
|
||||
continue;
|
||||
|
||||
readPinNumbers( *symbol, spiceItem );
|
||||
readPinNetNames( *symbol, spiceItem, ncCounter );
|
||||
|
||||
// TODO: transmission line handling?
|
||||
|
||||
m_items.push_back( std::move( spiceItem ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,7 +538,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|
|||
|
||||
try
|
||||
{
|
||||
m_libraries.try_emplace( path, SIM_LIBRARY::Create( path ) );
|
||||
m_libMgr.CreateLibrary( path );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
|
@ -545,72 +555,6 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
|
||||
std::string path;
|
||||
|
||||
if( field )
|
||||
path = std::string( field->GetShownText().ToUTF8() );
|
||||
|
||||
if( path == "" )
|
||||
return;
|
||||
|
||||
wxString absolutePath = m_schematic->Prj().AbsolutePath( path );
|
||||
|
||||
try
|
||||
{
|
||||
m_libraries.try_emplace( path, SIM_LIBRARY::Create( std::string( absolutePath.ToUTF8() ) ) );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, wxString::Format( "Failed reading model library '%s'.",
|
||||
absolutePath ),
|
||||
e.What() );
|
||||
}
|
||||
|
||||
aItem.libraryPath = path;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
if( m_libraries.count( aItem.libraryPath ) )
|
||||
{
|
||||
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::NAME_FIELD );
|
||||
|
||||
if( !field )
|
||||
return;
|
||||
|
||||
std::string modelName = std::string( field->GetShownText().ToUTF8() );
|
||||
const SIM_LIBRARY& library = *m_libraries.at( aItem.libraryPath );
|
||||
const SIM_MODEL* baseModel = library.FindModel( modelName );
|
||||
|
||||
if( baseModel )
|
||||
{
|
||||
try
|
||||
{
|
||||
aItem.model = SIM_MODEL::Create( *baseModel,
|
||||
m_sortedSymbolPinList.size(),
|
||||
aSymbol.GetFields() );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
DisplayErrorMessage( nullptr,
|
||||
wxString::Format( "Failed reading %s simulation model.", aItem.refName ),
|
||||
e.What() );
|
||||
return;
|
||||
}
|
||||
|
||||
aItem.modelName = modelName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
aItem.modelName = "__" + aItem.refName;
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
|
||||
ITEM& aItem,
|
||||
std::set<std::string>& aRefNames )
|
||||
|
@ -630,35 +574,20 @@ bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aS
|
|||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
void NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
if( !aItem.model.get() )
|
||||
{
|
||||
try
|
||||
{
|
||||
aItem.model = SIM_MODEL::Create(
|
||||
static_cast<int>( m_sortedSymbolPinList.size() ), aSymbol.GetFields() );
|
||||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
DisplayErrorMessage( nullptr,
|
||||
wxString::Format( _( "Failed reading %s simulation model." ), aItem.refName ),
|
||||
e.What() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto [modelName, model] = m_libMgr.CreateModel( aSymbol );
|
||||
aItem.modelName = ( modelName != "" ) ? modelName : ( "__" + aItem.refName );
|
||||
aItem.model = &model;
|
||||
|
||||
// Special case for legacy models.
|
||||
if( auto model = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model.get() ) )
|
||||
if( auto rawSpiceModel = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model ) )
|
||||
{
|
||||
unsigned libParamIndex = static_cast<unsigned>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
|
||||
std::string path = model->GetParam( libParamIndex ).value->ToString();
|
||||
int libParamIndex = static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
|
||||
std::string path = rawSpiceModel->GetParam( libParamIndex ).value->ToString();
|
||||
|
||||
if( path != "" )
|
||||
m_rawIncludes.insert( path );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -713,7 +642,7 @@ void NETLIST_EXPORTER_SPICE::writeInclude( OUTPUTFORMATTER& aFormatter, unsigned
|
|||
|
||||
void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
{
|
||||
for( auto&& [path, library] : m_libraries )
|
||||
for( auto&& [path, library] : m_libMgr.GetLibraries() )
|
||||
writeInclude( aFormatter, aNetlistOptions, path );
|
||||
|
||||
for( const std::string& path : m_rawIncludes )
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#define NETLIST_EXPORTER_SPICE_H
|
||||
|
||||
#include "netlist_exporter_base.h"
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_lib_mgr.h>
|
||||
#include <sim/sim_library.h>
|
||||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class NETLIST_EXPORTER_SPICE : public NETLIST_EXPORTER_BASE
|
||||
|
@ -53,11 +54,11 @@ public:
|
|||
std::string libraryPath;
|
||||
std::vector<std::string> pinNumbers;
|
||||
std::vector<std::string> pinNetNames;
|
||||
std::unique_ptr<const SIM_MODEL> model;
|
||||
const SIM_MODEL* model;
|
||||
std::string modelName;
|
||||
};
|
||||
|
||||
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) : NETLIST_EXPORTER_BASE( aSchematic ) {}
|
||||
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic );
|
||||
|
||||
/**
|
||||
* Write to specified output file.
|
||||
|
@ -128,12 +129,9 @@ protected:
|
|||
SCH_SHEET_LIST GetSheets( unsigned aNetlistOptions = 0 ) const;
|
||||
|
||||
private:
|
||||
void readLibraryField( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readEnabledField( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, ITEM& aItem,
|
||||
std::set<std::string>& aRefNames );
|
||||
bool readModel( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readModel( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem, int& aNcCounter );
|
||||
|
||||
|
@ -144,12 +142,13 @@ private:
|
|||
void writeModels( OUTPUTFORMATTER& aFormatter );
|
||||
void writeItems( OUTPUTFORMATTER& aFormatter );
|
||||
|
||||
SIM_LIB_MGR m_libMgr; ///< Holds libraries and models
|
||||
std::string m_title; ///< Spice simulation title found in the schematic sheet
|
||||
std::vector<std::string> m_directives; ///< Spice directives found in the schematic sheet
|
||||
std::map<std::string, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
|
||||
//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<ITEM> m_items; ///< Items representing schematic symbols in Spice world
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <sim/sim_library.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <pgm_base.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj )
|
||||
|
@ -34,10 +35,11 @@ SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj )
|
|||
}
|
||||
|
||||
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
||||
std::pair<std::string, SIM_MODEL&> SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
||||
{
|
||||
std::vector<LIB_PIN*> pins = aSymbol.GetLibPins();
|
||||
SCH_FIELD* libraryField = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
|
||||
std::string baseModelName;
|
||||
|
||||
if( libraryField )
|
||||
{
|
||||
|
@ -54,7 +56,7 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
|||
catch( const IO_ERROR& e )
|
||||
{
|
||||
THROW_IO_ERROR(
|
||||
wxString::Format( _( "Error loading simulation model library '%s'.\n%s" ),
|
||||
wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
||||
absolutePath,
|
||||
e.What() ) );
|
||||
}
|
||||
|
@ -67,7 +69,7 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
|||
SIM_LIBRARY::NAME_FIELD ) );
|
||||
}
|
||||
|
||||
std::string baseModelName = std::string( nameField->GetShownText().ToUTF8() );
|
||||
baseModelName = std::string( nameField->GetShownText().ToUTF8() );
|
||||
SIM_MODEL* baseModel = library->FindModel( baseModelName );
|
||||
|
||||
if( !baseModel )
|
||||
|
@ -88,5 +90,23 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( SCH_SYMBOL& aSymbol )
|
|||
aSymbol.GetFields() ) );
|
||||
}
|
||||
|
||||
return *m_models.back();
|
||||
return std::pair<std::string, SIM_MODEL&>( baseModelName, *m_models.back() );
|
||||
}
|
||||
|
||||
|
||||
SIM_LIBRARY& SIM_LIB_MGR::CreateLibrary( const std::string& aLibraryPath )
|
||||
{
|
||||
auto it = m_libraries.try_emplace( aLibraryPath, SIM_LIBRARY::Create( aLibraryPath ) ).first;
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> SIM_LIB_MGR::GetLibraries() const
|
||||
{
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> result;
|
||||
|
||||
for( auto&& [path, library] : m_libraries )
|
||||
result.try_emplace( path, *library );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -40,10 +40,14 @@ class SIM_LIB_MGR
|
|||
{
|
||||
public:
|
||||
SIM_LIB_MGR( const PROJECT& aPrj );
|
||||
virtual ~SIM_LIB_MGR() = default;
|
||||
|
||||
// TODO: The argument can be made const.
|
||||
SIM_MODEL& CreateModel( SCH_SYMBOL& aSymbol );
|
||||
std::pair<std::string, SIM_MODEL&> CreateModel( SCH_SYMBOL& aSymbol );
|
||||
|
||||
SIM_LIBRARY& CreateLibrary( const std::string& aLibraryPath );
|
||||
|
||||
std::map<std::string, std::reference_wrapper<const SIM_LIBRARY>> GetLibraries() const;
|
||||
|
||||
private:
|
||||
const PROJECT& m_project;
|
||||
|
|
|
@ -880,32 +880,39 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
{
|
||||
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
||||
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
||||
|
||||
SIM_LIB_MGR mgr( m_frame->Prj() );
|
||||
SIM_MODEL& model = mgr.CreateModel( *symbol );
|
||||
|
||||
auto ref = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
|
||||
std::vector<std::string> currentNames =
|
||||
model.SpiceGenerator().CurrentNames( ref );
|
||||
|
||||
if( currentNames.size() == 0 )
|
||||
return true;
|
||||
else if( currentNames.size() == 1 )
|
||||
try
|
||||
{
|
||||
simFrame->AddCurrentPlot( currentNames.at( 0 ) );
|
||||
return true;
|
||||
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
||||
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
||||
|
||||
SIM_LIB_MGR mgr( m_frame->Prj() );
|
||||
SIM_MODEL& model = mgr.CreateModel( *symbol ).second;
|
||||
|
||||
auto ref = std::string( symbol->GetRef( &m_frame->GetCurrentSheet() ).ToUTF8() );
|
||||
std::vector<std::string> currentNames =
|
||||
model.SpiceGenerator().CurrentNames( ref );
|
||||
|
||||
if( currentNames.size() == 0 )
|
||||
return true;
|
||||
else if( currentNames.size() == 1 )
|
||||
{
|
||||
simFrame->AddCurrentPlot( currentNames.at( 0 ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
int modelPinIndex =
|
||||
model.FindModelPinIndex( std::string( pin->GetNumber().ToUTF8() ) );
|
||||
|
||||
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
{
|
||||
wxString name = currentNames.at( modelPinIndex );
|
||||
simFrame->AddCurrentPlot( name );
|
||||
}
|
||||
}
|
||||
|
||||
int modelPinIndex =
|
||||
model.FindModelPinIndex( std::string( pin->GetNumber().ToUTF8() ) );
|
||||
|
||||
if( modelPinIndex != SIM_MODEL::PIN::NOT_CONNECTED )
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
wxString name = currentNames.at( modelPinIndex );
|
||||
simFrame->AddCurrentPlot( name );
|
||||
DisplayErrorMessage( m_frame, e.What() );
|
||||
}
|
||||
}
|
||||
else if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T } ) )
|
||||
|
|
Loading…
Reference in New Issue