KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_length_item_order.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 2
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
27
29
30#include <board.h>
31#include <base_units.h>
32#include <netinfo.h>
33#include <pcb_track.h>
36
37#include <algorithm>
38#include <numeric>
39#include <set>
40
41
42BOOST_AUTO_TEST_SUITE( DrcLengthItemOrder )
43
44
45static VECTOR2I mmPoint( double aX, double aY )
46{
47 return VECTOR2I( pcbIUScale.mmToIU( aX ), pcbIUScale.mmToIU( aY ) );
48}
49
50
51static void addTrack( BOARD& aBoard, int aNetCode, PCB_LAYER_ID aLayer, const VECTOR2I& aStart, const VECTOR2I& aEnd )
52{
53 PCB_TRACK* track = new PCB_TRACK( &aBoard );
54 track->SetLayer( aLayer );
55 track->SetStart( aStart );
56 track->SetEnd( aEnd );
57 track->SetWidth( pcbIUScale.mmToIU( 0.115 ) );
58 track->SetNetCode( aNetCode );
59 aBoard.Add( track );
60}
61
62
63/*
64 * A via transition where both layers bend at the same point inside the via pad.
65 */
66static void buildViaTransition( BOARD& aBoard, int aNetCode )
67{
68 const VECTOR2I viaPos = mmPoint( 0.0, 0.0 );
69
70 // 0.190919 mm from the centre, inside the 0.2 mm via radius
71 const VECTOR2I bend = mmPoint( -0.135, -0.135 );
72
73 PCB_VIA* via = new PCB_VIA( &aBoard );
74 via->SetPosition( viaPos );
75 via->SetWidth( F_Cu, pcbIUScale.mmToIU( 0.4 ) );
76 via->SetDrill( pcbIUScale.mmToIU( 0.2 ) );
77 via->SetLayerPair( F_Cu, B_Cu );
78 via->SetNetCode( aNetCode );
79 aBoard.Add( via );
80
81 addTrack( aBoard, aNetCode, F_Cu, bend, viaPos );
82 addTrack( aBoard, aNetCode, F_Cu, mmPoint( -5.0, -0.135 ), bend );
83
84 addTrack( aBoard, aNetCode, B_Cu, bend, viaPos );
85 addTrack( aBoard, aNetCode, B_Cu, mmPoint( -5.0, -0.135 ), bend );
86}
87
88
89BOOST_AUTO_TEST_CASE( LengthIsIndependentOfItemOrder )
90{
91 BOARD board;
92
93 NETINFO_ITEM* net = new NETINFO_ITEM( &board, wxT( "sig" ), 1 );
94 board.Add( net );
95
96 buildViaTransition( board, net->GetNetCode() );
97
99 std::vector<LENGTH_DELAY_CALCULATION_ITEM> items;
100
101 for( PCB_TRACK* track : board.Tracks() )
102 items.emplace_back( calc->GetLengthCalculationItem( track ) );
103
104 BOOST_REQUIRE_EQUAL( items.size(), 5 );
105
106 constexpr PATH_OPTIMISATIONS drcOpts = {
107 .OptimiseVias = true, .MergeTracks = true, .OptimiseTracesInPads = true, .InferViaInPad = false
108 };
109
110 std::vector<size_t> order( items.size() );
111 std::iota( order.begin(), order.end(), 0 );
112
113 std::set<int64_t> lengths;
114
115 do
116 {
117 // CalculateLength consumes its input, so every order starts from fresh copies
118 std::vector<LENGTH_DELAY_CALCULATION_ITEM> ordered;
119 ordered.reserve( order.size() );
120
121 for( size_t idx : order )
122 ordered.emplace_back( items[idx] );
123
124 lengths.insert( calc->CalculateLength( ordered, drcOpts, nullptr, nullptr ) );
125 } while( std::next_permutation( order.begin(), order.end() ) );
126
127 BOOST_CHECK_MESSAGE( lengths.size() == 1, "net length depends on item order: "
128 << lengths.size() << " different lengths, spread "
129 << ( *lengths.rbegin() - *lengths.begin() ) / 1e6 << " mm" );
130}
131
132
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1524
LENGTH_DELAY_CALCULATION * GetLengthCalculation() const
Returns the track length calculator.
Definition board.h:1672
const TRACKS & Tracks() const
Definition board.h:462
Class which calculates lengths (and associated routing statistics) in a BOARD context.
int64_t CalculateLength(std::vector< LENGTH_DELAY_CALCULATION_ITEM > &aItems, PATH_OPTIMISATIONS aOptimisations, const PAD *aStartPad=nullptr, const PAD *aEndPad=nullptr) const
Calculates the electrical length of the given items.
LENGTH_DELAY_CALCULATION_ITEM GetLengthCalculationItem(const BOARD_CONNECTED_ITEM *aBoardItem) const
Return a LENGTH_CALCULATION_ITEM constructed from the given BOARD_CONNECTED_ITEM.
Handle the data for a net.
Definition netinfo.h:50
int GetNetCode() const
Definition netinfo.h:104
void SetEnd(const VECTOR2I &aEnd)
Definition pcb_track.h:94
void SetStart(const VECTOR2I &aStart)
Definition pcb_track.h:97
virtual void SetWidth(int aWidth)
Definition pcb_track.h:91
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ B_Cu
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:60
Struct to control which optimisations the length calculation code runs on the given path objects.
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(LengthIsIndependentOfItemOrder)
static void addTrack(BOARD &aBoard, int aNetCode, PCB_LAYER_ID aLayer, const VECTOR2I &aStart, const VECTOR2I &aEnd)
static void buildViaTransition(BOARD &aBoard, int aNetCode)
static VECTOR2I mmPoint(double aX, double aY)
BOOST_AUTO_TEST_SUITE_END()
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708