KiCad PCB EDA Suite
ERC_TESTER Class Reference

#include <erc.h>

Public Member Functions

 ERC_TESTER (SCHEMATIC *aSchematic)
 
void TestOthersItems (NETLIST_OBJECT_LIST *aList, unsigned aNetItemRef, unsigned aNetStart, int *aMinConnexion)
 Perform ERC testing for electrical conflicts between NetItemRef and other items (mainly pin) on the same net. More...
 
int TestDuplicateSheetNames (bool aCreateMarker)
 Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated). More...
 
void TestTextVars (DS_PROXY_VIEW_ITEM *aDrawingSheet)
 Check for any unresolved text variable references. More...
 
int TestConflictingBusAliases ()
 Check that there are no conflicting bus alias definitions in the schematic. More...
 
int TestMultiunitFootprints ()
 Test if all units of each multiunit symbol have the same footprint assigned. More...
 
int TestNoConnectPins ()
 In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type. More...
 
int TestPinToPin ()
 Checks the full netlist against the pin-to-pin connectivity requirements. More...
 
int TestMultUnitPinConflicts ()
 Checks if shared pins on multi-unit symbols have been connected to different nets. More...
 
int TestSimilarLabels ()
 Checks for labels that differ only in capitalization. More...
 
int TestLibSymbolIssues ()
 Test symbols for changed library symbols and broken symbol library links. More...
 

Private Attributes

SCHEMATICm_schematic
 

Detailed Description

Definition at line 47 of file erc.h.

Constructor & Destructor Documentation

◆ ERC_TESTER()

ERC_TESTER::ERC_TESTER ( SCHEMATIC aSchematic)
inline

Definition at line 51 of file erc.h.

51  :
52  m_schematic( aSchematic )
53  {
54  }
SCHEMATIC * m_schematic
Definition: erc.h:133

Member Function Documentation

◆ TestConflictingBusAliases()

int ERC_TESTER::TestConflictingBusAliases ( )

Check that there are no conflicting bus alias definitions in the schematic.

(for example, two hierarchical sub-sheets contain different definitions for the same bus alias)

Returns
the error count

Definition at line 282 of file erc.cpp.

283 {
284  wxString msg;
285  int err_count = 0;
286 
287  SCH_SCREENS screens( m_schematic->Root() );
288  std::vector< std::shared_ptr<BUS_ALIAS> > aliases;
289 
290  for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
291  {
292  std::unordered_set< std::shared_ptr<BUS_ALIAS> > screen_aliases = screen->GetBusAliases();
293 
294  for( const std::shared_ptr<BUS_ALIAS>& alias : screen_aliases )
295  {
296  for( const std::shared_ptr<BUS_ALIAS>& test : aliases )
297  {
298  if( alias->GetName() == test->GetName() && alias->Members() != test->Members() )
299  {
300  msg.Printf( _( "Bus alias %s has conflicting definitions on %s and %s" ),
301  alias->GetName(),
302  alias->GetParent()->GetFileName(),
303  test->GetParent()->GetFileName() );
304 
305  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_BUS_ALIAS_CONFLICT );
306  ercItem->SetErrorMessage( msg );
307 
308  SCH_MARKER* marker = new SCH_MARKER( ercItem, wxPoint() );
309  test->GetParent()->Append( marker );
310 
311  ++err_count;
312  }
313  }
314  }
315 
316  aliases.insert( aliases.end(), screen_aliases.begin(), screen_aliases.end() );
317  }
318 
319  return err_count;
320 }
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
#define _(s)
SCH_SHEET & Root() const
Definition: schematic.h:92
Conflicting bus alias definitions across sheets.
Definition: erc_settings.h:55
SCHEMATIC * m_schematic
Definition: erc.h:133
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:557

References _, ERC_ITEM::Create(), ERCE_BUS_ALIAS_CONFLICT, m_schematic, and SCHEMATIC::Root().

Referenced by DIALOG_ERC::testErc().

◆ TestDuplicateSheetNames()

int ERC_TESTER::TestDuplicateSheetNames ( bool  aCreateMarker)

Inside a given sheet, one cannot have sheets with duplicate names (file names can be duplicated).

Returns
the error count
Parameters
aCreateMarkertrue = create error markers in schematic, false = calculate error count only

Definition at line 118 of file erc.cpp.

