KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_net_chain_total_length_sexpr.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.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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
20#include <boost/test/unit_test.hpp>
22#include <board.h>
23#include <pcb_track.h>
24#include <netinfo.h>
25#include <pad.h>
26#include <footprint.h>
29
30static const long long MM = 1000000LL; // internal units
31
32static const char* BOARD_FILE = "net_chains/net_chain_total_length.kicad_pcb";
33
34BOOST_AUTO_TEST_SUITE( SignalTotalLengthSexpr )
35
36BOOST_AUTO_TEST_CASE( SignalAggregateMatchesPadSpacing )
37{
38 PCB_IO_KICAD_SEXPR plugin;
39 std::unique_ptr<BOARD> board = plugin.LoadBoard( KI_TEST::GetPcbnewTestDataDir() + BOARD_FILE );
40 board->BuildConnectivity();
41
42 // Assign signal name
43 for( NETINFO_ITEM* net : board->GetNetInfo() )
44 if( net->GetNetCode() > 0 ) net->SetNetChain( wxS("Signal1") );
45
46 // Map net -> two pads (terminal pads) using pad net codes
47 std::map<int, std::vector<PAD*>> netPads;
48 for( FOOTPRINT* fp : board->Footprints() )
49 for( PAD* pad : fp->Pads() )
50 if( pad->GetNetCode() > 0 ) netPads[ pad->GetNetCode() ].push_back( pad );
51
52 for( auto& [code, pads] : netPads )
53 {
54 if( pads.size() >= 2 )
55 {
56 NETINFO_ITEM* net = board->FindNet( code );
57 net->SetTerminalPad( 0, pads[0] );
58 net->SetTerminalPad( 1, pads[1] );
59 }
60 }
61
62 NETINFO_ITEM* n1 = board->FindNet( wxS( "Net-(R1-Pad1)" ) );
63 BOOST_REQUIRE( n1 );
64
65 PNS_KICAD_IFACE_BASE ifaceBase; ifaceBase.SetBoard( board.get() );
66 long long extraLen = 0, extraDelay = 0;
67 bool ok = ifaceBase.GetSignalAggregate( n1, n1, extraLen, extraDelay );
68 BOOST_CHECK( ok );
69
70 // Compute actual routed length (with wiggles) and linear span for net1
71 long long net1TrackLen = 0;
72 bool havePoint = false; long long minX = 0, maxX = 0;
73 for( BOARD_ITEM* bi : board->Tracks() )
74 if( auto tr = dynamic_cast<PCB_TRACK*>( bi ) )
75 if( tr->GetNetCode() == n1->GetNetCode() )
76 {
77 net1TrackLen += ( tr->GetStart() - tr->GetEnd() ).EuclideanNorm();
78 long long sx = tr->GetStart().x; long long ex = tr->GetEnd().x;
79 if( !havePoint ) { minX = std::min( sx, ex ); maxX = std::max( sx, ex ); havePoint = true; }
80 else { minX = std::min( minX, std::min( sx, ex ) ); maxX = std::max( maxX, std::max( sx, ex ) ); }
81 }
82 long long net1Span = havePoint ? ( maxX - minX ) : 0;
83 BOOST_CHECK( net1Span > 0 );
84 BOOST_CHECK( net1TrackLen >= net1Span ); // jog increases physical path
85
86 // Chain layout: TP2(0,0) — net1 — R1 — net2 — R2 — net3 — R3 — net4 — TP1(30,0)
87 //
88 // Copper per net (tracks + jog segments):
89 // net1: 8.000 + 0.283 = 8.283 mm
90 // net2: 5.705 + 0.014 = 5.719 mm
91 // net3: 3.495 + 0.014 = 3.509 mm
92 // net4: 7.850 + 0.354 = 8.204 mm
93 // Total copper: 25.715 mm
94 //
95 // Bridging through resistors (pad-to-pad, not copper):
96 // R1: 1.65 mm, R2: 1.65 mm, R3: 1.65 mm = 4.95 mm
97 //
98 // Full chain: 25.715 + 4.95 = 30.665 mm
99 //
100 // GetSignalAggregate returns copper only (no bridging).
101 // extraLen = net2 + net3 + net4 copper = ~17.432 mm
102 long long totalCopper = net1TrackLen + extraLen;
103 long long expectedCopper = 25 * MM;
104 long long padSpacing = 30 * MM;
105 BOOST_CHECK_MESSAGE( totalCopper >= expectedCopper,
106 "RoutedTotal=" << totalCopper << " expected>=" << expectedCopper
107 << " net1Track=" << net1TrackLen << " extra=" << extraLen );
108 BOOST_CHECK( totalCopper < padSpacing ); // copper alone is less than pad spacing
109
110 // Compute bridging: pad-to-pad distance through each 2-net series component
111 long long bridging = 0;
112 for( FOOTPRINT* fp : board->Footprints() )
113 {
114 std::map<int, PAD*> chainPads;
115 for( PAD* pad : fp->Pads() )
116 {
117 NETINFO_ITEM* pn = pad->GetNet();
118 if( pn && !pn->GetNetChain().IsEmpty() )
119 chainPads.emplace( pn->GetNetCode(), pad );
120 }
121 if( chainPads.size() == 2 )
122 {
123 auto it = chainPads.begin();
124 PAD* p1 = it->second; ++it; PAD* p2 = it->second;
125 bridging += ( p1->GetCenter() - p2->GetCenter() ).EuclideanNorm();
126 }
127 }
128 BOOST_CHECK( bridging > 0 );
129
130 // Full chain length (copper + bridging) must cover the pad spacing
131 long long fullChain = totalCopper + bridging;
132 long long tol = 1 * MM;
133 BOOST_CHECK_MESSAGE( fullChain >= padSpacing && fullChain < padSpacing + tol,
134 "FullChain=" << fullChain << " padSpacing=" << padSpacing
135 << " copper=" << totalCopper << " bridging=" << bridging );
136}
137
General utilities for PCB file IO for QA programs.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
Handle the data for a net.
Definition netinfo.h:50
const wxString & GetNetChain() const
Definition netinfo.h:122
int GetNetCode() const
Definition netinfo.h:104
Definition pad.h:61
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition pad.h:327
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
std::unique_ptr< BOARD > LoadBoard(const wxString &aFileName, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into new BOA...
Definition pcb_io.cpp:72
void SetBoard(BOARD *aBoard)
bool GetSignalAggregate(PNS::NET_HANDLE aNetP, PNS::NET_HANDLE aNetN, long long &aExtraLength, long long &aExtraDelay) const override
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static const char * BOARD_FILE
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
static const long long MM