KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_net_chain_pin_to_pin.cpp
Go to the documentation of this file.
1#include <boost/test/unit_test.hpp>
3#include <erc/erc.h>
4#include <erc/erc_settings.h>
5#include <erc/erc_report.h>
7#include <connection_graph.h>
8#include <locale_io.h>
9#include <pin_type.h>
10
17
18BOOST_AUTO_TEST_SUITE( ERCSignal )
19
20// Validate that pins incompatible across multi-net grouped signals trigger ERC.
21// Schematic now defines 3 separate two-pin signals (X1-X2 power_out vs power_out,
22// X3-X4 power_out vs output, X6-X7 output vs output). All three should produce
23// pin-to-pin mismatch markers (warning or error depending on matrix severity).
25{
27 KI_TEST::LoadSchematic( m_settingsManager, wxString( "erc_net_chain_pin_to_pin" ), m_schematic );
28
29 ERC_SETTINGS& settings = m_schematic->ErcSettings();
32 // Ensure signals are constructed before ERC tests.
33 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
34 // Manually promote all potential net chains
35 {
36 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
37 int idx = 1;
38 for( const auto& pot : graph->GetPotentialNetChains() )
39 {
40 if( !pot ) continue;
41 wxString name = wxString::Format( wxS("ERC_SIG_%d"), idx++ );
42 graph->CreateNetChainFromPotential( pot.get(), name );
43 }
44 }
45 m_schematic->ConnectionGraph()->RunERC();
46
47 ERC_TESTER tester( m_schematic.get() );
48 tester.TestPinToPin();
49
50 SHEETLIST_ERC_ITEMS_PROVIDER provider( m_schematic.get() );
52
53 ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MM );
54
55 const int expectedMismatches = 3;
56
57 int mismatchCount = 0;
58 for( size_t i = 0; i < provider.GetCount(); ++i )
59 {
60 auto item = provider.GetItem( i );
61 if( !item )
62 continue;
63 auto code = item->GetErrorCode();
64 if( code == ERCE_PIN_TO_PIN_WARNING || code == ERCE_PIN_TO_PIN_ERROR )
65 mismatchCount++;
66 }
67
68 if( mismatchCount != expectedMismatches )
69 {
70 // Debug dump of signals when expectation fails
71 auto* graph = m_schematic->ConnectionGraph();
72 // Ensure signals are rebuilt explicitly in case RunERC did not force it
73 graph->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
74 const auto& netChains = graph->GetCommittedNetChains();
75 std::ostringstream oss;
76 oss << "DEBUG Pin-to-Pin mismatch failure: expected=" << expectedMismatches
77 << " got=" << mismatchCount << " totalItems=" << provider.GetCount()
78 << " chains=" << netChains.size() << "\n";
79 for( size_t si = 0; si < netChains.size(); ++si )
80 {
81 const auto& sig = netChains[si];
82 if( !sig ) continue;
83 oss << " Signal[" << si << "] name='" << sig->GetName() << "' nets={";
84 for( const auto& n : sig->GetNets() ) oss << n << ",";
85 oss << "} pins={";
86 // Collect pins per net via public GetAllSubgraphs API
87 for( const auto& n : sig->GetNets() )
88 {
89 const auto& subgraphs = graph->GetAllSubgraphs( n );
90 for( CONNECTION_SUBGRAPH* sg : subgraphs )
91 {
92 for( SCH_ITEM* item : sg->GetItems() )
93 {
94 if( item->Type() == SCH_PIN_T )
95 {
96 SCH_PIN* p = static_cast<SCH_PIN*>( item );
97 oss << p->GetParentSymbol()->GetRef( &sg->GetSheet() ) << ":" << p->GetNumber() << "=" << (int) p->GetType() << ";";
98 }
99 }
100 }
101 }
102 oss << "}\n";
103 }
104 // Also list all item codes for clarity
105 oss << "All ERC item codes (severity filtered): ";
106 for( size_t i = 0; i < provider.GetCount(); ++i )
107 {
108 auto it = provider.GetItem( i );
109 if( it )
110 oss << (int) it->GetErrorCode() << ",";
111 }
112 oss << "\n";
113
114 BOOST_CHECK_MESSAGE( mismatchCount == expectedMismatches,
115 oss.str() + reportWriter.GetTextReport() );
116 }
117 else
118 BOOST_CHECK_MESSAGE( mismatchCount == expectedMismatches,
119 "Expected 3 pin-to-pin mismatch errors but got " << mismatchCount
120 << "\n" << reportWriter.GetTextReport() );
121}
122
123// New test: ensure power input pin on one net is considered driven by power output on another net in same signal.
124BOOST_FIXTURE_TEST_CASE( ERCSignalPowerInputDrivenAcrossSignal, ERC_SIGNAL_TEST_FIXTURE )
125{
127 KI_TEST::LoadSchematic( m_settingsManager, wxString( "erc_net_chain_input_power_driven" ), m_schematic );
128
129 ERC_SETTINGS& settings = m_schematic->ErcSettings();
132 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(), true );
133 // Promote potential net chains prior to ERC.
134 {
135 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
136 int idx = 1;
137 for( const auto& pot : graph->GetPotentialNetChains() )
138 {
139 if( !pot ) continue;
140 wxString name = wxString::Format( wxS("ERC_SIG_%d"), idx++ );
141 graph->CreateNetChainFromPotential( pot.get(), name );
142 }
143 }
144 m_schematic->ConnectionGraph()->RunERC();
145
146 ERC_TESTER tester( m_schematic.get() );
147 tester.TestPinToPin();
148
149 SHEETLIST_ERC_ITEMS_PROVIDER provider( m_schematic.get() );
151
152 // Count any POWER PIN NOT DRIVEN markers (should be zero due to suppression across signal)
153 int powerNotDriven = 0;
154 for( size_t i = 0; i < provider.GetCount(); ++i )
155 {
156 auto item = provider.GetItem( i );
157 if( item && item->GetErrorCode() == ERCE_POWERPIN_NOT_DRIVEN )
158 powerNotDriven++;
159 }
160
161 ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MM );
162 BOOST_CHECK_MESSAGE( powerNotDriven == 0, "Expected no ERCE_POWERPIN_NOT_DRIVEN errors due to cross-signal driver; got " << powerNotDriven << "\n" << reportWriter.GetTextReport() );
163}
164
165// Regression test for chain-cross pin-to-pin gating. The chain-cross gate
166// previously consulted IsTestEnabled( ERCE_PIN_TO_PIN_WARNING ) regardless of
167// the resolved code, so silencing pin-to-pin warnings also suppressed
168// pin-to-pin errors. The fix selects ercCode (warning vs error) from the
169// resolved PIN_ERROR first, then gates IsTestEnabled( ercCode ). To make the
170// regression observable, ERCE_PIN_TO_PIN_WARNING and ERCE_PIN_TO_PIN_ERROR
171// must be independently controllable; that decoupling lives in
172// ERC_SETTINGS::GetSeverity.
173BOOST_FIXTURE_TEST_CASE( ERCSignalPinToPinErrorMatrixMapped, ERC_SIGNAL_TEST_FIXTURE )
174{
176 KI_TEST::LoadSchematic( m_settingsManager, wxString( "erc_net_chain_pin_to_pin" ), m_schematic );
177
178 ERC_SETTINGS& settings = m_schematic->ErcSettings();
181
182 // Force OUTPUT-OUTPUT pairs to PP_ERROR so the X6/X7 chain-cross pair
183 // resolves to ERCE_PIN_TO_PIN_ERROR rather than ERCE_PIN_TO_PIN_WARNING.
186
187 // Silence ERCE_PIN_TO_PIN_WARNING while leaving ERCE_PIN_TO_PIN_ERROR active.
188 // Under the OLD gate (always IsTestEnabled( ERCE_PIN_TO_PIN_WARNING )) this
189 // would suppress the marker; under the NEW gate the resolved ercCode is
190 // ERCE_PIN_TO_PIN_ERROR, which is still enabled, so the marker reports.
193
196
197 m_schematic->ConnectionGraph()->Recalculate( m_schematic->BuildSheetListSortedByPageNumbers(),
198 true );
199
200 {
201 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
202 int idx = 1;
203
204 for( const auto& pot : graph->GetPotentialNetChains() )
205 {
206 if( !pot )
207 continue;
208
209 wxString name = wxString::Format( wxS( "ERC_SIG_%d" ), idx++ );
210 graph->CreateNetChainFromPotential( pot.get(), name );
211 }
212 }
213
214 m_schematic->ConnectionGraph()->RunERC();
215
216 ERC_TESTER tester( m_schematic.get() );
217 tester.TestPinToPin();
218
219 SHEETLIST_ERC_ITEMS_PROVIDER provider( m_schematic.get() );
221
222 int errorCount = 0;
223 int warningCount = 0;
224
225 for( size_t i = 0; i < provider.GetCount(); ++i )
226 {
227 auto item = provider.GetItem( i );
228
229 if( !item )
230 continue;
231
232 if( item->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR )
233 errorCount++;
234 else if( item->GetErrorCode() == ERCE_PIN_TO_PIN_WARNING )
235 warningCount++;
236 }
237
238 ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MM );
239
240 BOOST_CHECK_MESSAGE( errorCount > 0,
241 "Expected ERCE_PIN_TO_PIN_ERROR markers to be reported when only"
242 " ERCE_PIN_TO_PIN_WARNING is silenced, but got "
243 << errorCount << "\n"
244 << reportWriter.GetTextReport() );
245
246 BOOST_CHECK_MESSAGE( warningCount == 0,
247 "Expected zero ERCE_PIN_TO_PIN_WARNING markers when warning is silenced,"
248 " got " << warningCount << "\n"
249 << reportWriter.GetTextReport() );
250}
251
const char * name
Calculate the connectivity of a schematic and generates netlists.
SCH_NETCHAIN * CreateNetChainFromPotential(SCH_NETCHAIN *aPotential, const wxString &aName)
Promote a potential net chain to an actual user net chain with the provided name.
const std::vector< std::unique_ptr< SCH_NETCHAIN > > & GetPotentialNetChains() const
Potential net chains are inferred groupings produced by RebuildNetChains() but not yet user-committed...
A subgraph is a set of items that are electrically connected on a single sheet.
wxString GetTextReport()
Returns the ERC report in "text" (human readable) format in the C-locale.
Container for ERC settings.
bool IsTestEnabled(int aErrorCode) const
std::map< int, SEVERITY > m_ERCSeverities
void SetPinMapValue(int aFirstType, int aSecondType, PIN_ERROR aValue)
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition erc.cpp:984
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:41
int GetErrorCode() const
Definition rc_item.h:161
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:168
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:278
const wxString & GetNumber() const
Definition sch_pin.h:127
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:393
An implementation of the RC_ITEM_LIST interface which uses the global SHEETLIST to fulfill the contra...
int GetCount(int aSeverity=-1) const override
void SetSeverities(int aSeverities) override
std::shared_ptr< RC_ITEM > GetItem(int aIndex) const override
Retrieve a RC_ITEM by index.
virtual const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const =0
@ ERCE_POWERPIN_NOT_DRIVEN
Power input pin connected to some others pins but no power out pin to drive it.
@ ERCE_LIB_SYMBOL_MISMATCH
Symbol doesn't match copy in library.
@ ERCE_PIN_TO_PIN_WARNING
@ ERCE_LIB_SYMBOL_ISSUES
Symbol not found in active libraries.
@ ERCE_PIN_TO_PIN_ERROR
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ PT_OUTPUT
usual output
Definition pin_type.h:38
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
std::vector< FAB_LAYER_COLOR > dummy
std::unique_ptr< SCHEMATIC > m_schematic
BOOST_FIXTURE_TEST_CASE(ServerStartsAndResponds, API_SERVER_E2E_FIXTURE)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_FIXTURE_TEST_CASE(ERCSignalPinToPin, ERC_SIGNAL_TEST_FIXTURE)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
@ SCH_PIN_T
Definition typeinfo.h:154