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 )