Sort nets in netlist by name; generate ordered net codes

This commit is contained in:
Jon Evans 2020-01-18 12:57:02 -05:00
parent ef00fa6008
commit 41725e6b07
4 changed files with 68 additions and 37 deletions

View File

@ -954,7 +954,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
subgraph->AddItem( pin ); subgraph->AddItem( pin );
subgraph->ResolveDrivers(); subgraph->ResolveDrivers();
m_net_code_to_subgraphs_map[ code ].push_back( subgraph ); auto key = std::make_pair( subgraph->GetNetName(), code );
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
m_subgraphs.push_back( subgraph ); m_subgraphs.push_back( subgraph );
m_driver_subgraphs.push_back( subgraph ); m_driver_subgraphs.push_back( subgraph );
@ -1409,8 +1410,9 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( subgraph->m_driver_connection->IsBus() ) if( subgraph->m_driver_connection->IsBus() )
continue; continue;
int code = subgraph->m_driver_connection->NetCode(); auto key = std::make_pair( subgraph->GetNetName(),
m_net_code_to_subgraphs_map[ code ].push_back( subgraph ); subgraph->m_driver_connection->NetCode() );
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
} }
// Clean up and deallocate stale subgraphs // Clean up and deallocate stale subgraphs

View File

@ -198,6 +198,11 @@ public:
CONNECTION_SUBGRAPH* m_hier_parent; CONNECTION_SUBGRAPH* m_hier_parent;
}; };
/// Associates a net code with the final name of a net
typedef std::pair<wxString, int> NET_NAME_CODE;
/// Associates a NET_CODE_NAME with all the subgraphs in that net
typedef std::map<NET_NAME_CODE, std::vector<CONNECTION_SUBGRAPH*>> NET_MAP;
/** /**
* Calculates the connectivity of a schematic and generates netlists * Calculates the connectivity of a schematic and generates netlists
@ -255,12 +260,11 @@ public:
*/ */
int RunERC( const ERC_SETTINGS& aSettings, bool aCreateMarkers = true ); int RunERC( const ERC_SETTINGS& aSettings, bool aCreateMarkers = true );
const NET_MAP& GetNetMap() const { return m_net_code_to_subgraphs_map; }
// TODO(JE) Remove this when pressure valve is removed // TODO(JE) Remove this when pressure valve is removed
static bool m_allowRealTime; static bool m_allowRealTime;
// TODO(JE) firm up API and move to private
std::map<int, std::vector<CONNECTION_SUBGRAPH*> > m_net_code_to_subgraphs_map;
private: private:
std::unordered_set<SCH_ITEM*> m_items; std::unordered_set<SCH_ITEM*> m_items;
@ -291,6 +295,8 @@ private:
std::unordered_map<wxString, std::unordered_map<wxString,
std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map; std::vector<CONNECTION_SUBGRAPH*>> m_net_name_to_subgraphs_map;
NET_MAP m_net_code_to_subgraphs_map;
int m_last_net_code; int m_last_net_code;
int m_last_bus_code; int m_last_bus_code;

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 1992-2013 jp.charras at wanadoo.fr
* Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2013-2017 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -503,57 +503,75 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
if( aUseGraph ) if( aUseGraph )
{ {
wxASSERT( m_graph ); wxASSERT( m_graph );
int code = 0;
for( const auto& it : m_graph->m_net_code_to_subgraphs_map ) for( const auto& it : m_graph->GetNetMap() )
{ {
bool added = false; bool added = false;
wxString net_name = it.first.first;
auto subgraphs = it.second;
auto code = it.first; // Code starts at 1
auto subgraphs = it.second; code++;
auto net_name = subgraphs[0]->GetNetName();
XNODE* xnode; XNODE* xnode;
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
for( auto subgraph : subgraphs ) for( auto subgraph : subgraphs )
{ {
auto sheet = subgraph->m_sheet; auto sheet = subgraph->m_sheet;
for( auto item : subgraph->m_items ) for( auto item : subgraph->m_items )
{
if( item->Type() == SCH_PIN_T ) if( item->Type() == SCH_PIN_T )
{ sorted_items.emplace_back(
auto pin = static_cast<SCH_PIN*>( item ); std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
}
auto refText = pin->GetParentComponent()->GetRef( &sheet ); // Netlist ordering: Net name, then ref des, then pin name
const auto& pinText = pin->GetNumber(); std::sort( sorted_items.begin(), sorted_items.end(), []( auto a, auto b ) {
auto ref_a = a.first->GetParentComponent()->GetRef( &a.second );
auto ref_b = b.first->GetParentComponent()->GetRef( &b.second );
// Skip power symbols and virtual components if( ref_a == ref_b )
if( refText[0] == wxChar( '#' ) ) return a.first->GetNumber() < b.first->GetNumber();
continue;
if( !added ) return ref_a < ref_b;
{ } );
xnets->AddChild( xnet = node( "net" ) );
netCodeTxt.Printf( "%d", code );
xnet->AddAttribute( "code", netCodeTxt );
xnet->AddAttribute( "name", net_name );
added = true; for( const auto& pair : sorted_items )
} {
SCH_PIN* pin = pair.first;
SCH_SHEET_PATH sheet = pair.second;
xnet->AddChild( xnode = node( "node" ) ); auto refText = pin->GetParentComponent()->GetRef( &sheet );
xnode->AddAttribute( "ref", refText ); const auto& pinText = pin->GetNumber();
xnode->AddAttribute( "pin", pinText );
wxString pinName; // Skip power symbols and virtual components
if( refText[0] == wxChar( '#' ) )
continue;
if( pin->GetName() != "~" ) // ~ is a char used to code empty strings in libs. if( !added )
pinName = pin->GetName(); {
xnets->AddChild( xnet = node( "net" ) );
netCodeTxt.Printf( "%d", code );
xnet->AddAttribute( "code", netCodeTxt );
xnet->AddAttribute( "name", net_name );
if( !pinName.IsEmpty() ) added = true;
xnode->AddAttribute( "pinfunction", pinName );
}
} }
xnet->AddChild( xnode = node( "node" ) );
xnode->AddAttribute( "ref", refText );
xnode->AddAttribute( "pin", pinText );
wxString pinName;
if( pin->GetName() != "~" ) // ~ is a char used to code empty strings in libs.
pinName = pin->GetName();
if( !pinName.IsEmpty() )
xnode->AddAttribute( "pinfunction", pinName );
} }
} }
} }

View File

@ -319,11 +319,16 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), UnescapeString( Name() ), BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), UnescapeString( Name() ), BROWN ) );
// NOTE(JE) Disabling this for now, because net codes are generated in the netlist exporter
// in order to avoid sort costs. It may make sense to just tear out net codes from the
// CONNECTION_GRAPH entirely in the future, as they are mostly only useful for netlist exports.
#if 0
if( !IsBus() ) if( !IsBus() )
{ {
msg.Printf( "%d", m_net_code ); msg.Printf( "%d", m_net_code );
aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), msg, BROWN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), msg, BROWN ) );
} }
#endif
if( auto alias = g_ConnectionGraph->GetBusAlias( m_name ) ) if( auto alias = g_ConnectionGraph->GetBusAlias( m_name ) )
{ {