KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_shared_pin_multiunit.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
32
35
36#include <algorithm>
37
38#include <advanced_config.h>
39#include <sch_marker.h>
40#include <erc/erc_item.h>
41#include <sch_symbol.h>
42#include <connection_graph.h>
43#include <schematic.h>
44#include <erc/erc_settings.h>
45#include <erc/erc.h>
46#include <erc/erc_exclusion.h>
47#include <erc/erc_report.h>
50#include <locale_io.h>
51#include <scoped_set_reset.h>
52
53
61
62
63BOOST_FIXTURE_TEST_CASE( Issue1768_SharedPinDifferentNets, ERC_SHARED_PIN_TEST_FIXTURE )
64{
66
67 // Load the issue 1768 test schematic
68 // This schematic has a 4-unit diode symbol (ESDAxx-SC5-V) where pin 2 is the
69 // common anode shared across all units. In the test case, only unit 2 has
70 // pin 2 connected to GND, while the other units have pin 2 unconnected
71 // (which results in auto-generated net names).
72 KI_TEST::LoadSchematic( m_settingsManager, "issue1768/issue1768", m_schematic );
73
74 ERC_SETTINGS& settings = m_schematic->ErcSettings();
75 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
76
77 // Ignore library symbol warnings since we're using old/rescue symbols
80
81 // Build connectivity and run ERC
82 m_schematic->ConnectionGraph()->RunERC();
83
84 ERC_TESTER tester( m_schematic.get() );
85
86 // This is the key test - TestMultUnitPinConflicts should detect that the shared
87 // pin 2 is connected to different nets across different unit instances
88 int multiUnitErrors = tester.TestMultUnitPinConflicts();
89
91
92 ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MM );
93
94 // We expect at least one ERCE_DIFFERENT_UNIT_NET error because pin 2
95 // is connected to GND in one unit but has auto-generated nets in others
96 BOOST_CHECK_MESSAGE( multiUnitErrors > 0,
97 "Expected ERC to detect shared pin on different nets.\n"
98 << reportWriter.GetTextReport() );
99
100 // Verify the specific error type is present
101 bool foundDifferentUnitNetError = false;
102
103 for( int i = 0; i < errors.GetCount(); ++i )
104 {
105 std::shared_ptr<RC_ITEM> item = errors.GetItem( i );
106
107 if( item && item->GetErrorCode() == ERCE_DIFFERENT_UNIT_NET )
108 {
109 foundDifferentUnitNetError = true;
110 break;
111 }
112 }
113
114 BOOST_CHECK_MESSAGE( foundDifferentUnitNetError,
115 "Expected ERCE_DIFFERENT_UNIT_NET error for shared pin 2.\n"
116 << reportWriter.GetTextReport() );
117}
118
119
120BOOST_AUTO_TEST_CASE( Issue1768_NetlistPreferUserNet )
121{
122 LOCALE_IO locale;
123 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
124 SCOPED_SET_RESET restore( enabled, enabled );
125 struct EXPORTER : NETLIST_EXPORTER_KICAD
126 {
132 };
133
134 for( bool backend : { false, true } )
135 {
136 BOOST_TEST_CONTEXT( "new engine=" << backend )
137 {
138 enabled = backend;
139 SETTINGS_MANAGER settings;
140 std::unique_ptr<SCHEMATIC> schematic;
141 KI_TEST::LoadSchematic( settings, "issue1768/issue1768", schematic );
142 schematic->RebuildConnectivity();
143 const SCH_SHEET_PATH path = schematic->Hierarchy().front();
144 std::vector<SCH_SYMBOL*> units;
145
146 for( SCH_ITEM* item : path.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
147 {
148 auto* symbol = static_cast<SCH_SYMBOL*>( item );
149
150 if( symbol->GetRef( &path ) != "VD1" )
151 continue;
152
153 units.push_back( symbol );
154 }
155
156 BOOST_REQUIRE_EQUAL( units.size(), 4u );
157 EXPORTER exporter( schematic.get(), nullptr );
158 EXPORTER::CONNECTIVITY_SCOPE connectivity( exporter );
159 size_t sharedPins = 0;
160
161 for( const PIN_INFO& pin : exporter.CreatePinList( units.front(), path ) )
162 {
163 if( pin.num == "2" )
164 {
165 ++sharedPins;
166 BOOST_CHECK_EQUAL( pin.netName, wxString( "GND" ) );
167 }
168 }
169
170 BOOST_CHECK_EQUAL( sharedPins, 1u );
171 std::vector<PIN_INFO> nativePins;
172 exporter.findAllUnitsOfSymbol( units.front(), path, nativePins );
173 std::erase_if( nativePins, []( const PIN_INFO& pin ) { return pin.num != "2"; } );
174 BOOST_REQUIRE_EQUAL( nativePins.size(), 4u );
175
176 for( bool userFirst : { false, true } )
177 {
178 auto pins = nativePins;
179 std::stable_partition( pins.begin(), pins.end(), [&]( const PIN_INFO& pin )
180 {
181 return ( pin.netName == "GND" ) == userFirst;
182 } );
183 BOOST_REQUIRE_EQUAL( pins.front().netName == "GND", userFirst );
184 exporter.eraseDuplicatePins( pins );
185 std::erase_if( pins, []( const PIN_INFO& pin ) { return pin.num.empty(); } );
186 BOOST_REQUIRE_EQUAL( pins.size(), 1u );
187 BOOST_CHECK_EQUAL( pins.front().netName, wxString( "GND" ) );
188 }
189 }
190 }
191}
192
193
194BOOST_AUTO_TEST_CASE( ERCMultiUnitPinConflictsMatchLegacy )
195{
196 LOCALE_IO locale;
197 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
198 SCOPED_SET_RESET restore( enabled, false );
199 SETTINGS_MANAGER settings;
200 std::unique_ptr<SCHEMATIC> schematic;
201 KI_TEST::LoadSchematic( settings, "issue1768/issue1768", schematic );
202 schematic->RebuildConnectivity();
203 ERC_TESTER tester( schematic.get() );
204 const auto run = [&]()
205 {
206 const int count = tester.TestMultUnitPinConflicts();
207 std::vector<std::string> markers;
208 SCH_SCREENS screens( schematic->Root() );
209
210 for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
211 {
212 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
213 {
214 auto* marker = static_cast<SCH_MARKER*>( item );
215 BOOST_CHECK_EQUAL( marker->GetRCItem()->GetErrorCode(), ERCE_DIFFERENT_UNIT_NET );
216 BOOST_CHECK_EQUAL( marker->GetRCItem()->GetIDs().size(), 2 );
217 const auto ercItem = std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() );
218 BOOST_CHECK( ercItem->GetSpecificSheetPath().LastScreen() == screen );
219 markers.push_back( ERC_EXCLUSION::FromMarker( *marker ).GetSortKey()
220 + marker->GetRCItem()->GetErrorMessage( true ).ToStdString() );
221 }
222 }
223
224 BOOST_CHECK_EQUAL( count, markers.size() );
226 std::sort( markers.begin(), markers.end() );
227 return markers;
228 };
229 const auto legacy = run();
230 BOOST_REQUIRE( !legacy.empty() );
231 enabled = true;
232 schematic->RebuildConnectivity();
233 schematic->ConnectionGraph()->Reset();
234 const auto captured = run();
235 BOOST_TEST( captured == legacy, boost::test_tools::per_element() );
236}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
static ERC_EXCLUSION FromMarker(const SCH_MARKER &aMarker)
wxString GetTextReport()
Returns the ERC report in "text" (human readable) format in the C-locale.
Container for ERC settings.
std::map< int, SEVERITY > m_ERCSeverities
Runs the electrical rules checks and adds a SCH_MARKER for each violation.
Definition erc.h:60
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
Definition erc.cpp:2145
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
void findAllUnitsOfSymbol(SCH_SYMBOL *aSchSymbol, const SCH_SHEET_PATH &aSheetPath, std::vector< PIN_INFO > &aPins)
Find all units for symbols with multiple symbols per package.
void eraseDuplicatePins(std::vector< PIN_INFO > &pins)
Erase duplicate pins.
std::vector< PIN_INFO > CreatePinList(SCH_SYMBOL *aSymbol, const SCH_SHEET_PATH &aSheetPath)
Find a symbol from the DrawList and builds its pin list.
Generate the KiCad netlist format supported by Pcbnew.
NETLIST_EXPORTER_KICAD(SCHEMATIC *aSchematic, KIWAY *aKiway)
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition sch_screen.h:818
SCH_SCREEN * GetNext()
SCH_SCREEN * GetFirst()
void DeleteAllMarkers(enum MARKER_BASE::MARKER_T aMarkerType, bool aIncludeExclusions)
Delete all electronic rules check markers of aMarkerType from all the screens in the list.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:73
RAII class that sets an value at construction and resets it to the original value at destruction.
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.
@ ERCE_DIFFERENT_UNIT_NET
Shared pin in a multi-unit symbol is connected to more than one net.
@ ERCE_LIB_SYMBOL_MISMATCH
Symbol doesn't match copy in library.
@ ERCE_LIB_SYMBOL_ISSUES
Symbol not found in active libraries.
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
std::vector< FAB_LAYER_COLOR > dummy
std::unique_ptr< SCHEMATIC > m_schematic
BOOST_AUTO_TEST_CASE(Issue1768_NetlistPreferUserNet)
BOOST_FIXTURE_TEST_CASE(Issue1768_SharedPinDifferentNets, ERC_SHARED_PIN_TEST_FIXTURE)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
std::string path
KIBIS_PIN * pin
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_MARKER_T
Definition typeinfo.h:154