KiCad PCB EDA Suite
netlist_object.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 (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
31 #include <fctsys.h>
32 #include <macros.h>
33 #include <list>
34 
35 #include <sch_component.h>
36 #include <sch_connection.h>
37 #include <netlist_object.h>
38 #include <sch_edit_frame.h>
39 #include <schematic.h>
40 #include <project/net_settings.h>
41 
42 #if defined(DEBUG)
43 
44 #include <iostream>
45 
46 const char* ShowType( NETLIST_ITEM aType )
47 {
48  const char* ret;
49 
50  switch( aType )
51  {
53  ret = "segment"; break;
54 
55  case NETLIST_ITEM::BUS:
56  ret = "bus"; break;
57 
59  ret = "junction"; break;
60 
62  ret = "label"; break;
63 
65  ret = "hierlabel"; break;
66 
68  ret = "glabel"; break;
69 
71  ret = "buslblmember"; break;
72 
74  ret = "hierbuslblmember"; break;
75 
77  ret = "gbuslblmember"; break;
78 
80  ret = "sbuslblmember"; break;
81 
83  ret = "sheetlabel"; break;
84 
86  ret = "pinlabel"; break;
87 
88  case NETLIST_ITEM::PIN:
89  ret = "pin"; break;
90 
92  ret = "noconnect"; break;
93 
94  default:
95  ret = "??"; break;
96  }
97 
98  return ret;
99 }
100 
101 
102 void NETLIST_OBJECT::Show( std::ostream& out, int ndx ) const
103 {
104  wxString path = m_SheetPath.PathHumanReadable();
105 
106  out << "<netItem ndx=\"" << ndx << '"' <<
107  " type=\"" << ShowType( m_Type ) << '"' <<
108  " netCode=\"" << GetNet() << '"' <<
109  " sheet=\"" << TO_UTF8( path ) << '"' <<
110  ">\n";
111 
112  out << " <start " << m_Start << "/> <end " << m_End << "/>\n";
113 
114  if( !m_Label.IsEmpty() )
115  out << " <label>" << m_Label.mb_str() << "</label>\n";
116 
117  out << " <sheetpath>" << m_SheetPath.PathHumanReadable().mb_str() << "</sheetpath>\n";
118 
119  switch( m_Type )
120  {
121  case NETLIST_ITEM::PIN:
122  /* GetRef() needs to be const
123  out << " <refOfComp>" << GetComponentParent()->GetRef(&m_SheetPath).mb_str()
124  << "</refOfComp>\n";
125  */
126 
127  if( m_Comp )
128  m_Comp->Show( 1, out );
129 
130  break;
131 
132  default:
133  // not all the m_Comp classes have working Show functions.
134  ;
135  }
136 
137 /* was segfault-ing
138  if( m_Comp )
139  m_Comp->Show( 1, out ); // labels may not have good Show() funcs?
140  else
141  out << " m_Comp==NULL\n";
142 */
143 
144  out << "</netItem>\n";
145 }
146 
147 #endif
148 
149 
151 {
152  m_Type = NETLIST_ITEM::ITEM_UNSPECIFIED; /* Type of this item (see NETLIST_ITEM_T enum) */
153  m_Comp = NULL; /* Pointer on the library item that created this net object
154  * (the parent)*/
155  m_Link = NULL; /* For SCH_SHEET_PIN:
156  * Pointer to the hierarchy sheet that contains this
157  * SCH_SHEET_PIN For Pins: pointer to the component that
158  * contains this pin
159  */
160  m_Flag = 0; /* flag used in calculations */
161  m_netCode = 0; /* net code for all items except BUS labels because a BUS
162  * label has as many net codes as bus members
163  */
164  m_BusNetCode = 0; /* Used for BUS connections */
165  m_Member = 0; /* for labels type NETLIST_ITEM::BUSLABELMEMBER ( bus member created
166  * from the BUS label ) member number
167  */
170  ELECTRICAL_PINTYPE::PT_INPUT; /* Has meaning only for Pins: electrical type of the pin
171  * used to detect conflicts between pins in ERC
172  */
173  m_netNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this
174  * object used to give a name to the net
175  */
176 }
177 
178 
179 // Copy constructor
181 {
182  *this = aSource;
183 }
184 
185 
187 {
188 }
189 
190 
191 // return true if the object is a label of any type
193 {
198 }
199 
201 {
202  if( aNetItem == this ) // Don't compare the same net list object.
203  return false;
204 
205  NETLIST_ITEM at = m_Type;
206  NETLIST_ITEM bt = aNetItem->m_Type;
207 
210  {
211  if( m_SheetPath == aNetItem->m_SheetPathInclude )
212  {
213  return true; //connected!
214  }
215  }
216  else if( ( at == NETLIST_ITEM::GLOBLABEL ) && ( bt == NETLIST_ITEM::GLOBLABEL ) )
217  {
218  if( m_Label == aNetItem->m_Label )
219  return true; //connected!
220  }
221 
222  return false; //these two are unconnected
223 }
224 
225 
227 {
228  SCH_CONNECTION conn;
229  wxCHECK_RET( conn.IsBusLabel( m_Label ),
230  wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );
231 
234  else if( m_Type == NETLIST_ITEM::GLOBLABEL )
236  else if( m_Type == NETLIST_ITEM::SHEETLABEL )
238  else if( m_Type == NETLIST_ITEM::LABEL )
240  else
241  wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
242 
243  // NOTE: all netlist objects generated from a single bus definition need to have different
244  // member codes set. For bus vectors, the member code matches the vector index, but for
245  // bus groups (including with nested vectors) the code is something arbitrary.
246  long member_offset = 0;
247 
248  auto alias = static_cast<SCH_ITEM*>( m_Comp )->Schematic()->GetBusAlias( m_Label );
249  wxString group_name;
250  bool self_set = false;
251  std::vector<wxString> bus_contents_vec;
252 
253  if( alias || NET_SETTINGS::ParseBusGroup( m_Label, &group_name, &bus_contents_vec ) )
254  {
255  if( alias )
256  {
257  for( const wxString& member : alias->Members() )
258  bus_contents_vec.emplace_back( member );
259  }
260 
261  // For named bus groups, like "USB{DP DM}"
262  wxString group_prefix = ( group_name != "" ) ? ( group_name + "." ) : "";
263 
264  std::list<wxString> bus_contents( bus_contents_vec.begin(), bus_contents_vec.end() );
265 
266  for( const auto& bus_member : bus_contents )
267  {
268  wxString prefix;
269  std::vector<wxString> members;
270 
271  // Nested bus vector inside a bus group
272  if( NET_SETTINGS::ParseBusVector( bus_member, &prefix, &members ) )
273  {
274  long begin, end;
275 
276  prefix = group_prefix + prefix;
277  begin = conn.VectorStart();
278  end = conn.VectorEnd();
279 
280  if( !self_set )
281  {
282  m_Label = members[0];
283  m_Member = ( begin++ ) + ( member_offset++ );
284 
285  self_set = true;
286  begin++;
287  }
288 
289  fillBusVector( aNetListItems, prefix, begin, end, member_offset );
290  member_offset += std::abs( end - begin );
291  }
292  else if( auto nested_alias = static_cast<SCH_ITEM*>( m_Comp )->Schematic()->GetBusAlias(
293  bus_member ) )
294  {
295  // Nested alias inside a group
296  for( const auto& alias_member : nested_alias->Members() )
297  {
298  bus_contents.push_back( alias_member );
299  }
300  }
301  else
302  {
303  if( !self_set )
304  {
305  m_Label = group_prefix + bus_member;
306  m_Member = member_offset++;
307  self_set = true;
308  }
309  else
310  {
311  auto item = new NETLIST_OBJECT( *this );
312  item->m_Label = group_prefix + bus_member;
313  item->m_Member = member_offset++;
314  aNetListItems.push_back( item );
315  }
316  }
317  }
318  }
319  else if( NET_SETTINGS::ParseBusVector( m_Label, &group_name, &bus_contents_vec ) )
320  {
321  long begin = conn.VectorStart();
322  long end = conn.VectorEnd();
323 
324  m_Label = bus_contents_vec[0];
325  m_Member = begin;
326 
327  fillBusVector( aNetListItems, group_name, begin + 1, end, 0 );
328  }
329 }
330 
332  wxString aName, long aBegin, long aEnd, long aOffset )
333 {
334  for( long member = aBegin; member <= aEnd; member++ )
335  {
336  auto item = new NETLIST_OBJECT( *this );
337 
338  item->m_Label = aName;
339  item->m_Label << member;
340  item->m_Member = member;
341 
342  aNetListItems.push_back( item );
343  }
344 }
345 
346 
348 {
349  // return true if the object is a global label
350  // * a actual global label
351  // * a pin label coming from a invisible power pin
354 }
355 
356 
358 {
359  // return true if the object is a bus label member build from a
360  // schematic bus label (like label[xx..yy)
361  // They are labels with very specific properties, especially for connection
362  // between them: 2 bus label members can be connected only
363  // if they have the same member value.
368 }
369 
370 
371 /*
372  * return the net name of the item
373  */
375 {
376  if( m_netNameCandidate == NULL )
377  return wxEmptyString;
378 
379  wxString netName;
380 
382  return GetShortNetName();
383 
385  {
386  // usual net name, prefix it by the sheet path
388  }
389 
390  netName += m_netNameCandidate->m_Label;
391 
392  return netName;
393 }
394 
401 {
402  if( m_netNameCandidate == NULL )
403  return wxEmptyString;
404 
405  wxString netName;
406 
408  {
410  if( link ) // Should be always true
411  {
412  netName = wxT("Net-(");
413  netName << link->GetRef( &m_netNameCandidate->m_SheetPath );
414  netName << wxT("-Pad") << m_netNameCandidate->m_PinNum << wxT(")");
415  }
416  }
417  else
418  netName = m_netNameCandidate->m_Label;
419 
420  return netName;
421 }
422 
432 {
433  switch( aCandidate->m_Type )
434  {
436  case NETLIST_ITEM::LABEL:
441  case NETLIST_ITEM::PIN:
442  m_netNameCandidate = aCandidate;
443  break;
444 
445  default:
446  break;
447  }
448 }
449 
450 
451 const wxString NETLIST_OBJECT::GetPinNameText() const
452 {
453  wxString name;
454  // returns the pin name, for NETLIST_ITEM::PIN (usual pin) item.
455  if( m_Type == NETLIST_ITEM::PIN )
456  {
457  name = static_cast<LIB_PIN*>( m_Comp )->GetName();
458 
459  if( name == "~" ) //empty name
460  name = wxEmptyString;
461  }
462 
463  return name;
464 }
void fillBusVector(NETLIST_OBJECT_LIST &aNetListItems, wxString aName, long aBegin, long aEnd, long aOffset)
Given a bus vector, append the appropriate members into the list If given something like "DATA",...
SCH_COMPONENT * GetComponentParent() const
For Pins (NET_PINS):
SCH_SHEET_PATH m_SheetPathInclude
NETLIST_OBJECT * m_netNameCandidate
static bool IsBusLabel(const wxString &aLabel)
Test if aLabel has a bus notation.
int GetNet() const
SCH_SHEET_PATH m_SheetPath
ELECTRICAL_PINTYPE m_ElectricalPinType
bool IsLabelType() const
Function IsLabelType.
EDA_ITEM * m_Comp
bool IsLabelBusMemberType() const
Function IsLabelBusMemberType.
This file contains miscellaneous commonly used macros and functions.
bool IsLabelGlobal() const
Function IsLabelGlobal.
NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected items in a...
static bool ParseBusGroup(wxString aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parses a bus group label into the name and a list of components.
const wxString GetPinNameText() const
returns the pin name, for NET_PIN (usual pin) item.
#define NULL
long VectorEnd() const
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
bool IsLabelConnected(NETLIST_OBJECT *aNetItem)
Function IsLabelConnected tests if the net list object is a hierarchical label or sheet label and is ...
const char * name
Definition: DXF_plotter.cpp:60
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
usual pin input: must be connected
wxString GetShortNetName() const
Function GetShortNetName.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parses a bus vector (e.g.
void SetNetNameCandidate(NETLIST_OBJECT *aCandidate)
Set m_netNameCandidate to a connected item which will be used to calcule the net name of the item Obv...
Schematic symbol object.
Definition: sch_component.h:88
#define TO_UTF8(wxstring)
long VectorStart() const
NETLIST_ITEM
wxString GetNetName() const
Function GetNetName.
NET_CONNECTION m_ConnectionType
wxString PathHumanReadable() const
Function PathHumanReadable returns the sheet path in a human readable form, i.e.
Definition of the NETLIST_OBJECT class.
NETLIST_ITEM m_Type
SCH_ITEM * m_Link
void ConvertBusToNetListItems(NETLIST_OBJECT_LIST &aNetListItems)
Function ConvertBusToNetListItems breaks the text of a bus label type net list object into as many me...