Fix a few issues with hierarchical propagation
This commit is contained in:
parent
3c714f1d8c
commit
e98debfeb2
|
@ -50,6 +50,13 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
|||
|
||||
m_driver = nullptr;
|
||||
|
||||
// Hierarchical labels are lower priority than local labels here,
|
||||
// because on the first pass we want local labels to drive subgraphs
|
||||
// so that we can identify same-sheet neighbors and link them together.
|
||||
// Hierarchical labels will end up overriding the final net name if
|
||||
// a higher-level sheet has a different name during the hierarchical
|
||||
// pass.
|
||||
|
||||
for( auto item : m_drivers )
|
||||
{
|
||||
int item_priority = 0;
|
||||
|
@ -57,8 +64,8 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
|||
switch( item->Type() )
|
||||
{
|
||||
case SCH_SHEET_PIN_T: item_priority = 2; break;
|
||||
case SCH_LABEL_T: item_priority = 3; break;
|
||||
case SCH_HIERARCHICAL_LABEL_T: item_priority = 4; break;
|
||||
case SCH_HIERARCHICAL_LABEL_T: item_priority = 3; break;
|
||||
case SCH_LABEL_T: item_priority = 4; break;
|
||||
case SCH_PIN_CONNECTION_T:
|
||||
{
|
||||
auto pin_connection = static_cast<SCH_PIN_CONNECTION*>( item );
|
||||
|
@ -90,6 +97,9 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
|||
}
|
||||
}
|
||||
|
||||
if( highest_priority >= 4 )
|
||||
m_strong_driver = true;
|
||||
|
||||
if( candidates.size() )
|
||||
{
|
||||
if( candidates.size() > 1 )
|
||||
|
@ -109,8 +119,26 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
|
|||
return name_a < name_b;
|
||||
} );
|
||||
}
|
||||
|
||||
if( highest_priority == 2 )
|
||||
{
|
||||
// We have multiple options, and they are all hierarchical
|
||||
// sheet pins. Let's prefer outputs over inputs.
|
||||
|
||||
for( auto c : candidates )
|
||||
{
|
||||
auto p = static_cast<SCH_SHEET_PIN*>( c );
|
||||
|
||||
if( p->GetShape() == NET_OUTPUT )
|
||||
{
|
||||
m_driver = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_driver )
|
||||
m_driver = candidates[0];
|
||||
}
|
||||
|
||||
|
@ -641,6 +669,56 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
while( threadsFinished < parallelThreadCount )
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
|
||||
|
||||
// Check for subgraphs with the same net name but only weak drivers.
|
||||
// For example, two wires that are both connected to hierarchical
|
||||
// sheet pins that happen to have the same name, but are not the same.
|
||||
|
||||
for( auto subgraph : m_subgraphs )
|
||||
subgraph->m_dirty = true;
|
||||
|
||||
for( auto subgraph : m_subgraphs )
|
||||
{
|
||||
if( !subgraph->m_dirty )
|
||||
continue;
|
||||
|
||||
subgraph->m_dirty = false;
|
||||
|
||||
if( !subgraph->m_driver || subgraph->m_strong_driver )
|
||||
continue;
|
||||
|
||||
auto name = subgraph->m_driver->Connection( subgraph->m_sheet )->Name();
|
||||
|
||||
unsigned suffix = 1;
|
||||
|
||||
for( auto candidate : m_subgraphs )
|
||||
{
|
||||
if( !candidate->m_dirty )
|
||||
continue;
|
||||
|
||||
if( candidate == subgraph || !candidate->m_driver || candidate->m_strong_driver )
|
||||
continue;
|
||||
|
||||
auto conn = candidate->m_driver->Connection( candidate->m_sheet );
|
||||
auto check_name = conn->Name();
|
||||
|
||||
if( check_name == name )
|
||||
{
|
||||
auto new_name = wxString::Format( _( "%s%u" ), name, suffix );
|
||||
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Subgraph %ld and %ld both have name %s. Changing %ld to %s.",
|
||||
subgraph->m_code, candidate->m_code, name,
|
||||
candidate->m_code, new_name );
|
||||
#endif
|
||||
|
||||
conn->SetSuffix( wxString::Format( _( "%u" ), suffix ) );
|
||||
|
||||
candidate->m_dirty = false;
|
||||
suffix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate net codes
|
||||
|
||||
for( auto subgraph : m_subgraphs )
|
||||
|
@ -721,6 +799,10 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
connections_to_check.push_back( std::make_shared<SCH_CONNECTION>( *connection ) );
|
||||
}
|
||||
|
||||
// Look for "neighbors" for subgraphs that have hierarchical connections.
|
||||
// These are usually other subgraphs that have local labels on the
|
||||
// same sheet and so should be connected together.
|
||||
|
||||
for( unsigned i = 0; i < connections_to_check.size(); i++ )
|
||||
{
|
||||
auto member = connections_to_check[i];
|
||||
|
@ -984,15 +1066,31 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
* 3) Recurse down onto any subsheets connected to the SSSG.
|
||||
*/
|
||||
|
||||
for( auto item : subgraph->m_items )
|
||||
std::vector<CONNECTION_SUBGRAPH*> child_subgraphs;
|
||||
|
||||
child_subgraphs.push_back( subgraph );
|
||||
|
||||
for( unsigned i = 0; i < child_subgraphs.size(); i++ )
|
||||
{
|
||||
// child_subgraphs[i] now refers to the "parent" subgraph that we
|
||||
// are descending the hierarchy with. If there are multiple levels
|
||||
// of hierarchy, those will get pushed onto child_subgraphs below.
|
||||
|
||||
for( auto item : child_subgraphs[i]->m_items )
|
||||
{
|
||||
if( item->Type() == SCH_SHEET_PIN_T )
|
||||
{
|
||||
auto sp = static_cast<SCH_SHEET_PIN*>( item );
|
||||
auto sp_name = sp->GetText();
|
||||
auto subsheet = sheet;
|
||||
auto subsheet = child_subgraphs[i]->m_sheet;
|
||||
subsheet.push_back( sp->GetParent() );
|
||||
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( wxT("Propagating sheet pin %s on %s with connection %s to subsheet %s"),
|
||||
sp_name, child_subgraphs[i]->m_sheet.PathHumanReadable(),
|
||||
connection->Name(), subsheet.PathHumanReadable() );
|
||||
#endif
|
||||
|
||||
for( auto candidate : m_subgraphs )
|
||||
{
|
||||
if( !candidate->m_dirty )
|
||||
|
@ -1000,22 +1098,37 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
|
||||
if( candidate->m_sheet == subsheet && candidate->m_driver )
|
||||
{
|
||||
auto driver = candidate->m_driver;
|
||||
SCH_ITEM* hier_label = nullptr;
|
||||
|
||||
if( ( driver->Type() == SCH_HIERARCHICAL_LABEL_T ) &&
|
||||
( static_cast<SCH_HIERLABEL*>( driver )->GetText() == sp_name ) )
|
||||
for( auto d : candidate->m_drivers )
|
||||
{
|
||||
if( ( d->Type() == SCH_HIERARCHICAL_LABEL_T ) &&
|
||||
( static_cast<SCH_HIERLABEL*>( d )->GetText() == sp_name ) )
|
||||
hier_label = d;
|
||||
}
|
||||
|
||||
if( hier_label )
|
||||
{
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Found child %s", static_cast<SCH_HIERLABEL*>( hier_label )->GetText() );
|
||||
#endif
|
||||
|
||||
// We found a subgraph that is a subsheet child of
|
||||
// our top-level subgraph, so let's mark it
|
||||
|
||||
candidate->m_dirty = false;
|
||||
|
||||
auto type = driver->Connection( subsheet )->Type();
|
||||
auto type = hier_label->Connection( subsheet )->Type();
|
||||
|
||||
bool candidate_has_sheet_pins = false;
|
||||
|
||||
// Directly update subsheet net connections
|
||||
|
||||
for( auto c_item : candidate->m_items )
|
||||
{
|
||||
if( c_item->Type() == SCH_SHEET_PIN_T )
|
||||
candidate_has_sheet_pins = true;
|
||||
|
||||
auto c = c_item->Connection( subsheet );
|
||||
|
||||
wxASSERT( c );
|
||||
|
@ -1035,6 +1148,11 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
auto member = kv.first;
|
||||
std::shared_ptr<SCH_CONNECTION> top_level_conn;
|
||||
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Found child neighbor from member %s",
|
||||
member->Name() );
|
||||
#endif
|
||||
|
||||
if( type == CONNECTION_BUS_GROUP )
|
||||
{
|
||||
// Bus group: match parent by name
|
||||
|
@ -1079,6 +1197,13 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
|
||||
for( auto neighbor : kv.second )
|
||||
{
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Propagating to neighbor driven by %s",
|
||||
neighbor->m_driver->GetSelectMenuText( MILLIMETRES ) );
|
||||
#endif
|
||||
|
||||
bool neighbor_has_sheet_pins = false;
|
||||
|
||||
for( auto n_item : neighbor->m_items )
|
||||
{
|
||||
auto c = n_item->Connection( subsheet );
|
||||
|
@ -1086,7 +1211,31 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
wxASSERT( c );
|
||||
|
||||
c->Clone( *top_level_conn );
|
||||
|
||||
if( n_item->Type() == SCH_SHEET_PIN_T )
|
||||
neighbor_has_sheet_pins = true;
|
||||
}
|
||||
|
||||
if( neighbor_has_sheet_pins )
|
||||
{
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Neighbor driven by %s has subsheet pins",
|
||||
neighbor->m_driver->GetSelectMenuText( MILLIMETRES ) );
|
||||
#endif
|
||||
child_subgraphs.push_back( neighbor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, check to see if the candidate also has
|
||||
// sheet pin members. If so, add to the queue.
|
||||
if( candidate_has_sheet_pins)
|
||||
{
|
||||
#ifdef CONNECTIVITY_DEBUG
|
||||
wxLogDebug( "Candidate %s has subsheet pins",
|
||||
candidate->m_driver->GetSelectMenuText( MILLIMETRES ) );
|
||||
#endif
|
||||
child_subgraphs.push_back( candidate );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,9 @@ public:
|
|||
/// True if this subgraph contains multiple power ports to join in one net
|
||||
bool m_multiple_power_ports;
|
||||
|
||||
/// True if the driver is "strong": a label or power object
|
||||
bool m_strong_driver;
|
||||
|
||||
/// No-connect item in graph, if any
|
||||
SCH_ITEM* m_no_connect;
|
||||
|
||||
|
|
|
@ -188,6 +188,7 @@ void SCH_CONNECTION::Reset()
|
|||
m_type = CONNECTION_NONE;
|
||||
m_name = "<NO NET>";
|
||||
m_prefix = "";
|
||||
m_suffix = "";
|
||||
m_driver = nullptr;
|
||||
m_members.clear();
|
||||
m_dirty = true;
|
||||
|
@ -208,6 +209,8 @@ void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther )
|
|||
m_sheet = aOther.Sheet();
|
||||
m_name = aOther.Name( true );
|
||||
m_prefix = aOther.Prefix();
|
||||
// Don't clone suffix, it will be rolled into the name
|
||||
//m_suffix = aOther.Suffix();
|
||||
m_members = aOther.Members();
|
||||
m_net_code = aOther.NetCode();
|
||||
m_bus_code = aOther.BusCode();
|
||||
|
@ -242,7 +245,7 @@ bool SCH_CONNECTION::IsDriver() const
|
|||
|
||||
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
|
||||
{
|
||||
wxString ret = m_name;
|
||||
wxString ret = m_name + m_suffix;
|
||||
|
||||
if( !Parent() || m_type == CONNECTION_NONE )
|
||||
return ret;
|
||||
|
@ -277,7 +280,7 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
|
|||
wxString msg, group_name;
|
||||
std::vector<wxString> group_members;
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), m_name, BROWN ) );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), Name(), BROWN ) );
|
||||
|
||||
msg.Printf( "%d", m_net_code );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), msg, BROWN ) );
|
||||
|
|
|
@ -152,11 +152,21 @@ public:
|
|||
return m_prefix;
|
||||
}
|
||||
|
||||
wxString Suffix() const
|
||||
{
|
||||
return m_suffix;
|
||||
}
|
||||
|
||||
void SetPrefix( wxString aPrefix )
|
||||
{
|
||||
m_prefix = aPrefix;
|
||||
}
|
||||
|
||||
void SetSuffix( wxString aSuffix )
|
||||
{
|
||||
m_suffix = aSuffix;
|
||||
}
|
||||
|
||||
CONNECTION_TYPE Type() const
|
||||
{
|
||||
return m_type;
|
||||
|
@ -318,6 +328,8 @@ private:
|
|||
///< Prefix if connection is member of a labeled bus group (or "" if not)
|
||||
wxString m_prefix;
|
||||
|
||||
wxString m_suffix; ///< Name suffix (used only for disambiguation)
|
||||
|
||||
int m_net_code; // TODO(JE) remove if unused
|
||||
|
||||
int m_bus_code; // TODO(JE) remove if unused
|
||||
|
|
Loading…
Reference in New Issue