Changed the way of looking up NETINFO_ITEM using net names (using boost::unordered_map). Added a hash function (wxString) for that. Introduced NETINFO_ITEM::GetNetItem( wxString ). BOARD::FindNet() uses the map.
Net codes are updated upon net list update. (BOARD::ReplaceNetlist()) Added in some places (mostly class_board.cpp) pad->SetNet() calls to synchronize net codes. On creation of NETINFO_LIST, the first NETINFO_ITEM is added (the unconnected items net). Removed COMPONENT_NET::m_netNumber, as it was not used anywhere. Added an assert to D_PAD::GetNetname(), checking if net code and net name is consistent for unconnected pads. Added an assert for NETINFO_LIST::AppendNet() to assure that appended nets are unique. It seems that at this point: - Updating net lists works fine. The only difference between the file ouput is that after changes it contains empty nets as well. - Nets are not saved in the lexical order. Still, net names and net codes are properly assigned to all items in the .kicad_pcb file. It is going to be addressed in the next commit. I believe it should not create any problems, as pads are sorted by their net names anyway (NETINFO_LIST::buildPadsFullList()) Performed tests: - Created a blank PCB, saved as pic_programmer.kicad_pcb (from demos folder). Updated net lists. .kicad_pcb file (comparing to the results from master branch) differ with net order (as mentioned before), net codes and timestamps. - Removed some of components from the above .kicad_pcb file and updated net lists. Modules reappeared. .kicad_pcb file differs in the same way as described above. - Trying to change a pad net name (via properties dialog) results in assert being fired. It is done on purpose (as there is a call to GetNetname() and net name and net code do not match). This will not happen after the next commit. - Prepared a simple project (starting with schematics). Imported net list, changed schematic, reimported net list - changes are applied. - Eagle & KiCad legacy boards seem to load without any problem.
This commit is contained in:
parent
386d1fc257
commit
bf80cc770e
|
@ -98,6 +98,24 @@ struct fnv_1a
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Hash function for wxString, counterpart of std::string hash
|
||||||
|
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
|
||||||
|
{
|
||||||
|
std::size_t operator()( const wxString& aString ) const
|
||||||
|
{
|
||||||
|
std::size_t hash = 2166136261u;
|
||||||
|
|
||||||
|
for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it )
|
||||||
|
{
|
||||||
|
hash ^= (unsigned char) *it;
|
||||||
|
hash *= 16777619;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type KEYWORD_MAP
|
* Type KEYWORD_MAP
|
||||||
* is a hashtable made of a const char* and an int. Note that use of this
|
* is a hashtable made of a const char* and an int. Note that use of this
|
||||||
|
|
|
@ -1355,79 +1355,7 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
|
||||||
|
|
||||||
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
|
NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
|
||||||
{
|
{
|
||||||
// the first valid netcode is 1.
|
return m_NetInfo.GetNetItem( aNetname );
|
||||||
// zero is reserved for "no connection" and is not used.
|
|
||||||
if( aNetname.IsEmpty() )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int ncount = m_NetInfo.GetNetCount();
|
|
||||||
|
|
||||||
// Search for a netname = aNetname
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// Use a sequential search: easy to understand, but slow
|
|
||||||
for( int ii = 1; ii < ncount; ii++ )
|
|
||||||
{
|
|
||||||
NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii );
|
|
||||||
|
|
||||||
if( item && item->GetNetname() == aNetname )
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Use a fast binary search,
|
|
||||||
// this is possible because Nets are alphabetically ordered in list
|
|
||||||
// see NETINFO_LIST::BuildListOfNets() and
|
|
||||||
// NETINFO_LIST::Build_Pads_Full_List()
|
|
||||||
int imax = ncount - 1;
|
|
||||||
int index = imax;
|
|
||||||
|
|
||||||
while( ncount > 0 )
|
|
||||||
{
|
|
||||||
int ii = ncount;
|
|
||||||
ncount >>= 1;
|
|
||||||
|
|
||||||
if( (ii & 1) && ( ii > 1 ) )
|
|
||||||
ncount++;
|
|
||||||
|
|
||||||
NETINFO_ITEM* item = m_NetInfo.GetNetItem( index );
|
|
||||||
|
|
||||||
if( item == NULL )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int icmp = item->GetNetname().Cmp( aNetname );
|
|
||||||
|
|
||||||
if( icmp == 0 ) // found !
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( icmp < 0 ) // must search after item
|
|
||||||
{
|
|
||||||
index += ncount;
|
|
||||||
|
|
||||||
if( index > imax )
|
|
||||||
index = imax;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( icmp > 0 ) // must search before item
|
|
||||||
{
|
|
||||||
index -= ncount;
|
|
||||||
|
|
||||||
if( index < 1 )
|
|
||||||
index = 1;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2618,7 +2546,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !aNetlist.IsDryRun() )
|
if( !aNetlist.IsDryRun() )
|
||||||
|
{
|
||||||
pad->SetNetname( wxEmptyString );
|
pad->SetNetname( wxEmptyString );
|
||||||
|
pad->SetNet( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Footprint pad has a net.
|
else // Footprint pad has a net.
|
||||||
|
@ -2638,7 +2569,19 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !aNetlist.IsDryRun() )
|
if( !aNetlist.IsDryRun() )
|
||||||
|
{
|
||||||
pad->SetNetname( net.GetNetName() );
|
pad->SetNetname( net.GetNetName() );
|
||||||
|
|
||||||
|
NETINFO_ITEM* netinfo = FindNet( net.GetNetName() );
|
||||||
|
if( netinfo == NULL )
|
||||||
|
{
|
||||||
|
// It is a new net, we have to add it
|
||||||
|
netinfo = new NETINFO_ITEM( this, net.GetNetName(), m_NetInfo.GetNetCount() );
|
||||||
|
m_NetInfo.AppendNet( netinfo );
|
||||||
|
}
|
||||||
|
|
||||||
|
pad->SetNet( netinfo->GetNet() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2711,6 +2654,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
aReporter->Report( msg );
|
aReporter->Report( msg );
|
||||||
}
|
}
|
||||||
previouspad->SetNetname( wxEmptyString );
|
previouspad->SetNetname( wxEmptyString );
|
||||||
|
previouspad->SetNet( 0 );
|
||||||
}
|
}
|
||||||
netname = pad->GetNetname();
|
netname = pad->GetNetname();
|
||||||
count = 1;
|
count = 1;
|
||||||
|
@ -2723,7 +2667,10 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
|
||||||
|
|
||||||
// Examine last pad
|
// Examine last pad
|
||||||
if( pad && count == 1 )
|
if( pad && count == 1 )
|
||||||
|
{
|
||||||
pad->SetNetname( wxEmptyString );
|
pad->SetNetname( wxEmptyString );
|
||||||
|
pad->SetNet( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last step: Some tests:
|
// Last step: Some tests:
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <gr_basic.h>
|
#include <gr_basic.h>
|
||||||
#include <class_netclass.h>
|
#include <class_netclass.h>
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <hashtables.h>
|
||||||
|
|
||||||
|
|
||||||
class wxDC;
|
class wxDC;
|
||||||
|
@ -115,7 +117,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class NETINFO
|
* Class NETINFO
|
||||||
* is a container class for NETINFO_ITEM elements, which are the nets. That makes
|
* is a container class for NETINFO_ITEM elements, which are the nets. That makes
|
||||||
|
@ -141,6 +142,20 @@ public:
|
||||||
return m_NetBuffer[aNetcode];
|
return m_NetBuffer[aNetcode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetItem
|
||||||
|
* @param aNetName = net name to identify a given NETINFO_ITEM
|
||||||
|
* @return NETINFO_ITEM* - by \a aNetName, or NULL if not found
|
||||||
|
*/
|
||||||
|
NETINFO_ITEM* GetNetItem( const wxString& aNetName ) const
|
||||||
|
{
|
||||||
|
NETNAMES_MAP::const_iterator result = m_netNames.find( aNetName );
|
||||||
|
if( result != m_netNames.end() )
|
||||||
|
return (*result).second;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetNetCount
|
* Function GetNetCount
|
||||||
* @return the number of nets ( always >= 1 )
|
* @return the number of nets ( always >= 1 )
|
||||||
|
@ -188,6 +203,8 @@ public:
|
||||||
void Show() const;
|
void Show() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef boost::unordered_map<const wxString, NETINFO_ITEM*, WXSTRING_HASH> NETNAMES_MAP;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,6 +231,7 @@ private:
|
||||||
void buildPadsFullList();
|
void buildPadsFullList();
|
||||||
|
|
||||||
BOARD* m_Parent;
|
BOARD* m_Parent;
|
||||||
|
NETNAMES_MAP m_netNames; ///< map for a fast look up by net names
|
||||||
std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
|
std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
|
||||||
|
|
||||||
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
|
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
|
||||||
|
@ -394,15 +412,15 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetNetname
|
* Function GetNetname
|
||||||
* @return const wxString * , a pointer to the full netname
|
* @return const wxString&, a reference to the full netname
|
||||||
*/
|
*/
|
||||||
wxString GetNetname() const { return m_Netname; }
|
const wxString& GetNetname() const { return m_Netname; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetShortNetname
|
* Function GetShortNetname
|
||||||
* @return const wxString * , a pointer to the short netname
|
* @return const wxString &, a reference to the short netname
|
||||||
*/
|
*/
|
||||||
wxString GetShortNetname() const { return m_ShortNetname; }
|
const wxString& GetShortNetname() const { return m_ShortNetname; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetMsgPanelInfo
|
* Function GetMsgPanelInfo
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
|
|
||||||
|
|
||||||
// Constructor and destructor
|
// Constructor and destructor
|
||||||
NETINFO_LIST::NETINFO_LIST( BOARD* aParent )
|
NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) : m_Parent( aParent )
|
||||||
{
|
{
|
||||||
m_Parent = aParent;
|
// Make sure that the unconnected net has number 0
|
||||||
|
AppendNet( new NETINFO_ITEM( aParent, wxEmptyString, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,14 +35,20 @@ void NETINFO_LIST::clear()
|
||||||
|
|
||||||
m_NetBuffer.clear();
|
m_NetBuffer.clear();
|
||||||
m_PadsFullList.clear();
|
m_PadsFullList.clear();
|
||||||
|
m_netNames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
|
void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
|
||||||
{
|
{
|
||||||
|
// net names & codes are supposed to be unique
|
||||||
|
assert( GetNetItem( aNewElement->GetNetname() ) == NULL );
|
||||||
|
assert( GetNetItem( aNewElement->GetNet() ) == NULL );
|
||||||
|
|
||||||
m_NetBuffer.push_back( aNewElement );
|
m_NetBuffer.push_back( aNewElement );
|
||||||
|
|
||||||
// D(Show();)
|
// add an entry for fast look up by a net name using a map
|
||||||
|
m_netNames.insert( std::make_pair( aNewElement->GetNetname(), aNewElement ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,18 +81,13 @@ void NETINFO_LIST::buildListOfNets()
|
||||||
{
|
{
|
||||||
D_PAD* pad;
|
D_PAD* pad;
|
||||||
int nodes_count = 0;
|
int nodes_count = 0;
|
||||||
NETINFO_ITEM* net_item;
|
|
||||||
|
|
||||||
// Build the PAD list, sorted by net
|
// Build the PAD list, sorted by net
|
||||||
buildPadsFullList();
|
buildPadsFullList();
|
||||||
|
|
||||||
// Restore the initial state of NETINFO_ITEMs
|
// Restore the initial state of NETINFO_ITEMs
|
||||||
for( unsigned i = 0; i < GetNetCount(); ++i )
|
for( unsigned i = 0; i < GetNetCount(); ++i )
|
||||||
{
|
|
||||||
GetNetItem( i )->Clear();
|
GetNetItem( i )->Clear();
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << m_PadsFullList.size() << std::endl;
|
|
||||||
|
|
||||||
// Assign pads to appropriate NETINFO_ITEMs
|
// Assign pads to appropriate NETINFO_ITEMs
|
||||||
for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
|
for( unsigned ii = 0; ii < m_PadsFullList.size(); ii++ )
|
||||||
|
@ -95,8 +97,8 @@ void NETINFO_LIST::buildListOfNets()
|
||||||
if( pad->GetNet() == 0 ) // pad not connected
|
if( pad->GetNet() == 0 ) // pad not connected
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
net_item = GetNetItem( pad->GetNet() );
|
// Add pad to the appropriate list of pads
|
||||||
net_item->m_PadInNetList.push_back( pad );
|
GetNetItem( pad->GetNet() )->m_PadInNetList.push_back( pad );
|
||||||
|
|
||||||
++nodes_count;
|
++nodes_count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,7 @@ void D_PAD::CopyNetlistSettings( D_PAD* aPad )
|
||||||
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
|
wxCHECK_RET( aPad != NULL && aPad != this, wxT( "Cannot copy to NULL or yourself." ) );
|
||||||
|
|
||||||
aPad->SetNetname( GetNetname() );
|
aPad->SetNetname( GetNetname() );
|
||||||
|
aPad->SetNet( GetNet() );
|
||||||
|
|
||||||
aPad->SetLocalClearance( m_LocalClearance );
|
aPad->SetLocalClearance( m_LocalClearance );
|
||||||
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
|
aPad->SetLocalSolderMaskMargin( m_LocalSolderMaskMargin );
|
||||||
|
|
|
@ -128,7 +128,13 @@ public:
|
||||||
* Function GetNetname
|
* Function GetNetname
|
||||||
* @return const wxString& - the full netname
|
* @return const wxString& - the full netname
|
||||||
*/
|
*/
|
||||||
const wxString& GetNetname() const { return m_Netname; }
|
const wxString& GetNetname() const
|
||||||
|
{
|
||||||
|
assert( ( GetNet() == 0 ) == m_Netname.IsEmpty() );
|
||||||
|
// assert( GetBoard()->FindNet( GetNet() ) == GetBoard()->FindNet( m_Netname ) );
|
||||||
|
|
||||||
|
return m_Netname;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetShortNetname
|
* Function GetShortNetname
|
||||||
|
|
|
@ -142,6 +142,7 @@ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
|
||||||
// Update the pad properties.
|
// Update the pad properties.
|
||||||
Import_Pad_Settings( pad, false );
|
Import_Pad_Settings( pad, false );
|
||||||
pad->SetNetname( wxEmptyString );
|
pad->SetNetname( wxEmptyString );
|
||||||
|
pad->SetNet( 0 );
|
||||||
|
|
||||||
pad->SetPosition( GetCrossHairPosition() );
|
pad->SetPosition( GetCrossHairPosition() );
|
||||||
|
|
||||||
|
|
|
@ -47,16 +47,14 @@ class REPORTER;
|
||||||
class COMPONENT_NET
|
class COMPONENT_NET
|
||||||
{
|
{
|
||||||
wxString m_pinName;
|
wxString m_pinName;
|
||||||
wxString m_netNumber;
|
|
||||||
wxString m_netName;
|
wxString m_netName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
COMPONENT_NET() {}
|
COMPONENT_NET() {}
|
||||||
|
|
||||||
COMPONENT_NET( const wxString& aPinName, const wxString& aNetName )
|
COMPONENT_NET( const wxString& aPinName, const wxString& aNetName ) :
|
||||||
|
m_pinName( aPinName ), m_netName( aNetName )
|
||||||
{
|
{
|
||||||
m_pinName = aPinName;
|
|
||||||
m_netName = aNetName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString& GetPinName() const { return m_pinName; }
|
const wxString& GetPinName() const { return m_pinName; }
|
||||||
|
|
Loading…
Reference in New Issue