119 {
120  SCH_SCREEN* screen;
121  int err_count = 0;
122 
123  SCH_SCREENS screenList( m_schematic->Root() );
124 
125  for( screen = screenList.GetFirst(); screen != nullptr; screen = screenList.GetNext() )
126  {
127  std::vector<SCH_SHEET*> list;
128 
129  for( SCH_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
130  list.push_back( static_cast<SCH_SHEET*>( item ) );
131 
132  for( size_t i = 0; i < list.size(); i++ )
133  {
134  SCH_SHEET* sheet = list[i];
135 
136  for( size_t j = i + 1; j < list.size(); j++ )
137  {
138  SCH_SHEET* test_item = list[j];
139 
140  // We have found a second sheet: compare names
141  // we are using case insensitive comparison to avoid mistakes between
142  // similar names like Mysheet and mysheet
143  if( sheet->GetName().CmpNoCase( test_item->GetName() ) == 0 )
144  {
145  if( aCreateMarker )
146  {
147  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DUPLICATE_SHEET_NAME );
148  ercItem->SetItems( sheet, test_item );
149 
150  SCH_MARKER* marker = new SCH_MARKER( ercItem, sheet->GetPosition() );
151  screen->Append( marker );
152  }
153 
154  err_count++;
155  }
156  }
157  }
158  }
159 
160  return err_count;
161 }
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
wxString GetName() const
Definition: sch_sheet.h:101
wxPoint GetPosition() const override
Definition: sch_sheet.h:380
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
SCH_SHEET & Root() const
Definition: schematic.h:92
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
SCHEMATIC * m_schematic
Definition: erc.h:133
Duplicate sheet names within a given sheet.
Definition: erc_settings.h:40
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:557

References SCH_SCREEN::Append(), ERC_ITEM::Create(), ERCE_DUPLICATE_SHEET_NAME, SCH_SHEET::GetName(), SCH_SHEET::GetPosition(), SCH_SCREEN::Items(), m_schematic, EE_RTREE::OfType(), SCHEMATIC::Root(), and SCH_SHEET_T.

Referenced by DIALOG_ERC::testErc().

◆ TestLibSymbolIssues()

int ERC_TESTER::TestLibSymbolIssues ( )

Test symbols for changed library symbols and broken symbol library links.

Returns
the number of issues found

Definition at line 675 of file erc.cpp.

676 {
677  wxCHECK( m_schematic, 0 );
678 
679  SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
680  wxString msg;
681  int err_count = 0;
682 
683  SCH_SCREENS screens( m_schematic->Root() );
684 
685  for( SCH_SCREEN* screen = screens.GetFirst(); screen != nullptr; screen = screens.GetNext() )
686  {
687  std::vector<SCH_MARKER*> markers;
688 
689  for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
690  {
691  SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item );
692 
693  wxCHECK2( symbol, continue );
694 
695  LIB_SYMBOL* libSymbolInSchematic = symbol->GetLibSymbolRef().get();
696 
697  wxCHECK2( libSymbolInSchematic, continue );
698 
699  wxString libName = symbol->GetLibId().GetLibNickname();
700  LIB_TABLE_ROW* libTableRow = libTable->FindRow( libName, true );
701 
702  if( !libTableRow )
703  {
704  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
705  ercItem->SetItems( symbol );
706  msg.Printf( _( "The current configuration does not include the library '%s'." ),
707  UnescapeString( libName ) );
708  ercItem->SetErrorMessage( msg );
709 
710  markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
711  continue;
712  }
713  else if( !libTable->HasLibrary( libName, true ) )
714  {
715  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
716  ercItem->SetItems( symbol );
717  msg.Printf( _( "The library '%s' is not enabled in the current configuration." ),
718  UnescapeString( libName ) );
719  ercItem->SetErrorMessage( msg );
720 
721  markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
722  continue;
723  }
724 
725  wxString symbolName = symbol->GetLibId().GetLibItemName();
726  LIB_SYMBOL* libSymbol = SchGetLibSymbol( symbol->GetLibId(), libTable );
727 
728  if( libSymbol == nullptr )
729  {
730  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
731  ercItem->SetItems( symbol );
732  msg.Printf( "Symbol '%s' not found in symbol library '%s'.",
733  UnescapeString( symbolName ),
734  UnescapeString( libName ) );
735  ercItem->SetErrorMessage( msg );
736 
737  markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
738  continue;
739  }
740 
741  std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
742 
743  if( *flattenedSymbol != *libSymbolInSchematic )
744  {
745  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_LIB_SYMBOL_ISSUES );
746  ercItem->SetItems( symbol );
747  msg.Printf( "Symbol '%s' has been modified in library '%s'.",
748  UnescapeString( symbolName ),
749  UnescapeString( libName ) );
750  ercItem->SetErrorMessage( msg );
751 
752  markers.emplace_back( new SCH_MARKER( ercItem, symbol->GetPosition() ) );
753  }
754  }
755 
756  for( SCH_MARKER* marker : markers )
757  {
758  screen->Append( marker );
759  err_count += 1;
760  }
761  }
762 
763  return err_count;
764 }
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
Hold a record identifying a library accessed by the appropriate plug in object in the LIB_TABLE.
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
LIB_SYMBOL * SchGetLibSymbol(const LIB_ID &aLibId, SYMBOL_LIB_TABLE *aLibTable, SYMBOL_LIB *aCacheLib, wxWindow *aParent, bool aShowErrorMsg)
Load symbol from symbol library table.
Define a library symbol object.
Definition: lib_symbol.h:96
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:332
Library symbol changed from current symbol in schematic or the library symbol link no longer valid.
Definition: erc_settings.h:66
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition: sch_symbol.h:164
#define _(s)
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
wxString UnescapeString(const wxString &aSource)
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
SCH_SHEET & Root() const
Definition: schematic.h:92
Schematic symbol object.
Definition: sch_symbol.h:78
wxPoint GetPosition() const override
Definition: sch_symbol.h:641
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
SCHEMATIC * m_schematic
Definition: erc.h:133
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:557
const LIB_ID & GetLibId() const
Definition: sch_symbol.h:147

