コード例 #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;
}
コード例 #2
0
ファイル: sch_text.cpp プロジェクト: johnbeard/kicad
void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
                               SCH_SHEET_PATH*      aSheetPath )
{
    if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL )
        return;

    NETLIST_OBJECT* item = new NETLIST_OBJECT();
    item->m_SheetPath = *aSheetPath;
    item->m_SheetPathInclude = *aSheetPath;
    item->m_Comp = (SCH_ITEM*) this;
    item->m_Type = NET_LABEL;

    if( GetLayer() == LAYER_GLOBLABEL )
        item->m_Type = NET_GLOBLABEL;
    else if( GetLayer() == LAYER_HIERLABEL )
        item->m_Type = NET_HIERLABEL;

    item->m_Label = m_Text;
    item->m_Start = item->m_End = GetTextPos();

    aNetListItems.push_back( item );

    // If a bus connects to label
    if( Connection( *aSheetPath )->IsBusLabel( m_Text ) )
    {
        item->ConvertBusToNetListItems( aNetListItems );
    }
}
コード例 #3
0
ファイル: sch_no_connect.cpp プロジェクト: cpavlina/kicad
void SCH_NO_CONNECT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
                                     SCH_SHEET_PATH*      aSheetPath )
{
    NETLIST_OBJECT* item = new NETLIST_OBJECT();

    item->m_SheetPath = *aSheetPath;
    item->m_SheetPathInclude = *aSheetPath;
    item->m_Comp = this;
    item->m_Type = NET_NOCONNECT;
    item->m_Start = item->m_End = m_pos;

    aNetListItems.push_back( item );
}
コード例 #4
0
ファイル: sch_junction.cpp プロジェクト: cpavlina/kicad
void SCH_JUNCTION::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
                                   SCH_SHEET_PATH*          aSheetPath )
{
    NETLIST_OBJECT* item = new NETLIST_OBJECT();

    item->m_SheetPath = *aSheetPath;
    item->m_SheetPathInclude = *aSheetPath;
    item->m_Comp = (SCH_ITEM*) this;
    item->m_Type = NET_JUNCTION;
    item->m_Start = item->m_End = m_pos;

    aNetListItems.push_back( item );
}
コード例 #5
0
ファイル: sch_sheet.cpp プロジェクト: cpavlina/kicad
void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
                                SCH_SHEET_PATH*      aSheetPath )
{
    SCH_SHEET_PATH sheetPath = *aSheetPath;
    sheetPath.push_back( this );

    for( size_t i = 0;  i < m_pins.size();  i++ )
    {
        NETLIST_OBJECT* item = new NETLIST_OBJECT();
        item->m_SheetPathInclude = sheetPath;
        item->m_SheetPath = *aSheetPath;
        item->m_Comp = &m_pins[i];
        item->m_Link = this;
        item->m_Type = NET_SHEETLABEL;
        item->m_Label = m_pins[i].GetText();
        item->m_Start = item->m_End = m_pins[i].GetPosition();
        aNetListItems.push_back( item );

        if( IsBusLabel( m_pins[i].GetText() ) )
            item->ConvertBusToNetListItems( aNetListItems );
    }
}
コード例 #6
0
void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems )
{
    wxCHECK_RET( IsBusLabel( m_Label ),
                 wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );

    if( m_Type == NET_HIERLABEL )
        m_Type = NET_HIERBUSLABELMEMBER;
    else if( m_Type == NET_GLOBLABEL )
        m_Type = NET_GLOBBUSLABELMEMBER;
    else if( m_Type == NET_SHEETLABEL )
        m_Type = NET_SHEETBUSLABELMEMBER;
    else if( m_Type == NET_LABEL )
        m_Type = NET_BUSLABELMEMBER;
    else
        wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );

    unsigned i;
    wxString tmp, busName, busNumber;
    long begin, end, member;

    busName = busLabelRe.GetMatch( m_Label, 1 );
    busNumber = busLabelRe.GetMatch( m_Label, 2 );

    /* Search for  '[' because a bus label is like "busname[nn..mm]" */
    i = busNumber.Find( '[' );
    i++;

    while( i < busNumber.Len() && busNumber[i] != '.' )
    {
        tmp.Append( busNumber[i] );
        i++;
    }

    tmp.ToLong( &begin );

    while( i < busNumber.Len() && busNumber[i] == '.' )
        i++;

    tmp.Empty();

    while( i < busNumber.Len() && busNumber[i] != ']' )
    {
        tmp.Append( busNumber[i] );
        i++;
    }

    tmp.ToLong( &end );

    if( begin < 0 )
        begin = 0;

    if( end < 0 )
        end = 0;

    if( begin > end )
        std::swap( begin, end );

    member = begin;
    tmp = busName;
    tmp << member;
    m_Label = tmp;
    m_Member = member;

    for( member++; member <= end; member++ )
    {
        NETLIST_OBJECT* item = new NETLIST_OBJECT( *this );

        // Conversion of bus label to the root name + the current member id.
        tmp = busName;
        tmp << member;
        item->m_Label = tmp;
        item->m_Member = member;

        aNetListItems.push_back( item );
    }
}
コード例 #7
0
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;
}
コード例 #8
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;
                }
            }
        }
    }
}
コード例 #9
0
/* the master function of NETLIST_OBJECT_LIST class.
 * Build the list of connected objects (pins, labels ...) and
 * all info needed to generate netlists or run ERC diags
 */
bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets )
{
    s_NetObjectslist.SetOwner( true );
    s_NetObjectslist.FreeList();

    SCH_SHEET_PATH* sheet;

    // Fill list with connected items from the flattened sheet list
    for( sheet = aSheets.GetFirst(); sheet != NULL;
         sheet = aSheets.GetNext() )
    {
        for( SCH_ITEM* item = sheet->LastScreen()->GetDrawItems(); item; item = item->Next() )
        {
            item->GetNetListItem( *this, sheet );
        }
    }

    if( size() == 0 )
        return false;

    // Sort objects by Sheet
    SortListbySheet();

    sheet = &(GetItem( 0 )->m_SheetPath);
    m_lastNetCode = m_lastBusNetCode = 1;

    for( unsigned ii = 0, istart = 0; ii < size(); ii++ )
    {
        NETLIST_OBJECT* net_item = GetItem( ii );

        if( net_item->m_SheetPath != *sheet )   // Sheet change
        {
            sheet  = &(net_item->m_SheetPath);
            istart = ii;
        }

        switch( net_item->m_Type )
        {
        case NET_ITEM_UNSPECIFIED:
            wxMessageBox( wxT( "BuildNetListBase() error" ) );
            break;

        case NET_PIN:
        case NET_PINLABEL:
        case NET_SHEETLABEL:
        case NET_NOCONNECT:
            if( net_item->GetNet() != 0 )
                break;

        case NET_SEGMENT:
            // Test connections point to point type without bus.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            pointToPointConnect( net_item, IS_WIRE, istart );
            break;

        case NET_JUNCTION:
            // Control of the junction outside BUS.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            segmentToPointConnect( net_item, IS_WIRE, istart );

            /* Control of the junction, on BUS. */
            if( net_item->m_BusNetCode == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            segmentToPointConnect( net_item, IS_BUS, istart );
            break;

        case NET_LABEL:
        case NET_HIERLABEL:
        case NET_GLOBLABEL:
            // Test connections type junction without bus.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            segmentToPointConnect( net_item, IS_WIRE, istart );
            break;

        case NET_SHEETBUSLABELMEMBER:
            if( net_item->m_BusNetCode != 0 )
                break;

        case NET_BUS:
            /* Control type connections point to point mode bus */
            if( net_item->m_BusNetCode == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            pointToPointConnect( net_item, IS_BUS, istart );
            break;

        case NET_BUSLABELMEMBER:
        case NET_HIERBUSLABELMEMBER:
        case NET_GLOBBUSLABELMEMBER:
            /* Control connections similar has on BUS */
            if( net_item->GetNet() == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            segmentToPointConnect( net_item, IS_BUS, istart );
            break;
        }
    }

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter sheet local\n\n";
    DumpNetTable();
#endif

    /* Updating the Bus Labels Netcode connected by Bus */
    connectBusLabels();

    /* Group objects by label. */
    for( unsigned ii = 0; ii < size(); ii++ )
    {
        switch( GetItem( ii )->m_Type )
        {
        case NET_PIN:
        case NET_SHEETLABEL:
        case NET_SEGMENT:
        case NET_JUNCTION:
        case NET_BUS:
        case NET_NOCONNECT:
            break;

        case NET_LABEL:
        case NET_GLOBLABEL:
        case NET_PINLABEL:
        case NET_BUSLABELMEMBER:
        case NET_GLOBBUSLABELMEMBER:
            labelConnect( GetItem( ii ) );
            break;

        case NET_SHEETBUSLABELMEMBER:
        case NET_HIERLABEL:
        case NET_HIERBUSLABELMEMBER:
            break;

        case NET_ITEM_UNSPECIFIED:
            break;
        }
    }

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter sheet global\n\n";
    DumpNetTable();
#endif

    // Connection between hierarchy sheets
    for( unsigned ii = 0; ii < size(); ii++ )
    {
        if( GetItem( ii )->m_Type == NET_SHEETLABEL
            || GetItem( ii )->m_Type == NET_SHEETBUSLABELMEMBER )
            sheetLabelConnect( GetItem( ii ) );
    }

    // Sort objects by NetCode
    SortListbyNetcode();

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter qsort()\n";
    DumpNetTable();
#endif

    /* Compress numbers of Netcode having consecutive values. */
    int NetCode = 0;
    m_lastNetCode = 0;

    for( unsigned ii = 0; ii < size(); ii++ )
    {
        if( GetItem( ii )->GetNet() != m_lastNetCode )
        {
            NetCode++;
            m_lastNetCode = GetItem( ii )->GetNet();
        }

        GetItem( ii )->SetNet( NetCode );
    }

    // Set the minimal connection info:
    setUnconnectedFlag();

    // find the best label object to give the best net name to each net
    findBestNetNameForEachNet();

    return true;
}
コード例 #10
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 ) );
        }
    }
}