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 ff8ddae9bd
)
This commit is contained in:
parent
45e17307a1
commit
03af8dcc88
|
@ -33,6 +33,9 @@
|
|||
#include <sch_symbol.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <schematic.h>
|
||||
#include <sim/sim_model.h>
|
||||
#include <sim/spice_generator.h>
|
||||
#include <sim/sim_lib_mgr.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <trigo.h>
|
||||
#include <refdes_utils.h>
|
||||
|
@ -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<SCH_SYMBOL&>( *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<const SIM_MODEL::PIN>& 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue