Sim: Resolve name collisions for generated model names
This commit is contained in:
parent
b2f05c758b
commit
4931b80066
|
@ -75,6 +75,25 @@ namespace NETLIST_EXPORTER_SPICE_PARSER
|
|||
}
|
||||
|
||||
|
||||
std::string NAME_GENERATOR::Generate( const std::string& aProposedName )
|
||||
{
|
||||
if( !m_names.count( aProposedName ) )
|
||||
return aProposedName;
|
||||
|
||||
for( uint64_t i = 1; i < UINT64_MAX; ++i )
|
||||
{
|
||||
std::string name = fmt::format( "{}#{}", aProposedName, i );
|
||||
|
||||
if( !m_names.count( name ) )
|
||||
return name;
|
||||
}
|
||||
|
||||
// Should never happen.
|
||||
THROW_IO_ERROR( wxString::Format( _( "Failed to generate a name for '%s': exceeded UINT64_MAX" ),
|
||||
aProposedName ) );
|
||||
}
|
||||
|
||||
|
||||
NETLIST_EXPORTER_SPICE::NETLIST_EXPORTER_SPICE( SCHEMATIC_IFACE* aSchematic ) :
|
||||
NETLIST_EXPORTER_BASE( aSchematic ),
|
||||
m_libMgr( aSchematic->Prj() )
|
||||
|
@ -322,11 +341,15 @@ 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 )
|
||||
{
|
||||
auto [modelName, model] = m_libMgr.CreateModel( aSymbol );
|
||||
aItem.modelName = ( modelName != "" ) ? modelName : ( "__" + aItem.refName );
|
||||
auto [baseModelName, model] = m_libMgr.CreateModel( aSymbol );
|
||||
aItem.model = &model;
|
||||
|
||||
// FIXME: Special cases for raw Spice models and KIBIS.
|
||||
std::string modelName = aItem.model->SpiceGenerator().ModelName( aItem.refName,
|
||||
baseModelName );
|
||||
// Resolve model name collisions.
|
||||
aItem.modelName = m_modelNameGenerator.Generate( modelName );
|
||||
|
||||
// FIXME: Don't have special cases for raw Spice models and KIBIS.
|
||||
if( auto rawSpiceModel = dynamic_cast<const SIM_MODEL_RAW_SPICE*>( aItem.model ) )
|
||||
{
|
||||
int libParamIndex = static_cast<int>( SIM_MODEL_RAW_SPICE::SPICE_PARAM::LIB );
|
||||
|
@ -337,9 +360,6 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
|
|||
}
|
||||
else if( auto kibisModel = dynamic_cast<const SIM_MODEL_KIBIS*>( aItem.model ) )
|
||||
{
|
||||
aItem.modelName = aItem.model->GetFieldValue( &aSymbol.GetFields(),
|
||||
SIM_LIBRARY_KIBIS::MODEL_FIELD );
|
||||
|
||||
wxFileName cacheDir;
|
||||
cacheDir.AssignDir( PATHS::GetUserCachePath() );
|
||||
cacheDir.AppendDir( wxT( "ibis" ) );
|
||||
|
@ -357,7 +377,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() );
|
||||
std::string modelData = spiceGenerator.IbisDevice( aSymbol.GetFields(), aItem.modelName );
|
||||
|
||||
cacheFile.Write( wxString( modelData ) );
|
||||
m_rawIncludes.insert( libraryPath );
|
||||
|
|
|
@ -32,6 +32,16 @@
|
|||
#include <sim/sim_model.h>
|
||||
|
||||
|
||||
class NAME_GENERATOR
|
||||
{
|
||||
public:
|
||||
std::string Generate( const std::string& aProposedName );
|
||||
|
||||
private:
|
||||
std::unordered_set<std::string> m_names;
|
||||
};
|
||||
|
||||
|
||||
class NETLIST_EXPORTER_SPICE : public NETLIST_EXPORTER_BASE
|
||||
{
|
||||
public:
|
||||
|
@ -141,13 +151,15 @@ 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
|
||||
SIM_LIB_MGR m_libMgr; ///< Holds libraries and models
|
||||
NAME_GENERATOR m_modelNameGenerator; ///< Generates unique model names
|
||||
NAME_GENERATOR m_netNameGenerator; ///< Generates unique net names (only unique for NC nets for now)
|
||||
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::set<std::string> m_rawIncludes; ///< include directives found in symbols
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
#include <fmt/core.h>
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR_KIBIS::ModelName( const std::string& aRefName,
|
||||
const std::string& aBaseModelName ) const
|
||||
{
|
||||
return fmt::format( "{}.{}", aRefName, aBaseModelName );
|
||||
}
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR_KIBIS::ModelLine( const std::string& aModelName ) const
|
||||
{
|
||||
return "";
|
||||
|
@ -51,7 +58,8 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const std::string&
|
|||
}
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFields ) const
|
||||
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const std::vector<SCH_FIELD>& aFields,
|
||||
const std::string& aModelName ) const
|
||||
{
|
||||
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::LIBRARY_FIELD );
|
||||
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aFields, SIM_LIBRARY::NAME_FIELD );
|
||||
|
@ -101,7 +109,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, ibisModelName, *kmodel, kparams );
|
||||
kpin->writeSpiceDevice( &result, aModelName, *kmodel, kparams );
|
||||
break;
|
||||
|
||||
case SIM_MODEL::TYPE::KIBIS_DRIVER_DC:
|
||||
|
@ -124,7 +132,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, ibisModelName, *kmodel, kparams );
|
||||
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -137,7 +145,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, ibisModelName, *kmodel, kparams );
|
||||
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -150,7 +158,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, ibisModelName, *kmodel, kparams );
|
||||
kpin->writeSpiceDriver( &result, aModelName, *kmodel, kparams );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,13 @@ 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 IbisDevice( const std::vector<SCH_FIELD>& aFields ) const;
|
||||
std::string IbisDevice( const std::vector<SCH_FIELD>& aFields,
|
||||
const std::string& aModelName ) const;
|
||||
|
||||
protected:
|
||||
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;
|
||||
|
|
|
@ -29,6 +29,20 @@
|
|||
#include <fmt/core.h>
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR::ModelName( const std::string& aRefName,
|
||||
const std::string& aBaseModelName ) const
|
||||
{
|
||||
if( aBaseModelName == "" )
|
||||
return fmt::format( "__{}", aRefName );
|
||||
|
||||
// FIXME: This ModelLine() call is relatively expensive.
|
||||
if( ModelLine( aBaseModelName ) != "" )
|
||||
return fmt::format( "{}.{}", aRefName, aBaseModelName );
|
||||
|
||||
return aBaseModelName;
|
||||
}
|
||||
|
||||
|
||||
std::string SPICE_GENERATOR::ModelLine( const std::string& aModelName ) const
|
||||
{
|
||||
if( !m_model.HasSpiceNonInstanceOverrides() && !m_model.requiresSpiceModelLine() )
|
||||
|
|
|
@ -34,6 +34,8 @@ 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;
|
||||
|
||||
std::string ItemLine( const std::string& aRefName,
|
||||
|
|
Loading…
Reference in New Issue