From 03af8dcc8865eaefdabbd485b6956e65930e978d Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 4 Mar 2024 14:24:00 +0000 Subject: [PATCH] Convert OP text variables pin names/numbers to SPICE vectors. Also fixes a wrap-around bug in SPICE_VALUE::Normalize() where it would lose the run of itself if the value was already normalized to either the largest or smallest UNIT_PREFIX. Fixes https://gitlab.com/kicad/code/kicad/-/issues/17228 (cherry picked from commit ff8ddae9bd65e44a040f19f3dea8bdf28d4fd6bf) --- eeschema/sch_symbol.cpp | 61 ++++++++++++++++++++++++----- eeschema/sim/sim_lib_mgr.cpp | 11 ++++-- eeschema/sim/simulator_frame_ui.cpp | 5 ++- eeschema/sim/spice_value.cpp | 12 +++--- 4 files changed, 70 insertions(+), 19 deletions(-) diff --git a/eeschema/sch_symbol.cpp b/eeschema/sch_symbol.cpp index 9941c15f5a..c1d3d40d3a 100644 --- a/eeschema/sch_symbol.cpp +++ b/eeschema/sch_symbol.cpp @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -1285,7 +1288,7 @@ bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, i { static wxRegEx operatingPoint( wxT( "^" "OP" - "(:[a-zA-Z]*)?" // port + "(:[^.]*)?" // pin "(.([0-9])?([a-zA-Z]*))?" // format "$" ) ); @@ -1298,26 +1301,66 @@ bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, i if( operatingPoint.Matches( *token ) ) { - wxString port( operatingPoint.GetMatch( *token, 1 ) ); + wxString pin( operatingPoint.GetMatch( *token, 1 ).Lower() ); wxString precisionStr( operatingPoint.GetMatch( *token, 3 ) ); wxString range( operatingPoint.GetMatch( *token, 4 ) ); - - wxString signal = GetRef( aPath ) + port; int precision = 3; if( !precisionStr.IsEmpty() ) precision = precisionStr[0] - '0'; if( range.IsEmpty() ) + range = wxS( "~A" ); + + SIM_LIB_MGR simLibMgr( &schematic->Prj() ); + NULL_REPORTER devnull; + SIM_MODEL& model = simLibMgr.CreateModel( aPath, const_cast( *this ), + devnull ).model; + SPICE_ITEM spiceItem; + spiceItem.refName = GetRef( aPath ); + + wxString spiceRef = model.SpiceGenerator().ItemName( spiceItem ); + spiceRef = spiceRef.Lower(); + + if( pin.IsEmpty() ) { - if( port == wxS( ":power" ) ) + *token = schematic->GetOperatingPoint( spiceRef, precision, range ); + return true; + } + else if( pin == wxS( ":power" ) ) + { + if( range.IsEmpty() ) range = wxS( "~W" ); - else - range = wxS( "~A" ); + + *token = schematic->GetOperatingPoint( spiceRef + wxS( ":power" ), precision, range ); + return true; + } + else + { + pin = pin.SubString( 1, -1 ); // Strip ':' from front + + for( const std::reference_wrapper& modelPin : model.GetPins() ) + { + SCH_PIN* symbolPin = GetPin( modelPin.get().symbolPinNumber ); + + if( pin == symbolPin->GetName().Lower() || pin == symbolPin->GetNumber().Lower() ) + { + if( model.GetPins().size() == 2 ) + { + *token = schematic->GetOperatingPoint( spiceRef, precision, range ); + } + else + { + wxString signalName = spiceRef + wxS( ":" ) + modelPin.get().name; + *token = schematic->GetOperatingPoint( signalName, precision, range ); + } + + return true; + } + } } - *token = schematic->GetOperatingPoint( signal.Lower(), precision, range ); - + *token = wxS( "?" ); return true; } diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index 2835907089..88a80f97e5 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -202,12 +202,17 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S for( const SCH_FIELD& field : aSymbol.GetFields() ) { - fields.emplace_back( VECTOR2I(), -1, &aSymbol, field.GetName() ); - if( field.GetId() == REFERENCE_FIELD ) + { + fields.emplace_back( VECTOR2I(), -1, &aSymbol, field.GetName() ); fields.back().SetText( aSymbol.GetRef( aSheetPath ) ); - else + } + else if( field.GetId() == VALUE_FIELD + || field.GetName().StartsWith( wxS( "Sim." ) ) ) + { + fields.emplace_back( VECTOR2I(), -1, &aSymbol, field.GetName() ); fields.back().SetText( field.GetShownText( aSheetPath, false ) ); + } } wxString deviceType; diff --git a/eeschema/sim/simulator_frame_ui.cpp b/eeschema/sim/simulator_frame_ui.cpp index 2a5077490c..3b29c47652 100644 --- a/eeschema/sim/simulator_frame_ui.cpp +++ b/eeschema/sim/simulator_frame_ui.cpp @@ -2795,9 +2795,12 @@ void SIMULATOR_FRAME_UI::OnSimRefresh( bool aFinal ) m_simConsole->AppendText( msg ); m_simConsole->SetInsertionPointEnd(); - if( signal.StartsWith( wxS( "V(" ) ) || signal.StartsWith( wxS( "I(" ) ) ) + if( type == SPT_VOLTAGE || type == SPT_CURRENT || type == SPT_POWER ) signal = signal.SubString( 2, signal.Length() - 2 ); + if( type == SPT_POWER ) + signal += wxS( ":power" ); + m_schematicFrame->Schematic().SetOperatingPoint( signal, val_list.at( 0 ) ); } } diff --git a/eeschema/sim/spice_value.cpp b/eeschema/sim/spice_value.cpp index 44a8cde121..1ae26c62c9 100644 --- a/eeschema/sim/spice_value.cpp +++ b/eeschema/sim/spice_value.cpp @@ -115,20 +115,20 @@ void SPICE_VALUE::Normalize() { while( std::fabs( m_base ) >= 1000.0 ) { - m_base *= 0.001; - m_prefix = (UNIT_PREFIX)( m_prefix + 3 ); - if( m_prefix == PFX_TERA ) // this is the biggest unit available break; + + m_base *= 0.001; + m_prefix = (UNIT_PREFIX)( m_prefix + 3 ); } while( m_base != 0.0 && std::fabs( m_base ) < 1.000 ) { - m_base *= 1000.0; - m_prefix = (UNIT_PREFIX)( m_prefix - 3 ); - if( m_prefix == PFX_FEMTO ) // this is the smallest unit available break; + + m_base *= 1000.0; + m_prefix = (UNIT_PREFIX)( m_prefix - 3 ); } }