Re-enable sim model ERC testing.
This commit is contained in:
parent
c2e7524cb6
commit
7f35323416
|
@ -43,8 +43,7 @@
|
|||
#include <drawing_sheet/ds_draw_item.h>
|
||||
#include <drawing_sheet/ds_proxy_view_item.h>
|
||||
#include <wx/ffile.h>
|
||||
|
||||
#include "sim/sim_model.h"
|
||||
#include <sim/sim_lib_mgr.h>
|
||||
|
||||
|
||||
/* ERC tests :
|
||||
|
@ -1013,8 +1012,11 @@ int ERC_TESTER::TestOffGridEndpoints( int aGridSize )
|
|||
|
||||
int ERC_TESTER::TestSimModelIssues()
|
||||
{
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
int err_count = 0;
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
int err_count = 0;
|
||||
SIM_LIB_MGR libMgr( &m_schematic->Prj(), &reporter );
|
||||
|
||||
for( SCH_SHEET_PATH& sheet : sheets )
|
||||
{
|
||||
|
@ -1022,18 +1024,16 @@ int ERC_TESTER::TestSimModelIssues()
|
|||
|
||||
for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
|
||||
{
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
// Reset for each symbol
|
||||
msg.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
/* JEY TODO
|
||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( &sheet, symbol, true );
|
||||
*/
|
||||
}
|
||||
catch( IO_ERROR& e )
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( &sheet, *symbol );
|
||||
|
||||
if( !msg.IsEmpty() )
|
||||
{
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMULATION_MODEL );
|
||||
ercItem->SetErrorMessage( e.Problem() );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( symbol );
|
||||
|
||||
markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
|
||||
|
|
|
@ -258,6 +258,8 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
|||
spiceItem.fields.back().SetText( pinMap );
|
||||
}
|
||||
|
||||
// JEY TODO: move from try/catch to REPORTER interface...
|
||||
// readModel() is the only one that throws, and it won't if m_libMgr has a REPORTER
|
||||
try
|
||||
{
|
||||
readRefName( sheet, *symbol, spiceItem, refNames );
|
||||
|
|
|
@ -36,8 +36,9 @@
|
|||
#include <sim/sim_model.h>
|
||||
#include <sim/sim_model_ideal.h>
|
||||
|
||||
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT* aPrj ) :
|
||||
m_project( aPrj )
|
||||
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT* aPrj, REPORTER* aReporter ) :
|
||||
m_project( aPrj ),
|
||||
m_reporter( aReporter )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ SIM_LIBRARY& SIM_LIB_MGR::SetLibrary( const wxString& aLibraryPath, REPORTER* aR
|
|||
|
||||
SIM_MODEL& SIM_LIB_MGR::CreateModel( SIM_MODEL::TYPE aType, const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aType, aPins ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aType, aPins, m_reporter ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
|
@ -154,7 +155,7 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( SIM_MODEL::TYPE aType, const std::vector<LI
|
|||
SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins, m_reporter ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
|
@ -164,7 +165,7 @@ SIM_MODEL& SIM_LIB_MGR::CreateModel( const SIM_MODEL& aBaseModel,
|
|||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins, aFields ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aBaseModel, aPins, aFields, m_reporter ) );
|
||||
return *m_models.back();
|
||||
}
|
||||
|
||||
|
@ -254,7 +255,7 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const std::vector<T>& aFields,
|
|||
}
|
||||
else
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( aFields, aPins ) );
|
||||
m_models.push_back( SIM_MODEL::Create( aFields, aPins, m_reporter ) );
|
||||
return { baseModelName, *m_models.back() };
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +274,7 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
|||
{
|
||||
wxString path = ResolveLibraryPath( aLibraryPath, m_project );
|
||||
SIM_LIBRARY* library = nullptr;
|
||||
wxString msg;
|
||||
|
||||
std::function<std::string(const std::string&, const std::string&)> f2 =
|
||||
std::bind( &SIM_LIB_MGR::ResolveEmbeddedLibraryPath, this, std::placeholders::_1, std::placeholders::_2 );
|
||||
|
@ -284,28 +286,42 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const wxString& aLibraryPath,
|
|||
}
|
||||
catch( const IO_ERROR& e )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model library '%s': %s" ),
|
||||
path,
|
||||
e.What() ) );
|
||||
msg.Printf( _( "Error loading simulation model library '%s': %s" ),
|
||||
path,
|
||||
e.What() );
|
||||
|
||||
if( m_reporter )
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
else
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
if( aBaseModelName == "" )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: no '%s' field" ),
|
||||
SIM_LIBRARY::NAME_FIELD ) );
|
||||
msg.Printf( _( "Error loading simulation model: no '%s' field" ),
|
||||
SIM_LIBRARY::NAME_FIELD );
|
||||
|
||||
if( m_reporter )
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
else
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
SIM_MODEL* baseModel = library->FindModel( aBaseModelName );
|
||||
|
||||
if( !baseModel )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Error loading simulation model: could not find "
|
||||
"base model '%s' in library '%s'" ),
|
||||
aBaseModelName,
|
||||
path ) );
|
||||
msg.Printf( _( "Error loading simulation model: could not find base model '%s' in library '%s'" ),
|
||||
aBaseModelName,
|
||||
path );
|
||||
|
||||
if( m_reporter )
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
else
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
m_models.push_back( SIM_MODEL::Create( *baseModel, aPins, aFields ) );
|
||||
m_models.push_back( SIM_MODEL::Create( *baseModel, aPins, aFields, m_reporter ) );
|
||||
|
||||
return { aBaseModelName, *m_models.back() };
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ class SCH_SYMBOL;
|
|||
class SIM_LIB_MGR
|
||||
{
|
||||
public:
|
||||
SIM_LIB_MGR( const PROJECT* aPrj );
|
||||
SIM_LIB_MGR( const PROJECT* aPrj, REPORTER* aReporter = nullptr );
|
||||
virtual ~SIM_LIB_MGR() = default;
|
||||
|
||||
void Clear();
|
||||
|
@ -80,6 +80,7 @@ public:
|
|||
|
||||
private:
|
||||
const PROJECT* m_project;
|
||||
REPORTER* m_reporter;
|
||||
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries;
|
||||
std::vector<std::unique_ptr<SIM_MODEL>> m_models;
|
||||
};
|
||||
|
|
|
@ -47,7 +47,7 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath )
|
|||
|
||||
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
||||
{
|
||||
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pins ) );
|
||||
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, pins, nullptr ) );
|
||||
m_modelNames.emplace_back( kcomp.m_name );
|
||||
|
||||
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
||||
|
|
|
@ -443,7 +443,8 @@ void SIM_MODEL::WriteFields( std::vector<LIB_FIELD>& aFields ) const
|
|||
}
|
||||
|
||||
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, const std::vector<LIB_PIN*>& aPins )
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
std::unique_ptr<SIM_MODEL> model = Create( aType );
|
||||
|
||||
|
@ -452,9 +453,12 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, const std::vector<LIB_
|
|||
// Passing nullptr to ReadDataFields will make it act as if all fields were empty.
|
||||
model->ReadDataFields( static_cast<const std::vector<SCH_FIELD>*>( nullptr ), aPins );
|
||||
}
|
||||
catch( ... )
|
||||
catch( IO_ERROR& err )
|
||||
{
|
||||
// Shouldn't happen with nothing to read from fields
|
||||
if( aReporter )
|
||||
aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
|
||||
else
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
|
||||
return model;
|
||||
|
@ -462,7 +466,8 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType, const std::vector<LIB_
|
|||
|
||||
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins)
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
std::unique_ptr<SIM_MODEL> model;
|
||||
|
||||
|
@ -480,7 +485,10 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
|||
}
|
||||
catch( IO_ERROR& err )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
if( aReporter )
|
||||
aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
|
||||
else
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
|
||||
return model;
|
||||
|
@ -490,7 +498,8 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
|||
template <typename T>
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields )
|
||||
const std::vector<T>& aFields,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
TYPE type = ReadTypeFromFields( aFields );
|
||||
|
||||
|
@ -514,7 +523,10 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
|||
}
|
||||
catch( IO_ERROR& err )
|
||||
{
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
if( aReporter )
|
||||
aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
|
||||
else
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
|
||||
return model;
|
||||
|
@ -522,16 +534,19 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
|||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<SCH_FIELD>& aFields );
|
||||
const std::vector<SCH_FIELD>& aFields,
|
||||
REPORTER* aReporter );
|
||||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<LIB_FIELD>& aFields );
|
||||
const std::vector<LIB_FIELD>& aFields,
|
||||
REPORTER* aReporter );
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins )
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter )
|
||||
{
|
||||
TYPE type = ReadTypeFromFields( aFields );
|
||||
std::unique_ptr<SIM_MODEL> model = SIM_MODEL::Create( type );
|
||||
|
@ -560,7 +575,10 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
|
|||
catch( const IO_ERROR& err )
|
||||
{
|
||||
// We own the pin syntax, so if we can't parse it then there's an error, full stop.
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
if( aReporter )
|
||||
aReporter->Report( err.What(), RPT_SEVERITY_ERROR );
|
||||
else
|
||||
DisplayErrorMessage( nullptr, err.What() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,9 +586,11 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<T>& aFields,
|
|||
}
|
||||
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<SCH_FIELD>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter );
|
||||
template std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( const std::vector<LIB_FIELD>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter );
|
||||
|
||||
|
||||
template <typename T>
|
||||
|
@ -1529,40 +1549,35 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
}
|
||||
|
||||
wxString spiceDeviceType = spiceDeviceInfo.m_Text.Trim( true ).Trim( false );
|
||||
wxString spiceLib = spiceLibInfo.m_Text.Trim( true ).Trim( false );
|
||||
wxString spiceModel = spiceModelInfo.m_Text.Trim( true ).Trim( false );
|
||||
|
||||
bool libraryModel = false;
|
||||
bool inferredModel = false;
|
||||
bool internalModel = false;
|
||||
|
||||
if( !spiceLibInfo.IsEmpty() )
|
||||
if( !spiceLib.IsEmpty() )
|
||||
{
|
||||
SIM_LIB_MGR libMgr( aProject );
|
||||
wxString msg;
|
||||
WX_STRING_REPORTER reporter( &msg );
|
||||
SIM_LIB_MGR libMgr( aProject, &reporter );
|
||||
std::vector<T_field> emptyFields;
|
||||
|
||||
try
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
|
||||
emptyFields, sourcePins );
|
||||
|
||||
libraryModel = !reporter.HasMessage(); // Otherwise we'll fall back to raw spice model
|
||||
|
||||
if( pinMapInfo.IsEmpty() )
|
||||
{
|
||||
std::vector<T_field> emptyFields;
|
||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLibInfo.m_Text,
|
||||
spiceModel.ToStdString(),
|
||||
emptyFields, sourcePins );
|
||||
// Try to generate a default pin map from the SIM_MODEL's pins; if that fails,
|
||||
// generate one from the symbol's pins
|
||||
|
||||
libraryModel = true;
|
||||
model.model.SIM_MODEL::createPins( sourcePins );
|
||||
pinMapInfo.m_Text = wxString( model.model.Serializer().GeneratePins() );
|
||||
|
||||
if( pinMapInfo.IsEmpty() )
|
||||
{
|
||||
// Try to generate a default pin map from the SIM_MODEL's pins; if that fails,
|
||||
// generate one from the symbol's pins
|
||||
|
||||
model.model.SIM_MODEL::createPins( sourcePins );
|
||||
pinMapInfo.m_Text = wxString( model.model.Serializer().GeneratePins() );
|
||||
|
||||
if( pinMapInfo.IsEmpty() )
|
||||
pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
|
||||
}
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// Fall back to raw spice model
|
||||
pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
|
||||
}
|
||||
}
|
||||
else if( ( spiceDeviceType == "R" || spiceDeviceType == "L" || spiceDeviceType == "C" )
|
||||
|
@ -1670,14 +1685,14 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
|||
}
|
||||
else // Insert a raw spice model as a substitute.
|
||||
{
|
||||
if( spiceDeviceType.IsEmpty() && spiceLibInfo.IsEmpty() )
|
||||
if( spiceDeviceType.IsEmpty() && spiceLib.IsEmpty() )
|
||||
{
|
||||
spiceParamsInfo = spiceModelInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiceParamsInfo.m_Text.Printf( wxT( "type=\"%s\" model=\"%s\" lib=\"%s\"" ),
|
||||
spiceDeviceType, spiceModel, spiceLibInfo.m_Text );
|
||||
spiceDeviceType, spiceModel, spiceLib );
|
||||
}
|
||||
|
||||
T_field deviceField = spiceDeviceInfo.CreateField( &aSymbol, SIM_MODEL::DEVICE_TYPE_FIELD );
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include <reporter.h>
|
||||
#include <sch_field.h>
|
||||
#include <lib_field.h>
|
||||
|
||||
|
@ -400,19 +401,23 @@ public:
|
|||
static TYPE InferTypeFromLegacyFields( const std::vector<T>& aFields );
|
||||
|
||||
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, const std::vector<LIB_PIN*>& aPins );
|
||||
static std::unique_ptr<SIM_MODEL> Create( TYPE aType, const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter );
|
||||
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter );
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( const SIM_MODEL& aBaseModel,
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
const std::vector<T>& aFields );
|
||||
const std::vector<T>& aFields,
|
||||
REPORTER* aReporter );
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<SIM_MODEL> Create( const std::vector<T>& aFields,
|
||||
const std::vector<LIB_PIN*>& aPins );
|
||||
const std::vector<LIB_PIN*>& aPins,
|
||||
REPORTER* aReporter );
|
||||
|
||||
template <typename T>
|
||||
static std::string GetFieldValue( const std::vector<T>* aFields, const std::string& aFieldName,
|
||||
|
|
|
@ -874,6 +874,7 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
|||
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
||||
|
||||
// JEY TODO: move to reporter interface instead of try/catch....
|
||||
SIM_LIB_MGR mgr( &m_frame->Prj() );
|
||||
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol ).model;
|
||||
|
||||
|
|
Loading…
Reference in New Issue