Promote locally-labeled nets to global when tied to global buses

Fixes: lp:1822964
* https://bugs.launchpad.net/kicad/+bug/1822964
This commit is contained in:
Jon Evans 2019-04-03 21:47:26 -04:00
parent ce254d1061
commit d5990100e1
2 changed files with 88 additions and 12 deletions

View File

@ -538,17 +538,12 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( connection->IsDriver() )
subgraph->m_drivers.push_back( item );
if( item->Type() == SCH_NO_CONNECT_T )
{
subgraph->m_no_connect = item;
}
else if( item->Type() == SCH_PIN_T )
connection->SetSubgraphCode( subgraph->m_code );
if( item->Type() == SCH_PIN_T )
{
auto pin = static_cast<SCH_PIN*>( item );
if( pin->GetType() == PIN_NC )
subgraph->m_no_connect = item;
// Invisible power pins need to be post-processed later
if( pin->IsPowerConnection() && !pin->IsVisible() )
@ -557,8 +552,6 @@ void CONNECTION_GRAPH::buildConnectionGraph()
}
}
connection->SetSubgraphCode( subgraph->m_code );
std::list<SCH_ITEM*> members( item->ConnectedItems().begin(),
item->ConnectedItems().end() );
@ -633,6 +626,34 @@ void CONNECTION_GRAPH::buildConnectionGraph()
if( !subgraph->m_dirty )
continue;
// Special processing for some items
for( auto item : subgraph->m_items )
{
switch( item->Type() )
{
case SCH_NO_CONNECT_T:
subgraph->m_no_connect = item;
break;
case SCH_BUS_WIRE_ENTRY_T:
subgraph->m_bus_entry = item;
break;
case SCH_PIN_T:
{
auto pin = static_cast<SCH_PIN*>( item );
if( pin->GetType() == PIN_NC )
subgraph->m_no_connect = item;
break;
}
default:
break;
}
}
if( !subgraph->ResolveDrivers() )
{
subgraph->m_dirty = false;
@ -1041,6 +1062,58 @@ void CONNECTION_GRAPH::buildConnectionGraph()
}
}
// Promote local nets connected to a globally-labeled bus to global
if( subgraph->m_bus_entry && connection->IsNet() )
{
auto be = static_cast<SCH_BUS_WIRE_ENTRY*>( subgraph->m_bus_entry );
if( be->m_connected_bus_item )
{
auto bus_conn = be->m_connected_bus_item->Connection( sheet );
if( bus_conn->Driver() &&
bus_conn->Driver()->Type() == SCH_GLOBAL_LABEL_T )
{
wxLogTrace( "CONN", "Net %s connected to global bus %s",
connection->Name(), bus_conn->Name() );
std::shared_ptr<SCH_CONNECTION> parent;
for( auto member : bus_conn->Members() )
{
if( member->IsNet() &&
member->Name( true ) == connection->Name( true ) )
{
if( member->NetCode() == 0 )
assignNewNetCode( *member );
parent = member;
}
}
if( parent && ( parent->Name() != connection->Name() ) )
{
wxLogTrace( "CONN", "Promoting %s to %s", connection->Name(),
parent->Name() );
connection->Clone( *parent );
for( auto item : subgraph->m_items )
{
auto item_conn = item->Connection( sheet );
item_conn->Clone( *connection );
}
}
else
{
wxLogTrace( "CONN", "Could not find matching parent for %s!",
connection->Name() );
}
}
}
}
/**
* Is this bus in the highest level of hierarchy? That is, does it
* contain no hierarchical ports to parent sheets? If so, we process it

View File

@ -62,8 +62,8 @@ class CONNECTION_SUBGRAPH
public:
CONNECTION_SUBGRAPH( SCH_EDIT_FRAME* aFrame ) :
m_dirty( false ), m_code( -1 ), m_multiple_power_ports( false ),
m_strong_driver( false ), m_no_connect( nullptr ), m_driver( nullptr ),
m_frame( aFrame ), m_driver_connection( nullptr )
m_strong_driver( false ), m_no_connect( nullptr ), m_bus_entry( nullptr ),
m_driver( nullptr ), m_frame( aFrame ), m_driver_connection( nullptr )
{}
/**
* Determines which potential driver should drive the subgraph.
@ -97,6 +97,9 @@ public:
/// No-connect item in graph, if any
SCH_ITEM* m_no_connect;
/// Bus entry in graph, if any
SCH_ITEM* m_bus_entry;
std::vector<SCH_ITEM*> m_items;
std::vector<SCH_ITEM*> m_drivers;