From c7859e7ed71a9abc9232ba6278ad3c035be5774f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 2 Sep 2024 09:49:06 +0100 Subject: [PATCH] Clean up (and better comment) referential model handling. --- eeschema/sim/sim_model.cpp | 1 - eeschema/sim/sim_model.h | 1 - eeschema/sim/sim_model_spice.cpp | 7 ++--- eeschema/sim/sim_model_spice.h | 3 +- eeschema/sim/spice_library_parser.cpp | 6 ++-- eeschema/sim/spice_library_parser.h | 2 +- eeschema/sim/spice_model_parser.cpp | 40 +++++++++++++++++---------- eeschema/sim/spice_model_parser.h | 4 +-- 8 files changed, 36 insertions(+), 28 deletions(-) diff --git a/eeschema/sim/sim_model.cpp b/eeschema/sim/sim_model.cpp index ee152f4329..6bb60480eb 100644 --- a/eeschema/sim/sim_model.cpp +++ b/eeschema/sim/sim_model.cpp @@ -376,7 +376,6 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType ) case TYPE::KIBIS_DRIVER_PRBS: return { "X" }; case TYPE::NONE: - case TYPE::REFERENTIAL: case TYPE::RAWSPICE: return {}; default: wxFAIL; return {}; diff --git a/eeschema/sim/sim_model.h b/eeschema/sim/sim_model.h index db54802ea4..5615847b36 100644 --- a/eeschema/sim/sim_model.h +++ b/eeschema/sim/sim_model.h @@ -280,7 +280,6 @@ public: I_RANDPOISSON, I_BEHAVIORAL, - REFERENTIAL, SUBCKT, XSPICE, diff --git a/eeschema/sim/sim_model_spice.cpp b/eeschema/sim/sim_model_spice.cpp index a1aa3152f2..db270f353c 100644 --- a/eeschema/sim/sim_model_spice.cpp +++ b/eeschema/sim/sim_model_spice.cpp @@ -55,12 +55,11 @@ std::string SPICE_GENERATOR_SPICE::Preview( const SPICE_ITEM& aItem ) const std::unique_ptr SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode, - bool aSkipReferential, - REPORTER& aReporter ) + bool aFirstPass, REPORTER& aReporter ) { - SIM_MODEL::TYPE type = SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode, aSkipReferential ); + SIM_MODEL::TYPE type = SIM_MODEL::TYPE::NONE; - if( type == SIM_MODEL::TYPE::REFERENTIAL ) + if( !SPICE_MODEL_PARSER::ReadType( aLibrary, aSpiceCode, &type, aFirstPass ) ) return nullptr; std::unique_ptr model = SIM_MODEL::Create( type ); diff --git a/eeschema/sim/sim_model_spice.h b/eeschema/sim/sim_model_spice.h index e2122aef0d..1267e02c77 100644 --- a/eeschema/sim/sim_model_spice.h +++ b/eeschema/sim/sim_model_spice.h @@ -49,8 +49,7 @@ public: static std::unique_ptr Create( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode, - bool aSkipReferential, - REPORTER& aReporter ); + bool aFirstPass, REPORTER& aReporter ); SIM_MODEL_SPICE( TYPE aType, std::unique_ptr aSpiceGenerator ); diff --git a/eeschema/sim/spice_library_parser.cpp b/eeschema/sim/spice_library_parser.cpp index f3deac093c..e271d92713 100644 --- a/eeschema/sim/spice_library_parser.cpp +++ b/eeschema/sim/spice_library_parser.cpp @@ -128,10 +128,10 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor } auto createModel = - [&]( int ii, bool aSkipReferential ) + [&]( int ii, bool firstPass ) { m_library.m_models[ii] = SIM_MODEL_SPICE::Create( m_library, modelQueue[ii].second, - aSkipReferential, aReporter ); + firstPass, aReporter ); }; // Read all self-contained models in parallel @@ -145,7 +145,7 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor } ); tp.wait_for_tasks(); - // Now read all referential models in order. + // Now read all models that might refer to other models in order. for( int ii = 0; ii < (int) modelQueue.size(); ++ii ) { if( !m_library.m_models[ii] ) diff --git a/eeschema/sim/spice_library_parser.h b/eeschema/sim/spice_library_parser.h index 3a8a401ec4..c4b6f44150 100644 --- a/eeschema/sim/spice_library_parser.h +++ b/eeschema/sim/spice_library_parser.h @@ -41,7 +41,7 @@ public: virtual ~SPICE_LIBRARY_PARSER() {}; - virtual void ReadFile( const wxString& aFilePath, REPORTER& aReporter ); + virtual void ReadFile( const wxString& aFilePath, REPORTER& firstPass ); protected: void parseFile( const wxString& aFilePath, REPORTER& aReporter, diff --git a/eeschema/sim/spice_model_parser.cpp b/eeschema/sim/spice_model_parser.cpp index f47a1b075a..7960d8af34 100644 --- a/eeschema/sim/spice_model_parser.cpp +++ b/eeschema/sim/spice_model_parser.cpp @@ -59,9 +59,11 @@ namespace SIM_MODEL_SPICE_PARSER } -SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, - const std::string& aSpiceCode, bool aSkipReferential ) +bool SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode, + SIM_MODEL::TYPE* aType, bool aFirstPass ) { + *aType = SIM_MODEL::TYPE::NONE; + tao::pegtl::string_input<> in( aSpiceCode, "Spice_Code" ); std::unique_ptr root; @@ -76,15 +78,17 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, catch( const tao::pegtl::parse_error& e ) { wxLogTrace( traceSpiceModelParser, wxS( "%s" ), e.what() ); - return SIM_MODEL::TYPE::NONE; + return true; } for( const auto& node : root->children ) { if( node->is_type() ) { - if( aSkipReferential ) - return SIM_MODEL::TYPE::REFERENTIAL; + // The first pass of model loading is done in parallel, so we can't (yet) look + // up our reference model. + if( aFirstPass ) + return false; std::string modelName = node->children.at( 0 )->string(); std::string akoName = node->children.at( 1 )->string(); @@ -98,7 +102,8 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, modelName ) ); } - return sourceModel->GetType(); + *aType = sourceModel->GetType(); + return true; } else if( node->is_type() ) { @@ -119,7 +124,10 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, SIM_MODEL::TYPE type = ReadTypeFromSpiceStrings( typeString ); if( type != SIM_MODEL::TYPE::RAWSPICE ) - return type; + { + *aType = type; + return true; + } } else if( subnode->is_type() ) { @@ -137,7 +145,7 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, else { wxFAIL_MSG( "Unhandled parse tree subnode" ); - return SIM_MODEL::TYPE::NONE; + return true; } } @@ -145,24 +153,28 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, // `version` variables into account too. This is suboptimal since we read the model // twice this way, and moreover the code is now somewhat duplicated. - return ReadTypeFromSpiceStrings( typeString, level, version, false ); + *aType = ReadTypeFromSpiceStrings( typeString, level, version, false ); + return true; } else if( node->is_type() ) { - if( aSkipReferential ) - return SIM_MODEL::TYPE::REFERENTIAL; + // The first pass of model loading is done in parallel, so we can't (yet) refer to + // any other models in a subcircuit. + if( aFirstPass ) + return false; - return SIM_MODEL::TYPE::SUBCKT; + *aType = SIM_MODEL::TYPE::SUBCKT; + return true; } else { wxFAIL_MSG( "Unhandled parse tree node" ); - return SIM_MODEL::TYPE::NONE; + return true; } } wxFAIL_MSG( "Could not derive type from SPICE code" ); - return SIM_MODEL::TYPE::NONE; + return true; } diff --git a/eeschema/sim/spice_model_parser.h b/eeschema/sim/spice_model_parser.h index b8d5181104..be1ed9c0cb 100644 --- a/eeschema/sim/spice_model_parser.h +++ b/eeschema/sim/spice_model_parser.h @@ -34,8 +34,8 @@ class SIM_LIBRARY_SPICE; class SPICE_MODEL_PARSER { public: - static SIM_MODEL::TYPE ReadType( const SIM_LIBRARY_SPICE& aLibrary, - const std::string& aSpiceCode, bool aSkipReferential ); + static bool ReadType( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode, + SIM_MODEL::TYPE* aType, bool aFirstPass ); SPICE_MODEL_PARSER( SIM_MODEL_SPICE& aModel ) : m_model( aModel ) {} virtual ~SPICE_MODEL_PARSER() = default;