++eeschema:

In netlist generation, changed the rule to calculate netnames of nets with labels:
    Previously, named nets (i.e. nets with local, hierarchical or global labels) have their name
    defined by the first label found in list.
    So net names could be changed without really changing the schematic.
    Now the names are calculated from the rules (by priority order) :
    1 - use the most top level labels in hierarchies.
    2 - use global labels first, local labels next (hidden power pins names are global labels).
    3 - use alphabetic sort (so, if GND and AGND are connected, the net will be always named AGND,
    and adding a VSS connection cannot change the net name)
    So power nets and nets that have more than one label cannot have their netname changed
    if there is no actual change relative to these nets names in schematic
This commit is contained in:
jean-pierre charras 2010-06-23 19:00:12 +02:00
parent ab056f3ed6
commit 3543ba65de
6 changed files with 211 additions and 97 deletions

View File

@ -4,6 +4,22 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-jun-23, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++eeschema:
In netlist generation, changed the rule to calculate netnames of nets with labels:
Previously, named nets (i.e. nets with local, hierarchical or global labels) have their name
defined by the first label found in list.
So net names could be changed without really changing the schematic.
Now the names are calculated from the rules (by priority order) :
1 - use the most top level labels in hierarchies.
2 - use global labels first, local labels next (hidden power pins names are global labels).
3 - use alphabetic sort (so, if GND and AGND are connected, the net will be always named AGND,
and adding a VSS connection cannot change the net name)
So power nets and nets that have more than one label cannot have their netname changed
if there is no actual change relative to these nets names in schematic
2010-Jun-17 UPDATE Dick Hollenbeck <dick@softplc.com> 2010-Jun-17 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++eeschema: ++eeschema:

View File

@ -1,4 +1,4 @@
update=12/06/2010 08:55:18 update=23/06/2010 18:43:01
last_client=pcbnew last_client=pcbnew
[general] [general]
version=1 version=1
@ -17,8 +17,8 @@ NetDir=
[pcbnew] [pcbnew]
version=1 version=1
PadDrlX=320 PadDrlX=320
PadDimH=700 PadDimH=620
PadDimV=700 PadDimV=1100
BoardThickness=630 BoardThickness=630
SgPcb45=1 SgPcb45=1
TxtPcbV=800 TxtPcbV=800

View File