References _, ERC_ITEM::Create(), ERCE_LIB_SYMBOL_ISSUES, SYMBOL_LIB_TABLE::FindRow(), LIB_SYMBOL::Flatten(), SCH_SYMBOL::GetLibId(), LIB_ID::GetLibItemName(), LIB_ID::GetLibNickname(), SCH_SYMBOL::GetLibSymbolRef(), SCH_SYMBOL::GetPosition(), LIB_TABLE::HasLibrary(), m_schematic, SCHEMATIC::Prj(), SCHEMATIC::Root(), SCH_SYMBOL_T, SchGetLibSymbol(), and UnescapeString().

Referenced by DIALOG_ERC::testErc().

◆ TestMultiunitFootprints()

int ERC_TESTER::TestMultiunitFootprints ( )

Test if all units of each multiunit symbol have the same footprint assigned.

Returns
The error count.

Definition at line 323 of file erc.cpp.

324 {
326 
327  int errors = 0;
328  std::map<wxString, LIB_ID> footprints;
330  sheets.GetMultiUnitSymbols( refMap, true );
331 
332  for( std::pair<const wxString, SCH_REFERENCE_LIST>& symbol : refMap )
333  {
334  SCH_REFERENCE_LIST& refList = symbol.second;
335 
336  if( refList.GetCount() == 0 )
337  {
338  wxFAIL; // it should not happen
339  continue;
340  }
341 
342  // Reference footprint
343  SCH_SYMBOL* unit = nullptr;
344  wxString unitName;
345  wxString unitFP;
346 
347  for( unsigned i = 0; i < refList.GetCount(); ++i )
348  {
349  SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
350  unitFP = refList.GetItem( i ).GetFootprint();
351 
352  if( !unitFP.IsEmpty() )
353  {
354  unit = refList.GetItem( i ).GetSymbol();
355  unitName = unit->GetRef( &sheetPath, true );
356  break;
357  }
358  }
359 
360  for( unsigned i = 0; i < refList.GetCount(); ++i )
361  {
362  SCH_REFERENCE& secondRef = refList.GetItem( i );
363  SCH_SYMBOL* secondUnit = secondRef.GetSymbol();
364  wxString secondName = secondUnit->GetRef( &secondRef.GetSheetPath(), true );
365  const wxString secondFp = secondRef.GetFootprint();
366  wxString msg;
367 
368  if( unit && !secondFp.IsEmpty() && unitFP != secondFp )
369  {
370  msg.Printf( _( "Different footprints assigned to %s and %s" ),
371  unitName, secondName );
372 
373  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_FP );
374  ercItem->SetErrorMessage( msg );
375  ercItem->SetItems( unit, secondUnit );
376 
377  SCH_MARKER* marker = new SCH_MARKER( ercItem, secondUnit->GetPosition() );
378  secondRef.GetSheetPath().LastScreen()->Append( marker );
379 
380  ++errors;
381  }
382  }
383  }
384 
385  return errors;
386 }
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
SCH_REFERENCE & GetItem(int aIdx)
Different units of the same symbol have different footprints assigned.
Definition: erc_settings.h:51
void GetMultiUnitSymbols(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true) const
Add a SCH_REFERENCE_LIST object to aRefList for each same-reference set of multi-unit parts in the li...
const SCH_SHEET_PATH & GetSheetPath() const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
SCH_SYMBOL * GetSymbol() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:441
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
const wxString GetFootprint() const
#define _(s)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
Schematic symbol object.
Definition: sch_symbol.h:78
SCH_SCREEN * LastScreen()
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
wxPoint GetPosition() const override
Definition: sch_symbol.h:641
SCHEMATIC * m_schematic
Definition: erc.h:133
A helper to define a symbol's reference designator in a schematic.

References _, SCH_SCREEN::Append(), ERC_ITEM::Create(), ERCE_DIFFERENT_UNIT_FP, SCH_REFERENCE_LIST::GetCount(), SCH_REFERENCE::GetFootprint(), SCH_REFERENCE_LIST::GetItem(), SCH_SHEET_LIST::GetMultiUnitSymbols(), SCH_SYMBOL::GetPosition(), SCH_SYMBOL::GetRef(), SCH_REFERENCE::GetSheetPath(), SCHEMATIC::GetSheets(), SCH_REFERENCE::GetSymbol(), SCH_SHEET_PATH::LastScreen(), and m_schematic.

