++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
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>
================================================================================
++eeschema:

View File

@ -1,4 +1,4 @@
update=12/06/2010 08:55:18
update=23/06/2010 18:43:01
last_client=pcbnew
[general]
version=1
@ -17,8 +17,8 @@ NetDir=
[pcbnew]
version=1
PadDrlX=320
PadDimH=700
PadDimV=700
PadDimH=620
PadDimV=1100
BoardThickness=630
SgPcb45=1
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_Comp = NULL; /* Pointer on the library item that created this net object (the parent)*/
m_Link = NULL; /* For SCH_SHEET_PIN:
* Pointer to the hierarchy sheet that contains this SCH_SHEET_PIN
* For Pins: pointer to the component that contains this pin
*/
m_Link = NULL; /* For SCH_SHEET_PIN:
* Pointer to the hierarchy sheet that contains this SCH_SHEET_PIN
* For Pins: pointer to the component that contains this pin
*/
m_Flag = 0; /* flag used in calculations */
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
@ -116,16 +116,21 @@ NETLIST_OBJECT::NETLIST_OBJECT()
m_FlagOfConnection = UNCONNECTED;
m_PinNum = 0; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */
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
NETLIST_OBJECT::NETLIST_OBJECT( NETLIST_OBJECT& aSource )
{
*this = aSource;
m_Label = NULL; // set to null because some items are owner, so the delete operator can create problems
*this = aSource;
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)
}
NETLIST_OBJECT::~NETLIST_OBJECT()
{
/* 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
* that contains this pin
*/
int m_Flag; /* flag used in calculations */
SCH_SHEET_PATH m_SheetList;
int m_ElectricalType; /* Has meaning only for Pins and
int m_Flag; /* flag used in calculations */
SCH_SHEET_PATH m_SheetList;
int m_ElectricalType; /* Has meaning only for Pins and
* hierarchical pins: electrical type */
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
* as many net codes as bus members
*/
public:
int m_BusNetCode; /* Used for BUS connections */
int m_Member; /* for labels type NET_BUSLABELMEMBER
int m_BusNetCode; /* Used for BUS connections */
int m_Member; /* for labels type NET_BUSLABELMEMBER
* ( bus member created from the BUS
* label ) member number
*/
@ -90,6 +90,10 @@ public:
// starting point
wxPoint m_End; // For segments (wire and buses):
// 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)
void Show( std::ostream& out, int ndx );

View File

@ -212,43 +212,29 @@ static wxString ReturnPinNetName( NETLIST_OBJECT* Pin,
wxString NetName;
if( (netcode == 0 ) || ( Pin->m_FlagOfConnection != PAD_CONNECT ) )
{
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
{
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.Printf( DefaultFormatNetname.GetData(), netcode );
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;
}
@ -890,31 +876,22 @@ static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
{
SameNetcodeCount = 0; // Items count for this net
NetName.Empty();
unsigned jj;
// Find a label (if exists) for this net.
for( jj = 0; jj < aObjectsList.size(); jj++ )
{
if( aObjectsList[jj]->GetNet() != NetCode )
continue;
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;
}
NETLIST_OBJECT* netref;
netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref )
NetName = *netref->m_Label;
NetcodeName.Printf( wxT( "Net %d " ), NetCode );
NetcodeName += wxT( "\"" );
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
NetcodeName +=
aObjectsList[jj]->m_SheetList.PathHumanReadable();
netref->m_SheetList.PathHumanReadable();
}
NetcodeName += NetName;
}
@ -957,6 +934,7 @@ static void WriteGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
if( SameNetcodeCount >= 2 )
fprintf( f, " %s %.4s\n", CONV_TO_UTF8( CmpRef ),
(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 StartNetDesc = StartLine + wxT( "TER" );
wxString NetcodeName, InitNetDescLine;
unsigned ii, jj;
unsigned ii;
int print_ter = 0;
int NetCode, LastNetCode = -1;
SCH_COMPONENT* Cmp;
@ -1084,31 +1062,21 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
if( ( NetCode = aObjectsList[ii]->GetNet() ) != LastNetCode )
{
NetName.Empty();
for( jj = 0; jj < aObjectsList.size(); jj++ )
{
if( aObjectsList[jj]->GetNet() != NetCode )
continue;
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;
}
NETLIST_OBJECT* netref;
netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref )
NetName = *netref->m_Label;
NetcodeName = wxT( "\"" );
if( !NetName.IsEmpty() )
{
NetcodeName += NetName;
if( aObjectsList[jj]->m_Type != NET_PINLABEL )
if( netref->m_Type != NET_PINLABEL )
{
NetcodeName =
aObjectsList[jj]->m_SheetList.PathHumanReadable()
+ NetcodeName;
//NetcodeName << wxT("_") <<
// g_NetObjectslist[jj].m_SheetList.PathHumanReadable();
// usual net name, prefix it by the sheet path
NetcodeName +=
netref->m_SheetList.PathHumanReadable();
}
NetcodeName += NetName;
}
else // this net has no name: create a default name $<net number>
NetcodeName << wxT( "$" ) << NetCode;
@ -1139,10 +1107,10 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
buf[4] = 0;
str_pinnum = CONV_FROM_UTF8( buf );
InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
InitNetDesc.GetData(),
refstr.GetData(),
str_pinnum.GetData(),
NetcodeName.GetData() );
GetChars(InitNetDesc),
GetChars(refstr),
GetChars(str_pinnum),
GetChars(NetcodeName) );
}
print_ter++;
break;
@ -1165,9 +1133,9 @@ static void WriteListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjectsList )
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.
for( jj = ii + 1; jj < aObjectsList.size(); jj++ )
for( unsigned jj = ii + 1; jj < aObjectsList.size(); jj++ )
{
if( aObjectsList[jj]->GetNet() != NetCode )
break;

View File

@ -22,8 +22,8 @@ NETLIST_OBJECT_LIST g_NetObjectslist;
static void PropageNetCode( int OldNetCode, int NewNetCode, int IsBus );
static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel );
static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist,
NETLIST_OBJECT_LIST& aNetItemBuffer );
static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
NETLIST_OBJECT_LIST& aNetItemBuffer );
static int ConvertBusToMembers( NETLIST_OBJECT_LIST& aNetItemBuffer, NETLIST_OBJECT& ObjNet );
static void PointToPointConnect( NETLIST_OBJECT* Ref, 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 SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer );
static void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer );
static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer );
// Sort functions used here:
static bool SortItemsbyNetcode( 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 LastNetCode, LastBusNetCode;
@ -93,7 +97,7 @@ void WinEDA_SchematicFrame::BuildNetListBase()
sheet = SheetListList.GetFirst();
for( ; sheet != NULL; sheet = SheetListList.GetNext() )
ListeObjetConnection( sheet, g_NetObjectslist );
AddConnectedObjects( sheet, g_NetObjectslist );
if( g_NetObjectslist.size() == 0 )
return; // no objects
@ -290,9 +294,126 @@ void WinEDA_SchematicFrame::BuildNetListBase()
/* Assignment of m_FlagOfConnection based connection or not. */
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
*/
@ -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,
* wires, labels, junctions ...)
*
@ -340,8 +461,8 @@ static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
* @param aNetItemBuffer: a std::vector to store pointer on NETLIST_OBJECT
* created
*/
static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist,
std::vector<NETLIST_OBJECT*>& aNetItemBuffer )
static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist,
std::vector<NETLIST_OBJECT*>& aNetItemBuffer )
{
int ii;
SCH_ITEM* DrawList;
@ -563,7 +684,7 @@ static void ListeObjetConnection( SCH_SHEET_PATH* sheetlist,
{
wxString msg;
msg.Printf( wxT( "Netlist: unexpected struct type %d" ),
DrawList->Type() );
DrawList->Type() );
wxMessageBox( msg );
break;
}
@ -663,7 +784,7 @@ int IsBusLabel( const wxString& LabelDrawList )
}
if( !BufLine.ToLong( &tmp ) )
error = TRUE; ;
error = TRUE;;
LastNumWireBus = tmp;
if( FirstNumWireBus < 0 )