Esempio n. 1
0
/*
 * Build net list connection table.
 * Initializes s_NetObjectslist
 */
NETLIST_OBJECT_LIST * SCH_EDIT_FRAME::BuildNetListBase()
{
    wxBusyCursor    Busy;

    // Creates the flattened sheet list:
    SCH_SHEET_LIST aSheets;

    // Build netlist info
    bool success = s_NetObjectslist.BuildNetListInfo( aSheets );

    if( !success )
    {
        SetStatusText( _("No Objects" ) );
        return &s_NetObjectslist;
    }

    /* The new %zu specification is needed to properly format a size_t
     * value (returned by size(), here) */
    wxString msg;

    msg.Printf( _( "Net count = %zu" ), s_NetObjectslist.size() );
    SetStatusText( msg );

    return &s_NetObjectslist;
}
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;
}
Esempio 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;
                }
            }
        }
    }
}
Esempio n. 4
0
void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
{
    wxFileName fn;

    if( !DiagErcTableInit )
    {
        memcpy( DiagErc, DefaultDiagErc, sizeof(DefaultDiagErc) );
        DiagErcTableInit = true;
    }

    m_writeErcFile = m_WriteResultOpt->GetValue();

    /* Build the whole sheet list in hierarchy (sheet, not screen) */
    SCH_SHEET_LIST sheets;
    sheets.AnnotatePowerSymbols();

    if( m_parent->CheckAnnotate( aMessagesList, false ) )
    {
        if( aMessagesList )
        {
            wxString msg = _( "Annotation required!" );
            msg += wxT( "\n" );
            aMessagesList->Add( msg );
        }

        return;
    }

    SCH_SCREENS screens;

    // Erase all previous DRC markers.
    screens.DeleteAllMarkers( MARK_ERC );

    for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
    {
        /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted
         * data problems.
         */
        if( screen->SchematicCleanUp( NULL ) )
            screen->ClearUndoRedoList();
    }

    /* Test duplicate sheet names inside a given sheet, one cannot have sheets with
     * duplicate names (file names can be duplicated).
     */
    TestDuplicateSheetNames( true );

    NETLIST_OBJECT_LIST* objectsConnectedList = m_parent->BuildNetListBase();

    // Reset the connection type indicator
    objectsConnectedList->ResetConnectionsType();

    unsigned lastNet;
    unsigned nextNet = lastNet = 0;
    int NetNbItems = 0;
    int MinConn    = NOC;

    for( unsigned net = 0; net < objectsConnectedList->size(); net++ )
    {
        if( objectsConnectedList->GetItemNet( lastNet ) !=
            objectsConnectedList->GetItemNet( net ) )
        {
            // New net found:
            MinConn    = NOC;
            NetNbItems = 0;
            nextNet   = net;
        }

        switch( objectsConnectedList->GetItemType( net ) )
        {
        // These items do not create erc problems
        case NET_ITEM_UNSPECIFIED:
        case NET_SEGMENT:
        case NET_BUS:
        case NET_JUNCTION:
        case NET_LABEL:
        case NET_BUSLABELMEMBER:
        case NET_PINLABEL:
        case NET_GLOBLABEL:
        case NET_GLOBBUSLABELMEMBER:
            break;

        case NET_HIERLABEL:
        case NET_HIERBUSLABELMEMBER:
        case NET_SHEETLABEL:
        case NET_SHEETBUSLABELMEMBER:

            // ERC problems when pin sheets do not match hierarchical labels.
            // Each pin sheet must match a hierarchical label
            // Each hierarchical label must match a pin sheet
            TestLabel( objectsConnectedList, net, nextNet );
            break;

        case NET_NOCONNECT:

            // ERC problems when a noconnect symbol is connected to more than one pin.
            MinConn = NET_NC;

            if( NetNbItems != 0 )
                Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC );

            break;

        case NET_PIN:

            // Look for ERC problems between pins:
            TestOthersItems( objectsConnectedList, net, nextNet, &NetNbItems, &MinConn );
            break;
        }

        lastNet = net;
    }

    // Displays global results:
    wxString num;
    int markers = screens.GetMarkerCount();
    int warnings = screens.GetMarkerCount( WAR );

    num.Printf( wxT( "%d" ), markers );
    m_TotalErrCount->SetLabel( num );

    num.Printf( wxT( "%d" ), markers - warnings );
    m_LastErrCount->SetLabel( num );

    num.Printf( wxT( "%d" ), warnings );
    m_LastWarningCount->SetLabel( num );

    // Display diags:
    DisplayERC_MarkersList();

    // Display new markers:
    m_parent->GetCanvas()->Refresh();

    if( m_writeErcFile )
    {
        fn = g_RootSheet->GetScreen()->GetFileName();
        fn.SetExt( wxT( "erc" ) );

        wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(),
                          _( "Electronic rule check file (.erc)|*.erc" ),
                          wxFD_SAVE | wxFD_OVERWRITE_PROMPT );

        if( dlg.ShowModal() == wxID_CANCEL )
            return;

        if( WriteDiagnosticERC( dlg.GetPath() ) )
        {
            Close( true );
            ExecuteFile( this, wxGetApp().GetEditorName(), QuoteFullPath( fn ) );
        }
    }
}