Referenced by DIALOG_ERC::testErc().

◆ TestMultUnitPinConflicts()

int ERC_TESTER::TestMultUnitPinConflicts ( )

Checks if shared pins on multi-unit symbols have been connected to different nets.

Returns
the error count

Definition at line 562 of file erc.cpp.

563 {
564  const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
565 
566  int errors = 0;
567 
568  std::unordered_map<wxString, std::pair<wxString, SCH_PIN*>> pinToNetMap;
569 
570  for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
571  {
572  const wxString& netName = net.first.first;
573  std::vector<SCH_PIN*> pins;
574 
575  for( CONNECTION_SUBGRAPH* subgraph : net.second )
576  {
577  for( EDA_ITEM* item : subgraph->m_items )
578  {
579  if( item->Type() == SCH_PIN_T )
580  {
581  SCH_PIN* pin = static_cast<SCH_PIN*>( item );
582 
583  if( !pin->GetLibPin()->GetParent()->IsMulti() )
584  continue;
585 
586  wxString name = pin->GetParentSymbol()->GetRef( &subgraph->m_sheet ) +
587  + ":" + pin->GetShownNumber();
588 
589  if( !pinToNetMap.count( name ) )
590  {
591  pinToNetMap[name] = std::make_pair( netName, pin );
592  }
593  else if( pinToNetMap[name].first != netName )
594  {
595  std::shared_ptr<ERC_ITEM> ercItem =
597 
598  ercItem->SetErrorMessage( wxString::Format(
599  _( "Pin %s is connected to both %s and %s" ),
600  pin->GetShownNumber(),
601  netName,
602  pinToNetMap[name].first ) );
603 
604  ercItem->SetItems( pin, pinToNetMap[name].second );
605  ercItem->SetIsSheetSpecific();
606 
607  SCH_MARKER* marker = new SCH_MARKER( ercItem,
608  pin->GetTransformedPosition() );
609  subgraph->m_sheet.LastScreen()->Append( marker );
610  errors += 1;
611  }
612  }
613  }
614  }
615  }
616 
617  return errors;
618 }
SCH_SHEET_PATH m_sheet
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:131
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
std::pair< wxString, int > NET_NAME_CODE
Associates a net code with the final name of a net.
A subgraph is a set of items that are electrically connected on a single sheet.
std::vector< SCH_ITEM * > m_items
Shared pin in a multi-unit symbol is connected to more than one net.
Definition: erc_settings.h:53
const NET_MAP & GetNetMap() const
#define _(s)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
SCH_SCREEN * LastScreen()
const char * name
Definition: DXF_plotter.cpp:56
std::map< NET_NAME_CODE, std::vector< CONNECTION_SUBGRAPH * > > NET_MAP
Associates a NET_CODE_NAME with all the subgraphs in that net.
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
SCHEMATIC * m_schematic
Definition: erc.h:133
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113

References _, SCH_SCREEN::Append(), SCHEMATIC::ConnectionGraph(), ERC_ITEM::Create(), ERCE_DIFFERENT_UNIT_NET, Format(), CONNECTION_GRAPH::GetNetMap(), SCH_SHEET_PATH::LastScreen(), CONNECTION_SUBGRAPH::m_items, m_schematic, CONNECTION_SUBGRAPH::m_sheet, name, pin, SCH_PIN_T, and EDA_ITEM::Type().

Referenced by DIALOG_ERC::testErc().

◆ TestNoConnectPins()

int ERC_TESTER::TestNoConnectPins ( )

In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.

In KiCad 6, this no longer results in those pins joining the net, so we need to warn about it

Returns
the error count

Definition at line 389 of file erc.cpp.

390 {
391  int err_count = 0;
392 
393  for( const SCH_SHEET_PATH& sheet : m_schematic->GetSheets() )
394  {
395  std::map<wxPoint, std::vector<SCH_PIN*>> pinMap;
396 
397  for( SCH_ITEM* item : sheet.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
398  {
399  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
400 
401  for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
402  {
403  if( pin->GetLibPin()->GetType() == ELECTRICAL_PINTYPE::PT_NC )
404  pinMap[pin->GetPosition()].emplace_back( pin );
405  }
406  }
407 
408  for( auto& pair : pinMap )
409  {
410  if( pair.second.size() > 1 )
411  {
412  err_count++;
413 
414  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED );
415 
416  ercItem->SetItems( pair.second[0], pair.second[1],
417  pair.second.size() > 2 ? pair.second[2] : nullptr,
418  pair.second.size() > 3 ? pair.second[3] : nullptr );
419  ercItem->SetErrorMessage( _( "Pins with \"no connection\" type are connected" ) );
420 
421  SCH_MARKER* marker = new SCH_MARKER( ercItem, pair.first );
422  sheet.LastScreen()->Append( marker );
423  }
424  }
425  }
426 
427  return err_count;
428 }
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
#define _(s)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
A no connect symbol is connected to more than 1 pin.
Definition: erc_settings.h:47
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
Schematic symbol object.
Definition: sch_symbol.h:78
SCHEMATIC * m_schematic
Definition: erc.h:133
not connected (must be left open)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
Definition: sch_symbol.cpp:866

