Simulation bug fixes.
1) Use C-locale when converting output of parsers to strings. 2) InferSimModel() must run on local copy of fields, not the fields in the symbol (which might be different if they've already been edited in the Symbol Properties Dialog, for instance). 3) InferSimModel() should accept a deviceType already set to RLC. 4) Don't output trailing decimal separators if there's no fraction.
This commit is contained in:
parent
f601c87cea
commit
58ce0bb804
|
@ -139,8 +139,8 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
|||
wxString pinMap;
|
||||
|
||||
// Infer RLC and VI models if they aren't specified
|
||||
if( SIM_MODEL::InferSimModel<T_symbol, T_field>( m_symbol, false, SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&deviceType, &modelType, &modelParams, &pinMap ) )
|
||||
if( SIM_MODEL::InferSimModel( m_symbol, &m_fields, false, SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&deviceType, &modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
m_fields.emplace_back( &m_symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
m_fields.back().SetText( deviceType );
|
||||
|
|
|
@ -238,10 +238,9 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
wxString pinMap;
|
||||
|
||||
// Infer RLC and VI models if they aren't specified
|
||||
if( SIM_MODEL::InferSimModel<SCH_SYMBOL, SCH_FIELD>( *symbol, true,
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SPICE,
|
||||
&deviceType, &modelType,
|
||||
&modelParams, &pinMap ) )
|
||||
if( SIM_MODEL::InferSimModel( *symbol, &spiceItem.fields, true,
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SPICE, &deviceType,
|
||||
&modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
spiceItem.fields.emplace_back( symbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
spiceItem.fields.back().SetText( deviceType );
|
||||
|
|
|
@ -203,10 +203,8 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
|
|||
wxString pinMap;
|
||||
|
||||
// Infer RLC and VI models if they aren't specified
|
||||
if( SIM_MODEL::InferSimModel<SCH_SYMBOL, SCH_FIELD>( aSymbol, true,
|
||||
SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&deviceType, &modelType, &modelParams,
|
||||
&pinMap ) )
|
||||
if( SIM_MODEL::InferSimModel( aSymbol, &fields, true, SIM_VALUE_GRAMMAR::NOTATION::SI,
|
||||
&deviceType, &modelType, &modelParams, &pinMap ) )
|
||||
{
|
||||
fields.emplace_back( &aSymbol, -1, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
fields.back().SetText( deviceType );
|
||||
|
|
|
@ -524,7 +524,8 @@ template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<LIB_FIE
|
|||
|
||||
|
||||
template <typename T>
|
||||
std::string SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName )
|
||||
std::string SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName,
|
||||
bool aResolve )
|
||||
{
|
||||
static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
|
||||
|
||||
|
@ -537,17 +538,19 @@ std::string SIM_MODEL::GetFieldValue( const std::vector<T>* aFields, const std::
|
|||
return field.GetName() == aFieldName;
|
||||
} );
|
||||
|
||||
if( it != aFields->end() )
|
||||
if( it == aFields->end() )
|
||||
return "";
|
||||
else if( aResolve )
|
||||
return std::string( it->GetShownText().ToUTF8() );
|
||||
else
|
||||
return std::string( it->GetText().ToUTF8() );
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// This specialization is used when no fields are passed.
|
||||
template <>
|
||||
std::string SIM_MODEL::GetFieldValue( const std::vector<void>* aFields,
|
||||
const std::string& aFieldName )
|
||||
const std::string& aFieldName, bool aResolve )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
@ -1050,7 +1053,7 @@ bool SIM_MODEL::requiresSpiceModelLine() const
|
|||
|
||||
|
||||
template <class T_symbol, class T_field>
|
||||
bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
||||
bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, std::vector<T_field>* aFields, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString* aDeviceType,
|
||||
wxString* aModelType, wxString* aModelParams, wxString* aPinMap )
|
||||
{
|
||||
|
@ -1071,38 +1074,25 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
|||
return units;
|
||||
};
|
||||
|
||||
auto getFieldValue =
|
||||
[&]( const wxString& fieldName ) -> wxString
|
||||
{
|
||||
T_field* field = aSymbol.FindField( fieldName );
|
||||
|
||||
if( field )
|
||||
{
|
||||
if( aResolve )
|
||||
return field->GetShownText();
|
||||
else
|
||||
return field->GetText();
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
};
|
||||
|
||||
wxString prefix = aSymbol.GetPrefix();
|
||||
wxString value = getFieldValue( VALUE_FIELD );
|
||||
wxString value = GetFieldValue( aFields, VALUE_FIELD, aResolve );
|
||||
std::vector<LIB_PIN*> pins = aSymbol.GetAllLibPins();
|
||||
|
||||
*aDeviceType = getFieldValue( DEVICE_TYPE_FIELD );
|
||||
*aModelType = getFieldValue( TYPE_FIELD );
|
||||
*aModelParams = getFieldValue( PARAMS_FIELD );
|
||||
*aPinMap = getFieldValue( PINS_FIELD );
|
||||
*aDeviceType = GetFieldValue( aFields, DEVICE_TYPE_FIELD, aResolve );
|
||||
*aModelType = GetFieldValue( aFields, TYPE_FIELD, aResolve );
|
||||
*aModelParams = GetFieldValue( aFields, PARAMS_FIELD, aResolve );
|
||||
*aPinMap = GetFieldValue( aFields, PINS_FIELD, aResolve );
|
||||
|
||||
if( pins.size() != 2 )
|
||||
return false;
|
||||
|
||||
if( aDeviceType->IsEmpty()
|
||||
&& aModelType->IsEmpty()
|
||||
&& !value.IsEmpty()
|
||||
&& ( prefix.StartsWith( "R" ) || prefix.StartsWith( "L" ) || prefix.StartsWith( "C" ) ) )
|
||||
if( ( ( *aDeviceType == "R" || *aDeviceType == "L" || *aDeviceType == "C" )
|
||||
&& aModelType->IsEmpty() )
|
||||
||
|
||||
( aDeviceType->IsEmpty()
|
||||
&& aModelType->IsEmpty()
|
||||
&& !value.IsEmpty()
|
||||
&& ( prefix.StartsWith( "R" ) || prefix.StartsWith( "L" ) || prefix.StartsWith( "C" ) ) ) )
|
||||
{
|
||||
if( aDeviceType->IsEmpty() )
|
||||
*aDeviceType = prefix.Left( 1 );
|
||||
|
@ -1123,7 +1113,7 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
|||
wxString valueExponent( idealVal.GetMatch( value, 2 ) );
|
||||
wxString valueFraction( idealVal.GetMatch( value, 6 ) );
|
||||
|
||||
if( valueMantissa.Contains( wxT( "." ) ) )
|
||||
if( valueMantissa.Contains( wxT( "." ) ) || valueFraction.IsEmpty() )
|
||||
{
|
||||
aModelParams->Printf( wxT( "%s=\"%s%s\"" ),
|
||||
prefix.Left(1).Lower(),
|
||||
|
@ -1152,13 +1142,13 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
|||
return true;
|
||||
}
|
||||
|
||||
if( ( ( *aDeviceType == wxT( "V" ) || *aDeviceType == wxT( "I" ) )
|
||||
&& aModelType->IsEmpty() )
|
||||
||
|
||||
( aDeviceType->IsEmpty()
|
||||
&& aModelType->IsEmpty()
|
||||
&& !value.IsEmpty()
|
||||
&& ( prefix.StartsWith( "V" ) || prefix.StartsWith( "I" ) ) ) )
|
||||
if( ( ( *aDeviceType == wxT( "V" ) || *aDeviceType == wxT( "I" ) )
|
||||
&& aModelType->IsEmpty() )
|
||||
||
|
||||
( aDeviceType->IsEmpty()
|
||||
&& aModelType->IsEmpty()
|
||||
&& !value.IsEmpty()
|
||||
&& ( prefix.StartsWith( "V" ) || prefix.StartsWith( "I" ) ) ) )
|
||||
{
|
||||
if( aDeviceType->IsEmpty() )
|
||||
*aDeviceType = prefix.Left( 1 );
|
||||
|
@ -1185,7 +1175,7 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
|||
wxString valueExponent( sourceVal.GetMatch( value, 2 ) );
|
||||
wxString valueFraction( sourceVal.GetMatch( value, 6 ) );
|
||||
|
||||
if( valueMantissa.Contains( wxT( "." ) ) )
|
||||
if( valueMantissa.Contains( wxT( "." ) ) || valueFraction.IsEmpty() )
|
||||
{
|
||||
aModelParams->Printf( wxT( "dc=\"%s%s\"" ),
|
||||
valueMantissa,
|
||||
|
@ -1215,13 +1205,17 @@ bool SIM_MODEL::InferSimModel( T_symbol& aSymbol, bool aResolve,
|
|||
}
|
||||
|
||||
|
||||
template bool SIM_MODEL::InferSimModel<SCH_SYMBOL, SCH_FIELD>( SCH_SYMBOL& aSymbol, bool aResolve,
|
||||
template bool SIM_MODEL::InferSimModel<SCH_SYMBOL, SCH_FIELD>( SCH_SYMBOL& aSymbol,
|
||||
std::vector<SCH_FIELD>* aFields,
|
||||
bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation,
|
||||
wxString* aDeviceType,
|
||||
wxString* aModelType,
|
||||
wxString* aModelParams,
|
||||
wxString* aPinMap );
|
||||
template bool SIM_MODEL::InferSimModel<LIB_SYMBOL, LIB_FIELD>( LIB_SYMBOL& aSymbol, bool aResolve,
|
||||
template bool SIM_MODEL::InferSimModel<LIB_SYMBOL, LIB_FIELD>( LIB_SYMBOL& aSymbol,
|
||||
std::vector<LIB_FIELD>* aFields,
|
||||
bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation,
|
||||
wxString* aDeviceType,
|
||||
wxString* aModelType,
|
||||
|
|
|
@ -415,7 +415,8 @@ public:
|
|||
const std::vector<LIB_PIN*>& aPins );
|
||||
|
||||
template <typename T>
|
||||
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName );
|
||||
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName,
|
||||
bool aResolve = true );
|
||||
|
||||
template <typename T>
|
||||
static void SetFieldValue( std::vector<T>& aFields, const std::string& aFieldName,
|
||||
|
@ -519,7 +520,7 @@ public:
|
|||
virtual void SwitchSingleEndedDiff( bool aDiff ) { };
|
||||
|
||||
template <class T_symbol, class T_field>
|
||||
static bool InferSimModel( T_symbol& aSymbol, bool aResolve,
|
||||
static bool InferSimModel( T_symbol& aSymbol, std::vector<T_field>* aFields, bool aResolve,
|
||||
SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString* aDeviceType,
|
||||
wxString* aModelType, wxString* aModelParams, wxString* aPinMap );
|
||||
|
||||
|
|
|
@ -509,6 +509,8 @@ bool SIM_VALUE_FLOAT::FromString( const std::string& aString, NOTATION aNotation
|
|||
|
||||
try
|
||||
{
|
||||
LOCALE_IO toggle;
|
||||
|
||||
m_value = std::stod( parseResult.significand ) * std::pow( 10, exponent );
|
||||
}
|
||||
catch( const std::invalid_argument& )
|
||||
|
|
Loading…
Reference in New Issue