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 
41 #if defined(DEBUG)
42 
43 #include <iostream>
44 const char* ShowType( NETLIST_ITEM aType )
45 {
46  const char* ret;
47 
48  switch( aType )
49  {
51  ret = "segment"; break;
52 
53  case NETLIST_ITEM::BUS:
54  ret = "bus"; break;
55 
57  ret = "junction"; break;
58 
60  ret = "label"; break;
61 
63  ret = "hierlabel"; break;
64 
66  ret = "glabel"; break;
67 
69  ret = "buslblmember"; break;
70 
72  ret = "hierbuslblmember"; break;
73 
75  ret = "gbuslblmember"; break;
76 
78  ret = "sbuslblmember"; break;
79 
81  ret = "sheetlabel"; break;
82 
84  ret = "pinlabel"; break;
85 
86  case NETLIST_ITEM::PIN:
87  ret = "pin"; break;
88 
90  ret = "noconnect"; break;
91 
92  default:
93  ret = "??"; break;
94  }
95 
96  return ret;
97 }
98 
99 
100 void NETLIST_OBJECT::Show( std::ostream& out, int ndx ) const
101 {
102  wxString path = m_SheetPath.PathHumanReadable();
103 
104  out << "<netItem ndx=\"" << ndx << '"' <<
105  " type=\"" << ShowType( m_Type ) << '"' <<
106  " netCode=\"" << GetNet() << '"' <<
107  " sheet=\"" << TO_UTF8( path ) << '"' <<
108  ">\n";
109 
110  out << " <start " << m_Start << "/> <end " << m_End << "/>\n";
111 
112  if( !m_Label.IsEmpty() )
113  out << " <label>" << m_Label.mb_str() << "</label>\n";
114 
115  out << " <sheetpath>" << m_SheetPath.PathHumanReadable().mb_str() << "</sheetpath>\n";
116 
117  switch( m_Type )
118  {
119  case NETLIST_ITEM::PIN:
120  /* GetRef() needs to be const
121  out << " <refOfComp>" << GetComponentParent()->GetRef(&m_SheetPath).mb_str()
122  << "</refOfComp>\n";
123  */
124 
125  if( m_Comp )
126  m_Comp->Show( 1, out );
127 
128  break;
129 
130  default:
131  // not all the m_Comp classes have working Show functions.
132  ;
133  }
134 
135 /* was segfault-ing
136  if( m_Comp )
137  m_Comp->Show( 1, out ); // labels may not have good Show() funcs?
138  else
139  out << " m_Comp==NULL\n";
140 */
141 
142  out << "</netItem>\n";
143 }
144 
145 #endif
146 
147 
149 {
150  m_Type = NETLIST_ITEM::ITEM_UNSPECIFIED; /* Type of this item (see NETLIST_ITEM_T enum) */
151  m_Comp = NULL; /* Pointer on the library item that created this net object
152  * (the parent)*/
153  m_Link = NULL; /* For SCH_SHEET_PIN:
154  * Pointer to the hierarchy sheet that contains this
155  * SCH_SHEET_PIN For Pins: pointer to the component that
156  * contains this pin
157  */
158  m_Flag = 0; /* flag used in calculations */
159  m_netCode = 0; /* net code for all items except BUS labels because a BUS
160  * label has as many net codes as bus members
161  */
162  m_BusNetCode = 0; /* Used for BUS connections */
163  m_Member = 0; /* for labels type NETLIST_ITEM::BUSLABELMEMBER ( bus member created
164  * from the BUS label ) member number
165  */
168  ELECTRICAL_PINTYPE::PT_INPUT; /* Has meaning only for Pins: electrical type of the pin
169  * used to detect conflicts between pins in ERC
170  */
171  m_netNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this
172  * object used to give a name to the net
173  */
174 }
175 
176 
177 // Copy constructor
179 {
180  *this = aSource;
181 }
182 
183 
185 {
186 }
187 
188 
189 // return true if the object is a label of any type
191 {
196 }
197 
199 {
200  if( aNetItem == this ) // Don't compare the same net list object.
201  return false;
202 
203  NETLIST_ITEM at = m_Type;
204  NETLIST_ITEM bt = aNetItem->m_Type;
205 
208  {
209  if( m_SheetPath == aNetItem->m_SheetPathInclude )
210  {
211  return true; //connected!
212  }
213  }
214  else if( ( at == NETLIST_ITEM::GLOBLABEL ) && ( bt == NETLIST_ITEM::GLOBLABEL ) )
215  {
216  if( m_Label == aNetItem->m_Label )
217  return true; //connected!
218  }
219 
220  return false; //these two are unconnected
221 }
222 
223 
225 {
226  SCH_CONNECTION conn;
227  wxCHECK_RET( conn.IsBusLabel( m_Label ),
228  wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );
229 
232  else if( m_Type == NETLIST_ITEM::GLOBLABEL )
234  else if( m_Type == NETLIST_ITEM::SHEETLABEL )
236  else if( m_Type == NETLIST_ITEM::LABEL )
238  else
239  wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
240 
241  // NOTE: all netlist objects generated from a single bus definition need to have different
242  // member codes set. For bus vectors, the member code matches the vector index, but for
243  // bus groups (including with nested vectors) the code is something arbitrary.
244  long member_offset = 0;
245 
246  auto alias = static_cast<SCH_ITEM*>( m_Comp )->Schematic()->GetBusAlias( m_Label );
247  wxString group_name;
248  bool self_set = false;
249  std::vector<wxString> bus_contents_vec;
250 
251  if( alias || SCH_CONNECTION::ParseBusGroup( m_Label, &group_name, &bus_contents_vec ) )
252  {
253  if( alias )
254  {
255  for( const wxString& member : alias->Members() )
256  bus_contents_vec.emplace_back( member );
257  }
258 
259  // For named bus groups, like "USB{DP DM}"
260  wxString group_prefix = ( group_name != "" ) ? ( group_name + "." ) : "";
261 
262  std::list<wxString> bus_contents( bus_contents_vec.begin(), bus_contents_vec.end() );
263 
264  for( const auto& bus_member : bus_contents )
265  {
266  wxString prefix;
267  std::vector<wxString> members;
268 
269  // Nested bus vector inside a bus group
270  if( SCH_CONNECTION::ParseBusVector( bus_member, &prefix, &members ) )
271  {
272  long begin, end;
273 
274  prefix = group_prefix + prefix;
275  begin = conn.VectorStart();
276  end = conn.VectorEnd();
277 
278  if( !self_set )
279  {
280  m_Label = members[0];
281  m_Member = ( begin++ ) + ( member_offset++ );
282 
283  self_set = true;
284  begin++;
285  }
286 
287  fillBusVector( aNetListItems, prefix, begin, end, member_offset );
288  member_offset += std::abs( end - begin );
289  }
290  else if( auto nested_alias = static_cast<SCH_ITEM*>( m_Comp )->Schematic()->GetBusAlias(
291  bus_member ) )
292  {
293  // Nested alias inside a group
294  for( const auto& alias_member : nested_alias->Members() )
295  {
296  bus_contents.push_back( alias_member );
297  }
298  }
299  else
300  {
301  if( !self_set )
302  {
303  m_Label = group_prefix + bus_member;
304  m_Member = member_offset++;
305  self_set = true;
306  }
307  else
308  {
309  auto item = new NETLIST_OBJECT( *this );
310  item->m_Label = group_prefix + bus_member;
311  item->m_Member = member_offset++;
312  aNetListItems.push_back( item );
313  }
314  }
315  }
316  }
317  else if( SCH_CONNECTION::ParseBusVector( m_Label, &group_name, &bus_contents_vec ) )
318  {
319  long begin = conn.VectorStart();
320  long end = conn.VectorEnd();
321 
322  m_Label = bus_contents_vec[0];
323  m_Member = begin;
324 
325  fillBusVector( aNetListItems, group_name, begin + 1, end, 0 );
326  }
327 }
328 
330  wxString aName, long aBegin, long aEnd, long aOffset )
331 {
332  for( long member = aBegin; member <= aEnd; member++ )
333  {
334  auto item = new NETLIST_OBJECT( *this );
335 
336  item->m_Label = aName;
337  item->m_Label << member;
338  item->m_Member = member;
339 
340  aNetListItems.push_back( item );
341  }
342 }
343 
344 
346 {
347  // return true if the object is a global label
348  // * a actual global label
349  // * a pin label coming from a invisible power pin
352 }
353 
354 
356 {
357  // return true if the object is a bus label member build from a
358  // schematic bus label (like label[xx..yy)
359  // They are labels with very specific properties, especially for connection
360  // between them: 2 bus label members can be connected only
361  // if they have the same member value.
366 }
367 
368 
369 /*
370  * return the net name of the item
371  */
373 {
374  if( m_netNameCandidate == NULL )
375  return wxEmptyString;
376 
377  wxString netName;
378 
380  return GetShortNetName();
381 
383  {
384  // usual net name, prefix it by the sheet path
386  }
387 
388  netName += m_netNameCandidate->m_Label;
389 
390  return netName;
391 }
392 
399 {
400  if( m_netNameCandidate == NULL )
401  return wxEmptyString;
402 
403  wxString netName;
404 
406  {
408  if( link ) // Should be always true
409  {
410  netName = wxT("Net-(");
411  netName << link->GetRef( &m_netNameCandidate->m_SheetPath );
412  netName << wxT("-Pad") << m_netNameCandidate->m_PinNum << wxT(")");
413  }
414  }
415  else
416  netName = m_netNameCandidate->m_Label;
417 
418  return netName;
419 }
420 
430 {
431  switch( aCandidate->m_Type )
432  {
434  case NETLIST_ITEM::LABEL:
439  case NETLIST_ITEM::PIN:
440  m_netNameCandidate = aCandidate;
441  break;
442 
443  default:
444  break;
445  }
446 }
447 
448 
449 const wxString NETLIST_OBJECT::GetPinNameText() const
450 {
451  wxString name;
452  // returns the pin name, for NETLIST_ITEM::PIN (usual pin) item.
453  if( m_Type == NETLIST_ITEM::PIN )
454  {
455  name = static_cast<LIB_PIN*>( m_Comp )->GetName();
456 
457  if( name == "~" ) //empty name
458  name = wxEmptyString;
459  }
460 
461  return name;
462 }
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 ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parses a bus vector (e.g.
const wxString GetPinNameText() const
returns the pin name, for NET_PIN (usual pin) item.
static bool ParseBusGroup(wxString aGroup, wxString *name, std::vector< wxString > *aMemberList)
Parses a bus group label into the name and a list of components.
#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.
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...