Allow inferred voltage/current sources to have a single float in Value

Update Opamp test to use this feature.
This commit is contained in:
Mikolaj Wielgus 2022-08-24 06:13:55 +02:00
parent e30f059b43
commit 8a6a0ff7dc
9 changed files with 87 additions and 97 deletions

View File

@ -55,6 +55,11 @@ namespace SIM_MODEL_PARSER
template <> struct fieldParamValuePairsSelector<unquotedString> : std::true_type {};
template <typename Rule> struct fieldFloatValueSelector : std::false_type {};
template <> struct fieldFloatValueSelector<number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>>
: std::true_type {};
template <typename Rule> struct pinSequenceSelector : std::false_type {};
template <> struct pinSequenceSelector<pinNumber> : std::true_type {};
}
@ -1316,7 +1321,7 @@ void SIM_MODEL::ParseParamsField( const wxString& aParamsField )
THROW_IO_ERROR( e.what() );
}
wxString paramName = "";
wxString paramName;
for( const auto& node : root->children )
{
@ -1516,26 +1521,52 @@ void SIM_MODEL::doReadDataFields( unsigned aSymbolPinCount, const std::vector<T>
template <typename T>
void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields )
void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields,
bool aAllowOnlyFirstValue,
bool aAllowParamValuePairs )
{
ParsePinsField( aSymbolPinCount, GetFieldValue( aFields, PINS_FIELD ) );
if( InferTypeFromRefAndValue( GetFieldValue( aFields, REFERENCE_FIELD ),
GetFieldValue( aFields, VALUE_FIELD ) ) == GetType() )
GetFieldValue( aFields, VALUE_FIELD ) ) != GetType() )
{
ParseParamsField( GetFieldValue( aFields, VALUE_FIELD ) );
m_isInferred = true;
// Not an inferred model. Nothing to do here.
return;
}
else if( GetFieldValue( aFields, VALUE_FIELD ) == DeviceTypeInfo( GetDeviceType() ).fieldValue )
wxString valueField = GetFieldValue( aFields, VALUE_FIELD );
if( aAllowParamValuePairs ) // The usual param-value pairs have precedence.
{
m_isInferred = true;
try
{
ParseParamsField( GetFieldValue( aFields, VALUE_FIELD ) );
}
catch( const IO_ERROR& e )
{
if( aAllowOnlyFirstValue )
SetParamValue( 0, parseFieldFloatValue( valueField ) );
else
throw e;
}
}
else if( aAllowOnlyFirstValue )
{
// This is reached only when model allows only the first value.
SetParamValue( 0, parseFieldFloatValue( valueField ) );
}
m_isInferred = true;
}
template void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount,
const std::vector<SCH_FIELD>* aFields );
const std::vector<SCH_FIELD>* aFields,
bool aAllowOnlyFirstValue,
bool aAllowParamValuePairs );
template void SIM_MODEL::InferredReadDataFields( unsigned aSymbolPinCount,
const std::vector<LIB_FIELD>* aFields );
const std::vector<LIB_FIELD>* aFields,
bool aAllowOnlyFirstValue,
bool aAllowParamValuePairs );
template <typename T>
@ -1589,6 +1620,26 @@ wxString SIM_MODEL::generateDisabledField() const
}
wxString SIM_MODEL::parseFieldFloatValue( wxString aFieldFloatValue )
{
try
{
tao::pegtl::string_input<> in( aFieldFloatValue.ToUTF8(), "Value" );
auto root = tao::pegtl::parse_tree::parse<
SIM_MODEL_PARSER::fieldFloatValueGrammar,
SIM_MODEL_PARSER::fieldFloatValueSelector>
( in );
return root->children[0]->string();
}
catch( const tao::pegtl::parse_error& )
{
THROW_IO_ERROR( wxString::Format( _( "Failed to infer model from Value '%s'" ),
aFieldFloatValue ) );
}
}
bool SIM_MODEL::requiresSpiceModel() const
{
for( const PARAM& param : GetParams() )

View File

@ -579,7 +579,9 @@ protected:
= SIM_VALUE_GRAMMAR::NOTATION::SPICE );
template <typename T>
void InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
void InferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields,
bool aAllowOnlyFirstValue = false,
bool aAllowParamValuePairs = true );
wxString m_spiceCode;
@ -597,17 +599,18 @@ private:
template <typename T>
void doWriteFields( std::vector<T>& aFields ) const;
virtual std::vector<wxString> getPinNames() const { return {}; }
wxString generateDeviceTypeField() const;
wxString generateTypeField() const;
wxString generatePinsField() const;
wxString generateDisabledField() const;
wxString parseFieldFloatValue( wxString aFieldFloatValue );
virtual bool requiresSpiceModel() const;
virtual std::vector<wxString> getPinNames() const { return {}; }
const SIM_MODEL* m_baseModel;

