Spice simulator: more elegant approach to generating Spice device names

Code fixing Spice device names (prefixing reference with a character
corresponding to the assigned device model type) that was duplicated in
a few places has been moved to a function (NETLIST_EXPORTER_PSPICE::GetSpiceDevice()).
This commit is contained in:
Maciej Suminski 2018-04-28 00:34:06 +02:00
parent 095112a902
commit 539d12b08f
8 changed files with 47 additions and 44 deletions

View File

@ -117,11 +117,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
try
{
wxString dcSource = m_dcSource1->GetValue();
// Add voltage source prefix if needed
if( dcSource[0] != 'v' && dcSource[0] != 'V' )
dcSource += 'v' + dcSource;
wxString dcSource = m_exporter->GetSpiceDevice( m_dcSource1->GetValue() );
simCmd += wxString::Format( "%s %s %s %s",
dcSource,
@ -151,11 +147,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
try
{
wxString dcSource = m_dcSource2->GetValue();
// Add voltage source prefix if needed
if( dcSource[0] != 'v' && dcSource[0] != 'V' )
dcSource += 'v' + dcSource;
wxString dcSource = m_exporter->GetSpiceDevice( m_dcSource2->GetValue() );
simCmd += wxString::Format( "%s %s %s %s",
dcSource,
@ -186,7 +178,7 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
wxString ref = empty( m_noiseRef )
? wxString() : wxString::Format( ", %d", netMap.at( m_noiseRef->GetValue() ) );
wxString noiseSource = m_noiseSrc->GetValue();
wxString noiseSource = m_exporter->GetSpiceDevice( m_noiseSrc->GetValue() );
// Add voltage source prefix if needed
if( noiseSource[0] != 'v' && noiseSource[0] != 'V' )

View File

@ -39,6 +39,24 @@
#include <wx/tokenzr.h>
#include <wx/regex.h>
wxString NETLIST_EXPORTER_PSPICE::GetSpiceDevice( const wxString& aComponent ) const
{
const auto& spiceItems = GetSpiceItems();
auto it = std::find_if( spiceItems.begin(), spiceItems.end(), [&]( const SPICE_ITEM& item ) {
return item.m_refName == aComponent;
} );
if( it == spiceItems.end() )
return wxEmptyString;
// Prefix the device type if plain reference would result in a different device type
return it->m_primitive != it->m_refName[0] ?
wxString( it->m_primitive + it->m_refName ) : it->m_refName;
}
bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
{
FILE_OUTPUTFORMATTER outputFile( aOutFileName, wxT( "wt" ), '\'' );
@ -99,12 +117,8 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl
if( !item.m_enabled )
continue;
// Add a character determining the device type if the original reference
// would result in a different device type
if( item.m_primitive != item.m_refName[0] )
aFormatter->Print( 0, "%c", item.m_primitive );
aFormatter->Print( 0, "%s ", (const char*) item.m_refName.c_str() );
wxString device = GetSpiceDevice( item.m_refName );
aFormatter->Print( 0, "%s ", (const char*) device.c_str() );
size_t pspiceNodes = item.m_pinSequence.empty() ? item.m_pins.size() : item.m_pinSequence.size();

View File

@ -122,6 +122,17 @@ public:
return m_spiceItems;
}
/**
* @brief Returns name of Spice device corresponding to a schematic component.
*
* @param aComponent is the component reference.
* @return Spice device name or empty string if there is no such component in the netlist. The
* name is either plain reference if the first character of reference corresponds to the
* assigned device model type or it is the reference prefixed with a character defining
* the device model type.
*/
wxString GetSpiceDevice( const wxString& aComponent ) const;
/**
* Function WriteNetlist
* writes to specified output file

View File

@ -85,21 +85,6 @@ const std::vector<wxString>& NETLIST_EXPORTER_PSPICE_SIM::GetCurrents( SPICE_PRI
}
wxString NETLIST_EXPORTER_PSPICE_SIM::GetSpiceDevice( const wxString& aComponent ) const
{
const auto& spiceItems = GetSpiceItems();
auto it = std::find_if( spiceItems.begin(), spiceItems.end(), [&]( const SPICE_ITEM& item ) {
return item.m_refName == aComponent;
} );
if( it == spiceItems.end() )
return wxEmptyString;
return wxString( it->m_primitive + it->m_refName );
}
wxString NETLIST_EXPORTER_PSPICE_SIM::GetSheetSimCommand()
{
wxString simCmd;

View File

@ -53,13 +53,6 @@ public:
wxString GetSpiceVector( const wxString& aName, SIM_PLOT_TYPE aType,
const wxString& aParam = wxEmptyString ) const;
/**
* @brief Returns name of Spice device corresponding to a schematic component.
* @param aComponent is the component reference.
* @return Spice device name or empty string if there is no such component in the netlist.
*/
wxString GetSpiceDevice( const wxString& aComponent ) const;
/**
* @brief Returns a list of currents that can be probed in a Spice primitive.
*/

View File

@ -407,6 +407,12 @@ SIM_PLOT_PANEL* SIM_PLOT_FRAME::CurrentPlot() const
}
const NETLIST_EXPORTER_PSPICE_SIM* SIM_PLOT_FRAME::GetExporter() const
{
return m_exporter.get();
}
void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam )
{
SIM_TYPE simType = m_exporter->GetSimType();

View File

@ -156,6 +156,11 @@ public:
*/
SIM_PLOT_PANEL* CurrentPlot() const;
/**
* Returns the netlist exporter object used for simulations.
*/
const NETLIST_EXPORTER_PSPICE_SIM* GetExporter() const;
private:
void LoadSettings( wxConfigBase* aCfg ) override;
void SaveSettings( wxConfigBase* aCfg ) override;

View File

@ -27,7 +27,7 @@
#include <sim/sim_plot_frame.h>
#include <sch_component.h>
#include <template_fieldnames.h>
#include <netlist_exporters/netlist_exporter_pspice.h>
#include <sim/netlist_exporter_pspice_sim.h>
TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_COMPONENT* aComponent )
: TUNER_SLIDER_BASE( aParent ), m_component( aComponent ),
@ -37,10 +37,7 @@ TUNER_SLIDER::TUNER_SLIDER( SIM_PLOT_FRAME* aFrame, wxWindow* aParent, SCH_COMPO
m_name->SetLabel( compName );
m_value = SPICE_VALUE( aComponent->GetField( VALUE )->GetText() );
m_changed = false;
// Generate Spice component name
char prim = NETLIST_EXPORTER_PSPICE::GetSpiceField( SF_PRIMITIVE, aComponent, 0 )[0];
m_spiceName = wxString( prim + compName ).Lower();
m_spiceName = aFrame->GetExporter()->GetSpiceDevice( compName ).Lower();
// Call Set*() methods to update fields and slider
m_max = SPICE_VALUE( 2.0 ) * m_value;