From 3543ba65de82075fa016a1aef3288fd44bc93b6a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 23 Jun 2010 19:00:12 +0200 Subject: [PATCH] ++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 --- CHANGELOG.txt | 16 +++ demos/pic_programmer/pic_programmer.pro | 6 +- eeschema/class_netlist_object.cpp | 17 +-- eeschema/class_netlist_object.h | 16 +-- eeschema/netform.cpp | 116 ++++++++------------ eeschema/netlist.cpp | 137 ++++++++++++++++++++++-- 6 files changed, 211 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 90b8691d87..5e625f6add 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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 +================================================================================ +++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 ================================================================================ ++eeschema: diff --git a/demos/pic_programmer/pic_programmer.pro b/demos/pic_programmer/pic_programmer.pro index 868476ee83..750daa8a11 100644 --- a/demos/pic_programmer/pic_programmer.pro +++ b/demos/pic_programmer/pic_programmer.pro @@ -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 diff --git a/eeschema/class_netlist_object.cpp b/eeschema/class_netlist_object.cpp index 66c210d5a0..1277664e42 100644 --- a/eeschema/class_netlist_object.cpp +++ b/eeschema/class_netlist_object.cpp @@ -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 diff --git a/eeschema/class_netlist_object.h b/eeschema/class_netlist_object.h index 0fda5cf496..1ed96afe60 100644 --- a/eeschema/class_netlist_object.h +++ b/eeschema/class_netlist_object.h @@ -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 ); diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index ed1023dd0f..330475a197 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -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 $ 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; diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp index aa521546ff..04a038d64e 100644 --- a/eeschema/netlist.cpp +++ b/eeschema/netlist.cpp @@ -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& aNetItemBuffer ) +static void AddConnectedObjects( SCH_SHEET_PATH* sheetlist, + std::vector& 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 )