526 lines
19 KiB
C++
526 lines
19 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
|
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you may find one here:
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
/**
|
|
* @file netlist_object.h
|
|
* @brief Definition of the NETLIST_OBJECT class.
|
|
*/
|
|
|
|
#ifndef NETLIST_OBJECT_H
|
|
#define NETLIST_OBJECT_H
|
|
|
|
|
|
#include <sch_sheet_path.h>
|
|
#include <lib_pin.h>
|
|
#include <sch_item.h>
|
|
|
|
class NETLIST_OBJECT_LIST;
|
|
class SCH_COMPONENT;
|
|
|
|
|
|
/* Type of Net objects (wires, labels, pins...) */
|
|
enum NETLIST_ITEM_T
|
|
{
|
|
NET_ITEM_UNSPECIFIED, // only for not yet initialized instances
|
|
NET_SEGMENT, // connection by wire
|
|
NET_BUS, // connection by bus
|
|
NET_JUNCTION, // connection by junction: can connect to
|
|
// or more crossing wires
|
|
NET_LABEL, // this is a local label
|
|
NET_GLOBLABEL, // this is a global label that connect all
|
|
// others global label in whole hierarchy
|
|
NET_HIERLABEL, // element to indicate connection to a
|
|
// higher-level sheet
|
|
NET_SHEETLABEL, // element to indicate connection to a
|
|
// lower-level sheet.
|
|
NET_BUSLABELMEMBER, /* created when a bus label is found:
|
|
* the bus label (like DATA[0..7] is
|
|
* converted to n single labels like
|
|
* DATA0, DATA1 ...
|
|
* These objects are living only in the current
|
|
* NETLIST_OBJECT_LIST, not in shematic.
|
|
*/
|
|
NET_GLOBBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
|
|
// global bus label is found
|
|
NET_HIERBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
|
|
// hierarchical bus label is found
|
|
NET_SHEETBUSLABELMEMBER, // see NET_BUSLABELMEMBER, used when a
|
|
// pin sheet label using bus notation
|
|
// is found
|
|
NET_PINLABEL, /* created when a pin is POWER (IN or
|
|
* OUT) with invisible attribute is found:
|
|
* these pins are equivalent to a global
|
|
* label and are automatically connected
|
|
*/
|
|
NET_PIN, // this is an usual pin
|
|
NET_NOCONNECT // this is a no connect symbol
|
|
};
|
|
|
|
|
|
/* Values for .m_FlagOfConnection member */
|
|
enum NET_CONNECTION_T
|
|
{
|
|
UNCONNECTED = 0, /* Pin or Label not connected (error) */
|
|
NOCONNECT_SYMBOL_PRESENT, /* Pin not connected but have a NoConnect
|
|
* symbol on it (no error) */
|
|
PAD_CONNECT /* Normal connection (no error) */
|
|
};
|
|
|
|
|
|
class NETLIST_OBJECT
|
|
{
|
|
public:
|
|
NETLIST_ITEM_T m_Type; /* Type of item (see NETLIST_ITEM_T enum) */
|
|
EDA_ITEM* m_Comp; /* Pointer to the library item that
|
|
* created this net object (the parent)
|
|
*/
|
|
SCH_ITEM* m_Link; /* For SCH_SHEET_PIN:
|
|
* Pointer to the hierarchy sheet that
|
|
* contains this SCH_SHEET_PIN
|
|
* For Pins: pointer to the schematic component
|
|
* that contains this pin
|
|
*/
|
|
int m_Flag; /* flag used in calculations */
|
|
SCH_SHEET_PATH m_SheetPath; // the sheet path which contains this item
|
|
SCH_SHEET_PATH m_SheetPathInclude; // sheet path which contains the hierarchical label
|
|
ELECTRICAL_PINTYPE m_ElectricalPinType; // Has meaning only for Pins: electrical type of the pin
|
|
int m_BusNetCode; /* Used for BUS connections */
|
|
int m_Member; /* for labels type NET_BUSLABELMEMBER ( bus member
|
|
* created from the BUS label ) member number.
|
|
*/
|
|
NET_CONNECTION_T m_ConnectionType; // Used to store the connection type
|
|
wxString m_PinNum; // pin number
|
|
wxString m_Label; // Label text (for labels) or Pin name (for pins)
|
|
wxPoint m_Start; // Position of object or for segments: starting point
|
|
wxPoint m_End; // For segments (wire and buses): ending point
|
|
|
|
private:
|
|
int m_netCode; /* net code for all items except BUS
|
|
* labels because a BUS label has
|
|
* as many net codes as bus members
|
|
*/
|
|
NETLIST_OBJECT* m_netNameCandidate; /* a pointer to a label connected to the net,
|
|
* that can be used to give a name to the net
|
|
* or a pin if there is no label in net
|
|
* When no label, the pin is used to build
|
|
* default net name.
|
|
*/
|
|
|
|
public:
|
|
|
|
#if defined(DEBUG)
|
|
void Show( std::ostream& out, int ndx ) const;
|
|
|
|
#endif
|
|
|
|
NETLIST_OBJECT();
|
|
NETLIST_OBJECT( NETLIST_OBJECT& aSource ); // Copy constructor
|
|
|
|
~NETLIST_OBJECT();
|
|
|
|
// Accessors:
|
|
void SetNet( int aNetCode ) { m_netCode = aNetCode; }
|
|
int GetNet() const { return m_netCode; }
|
|
|
|
/**
|
|
* Set the item connection type:
|
|
* UNCONNECTED Pin or Label not connected (error)
|
|
* NOCONNECT_SYMBOL_PRESENT Pin not connected but have a NoConnect
|
|
* symbol on it (no error)
|
|
* PAD_CONNECT Normal connection (no error)
|
|
*/
|
|
void SetConnectionType( NET_CONNECTION_T aFlg = UNCONNECTED )
|
|
{
|
|
m_ConnectionType = aFlg;
|
|
}
|
|
|
|
NET_CONNECTION_T GetConnectionType() const
|
|
{
|
|
return m_ConnectionType;
|
|
}
|
|
|
|
/**
|
|
* Set m_netNameCandidate to a connected item which will
|
|
* be used to calcule the net name of the item
|
|
* Obviously the candidate can be only a label
|
|
* when there is no label on the net a pad which will
|
|
* used to build a net name (something like Cmp<REF>_Pad<PAD_NAME>
|
|
* @param aCandidate = the connected item candidate
|
|
*/
|
|
void SetNetNameCandidate( NETLIST_OBJECT* aCandidate );
|
|
|
|
/**
|
|
* @return true if an item has already a net name candidate
|
|
* and false if not ( m_netNameCandidate == NULL )
|
|
*/
|
|
bool HasNetNameCandidate() { return m_netNameCandidate != NULL; }
|
|
|
|
/**
|
|
* returns a pin number in wxString form. Pin numbers are not always
|
|
* numbers. \"A23\" would be a valid pin number.
|
|
*/
|
|
const wxString& GetPinNumText() const
|
|
{
|
|
return m_PinNum;
|
|
}
|
|
|
|
/**
|
|
* returns the pin name, for NET_PIN (usual pin) item.
|
|
*/
|
|
const wxString GetPinNameText() const;
|
|
|
|
/** For Pins (NET_PINS):
|
|
* @return the schematic component which contains this pin
|
|
* (Note: this is the schematic component, not the library component
|
|
* for others items: return NULL
|
|
*/
|
|
SCH_COMPONENT* GetComponentParent() const
|
|
{
|
|
if( m_Link && m_Link->Type() == SCH_COMPONENT_T )
|
|
return (SCH_COMPONENT*) m_Link;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Function IsLabelConnected
|
|
* tests if the net list object is a hierarchical label or sheet label and is
|
|
* connected to an associated hierarchical label or sheet label of \a aNetItem.
|
|
*
|
|
* @param aNetItem A pointer to a NETLIST_OBJECT to test against.
|
|
* @return A bool value of true if there is a connection with \a aNetItem or false
|
|
* if no connection to \a aNetItem.
|
|
*/
|
|
bool IsLabelConnected( NETLIST_OBJECT* aNetItem );
|
|
|
|
/**
|
|
* Function IsLabelGlobal
|
|
* @return true if the object is a global label
|
|
* (i.e. an real global label or a pin label coming
|
|
* from a power pin invisible
|
|
*/
|
|
bool IsLabelGlobal() const;
|
|
|
|
/**
|
|
* Function IsLabelBusMemberType
|
|
* @return true if the object is a bus label member build from a
|
|
* schematic bus label (like label[xx..yy], xx and yy are the first and last
|
|
* bus member id)
|
|
* bus label members have specific properties:
|
|
* they do not live in schematic
|
|
* they have specific properties in connections:
|
|
* 2 bus label members can be connected connected only if they have the same member value.
|
|
*/
|
|
bool IsLabelBusMemberType() const;
|
|
|
|
/**
|
|
* Function IsLabelType
|
|
* @return true if the object is a label of any type
|
|
*/
|
|
bool IsLabelType() const;
|
|
|
|
/**
|
|
* Function GetNetName
|
|
* @param adoptTimestamp if annotation is not done (i.e. GetRef returns something with an ? at the end)
|
|
* @return the full net name of the item, i.e. the net name
|
|
* from the "best" label, prefixed by the sheet path
|
|
*/
|
|
wxString GetNetName( bool adoptTimestamp = false ) const;
|
|
|
|
/**
|
|
* Function GetShortNetName
|
|
* @param adoptTimestamp if annotation is not done (i.e. GetRef returns something with an ? at the end)
|
|
* @return the short net name of the item i.e. the net name
|
|
* from the "best" label without any prefix.
|
|
* 2 different nets can have the same short name
|
|
*/
|
|
wxString GetShortNetName( bool adoptTimestamp = false ) const;
|
|
|
|
/**
|
|
* Function ConvertBusToNetListItems
|
|
* breaks the text of a bus label type net list object into as many members as
|
|
* it contains and creates a #NETLIST_OBJECT for each label and adds it to \a
|
|
* aNetListItems.
|
|
*
|
|
* @param aNetListItems A reference to vector of #NETLIST_OBJECT pointers to add
|
|
* the bus label NETLIST_OBJECTs.
|
|
*/
|
|
void ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems );
|
|
|
|
private:
|
|
/**
|
|
* Given a bus vector, append the appropriate members into the list
|
|
* If given something like "DATA", 7, 0, will append "DATA7", "DATA6", etc.
|
|
*
|
|
* @param aNetListItems is the list to append to
|
|
* @param aName is the prefix for the vector, like "DATA"
|
|
* @param aBegin is the first entry in the vector
|
|
* @param aEnd is the last entry in the vector
|
|
* @param aOffset is an offset to add to the member code for each member
|
|
*/
|
|
void fillBusVector( NETLIST_OBJECT_LIST& aNetListItems, wxString aName,
|
|
long aBegin, long aEnd, long aOffset );
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Type NETLIST_OBJECTS
|
|
* is a container referring to (not owning) NETLIST_OBJECTs, which are connected items
|
|
* in a full schematic hierarchy. It is useful when referring to NETLIST_OBJECTs
|
|
* actually owned by some other container.
|
|
*/
|
|
typedef std::vector<NETLIST_OBJECT*> NETLIST_OBJECTS;
|
|
|
|
|
|
/**
|
|
* NETLIST_OBJECT_LIST
|
|
* is a container holding and _owning_ NETLIST_OBJECTs, which are connected items
|
|
* in a full schematic hierarchy. It is helpful for netlist and ERC calculations.
|
|
*/
|
|
class NETLIST_OBJECT_LIST : public NETLIST_OBJECTS
|
|
{
|
|
int m_lastNetCode; // Used in intermediate calculation: last net code created
|
|
int m_lastBusNetCode; // Used in intermediate calculation:
|
|
// last net code created for bus members
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
* NETLIST_OBJECT_LIST handle a list of connected items.
|
|
* these NETLIST_OBJECT items are freeed by the destructor
|
|
*/
|
|
NETLIST_OBJECT_LIST()
|
|
{
|
|
// Do not leave some members uninitialized:
|
|
m_lastNetCode = 0;
|
|
m_lastBusNetCode = 0;
|
|
}
|
|
|
|
~NETLIST_OBJECT_LIST();
|
|
|
|
/**
|
|
* Function BuildNetListInfo
|
|
* the master function of tgis class.
|
|
* Build the list of connected objects (pins, labels ...) and
|
|
* all info to generate netlists or run ERC diags
|
|
* @param aSheets = the flattened sheet list
|
|
* @return true if OK, false is not item found
|
|
*/
|
|
bool BuildNetListInfo( SCH_SHEET_LIST& aSheets );
|
|
|
|
/**
|
|
* Acces to an item in list
|
|
*/
|
|
NETLIST_OBJECT* GetItem( unsigned aIdx ) const
|
|
{
|
|
return *( this->begin() + aIdx );
|
|
}
|
|
|
|
/**
|
|
* Acces to an item type
|
|
*/
|
|
NETLIST_ITEM_T GetItemType( unsigned aIdx ) const
|
|
{
|
|
return GetItem( aIdx )->m_Type;
|
|
}
|
|
|
|
/**
|
|
* Acces to an item net code
|
|
*/
|
|
int GetItemNet( unsigned aIdx ) const
|
|
{
|
|
return GetItem( aIdx )->GetNet();
|
|
}
|
|
|
|
NET_CONNECTION_T GetConnectionType( unsigned aIdx )
|
|
{
|
|
return GetItem( aIdx )->GetConnectionType();
|
|
}
|
|
|
|
/**
|
|
* Set the item connection type:
|
|
* UNCONNECTED Pin or Label not connected (error)
|
|
* NOCONNECT_SYMBOL_PRESENT Pin not connected but have a NoConnect
|
|
* symbol on it (no error)
|
|
* PAD_CONNECT Normal connection (no error)
|
|
*/
|
|
void SetConnectionType( unsigned aIdx, NET_CONNECTION_T aFlg = UNCONNECTED )
|
|
{
|
|
GetItem( aIdx )->SetConnectionType( aFlg );
|
|
}
|
|
|
|
/** Delete all objects in list and clear list */
|
|
void Clear();
|
|
|
|
/**
|
|
* Reset the connection type of all items to UNCONNECTED type
|
|
*/
|
|
void ResetConnectionsType()
|
|
{
|
|
for( unsigned ii = 0; ii < size(); ii++ )
|
|
GetItem( ii )->SetConnectionType( UNCONNECTED );
|
|
}
|
|
|
|
/*
|
|
* Sorts the list of connected items by net code
|
|
*/
|
|
void SortListbyNetcode();
|
|
|
|
/*
|
|
* Sorts the list of connected items by sheet.
|
|
* This sorting is used when searching "physical" connection between items
|
|
* because obviously only items inside the same sheet can be connected
|
|
*/
|
|
void SortListbySheet();
|
|
|
|
/**
|
|
* Counts number of pins connected on the same net.
|
|
* Used to count all pins connected to a no connect symbol
|
|
* @return the pin count of the net starting at aNetStart
|
|
* @param aNetStart = index in list of net objects of the first item
|
|
*/
|
|
int CountPinsInNet( unsigned aNetStart );
|
|
|
|
/**
|
|
* Function TestforNonOrphanLabel
|
|
* Sheet labels are expected to be connected to a hierarchical label.
|
|
* Hierarchical labels are expected to be connected to a sheet label.
|
|
* Global labels are expected to be not orphan (connected to at least one
|
|
* other global label.
|
|
* This function tests the connection to another suitable label.
|
|
*/
|
|
void TestforNonOrphanLabel( unsigned aNetItemRef, unsigned aStartNet );
|
|
|
|
/**
|
|
* Function TestforSimilarLabels
|
|
* detects labels which are different when using case sensitive comparisons
|
|
* but are equal when using case insensitive comparisons
|
|
* It can be due to a mistake from designer, so this kind of labels
|
|
* is reported by TestforSimilarLabels
|
|
*/
|
|
void TestforSimilarLabels();
|
|
|
|
#if defined(DEBUG)
|
|
void DumpNetTable()
|
|
{
|
|
for( unsigned idx = 0; idx < size(); ++idx )
|
|
{
|
|
GetItem( idx )->Show( std::cout, idx );
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
private:
|
|
/*
|
|
* Propagate aNewNetCode to items having an internal netcode aOldNetCode
|
|
* used to interconnect group of items already physically connected,
|
|
* when a new connection is found between aOldNetCode and aNewNetCode
|
|
*/
|
|
void propagateNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus );
|
|
|
|
/*
|
|
* This function merges the net codes of groups of objects already connected
|
|
* to labels (wires, bus, pins ... ) when 2 labels are equivalents
|
|
* (i.e. group objects connected by labels)
|
|
*/
|
|
void labelConnect( NETLIST_OBJECT* aLabelRef );
|
|
|
|
/* Comparison function to sort by increasing Netcode the list of connected items
|
|
*/
|
|
static bool sortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
|
|
{
|
|
return Objet1->GetNet() < Objet2->GetNet();
|
|
}
|
|
|
|
/* Comparison routine to sort items by Sheet path
|
|
*/
|
|
static bool sortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
|
|
{
|
|
return Objet1->m_SheetPath.Cmp( Objet2->m_SheetPath ) < 0;
|
|
}
|
|
|
|
/**
|
|
* Propagate net codes from a parent sheet to an include sheet,
|
|
* from a pin sheet connection
|
|
*/
|
|
void sheetLabelConnect( NETLIST_OBJECT* aSheetLabel );
|
|
|
|
void pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus, int start );
|
|
|
|
/**
|
|
* Search connections between a junction and segments
|
|
* Propagate the junction net code to objects connected by this junction.
|
|
* The junction must have a valid net code
|
|
* The list of objects is expected sorted by sheets.
|
|
* Search is done from index aIdxStart to the last element of list
|
|
*/
|
|
void segmentToPointConnect( NETLIST_OBJECT* aJonction, bool aIsBus, int aIdxStart );
|
|
|
|
|
|
/**
|
|
* Function connectBusLabels
|
|
* Propagate the net code (and create it, if not yet existing) between
|
|
* all bus label member objects connected by they name.
|
|
* Search is done in the entire list
|
|
*/
|
|
void connectBusLabels();
|
|
|
|
/**
|
|
* Set the m_FlagOfConnection member of items in list
|
|
* depending on the connection type:
|
|
* UNCONNECTED, PAD_CONNECT or NOCONNECT_SYMBOL_PRESENT
|
|
* The list is expected sorted by order of net code,
|
|
* i.e. items having the same net code are grouped
|
|
*/
|
|
void setUnconnectedFlag();
|
|
|
|
/**
|
|
* Function findBestNetNameForEachNet
|
|
* fill the .m_NetNameCandidate member of each item of aNetItemBuffer
|
|
* with a reference to the "best" NETLIST_OBJECT usable to give a name to the net
|
|
* If no suitable object found, .m_NetNameCandidate is filled with 0.
|
|
* The "best" NETLIST_OBJECT is a NETLIST_OBJECT that have the type label
|
|
* and by priority order:
|
|
* the label is global or local
|
|
* the label is in the first sheet in a hierarchy (the root sheet has the most priority)
|
|
* alphabetic order.
|
|
*/
|
|
void findBestNetNameForEachNet();
|
|
};
|
|
|
|
|
|
/**
|
|
* Function IsBusLabel
|
|
* test if \a aLabel has a bus notation.
|
|
*
|
|
* @param aLabel A wxString object containing the label to test.
|
|
* @return true if text is a bus notation format otherwise false is returned.
|
|
*/
|
|
extern bool IsBusLabel( const wxString& aLabel );
|
|
|
|
#endif // NETLIST_OBJECT_H
|