References _, ERC_ITEM::Create(), ERCE_NOCONNECT_CONNECTED, SCH_SYMBOL::GetPins(), SCHEMATIC::GetSheets(), m_schematic, pin, PT_NC, and SCH_SYMBOL_T.

Referenced by DIALOG_ERC::testErc().

◆ TestOthersItems()

void ERC_TESTER::TestOthersItems ( NETLIST_OBJECT_LIST *  aList,
unsigned  aNetItemRef,
unsigned  aNetStart,
int *  aMinConnexion 
)

Perform ERC testing for electrical conflicts between NetItemRef and other items (mainly pin) on the same net.

Parameters
aList= a reference to the list of connected objects
aNetItemRef= index in list of the current object
aNetStart= index in list of net objects of the first item
aMinConnexion= a pointer to a variable to store the minimal connection found( NOD, DRV, NPI, NET_NC)

◆ TestPinToPin()

int ERC_TESTER::TestPinToPin ( )

Checks the full netlist against the pin-to-pin connectivity requirements.

Returns
the error count

Definition at line 431 of file erc.cpp.

432 {
433  ERC_SETTINGS& settings = m_schematic->ErcSettings();
434  const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
435 
436  int errors = 0;
437 
438  for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
439  {
440  std::vector<SCH_PIN*> pins;
441  std::unordered_map<EDA_ITEM*, SCH_SCREEN*> pinToScreenMap;
442 
443  for( CONNECTION_SUBGRAPH* subgraph: net.second )
444  {
445  for( EDA_ITEM* item : subgraph->m_items )
446  {
447  if( item->Type() == SCH_PIN_T )
448  {
449  pins.emplace_back( static_cast<SCH_PIN*>( item ) );
450  pinToScreenMap[item] = subgraph->m_sheet.LastScreen();
451  }
452  }
453  }
454 
455  // Single-pin nets are handled elsewhere
456  if( pins.size() < 2 )
457  continue;
458 
459  std::set<std::pair<SCH_PIN*, SCH_PIN*>> tested;
460 
461  SCH_PIN* needsDriver = nullptr;
462  bool hasDriver = false;
463 
464  // We need different drivers for power nets and normal nets.
465  // A power net has at least one pin having the ELECTRICAL_PINTYPE::PT_POWER_IN
466  // and power nets can be driven only by ELECTRICAL_PINTYPE::PT_POWER_OUT pins
467  bool ispowerNet = false;
468 
469  for( SCH_PIN* refPin : pins )
470  {
471  if( refPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
472  {
473  ispowerNet = true;
474  break;
475  }
476  }
477 
478  for( SCH_PIN* refPin : pins )
479  {
480  ELECTRICAL_PINTYPE refType = refPin->GetType();
481 
482  if( DrivenPinTypes.count( refType ) )
483  {
484  // needsDriver will be the pin shown in the error report eventually, so try to
485  // upgrade to a "better" pin if possible: something visible and only a power symbol
486  // if this net needs a power driver
487  if( !needsDriver ||
488  ( !needsDriver->IsVisible() && refPin->IsVisible() ) ||
489  ( ispowerNet != ( needsDriver->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN ) &&
490  ispowerNet == ( refType == ELECTRICAL_PINTYPE::PT_POWER_IN ) ) )
491  {
492  needsDriver = refPin;
493  }
494  }
495 
496  if( ispowerNet )
497  hasDriver |= ( DrivingPowerPinTypes.count( refType ) != 0 );
498  else
499  hasDriver |= ( DrivingPinTypes.count( refType ) != 0 );
500 
501  for( SCH_PIN* testPin : pins )
502  {
503  if( testPin == refPin )
504  continue;
505 
506  std::pair<SCH_PIN*, SCH_PIN*> pair1 = std::make_pair( refPin, testPin );
507  std::pair<SCH_PIN*, SCH_PIN*> pair2 = std::make_pair( testPin, refPin );
508 
509  if( tested.count( pair1 ) || tested.count( pair2 ) )
510  continue;
511 
512  tested.insert( pair1 );
513  tested.insert( pair2 );
514 
515  ELECTRICAL_PINTYPE testType = testPin->GetType();
516 
517  if( ispowerNet )
518  hasDriver |= ( DrivingPowerPinTypes.count( testType ) != 0 );
519  else
520  hasDriver |= ( DrivingPinTypes.count( testType ) != 0 );
521 
522  PIN_ERROR erc = settings.GetPinMapValue( refType, testType );
523 
524  if( erc != PIN_ERROR::OK )
525  {
526  std::shared_ptr<ERC_ITEM> ercItem =
529  ercItem->SetItems( refPin, testPin );
530  ercItem->SetIsSheetSpecific();
531 
532  ercItem->SetErrorMessage(
533  wxString::Format( _( "Pins of type %s and %s are connected" ),
534  ElectricalPinTypeGetText( refType ),
535  ElectricalPinTypeGetText( testType ) ) );
536 
537  SCH_MARKER* marker =
538  new SCH_MARKER( ercItem, refPin->GetTransformedPosition() );
539  pinToScreenMap[refPin]->Append( marker );
540  errors++;
541  }
542  }
543  }
544 
545  if( needsDriver && !hasDriver )
546  {
547  int err_code = ispowerNet ? ERCE_POWERPIN_NOT_DRIVEN : ERCE_PIN_NOT_DRIVEN;
548  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( err_code );
549 
550  ercItem->SetItems( needsDriver );
551 
552  SCH_MARKER* marker = new SCH_MARKER( ercItem, needsDriver->GetTransformedPosition() );
553  pinToScreenMap[needsDriver]->Append( marker );
554  errors++;
555  }
556  }
557 
558  return errors;
559 }
power input (GND, VCC for ICs). Must be connected to a power output.
SCH_SHEET_PATH m_sheet
const std::set< ELECTRICAL_PINTYPE > DrivenPinTypes
Definition: erc.cpp:112
const std::set< ELECTRICAL_PINTYPE > DrivingPowerPinTypes
Definition: erc.cpp:106
Power input pin connected to some others pins but no power out pin to drive it.
Definition: erc_settings.h:44
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:131
bool IsVisible() const
Definition: sch_pin.h:103
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:237
std::pair< wxString, int > NET_NAME_CODE
Associates a net code with the final name of a net.
const std::set< ELECTRICAL_PINTYPE > DrivingPinTypes
Definition: erc.cpp:94
PIN_ERROR
The values a pin-to-pin entry in the pin matrix can take on.
Definition: erc_settings.h:85
A subgraph is a set of items that are electrically connected on a single sheet.
Pin connected to some others pins but no pin to drive it.
Definition: erc_settings.h:42
std::vector< SCH_ITEM * > m_items
const NET_MAP & GetNetMap() const
#define _(s)
Container for ERC settings.
Definition: erc_settings.h:106
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
SCH_SCREEN * LastScreen()
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:35
std::map< NET_NAME_CODE, std::vector< CONNECTION_SUBGRAPH * > > NET_MAP
Associates a NET_CODE_NAME with all the subgraphs in that net.
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:113
PIN_ERROR GetPinMapValue(int aFirstType, int aSecondType) const
Definition: erc_settings.h:134
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:174
SCHEMATIC * m_schematic
Definition: erc.h:133
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
wxPoint GetTransformedPosition() const
Definition: sch_pin.cpp:299

References _, SCHEMATIC::ConnectionGraph(), ERC_ITEM::Create(), DrivenPinTypes, DrivingPinTypes, DrivingPowerPinTypes, ElectricalPinTypeGetText(), erc, ERCE_PIN_NOT_DRIVEN, ERCE_PIN_TO_PIN_ERROR, ERCE_PIN_TO_PIN_WARNING, ERCE_POWERPIN_NOT_DRIVEN, SCHEMATIC::ErcSettings(), Format(), CONNECTION_GRAPH::GetNetMap(), ERC_SETTINGS::GetPinMapValue(), SCH_PIN::GetTransformedPosition(), SCH_PIN::GetType(), SCH_PIN::IsVisible(), SCH_SHEET_PATH::LastScreen(), CONNECTION_SUBGRAPH::m_items, m_schematic, CONNECTION_SUBGRAPH::m_sheet, OK, PT_POWER_IN, SCH_PIN_T, EDA_ITEM::Type(), and WARNING.

Referenced by DIALOG_ERC::testErc().

◆ TestSimilarLabels()

int ERC_TESTER::TestSimilarLabels ( )

Checks for labels that differ only in capitalization.

Returns
the error count

Definition at line 621 of file erc.cpp.

622 {
623  const NET_MAP& nets = m_schematic->ConnectionGraph()->GetNetMap();
624 
625  int errors = 0;
626 
627  std::unordered_map<wxString, SCH_TEXT*> labelMap;
628 
629  for( const std::pair<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> net : nets )
630  {
631  std::vector<SCH_PIN*> pins;
632 
633  for( CONNECTION_SUBGRAPH* subgraph : net.second )
634  {
635  for( EDA_ITEM* item : subgraph->m_items )
636  {
637  switch( item->Type() )
638  {
639  case SCH_LABEL_T:
640  case SCH_HIER_LABEL_T:
641  case SCH_GLOBAL_LABEL_T:
642  {
643  SCH_TEXT* text = static_cast<SCH_TEXT*>( item );
644 
645  wxString normalized = text->GetShownText().Lower();
646 
647  if( !labelMap.count( normalized ) )
648  {
649  labelMap[normalized] = text;
650  }
651  else if( labelMap.at( normalized )->GetShownText() != text->GetShownText() )
652  {
653  std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_SIMILAR_LABELS );
654  ercItem->SetItems( text, labelMap.at( normalized ) );
655 
656  SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
657  subgraph->m_sheet.LastScreen()->Append( marker );
658  errors += 1;
659  }
660 
661  break;
662  }
663 
664  default:
665  break;
666  }
667  }
668  }
669  }
670 
671  return errors;
672 }
SCH_SHEET_PATH m_sheet
CONNECTION_GRAPH * ConnectionGraph() const override
Definition: schematic.h:131
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
std::pair< wxString, int > NET_NAME_CODE
Associates a net code with the final name of a net.
A subgraph is a set of items that are electrically connected on a single sheet.
std::vector< SCH_ITEM * > m_items
2 labels are equal for case insensitive comparisons.
Definition: erc_settings.h:50
const NET_MAP & GetNetMap() const
SCH_SCREEN * LastScreen()
std::map< NET_NAME_CODE, std::vector< CONNECTION_SUBGRAPH * > > NET_MAP
Associates a NET_CODE_NAME with all the subgraphs in that net.
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
SCHEMATIC * m_schematic
Definition: erc.h:133
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113

