XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets() { XNODE* xnets = node( wxT( "nets" ) ); // auto_ptr if exceptions ever get used. wxString netCodeTxt; wxString netName; wxString ref; wxString sNet = wxT( "net" ); wxString sName = wxT( "name" ); wxString sCode = wxT( "code" ); wxString sRef = wxT( "ref" ); wxString sPin = wxT( "pin" ); wxString sNode = wxT( "node" ); wxString sFmtd = wxT( "%d" ); XNODE* xnet = 0; int netCode; int lastNetCode = -1; int sameNetcodeCount = 0; /* output: <net code="123" name="/cfcard.sch/WAIT#"> <node ref="R23" pin="1"/> <node ref="U18" pin="12"/> </net> */ m_LibParts.clear(); // must call this function before using m_LibParts. for( unsigned ii = 0; ii < m_masterList->size(); ii++ ) { NETLIST_OBJECT* nitem = m_masterList->GetItem( ii ); SCH_COMPONENT* comp; // New net found, write net id; if( ( netCode = nitem->GetNet() ) != lastNetCode ) { sameNetcodeCount = 0; // item count for this net netName = nitem->GetNetName(); lastNetCode = netCode; } if( nitem->m_Type != NET_PIN ) continue; if( nitem->m_Flag != 0 ) // Redundant pin, skip it continue; comp = nitem->GetComponentParent(); // Get the reference for the net name and the main parent component ref = comp->GetRef( &nitem->m_SheetPath ); if( ref[0] == wxChar( '#' ) ) continue; if( ++sameNetcodeCount == 1 ) { xnets->AddChild( xnet = node( sNet ) ); netCodeTxt.Printf( sFmtd, netCode ); xnet->AddAttribute( sCode, netCodeTxt ); xnet->AddAttribute( sName, netName ); } XNODE* xnode; xnet->AddChild( xnode = node( sNode ) ); xnode->AddAttribute( sRef, ref ); xnode->AddAttribute( sPin, nitem->GetPinNumText() ); } return xnets; }
void NETLIST_OBJECT_LIST::findBestNetNameForEachNet() { // Important note: NET_SHEETLABEL items of sheet items should *NOT* be considered, // because they live in a sheet but their names are actually used in the subsheet. // Moreover, in the parent sheet, the name of NET_SHEETLABEL can be not unique, // ( for instance when 2 different sheets share the same schematic in complex hierarchies // and 2 identical NET_SHEETLABEL labels can be connected to 2 different nets int netcode = 0; // current netcode for tested items unsigned idxstart = 0; // index of the first item of this net NETLIST_OBJECT* item; NETLIST_OBJECT* candidate; // Pass 1: find the best name for labelled nets: candidate = NULL; for( unsigned ii = 0; ii <= size(); ii++ ) { if( ii == size() ) // last item already tested item = NULL; else item = GetItem( ii ); if( !item || netcode != item->GetNet() ) // End of net found { if( candidate ) // One or more labels exists, find the best { for (unsigned jj = idxstart; jj < ii; jj++ ) GetItem( jj )->SetNetNameCandidate( candidate ); } if( item == NULL ) // End of list break; // Prepare next net analysis: netcode = item->GetNet(); candidate = NULL; idxstart = ii; } switch( item->m_Type ) { case NET_HIERLABEL: case NET_LABEL: case NET_PINLABEL: case NET_GLOBLABEL: case NET_GLOBBUSLABELMEMBER: // A candidate is found: select the better between the previous // and this one if( candidate == NULL ) candidate = item; else { if( evalLabelsPriority( item, candidate ) ) // item has a highter priority than candidate // so update the best candidate candidate = item; } break; default: break; } } // Pass 2: find the best name for not labelled nets: // The "default" net name is Net-<<Ref cmp>_Pad<num pad>> // (see NETLIST_OBJECT::GetShortNetName()) // therefore the "best" is the short net name alphabetically classed first // (to avoid net names changes when the net is not modified, // even if components are moved or deleted and undelete or replaced, as long // the reference is kept) // Build a list of items with no net names NETLIST_OBJECTS list; // no ownership of elements being pointed at for( unsigned ii = 0; ii < size(); ii++ ) { item = GetItem( ii ); if( !item->HasNetNameCandidate() ) list.push_back( item ); } if( list.size() == 0 ) return; idxstart = 0; candidate = NULL; netcode = list[0]->GetNet(); for( unsigned ii = 0; ii <= list.size(); ii++ ) { if( ii < list.size() ) item = list[ii]; else item = NULL; if( !item || netcode != item->GetNet() ) // End of net found { if( candidate ) { for (unsigned jj = idxstart; jj < ii; jj++ ) { NETLIST_OBJECT* obj = list[jj]; obj->SetNetNameCandidate( candidate ); } } if( !item ) break; netcode = item->GetNet(); candidate = NULL; idxstart = ii; } // Examine all pins of the net to find the best candidate, // i.e. the first net name candidate, by alphabetic order // the net names are built by GetShortNetName // (Net-<{reference}-Pad{pad number}> like Net-<U3-Pad5> // Not named nets do not have usually a lot of members. // Many have only 2 members(a pad and a non connection symbol) if( item->m_Type == NET_PIN ) { // A candidate is found, however components which are not in // netlist are not candidate because some have their reference // changed each time the netlist is built (power components) // and anyway obviously they are not a good candidate SCH_COMPONENT* link = item->GetComponentParent(); if( link && link->IsInNetlist() ) { // select the better between the previous and this one item->SetNetNameCandidate( item ); // Needed to calculate GetShortNetName if( candidate == NULL ) candidate = item; else { if( item->GetShortNetName().Cmp( candidate->GetShortNetName() ) < 0 ) candidate = item; } } } } }
bool NETLIST_EXPORTER_GENERIC::writeListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) { int ret = 0; int netCode; int lastNetCode = -1; int sameNetcodeCount = 0; wxString netName; wxString ref; wxString netcodeName; char firstItemInNet[256]; for( unsigned ii = 0; ii < aObjectsList.size(); ii++ ) { SCH_COMPONENT* comp; NETLIST_OBJECT* nitem = aObjectsList[ii]; // New net found, write net id; if( ( netCode = nitem->GetNet() ) != lastNetCode ) { sameNetcodeCount = 0; // Items count for this net netName = nitem->GetNetName(); netcodeName.Printf( wxT( "Net %d " ), netCode ); netcodeName << wxT( "\"" ) << netName << wxT( "\"" ); // Add the netname without prefix, in cases we need only the // "short" netname netcodeName += wxT( " \"" ) + nitem->GetShortNetName() + wxT( "\"" ); lastNetCode = netCode; } if( nitem->m_Type != NET_PIN ) continue; if( nitem->m_Flag != 0 ) // Redundant pin, skip it continue; comp = nitem->GetComponentParent(); // Get the reference for the net name and the main parent component ref = comp->GetRef( &nitem->m_SheetPath ); if( ref[0] == wxChar( '#' ) ) continue; // Pseudo component (Like Power symbol) // Print the pin list for this net, use special handling if // 2 or more items are connected: // if first item for this net found, defer printing this connection // until a second item will is found if( ++sameNetcodeCount == 1 ) { snprintf( firstItemInNet, sizeof(firstItemInNet), " %s %.4s\n", TO_UTF8( ref ), (const char*) &aObjectsList[ii]->m_PinNum ); } // Second item for this net found, print the Net name, and the // first item if( sameNetcodeCount == 2 ) { ret |= fprintf( f, "%s\n", TO_UTF8( netcodeName ) ); ret |= fputs( firstItemInNet, f ); } if( sameNetcodeCount >= 2 ) ret |= fprintf( f, " %s %.4s\n", TO_UTF8( ref ), (const char*) &nitem->m_PinNum ); } return ret >= 0; }
bool NETLIST_EXPORTER_CADSTAR::writeListOfNets( FILE* f ) { int ret = 0; wxString InitNetDesc = StartLine + wxT( "ADD_TER" ); wxString StartNetDesc = StartLine + wxT( "TER" ); wxString netcodeName, InitNetDescLine; unsigned ii; int print_ter = 0; int NetCode, lastNetCode = -1; SCH_COMPONENT* Cmp; wxString netName; for( ii = 0; ii < m_masterList->size(); ii++ ) { NETLIST_OBJECT* nitem = m_masterList->GetItem( ii ); // Get the NetName of the current net : if( ( NetCode = nitem->GetNet() ) != lastNetCode ) { netName = nitem->GetNetName(); netcodeName = wxT( "\"" ); if( !netName.IsEmpty() ) netcodeName << netName; else // this net has no name: create a default name $<net number> netcodeName << wxT( "$" ) << NetCode; netcodeName += wxT( "\"" ); lastNetCode = NetCode; print_ter = 0; } if( nitem->m_Type != NET_PIN ) continue; if( nitem->m_Flag != 0 ) continue; Cmp = nitem->GetComponentParent(); wxString refstr = Cmp->GetRef( &nitem->m_SheetPath ); if( refstr[0] == '#' ) continue; // Power supply symbols. switch( print_ter ) { case 0: { char buf[5]; wxString str_pinnum; strncpy( buf, (char*) &nitem->m_PinNum, 4 ); buf[4] = 0; str_pinnum = FROM_UTF8( buf ); InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ), GetChars( InitNetDesc ), GetChars( refstr ), GetChars( str_pinnum ), GetChars( netcodeName ) ); } print_ter++; break; case 1: ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) ); ret |= fprintf( f, "%s %s %.4s\n", TO_UTF8( StartNetDesc ), TO_UTF8( refstr ), (char*) &nitem->m_PinNum ); print_ter++; break; default: ret |= fprintf( f, " %s %.4s\n", TO_UTF8( refstr ), (char*) &nitem->m_PinNum ); break; } nitem->m_Flag = 1; } return ret >= 0; }
/** * 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 NETLIST_OBJECT_LIST::findBestNetNameForEachNet() { int netcode = 0; // current netcode for tested items unsigned idxstart = 0; // index of the first item of this net NETLIST_OBJECT* item; NETLIST_OBJECT* candidate; // Pass 1: find the best name for labelled nets: item = NULL; candidate = NULL; for( unsigned ii = 0; ii <= size(); ii++ ) { if( ii == size() ) // last item already found netcode = -2; else item = GetItem( ii ); if( netcode != item->GetNet() ) // End of net found { if( candidate ) // One or more labels exists, find the best { for (unsigned jj = idxstart; jj < ii; jj++ ) GetItem( jj )->SetNetNameCandidate( candidate ); } if( netcode == -2 ) break; netcode = item->GetNet(); candidate = NULL; idxstart = ii; } switch( item->m_Type ) { case NET_HIERLABEL: case NET_LABEL: case NET_PINLABEL: case NET_GLOBLABEL: // A candidate is found: select the better between the previous // and this one if( candidate == NULL ) candidate = item; else { if( evalLabelsPriority( item, candidate ) ) // item has a highter priority than candidate // so update the best candidate candidate = item; } break; default: break; } } // Pass 2: find the best name for not labelled nets: // The "default" net name is Net-<<Ref cmp>_Pad<num pad>> // (see NETLIST_OBJECT::GetShortNetName()) // therefore the "best" is the short net name alphabetically classed first // (to avoid net names changes when the net is not modified, // even if components are moved or deleted and undelete or replaced, as long // the reference is kept) // Build the list of items with no net names NETLIST_OBJECT_LIST list; for( unsigned ii = 0; ii < size(); ii++ ) { item = GetItem( ii ); if( !item->HasNetNameCandidate() ) list.push_back( item ); } if( list.size() == 0 ) return; idxstart = 0; candidate = NULL; netcode = list.GetItemNet( 0 ); for( unsigned ii = 0; ii <= list.size(); ii++ ) { if( ii < list.size() ) item = list.GetItem( ii ); if( netcode != item->GetNet() || ii >= list.size() ) // End of net found { if( candidate ) { for (unsigned jj = idxstart; jj < ii; jj++ ) { NETLIST_OBJECT* obj = list.GetItem( jj ); obj->SetNetNameCandidate( candidate ); } } if( ii >= list.size() ) break; netcode = item->GetNet(); candidate = NULL; idxstart = ii; } // Examine all pins of the net to find the best candidate, // i.e. the first net name candidate, by alphabetic order // the net names are names bu_ilt by GetShortNetName // (Net-<{reference}-Pad{pad number}> like Net-<U3-Pad5> // Not named nets do not have usually a lot of members. // Many have only 2 members(a pad and a non connection symbol) if( item->m_Type == NET_PIN ) { // A candidate is found, however components which are not in // netlist are not candidate because some have their reference // changed each time the netlist is built (power components) // and anyway obviously they are not a good candidate SCH_COMPONENT* link = item->GetComponentParent(); if( link && link->IsInNetlist() ) { // select the better between the previous and this one item->SetNetNameCandidate( item ); // Needed to calculate GetShortNetName if( candidate == NULL ) candidate = item; else { if( item->GetShortNetName().Cmp( candidate->GetShortNetName() ) < 0 ) candidate = item; } } } } }