mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
Clean up (and better comment) referential model handling.
This commit is contained in:
parent
ee77d06be7
commit
c7859e7ed7
@ -376,7 +376,6 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
|||||||
case TYPE::KIBIS_DRIVER_PRBS: return { "X" };
|
case TYPE::KIBIS_DRIVER_PRBS: return { "X" };
|
||||||
|
|
||||||
case TYPE::NONE:
|
case TYPE::NONE:
|
||||||
case TYPE::REFERENTIAL:
|
|
||||||
case TYPE::RAWSPICE: return {};
|
case TYPE::RAWSPICE: return {};
|
||||||
|
|
||||||
default: wxFAIL; return {};
|
default: wxFAIL; return {};
|
||||||
|
@ -280,7 +280,6 @@ public:
|
|||||||
I_RANDPOISSON,
|
I_RANDPOISSON,
|
||||||
I_BEHAVIORAL,
|
I_BEHAVIORAL,
|
||||||
|
|
||||||
REFERENTIAL,
|
|
||||||
SUBCKT,
|
SUBCKT,
|
||||||
XSPICE,
|
XSPICE,
|
||||||
|
|
||||||
|
@ -55,12 +55,11 @@ std::string SPICE_GENERATOR_SPICE::Preview( const SPICE_ITEM& aItem ) const
|
|||||||
|
|
||||||
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
|
std::unique_ptr<SIM_MODEL_SPICE> SIM_MODEL_SPICE::Create( const SIM_LIBRARY_SPICE& aLibrary,
|
||||||
const std::string& aSpiceCode,
|
const std::string& aSpiceCode,
|
||||||
bool aSkipReferential,
|
bool aFirstPass, REPORTER& aReporter )
|
||||||
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;
|
return nullptr;
|
||||||
|
|
||||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
||||||
|
@ -49,8 +49,7 @@ public:
|
|||||||
|
|
||||||
static std::unique_ptr<SIM_MODEL_SPICE> Create( const SIM_LIBRARY_SPICE& aLibrary,
|
static std::unique_ptr<SIM_MODEL_SPICE> Create( const SIM_LIBRARY_SPICE& aLibrary,
|
||||||
const std::string& aSpiceCode,
|
const std::string& aSpiceCode,
|
||||||
bool aSkipReferential,
|
bool aFirstPass, REPORTER& aReporter );
|
||||||
REPORTER& aReporter );
|
|
||||||
|
|
||||||
SIM_MODEL_SPICE( TYPE aType,
|
SIM_MODEL_SPICE( TYPE aType,
|
||||||
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator );
|
std::unique_ptr<SPICE_GENERATOR> aSpiceGenerator );
|
||||||
|
@ -128,10 +128,10 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto createModel =
|
auto createModel =
|
||||||
[&]( int ii, bool aSkipReferential )
|
[&]( int ii, bool firstPass )
|
||||||
{
|
{
|
||||||
m_library.m_models[ii] = SIM_MODEL_SPICE::Create( m_library, modelQueue[ii].second,
|
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
|
// 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();
|
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 )
|
for( int ii = 0; ii < (int) modelQueue.size(); ++ii )
|
||||||
{
|
{
|
||||||
if( !m_library.m_models[ii] )
|
if( !m_library.m_models[ii] )
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
virtual ~SPICE_LIBRARY_PARSER()
|
virtual ~SPICE_LIBRARY_PARSER()
|
||||||
{};
|
{};
|
||||||
|
|
||||||
virtual void ReadFile( const wxString& aFilePath, REPORTER& aReporter );
|
virtual void ReadFile( const wxString& aFilePath, REPORTER& firstPass );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void parseFile( const wxString& aFilePath, REPORTER& aReporter,
|
void parseFile( const wxString& aFilePath, REPORTER& aReporter,
|
||||||
|
@ -59,9 +59,11 @@ namespace SIM_MODEL_SPICE_PARSER
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary,
|
bool SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode,
|
||||||
const std::string& aSpiceCode, bool aSkipReferential )
|
SIM_MODEL::TYPE* aType, bool aFirstPass )
|
||||||
{
|
{
|
||||||
|
*aType = SIM_MODEL::TYPE::NONE;
|
||||||
|
|
||||||
tao::pegtl::string_input<> in( aSpiceCode, "Spice_Code" );
|
tao::pegtl::string_input<> in( aSpiceCode, "Spice_Code" );
|
||||||
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
std::unique_ptr<tao::pegtl::parse_tree::node> root;
|
||||||
|
|
||||||
@ -76,15 +78,17 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary,
|
|||||||
catch( const tao::pegtl::parse_error& e )
|
catch( const tao::pegtl::parse_error& e )
|
||||||
{
|
{
|
||||||
wxLogTrace( traceSpiceModelParser, wxS( "%s" ), e.what() );
|
wxLogTrace( traceSpiceModelParser, wxS( "%s" ), e.what() );
|
||||||
return SIM_MODEL::TYPE::NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( const auto& node : root->children )
|
for( const auto& node : root->children )
|
||||||
{
|
{
|
||||||
if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModelAko>() )
|
if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModelAko>() )
|
||||||
{
|
{
|
||||||
if( aSkipReferential )
|
// The first pass of model loading is done in parallel, so we can't (yet) look
|
||||||
return SIM_MODEL::TYPE::REFERENTIAL;
|
// up our reference model.
|
||||||
|
if( aFirstPass )
|
||||||
|
return false;
|
||||||
|
|
||||||
std::string modelName = node->children.at( 0 )->string();
|
std::string modelName = node->children.at( 0 )->string();
|
||||||
std::string akoName = node->children.at( 1 )->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 ) );
|
modelName ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return sourceModel->GetType();
|
*aType = sourceModel->GetType();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() )
|
else if( node->is_type<SIM_MODEL_SPICE_PARSER::dotModel>() )
|
||||||
{
|
{
|
||||||
@ -119,7 +124,10 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary,
|
|||||||
SIM_MODEL::TYPE type = ReadTypeFromSpiceStrings( typeString );
|
SIM_MODEL::TYPE type = ReadTypeFromSpiceStrings( typeString );
|
||||||
|
|
||||||
if( type != SIM_MODEL::TYPE::RAWSPICE )
|
if( type != SIM_MODEL::TYPE::RAWSPICE )
|
||||||
return type;
|
{
|
||||||
|
*aType = type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( subnode->is_type<SIM_MODEL_SPICE_PARSER::param>() )
|
else if( subnode->is_type<SIM_MODEL_SPICE_PARSER::param>() )
|
||||||
{
|
{
|
||||||
@ -137,7 +145,7 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadType( const SIM_LIBRARY_SPICE& aLibrary,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxFAIL_MSG( "Unhandled parse tree subnode" );
|
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
|
// `version` variables into account too. This is suboptimal since we read the model
|
||||||
// twice this way, and moreover the code is now somewhat duplicated.
|
// 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<SIM_MODEL_SPICE_PARSER::dotSubckt>() )
|
else if( node->is_type<SIM_MODEL_SPICE_PARSER::dotSubckt>() )
|
||||||
{
|
{
|
||||||
if( aSkipReferential )
|
// The first pass of model loading is done in parallel, so we can't (yet) refer to
|
||||||
return SIM_MODEL::TYPE::REFERENTIAL;
|
// any other models in a subcircuit.
|
||||||
|
if( aFirstPass )
|
||||||
|
return false;
|
||||||
|
|
||||||
return SIM_MODEL::TYPE::SUBCKT;
|
*aType = SIM_MODEL::TYPE::SUBCKT;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxFAIL_MSG( "Unhandled parse tree node" );
|
wxFAIL_MSG( "Unhandled parse tree node" );
|
||||||
return SIM_MODEL::TYPE::NONE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFAIL_MSG( "Could not derive type from SPICE code" );
|
wxFAIL_MSG( "Could not derive type from SPICE code" );
|
||||||
return SIM_MODEL::TYPE::NONE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ class SIM_LIBRARY_SPICE;
|
|||||||
class SPICE_MODEL_PARSER
|
class SPICE_MODEL_PARSER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static SIM_MODEL::TYPE ReadType( const SIM_LIBRARY_SPICE& aLibrary,
|
static bool ReadType( const SIM_LIBRARY_SPICE& aLibrary, const std::string& aSpiceCode,
|
||||||
const std::string& aSpiceCode, bool aSkipReferential );
|
SIM_MODEL::TYPE* aType, bool aFirstPass );
|
||||||
|
|
||||||
SPICE_MODEL_PARSER( SIM_MODEL_SPICE& aModel ) : m_model( aModel ) {}
|
SPICE_MODEL_PARSER( SIM_MODEL_SPICE& aModel ) : m_model( aModel ) {}
|
||||||
virtual ~SPICE_MODEL_PARSER() = default;
|
virtual ~SPICE_MODEL_PARSER() = default;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user