References SCH_SCREEN::Append(), SCHEMATIC::ConnectionGraph(), ERC_ITEM::Create(), ERCE_SIMILAR_LABELS, CONNECTION_GRAPH::GetNetMap(), SCH_SHEET_PATH::LastScreen(), CONNECTION_SUBGRAPH::m_items, m_schematic, CONNECTION_SUBGRAPH::m_sheet, SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_LABEL_T, text, and EDA_ITEM::Type().

Referenced by DIALOG_ERC::testErc().

◆ TestTextVars()

void ERC_TESTER::TestTextVars ( DS_PROXY_VIEW_ITEM aDrawingSheet)

Check for any unresolved text variable references.

Definition at line 164 of file erc.cpp.

165 {
166  DS_DRAW_ITEM_LIST wsItems;
167 
168  auto unresolved = [this]( wxString str )
169  {
170  str = ExpandEnvVarSubstitutions( str, &m_schematic->Prj() );
171  return str.Matches( wxT( "*${*}*" ) );
172  };
173 
174  if( aDrawingSheet )
175  {
176  wsItems.SetMilsToIUfactor( IU_PER_MILS );
177  wsItems.SetPageNumber( "1" );
178  wsItems.SetSheetCount( 1 );
179  wsItems.SetFileName( "dummyFilename" );
180  wsItems.SetSheetName( "dummySheet" );
181  wsItems.SetSheetLayer( "dummyLayer" );
182  wsItems.SetProject( &m_schematic->Prj() );
183  wsItems.BuildDrawItemsList( aDrawingSheet->GetPageInfo(), aDrawingSheet->GetTitleBlock());
184  }
185 
186  SCH_SHEET_PATH savedCurrentSheet = m_schematic->CurrentSheet();
188 
189  for( SCH_SHEET_PATH& sheet : sheets )
190  {
191  m_schematic->SetCurrentSheet( sheet );
192  SCH_SCREEN* screen = sheet.LastScreen();
193 
194  for( SCH_ITEM* item : screen->Items().OfType( SCH_LOCATE_ANY_T ) )
195  {
196  if( item->Type() == SCH_SYMBOL_T )
197  {
198  SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
199 
200  for( SCH_FIELD& field : symbol->GetFields() )
201  {
202  if( unresolved( field.GetShownText() ) )
203  {
204  wxPoint pos = field.GetPosition() - symbol->GetPosition();
205  pos = symbol->GetTransform().TransformCoordinate( pos );
206  pos += symbol->GetPosition();
207 
208  std::shared_ptr<ERC_ITEM> ercItem =
210  ercItem->SetItems( &field );
211 
212  SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
213  screen->Append( marker );
214  }
215  }
216  }
217  else if( item->Type() == SCH_SHEET_T )
218  {
219  SCH_SHEET* subSheet = static_cast<SCH_SHEET*>( item );
220 
221  for( SCH_FIELD& field : subSheet->GetFields() )
222  {
223  if( unresolved( field.GetShownText() ) )
224  {
225  std::shared_ptr<ERC_ITEM> ercItem =
227  ercItem->SetItems( &field );
228 
229  SCH_MARKER* marker = new SCH_MARKER( ercItem, field.GetPosition() );
230  screen->Append( marker );
231  }
232  }
233 
234  for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
235  {
236  if( pin->GetShownText().Matches( wxT( "*${*}*" ) ) )
237  {
238  std::shared_ptr<ERC_ITEM> ercItem =
240  ercItem->SetItems( pin );
241 
242  SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetPosition() );
243  screen->Append( marker );
244  }
245  }
246  }
247  else if( SCH_TEXT* text = dynamic_cast<SCH_TEXT*>( item ) )
248  {
249  if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
250  {
251  std::shared_ptr<ERC_ITEM> ercItem =
253  ercItem->SetItems( text );
254 
255  SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
256  screen->Append( marker );
257  }
258  }
259  }
260 
261  for( DS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
262  {
263  if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
264  {
265  if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
266  {
267  std::shared_ptr<ERC_ITEM> ercItem =
269  ercItem->SetErrorMessage( _( "Unresolved text variable in drawing sheet." ) );
270 
271  SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() );
272  screen->Append( marker );
273  }
274  }
275  }
276  }
277 
278  m_schematic->SetCurrentSheet( savedCurrentSheet );
279 }
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:216
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
const PAGE_INFO & GetPageInfo()
void SetMilsToIUfactor(double aMils2Iu)
Set the scalar to convert pages units (mils) to draw/plot units.
Definition: ds_draw_item.h:442
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:194
void SetFileName(const wxString &aFileName)
Set the filename to draw/plot.
Definition: ds_draw_item.h:415
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:711
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:279
TRANSFORM & GetTransform()
Definition: sch_symbol.h:231
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:88
Base class to handle basic graphic items.
Definition: ds_draw_item.h:58
A graphic text.
Definition: ds_draw_item.h:297
DS_DRAW_ITEM_BASE * GetNext()
Definition: ds_draw_item.h:494
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
Definition: ds_draw_item.h:455
#define _(s)
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:65
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
Definition: ds_draw_item.h:423
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:75
A text variable could not be resolved.
Definition: erc_settings.h:64
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
void BuildDrawItemsList(const PAGE_INFO &aPageInfo, const TITLE_BLOCK &aTitleBlock)
Drawing or plot the drawing sheet.
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
Definition: ds_draw_item.h:431
Schematic symbol object.
Definition: sch_symbol.h:78
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:144
const TITLE_BLOCK & GetTitleBlock()
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:110
void SetProject(const PROJECT *aProject)
Definition: ds_draw_item.h:400
#define IU_PER_MILS
Definition: plotter.cpp:136
void SetCurrentSheet(const SCH_SHEET_PATH &aPath) override
Definition: schematic.h:126
wxPoint GetPosition() const override
Definition: sch_symbol.h:641
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
Definition: ds_draw_item.h:468
Store the list of graphic items: rect, lines, polygons and texts to draw/plot the title block and fra...
Definition: ds_draw_item.h:376
SCHEMATIC * m_schematic
Definition: erc.h:133
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:121
DS_DRAW_ITEM_BASE * GetFirst()
Definition: ds_draw_item.h:484
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:193

