From b7cd1dd764a9df485611915a712481a3c07d2bbc Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 22 Mar 2023 01:37:55 +0000 Subject: [PATCH] Handle single-token flag parameters. Also fixes a bug where all VDMOS instance parameters weren't marked as instance parameters. Also fixes a bug where VDMOS thermal models weren't supported (they have two extra pins: Tj and Tcase). (cherry picked from commit 5bda3b99f9992135a4b32985d0a98767e629db5f) --- eeschema/sim/sim_model_ngspice.cpp | 5 +- eeschema/sim/sim_model_ngspice_data.cpp | 74 +++++++++---------- eeschema/sim/sim_model_serializer.cpp | 12 ++- eeschema/sim/sim_model_serializer.h | 17 +++-- eeschema/sim/spice_generator.cpp | 28 +++++-- .../eeschema/sim/test_library_spice.cpp | 31 ++++---- 6 files changed, 100 insertions(+), 67 deletions(-) diff --git a/eeschema/sim/sim_model_ngspice.cpp b/eeschema/sim/sim_model_ngspice.cpp index a3b120657d..04a6b0ec73 100644 --- a/eeschema/sim/sim_model_ngspice.cpp +++ b/eeschema/sim/sim_model_ngspice.cpp @@ -67,9 +67,10 @@ SIM_MODEL_NGSPICE::SIM_MODEL_NGSPICE( TYPE aType ) : for( const SIM_MODEL::PARAM::INFO& paramInfo : modelInfo.instanceParams ) { - // For now, only the geometry parameters. + // For now, only the geometry and flags parameters. if( paramInfo.category == SIM_MODEL::PARAM::CATEGORY::PRINCIPAL - || paramInfo.category == SIM_MODEL::PARAM::CATEGORY::GEOMETRY ) + || paramInfo.category == SIM_MODEL::PARAM::CATEGORY::GEOMETRY + || paramInfo.category == SIM_MODEL::PARAM::CATEGORY::FLAGS ) { AddParam( paramInfo ); } diff --git a/eeschema/sim/sim_model_ngspice_data.cpp b/eeschema/sim/sim_model_ngspice_data.cpp index 4609795f3b..885274a9da 100644 --- a/eeschema/sim/sim_model_ngspice_data.cpp +++ b/eeschema/sim/sim_model_ngspice_data.cpp @@ -1264,7 +1264,7 @@ struct MODEL_INFO_MAP modelInfos[MODEL_TYPE::HFET2].instanceParams.emplace_back( "p", 8, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Power dissipated by the mesfet", true ); - modelInfos[MODEL_TYPE::VDMOS] = { "VDMOS", "NCHAN", "PCHAN", { "D", "G", "S" }, "DMOS model based on Level 1 MOSFET model", {}, {} }; + modelInfos[MODEL_TYPE::VDMOS] = { "VDMOS", "NCHAN", "PCHAN", { "D", "G", "S", "", "" }, "DMOS model based on Level 1 MOSFET model", {}, {} }; // Model parameters modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "type", 116, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_STRING, "", SIM_MODEL::PARAM::CATEGORY::DC, "vdmosn", "vdmosp", "N-channel or P-channel MOS" ); modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "vto", 101, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "Threshold voltage" ); @@ -1336,42 +1336,42 @@ struct MODEL_INFO_MAP modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "rth_ext", 165, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::TEMPERATURE, "1000", "1000", "thermal resistance case to ambient, incl. heat sink" ); modelInfos[MODEL_TYPE::VDMOS].modelParams.emplace_back( "derating", 166, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::DC, "0", "0", "thermal derating for power" ); // Instance parameters - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "m", 9, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::GEOMETRY, "0.5", "0.5", "Multiplier" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "off", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Device initially off" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvds", 3, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial D-S voltage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvgs", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial G-S voltage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "temp", 8, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dtemp", 10, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature difference" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ic", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of D-S, G-S voltages" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "thermal", 11, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Thermal model switch on/off" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "id", 214, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain current" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "is", 6, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1e-14", "1e-14", "Source current" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ig", 5, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate current" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vgs", 217, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source voltage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vds", 218, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source voltage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgs", 201, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Gate-Source capacitance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgd", 202, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain capacitance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cds", 203, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source capacitance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "idio", 223, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Body diode current" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnode", 204, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the drain node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gnode", 205, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the gate node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snode", 206, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the source node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tempnode", 207, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of temperature node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tcasenode", 208, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of 2nd temperature node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnodeprime", 209, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. drain node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snodeprime", 210, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. source node" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "von", 213, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device on state voltage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rs", 224, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Source resistance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "sourceconductance", 211, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of source" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rd", 225, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Drain conductance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "drainconductance", 212, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of drain" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gm", 215, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Transconductance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gds", 216, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source conductance" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgs", 220, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-source charge storage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgd", 222, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-drain charge storage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgs", 219, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source charge storage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgd", 221, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain charge storage" ); - modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instantaneous power" ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "m", 9, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::GEOMETRY, "0.5", "0.5", "Multiplier", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "off", 1, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Device initially off", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvds", 3, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial D-S voltage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "icvgs", 4, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Initial G-S voltage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "temp", 8, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dtemp", 10, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_FLOAT, "deg C", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instance temperature difference", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ic", 2, SIM_MODEL::PARAM::DIR_IN, SIM_VALUE::TYPE_FLOAT_VECTOR, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Vector of D-S, G-S voltages", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "thermal", 11, SIM_MODEL::PARAM::DIR_INOUT, SIM_VALUE::TYPE_BOOL, "", SIM_MODEL::PARAM::CATEGORY::FLAGS, "", "", "Thermal model switch on/off", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "id", 214, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain current", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "is", 6, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "1e-14", "1e-14", "Source current", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "ig", 5, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate current", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vgs", 217, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source voltage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "vds", 218, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source voltage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgs", 201, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Gate-Source capacitance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cgd", 202, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain capacitance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cds", 203, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source capacitance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "idio", 223, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "A", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Body diode current", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnode", 204, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the drain node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gnode", 205, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the gate node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snode", 206, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of the source node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tempnode", 207, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of temperature node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "tcasenode", 208, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of 2nd temperature node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "dnodeprime", 209, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. drain node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "snodeprime", 210, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_INT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Number of int. source node", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "von", 213, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "V", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Device on state voltage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rs", 224, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "ohm", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Source resistance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "sourceconductance", 211, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of source", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "rd", 225, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "0", "0", "Drain conductance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "drainconductance", 212, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Conductance of drain", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gm", 215, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Transconductance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "gds", 216, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Drain-Source conductance", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgs", 220, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-source charge storage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "cqgd", 222, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "F", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Capacitance due to gate-drain charge storage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgs", 219, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Source charge storage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "qgd", 221, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Gate-Drain charge storage", true ); + modelInfos[MODEL_TYPE::VDMOS].instanceParams.emplace_back( "p", 7, SIM_MODEL::PARAM::DIR_OUT, SIM_VALUE::TYPE_FLOAT, "", SIM_MODEL::PARAM::CATEGORY::SUPERFLUOUS, "", "", "Instantaneous power", true ); modelInfos[MODEL_TYPE::MOS1] = { "Mos1", "NMOS", "PMOS", { "D", "G", "S", "B" }, "Level 1 MOSfet model with Meyer capacitance model", {}, {} }; diff --git a/eeschema/sim/sim_model_serializer.cpp b/eeschema/sim/sim_model_serializer.cpp index 08339ef96e..12e87dfb67 100644 --- a/eeschema/sim/sim_model_serializer.cpp +++ b/eeschema/sim/sim_model_serializer.cpp @@ -38,6 +38,7 @@ namespace SIM_MODEL_SERIALIZER_PARSER template struct fieldParamValuePairsSelector : std::false_type {}; template <> struct fieldParamValuePairsSelector : std::true_type {}; + template <> struct fieldParamValuePairsSelector : std::true_type {}; template <> struct fieldParamValuePairsSelector : std::true_type {}; template <> struct fieldParamValuePairsSelector : std::true_type {}; @@ -238,6 +239,12 @@ bool SIM_MODEL_SERIALIZER::ParseParams( const std::string& aParams ) m_model.SetParamValue( paramName, str, SIM_VALUE_GRAMMAR::NOTATION::SI ); } + else if( node->is_type() ) + { + std::string token = node->string(); + + m_model.SetParamValue( token, "1", SIM_VALUE_GRAMMAR::NOTATION::SI ); + } else { wxFAIL; @@ -300,7 +307,10 @@ std::string SIM_MODEL_SERIALIZER::generateParamValuePair( const SIM_MODEL::PARAM name = aParam.info.name.substr( 0, aParam.info.name.length() - 1 ); std::string value = aParam.value; - + + if( aParam.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS ) + return value == "1" ? aParam.info.name : ""; + if( value == "" || value.find( ' ' ) != std::string::npos ) value = fmt::format( "\"{}\"", value ); diff --git a/eeschema/sim/sim_model_serializer.h b/eeschema/sim/sim_model_serializer.h index f79e0411ec..42d264ec71 100644 --- a/eeschema/sim/sim_model_serializer.h +++ b/eeschema/sim/sim_model_serializer.h @@ -62,12 +62,17 @@ namespace SIM_MODEL_SERIALIZER_GRAMMAR quotedStringContent, one<'"'>> {}; - struct fieldParamValuePair : if_must, - one<'='>, - opt, - sor> {}; + struct flagParam : sor {}; // BSIM1 + + struct fieldParamValuePair : sor, + one<'='>, + opt, + sor>> {}; struct fieldParamValuePairs : list {}; struct fieldParamValuePairsGrammar : must, opt, diff --git a/eeschema/sim/spice_generator.cpp b/eeschema/sim/spice_generator.cpp index c719e55d1b..ec83de2278 100644 --- a/eeschema/sim/spice_generator.cpp +++ b/eeschema/sim/spice_generator.cpp @@ -89,10 +89,18 @@ std::string SPICE_GENERATOR::ModelLine( const SPICE_ITEM& aItem ) const if( value == "" ) continue; - result.append( fmt::format( "+{}{}={}\n", - std::string( indentLength - 1, ' ' ), - name, - value ) ); + if( param.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS ) + { + if( value == "1" ) + result.append( fmt::format( "+{}\n", name ) ); + } + else + { + result.append( fmt::format( "+{}{}={}\n", + std::string( indentLength - 1, ' ' ), + name, + value ) ); + } } // Don't send SPICE empty models. @@ -179,8 +187,16 @@ std::string SPICE_GENERATOR::ItemParams() const : param.info.spiceInstanceName; std::string value = SIM_VALUE::ToSpice( param.value ); - if( value != "" ) - result.append( fmt::format( " {}={}", name, value ) ); + if( param.info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS ) + { + if( value == "1" ) + result.append( fmt::format( " {}", name ) ); + } + else + { + if( value != "" ) + result.append( fmt::format( " {}={}", name, value ) ); + } } return result; diff --git a/qa/unittests/eeschema/sim/test_library_spice.cpp b/qa/unittests/eeschema/sim/test_library_spice.cpp index dc487fe1a6..68b20169a8 100644 --- a/qa/unittests/eeschema/sim/test_library_spice.cpp +++ b/qa/unittests/eeschema/sim/test_library_spice.cpp @@ -112,32 +112,33 @@ public: fieldValue = "VD"; } - BOOST_CHECK_EQUAL( aModelName, - fmt::format( "_{}_{}_{}", - aModelIndex, - modelType, - fieldValue ) ); + BOOST_CHECK_EQUAL( aModelName, fmt::format( "_{}_{}_{}", + aModelIndex, + modelType, + fieldValue ) ); for( int i = 0; i < aParamNames.size(); ++i ) { - std::string paramName = aParamNames.at( i ); + std::string paramName = aParamNames.at( i ); + const SIM_MODEL::PARAM* param = aModel.FindParam( paramName ); BOOST_TEST_CONTEXT( "Param name: " << paramName ) { if( i % 10 == 0 ) { - BOOST_CHECK( aModel.FindParam( paramName )->value == "0M" - || aModel.FindParam( paramName )->value == "0" ); + BOOST_CHECK( param->value == "0M" || param->value == "0" ); } - else if( aModel.FindParam( paramName )->info.type == SIM_VALUE::TYPE_INT ) + else if( param->info.type == SIM_VALUE::TYPE_INT ) { - BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value, - fmt::format( "{:d}", i % 10 ) ); + BOOST_CHECK_EQUAL( param->value, fmt::format( "{:d}", i % 10 ) ); + } + else if( param->info.category == SIM_MODEL::PARAM::CATEGORY::FLAGS ) + { + BOOST_CHECK_EQUAL( param->value, "" ); } else { - BOOST_CHECK_EQUAL( aModel.FindParam( paramName )->value, - fmt::format( "{}000.0{}M", i % 10, i % 10 ) ); + BOOST_CHECK_EQUAL( param->value, fmt::format( "{}000.0{}M", i % 10, i % 10 ) ); } } } @@ -1254,7 +1255,7 @@ BOOST_AUTO_TEST_CASE( Fets ) "is_", "vj", "cjo", - "m", + "m_", "fc", "cgdmin", "cgdmax", @@ -1329,7 +1330,7 @@ BOOST_AUTO_TEST_CASE( Fets ) "is_", "vj", "cjo", - "m", + "m_", "fc", "cgdmin", "cgdmax",