Overhaul connectivity neighbor and global connection processing

This commit is contained in:
Jon Evans 2019-04-19 21:45:33 -04:00
parent 223e24f423
commit e2c12d8c25
6 changed files with 641 additions and 616 deletions

File diff suppressed because it is too large Load Diff

View File

@ -35,17 +35,15 @@
// #define CONNECTIVITY_DEBUG // #define CONNECTIVITY_DEBUG
#endif #endif
// Uncomment this line to enable real-time connectivity updates
// TODO(JE) re-enable this once performance concerns are sorted out
// #define CONNECTIVITY_REAL_TIME
class SCH_PIN;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
class SCH_HIERLABEL;
class SCH_PIN;
class SCH_SHEET_PIN;
/** /**
* A subgraph is a set of items that are "physically" connected in the schematic. * A subgraph is a set of items that are electrically connected on a single sheet.
* *
* For example, a label connected to a wire and so on. * For example, a label connected to a wire and so on.
* A net is composed of one or more subgraphs. * A net is composed of one or more subgraphs.
@ -61,7 +59,7 @@ class CONNECTION_SUBGRAPH
{ {
public: public:
CONNECTION_SUBGRAPH( SCH_EDIT_FRAME* aFrame ) : CONNECTION_SUBGRAPH( SCH_EDIT_FRAME* aFrame ) :
m_dirty( false ), m_code( -1 ), m_multiple_drivers( false ), m_dirty( false ), m_absorbed( false ), m_code( -1 ), m_multiple_drivers( false ),
m_strong_driver( false ), m_no_connect( nullptr ), m_bus_entry( nullptr ), m_strong_driver( false ), m_no_connect( nullptr ), m_bus_entry( nullptr ),
m_driver( nullptr ), m_frame( aFrame ), m_driver_connection( nullptr ) m_driver( nullptr ), m_frame( aFrame ), m_driver_connection( nullptr )
{} {}
@ -79,16 +77,27 @@ public:
/** /**
* Returns the fully-qualified net name for this subgraph (if one exists) * Returns the fully-qualified net name for this subgraph (if one exists)
*/ */
wxString GetNetName(); wxString GetNetName() const;
/// Returns all the bus labels attached to this subgraph (if any) /// Returns all the bus labels attached to this subgraph (if any)
std::vector<SCH_ITEM*> GetBusLabels(); std::vector<SCH_ITEM*> GetBusLabels() const;
// Returns the candidate net name for a driver /// Returns the candidate net name for a driver
wxString GetNameForDriver( SCH_ITEM* aItem ); wxString GetNameForDriver( SCH_ITEM* aItem ) const;
/// Combines another subgraph on the same sheet into this one.
void Absorb( CONNECTION_SUBGRAPH* aOther );
/// Adds a new item to the subgraph
void AddItem( SCH_ITEM* aItem );
/// Updates all items to match the driver connection
void UpdateItemConnections();
bool m_dirty; bool m_dirty;
bool m_absorbed;
long m_code; long m_code;
/** /**
@ -125,16 +134,21 @@ public:
SCH_CONNECTION* m_driver_connection; SCH_CONNECTION* m_driver_connection;
/** /**
* This map stores pointers to other subgraphs on the same sheet as this one * If a subgraph is a bus, this map contains links between the bus members and any
* which should be connected to this one. * local sheet neighbors with the same connection name.
* *
* For example, if this subgraph is part of the bus D[7..0] and there is * For example, if this subgraph is a bus D[7..0], and on the same sheet there is
* another subgraph on this sheet with connection D7, this map will include * a net with label D7, this map will contain an entry for the D7 bus member, and
* a pointer to that subgraph under the key D7 (where the key comes from * the vector will contain a pointer to the D7 net subgraph.
* the m_members list of the SCH_CONNECTION that drives this subgraph)
*/ */
std::unordered_map< std::shared_ptr<SCH_CONNECTION>, std::unordered_map< std::shared_ptr<SCH_CONNECTION>,
std::vector<CONNECTION_SUBGRAPH*> > m_neighbor_map; std::vector<CONNECTION_SUBGRAPH*> > m_bus_neighbors;
// Cache for lookup of any hierarchical (sheet) pins on this subgraph (for referring down)
std::vector<SCH_SHEET_PIN*> m_hier_pins;
// Cache for lookup of any hierarchical ports on this subgraph (for referring up)
std::vector<SCH_HIERLABEL*> m_hier_ports;
}; };
@ -173,7 +187,7 @@ public:
* @return a list of subgraphs that need migration * @return a list of subgraphs that need migration
*/ */
std::vector<CONNECTION_SUBGRAPH*> GetBusesNeedingMigration(); std::vector<const CONNECTION_SUBGRAPH*> GetBusesNeedingMigration();
/** /**
* Returns true if the graph makes use of any of the new bus features * Returns true if the graph makes use of any of the new bus features
@ -204,7 +218,7 @@ private:
std::vector<CONNECTION_SUBGRAPH*> m_subgraphs; std::vector<CONNECTION_SUBGRAPH*> m_subgraphs;
std::vector<SCH_PIN*> m_invisible_power_pins; std::vector<std::pair<SCH_SHEET_PATH, SCH_PIN*>> m_invisible_power_pins;
std::unordered_map< wxString, std::shared_ptr<BUS_ALIAS> > m_bus_alias_cache; std::unordered_map< wxString, std::shared_ptr<BUS_ALIAS> > m_bus_alias_cache;
@ -212,10 +226,10 @@ private:
std::map<wxString, int> m_bus_name_to_code_map; std::map<wxString, int> m_bus_name_to_code_map;
std::map<wxString, std::vector<CONNECTION_SUBGRAPH*>> m_global_label_cache; std::map<wxString, std::vector<const CONNECTION_SUBGRAPH*>> m_global_label_cache;
std::map< std::pair<SCH_SHEET_PATH, wxString>, std::map< std::pair<SCH_SHEET_PATH, wxString>,
std::vector<CONNECTION_SUBGRAPH*> > m_local_label_cache; std::vector<const CONNECTION_SUBGRAPH*> > m_local_label_cache;
int m_last_net_code; int m_last_net_code;
@ -280,6 +294,20 @@ private:
*/ */
int assignNewNetCode( SCH_CONNECTION& aConnection ); int assignNewNetCode( SCH_CONNECTION& aConnection );
/**
* Ensures all members of the bus connection have a valid net code assigned
* @param aConnection is a bus connection
*/
void assignNetCodesToBus( SCH_CONNECTION* aConnection );
/**
* Updates all neighbors of a subgraph with this one's connectivity info
*
* If this subgraph contains hierarchical links, this method will descent the
* hierarchy and propagate the connectivity across all linked sheets.
*/
void propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph );
/** /**
* Checks one subgraph for conflicting connections between net and bus labels * Checks one subgraph for conflicting connections between net and bus labels
* *
@ -289,7 +317,7 @@ private:
* @param aCreateMarkers controls whether error markers are created * @param aCreateMarkers controls whether error markers are created
* @return true for no errors, false for errors * @return true for no errors, false for errors
*/ */
bool ercCheckBusToNetConflicts( CONNECTION_SUBGRAPH* aSubgraph, bool ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSubgraph,
bool aCreateMarkers ); bool aCreateMarkers );
/** /**
@ -303,7 +331,7 @@ private:
* @param aCreateMarkers controls whether error markers are created * @param aCreateMarkers controls whether error markers are created
* @return true for no errors, false for errors * @return true for no errors, false for errors
*/ */
bool ercCheckBusToBusConflicts( CONNECTION_SUBGRAPH* aSubgraph, bool ercCheckBusToBusConflicts( const CONNECTION_SUBGRAPH* aSubgraph,
bool aCreateMarkers ); bool aCreateMarkers );
/** /**
@ -319,7 +347,7 @@ private:
* @param aCreateMarkers controls whether error markers are created * @param aCreateMarkers controls whether error markers are created
* @return true for no errors, false for errors * @return true for no errors, false for errors
*/ */
bool ercCheckBusToBusEntryConflicts( CONNECTION_SUBGRAPH* aSubgraph, bool ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH* aSubgraph,
bool aCreateMarkers ); bool aCreateMarkers );
/** /**
@ -332,7 +360,7 @@ private:
* @param aCreateMarkers controls whether error markers are created * @param aCreateMarkers controls whether error markers are created
* @return true for no errors, false for errors * @return true for no errors, false for errors
*/ */
bool ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph, bool ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph,
bool aCreateMarkers ); bool aCreateMarkers );
/** /**
@ -344,9 +372,9 @@ private:
* @param aCreateMarkers controls whether error markers are created * @param aCreateMarkers controls whether error markers are created
* @return true for no errors, false for errors * @return true for no errors, false for errors
*/ */
bool ercCheckLabels( CONNECTION_SUBGRAPH* aSubgraph, bool aCreateMarkers ); bool ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph, bool aCreateMarkers );
void ercReportIsolatedGlobalLabel( CONNECTION_SUBGRAPH* aSubgraph, SCH_ITEM* aLabel ); void ercReportIsolatedGlobalLabel( const CONNECTION_SUBGRAPH* aSubgraph, SCH_ITEM* aLabel );
}; };
#endif #endif