References _, SCH_SCREEN::Append(), DS_DRAW_ITEM_LIST::BuildDrawItemsList(), ERC_ITEM::Create(), SCHEMATIC::CurrentSheet(), ERCE_UNRESOLVED_VARIABLE, ExpandEnvVarSubstitutions(), SCH_SHEET::GetFields(), SCH_SYMBOL::GetFields(), DS_DRAW_ITEM_LIST::GetFirst(), DS_DRAW_ITEM_LIST::GetNext(), DS_PROXY_VIEW_ITEM::GetPageInfo(), SCH_SYMBOL::GetPosition(), SCHEMATIC::GetSheets(), DS_PROXY_VIEW_ITEM::GetTitleBlock(), SCH_SYMBOL::GetTransform(), SCH_SCREEN::Items(), IU_PER_MILS, m_schematic, EE_RTREE::OfType(), pin, SCHEMATIC::Prj(), SCH_LOCATE_ANY_T, SCH_SHEET_T, SCH_SYMBOL_T, SCHEMATIC::SetCurrentSheet(), DS_DRAW_ITEM_LIST::SetFileName(), DS_DRAW_ITEM_LIST::SetMilsToIUfactor(), DS_DRAW_ITEM_LIST::SetPageNumber(), DS_DRAW_ITEM_LIST::SetProject(), DS_DRAW_ITEM_LIST::SetSheetCount(), DS_DRAW_ITEM_LIST::SetSheetLayer(), DS_DRAW_ITEM_LIST::SetSheetName(), text, and TRANSFORM::TransformCoordinate().

Referenced by DIALOG_ERC::testErc().

Member Data Documentation

◆ m_schematic


The documentation for this class was generated from the following files: