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.Last() );

        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;
}
Ejemplo n.º 3
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;
                }
            }
        }
    }
}