View File

@ -29,16 +29,6 @@
using PARAM = SIM_MODEL::PARAM;
namespace SIM_MODEL_PARSER
{
using namespace SIM_MODEL_GRAMMAR;
template <typename Rule> struct fieldFloatValueSelector : std::false_type {};
template <> struct fieldFloatValueSelector<number<SIM_VALUE::TYPE_FLOAT, NOTATION::SI>>
: std::true_type {};
};
SIM_MODEL_IDEAL::SIM_MODEL_IDEAL( TYPE aType )
: SIM_MODEL( aType ),
m_isInferred( false )
@ -64,7 +54,7 @@ void SIM_MODEL_IDEAL::ReadDataSchFields( unsigned aSymbolPinCount,
if( GetFieldValue( aFields, PARAMS_FIELD ) != "" )
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
else
inferredReadDataFields( aSymbolPinCount, aFields );
InferredReadDataFields( aSymbolPinCount, aFields, true, false );
}
@ -74,7 +64,7 @@ void SIM_MODEL_IDEAL::ReadDataLibFields( unsigned aSymbolPinCount,
if( GetFieldValue( aFields, PARAMS_FIELD ) != "" )
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
else
inferredReadDataFields( aSymbolPinCount, aFields );
InferredReadDataFields( aSymbolPinCount, aFields, true, false );
}
@ -116,42 +106,6 @@ wxString SIM_MODEL_IDEAL::GenerateSpiceItemLine( const wxString& aRefName,
}
template <typename T>
void SIM_MODEL_IDEAL::inferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields )
{
ParsePinsField( aSymbolPinCount, GetFieldValue( aFields, PINS_FIELD ) );
if( InferTypeFromRefAndValue( GetFieldValue( aFields, REFERENCE_FIELD ),
GetFieldValue( aFields, VALUE_FIELD ) ) == GetType() )
{
try
{
wxString value = GetFieldValue( aFields, VALUE_FIELD );
tao::pegtl::string_input<> in( value.ToUTF8(), "Value" );
auto root = tao::pegtl::parse_tree::parse<
SIM_MODEL_PARSER::fieldFloatValueGrammar,
SIM_MODEL_PARSER::fieldFloatValueSelector>
( in );
// The grammar and selector must guarantee having at least one child.
SetParamValue( 0, root->children[0]->string() );
}
catch( const tao::pegtl::parse_error& )
{
THROW_IO_ERROR( wxString::Format( _( "Failed to infer model from Value '%s'" ),
GetFieldValue( aFields, VALUE_FIELD ) ) );
}
m_isInferred = true;
return;
}
if( GetFieldValue( aFields, VALUE_FIELD ) == DeviceTypeInfo( GetDeviceType() ).fieldValue )
m_isInferred = true;
}
template <typename T>
void SIM_MODEL_IDEAL::inferredWriteDataFields( std::vector<T>& aFields ) const
{

View File

@ -47,9 +47,6 @@ public:
private:
template <typename T>
void inferredReadDataFields( unsigned aSymbolPinCount, const std::vector<T>* aFields );
template <typename T>
void inferredWriteDataFields( std::vector<T>& aFields ) const;

View File

@ -54,7 +54,7 @@ void SIM_MODEL_SOURCE::ReadDataSchFields( unsigned aSymbolPinCount,
if( GetFieldValue( aFields, PARAMS_FIELD ) != "" )
SIM_MODEL::ReadDataSchFields( aSymbolPinCount, aFields );
else
InferredReadDataFields( aSymbolPinCount, aFields );
InferredReadDataFields( aSymbolPinCount, aFields, true );
}
@ -64,7 +64,7 @@ void SIM_MODEL_SOURCE::ReadDataLibFields( unsigned aSymbolPinCount,
if( GetFieldValue( aFields, PARAMS_FIELD ) != "" )
SIM_MODEL::ReadDataLibFields( aSymbolPinCount, aFields );
else
InferredReadDataFields( aSymbolPinCount, aFields );
InferredReadDataFields( aSymbolPinCount, aFields, true );
}
@ -242,8 +242,12 @@ bool SIM_MODEL_SOURCE::SetParamValue( unsigned aParamIndex, const wxString& aVal
// them out automatically. If a value is nulled, delete everything after it.
if( aValue == "" )
{
for( int paramIndex = aParamIndex; paramIndex < GetParamCount(); ++paramIndex )
for( int paramIndex = static_cast<int>( aParamIndex );
paramIndex < GetParamCount();
++paramIndex )
{
SIM_MODEL::SetParamValue( paramIndex, "", aNotation );
}
}
else
{

View File

@ -63,7 +63,8 @@ public:
const std::vector<wxString>& aPinNetNames ) const override;
bool SetParamValue( unsigned aParamIndex, const wxString& aValue,
SIM_VALUE_GRAMMAR::NOTATION aNotation ) override;
SIM_VALUE_GRAMMAR::NOTATION aNotation = SIM_VALUE_GRAMMAR::NOTATION::SI )
override;
bool HasAutofill() const override { return true; }

View File

@ -265,9 +265,11 @@
}
],
"meta": {
"version": 2
"version": 3
},
"net_colors": null
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {

View File

@ -1,4 +1,4 @@
(kicad_sch (version 20220622) (generator eeschema)
(kicad_sch (version 20220820) (generator eeschema)
(uuid fd5567b0-04f0-4d9e-b647-1775367d8ff4)
@ -404,18 +404,6 @@
(property "Datasheet" "~" (id 3) (at 153.67 76.2 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Device" "V" (id 4) (at 153.67 76.2 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Type" "DC" (id 5) (at 153.67 76.2 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Pins" "1 2" (id 6) (at 153.67 76.2 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Params" "dc=5" (id 7) (at 160.02 78.74 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 885c89aa-c780-4741-b398-9d4b8e38f094))
(pin "2" (uuid 8a2dca0c-b99f-4109-a426-af5e80ea91fe))
)
@ -528,18 +516,6 @@
(property "Datasheet" "~" (id 3) (at 153.67 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Device" "V" (id 4) (at 153.67 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Type" "DC" (id 5) (at 153.67 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Pins" "1 2" (id 6) (at 153.67 101.6 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Sim_Params" "dc=5" (id 7) (at 160.02 104.14 0)
(effects (font (size 1.27 1.27)))
)
(pin "1" (uuid 62bdf880-7061-4b86-be3a-09bf959fae21))
(pin "2" (uuid 9bd26aa2-337b-4c5a-a9de-bdab770672a9))
)
@ -591,10 +567,10 @@
(reference "U1") (unit 1) (value "OPAMP") (footprint "")
)
(path "/383ea298-1cb3-473e-8fce-19d3c7ac3912"
(reference "V2") (unit 1) (value "VDC") (footprint "")
(reference "V2") (unit 1) (value "5") (footprint "")
)
(path "/d2018f30-5def-453e-85fe-dac327cfbe9b"
(reference "V3") (unit 1) (value "VDC") (footprint "")
(reference "V3") (unit 1) (value "5") (footprint "")
)
(path "/10f44001-5f65-44eb-a535-b7b3c67d5b83"
(reference "VSIN1") (unit 1) (value "ampl=500m f=1k") (footprint "")

View File

@ -299,6 +299,8 @@ BOOST_AUTO_TEST_CASE( Opamp )
BOOST_AUTO_TEST_CASE( NpnCeAmp )
{
// This test intentionally uses non-inferred voltage sources to test them.
TestNetlist( "npn_ce_amp" );
TestTranPoint( 900e-6, { { "V(/in)", 0 }, { "V(/out)", 5.32 } } );
TestTranPoint( 925e-6, { { "V(/in)", 10e-3 }, { "V(/out)", 5.30 } } );