Move V6->V7 sim model migration from sheets to screens.
Also moves passive RLC inference out from migration to just-in-time creation for the simulator or netlisting. Also fixes a version guard mismatch because the spice migration was done inside UpdateSymbolInstances (which has its own version guard). Also changed UpdateSymbolInstances to UpdateSymbolInstanceData so someone else in the future doesn't think it's a general-purpose symbol instance updater.
This commit is contained in:
parent
f8e0a272c0
commit
38906397d2
|
@ -642,10 +642,10 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
|||
if( restoreSheet )
|
||||
currentSheet.LastScreen()->Append( m_sheet );
|
||||
|
||||
// The full hierarchy needs to be reloaded because due to the addition of a new sheet.
|
||||
// The full hierarchy needs to be reloaded due to the addition of a new sheet.
|
||||
fullHierarchy = schematic.GetFullHierarchy();
|
||||
fullHierarchy.UpdateSheetInstances( sheetInstances );
|
||||
fullHierarchy.UpdateSymbolInstances( symbolInstances );
|
||||
fullHierarchy.UpdateSheetInstanceData( sheetInstances );
|
||||
fullHierarchy.UpdateSymbolInstanceData( symbolInstances );
|
||||
}
|
||||
|
||||
if( m_clearAnnotationNewItems )
|
||||
|
|
|
@ -87,12 +87,17 @@ static std::unique_ptr<SCHEMATIC> readSchematicFromFile( const std::string& aFil
|
|||
SCH_SCREENS screens( schematic->Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
screen->MigrateSimModels();
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST sheets = schematic->GetSheets();
|
||||
|
||||
// Restore all of the loaded symbol instances from the root sheet screen.
|
||||
sheets.UpdateSymbolInstances( schematic->RootScreen()->GetSymbolInstances() );
|
||||
sheets.UpdateSymbolInstanceData( schematic->RootScreen()->GetSymbolInstances() );
|
||||
|
||||
sheets.AnnotatePowerSymbols();
|
||||
|
||||
|
|
|
@ -136,16 +136,20 @@ SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( wxString& aFileName, SCH_IO_MGR::SCH
|
|||
}
|
||||
|
||||
SCH_SHEET_LIST sheetList = schematic->GetSheets();
|
||||
SCH_SCREENS schematicScreenRoot( schematic->Root() );
|
||||
SCH_SCREENS screens( schematic->Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = schematicScreenRoot.GetFirst(); screen;
|
||||
screen = schematicScreenRoot.GetNext() )
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
|
||||
sheetList.UpdateSymbolInstances( schematic->RootScreen()->GetSymbolInstances() );
|
||||
if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
screen->MigrateSimModels();
|
||||
}
|
||||
|
||||
sheetList.UpdateSheetInstances( schematic->RootScreen()->GetSheetInstances() );
|
||||
if( schematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
|
||||
sheetList.UpdateSymbolInstanceData( schematic->RootScreen()->GetSymbolInstances());
|
||||
|
||||
sheetList.UpdateSheetInstanceData( schematic->RootScreen()->GetSheetInstances());
|
||||
|
||||
sheetList.AnnotatePowerSymbols();
|
||||
|
||||
|
|
|
@ -447,14 +447,19 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
}
|
||||
|
||||
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
||||
{
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
screen->MigrateSimModels();
|
||||
}
|
||||
|
||||
// Restore all of the loaded symbol and sheet instances from the root sheet.
|
||||
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
|
||||
sheetList.UpdateSymbolInstances( Schematic().RootScreen()->GetSymbolInstances() );
|
||||
sheetList.UpdateSymbolInstanceData( Schematic().RootScreen()->GetSymbolInstances());
|
||||
|
||||
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
|
||||
sheetList.UpdateSheetInstances( Schematic().RootScreen()->GetSheetInstances() );
|
||||
sheetList.UpdateSheetInstanceData( Schematic().RootScreen()->GetSheetInstances());
|
||||
}
|
||||
|
||||
Schematic().ConnectionGraph()->Reset();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "netlist_exporter_spice.h"
|
||||
#include <sim/sim_library_spice.h>
|
||||
#include <sim/sim_model_raw_spice.h>
|
||||
#include <sim/sim_model_ideal.h>
|
||||
#include <sim/spice_grammar.h>
|
||||
#include <common.h>
|
||||
#include <confirm.h>
|
||||
|
@ -228,6 +229,23 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
spiceItem.fields.back().SetText( symbol->GetFields()[i].GetShownText( 0, false ) );
|
||||
}
|
||||
|
||||
// Infer RLC passive models if they aren't specified
|
||||
if( !symbol->FindField( SIM_MODEL::DEVICE_TYPE_FIELD, false )
|
||||
&& !symbol->FindField( SIM_MODEL::PARAMS_FIELD, false ) )
|
||||
{
|
||||
wxString simParams = SIM_MODEL_IDEAL::InferSimParams( symbol->GetPrefix(),
|
||||
symbol->GetValueFieldText( true ) );
|
||||
|
||||
if( !simParams.IsEmpty() )
|
||||
{
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
spiceItem.fields.back().SetText( symbol->GetPrefix() );
|
||||
|
||||
spiceItem.fields.emplace_back( VECTOR2I(), -1, symbol, SIM_MODEL::PARAMS_FIELD );
|
||||
spiceItem.fields.back().SetText( simParams );
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if( !readRefName( sheet, *symbol, spiceItem, refNames ) )
|
||||
|
|
|
@ -92,4 +92,5 @@
|
|||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20221002 // Move instance data back into symbol definition.
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20221004 // Move instance data back into symbol definition.
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20221110 // Move sheet instance data to sheet definition.
|
||||
#define SEXPR_SCHEMATIC_FILE_VERSION 20221126 // Remove value and footprint from instance data.
|
||||
//#define SEXPR_SCHEMATIC_FILE_VERSION 20221126 // Remove value and footprint from instance data.
|
||||
#define SEXPR_SCHEMATIC_FILE_VERSION 20221206 // Simulation model fields V6 -> V7
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
#include <schematic.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <tool/common_tools.h>
|
||||
#include <sim/sim_model.h> // For V6 to V7 simulation model migration.
|
||||
#include <sim/sim_value.h> //
|
||||
#include <locale_io.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -1840,3 +1843,154 @@ void SCH_SCREENS::SetLegacySymbolInstanceData()
|
|||
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
||||
screen->SetLegacySymbolInstanceData();
|
||||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::MigrateSimModels()
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
// V6 schematics may specify model names in Value fields, which we don't do in V7.
|
||||
// Migrate by adding an equivalent model for these symbols.
|
||||
|
||||
for( SCH_ITEM* item : Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
migrateSimModel( *symbol );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::migrateSimModel( SCH_SYMBOL& aSymbol )
|
||||
{
|
||||
if( aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PINS_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
|
||||
{
|
||||
// Has a V7 model field -- skip.
|
||||
return;
|
||||
}
|
||||
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
wxString value = aSymbol.GetValueFieldText( true );
|
||||
|
||||
wxString spiceType;
|
||||
wxString spiceModel;
|
||||
wxString spiceLib;
|
||||
wxString pinMap;
|
||||
|
||||
if( aSymbol.FindField( "Spice_Primitive" )
|
||||
|| aSymbol.FindField( "Spice_Node_Sequence" )
|
||||
|| aSymbol.FindField( "Spice_Model" )
|
||||
|| aSymbol.FindField( "Spice_Netlist_Enabled" )
|
||||
|| aSymbol.FindField( "Spice_Lib_File" ) )
|
||||
{
|
||||
if( SCH_FIELD* primitiveField = aSymbol.FindField( "Spice_Primitive" ) )
|
||||
{
|
||||
spiceType = primitiveField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Primitive" );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* nodeSequenceField = aSymbol.FindField( "Spice_Node_Sequence" ) )
|
||||
{
|
||||
const wxString delimiters( "{:,; }" );
|
||||
const wxString& nodeSequence = nodeSequenceField->GetText();
|
||||
|
||||
if( nodeSequence != "" )
|
||||
{
|
||||
wxStringTokenizer tkz( nodeSequence, delimiters );
|
||||
|
||||
for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
|
||||
{
|
||||
long symbolPinNumber = 1;
|
||||
tkz.GetNextToken().ToLong( &symbolPinNumber );
|
||||
|
||||
if( modelPinNumber != 1 )
|
||||
pinMap.Append( " " );
|
||||
|
||||
pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol.RemoveField( "Spice_Node_Sequence" );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* modelField = aSymbol.FindField( "Spice_Model" ) )
|
||||
{
|
||||
spiceModel = modelField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Model" );
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceModel = aSymbol.FindField( "Value" )->GetText();
|
||||
}
|
||||
|
||||
if( SCH_FIELD* netlistEnabledField = aSymbol.FindField( "Spice_Netlist_Enabled" ) )
|
||||
{
|
||||
wxString netlistEnabled = netlistEnabledField->GetText().Lower();
|
||||
|
||||
if( netlistEnabled.StartsWith( "0" )
|
||||
|| netlistEnabled.StartsWith( "n" )
|
||||
|| netlistEnabled.StartsWith( "f" ) )
|
||||
{
|
||||
SCH_FIELD enableField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::ENABLE_FIELD );
|
||||
}
|
||||
}
|
||||
|
||||
if( SCH_FIELD* libFileField = aSymbol.FindField( "Spice_Lib_File" ) )
|
||||
{
|
||||
spiceLib = libFileField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Lib_File" );
|
||||
}
|
||||
}
|
||||
else if( prefix == wxT( "V" ) || prefix == wxT( "I" ) )
|
||||
{
|
||||
spiceModel = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert a plaintext model as a substitute.
|
||||
|
||||
SCH_FIELD deviceTypeField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
deviceTypeField.SetText(
|
||||
SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_TYPE_::SPICE ).fieldValue );
|
||||
aSymbol.AddField( deviceTypeField );
|
||||
|
||||
SCH_FIELD paramsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PARAMS_FIELD );
|
||||
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
|
||||
spiceType, spiceModel, spiceLib ) );
|
||||
aSymbol.AddField( paramsField );
|
||||
|
||||
// Legacy models by default get linear pin mapping.
|
||||
if( pinMap != "" )
|
||||
{
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString pins;
|
||||
|
||||
for( unsigned i = 0; i < aSymbol.GetLibPins().size(); ++i )
|
||||
{
|
||||
if( i != 0 )
|
||||
pins.Append( " " );
|
||||
|
||||
pins.Append( wxString::Format( "%u=%u", i + 1, i + 1 ) );
|
||||
}
|
||||
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pins );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,14 +515,9 @@ public:
|
|||
#endif
|
||||
|
||||
/**
|
||||
* last value for the zoom level, useful in Eeschema when changing the current displayed
|
||||
* sheet to reuse the same zoom level when back to the sheet using this screen
|
||||
* Migrate any symbols having V6 simulation models to their V7 equivalents.
|
||||
*/
|
||||
double m_LastZoomLevel;
|
||||
|
||||
private:
|
||||
bool doIsJunction( const VECTOR2I& aPosition, bool aBreakCrossings,
|
||||
bool* aHasExplicitJunctionDot, bool* aHasBusEntry ) const;
|
||||
void MigrateSimModels();
|
||||
|
||||
private:
|
||||
friend SCH_EDIT_FRAME; // Only to populate m_symbolInstances.
|
||||
|
@ -530,8 +525,24 @@ private:
|
|||
friend SCH_SEXPR_PLUGIN; // Only to save the loaded instance information to schematic file.
|
||||
friend SCH_ALTIUM_PLUGIN;
|
||||
|
||||
bool doIsJunction( const VECTOR2I& aPosition, bool aBreakCrossings,
|
||||
bool* aHasExplicitJunctionDot, bool* aHasBusEntry ) const;
|
||||
|
||||
void clearLibSymbols();
|
||||
|
||||
/**
|
||||
* Migrate the symbol's V6 simulation model SCH_FIELDs to their V7 equivalents
|
||||
*/
|
||||
void migrateSimModel( SCH_SYMBOL& aSymbol );
|
||||
|
||||
public:
|
||||
/**
|
||||
* last value for the zoom level, useful in Eeschema when changing the current displayed
|
||||
* sheet to reuse the same zoom level when back to the sheet using this screen
|
||||
*/
|
||||
double m_LastZoomLevel;
|
||||
|
||||
private:
|
||||
wxString m_fileName; // File used to load the screen.
|
||||
int m_fileFormatVersionAtLoad;
|
||||
int m_refCount; // Number of sheets referencing this screen.
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <sch_sheet_path.h>
|
||||
#include <sch_symbol.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_textbox.h>
|
||||
#include <schematic.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <trace_helpers.h>
|
||||
|
@ -40,11 +39,6 @@
|
|||
#include <boost/functional/hash.hpp>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
#include "erc_item.h"
|
||||
|
||||
#include <sim/sim_model.h> // For V6 to V7 simulation model migration.
|
||||
#include <sim/sim_value.h> //
|
||||
#include <locale_io.h>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1096,7 +1090,7 @@ SCH_SHEET_LIST SCH_SHEET_LIST::FindAllSheetsForScreen( const SCH_SCREEN* aScreen
|
|||
}
|
||||
|
||||
|
||||
void SCH_SHEET_LIST::UpdateSymbolInstances(
|
||||
void SCH_SHEET_LIST::UpdateSymbolInstanceData(
|
||||
const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbolInstances )
|
||||
{
|
||||
for( SCH_SHEET_PATH& sheetPath : *this )
|
||||
|
@ -1131,13 +1125,10 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
symbol->SetFootprintFieldText( it->m_Footprint );
|
||||
}
|
||||
}
|
||||
|
||||
if( size() >= 1 && at( 0 ).LastScreen()->GetFileFormatVersionAtLoad() < 20220622 )
|
||||
MigrateSimModelNameFields();
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET_LIST::UpdateSheetInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
|
||||
void SCH_SHEET_LIST::UpdateSheetInstanceData( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
|
||||
{
|
||||
|
||||
for( SCH_SHEET_PATH& path : *this )
|
||||
|
@ -1269,177 +1260,3 @@ int SCH_SHEET_LIST::GetLastVirtualPageNumber() const
|
|||
return lastVirtualPageNumber;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET_LIST::MigrateSimModelNameFields()
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
for( unsigned sheetIndex = 0; sheetIndex < size(); ++sheetIndex )
|
||||
{
|
||||
SCH_SCREEN* screen = at( sheetIndex ).LastScreen();
|
||||
|
||||
// V6 schematics may specify model names in Value fields, which we don't do in V7.
|
||||
// Migrate by adding an equivalent model for these symbols.
|
||||
|
||||
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
|
||||
if( !symbol )
|
||||
{
|
||||
// Shouldn't happen.
|
||||
wxFAIL;
|
||||
continue;
|
||||
}
|
||||
|
||||
migrateSimModel( *symbol, sheetIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET_LIST::migrateSimModel( SCH_SYMBOL& aSymbol, unsigned aSheetIndex )
|
||||
{
|
||||
if( aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::TYPE_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PINS_FIELD )
|
||||
|| aSymbol.FindField( SIM_MODEL::PARAMS_FIELD ) )
|
||||
{
|
||||
// Has a V7 model field -- skip.
|
||||
return;
|
||||
}
|
||||
|
||||
wxString ref = aSymbol.GetRef( &at( aSheetIndex ), true );
|
||||
wxString value = aSymbol.GetValueFieldText( true );
|
||||
|
||||
wxString spiceType;
|
||||
wxString spiceModel;
|
||||
wxString spiceLib;
|
||||
wxString pinMap;
|
||||
|
||||
if( aSymbol.FindField( "Spice_Primitive" )
|
||||
|| aSymbol.FindField( "Spice_Node_Sequence" )
|
||||
|| aSymbol.FindField( "Spice_Model" )
|
||||
|| aSymbol.FindField( "Spice_Netlist_Enabled" )
|
||||
|| aSymbol.FindField( "Spice_Lib_File" ) )
|
||||
{
|
||||
if( SCH_FIELD* primitiveField = aSymbol.FindField( "Spice_Primitive" ) )
|
||||
{
|
||||
spiceType = primitiveField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Primitive" );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* nodeSequenceField = aSymbol.FindField( "Spice_Node_Sequence" ) )
|
||||
{
|
||||
const wxString delimiters( "{:,; }" );
|
||||
const wxString& nodeSequence = nodeSequenceField->GetText();
|
||||
|
||||
if( nodeSequence != "" )
|
||||
{
|
||||
wxStringTokenizer tkz( nodeSequence, delimiters );
|
||||
|
||||
for( long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
|
||||
{
|
||||
long symbolPinNumber = 1;
|
||||
tkz.GetNextToken().ToLong( &symbolPinNumber );
|
||||
|
||||
if( modelPinNumber != 1 )
|
||||
pinMap.Append( " " );
|
||||
|
||||
pinMap.Append( wxString::Format( "%ld=%ld", symbolPinNumber, modelPinNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
aSymbol.RemoveField( "Spice_Node_Sequence" );
|
||||
}
|
||||
|
||||
if( SCH_FIELD* modelField = aSymbol.FindField( "Spice_Model" ) )
|
||||
{
|
||||
spiceModel = modelField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Model" );
|
||||
}
|
||||
else
|
||||
spiceModel = aSymbol.FindField( "Value" )->GetText();
|
||||
|
||||
if( SCH_FIELD* netlistEnabledField = aSymbol.FindField( "Spice_Netlist_Enabled" ) )
|
||||
{
|
||||
wxString netlistEnabled = netlistEnabledField->GetText().Lower();
|
||||
|
||||
if( netlistEnabled.StartsWith( "0" )
|
||||
|| netlistEnabled.StartsWith( "n" )
|
||||
|| netlistEnabled.StartsWith( "f" ) )
|
||||
{
|
||||
SCH_FIELD enableField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::ENABLE_FIELD );
|
||||
}
|
||||
}
|
||||
|
||||
if( SCH_FIELD* libFileField = aSymbol.FindField( "Spice_Lib_File" ) )
|
||||
{
|
||||
spiceLib = libFileField->GetText();
|
||||
aSymbol.RemoveField( "Spice_Lib_File" );
|
||||
}
|
||||
}
|
||||
else if( ref.StartsWith( "R" ) || ref.StartsWith( "L" ) || ref.StartsWith( "C" ) )
|
||||
{
|
||||
wxRegEx passiveVal(
|
||||
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
|
||||
|
||||
if( !passiveVal.Matches( value ) )
|
||||
return;
|
||||
|
||||
wxString prefix( passiveVal.GetMatch( value, 1 ) );
|
||||
wxString unit( passiveVal.GetMatch( value, 2 ) );
|
||||
wxString suffix( passiveVal.GetMatch( value, 6 ) );
|
||||
|
||||
if( unit == "M" )
|
||||
unit = "Meg";
|
||||
|
||||
spiceModel = prefix + unit;
|
||||
}
|
||||
else if( ref.StartsWith( "V" ) || ref.StartsWith( "I" ) )
|
||||
spiceModel = value;
|
||||
else
|
||||
return;
|
||||
|
||||
// Insert a plaintext model as a substitute.
|
||||
|
||||
SCH_FIELD deviceTypeField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
deviceTypeField.SetText(
|
||||
SIM_MODEL::DeviceInfo( SIM_MODEL::DEVICE_TYPE_::SPICE ).fieldValue );
|
||||
aSymbol.AddField( deviceTypeField );
|
||||
|
||||
SCH_FIELD paramsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PARAMS_FIELD );
|
||||
paramsField.SetText( wxString::Format( "type=\"%s\" model=\"%s\" lib=\"%s\"",
|
||||
spiceType, spiceModel, spiceLib ) );
|
||||
aSymbol.AddField( paramsField );
|
||||
|
||||
// Legacy models by default get linear pin mapping.
|
||||
if( pinMap != "" )
|
||||
{
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
|
||||
pinsField.SetText( pinMap );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString pins;
|
||||
|
||||
for( unsigned i = 0; i < aSymbol.GetLibPins().size(); ++i )
|
||||
{
|
||||
if( i != 0 )
|
||||
pins.Append( " " );
|
||||
|
||||
pins.Append( wxString::Format( "%u=%u", i + 1, i + 1 ) );
|
||||
}
|
||||
|
||||
SCH_FIELD pinsField( VECTOR2I( 0, 0 ), aSymbol.GetFieldCount(), &aSymbol,
|
||||
SIM_MODEL::PINS_FIELD );
|
||||
pinsField.SetText( pins );
|
||||
aSymbol.AddField( pinsField );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -614,7 +614,7 @@ public:
|
|||
* WARNING: Do not call this on anything other than the full hierarchy.
|
||||
* @param aSymbolInstances is the symbol path information loaded from the root schematic.
|
||||
*/
|
||||
void UpdateSymbolInstances( const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbolInstances );
|
||||
void UpdateSymbolInstanceData( const std::vector<SYMBOL_INSTANCE_REFERENCE>& aSymbolInstances );
|
||||
|
||||
/**
|
||||
* Update all of the sheet instance information using \a aSheetInstances.
|
||||
|
@ -623,7 +623,7 @@ public:
|
|||
*
|
||||
* @param aSymbolInstances is the symbol path information loaded from the root schematic.
|
||||
*/
|
||||
void UpdateSheetInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances );
|
||||
void UpdateSheetInstanceData( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances );
|
||||
|
||||
std::vector<KIID_PATH> GetPaths() const;
|
||||
|
||||
|
@ -667,17 +667,7 @@ public:
|
|||
|
||||
void RemoveSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
|
||||
|
||||
/**
|
||||
* Migrate V6 simulator models to V7. Must be called only after UpdateSymbolInstances().
|
||||
*/
|
||||
void MigrateSimModelNameFields();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Migrate a single V6 simulator model to V7. Must be called only after UpdateSymbolInstances().
|
||||
*/
|
||||
void migrateSimModel( SCH_SYMBOL& aSymbol, unsigned aSheetIndex );
|
||||
|
||||
SCH_SHEET_PATH m_currentSheetPath;
|
||||
};
|
||||
|
||||
|
|
|
@ -166,6 +166,9 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
|||
return false;
|
||||
}
|
||||
|
||||
if( newSheet->GetScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
newSheet->GetScreen()->MigrateSimModels();
|
||||
|
||||
// If the loaded schematic is in a different folder from the current project and
|
||||
// it contains hierarchical sheets, the hierarchical sheet paths need to be updated.
|
||||
if( fileName.GetPathWithSep() != Prj().GetProjectPath() && newSheet->CountSheets() )
|
||||
|
@ -498,7 +501,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
|
|||
{
|
||||
// If the loaded schematic is a root sheet for another project, update the symbol
|
||||
// instances.
|
||||
sheetHierarchy.UpdateSymbolInstances( newScreen->GetSymbolInstances() );
|
||||
sheetHierarchy.UpdateSymbolInstanceData( newScreen->GetSymbolInstances());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <sim/sim_lib_mgr.h>
|
||||
#include <sim/sim_library.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_model_ideal.h>
|
||||
|
||||
|
||||
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT& aPrj ) : m_project( aPrj )
|
||||
{
|
||||
|
@ -109,6 +111,23 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
|
|||
fields.back().SetText( aSymbol.GetFields()[ i ].GetShownText( 0, false ) );
|
||||
}
|
||||
|
||||
// Infer RLC passive models if they aren't specified
|
||||
if( !aSymbol.FindField( SIM_MODEL::DEVICE_TYPE_FIELD, false )
|
||||
&& !aSymbol.FindField( SIM_MODEL::PARAMS_FIELD, false ) )
|
||||
{
|
||||
wxString simParams = SIM_MODEL_IDEAL::InferSimParams( aSymbol.GetPrefix(),
|
||||
aSymbol.GetValueFieldText( true ) );
|
||||
|
||||
if( !simParams.IsEmpty() )
|
||||
{
|
||||
fields.emplace_back( VECTOR2I(), -1, &aSymbol, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
fields.back().SetText( aSymbol.GetPrefix() );
|
||||
|
||||
fields.emplace_back( VECTOR2I(), -1, &aSymbol, SIM_MODEL::PARAMS_FIELD );
|
||||
fields.back().SetText( simParams );
|
||||
}
|
||||
}
|
||||
|
||||
return CreateModel( fields, static_cast<int>( aSymbol.GetRawPins().size() ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <wx/regex.h>
|
||||
|
||||
std::string SPICE_GENERATOR_IDEAL::ModelLine( const SPICE_ITEM& aItem ) const
|
||||
{
|
||||
|
@ -73,6 +73,39 @@ SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType ) :
|
|||
}
|
||||
|
||||
|
||||
wxString SIM_MODEL_IDEAL::InferSimParams( const wxString& aPrefix, const wxString& aValue )
|
||||
{
|
||||
wxString spiceModel;
|
||||
|
||||
if( aPrefix == wxT( "R" ) || aPrefix == wxT( "L" ) || aPrefix == wxT( "C" ) )
|
||||
{
|
||||
wxRegEx passiveVal(
|
||||
wxT( "^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
|
||||
|
||||
if( passiveVal.Matches( aValue ) )
|
||||
{
|
||||
wxString valuePrefix( passiveVal.GetMatch( aValue, 1 ) );
|
||||
wxString valueUnits( passiveVal.GetMatch( aValue, 2 ) );
|
||||
wxString valueSuffix( passiveVal.GetMatch( aValue, 6 ) );
|
||||
|
||||
if( valueUnits == "M" )
|
||||
valueUnits = "Meg";
|
||||
|
||||
spiceModel = valuePrefix + valueUnits;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceModel = aValue;
|
||||
}
|
||||
}
|
||||
|
||||
if( !spiceModel.IsEmpty() )
|
||||
return wxString::Format( wxT( "%s=\"%s\"" ), aPrefix.Lower(), spiceModel );
|
||||
else
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
SIM_MODEL::PARAM::INFO SIM_MODEL_IDEAL::makeParamInfo( std::string aName, std::string aDescription,
|
||||
std::string aUnit )
|
||||
{
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
const PARAM* GetTunerParam() const override { return &GetParam( 0 ); }
|
||||
bool HasPrimaryValue() const override { return true; }
|
||||
|
||||
static wxString InferSimParams( const wxString& aPrefix, const wxString& aValue );
|
||||
|
||||
private:
|
||||
std::vector<std::string> getPinNames() const override { return { "+", "-" }; }
|
||||
|
||||
|
|
|
@ -140,13 +140,18 @@ void LoadSchematic( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath
|
|||
SCH_SCREENS screens( aSchematic->Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
if( aSchematic->RootScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
screen->MigrateSimModels();
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST sheets = aSchematic->GetSheets();
|
||||
|
||||
// Restore all of the loaded symbol instances from the root sheet screen.
|
||||
sheets.UpdateSymbolInstances( aSchematic->RootScreen()->GetSymbolInstances() );
|
||||
sheets.UpdateSheetInstances( aSchematic->RootScreen()->GetSheetInstances() );
|
||||
sheets.UpdateSymbolInstanceData( aSchematic->RootScreen()->GetSymbolInstances() );
|
||||
sheets.UpdateSheetInstanceData( aSchematic->RootScreen()->GetSheetInstances() );
|
||||
|
||||
sheets.AnnotatePowerSymbols();
|
||||
|
||||
|
|
|
@ -87,16 +87,21 @@ void KI_TEST::SCHEMATIC_TEST_FIXTURE::LoadSchematic( const wxString& aBaseName )
|
|||
SCH_SCREENS screens( m_schematic.Root() );
|
||||
|
||||
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
|
||||
{
|
||||
screen->UpdateLocalLibSymbolLinks();
|
||||
|
||||
if( m_schematic.RootScreen()->GetFileFormatVersionAtLoad() < 20221206 )
|
||||
screen->MigrateSimModels();
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST sheets = m_schematic.GetSheets();
|
||||
|
||||
// Restore all of the loaded symbol instances from the root sheet screen.
|
||||
if( m_schematic.RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
|
||||
sheets.UpdateSymbolInstances( m_schematic.RootScreen()->GetSymbolInstances() );
|
||||
sheets.UpdateSymbolInstanceData( m_schematic.RootScreen()->GetSymbolInstances());
|
||||
|
||||
if( m_schematic.RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
|
||||
sheets.UpdateSheetInstances( m_schematic.RootScreen()->GetSheetInstances() );
|
||||
sheets.UpdateSheetInstanceData( m_schematic.RootScreen()->GetSheetInstances());
|
||||
|
||||
sheets.AnnotatePowerSymbols();
|
||||
|
||||
|
|
Loading…
Reference in New Issue