diff --git a/eeschema/sim/sim_lib_mgr.cpp b/eeschema/sim/sim_lib_mgr.cpp index a3eed6ff01..a727e68e69 100644 --- a/eeschema/sim/sim_lib_mgr.cpp +++ b/eeschema/sim/sim_lib_mgr.cpp @@ -287,10 +287,16 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath, { path = ResolveLibraryPath( aLibraryPath, m_project ); - std::function f2 = - std::bind( &SIM_LIB_MGR::ResolveEmbeddedLibraryPath, this, _1, _2 ); + auto it = m_libraries.find( path ); + + if( it == m_libraries.end() ) + { + std::function f2 = + std::bind( &SIM_LIB_MGR::ResolveEmbeddedLibraryPath, this, _1, _2 ); + + it = m_libraries.emplace( path, SIM_LIBRARY::Create( path, m_reporter, &f2 ) ).first; + } - auto it = m_libraries.try_emplace( path, SIM_LIBRARY::Create( path, m_reporter, &f2 ) ).first; library = &*it->second; } catch( const IO_ERROR& e ) diff --git a/eeschema/sim/sim_model.cpp b/eeschema/sim/sim_model.cpp index 67b8b21833..11d364a360 100644 --- a/eeschema/sim/sim_model.cpp +++ b/eeschema/sim/sim_model.cpp @@ -1047,6 +1047,10 @@ void SIM_MODEL::doWriteFields( std::vector& aFields ) const bool SIM_MODEL::requiresSpiceModelLine( const SPICE_ITEM& aItem ) const { + // SUBCKTs are a single level; there's never a baseModel. + if( m_type == TYPE::SUBCKT ) + return false; + // Model must be written if there's no base model or the base model is an internal model if( !m_baseModel || aItem.baseModelName == "" ) return true; diff --git a/eeschema/sim/simulator_frame.cpp b/eeschema/sim/simulator_frame.cpp index a161e18f8e..b238ee81e1 100644 --- a/eeschema/sim/simulator_frame.cpp +++ b/eeschema/sim/simulator_frame.cpp @@ -527,6 +527,12 @@ SIMULATOR_FRAME::SIMULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // Prepare the color list to plot traces SIM_PLOT_COLORS::FillDefaultColorList( m_darkMode ); + NGSPICE_SIMULATOR_SETTINGS* settings = + dynamic_cast( m_simulator->Settings().get() ); + + if( settings->GetWorkbookFilename().IsEmpty() ) + settings->SetModelMode( NGSPICE_MODEL_MODE::LT_PSPICE ); + m_simulator->Init(); m_reporter = new SIM_THREAD_REPORTER( this ); diff --git a/eeschema/sim/spice_model_parser.cpp b/eeschema/sim/spice_model_parser.cpp index aa243f1be5..f520a446f8 100644 --- a/eeschema/sim/spice_model_parser.cpp +++ b/eeschema/sim/spice_model_parser.cpp @@ -266,44 +266,49 @@ SIM_MODEL::TYPE SPICE_MODEL_PARSER::ReadTypeFromSpiceStrings( const std::string& const std::string& aVersion, bool aSkipDefaultLevel ) { - std::string readLevel = wxString( aLevel ).BeforeFirst( '.' ).ToStdString(); + wxString input_level = wxString( aLevel ).BeforeFirst( '.' ); + wxString input_type( aTypeString ); + bool vdmos = false; + bool pchan = false; - for( SIM_MODEL::TYPE type : SIM_MODEL::TYPE_ITERATOR() ) + input_type.UpperCase(); + + if( input_type.StartsWith( wxS( "VDMOS" ) ) ) { - std::string typePrefix = SIM_MODEL::SpiceInfo( type ).modelType; - std::string level = SIM_MODEL::SpiceInfo( type ).level; - std::string version = SIM_MODEL::SpiceInfo( type ).version; - bool isDefaultLevel = SIM_MODEL::SpiceInfo( type ).isDefaultLevel; + vdmos = true; + pchan = input_type.Contains( wxS( "PCHAN" ) ); + } - if( typePrefix == "" ) + for( SIM_MODEL::TYPE candidate : SIM_MODEL::TYPE_ITERATOR() ) + { + wxString candidate_type = SIM_MODEL::SpiceInfo( candidate ).modelType; + wxString candidate_level = SIM_MODEL::SpiceInfo( candidate ).level; + wxString candidate_version = SIM_MODEL::SpiceInfo( candidate ).version; + bool candidate_isDefaultLevel = SIM_MODEL::SpiceInfo( candidate ).isDefaultLevel; + + if( candidate_type.IsEmpty() ) continue; - if( boost::starts_with( typePrefix, "VDMOS" ) ) + if( candidate_type.StartsWith( wxS( "VDMOS" ) ) && vdmos ) { - wxString deviceType = wxString( typePrefix ).BeforeFirst( ' ' ); // VDMOS - wxString channelType = wxString( typePrefix ).AfterFirst( ' ' ); // NCHAN or PCHAN - - wxStringTokenizer tokenizer( aTypeString, wxT( " \t\n\r+(" ), wxTOKEN_STRTOK ); - - if( tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Upper() == deviceType - && tokenizer.HasMoreTokens() && tokenizer.GetNextToken().Upper() == channelType ) - { - return type; - } + if( vdmos && pchan && candidate_type.EndsWith( wxS( "PCHAN" ) ) ) + return candidate; + else if( vdmos && !pchan && candidate_type.EndsWith( wxS( "NCHAN" ) ) ) + return candidate; } - else if( boost::starts_with( boost::to_upper_copy( aTypeString ), typePrefix ) ) + else if( input_type.StartsWith( candidate_type ) ) { - if( version != aVersion ) + if( candidate_version != aVersion ) continue; - if( level == readLevel ) - return type; + if( candidate_level == input_level ) + return candidate; if( aSkipDefaultLevel ) continue; - if( isDefaultLevel && aLevel == "" ) - return type; + if( candidate_isDefaultLevel && aLevel == "" ) + return candidate; } }