View File

@ -32,7 +32,7 @@ class CONNECTION_SUBGRAPH;
struct BUS_MIGRATION_STATUS struct BUS_MIGRATION_STATUS
{ {
CONNECTION_SUBGRAPH* subgraph; const CONNECTION_SUBGRAPH* subgraph;
std::vector<wxString> labels; std::vector<wxString> labels;

View File

@ -124,7 +124,8 @@ void SCH_CONNECTION::ConfigureFromLabel( wxString aLabel )
wxString name = m_vector_prefix; wxString name = m_vector_prefix;
name << i; name << i;
member->m_type = CONNECTION_NET; member->m_type = CONNECTION_NET;
member->m_name = m_prefix + name; member->m_prefix = m_prefix;
member->m_name = name;
member->m_vector_index = i; member->m_vector_index = i;
m_members.push_back( member ); m_members.push_back( member );
} }
@ -140,14 +141,14 @@ void SCH_CONNECTION::ConfigureFromLabel( wxString aLabel )
if( ParseBusGroup( aLabel, &group_name, members ) ) if( ParseBusGroup( aLabel, &group_name, members ) )
{ {
// Named bus groups generate a net prefix, unnamed ones don't // Named bus groups generate a net prefix, unnamed ones don't
auto prefix = ( group_name != "" ) ? ( group_name + "." ) : ""; wxString prefix = group_name != wxT( "" ) ? ( group_name + wxT( "." ) ) : wxT( "" );
for( auto group_member : members ) for( const auto& group_member : members )
{ {
// Handle alias inside bus group member list // Handle alias inside bus group member list
if( auto alias = g_ConnectionGraph->GetBusAlias( group_member ) ) if( auto alias = g_ConnectionGraph->GetBusAlias( group_member ) )
{ {
for( auto alias_member : alias->Members() ) for( const auto& alias_member : alias->Members() )
{ {
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet ); auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet );
member->SetPrefix( prefix ); member->SetPrefix( prefix );
@ -179,7 +180,7 @@ void SCH_CONNECTION::ConfigureFromLabel( wxString aLabel )
} }
else else
{ {
m_name = m_prefix + aLabel; m_name = aLabel;
m_type = CONNECTION_NET; m_type = CONNECTION_NET;
} }
} }
@ -209,7 +210,7 @@ void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther )
m_type = aOther.Type(); m_type = aOther.Type();
m_driver = aOther.Driver(); m_driver = aOther.Driver();
m_sheet = aOther.Sheet(); m_sheet = aOther.Sheet();
m_name = aOther.Name( true ); m_name = aOther.m_name;
m_prefix = aOther.Prefix(); m_prefix = aOther.Prefix();
// Don't clone suffix, it will be rolled into the name // Don't clone suffix, it will be rolled into the name
//m_suffix = aOther.Suffix(); //m_suffix = aOther.Suffix();
@ -247,7 +248,7 @@ bool SCH_CONNECTION::IsDriver() const
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
{ {
wxString ret = m_name + m_suffix; wxString ret = m_prefix + m_name + m_suffix;
if( !Parent() || m_type == CONNECTION_NONE ) if( !Parent() || m_type == CONNECTION_NONE )
return ret; return ret;

View File

@ -147,6 +147,16 @@ public:
wxString Name( bool aIgnoreSheet = false ) const; wxString Name( bool aIgnoreSheet = false ) const;
wxString RawName() const
{
return m_name;
}
void SetName( const wxString& aName )
{
m_name = aName;
}
wxString Prefix() const wxString Prefix() const
{ {
return m_prefix; return m_prefix;
@ -157,12 +167,12 @@ public:
return m_suffix; return m_suffix;
} }
void SetPrefix( wxString aPrefix ) void SetPrefix( const wxString& aPrefix )
{ {
m_prefix = aPrefix; m_prefix = aPrefix;
} }
void SetSuffix( wxString aSuffix ) void SetSuffix( const wxString& aSuffix )
{ {
m_suffix = aSuffix; m_suffix = aSuffix;
} }

View File

@ -31,15 +31,16 @@
#define SCH_ITEM_STRUCT_H #define SCH_ITEM_STRUCT_H
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include <base_screen.h> #include <base_screen.h>
#include <general.h> #include <general.h>
#include <sch_connection.h>
#include <sch_sheet_path.h> #include <sch_sheet_path.h>
class SCH_ITEM; class SCH_ITEM;
//class SCH_SHEET_PATH; //class SCH_SHEET_PATH;
class SCH_CONNECTION;
class LINE_READER; class LINE_READER;
class SCH_EDIT_FRAME; class SCH_EDIT_FRAME;
class wxFindReplaceData; class wxFindReplaceData;