@ -100,10 +100,10 @@ NETLIST_OBJECT::NETLIST_OBJECT()
{ {
m_Type = NET_ITEM_UNSPECIFIED; /* Type of this item (see NetObjetType enum) */ m_Type = NET_ITEM_UNSPECIFIED; /* Type of this item (see NetObjetType enum) */
m_Comp = NULL; /* Pointer on the library item that created this net object (the parent)*/ m_Comp = NULL; /* Pointer on the library item that created this net object (the parent)*/
m_Link = NULL; /* For SCH_SHEET_PIN: m_Link = NULL; /* For SCH_SHEET_PIN:
* Pointer to the hierarchy sheet that contains this SCH_SHEET_PIN * Pointer to the hierarchy sheet that contains this SCH_SHEET_PIN
* For Pins: pointer to the component that contains this pin * For Pins: pointer to the component that contains this pin
*/ */
m_Flag = 0; /* flag used in calculations */ m_Flag = 0; /* flag used in calculations */
m_ElectricalType = 0; /* Has meaning only for Pins and hierachical pins: electrical type */ m_ElectricalType = 0; /* Has meaning only for Pins and hierachical pins: electrical type */
m_NetCode = 0; /* net code for all items except BUS labels because a BUS label has m_NetCode = 0; /* net code for all items except BUS labels because a BUS label has
@ -116,16 +116,21 @@ NETLIST_OBJECT::NETLIST_OBJECT()
m_FlagOfConnection = UNCONNECTED; m_FlagOfConnection = UNCONNECTED;
m_PinNum = 0; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */ m_PinNum = 0; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */
m_Label = 0; /* For all labels:pointer on the text label */ m_Label = 0; /* For all labels:pointer on the text label */
m_NetNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this object
* used to give a name to the net
*/
} }
// Copy constructor // Copy constructor
NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource ) NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource )
{ {
*this = aSource; *this = aSource;
m_Label = NULL; // set to null because some items are owner, so the delete operator can create problems m_Label = NULL; // set to null because some items are owner, so the delete operator can create problems
// if this member is copied here (if 2 different items are owner of the same object) // if this member is copied here (if 2 different items are owner of the same object)
} }
NETLIST_OBJECT::~NETLIST_OBJECT() NETLIST_OBJECT::~NETLIST_OBJECT()
{ {
/* NETLIST_OBJECT is owner of m_Label only if its type is /* NETLIST_OBJECT is owner of m_Label only if its type is

View File

@ -64,18 +64,18 @@ public:
* For Pins: pointer to the component * For Pins: pointer to the component
* that contains this pin * that contains this pin
*/ */
int m_Flag; /* flag used in calculations */ int m_Flag; /* flag used in calculations */
SCH_SHEET_PATH m_SheetList; SCH_SHEET_PATH m_SheetList;
int m_ElectricalType; /* Has meaning only for Pins and int m_ElectricalType; /* Has meaning only for Pins and
* hierarchical pins: electrical type */ * hierarchical pins: electrical type */
private: private:
int m_NetCode; /* net code for all items except BUS int m_NetCode; /* net code for all items except BUS
* labels because a BUS label has * labels because a BUS label has
* as many net codes as bus members * as many net codes as bus members
*/ */
public: public:
int m_BusNetCode; /* Used for BUS connections */ int m_BusNetCode; /* Used for BUS connections */
int m_Member; /* for labels type NET_BUSLABELMEMBER int m_Member; /* for labels type NET_BUSLABELMEMBER
* ( bus member created from the BUS * ( bus member created from the BUS
* label ) member number * label ) member number
*/ */
@ -90,6 +90,10 @@ public:
// starting point // starting point
wxPoint m_End; // For segments (wire and buses): wxPoint m_End; // For segments (wire and buses):
// ending point // ending point
NETLIST_OBJECT* m_NetNameCandidate; /* a pointer to a label connected to the net,
* that can be used to give a name to the net
* NULL if no usable label
*/
#if defined(DEBUG) #if defined(DEBUG)
void Show( std::ostream& out, int ndx ); void Show( std::ostream& out, int ndx );

View File

@ -212,43 +212,29 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin,
wxString NetName; wxString NetName;
if( (netcode == 0 ) || ( Pin->m_FlagOfConnection != PAD_CONNECT ) ) if( (netcode == 0 ) || ( Pin->m_FlagOfConnection != PAD_CONNECT ) )
{
return NetName; return NetName;
NETLIST_OBJECT* netref = Pin->m_NetNameCandidate;
if( netref )
NetName = *netref->m_Label;
if( !NetName.IsEmpty() )
{
// prefix non global labels names by the sheet path, to avoid names collisions
if( netref->m_Type != NET_PINLABEL )
{
wxString lnet = NetName;
NetName = netref->m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name instead
if( NetName.Length() > 32 )
NetName = netref->m_SheetList.Path();
NetName += lnet;
}
} }
else else
{ NetName.Printf( DefaultFormatNetname.GetData(), netcode );
unsigned jj;
for( jj = 0; jj < g_NetObjectslist.size(); jj++ )
{
if( g_NetObjectslist[jj]->GetNet() != netcode )
continue;
if( ( g_NetObjectslist[jj]->m_Type != NET_HIERLABEL)
&& ( g_NetObjectslist[jj]->m_Type != NET_LABEL)
&& ( g_NetObjectslist[jj]->m_Type != NET_PINLABEL) )
continue;
NetName = *g_NetObjectslist[jj]->m_Label;
break;
}
if( !NetName.IsEmpty() )
{
if( g_NetObjectslist[jj]->m_Type != NET_PINLABEL )
{
wxString lnet = NetName;
NetName = g_NetObjectslist[jj]->m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name instead
if( NetName.Length() > 32 )
NetName = g_NetObjectslist[jj]->m_SheetList.Path();
NetName += lnet;
}
}
else
{
NetName.Printf( DefaultFormatNetname.GetData(), netcode );
}
}
return NetName; return NetName;
} }
@ -890,31 +876,22 @@ static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{ {
SameNetcodeCount = 0; // Items count for this net SameNetcodeCount = 0; // Items count for this net
NetName.Empty(); NetName.Empty();
unsigned jj;
// Find a label (if exists) for this net. // Find a label (if exists) for this net.
for( jj = 0; jj < aObjectsList.size(); jj++ ) NETLIST_OBJECT* netref;
{ netref = aObjectsList[ii]->m_NetNameCandidate;
if( aObjectsList[jj]->GetNet() != NetCode ) if( netref )
continue; NetName = *netref->m_Label;
if( ( aObjectsList[jj]->m_Type != NET_HIERLABEL)
&& ( aObjectsList[jj]->m_Type != NET_LABEL)
&& ( aObjectsList[jj]->m_Type != NET_PINLABEL) )
continue;
NetName = *aObjectsList[jj]->m_Label;
break;
}
NetcodeName.Printf( wxT( "Net %d " ), NetCode ); NetcodeName.Printf( wxT( "Net %d " ), NetCode );
NetcodeName += wxT( "\"" ); NetcodeName += wxT( "\"" );
if( !NetName.IsEmpty() ) if( !NetName.IsEmpty() )
{ {
if( aObjectsList[jj]->m_Type != NET_PINLABEL ) if( netref->m_Type != NET_PINLABEL )
{ {
// usual net name, prefix it by the sheet path // usual net name, prefix it by the sheet path
NetcodeName += NetcodeName +=
aObjectsList[jj]->m_SheetList.PathHumanReadable(); netref->m_SheetList.PathHumanReadable();
} }
NetcodeName += NetName; NetcodeName += NetName;
} }
@ -957,6 +934,7 @@ static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
if( SameNetcodeCount >= 2 ) if( SameNetcodeCount >= 2 )
fprintf( f, " %s %.4s\n", CONV_TO_UTF8( CmpRef ), fprintf( f, " %s %.4s\n", CONV_TO_UTF8( CmpRef ),
(const char*) &aObjectsList[ii]->m_PinNum ); (const char*) &aObjectsList[ii]->m_PinNum );
} }
} }
@ -1069,7 +1047,7 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
wxString InitNetDesc = StartLine + wxT( "ADD_TER" ); wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
wxString StartNetDesc = StartLine + wxT( "TER" ); wxString StartNetDesc = StartLine + wxT( "TER" );
wxString NetcodeName, InitNetDescLine; wxString NetcodeName, InitNetDescLine;
unsigned ii, jj; unsigned ii;
int print_ter = 0; int print_ter = 0;
int NetCode, LastNetCode = -1; int NetCode, LastNetCode = -1;
SCH_COMPONENT* Cmp; SCH_COMPONENT* Cmp;
@ -1084,31 +1062,21 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
if( ( NetCode = aObjectsList[ii]->GetNet() ) != LastNetCode ) if( ( NetCode = aObjectsList[ii]->GetNet() ) != LastNetCode )
{ {
NetName.Empty(); NetName.Empty();
for( jj = 0; jj < aObjectsList.size(); jj++ ) NETLIST_OBJECT* netref;
{ netref = aObjectsList[ii]->m_NetNameCandidate;
if( aObjectsList[jj]->GetNet() != NetCode ) if( netref )
continue; NetName = *netref->m_Label;
if( ( aObjectsList[jj]->m_Type != NET_HIERLABEL)
&& ( aObjectsList[jj]->m_Type != NET_LABEL)
&& ( aObjectsList[jj]->m_Type != NET_PINLABEL) )
continue;
NetName = *aObjectsList[jj]->m_Label; break;
}
NetcodeName = wxT( "\"" ); NetcodeName = wxT( "\"" );
if( !NetName.IsEmpty() ) if( !NetName.IsEmpty() )
{ {
NetcodeName += NetName; if( netref->m_Type != NET_PINLABEL )
if( aObjectsList[jj]->m_Type != NET_PINLABEL )
{ {
NetcodeName = // usual net name, prefix it by the sheet path
aObjectsList[jj]->m_SheetList.PathHumanReadable() NetcodeName +=
+ NetcodeName; netref->m_SheetList.PathHumanReadable();
//NetcodeName << wxT("_") <<
// g_NetObjectslist[jj].m_SheetList.PathHumanReadable();
} }
NetcodeName += NetName;
} }
else // this net has no name: create a default name $<net number> else // this net has no name: create a default name $<net number>
NetcodeName << wxT( "$" ) << NetCode; NetcodeName << wxT( "$" ) << NetCode;
@ -1139,10 +1107,10 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
buf[4] = 0; buf[4] = 0;
str_pinnum = CONV_FROM_UTF8( buf ); str_pinnum = CONV_FROM_UTF8( buf );
InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ), InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
InitNetDesc.GetData(), GetChars(InitNetDesc),
refstr.GetData(), GetChars(refstr),
str_pinnum.GetData(), GetChars(str_pinnum),
NetcodeName.GetData() ); GetChars(NetcodeName) );
} }
print_ter++; print_ter++;
break; break;
@ -1165,9 +1133,9 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
aObjectsList[ii]->m_Flag = 1; aObjectsList[ii]->m_Flag = 1;
// Search for redundant pins to avoid generation the same connection // Search for redundant pins to avoid generation of the same connection
// more than once. // more than once.
for( jj = ii + 1; jj < aObjectsList.size(); jj++ ) for( unsigned jj = ii + 1; jj < aObjectsList.size(); jj++ )
{ {
if( aObjectsList[jj]->GetNet() != NetCode ) if( aObjectsList[jj]->GetNet() != NetCode )
break; break;

View File

@ -22,8 +22,8 @@ NETLIST_OBJECT_LIST g_NetObjectslist;
static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus ); static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus );
static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel ); static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel );
static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist, static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
NETLIST_OBJECT_LIST& aNetItemBuffer ); NETLIST_OBJECT_LIST& aNetItemBuffer );
static int ConvertBusToMembers( NETLIST_OBJECT_LIST& aNetItemBuffer, NETLIST_OBJECT& ObjNet ); static int ConvertBusToMembers( NETLIST_OBJECT_LIST& aNetItemBuffer, NETLIST_OBJECT& ObjNet );
static void PointToPointConnect( NETLIST_OBJECT* Ref, int IsBus, int start ); static void PointToPointConnect( NETLIST_OBJECT* Ref, int IsBus, int start );
static void SegmentToPointConnect( NETLIST_OBJECT* Jonction, int IsBus, int start ); static void SegmentToPointConnect( NETLIST_OBJECT* Jonction, int IsBus, int start );
@ -31,10 +31,14 @@ static void LabelConnect( NETLIST_OBJECT* Label );
static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer ); static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer );
static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer ); static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer );
static void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer );
static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer );
// Sort functions used here: // Sort functions used here:
static bool SortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 ); static bool SortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 );
static bool SortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 ); static bool SortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 );
// Local variables
static int FirstNumWireBus, LastNumWireBus, RootBusNameLength; static int FirstNumWireBus, LastNumWireBus, RootBusNameLength;
static int LastNetCode, LastBusNetCode; static int LastNetCode, LastBusNetCode;
@ -93,7 +97,7 @@ void WinEDA_SchematicFrame::BuildNetListBase()
sheet = SheetListList.GetFirst(); sheet = SheetListList.GetFirst();
for( ; sheet != NULL; sheet = SheetListList.GetNext() ) for( ; sheet != NULL; sheet = SheetListList.GetNext() )
ListeObjetConnection( sheet, g_NetObjectslist ); AddConnectedObjects( sheet, g_NetObjectslist );
if( g_NetObjectslist.size() == 0 ) if( g_NetObjectslist.size() == 0 )
return; // no objects return; // no objects
@ -290,9 +294,126 @@ void WinEDA_SchematicFrame::BuildNetListBase()
/* Assignment of m_FlagOfConnection based connection or not. */ /* Assignment of m_FlagOfConnection based connection or not. */
SetUnconnectedFlag( g_NetObjectslist ); SetUnconnectedFlag( g_NetObjectslist );
/* find the best label object to give the best net name to each net */
FindBestNetNameForEachNet( g_NetObjectslist );
} }
/** 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( NETLIST_OBJECT_LIST& aNetItemBuffer )
{
NETLIST_OBJECT_LIST candidates;
int netcode = 0; // current netcode for tested items
unsigned idxstart = 0; // index of the first item of this net
for( unsigned ii = 0; ii <= aNetItemBuffer.size(); ii++ )
{
NETLIST_OBJECT* item;
if( ii == aNetItemBuffer.size() ) // last item already found
netcode = -2;
else
item = aNetItemBuffer[ii];
if( netcode != item->GetNet() ) // End of net found
{
if( candidates.size() ) // O,e or more labels exists, find the best
{
NETLIST_OBJECT* bestlabel = FindBestNetName( candidates );
for (unsigned jj = idxstart; jj < ii; jj++ )
aNetItemBuffer[jj]->m_NetNameCandidate = bestlabel;
}
if( netcode == -2 )
break;
netcode = item->GetNet();
candidates.clear();
idxstart = ii;
}
switch( item->m_Type )
{
case NET_HIERLABEL:
case NET_LABEL:
case NET_PINLABEL:
candidates.push_back( item );
break;
default:
break;
}
}
}
/** Function FindBestNetName
* @return a reference to the "best" label that can be used to give a name
* to a net.
* @param aLabelItemBuffer = list of NETLIST_OBJECT type labels candidates.
* labels are local labels, hierarchical labels or pin labels
* labels in included sheets have a lower priority than labels in the current sheet.
* so labels inside the root sheet have the highter priority.
* pin labels are global labels and have the highter priority
* local labels have the lower priority
* labels having the same priority are sorted by alphabetic order.
*
*/
static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer )
{
if( aLabelItemBuffer.size() == 0 )
return NULL;
NETLIST_OBJECT*item = aLabelItemBuffer[0];
for( unsigned ii = 1; ii < aLabelItemBuffer.size(); ii++ )
{
NETLIST_OBJECT* candidate = aLabelItemBuffer[ii];
if( candidate->m_SheetList.Path().Length() < item->m_SheetList.Path().Length() )
{
item = candidate;
continue;
}
switch ( item->m_Type )
{
case NET_HIERLABEL:
if( candidate->m_Type == NET_PINLABEL )
item = candidate;
else if( candidate->m_Type == NET_HIERLABEL )
{
if( candidate->m_Label->Cmp(*item->m_Label) < 0 )
item = candidate;
}
break;
case NET_LABEL:
if( candidate->m_Type == NET_LABEL )
{
if( candidate->m_Label->Cmp(*item->m_Label) < 0 )
item = candidate;
}
else
item = candidate;
break;
case NET_PINLABEL:
if( candidate->m_Type != NET_PINLABEL )
break;
if( candidate->m_Label->Cmp(*item->m_Label) < 0 )
item = candidate;
break;
default: // Should not occur.
break;
}
}
return item;
}
/* /*
* Connect sheets by sheetLabels * Connect sheets by sheetLabels
*/ */
@ -332,7 +453,7 @@ static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
} }
/** Function ListeObjetConnection /** Function AddConnectedObjects
* Creates the list of objects related to connections (pins of components, * Creates the list of objects related to connections (pins of components,
* wires, labels, junctions ...) * wires, labels, junctions ...)
* *
@ -340,8 +461,8 @@ static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
* @param aNetItemBuffer: a std::vector to store pointer on NETLIST_OBJECT * @param aNetItemBuffer: a std::vector to store pointer on NETLIST_OBJECT
* created * created
*/ */
static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist, static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
std::vector<NETLIST_OBJECT*>& aNetItemBuffer ) std::vector<NETLIST_OBJECT*>& aNetItemBuffer )
{ {
int ii; int ii;
SCH_ITEM* DrawList; SCH_ITEM* DrawList;
@ -563,7 +684,7 @@ static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist,
{ {
wxString msg; wxString msg;
msg.Printf( wxT( "Netlist: unexpected struct type %d" ), msg.Printf( wxT( "Netlist: unexpected struct type %d" ),
DrawList->Type() ); DrawList->Type() );
wxMessageBox( msg ); wxMessageBox( msg );
break; break;
} }
@ -663,7 +784,7 @@ int IsBusLabel( const wxString& LabelDrawList )
} }
if( !BufLine.ToLong( &tmp ) ) if( !BufLine.ToLong( &tmp ) )
error = TRUE; ; error = TRUE;;
LastNumWireBus = tmp; LastNumWireBus = tmp;
if( FirstNumWireBus < 0 ) if( FirstNumWireBus < 0 )