Fix multi-unit symbol bugs.
1) SPICE pins need to include all units 2) Already-seen-unit-x needs to be reset when getting netlist again. Fixes https://gitlab.com/kicad/code/kicad/issues/13164
This commit is contained in:
parent
89153ca75a
commit
24786fe0e9
|
@ -63,9 +63,7 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symb
|
||||||
{
|
{
|
||||||
m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
|
m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
|
||||||
|
|
||||||
// Note that to get ALL pins, not only of the current part, you need to use
|
m_sortedPartPins = m_symbol.GetAllLibPins();
|
||||||
// m_symbol.GetRawPins().
|
|
||||||
m_sortedPartPins = m_symbol.GetLibPins();
|
|
||||||
|
|
||||||
std::sort( m_sortedPartPins.begin(), m_sortedPartPins.end(),
|
std::sort( m_sortedPartPins.begin(), m_sortedPartPins.end(),
|
||||||
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
[]( const LIB_PIN* lhs, const LIB_PIN* rhs )
|
||||||
|
@ -247,9 +245,9 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
|
if( m_useInstanceModelRadioButton->GetValue() && type == m_curModelType )
|
||||||
m_builtinModelsMgr.CreateModel( m_fields, m_symbol.GetPinCount() );
|
m_builtinModelsMgr.CreateModel( m_fields, m_symbol.GetFullPinCount() );
|
||||||
else
|
else
|
||||||
m_builtinModelsMgr.CreateModel( type, m_symbol.GetPinCount() );
|
m_builtinModelsMgr.CreateModel( type, m_symbol.GetFullPinCount() );
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
|
@ -665,9 +663,9 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::loadLibrary( const wxString& aLibraryP
|
||||||
for( auto& [baseModelName, baseModel] : library()->GetModels() )
|
for( auto& [baseModelName, baseModel] : library()->GetModels() )
|
||||||
{
|
{
|
||||||
if( baseModelName == modelName )
|
if( baseModelName == modelName )
|
||||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetPinCount(), m_fields );
|
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetFullPinCount(), m_fields );
|
||||||
else
|
else
|
||||||
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetPinCount() );
|
m_libraryModelsMgr.CreateModel( baseModel, m_symbol.GetFullPinCount() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
|
|
|
@ -1241,7 +1241,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnUnitChoice( wxCommandEvent& event )
|
||||||
m_dataModel->SortRows( COL_NUMBER, true );
|
m_dataModel->SortRows( COL_NUMBER, true );
|
||||||
m_dataModel->BuildAttrs();
|
m_dataModel->BuildAttrs();
|
||||||
|
|
||||||
m_symbol->SetUnit(old_unit );
|
m_symbol->SetUnit( old_unit );
|
||||||
|
|
||||||
// Restore m_Flag modified by SetUnit()
|
// Restore m_Flag modified by SetUnit()
|
||||||
m_symbol->ClearFlags();
|
m_symbol->ClearFlags();
|
||||||
|
|
|
@ -685,7 +685,7 @@ void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffse
|
||||||
}
|
}
|
||||||
else if( item.Type() == LIB_FIELD_T )
|
else if( item.Type() == LIB_FIELD_T )
|
||||||
{
|
{
|
||||||
item.Print( aSettings, aOffset, (void*) NULL, aOpts.transform, aDimmed );
|
item.Print( aSettings, aOffset, nullptr, aOpts.transform, aDimmed );
|
||||||
}
|
}
|
||||||
else if( item.Type() == LIB_SHAPE_T )
|
else if( item.Type() == LIB_SHAPE_T )
|
||||||
{
|
{
|
||||||
|
@ -878,11 +878,11 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<LIB_PIN*> LIB_SYMBOL::GetLibPins() const
|
std::vector<LIB_PIN*> LIB_SYMBOL::GetAllLibPins() const
|
||||||
{
|
{
|
||||||
std::vector<LIB_PIN*> pinList;
|
std::vector<LIB_PIN*> pinList;
|
||||||
|
|
||||||
GetPins( pinList );
|
GetPins( pinList, 0, 0 );
|
||||||
return pinList;
|
return pinList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,12 +894,12 @@ LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert )
|
||||||
|
|
||||||
GetPins( pinList, aUnit, aConvert );
|
GetPins( pinList, aUnit, aConvert );
|
||||||
|
|
||||||
for( size_t i = 0; i < pinList.size(); i++ )
|
for( LIB_PIN* pin : pinList )
|
||||||
{
|
{
|
||||||
wxASSERT( pinList[i]->Type() == LIB_PIN_T );
|
wxASSERT( pin->Type() == LIB_PIN_T );
|
||||||
|
|
||||||
if( aNumber == pinList[i]->GetNumber() )
|
if( aNumber == pin->GetNumber() )
|
||||||
return pinList[i];
|
return pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -409,8 +409,8 @@ public:
|
||||||
*
|
*
|
||||||
* This is just a pin object specific version of GetNextDrawItem().
|
* This is just a pin object specific version of GetNextDrawItem().
|
||||||
*
|
*
|
||||||
* @param aItem - Pointer to the previous pin item, or NULL to get the
|
* @param aItem - Pointer to the previous pin item, or NULL to get the first pin in the draw
|
||||||
* first pin in the draw object list.
|
* object list.
|
||||||
* @return - The next pin object in the list if found, otherwise NULL.
|
* @return - The next pin object in the list if found, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
LIB_PIN* GetNextPin( LIB_PIN* aItem = nullptr )
|
LIB_PIN* GetNextPin( LIB_PIN* aItem = nullptr )
|
||||||
|
@ -421,36 +421,41 @@ public:
|
||||||
/**
|
/**
|
||||||
* Return a list of pin object pointers from the draw item list.
|
* Return a list of pin object pointers from the draw item list.
|
||||||
*
|
*
|
||||||
* Note pin objects are owned by the draw list of the symbol.
|
* Note pin objects are owned by the draw list of the symbol. Deleting any of the objects
|
||||||
* Deleting any of the objects will leave list in a unstable state
|
* will leave list in a unstable state and will likely segfault when the list is destroyed.
|
||||||
* and will likely segfault when the list is destroyed.
|
|
||||||
*
|
*
|
||||||
* @param aList - Pin list to place pin object pointers into.
|
* @param aList - Pin list to place pin object pointers into.
|
||||||
* @param aUnit - Unit number of pin to add to list. Set to 0 to
|
* @param aUnit - Unit number of pins to collect. Set to 0 to get pins from any symbol unit.
|
||||||
* get pins from any symbol unit.
|
* @param aConvert - Convert number of pins to collect. Set to 0 to get pins from any
|
||||||
* @param aConvert - Convert number of pin to add to list. Set to 0 to
|
* DeMorgan variant of symbol.
|
||||||
* get pins from any convert of symbol.
|
|
||||||
*/
|
*/
|
||||||
void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ) const;
|
void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ) const;
|
||||||
|
|
||||||
std::vector<LIB_PIN*> GetLibPins() const;
|
/**
|
||||||
|
* Return a list of pin pointers for all units / converts. Used primarily for SPICE where
|
||||||
|
* we want to treat all unit as a single part.
|
||||||
|
*/
|
||||||
|
std::vector<LIB_PIN*> GetAllLibPins() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a count of pins for all units / converts.
|
||||||
|
*/
|
||||||
|
size_t GetFullPinCount() { return GetAllLibPins().size(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return pin object with the requested pin \a aNumber.
|
* Return pin object with the requested pin \a aNumber.
|
||||||
*
|
*
|
||||||
* @param aNumber - Number of the pin to find.
|
* @param aNumber - Number of the pin to find.
|
||||||
* @param aUnit - Unit of the symbol to find. Set to 0 if a specific
|
* @param aUnit - Unit filter. Set to 0 if a specific unit number is not required.
|
||||||
* unit number is not required.
|
* @param aConvert - DeMorgan variant filter. Set to 0 if no specific DeMorgan variant is
|
||||||
* @param aConvert - Alternate body style filter (DeMorgan). Set to 0 if
|
* required.
|
||||||
* no alternate body style is required.
|
|
||||||
* @return The pin object if found. Otherwise NULL.
|
* @return The pin object if found. Otherwise NULL.
|
||||||
*/
|
*/
|
||||||
LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 ) const;
|
LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if this symbol's pins do not match another symbol's pins. This
|
* Return true if this symbol's pins do not match another symbol's pins. This is used to
|
||||||
* is used to detect whether the project cache is out of sync with the
|
* detect whether the project cache is out of sync with the system libs.
|
||||||
* system libs.
|
|
||||||
*
|
*
|
||||||
* @param aOtherSymbol - The other library symbol to test
|
* @param aOtherSymbol - The other library symbol to test
|
||||||
* @param aTestNums - Whether two pins at the same point must have the same number.
|
* @param aTestNums - Whether two pins at the same point must have the same number.
|
||||||
|
|
|
@ -166,6 +166,7 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
|
|
||||||
m_nets.clear();
|
m_nets.clear();
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
|
m_referencesAlreadyFound.Clear();
|
||||||
m_libParts.clear();
|
m_libParts.clear();
|
||||||
|
|
||||||
wxFileName cacheDir;
|
wxFileName cacheDir;
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include <refdes_utils.h>
|
#include <refdes_utils.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
#include <string_utils.h>
|
#include <string_utils.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include "plotters/plotter.h"
|
#include "plotters/plotter.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -997,11 +999,13 @@ void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<LIB_PIN*> SCH_SYMBOL::GetLibPins() const
|
std::vector<LIB_PIN*> SCH_SYMBOL::GetAllLibPins() const
|
||||||
{
|
{
|
||||||
std::vector<LIB_PIN*> pinList;
|
std::vector<LIB_PIN*> pinList;
|
||||||
|
|
||||||
GetLibPins( pinList );
|
if( m_part )
|
||||||
|
m_part->GetPins( pinList, 0, 0 );
|
||||||
|
|
||||||
return pinList;
|
return pinList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,7 +1044,7 @@ std::vector<SCH_PIN*> SCH_SYMBOL::GetPins( const SCH_SHEET_PATH* aSheet ) const
|
||||||
|
|
||||||
void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
|
void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( (aItem != nullptr) && (aItem->Type() == SCH_SYMBOL_T),
|
wxCHECK_RET( aItem != nullptr && aItem->Type() == SCH_SYMBOL_T,
|
||||||
wxT( "Cannot swap data with invalid symbol." ) );
|
wxT( "Cannot swap data with invalid symbol." ) );
|
||||||
|
|
||||||
SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
|
SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
|
||||||
|
@ -1048,7 +1052,7 @@ void SCH_SYMBOL::SwapData( SCH_ITEM* aItem )
|
||||||
std::swap( m_lib_id, symbol->m_lib_id );
|
std::swap( m_lib_id, symbol->m_lib_id );
|
||||||
|
|
||||||
LIB_SYMBOL* libSymbol = symbol->m_part.release();
|
LIB_SYMBOL* libSymbol = symbol->m_part.release();
|
||||||
symbol->m_part.reset( m_part.release() );
|
symbol->m_part = std::move( m_part );
|
||||||
symbol->UpdatePins();
|
symbol->UpdatePins();
|
||||||
m_part.reset( libSymbol );
|
m_part.reset( libSymbol );
|
||||||
UpdatePins();
|
UpdatePins();
|
||||||
|
|
|
@ -518,14 +518,19 @@ public:
|
||||||
void GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const;
|
void GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a vector with all the pins from the library object.
|
* @return a list of pin pointers for all units / converts. Used primarily for SPICE where
|
||||||
*
|
* we want to treat all units together as a single SPICE element.
|
||||||
* @return List of the pins
|
|
||||||
*/
|
*/
|
||||||
std::vector<LIB_PIN*> GetLibPins() const;
|
std::vector<LIB_PIN*> GetAllLibPins() const;
|
||||||
|
|
||||||
size_t GetPinCount() { return GetLibPins().size(); }
|
/**
|
||||||
|
* @return a count of pins for all units / converts.
|
||||||
|
*/
|
||||||
|
size_t GetFullPinCount() { return GetAllLibPins().size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the SCH_PIN associated with a particular LIB_PIN.
|
||||||
|
*/
|
||||||
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1089,7 +1089,7 @@ bool SIM_MODEL::InferPassiveSimModel( T& aSymbol, bool aResolve,
|
||||||
aValue );
|
aValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LIB_PIN*> pins = aSymbol.GetLibPins();
|
std::vector<LIB_PIN*> pins = aSymbol.GetAllLibPins();
|
||||||
|
|
||||||
if( pins.size() == 2 )
|
if( pins.size() == 2 )
|
||||||
{
|
{
|
||||||
|
@ -1271,7 +1271,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
|
|
||||||
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
wxStringSplit( legacyPins->GetText(), pinIndexes, ' ' );
|
||||||
|
|
||||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetLibPins();
|
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||||
|
|
||||||
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
|
if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
|
||||||
{
|
{
|
||||||
|
@ -1321,7 +1321,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
{
|
{
|
||||||
std::vector<T_field> emptyFields;
|
std::vector<T_field> emptyFields;
|
||||||
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
|
SIM_LIBRARY::MODEL model = libMgr.CreateModel( spiceLib, spiceModel.ToStdString(),
|
||||||
emptyFields, aSymbol.GetPinCount() );
|
emptyFields, aSymbol.GetFullPinCount() );
|
||||||
|
|
||||||
spiceParams = wxString( model.model.GetBaseModel()->Serde().GenerateParams() );
|
spiceParams = wxString( model.model.GetBaseModel()->Serde().GenerateParams() );
|
||||||
}
|
}
|
||||||
|
@ -1392,7 +1392,7 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
|
||||||
{
|
{
|
||||||
// Generate a 1:1 pin map. We don't necessarily know the SPICE model pinNames, so just
|
// Generate a 1:1 pin map. We don't necessarily know the SPICE model pinNames, so just
|
||||||
// use indexes.
|
// use indexes.
|
||||||
std::vector<LIB_PIN*> sourcePins = aSymbol.GetLibPins();
|
std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < sourcePins.size(); ++ii )
|
for( unsigned ii = 0; ii < sourcePins.size(); ++ii )
|
||||||
{
|
{
|
||||||
|
|
|
@ -874,7 +874,6 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
LIB_PIN* pin = static_cast<SCH_PIN*>( item )->GetLibPin();
|
||||||
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
|
||||||
std::vector<LIB_PIN*> pins = symbol->GetLibPins();
|
|
||||||
|
|
||||||
SIM_LIB_MGR mgr( &m_frame->Prj() );
|
SIM_LIB_MGR mgr( &m_frame->Prj() );
|
||||||
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol ).model;
|
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol ).model;
|
||||||
|
|
Loading…
Reference in New Issue