Add a new schematic exporter to Spice .subckt model
An option to use the current sheet as root is added to both the original and new (.subckt model) exporters.
This commit is contained in:
parent
aeb429b088
commit
300a1c4144
|
@ -259,6 +259,7 @@ set( EESCHEMA_SRCS
|
|||
netlist_exporters/netlist_exporter_kicad.cpp
|
||||
netlist_exporters/netlist_exporter_orcadpcb2.cpp
|
||||
netlist_exporters/netlist_exporter_spice.cpp
|
||||
netlist_exporters/netlist_exporter_spice_model.cpp
|
||||
netlist_exporters/netlist_exporter_xml.cpp
|
||||
netlist_exporters/netlist_generator.cpp
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ enum panel_netlist_index {
|
|||
PANELPCBNEW = 0, /* Handle Netlist format Pcbnew */
|
||||
PANELORCADPCB2, /* Handle Netlist format OracdPcb2 */
|
||||
PANELCADSTAR, /* Handle Netlist format CadStar */
|
||||
PANELSPICE, /* Handle Netlist format Pspice */
|
||||
PANELSPICE, /* Handle Netlist format Spice */
|
||||
PANELSPICEMODEL, /* Handle Netlist format Spice Model (subcircuit) */
|
||||
PANELCUSTOMBASE /* First auxiliary panel (custom netlists).
|
||||
* others use PANELCUSTOMBASE+1, PANELCUSTOMBASE+2.. */
|
||||
};
|
||||
|
@ -94,6 +95,7 @@ public:
|
|||
|
||||
NETLIST_TYPE_ID m_IdNetType;
|
||||
// opt to reformat passive component values (e.g. 1M -> 1Meg):
|
||||
wxCheckBox* m_CurSheetAsRoot;
|
||||
wxCheckBox* m_SaveAllVoltages;
|
||||
wxCheckBox* m_SaveAllCurrents;
|
||||
wxTextCtrl* m_CommandStringCtrl;
|
||||
|
@ -127,6 +129,8 @@ private:
|
|||
const wxString & aCommandString,
|
||||
NETLIST_TYPE_ID aNetTypeId );
|
||||
void InstallPageSpice();
|
||||
void InstallPageSpiceModel();
|
||||
|
||||
bool TransferDataFromWindow() override;
|
||||
void NetlistUpdateOpt();
|
||||
|
||||
|
@ -175,7 +179,7 @@ private:
|
|||
|
||||
public:
|
||||
SCH_EDIT_FRAME* m_Parent;
|
||||
NETLIST_PAGE_DIALOG* m_PanelNetType[4 + CUSTOMPANEL_COUNTMAX];
|
||||
NETLIST_PAGE_DIALOG* m_PanelNetType[5 + CUSTOMPANEL_COUNTMAX];
|
||||
};
|
||||
|
||||
|
||||
|
@ -202,6 +206,7 @@ private:
|
|||
/* Event id for notebook page buttons: */
|
||||
enum id_netlist {
|
||||
ID_CREATE_NETLIST = ID_END_EESCHEMA_ID_LIST + 1,
|
||||
ID_CUR_SHEET_AS_ROOT,
|
||||
ID_SAVE_ALL_VOLTAGES,
|
||||
ID_SAVE_ALL_CURRENTS,
|
||||
ID_RUN_SIMULATOR
|
||||
|
@ -265,6 +270,7 @@ NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) :
|
|||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "CadStar" ), NET_TYPE_CADSTAR, false );
|
||||
|
||||
InstallPageSpice();
|
||||
InstallPageSpiceModel();
|
||||
InstallCustomPages();
|
||||
|
||||
SetupStandardButtons( { { wxID_OK, _( "Export Netlist" ) },
|
||||
|
@ -334,21 +340,27 @@ void NETLIST_DIALOG::OnRunSpiceButtUI( wxUpdateUIEvent& aEvent )
|
|||
void NETLIST_DIALOG::InstallPageSpice()
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* page = m_PanelNetType[PANELSPICE] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE, false );
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice" ), NET_TYPE_SPICE, false );
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
page->m_CurSheetAsRoot = new wxCheckBox( page, ID_CUR_SHEET_AS_ROOT,
|
||||
_( "Use current sheet as root" ) );
|
||||
page->m_CurSheetAsRoot->SetToolTip( _( "Export netlist only for the current sheet" ) );
|
||||
page->m_CurSheetAsRoot->SetValue( settings.m_SpiceCurSheetAsRoot );
|
||||
page->m_LeftBoxSizer->Add( page->m_CurSheetAsRoot, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
|
||||
|
||||
page->m_SaveAllVoltages = new wxCheckBox( page, ID_SAVE_ALL_VOLTAGES,
|
||||
_( "Save all voltages" ) );
|
||||
page->m_SaveAllVoltages->SetToolTip( _( "Write a directive to save all voltages (.save all)" ) );
|
||||
page->m_SaveAllVoltages->SetValue( settings.m_SpiceSaveAllVoltages );
|
||||
page->m_LeftBoxSizer->Add( page->m_SaveAllVoltages, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
|
||||
page->m_RightBoxSizer->Add( page->m_SaveAllVoltages, 0, wxBOTTOM | wxRIGHT, 5 );
|
||||
|
||||
page->m_SaveAllCurrents = new wxCheckBox( page, ID_SAVE_ALL_CURRENTS,
|
||||
_( "Save all currents" ) );
|
||||
page->m_SaveAllCurrents->SetToolTip( _( "Write a directive to save all currents (.probe alli)" ) );
|
||||
page->m_SaveAllCurrents->SetValue( settings.m_SpiceSaveAllCurrents );
|
||||
page->m_RightBoxSizer->Add( page->m_SaveAllCurrents, 0, wxGROW | wxBOTTOM | wxLEFT, 5 );
|
||||
page->m_RightBoxSizer->Add( page->m_SaveAllCurrents, 0, wxBOTTOM | wxRIGHT, 5 );
|
||||
|
||||
|
||||
wxString simulatorCommand = settings.m_SpiceCommandString;
|
||||
|
@ -372,6 +384,21 @@ void NETLIST_DIALOG::InstallPageSpice()
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_DIALOG::InstallPageSpiceModel()
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* page = m_PanelNetType[PANELSPICEMODEL] =
|
||||
new NETLIST_PAGE_DIALOG( m_NoteBook, wxT( "Spice Model" ), NET_TYPE_SPICE_MODEL, false );
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
page->m_CurSheetAsRoot = new wxCheckBox( page, ID_CUR_SHEET_AS_ROOT,
|
||||
_( "Use current sheet as root" ) );
|
||||
page->m_CurSheetAsRoot->SetToolTip( _( "Export netlist only for the current sheet" ) );
|
||||
page->m_CurSheetAsRoot->SetValue( settings.m_SpiceModelCurSheetAsRoot );
|
||||
page->m_LeftBoxSizer->Add( page->m_CurSheetAsRoot, 0, wxGROW | wxBOTTOM | wxRIGHT, 5 );
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_DIALOG::InstallCustomPages()
|
||||
{
|
||||
NETLIST_PAGE_DIALOG* currPage;
|
||||
|
@ -440,16 +467,20 @@ void NETLIST_DIALOG::OnNetlistTypeSelection( wxNotebookEvent& event )
|
|||
|
||||
void NETLIST_DIALOG::NetlistUpdateOpt()
|
||||
{
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
wxString spice_cmd_string = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
|
||||
bool saveAllVoltages = m_PanelNetType[ PANELSPICE ]->m_SaveAllVoltages->IsChecked();
|
||||
bool saveAllCurrents = m_PanelNetType[ PANELSPICE ]->m_SaveAllCurrents->IsChecked();
|
||||
wxString spiceCmdString = m_PanelNetType[ PANELSPICE ]->m_CommandStringCtrl->GetValue();
|
||||
bool curSheetAsRoot = m_PanelNetType[ PANELSPICE ]->m_CurSheetAsRoot->GetValue();
|
||||
bool spiceModelCurSheetAsRoot = m_PanelNetType[ PANELSPICEMODEL ]->m_CurSheetAsRoot->GetValue();
|
||||
|
||||
SCHEMATIC_SETTINGS& settings = m_Parent->Schematic().Settings();
|
||||
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spice_cmd_string;
|
||||
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
settings.m_SpiceSaveAllVoltages = saveAllVoltages;
|
||||
settings.m_SpiceSaveAllCurrents = saveAllCurrents;
|
||||
settings.m_SpiceCommandString = spiceCmdString;
|
||||
settings.m_SpiceCurSheetAsRoot = curSheetAsRoot;
|
||||
settings.m_SpiceModelCurSheetAsRoot = spiceModelCurSheetAsRoot;
|
||||
settings.m_NetFormatName = m_PanelNetType[m_NoteBook->GetSelection()]->GetPageNetFmtName();
|
||||
}
|
||||
|
||||
|
||||
|
@ -480,6 +511,13 @@ bool NETLIST_DIALOG::TransferDataFromWindow()
|
|||
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES;
|
||||
if( currPage->m_SaveAllCurrents->GetValue() )
|
||||
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS;
|
||||
if( currPage->m_CurSheetAsRoot->GetValue() )
|
||||
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_CUR_SHEET_AS_ROOT;
|
||||
break;
|
||||
|
||||
case NET_TYPE_SPICE_MODEL:
|
||||
if( currPage->m_CurSheetAsRoot->GetValue() )
|
||||
netlist_opt |= NETLIST_EXPORTER_SPICE::OPTION_CUR_SHEET_AS_ROOT;
|
||||
break;
|
||||
|
||||
case NET_TYPE_CADSTAR:
|
||||
|
|
|
@ -611,7 +611,7 @@ void DIALOG_SIM_SETTINGS::loadDirectives()
|
|||
|
||||
void DIALOG_SIM_SETTINGS::updateNetlistOpts()
|
||||
{
|
||||
m_netlistOpts = NETLIST_EXPORTER_SPICE::OPTION_ALL_FLAGS;
|
||||
m_netlistOpts = NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS;
|
||||
|
||||
if( !m_fixPassiveVals->IsChecked() )
|
||||
m_netlistOpts &= ~NETLIST_EXPORTER_SPICE::OPTION_ADJUST_PASSIVE_VALS;
|
||||
|
|
|
@ -39,6 +39,7 @@ enum NETLIST_TYPE_ID {
|
|||
NET_TYPE_ORCADPCB2,
|
||||
NET_TYPE_CADSTAR,
|
||||
NET_TYPE_SPICE,
|
||||
NET_TYPE_SPICE_MODEL,
|
||||
NET_TYPE_CUSTOM1, /* NET_TYPE_CUSTOM1
|
||||
* is the first id for user netlist format
|
||||
* NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1
|
||||
|
|
|
@ -68,11 +68,11 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
|
|||
bool NETLIST_EXPORTER_SPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
FILE_OUTPUTFORMATTER formatter( aOutFileName, wxT( "wt" ), '\'' );
|
||||
return GenerateNetlist( formatter, aNetlistOptions );
|
||||
return DoWriteNetlist( formatter, aNetlistOptions );
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
bool NETLIST_EXPORTER_SPICE::DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
{
|
||||
LOCALE_IO dummy;
|
||||
|
||||
|
@ -85,34 +85,44 @@ bool NETLIST_EXPORTER_SPICE::GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsig
|
|||
if( !ReadSchematicAndLibraries( aNetlistOptions ) )
|
||||
return false;
|
||||
|
||||
aFormatter.Print( 0, ".title %s\n", TO_UTF8( m_title ) );
|
||||
WriteHead( aFormatter, aNetlistOptions );
|
||||
|
||||
writeIncludes( aFormatter, aNetlistOptions );
|
||||
writeModels( aFormatter );
|
||||
WriteDirectives( aFormatter, aNetlistOptions );
|
||||
writeItems( aFormatter );
|
||||
|
||||
aFormatter.Print( 0, ".end\n" );
|
||||
WriteTail( aFormatter, aNetlistOptions );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
{
|
||||
aFormatter.Print( 0, ".title %s\n", TO_UTF8( m_title ) );
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::WriteTail( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions )
|
||||
{
|
||||
aFormatter.Print( 0, ".end\n" );
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions )
|
||||
{
|
||||
std::set<wxString> refNames; // Set of reference names to check for duplication.
|
||||
int NCCounter = 1;
|
||||
int ncCounter = 1;
|
||||
|
||||
ReadDirectives();
|
||||
ReadDirectives( aNetlistOptions );
|
||||
|
||||
m_nets.clear();
|
||||
m_items.clear();
|
||||
m_libParts.clear();
|
||||
|
||||
for( unsigned sheetIndex = 0; sheetIndex < m_schematic->GetSheets().size(); ++sheetIndex )
|
||||
for( SCH_SHEET_PATH& sheet : GetSheets( aNetlistOptions ) )
|
||||
{
|
||||
SCH_SHEET_PATH sheet = m_schematic->GetSheets().at( sheetIndex );
|
||||
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = findNextSymbol( item, &sheet );
|
||||
|
@ -122,7 +132,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
|
||||
CreatePinList( symbol, &sheet, true );
|
||||
|
||||
SPICE_ITEM spiceItem;
|
||||
ITEM spiceItem;
|
||||
|
||||
if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
|
||||
return false;
|
||||
|
@ -134,7 +144,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
continue;
|
||||
|
||||
readPinNumbers( *symbol, spiceItem );
|
||||
readPinNetNames( *symbol, spiceItem, NCCounter );
|
||||
readPinNetNames( *symbol, spiceItem, ncCounter );
|
||||
|
||||
// TODO: transmission line handling?
|
||||
|
||||
|
@ -156,10 +166,10 @@ void NETLIST_EXPORTER_SPICE::ReplaceForbiddenChars( wxString& aNetName )
|
|||
|
||||
wxString NETLIST_EXPORTER_SPICE::GetItemName( const wxString& aRefName ) const
|
||||
{
|
||||
const std::list<SPICE_ITEM>& spiceItems = GetItems();
|
||||
const std::list<ITEM>& spiceItems = GetItems();
|
||||
|
||||
auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
|
||||
[aRefName]( const SPICE_ITEM& aItem )
|
||||
[aRefName]( const ITEM& aItem )
|
||||
{
|
||||
return aItem.refName == aRefName;
|
||||
} );
|
||||
|
@ -171,13 +181,13 @@ wxString NETLIST_EXPORTER_SPICE::GetItemName( const wxString& aRefName ) const
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::ReadDirectives()
|
||||
void NETLIST_EXPORTER_SPICE::ReadDirectives( unsigned aNetlistOptions )
|
||||
{
|
||||
m_directives.clear();
|
||||
|
||||
for( unsigned int sheetIndex = 0; sheetIndex < m_schematic->GetSheets().size(); ++sheetIndex )
|
||||
for( const SCH_SHEET_PATH& sheet : GetSheets( aNetlistOptions ) )
|
||||
{
|
||||
for( SCH_ITEM* item : m_schematic->GetSheets().at( sheetIndex ).LastScreen()->Items() )
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
|
||||
{
|
||||
wxString text;
|
||||
|
||||
|
@ -233,7 +243,7 @@ void NETLIST_EXPORTER_SPICE::ReadDirectives()
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||
void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
SCH_FIELD* field = aSymbol.FindField( SIM_LIBRARY::LIBRARY_FIELD );
|
||||
wxString path;
|
||||
|
@ -261,7 +271,7 @@ void NETLIST_EXPORTER_SPICE::readLibraryField( SCH_SYMBOL& aSymbol, SPICE_ITEM&
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||
void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
if( m_libraries.count( aItem.libraryPath ) )
|
||||
{
|
||||
|
@ -300,7 +310,7 @@ void NETLIST_EXPORTER_SPICE::readNameField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aIt
|
|||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol,
|
||||
SPICE_ITEM& aItem,
|
||||
ITEM& aItem,
|
||||
std::set<wxString>& aRefNames )
|
||||
{
|
||||
aItem.refName = aSymbol.GetRef( &aSheet );
|
||||
|
@ -318,7 +328,7 @@ bool NETLIST_EXPORTER_SPICE::readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aS
|
|||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||
bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
if( !aItem.model.get() )
|
||||
{
|
||||
|
@ -350,24 +360,19 @@ bool NETLIST_EXPORTER_SPICE::readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem )
|
||||
void NETLIST_EXPORTER_SPICE::readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem )
|
||||
{
|
||||
for( const PIN_INFO& pin : m_sortedSymbolPinList )
|
||||
aItem.pinNumbers.push_back( pin.num );
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
||||
int& aNCCounter )
|
||||
void NETLIST_EXPORTER_SPICE::readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem,
|
||||
int& aNcCounter )
|
||||
{
|
||||
for( const PIN_INFO& pinInfo : m_sortedSymbolPinList )
|
||||
{
|
||||
wxString netName = pinInfo.netName;
|
||||
ReplaceForbiddenChars( netName );
|
||||
netName = UnescapeString( netName );
|
||||
|
||||
if( netName == "" )
|
||||
netName = wxString::Format( wxT( "NC-%u" ), aNCCounter++ );
|
||||
wxString netName = GenerateItemPinNetName( pinInfo.netName, aNcCounter );
|
||||
|
||||
aItem.pinNetNames.push_back( netName );
|
||||
m_nets.insert( netName );
|
||||
|
@ -415,7 +420,7 @@ void NETLIST_EXPORTER_SPICE::writeIncludes( OUTPUTFORMATTER& aFormatter, unsigne
|
|||
|
||||
void NETLIST_EXPORTER_SPICE::writeModels( OUTPUTFORMATTER& aFormatter )
|
||||
{
|
||||
for( const SPICE_ITEM& item : m_items )
|
||||
for( const ITEM& item : m_items )
|
||||
{
|
||||
if( !item.model->IsEnabled() )
|
||||
continue;
|
||||
|
@ -427,7 +432,7 @@ void NETLIST_EXPORTER_SPICE::writeModels( OUTPUTFORMATTER& aFormatter )
|
|||
|
||||
void NETLIST_EXPORTER_SPICE::writeItems( OUTPUTFORMATTER& aFormatter )
|
||||
{
|
||||
for( const SPICE_ITEM& item : m_items )
|
||||
for( const ITEM& item : m_items )
|
||||
{
|
||||
if( !item.model->IsEnabled() )
|
||||
continue;
|
||||
|
@ -453,3 +458,28 @@ void NETLIST_EXPORTER_SPICE::WriteDirectives( OUTPUTFORMATTER& aFormatter,
|
|||
for( const wxString& directive : m_directives )
|
||||
aFormatter.Print( 0, "%s\n", TO_UTF8( directive ) );
|
||||
}
|
||||
|
||||
|
||||
wxString NETLIST_EXPORTER_SPICE::GenerateItemPinNetName( const wxString& aNetName,
|
||||
int& aNcCounter ) const
|
||||
{
|
||||
wxString netName = aNetName;
|
||||
|
||||
ReplaceForbiddenChars( netName );
|
||||
netName = UnescapeString( netName );
|
||||
|
||||
if( netName == "" )
|
||||
netName = wxString::Format( wxT( "NC-%u" ), aNcCounter++ );
|
||||
|
||||
return netName;
|
||||
}
|
||||
|
||||
|
||||
SCH_SHEET_LIST NETLIST_EXPORTER_SPICE::GetSheets( unsigned aNetlistOptions ) const
|
||||
{
|
||||
if( aNetlistOptions & OPTION_CUR_SHEET_AS_ROOT )
|
||||
return SCH_SHEET_LIST( m_schematic->CurrentSheet().at( 0 ) );
|
||||
else
|
||||
return m_schematic->GetSheets();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,35 +23,38 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef NETLIST_EXPORTER_PSPICE_H
|
||||
#define NETLIST_EXPORTER_PSPICE_H
|
||||
#ifndef NETLIST_EXPORTER_SPICE_H
|
||||
#define NETLIST_EXPORTER_SPICE_H
|
||||
|
||||
#include "netlist_exporter_base.h"
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_library.h>
|
||||
|
||||
|
||||
struct SPICE_ITEM
|
||||
{
|
||||
wxString refName;
|
||||
wxString libraryPath;
|
||||
std::vector<wxString> pinNumbers;
|
||||
std::vector<wxString> pinNetNames;
|
||||
std::unique_ptr<const SIM_MODEL> model;
|
||||
wxString modelName;
|
||||
};
|
||||
|
||||
|
||||
class NETLIST_EXPORTER_SPICE : public NETLIST_EXPORTER_BASE
|
||||
{
|
||||
public:
|
||||
enum OPTIONS
|
||||
{
|
||||
OPTION_ADJUST_INCLUDE_PATHS = 8,
|
||||
OPTION_ADJUST_PASSIVE_VALS = 16,
|
||||
OPTION_SAVE_ALL_VOLTAGES = 16,
|
||||
OPTION_SAVE_ALL_CURRENTS = 32,
|
||||
OPTION_ALL_FLAGS = 0xFFFF
|
||||
OPTION_ADJUST_INCLUDE_PATHS = 0x10,
|
||||
OPTION_ADJUST_PASSIVE_VALS = 0x20,
|
||||
OPTION_SAVE_ALL_VOLTAGES = 0x40,
|
||||
OPTION_SAVE_ALL_CURRENTS = 0x80,
|
||||
OPTION_CUR_SHEET_AS_ROOT = 0x0100,
|
||||
OPTION_DEFAULT_FLAGS = OPTION_ADJUST_INCLUDE_PATHS
|
||||
| OPTION_ADJUST_PASSIVE_VALS
|
||||
| OPTION_SAVE_ALL_VOLTAGES
|
||||
| OPTION_SAVE_ALL_CURRENTS
|
||||
};
|
||||
|
||||
struct ITEM
|
||||
{
|
||||
wxString refName;
|
||||
wxString libraryPath;
|
||||
std::vector<wxString> pinNumbers;
|
||||
std::vector<wxString> pinNetNames;
|
||||
std::unique_ptr<const SIM_MODEL> model;
|
||||
wxString modelName;
|
||||
};
|
||||
|
||||
NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) : NETLIST_EXPORTER_BASE( aSchematic ) {}
|
||||
|
@ -62,9 +65,19 @@ public:
|
|||
bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ) override;
|
||||
|
||||
/**
|
||||
* Generate the netlist in aFormatter.
|
||||
* Write the netlist in aFormatter.
|
||||
*/
|
||||
bool GenerateNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
|
||||
bool DoWriteNetlist( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
|
||||
|
||||
/**
|
||||
* Write the netlist head (title and so on).
|
||||
*/
|
||||
virtual void WriteHead( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
|
||||
|
||||
/**
|
||||
* Write the tail (.end).
|
||||
*/
|
||||
virtual void WriteTail( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions );
|
||||
|
||||
/**
|
||||
* Process the schematic and Spice libraries to create net mapping and a list of SPICE_ITEMs.
|
||||
|
@ -72,7 +85,7 @@ public:
|
|||
* if only net mapping and the list of SPICE_ITEMs are required.
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool ReadSchematicAndLibraries( unsigned aNetlistOptions );
|
||||
virtual bool ReadSchematicAndLibraries( unsigned aNetlistOptions );
|
||||
|
||||
/**
|
||||
* Replace illegal spice net name characters with underscores.
|
||||
|
@ -82,7 +95,8 @@ public:
|
|||
/**
|
||||
* Return the list of nets.
|
||||
*/
|
||||
const std::set<wxString>& GetNets() const { return m_nets; }
|
||||
std::set<wxString> GetNets() const { return m_nets; }
|
||||
|
||||
|
||||
/**
|
||||
* Return name of Spice device corresponding to a schematic symbol.
|
||||
|
@ -98,23 +112,30 @@ public:
|
|||
/**
|
||||
* Return the list of items representing schematic components in the Spice world.
|
||||
*/
|
||||
const std::list<SPICE_ITEM>& GetItems() const { return m_items; }
|
||||
const std::list<ITEM>& GetItems() const { return m_items; }
|
||||
|
||||
const std::vector<wxString>& GetDirectives() { return m_directives; }
|
||||
|
||||
protected:
|
||||
void ReadDirectives();
|
||||
void ReadDirectives( unsigned aNetlistOptions = 0 );
|
||||
virtual void WriteDirectives( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions ) const;
|
||||
|
||||
virtual wxString GenerateItemPinNetName( const wxString& aNetName, int& aNcCounter ) const;
|
||||
|
||||
/**
|
||||
* Return the paths of exported sheets (either all or the current one).
|
||||
*/
|
||||
SCH_SHEET_LIST GetSheets( unsigned aNetlistOptions = 0 ) const;
|
||||
|
||||
private:
|
||||
void readLibraryField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||
void readNameField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||
void readEnabledField( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||
bool readRefName( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem,
|
||||
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<wxString>& aRefNames );
|
||||
bool readModel( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||
void readPinNumbers( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem );
|
||||
void readPinNetNames( SCH_SYMBOL& aSymbol, SPICE_ITEM& aItem, int& aNCCounter );
|
||||
bool readModel( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readPinNumbers( SCH_SYMBOL& aSymbol, ITEM& aItem );
|
||||
void readPinNetNames( SCH_SYMBOL& aSymbol, ITEM& aItem, int& aNcCounter );
|
||||
|
||||
void writeInclude( OUTPUTFORMATTER& aFormatter, unsigned aNetlistOptions,
|
||||
const wxString& aPath );
|
||||
|
@ -123,13 +144,13 @@ private:
|
|||
void writeModels( OUTPUTFORMATTER& aFormatter );
|
||||
void writeItems( OUTPUTFORMATTER& aFormatter );
|
||||
|
||||
wxString m_title; ///< Spice simulation title found in the schematic sheet
|
||||
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet
|
||||
wxString m_title; ///< Spice simulation title found in the schematic sheet
|
||||
std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet
|
||||
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries; ///< Spice libraries
|
||||
std::set<wxString> m_rawIncludes; ///< include directives found in symbols
|
||||
std::set<wxString> m_nets;
|
||||
std::list<SPICE_ITEM> m_items; ///< Items representing schematic symbols in Spice world
|
||||
std::set<wxString> m_rawIncludes; ///< include directives found in symbols
|
||||
std::set<wxString> m_nets;
|
||||
std::list<ITEM> m_items; ///< Items representing schematic symbols in Spice world
|
||||
};
|
||||
|
||||
|
||||
#endif // NETLIST_EXPORTER_PSPICE_H
|
||||
#endif // NETLIST_EXPORTER_SPICE_H
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <netlist_exporter_orcadpcb2.h>
|
||||
#include <netlist_exporter_cadstar.h>
|
||||
#include <netlist_exporter_spice.h>
|
||||
#include <netlist_exporter_spice_model.h>
|
||||
#include <netlist_exporter_kicad.h>
|
||||
#include <netlist_exporter_xml.h>
|
||||
|
||||
|
@ -81,6 +82,10 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
|
|||
helper = new NETLIST_EXPORTER_SPICE( sch );
|
||||
break;
|
||||
|
||||
case NET_TYPE_SPICE_MODEL:
|
||||
helper = new NETLIST_EXPORTER_SPICE_MODEL( sch );
|
||||
break;
|
||||
|
||||
case NET_TYPE_BOM:
|
||||
// When generating the BOM, we have a bare filename so don't strip
|
||||
// the extension or you might string a '.' from the middle of the filename
|
||||
|
|
|
@ -53,8 +53,10 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
|
|||
m_DashedLineDashRatio( 12.0 ),
|
||||
m_DashedLineGapRatio( 3.0 ),
|
||||
m_SpiceAdjustPassiveValues( false ),
|
||||
m_SpiceCurSheetAsRoot( false ),
|
||||
m_SpiceSaveAllVoltages( false ),
|
||||
m_SpiceSaveAllCurrents( false ),
|
||||
m_SpiceModelCurSheetAsRoot( true ),
|
||||
m_NgspiceSimulatorSettings( nullptr )
|
||||
{
|
||||
EESCHEMA_SETTINGS* appSettings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
|
|
|
@ -70,10 +70,13 @@ public:
|
|||
|
||||
///< @todo These should probably be moved to the "schematic.simulator" path.
|
||||
bool m_SpiceAdjustPassiveValues;
|
||||
bool m_SpiceCurSheetAsRoot;
|
||||
bool m_SpiceSaveAllVoltages;
|
||||
bool m_SpiceSaveAllCurrents;
|
||||
wxString m_SpiceCommandString; // A command string to run external spice
|
||||
|
||||
bool m_SpiceModelCurSheetAsRoot;
|
||||
|
||||
TEMPLATES m_TemplateFieldNames;
|
||||
|
||||
/**
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
|
||||
bool GetNetlist( OUTPUTFORMATTER* aFormatter )
|
||||
{
|
||||
return NGSPICE_CIRCUIT_MODEL::GenerateNetlist( *aFormatter, m_options );
|
||||
return NGSPICE_CIRCUIT_MODEL::DoWriteNetlist( *aFormatter, m_options );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -895,7 +895,8 @@ void SIM_PLOT_FRAME::updateTuners()
|
|||
{
|
||||
const wxString& ref = (*it)->GetComponentName();
|
||||
|
||||
if( std::find_if( spiceItems.begin(), spiceItems.end(), [&]( const SPICE_ITEM& item )
|
||||
if( std::find_if( spiceItems.begin(), spiceItems.end(),
|
||||
[&]( const NETLIST_EXPORTER_SPICE::ITEM& item )
|
||||
{
|
||||
return item.refName == ref;
|
||||
}) == spiceItems.end() )
|
||||
|
@ -1475,7 +1476,7 @@ void SIM_PLOT_FRAME::onSettings( wxCommandEvent& event )
|
|||
if( !m_settingsDlg )
|
||||
m_settingsDlg = new DIALOG_SIM_SETTINGS( this, m_circuitModel, m_simulator->Settings() );
|
||||
|
||||
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_ALL_FLAGS ) )
|
||||
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "There were errors during netlist export, aborted." ) );
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue