ADDED: ERC for missing units
Reports a warning (by default) for missing units Reports an error for missing units with power input pins Reports a warning for missing units with input pins Reports a warning for missing units with bidi pins Fixes https://gitlab.com/kicad/code/kicad/issues/1922
This commit is contained in:
parent
458935bb5a
commit
09cc6decaf
|
@ -485,6 +485,8 @@ void DIALOG_ERC::testErc()
|
|||
m_parent->RecalculateConnections( NO_CLEANUP );
|
||||
sch->ConnectionGraph()->RunERC();
|
||||
|
||||
AdvancePhase( _( "Checking units..." ) );
|
||||
|
||||
// Test is all units of each multiunit symbol have the same footprint assigned.
|
||||
if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) )
|
||||
{
|
||||
|
@ -492,6 +494,14 @@ void DIALOG_ERC::testErc()
|
|||
tester.TestMultiunitFootprints();
|
||||
}
|
||||
|
||||
if( settings.IsTestEnabled( ERCE_MISSING_UNIT )
|
||||
|| settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN )
|
||||
|| settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN )
|
||||
|| settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
{
|
||||
tester.TestMissingUnits();
|
||||
}
|
||||
|
||||
AdvancePhase( _( "Checking pins..." ) );
|
||||
|
||||
if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) )
|
||||
|
|
143
eeschema/erc.cpp
143
eeschema/erc.cpp
|
@ -23,6 +23,9 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include "connection_graph.h"
|
||||
#include <common.h> // for ExpandEnvVarSubstitutions
|
||||
#include <erc.h>
|
||||
|
@ -407,6 +410,146 @@ int ERC_TESTER::TestMultiunitFootprints()
|
|||
}
|
||||
|
||||
|
||||
int ERC_TESTER::TestMissingUnits()
|
||||
{
|
||||
ERC_SETTINGS& settings = m_schematic->ErcSettings();
|
||||
SCH_SHEET_LIST sheets = m_schematic->GetSheets();
|
||||
|
||||
int errors = 0;
|
||||
SCH_MULTI_UNIT_REFERENCE_MAP refMap;
|
||||
sheets.GetMultiUnitSymbols( refMap, true );
|
||||
|
||||
for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
|
||||
{
|
||||
SCH_REFERENCE_LIST& refList = symbol.second;
|
||||
|
||||
wxCHECK2( refList.GetCount(), continue );
|
||||
|
||||
// Reference unit
|
||||
SCH_REFERENCE& base_ref = refList.GetItem( 0 );
|
||||
SCH_SYMBOL* unit = base_ref.GetSymbol();
|
||||
LIB_SYMBOL* libSymbol = base_ref.GetLibPart();
|
||||
|
||||
if( static_cast<ssize_t>( refList.GetCount() ) == libSymbol->GetUnitCount() )
|
||||
continue;
|
||||
|
||||
std::set<int> lib_units;
|
||||
std::set<int> instance_units;
|
||||
std::set<int> missing_units;
|
||||
|
||||
auto report_missing = [&]( std::set<int>& aMissingUnits, wxString aErrorMsg, int aErrorCode )
|
||||
{
|
||||
wxString msg;
|
||||
wxString missing_pin_units = wxT( "[ " );
|
||||
int ii = 0;
|
||||
|
||||
for( int missing_unit : aMissingUnits )
|
||||
{
|
||||
if( ii++ == 3 )
|
||||
{
|
||||
missing_pin_units += wxT( "....." );
|
||||
break;
|
||||
}
|
||||
|
||||
missing_pin_units += libSymbol->GetUnitDisplayName( missing_unit ) + ", " ;
|
||||
}
|
||||
|
||||
missing_pin_units.Truncate( missing_pin_units.length() - 2 );
|
||||
missing_pin_units += wxT( " ]" );
|
||||
|
||||
msg.Printf( aErrorMsg, symbol.first, missing_pin_units );
|
||||
|
||||
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( aErrorCode );
|
||||
ercItem->SetErrorMessage( msg );
|
||||
ercItem->SetItems( unit );
|
||||
|
||||
SCH_MARKER* marker = new SCH_MARKER( ercItem, unit->GetPosition() );
|
||||
base_ref.GetSheetPath().LastScreen()->Append( marker );
|
||||
|
||||
++errors;
|
||||
};
|
||||
|
||||
for( int ii = 1; ii <= libSymbol->GetUnitCount(); ++ii )
|
||||
lib_units.insert( lib_units.end(), ii );
|
||||
|
||||
for( size_t ii = 0; ii < refList.GetCount(); ++ii )
|
||||
instance_units.insert( instance_units.end(), refList.GetItem( ii ).GetUnit() );
|
||||
|
||||
std::set_difference( lib_units.begin(), lib_units.end(),
|
||||
instance_units.begin(), instance_units.end(),
|
||||
std::inserter( missing_units, missing_units.begin() ) );
|
||||
|
||||
if( !missing_units.empty() && settings.IsTestEnabled( ERCE_MISSING_UNIT ) )
|
||||
{
|
||||
report_missing( missing_units, _( "Symbol %s has unplaced units %s" ),
|
||||
ERCE_MISSING_UNIT );
|
||||
}
|
||||
|
||||
std::set<int> missing_power;
|
||||
std::set<int> missing_input;
|
||||
std::set<int> missing_bidi;
|
||||
|
||||
for( int missing_unit : missing_units )
|
||||
{
|
||||
LIB_PINS pins;
|
||||
int convert = 0;
|
||||
|
||||
for( size_t ii = 0; ii < refList.GetCount(); ++ii )
|
||||
{
|
||||
if( refList.GetItem( ii ).GetUnit() == missing_unit )
|
||||
{
|
||||
convert = refList.GetItem( ii ).GetSymbol()->GetConvert();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
libSymbol->GetPins( pins, missing_unit, convert );
|
||||
|
||||
for( auto pin : pins )
|
||||
{
|
||||
switch( pin->GetType() )
|
||||
{
|
||||
case ELECTRICAL_PINTYPE::PT_POWER_IN:
|
||||
missing_power.insert( missing_unit );
|
||||
break;
|
||||
|
||||
case ELECTRICAL_PINTYPE::PT_BIDI:
|
||||
missing_bidi.insert( missing_unit );
|
||||
break;
|
||||
|
||||
case ELECTRICAL_PINTYPE::PT_INPUT:
|
||||
missing_input.insert( missing_unit );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !missing_power.empty() && settings.IsTestEnabled( ERCE_MISSING_POWER_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_power, _( "Symbol %s has input power pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_POWER_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_input.empty() && settings.IsTestEnabled( ERCE_MISSING_INPUT_PIN ) )
|
||||
{
|
||||
report_missing( missing_input, _( "Symbol %s has input pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_INPUT_PIN );
|
||||
}
|
||||
|
||||
if( !missing_bidi.empty() && settings.IsTestEnabled( ERCE_MISSING_BIDI_PIN ) )
|
||||
{
|
||||
report_missing( missing_bidi, _( "Symbol %s has bidirectional pins in units %s that are not placed." ),
|
||||
ERCE_MISSING_BIDI_PIN );
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
int ERC_TESTER::TestNoConnectPins()
|
||||
{
|
||||
int err_count = 0;
|
||||
|
|
|
@ -139,6 +139,10 @@ public:
|
|||
*/
|
||||
int TestSimModelIssues();
|
||||
|
||||
/**
|
||||
* Test for uninstantiated units of multi unit symbols
|
||||
*/
|
||||
int TestMissingUnits();
|
||||
private:
|
||||
|
||||
SCHEMATIC* m_schematic;
|
||||
|
|
|
@ -154,6 +154,22 @@ ERC_ITEM ERC_ITEM::extraUnits( ERCE_EXTRA_UNITS,
|
|||
_( "Symbol has more units than are defined" ),
|
||||
wxT( "extra_units" ) );
|
||||
|
||||
ERC_ITEM ERC_ITEM::missingUnits( ERCE_MISSING_UNIT,
|
||||
_( "Symbol has units that are not placed" ),
|
||||
wxT( "missing_unit" ) );
|
||||
|
||||
ERC_ITEM ERC_ITEM::missingInputPin( ERCE_MISSING_INPUT_PIN,
|
||||
_( "Symbol has input pins that are not placed" ),
|
||||
wxT( "missing_input_pin" ) );
|
||||
|
||||
ERC_ITEM ERC_ITEM::missingBidiPin( ERCE_MISSING_BIDI_PIN,
|
||||
_( "Symbol has bidirectional pins that are not placed" ),
|
||||
wxT( "missing_bidi_pin" ) );
|
||||
|
||||
ERC_ITEM ERC_ITEM::missingPowerInputPin( ERCE_MISSING_POWER_INPUT_PIN,
|
||||
_( "Symbol has power input pins that are not placed" ),
|
||||
wxT( "missing_power_pin" ) );
|
||||
|
||||
ERC_ITEM ERC_ITEM::differentUnitValue( ERCE_DIFFERENT_UNIT_VALUE,
|
||||
_( "Units of same symbol have different values" ),
|
||||
wxT( "unit_value_mismatch" ) );
|
||||
|
@ -200,6 +216,10 @@ std::vector<std::reference_wrapper<RC_ITEM>> ERC_ITEM::allItemTypes( {
|
|||
ERC_ITEM::busLabelSyntax,
|
||||
ERC_ITEM::libSymbolIssues,
|
||||
ERC_ITEM::extraUnits,
|
||||
ERC_ITEM::missingUnits,
|
||||
ERC_ITEM::missingInputPin,
|
||||
ERC_ITEM::missingBidiPin,
|
||||
ERC_ITEM::missingPowerInputPin
|
||||
} );
|
||||
|
||||
|
||||
|
@ -239,6 +259,10 @@ std::shared_ptr<ERC_ITEM> ERC_ITEM::Create( int aErrorCode )
|
|||
case ERCE_DIFFERENT_UNIT_VALUE: return std::make_shared<ERC_ITEM>( differentUnitValue );
|
||||
case ERCE_DUPLICATE_REFERENCE: return std::make_shared<ERC_ITEM>( duplicateReference );
|
||||
case ERCE_BUS_ENTRY_NEEDED: return std::make_shared<ERC_ITEM>( busEntryNeeded );
|
||||
case ERCE_MISSING_UNIT: return std::make_shared<ERC_ITEM>( missingUnits );
|
||||
case ERCE_MISSING_INPUT_PIN: return std::make_shared<ERC_ITEM>( missingInputPin );
|
||||
case ERCE_MISSING_POWER_INPUT_PIN: return std::make_shared<ERC_ITEM>( missingPowerInputPin );
|
||||
case ERCE_MISSING_BIDI_PIN: return std::make_shared<ERC_ITEM>( missingBidiPin );
|
||||
case ERCE_UNSPECIFIED:
|
||||
default:
|
||||
wxFAIL_MSG( "Unknown ERC error code" );
|
||||
|
|
|
@ -99,6 +99,10 @@ private:
|
|||
static ERC_ITEM libSymbolIssues;
|
||||
static ERC_ITEM unannotated;
|
||||
static ERC_ITEM extraUnits;
|
||||
static ERC_ITEM missingUnits;
|
||||
static ERC_ITEM missingInputPin;
|
||||
static ERC_ITEM missingBidiPin;
|
||||
static ERC_ITEM missingPowerInputPin;
|
||||
static ERC_ITEM differentUnitValue;
|
||||
static ERC_ITEM duplicateReference;
|
||||
static ERC_ITEM busEntryNeeded;
|
||||
|
|
|
@ -103,6 +103,9 @@ ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
|
|||
m_ERCSeverities[ERCE_LIB_SYMBOL_ISSUES] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_NOCONNECT_CONNECTED] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_NOCONNECT_NOT_CONNECTED] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_MISSING_UNIT] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_MISSING_INPUT_PIN] = RPT_SEVERITY_WARNING;
|
||||
m_ERCSeverities[ERCE_MISSING_BIDI_PIN] = RPT_SEVERITY_WARNING;
|
||||
|
||||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
|
||||
[&]() -> nlohmann::json
|
||||
|
|
|
@ -51,6 +51,10 @@ enum ERCE_T
|
|||
ERCE_SIMILAR_LABELS, ///< 2 labels are equal for case insensitive comparisons.
|
||||
ERCE_DIFFERENT_UNIT_FP, ///< Different units of the same symbol have different
|
||||
///< footprints assigned.
|
||||
ERCE_MISSING_POWER_INPUT_PIN, ///< Symbol has power input pins that are not placed on the schematic
|
||||
ERCE_MISSING_INPUT_PIN, ///< Symbol has input pins that are not placed
|
||||
ERCE_MISSING_BIDI_PIN, ///< Symbol has bi-directional pins that are not placed
|
||||
ERCE_MISSING_UNIT, ///< Symbol has units that are not placed on the schematic
|
||||
ERCE_DIFFERENT_UNIT_NET, ///< Shared pin in a multi-unit symbol is connected to
|
||||
///< more than one net.
|
||||
ERCE_BUS_ALIAS_CONFLICT, ///< Conflicting bus alias definitions across sheets.
|
||||
|
|
Loading…
Reference in New Issue