Finish porting netlisters to use CONNECTION_GRAPH
This commit is contained in:
parent
d61b6f965e
commit
de9520d65e
|
@ -1416,6 +1416,7 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
}
|
||||
|
||||
m_net_code_to_subgraphs_map.clear();
|
||||
m_net_name_to_subgraphs_map.clear();
|
||||
|
||||
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
|
||||
{
|
||||
|
@ -1433,6 +1434,8 @@ void CONNECTION_GRAPH::buildConnectionGraph()
|
|||
auto key = std::make_pair( subgraph->GetNetName(),
|
||||
subgraph->m_driver_connection->NetCode() );
|
||||
m_net_code_to_subgraphs_map[ key ].push_back( subgraph );
|
||||
|
||||
m_net_name_to_subgraphs_map[subgraph->m_driver_connection->Name()].push_back( subgraph );
|
||||
}
|
||||
|
||||
// Clean up and deallocate stale subgraphs
|
||||
|
@ -1929,6 +1932,25 @@ std::vector<const CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetBusesNeedingMigrati
|
|||
}
|
||||
|
||||
|
||||
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindSubgraphByName(
|
||||
const wxString& aNetName, const SCH_SHEET_PATH& aPath )
|
||||
{
|
||||
if( !m_net_name_to_subgraphs_map.count( aNetName ) )
|
||||
return nullptr;
|
||||
|
||||
for( auto sg : m_net_name_to_subgraphs_map.at( aNetName ) )
|
||||
{
|
||||
// Cache is supposed to be valid by now
|
||||
wxASSERT( sg && !sg->m_absorbed && sg->m_driver_connection );
|
||||
|
||||
if( sg->m_sheet == aPath && sg->m_driver_connection->Name() == aNetName )
|
||||
return sg;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
int CONNECTION_GRAPH::RunERC()
|
||||
{
|
||||
int error_count = 0;
|
||||
|
|
|
@ -275,6 +275,15 @@ public:
|
|||
|
||||
const NET_MAP& GetNetMap() const { return m_net_code_to_subgraphs_map; }
|
||||
|
||||
/**
|
||||
* Returns the subgraph for a given net name on a given sheet
|
||||
* @param aNetName is the local net name to look for
|
||||
* @param aPath is a sheet path to look on
|
||||
* @return the subgraph matching the query, or nullptr if none is found
|
||||
*/
|
||||
CONNECTION_SUBGRAPH* FindSubgraphByName( const wxString& aNetName,
|
||||
const SCH_SHEET_PATH& aPath );
|
||||
|
||||
// TODO(JE) Remove this when pressure valve is removed
|
||||
static bool m_allowRealTime;
|
||||
|
||||
|
|
|
@ -404,9 +404,7 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
|
|||
}
|
||||
|
||||
{
|
||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||
NETLIST_EXPORTER_KICAD exporter(
|
||||
this, net_atoms, &Schematic(), Schematic().ConnectionGraph() );
|
||||
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
exporter.Format( &formatter, GNL_ALL );
|
||||
|
|
|
@ -32,9 +32,10 @@
|
|||
#include <refdes_utils.h>
|
||||
|
||||
#include <class_library.h>
|
||||
#include <netlist.h>
|
||||
#include <connection_graph.h>
|
||||
#include <sch_reference_list.h>
|
||||
#include <sch_screen.h>
|
||||
#include <schematic.h>
|
||||
|
||||
|
||||
wxString NETLIST_EXPORTER::MakeCommandLine( const wxString& aFormatString,
|
||||
|
@ -71,34 +72,6 @@ wxString NETLIST_EXPORTER::MakeCommandLine( const wxString& aFormatString,
|
|||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER::sprintPinNetName( wxString& aResult,
|
||||
const wxString& aNetNameFormat, NETLIST_OBJECT* aPin,
|
||||
bool aUseNetcodeAsNetName )
|
||||
{
|
||||
int netcode = aPin->GetNet();
|
||||
|
||||
// Not wxString::Clear(), which would free memory. We want the worst
|
||||
// case wxString memory to grow to avoid reallocation from within the
|
||||
// caller's loop.
|
||||
aResult.Empty();
|
||||
|
||||
if( netcode != 0 && aPin->GetConnectionType() == NET_CONNECTION::PAD_CONNECT )
|
||||
{
|
||||
if( aUseNetcodeAsNetName )
|
||||
{
|
||||
aResult.Printf( "%d", netcode );
|
||||
}
|
||||
else
|
||||
{
|
||||
aResult = aPin->GetNetName();
|
||||
|
||||
if( aResult.IsEmpty() ) // No net name: give a name from net code
|
||||
aResult.Printf( aNetNameFormat.GetData(), netcode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
wxString ref;
|
||||
|
@ -138,202 +111,3 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_P
|
|||
|
||||
return comp;
|
||||
}
|
||||
|
||||
|
||||
/// Comparison routine for sorting by pin numbers.
|
||||
static bool sortPinsByNum( NETLIST_OBJECT* aPin1, NETLIST_OBJECT* aPin2 )
|
||||
{
|
||||
// return "lhs < rhs"
|
||||
return UTIL::RefDesStringCompare( aPin1->GetPinNumText(), aPin2->GetPinNumText() ) < 0;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER::CreatePinList( SCH_COMPONENT* comp, SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
wxString ref( comp->GetRef( aSheetPath ) );
|
||||
|
||||
// Power symbols and other components which have the reference starting
|
||||
// with "#" are not included in netlist (pseudo or virtual components)
|
||||
|
||||
if( ref[0] == wxChar( '#' ) )
|
||||
return;
|
||||
|
||||
// if( Component->m_FlagControlMulti == 1 )
|
||||
// continue; /* yes */
|
||||
// removed because with multiple instances of one schematic
|
||||
// (several sheets pointing to 1 screen), this will be erroneously be
|
||||
// toggled.
|
||||
|
||||
if( !comp->GetPartRef() )
|
||||
return;
|
||||
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
// If component is a "multi parts per package" type
|
||||
if( comp->GetPartRef()->GetUnitCount() > 1 )
|
||||
{
|
||||
// test if this reference has already been processed, and if so skip
|
||||
if( m_ReferencesAlreadyFound.Lookup( ref ) )
|
||||
return;
|
||||
|
||||
// Collect all pins for this reference designator by searching
|
||||
// the entire design for other parts with the same reference designator.
|
||||
// This is only done once, it would be too expensive otherwise.
|
||||
findAllUnitsOfComponent( comp, comp->GetPartRef().get(), aSheetPath );
|
||||
}
|
||||
|
||||
else // entry->GetUnitCount() <= 1 means one part per package
|
||||
{
|
||||
LIB_PINS pins; // constructed once here
|
||||
|
||||
comp->GetPartRef()->GetPins(
|
||||
pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() );
|
||||
|
||||
for( size_t i = 0; i < pins.size(); i++ )
|
||||
{
|
||||
LIB_PIN* pin = pins[i];
|
||||
|
||||
wxASSERT( pin->Type() == LIB_PIN_T );
|
||||
|
||||
addPinToComponentPinList( comp, aSheetPath, pin );
|
||||
}
|
||||
}
|
||||
|
||||
// Sort pins in m_SortedComponentPinList by pin number
|
||||
sort( m_SortedComponentPinList.begin(), m_SortedComponentPinList.end(), sortPinsByNum );
|
||||
|
||||
// Remove duplicate Pins in m_SortedComponentPinList
|
||||
eraseDuplicatePins();
|
||||
|
||||
// record the usage of this library component entry.
|
||||
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
|
||||
}
|
||||
|
||||
|
||||
bool NETLIST_EXPORTER::addPinToComponentPinList( SCH_COMPONENT* aComponent,
|
||||
SCH_SHEET_PATH* aSheetPath, LIB_PIN* aPin )
|
||||
{
|
||||
// Search the PIN description for Pin in g_NetObjectslist
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
{
|
||||
NETLIST_OBJECT* pin = m_masterList->GetItem( ii );
|
||||
|
||||
if( pin->m_Type != NETLIST_ITEM::PIN )
|
||||
continue;
|
||||
|
||||
if( pin->m_Link != aComponent )
|
||||
continue;
|
||||
|
||||
if( pin->m_PinNum != aPin->GetNumber() )
|
||||
continue;
|
||||
|
||||
// most expensive test at the end.
|
||||
if( pin->m_SheetPath != *aSheetPath )
|
||||
continue;
|
||||
|
||||
m_SortedComponentPinList.push_back( pin );
|
||||
|
||||
if( m_SortedComponentPinList.size() >= MAXPIN )
|
||||
{
|
||||
// Log message for Internal error
|
||||
DisplayError( NULL, wxT( "addPinToComponentPinList err: MAXPIN reached" ) );
|
||||
}
|
||||
|
||||
return true; // we're done, we appended.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER::eraseDuplicatePins()
|
||||
{
|
||||
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
|
||||
{
|
||||
if( m_SortedComponentPinList[ii] == NULL ) /* already deleted */
|
||||
continue;
|
||||
|
||||
/* Search for duplicated pins
|
||||
* If found, remove duplicates. The priority is to keep connected pins
|
||||
* and remove unconnected
|
||||
* - So this allows (for instance when using multi op amps per package
|
||||
* - to connect only one op amp to power
|
||||
* Because the pin list is sorted by m_PinNum value, duplicated pins
|
||||
* are necessary successive in list
|
||||
*/
|
||||
int idxref = ii;
|
||||
for( unsigned jj = ii + 1; jj < m_SortedComponentPinList.size(); jj++ )
|
||||
{
|
||||
if( m_SortedComponentPinList[jj] == NULL ) // Already removed
|
||||
continue;
|
||||
|
||||
// if other pin num, stop search,
|
||||
// because all pins having the same number are consecutive in list.
|
||||
if( m_SortedComponentPinList[idxref]->m_PinNum != m_SortedComponentPinList[jj]->m_PinNum )
|
||||
break;
|
||||
|
||||
if( m_SortedComponentPinList[idxref]->GetConnectionType()
|
||||
== NET_CONNECTION::PAD_CONNECT )
|
||||
{
|
||||
m_SortedComponentPinList[jj]->m_Flag = 1;
|
||||
m_SortedComponentPinList[jj] = NULL;
|
||||
}
|
||||
else /* the reference pin is not connected: remove this pin if the
|
||||
* other pin is connected */
|
||||
{
|
||||
if( m_SortedComponentPinList[jj]->GetConnectionType()
|
||||
== NET_CONNECTION::PAD_CONNECT )
|
||||
{
|
||||
m_SortedComponentPinList[idxref]->m_Flag = 1;
|
||||
m_SortedComponentPinList[idxref] = NULL;
|
||||
idxref = jj;
|
||||
}
|
||||
else // the 2 pins are not connected: remove the tested pin,
|
||||
{ // and continue ...
|
||||
m_SortedComponentPinList[jj]->m_Flag = 1;
|
||||
m_SortedComponentPinList[jj] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NETLIST_EXPORTER::findAllUnitsOfComponent( SCH_COMPONENT* aComponent,
|
||||
LIB_PART* aEntry, SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
wxString ref = aComponent->GetRef( aSheetPath );
|
||||
wxString ref2;
|
||||
|
||||
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
|
||||
|
||||
for( unsigned i = 0; i < sheetList.size(); i++ )
|
||||
{
|
||||
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
|
||||
{
|
||||
SCH_COMPONENT* comp2 = static_cast<SCH_COMPONENT*>( item );
|
||||
|
||||
ref2 = comp2->GetRef( &sheetList[i] );
|
||||
|
||||
if( ref2.CmpNoCase( ref ) != 0 )
|
||||
continue;
|
||||
|
||||
int unit2 = comp2->GetUnitSelection( &sheetList[i] ); // slow
|
||||
|
||||
for( LIB_PIN* pin = aEntry->GetNextPin(); pin; pin = aEntry->GetNextPin( pin ) )
|
||||
{
|
||||
wxASSERT( pin->Type() == LIB_PIN_T );
|
||||
|
||||
if( pin->GetUnit() && pin->GetUnit() != unit2 )
|
||||
continue;
|
||||
|
||||
if( pin->GetConvert() && pin->GetConvert() != comp2->GetConvert() )
|
||||
continue;
|
||||
|
||||
// A suitable pin is found: add it to the current list
|
||||
addPinToComponentPinList( comp2, &sheetList[i], pin );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,13 +88,14 @@ struct LIB_PART_LESS_THAN
|
|||
class NETLIST_EXPORTER
|
||||
{
|
||||
protected:
|
||||
NETLIST_OBJECT_LIST* m_masterList; /// yes ownership, connected items flat list
|
||||
|
||||
// TODO(JE) NETLISTING
|
||||
#if 0
|
||||
/// Used to temporarily store and filter the list of pins of a schematic component
|
||||
/// when generating schematic component data in netlist (comp section). No ownership
|
||||
/// of members.
|
||||
/// TODO(snh): Descope this object
|
||||
NETLIST_OBJECTS m_SortedComponentPinList;
|
||||
#endif
|
||||
|
||||
/// Used for "multi parts per package" components,
|
||||
/// avoids processing a lib component more than once.
|
||||
|
@ -106,68 +107,10 @@ protected:
|
|||
/// The schematic we're generating a netlist for
|
||||
SCHEMATIC* m_schematic;
|
||||
|
||||
/**
|
||||
* Function sprintPinNetName
|
||||
* formats the net name for \a aPin using \a aNetNameFormat into \a aResult.
|
||||
* <p>
|
||||
* Net name is:
|
||||
* <ul>
|
||||
* <li> "?" if pin not connected
|
||||
* <li> "netname" for global net (like gnd, vcc ..
|
||||
* <li> "/path/netname" for the usual nets
|
||||
* </ul>
|
||||
* if aUseNetcodeAsNetName is true, the net name is just the net code (SPICE only)
|
||||
*/
|
||||
static void sprintPinNetName( wxString& aResult, const wxString& aNetNameFormat,
|
||||
NETLIST_OBJECT* aPin, bool aUseNetcodeAsNetName = false );
|
||||
|
||||
/**
|
||||
* Function findNextComponentAndCreatePinList
|
||||
* finds a component from the DrawList and builds
|
||||
* its pin list in m_SortedComponentPinList. This list is sorted by pin num.
|
||||
* the component is the next actual component after aItem
|
||||
* (power symbols and virtual components that have their reference starting by '#'are skipped).
|
||||
*/
|
||||
void CreatePinList( SCH_COMPONENT* aItem, SCH_SHEET_PATH* aSheetPath );
|
||||
|
||||
SCH_COMPONENT* findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
|
||||
|
||||
|
||||
/**
|
||||
* Function eraseDuplicatePins
|
||||
* erase duplicate Pins from m_SortedComponentPinList (i.e. set pointer in this list to NULL).
|
||||
* (This is a list of pins found in the whole schematic, for a single
|
||||
* component.) These duplicate pins were put in list because some pins (powers... )
|
||||
* are found more than one time when we have a multiple parts per package
|
||||
* component. For instance, a 74ls00 has 4 parts, and therefore the VCC pin
|
||||
* and GND pin appears 4 times in the list.
|
||||
* Note: this list *MUST* be sorted by pin number (.m_PinNum member value)
|
||||
* Also set the m_Flag member of "removed" NETLIST_OBJECT pin item to 1
|
||||
*/
|
||||
void eraseDuplicatePins();
|
||||
|
||||
/**
|
||||
* Function addPinToComponentPinList
|
||||
* adds a new pin description to the pin list m_SortedComponentPinList.
|
||||
* A pin description is a pointer to the corresponding structure
|
||||
* created by BuildNetList() in the table g_NetObjectslist.
|
||||
*/
|
||||
bool addPinToComponentPinList( SCH_COMPONENT* Component,
|
||||
SCH_SHEET_PATH* sheet,
|
||||
LIB_PIN* PinEntry );
|
||||
|
||||
/**
|
||||
* Function findAllUnitsOfComponent
|
||||
* is used for "multiple parts per package" components.
|
||||
* <p>
|
||||
* Search the entire design for all units of \a aComponent based on
|
||||
* matching reference designator, and for each unit, add all its pins
|
||||
* to the temporary sorted pin list, m_SortedComponentPinList.
|
||||
*/
|
||||
void findAllUnitsOfComponent( SCH_COMPONENT* aComponent,
|
||||
LIB_PART* aEntry,
|
||||
SCH_SHEET_PATH* aSheetPath );
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
@ -175,16 +118,14 @@ public:
|
|||
* @param aMasterList we take ownership of this here.
|
||||
* @param aLibTable is the symbol library table of the project.
|
||||
*/
|
||||
NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) :
|
||||
m_masterList( aMasterList ),
|
||||
NETLIST_EXPORTER( SCHEMATIC* aSchematic ) :
|
||||
m_schematic( aSchematic )
|
||||
{
|
||||
wxASSERT( aMasterList );
|
||||
wxASSERT( aSchematic );
|
||||
}
|
||||
|
||||
virtual ~NETLIST_EXPORTER()
|
||||
{
|
||||
delete m_masterList; // I own the list itself in this instance.
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <build_version.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#include <connection_graph.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_reference_list.h>
|
||||
|
||||
|
@ -62,10 +63,6 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
|
|||
ret |= fprintf( f, "\"%s\"\n", TO_UTF8( title ) );
|
||||
ret |= fprintf( f, ".TYP FULL\n\n" );
|
||||
|
||||
// Prepare list of nets generation
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
m_masterList->GetItem( ii )->m_Flag = 0;
|
||||
|
||||
// Create netlist module section
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
|
@ -82,8 +79,6 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
|
|||
if( !component )
|
||||
continue;
|
||||
|
||||
CreatePinList( component, &sheetList[i] );
|
||||
|
||||
if( !component->GetField( FOOTPRINT )->IsVoid() )
|
||||
footprint = component->GetField( FOOTPRINT )->GetText();
|
||||
else
|
||||
|
@ -103,8 +98,6 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
|
|||
|
||||
ret |= fprintf( f, "\n" );
|
||||
|
||||
m_SortedComponentPinList.clear();
|
||||
|
||||
if( ! writeListOfNets( f ) )
|
||||
ret = -1; // set error
|
||||
|
||||
|
@ -118,78 +111,99 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
|
|||
|
||||
bool NETLIST_EXPORTER_CADSTAR::writeListOfNets( FILE* f )
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
int print_ter = 0;
|
||||
|
||||
wxString InitNetDesc = StartLine + wxT( "ADD_TER" );
|
||||
wxString StartNetDesc = StartLine + wxT( "TER" );
|
||||
wxString netcodeName, InitNetDescLine;
|
||||
unsigned ii;
|
||||
int print_ter = 0;
|
||||
int NetCode, lastNetCode = -1;
|
||||
SCH_COMPONENT* Cmp;
|
||||
wxString InitNetDescLine;
|
||||
wxString netName;
|
||||
|
||||
for( ii = 0; ii < m_masterList->size(); ii++ )
|
||||
for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
|
||||
{
|
||||
NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
|
||||
auto subgraphs = it.second;
|
||||
|
||||
// Get the NetName of the current net :
|
||||
if( ( NetCode = nitem->GetNet() ) != lastNetCode )
|
||||
netName.Printf( wxT( "\"%s\"" ), it.first.first );
|
||||
|
||||
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
|
||||
|
||||
for( auto subgraph : subgraphs )
|
||||
{
|
||||
netName = nitem->GetNetName();
|
||||
netcodeName = wxT( "\"" );
|
||||
auto sheet = subgraph->m_sheet;
|
||||
|
||||
if( !netName.IsEmpty() )
|
||||
netcodeName << netName;
|
||||
else // this net has no name: create a default name $<net number>
|
||||
netcodeName << wxT( "$" ) << NetCode;
|
||||
|
||||
netcodeName += wxT( "\"" );
|
||||
lastNetCode = NetCode;
|
||||
print_ter = 0;
|
||||
for( auto item : subgraph->m_items )
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
sorted_items.emplace_back(
|
||||
std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
|
||||
}
|
||||
|
||||
// Netlist ordering: Net name, then ref des, then pin name
|
||||
std::sort( sorted_items.begin(), sorted_items.end(),
|
||||
[]( auto a, auto b )
|
||||
{
|
||||
wxString ref_a = a.first->GetParentComponent()->GetRef( &a.second );
|
||||
wxString ref_b = b.first->GetParentComponent()->GetRef( &b.second );
|
||||
|
||||
if( nitem->m_Type != NETLIST_ITEM::PIN )
|
||||
continue;
|
||||
if( ref_a == ref_b )
|
||||
return a.first->GetNumber() < b.first->GetNumber();
|
||||
|
||||
if( nitem->m_Flag != 0 )
|
||||
continue;
|
||||
return ref_a < ref_b;
|
||||
} );
|
||||
|
||||
Cmp = nitem->GetComponentParent();
|
||||
wxString refstr = Cmp->GetRef( &nitem->m_SheetPath );
|
||||
if( refstr[0] == '#' )
|
||||
continue; // Power supply symbols.
|
||||
// Some duplicates can exist, for example on multi-unit parts with duplicated
|
||||
// pins across units. If the user connects the pins on each unit, they will
|
||||
// appear on separate subgraphs. Remove those here:
|
||||
sorted_items.erase( std::unique( 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 );
|
||||
|
||||
switch( print_ter )
|
||||
return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
|
||||
} ),
|
||||
sorted_items.end() );
|
||||
|
||||
for( const auto& pair : sorted_items )
|
||||
{
|
||||
case 0:
|
||||
SCH_PIN* pin = pair.first;
|
||||
SCH_SHEET_PATH sheet = pair.second;
|
||||
|
||||
wxString refText = pin->GetParentComponent()->GetRef( &sheet );
|
||||
wxString pinText = pin->GetNumber();
|
||||
|
||||
// Skip power symbols and virtual components
|
||||
if( refText[0] == wxChar( '#' ) )
|
||||
continue;
|
||||
|
||||
switch( print_ter )
|
||||
{
|
||||
InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
|
||||
GetChars( InitNetDesc ),
|
||||
GetChars( refstr ),
|
||||
GetChars( nitem->m_PinNum ),
|
||||
GetChars( netcodeName ) );
|
||||
case 0:
|
||||
{
|
||||
InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
|
||||
GetChars( InitNetDesc ),
|
||||
GetChars( refText ),
|
||||
GetChars( pinText ),
|
||||
GetChars( netName ) );
|
||||
}
|
||||
print_ter++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
|
||||
ret |= fprintf( f, "%s %s %.4s\n",
|
||||
TO_UTF8( StartNetDesc ),
|
||||
TO_UTF8( refText ),
|
||||
TO_UTF8( pinText ) );
|
||||
print_ter++;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret |= fprintf( f, " %s %.4s\n",
|
||||
TO_UTF8( refText ),
|
||||
TO_UTF8( pinText ) );
|
||||
break;
|
||||
}
|
||||
print_ter++;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret |= fprintf( f, "%s\n", TO_UTF8( InitNetDescLine ) );
|
||||
ret |= fprintf( f, "%s %s %.4s\n",
|
||||
TO_UTF8( StartNetDesc ),
|
||||
TO_UTF8( refstr ),
|
||||
TO_UTF8( nitem->m_PinNum ) );
|
||||
print_ter++;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret |= fprintf( f, " %s %.4s\n",
|
||||
TO_UTF8( refstr ),
|
||||
TO_UTF8( nitem->m_PinNum ) );
|
||||
break;
|
||||
}
|
||||
|
||||
nitem->m_Flag = 1;
|
||||
}
|
||||
|
||||
return ret >= 0;
|
||||
|
|
|
@ -48,8 +48,8 @@ class NETLIST_EXPORTER_CADSTAR : public NETLIST_EXPORTER
|
|||
bool writeListOfNets( FILE* f );
|
||||
|
||||
public:
|
||||
NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aMasterList, aSchematic )
|
||||
NETLIST_EXPORTER_CADSTAR( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aSchematic )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,6 @@ static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 );
|
|||
|
||||
bool NETLIST_EXPORTER_GENERIC::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
// Prepare list of nets generation
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
m_masterList->GetItem( ii )->m_Flag = 0;
|
||||
|
||||
// output the XML format netlist.
|
||||
wxXmlDocument xdoc;
|
||||
|
||||
|
@ -201,6 +197,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
|
|||
XNODE* xcomps = node( "components" );
|
||||
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
m_LibParts.clear();
|
||||
|
||||
SCH_SHEET_LIST sheetList = m_schematic->GetSheets();
|
||||
|
||||
|
@ -379,11 +376,12 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibraries()
|
|||
wxString libNickname = *it;
|
||||
XNODE* xlibrary;
|
||||
|
||||
if( m_libTable->HasLibrary( libNickname ) )
|
||||
if( m_schematic->Prj().SchSymbolLibTable()->HasLibrary( libNickname ) )
|
||||
{
|
||||
xlibs->AddChild( xlibrary = node( "library" ) );
|
||||
xlibrary->AddAttribute( "logical", libNickname );
|
||||
xlibrary->AddChild( node( "uri", m_libTable->GetFullURI( libNickname ) ) );
|
||||
xlibrary->AddChild( node(
|
||||
"uri", m_schematic->Prj().SchSymbolLibTable()->GetFullURI( libNickname ) ) );
|
||||
}
|
||||
|
||||
// @todo: add more fun stuff here
|
||||
|
@ -496,7 +494,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts()
|
|||
}
|
||||
|
||||
|
||||
XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
|
||||
XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets()
|
||||
{
|
||||
XNODE* xnets = node( "nets" ); // auto_ptr if exceptions ever get used.
|
||||
wxString netCodeTxt;
|
||||
|
@ -504,10 +502,6 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
|
|||
wxString ref;
|
||||
|
||||
XNODE* xnet = 0;
|
||||
int netCode;
|
||||
int lastNetCode = -1;
|
||||
int sameNetcodeCount = 0;
|
||||
|
||||
|
||||
/* output:
|
||||
<net code="123" name="/cfcard.sch/WAIT#">
|
||||
|
@ -516,137 +510,85 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets( bool aUseGraph )
|
|||
</net>
|
||||
*/
|
||||
|
||||
m_LibParts.clear(); // must call this function before using m_LibParts.
|
||||
int code = 0;
|
||||
|
||||
if( aUseGraph )
|
||||
for( const auto& it : m_schematic->ConnectionGraph()->GetNetMap() )
|
||||
{
|
||||
wxASSERT( m_graph );
|
||||
int code = 0;
|
||||
bool added = false;
|
||||
wxString net_name = it.first.first;
|
||||
auto subgraphs = it.second;
|
||||
|
||||
for( const auto& it : m_graph->GetNetMap() )
|
||||
// Code starts at 1
|
||||
code++;
|
||||
|
||||
XNODE* xnode;
|
||||
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
|
||||
|
||||
for( auto subgraph : subgraphs )
|
||||
{
|
||||
bool added = false;
|
||||
wxString net_name = it.first.first;
|
||||
auto subgraphs = it.second;
|
||||
auto sheet = subgraph->m_sheet;
|
||||
|
||||
// Code starts at 1
|
||||
code++;
|
||||
|
||||
XNODE* xnode;
|
||||
std::vector<std::pair<SCH_PIN*, SCH_SHEET_PATH>> sorted_items;
|
||||
|
||||
for( auto subgraph : subgraphs )
|
||||
{
|
||||
auto sheet = subgraph->m_sheet;
|
||||
|
||||
for( auto item : subgraph->m_items )
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
sorted_items.emplace_back(
|
||||
std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
|
||||
}
|
||||
|
||||
// Netlist ordering: Net name, then ref des, then pin name
|
||||
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 );
|
||||
|
||||
if( ref_a == ref_b )
|
||||
return a.first->GetNumber() < b.first->GetNumber();
|
||||
|
||||
return ref_a < ref_b;
|
||||
} );
|
||||
|
||||
// Some duplicates can exist, for example on multi-unit parts with duplicated
|
||||
// pins across units. If the user connects the pins on each unit, they will
|
||||
// appear on separate subgraphs. Remove those here:
|
||||
sorted_items.erase( std::unique( 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 );
|
||||
|
||||
return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
|
||||
} ), sorted_items.end() );
|
||||
|
||||
for( const auto& pair : sorted_items )
|
||||
{
|
||||
SCH_PIN* pin = pair.first;
|
||||
SCH_SHEET_PATH sheet = pair.second;
|
||||
|
||||
auto refText = pin->GetParentComponent()->GetRef( &sheet );
|
||||
const auto& pinText = pin->GetNumber();
|
||||
|
||||
// Skip power symbols and virtual components
|
||||
if( refText[0] == wxChar( '#' ) )
|
||||
continue;
|
||||
|
||||
if( !added )
|
||||
{
|
||||
xnets->AddChild( xnet = node( "net" ) );
|
||||
netCodeTxt.Printf( "%d", code );
|
||||
xnet->AddAttribute( "code", netCodeTxt );
|
||||
xnet->AddAttribute( "name", net_name );
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
for( auto item : subgraph->m_items )
|
||||
if( item->Type() == SCH_PIN_T )
|
||||
sorted_items.emplace_back(
|
||||
std::make_pair( static_cast<SCH_PIN*>( item ), sheet ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
|
||||
// Netlist ordering: Net name, then ref des, then pin name
|
||||
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 );
|
||||
|
||||
if( ref_a == ref_b )
|
||||
return a.first->GetNumber() < b.first->GetNumber();
|
||||
|
||||
return ref_a < ref_b;
|
||||
} );
|
||||
|
||||
// Some duplicates can exist, for example on multi-unit parts with duplicated
|
||||
// pins across units. If the user connects the pins on each unit, they will
|
||||
// appear on separate subgraphs. Remove those here:
|
||||
sorted_items.erase( std::unique( 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 );
|
||||
|
||||
return ref_a == ref_b && a.first->GetNumber() == b.first->GetNumber();
|
||||
} ), sorted_items.end() );
|
||||
|
||||
for( const auto& pair : sorted_items )
|
||||
{
|
||||
NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
|
||||
SCH_COMPONENT* comp;
|
||||
SCH_PIN* pin = pair.first;
|
||||
SCH_SHEET_PATH sheet = pair.second;
|
||||
|
||||
// New net found, write net id;
|
||||
if( ( netCode = nitem->GetNet() ) != lastNetCode )
|
||||
{
|
||||
sameNetcodeCount = 0; // item count for this net
|
||||
netName = nitem->GetNetName();
|
||||
lastNetCode = netCode;
|
||||
}
|
||||
auto refText = pin->GetParentComponent()->GetRef( &sheet );
|
||||
const auto& pinText = pin->GetNumber();
|
||||
|
||||
if( nitem->m_Type != NETLIST_ITEM::PIN )
|
||||
// Skip power symbols and virtual components
|
||||
if( refText[0] == wxChar( '#' ) )
|
||||
continue;
|
||||
|
||||
if( nitem->m_Flag != 0 ) // Redundant pin, skip it
|
||||
continue;
|
||||
|
||||
comp = nitem->GetComponentParent();
|
||||
|
||||
// Get the reference for the net name and the main parent component
|
||||
ref = comp->GetRef( &nitem->m_SheetPath );
|
||||
if( ref[0] == wxChar( '#' ) )
|
||||
continue;
|
||||
|
||||
if( ++sameNetcodeCount == 1 )
|
||||
if( !added )
|
||||
{
|
||||
xnets->AddChild( xnet = node( "net" ) );
|
||||
netCodeTxt.Printf( "%d", netCode );
|
||||
netCodeTxt.Printf( "%d", code );
|
||||
xnet->AddAttribute( "code", netCodeTxt );
|
||||
xnet->AddAttribute( "name", netName );
|
||||
xnet->AddAttribute( "name", net_name );
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
||||
XNODE* xnode;
|
||||
xnet->AddChild( xnode = node( "node" ) );
|
||||
xnode->AddAttribute( "ref", ref );
|
||||
xnode->AddAttribute( "pin", nitem->GetPinNumText() );
|
||||
xnode->AddAttribute( "ref", refText );
|
||||
xnode->AddAttribute( "pin", pinText );
|
||||
|
||||
if( !nitem->GetPinNameText().IsEmpty() )
|
||||
xnode->AddAttribute( "pinfunction", nitem->GetPinNameText() );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,19 +62,9 @@ class NETLIST_EXPORTER_GENERIC : public NETLIST_EXPORTER
|
|||
private:
|
||||
std::set< wxString > m_libraries; ///< Set of library nicknames.
|
||||
|
||||
SYMBOL_LIB_TABLE* m_libTable;
|
||||
|
||||
protected:
|
||||
CONNECTION_GRAPH* m_graph;
|
||||
|
||||
public:
|
||||
NETLIST_EXPORTER_GENERIC( SCH_EDIT_FRAME* aFrame,
|
||||
NETLIST_OBJECT_LIST* aMasterList,
|
||||
SCHEMATIC* aSchematic,
|
||||
CONNECTION_GRAPH* aGraph = nullptr ) :
|
||||
NETLIST_EXPORTER( aMasterList, aSchematic ),
|
||||
m_libTable( aFrame->Prj().SchSymbolLibTable() ),
|
||||
m_graph( aGraph )
|
||||
NETLIST_EXPORTER_GENERIC( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aSchematic )
|
||||
{}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +122,7 @@ protected:
|
|||
* fills out an XML node with a list of nets and returns it.
|
||||
* @return XNODE* - the list of nets nodes
|
||||
*/
|
||||
XNODE* makeListOfNets( bool aUseGraph = true );
|
||||
XNODE* makeListOfNets();
|
||||
|
||||
/**
|
||||
* Function makeLibraries
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
|
||||
bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
wxASSERT( m_graph );
|
||||
|
||||
try
|
||||
{
|
||||
FILE_OUTPUTFORMATTER formatter( aOutFileName );
|
||||
|
@ -56,10 +54,6 @@ bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigne
|
|||
|
||||
void NETLIST_EXPORTER_KICAD::Format( OUTPUTFORMATTER* aOut, int aCtl )
|
||||
{
|
||||
// Prepare list of nets generation
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
m_masterList->GetItem( ii )->m_Flag = 0;
|
||||
|
||||
std::unique_ptr<XNODE> xroot( makeRoot( aCtl ) );
|
||||
|
||||
xroot->Format( aOut, 0 );
|
||||
|
|
|
@ -38,11 +38,8 @@ class OUTPUTFORMATTER;
|
|||
class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC
|
||||
{
|
||||
public:
|
||||
NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame,
|
||||
NETLIST_OBJECT_LIST* aMasterList,
|
||||
SCHEMATIC* aSchematic,
|
||||
CONNECTION_GRAPH* aGraph = nullptr ) :
|
||||
NETLIST_EXPORTER_GENERIC( aFrame, aMasterList, aSchematic, aGraph )
|
||||
NETLIST_EXPORTER_KICAD( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER_GENERIC( aSchematic )
|
||||
{}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <build_version.h>
|
||||
#include <confirm.h>
|
||||
#include <refdes_utils.h>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_reference_list.h>
|
||||
|
@ -61,10 +61,6 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
|||
ret |= fprintf( f, "( { %s created %s }\n",
|
||||
NETLIST_HEAD_STRING, TO_UTF8( DateAndTime() ) );
|
||||
|
||||
// Prepare list of nets generation
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
m_masterList->GetItem( ii )->m_Flag = 0;
|
||||
|
||||
// Create netlist module section
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
|
||||
|
@ -72,24 +68,18 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
|||
|
||||
for( unsigned i = 0; i < sheetList.size(); i++ )
|
||||
{
|
||||
SCH_SHEET_PATH sheet = sheetList[i];
|
||||
|
||||
// Process component attributes
|
||||
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
|
||||
for( auto item : sheet.LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
|
||||
{
|
||||
SCH_COMPONENT* comp = findNextComponent( item, &sheetList[i] );
|
||||
SCH_COMPONENT* comp = findNextComponent( item, &sheet );
|
||||
|
||||
if( !comp )
|
||||
continue;
|
||||
|
||||
CreatePinList( comp, &sheetList[i] );
|
||||
|
||||
if( comp->GetPartRef() )
|
||||
{
|
||||
if( comp->GetPartRef()->GetFootprints().GetCount() != 0 ) // Put in list
|
||||
{
|
||||
cmpList.push_back( SCH_REFERENCE( comp, comp->GetPartRef().get(),
|
||||
sheetList[i] ) );
|
||||
}
|
||||
}
|
||||
if( comp->GetPartRef() && comp->GetPartRef()->GetFootprints().GetCount() != 0 )
|
||||
cmpList.push_back( SCH_REFERENCE( comp, comp->GetPartRef().get(), sheet ) );
|
||||
|
||||
if( !comp->GetField( FOOTPRINT )->IsVoid() )
|
||||
{
|
||||
|
@ -97,7 +87,9 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
|||
footprint.Replace( wxT( " " ), wxT( "_" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
footprint = wxT( "$noname" );
|
||||
}
|
||||
|
||||
field = comp->GetRef( &sheetList[i] );
|
||||
|
||||
|
@ -114,21 +106,27 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
|||
ret |= fprintf( f, "\n" );
|
||||
|
||||
// Write pin list:
|
||||
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
|
||||
std::vector<SCH_PIN*> pins;
|
||||
|
||||
for( const auto& pin : comp->GetSchPins( &sheet ) )
|
||||
pins.emplace_back( pin );
|
||||
|
||||
std::sort( pins.begin(), pins.end(),
|
||||
[]( const SCH_PIN* a, const SCH_PIN* b )
|
||||
{
|
||||
return UTIL::RefDesStringCompare( a->GetNumber(), b->GetNumber() ) < 0;
|
||||
} );
|
||||
|
||||
for( const auto* pin : pins )
|
||||
{
|
||||
NETLIST_OBJECT* pin = m_SortedComponentPinList[ii];
|
||||
|
||||
if( !pin )
|
||||
continue;
|
||||
|
||||
sprintPinNetName( netName, wxT( "N-%.6d" ), pin );
|
||||
|
||||
if( netName.IsEmpty() )
|
||||
if( auto conn = pin->Connection( sheet ) )
|
||||
netName = conn->Name();
|
||||
else
|
||||
netName = wxT( "?" );
|
||||
|
||||
netName.Replace( wxT( " " ), wxT( "_" ) );
|
||||
|
||||
ret |= fprintf( f, " ( %4.4s %s )\n", TO_UTF8( pin->m_PinNum ),
|
||||
ret |= fprintf( f, " ( %4.4s %s )\n", TO_UTF8( pin->GetNumber() ),
|
||||
TO_UTF8( netName ) );
|
||||
}
|
||||
|
||||
|
@ -140,6 +138,5 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
|
|||
|
||||
fclose( f );
|
||||
|
||||
m_SortedComponentPinList.clear();
|
||||
return ret >= 0;
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
class NETLIST_EXPORTER_ORCADPCB2 : public NETLIST_EXPORTER
|
||||
{
|
||||
public:
|
||||
NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aMasterList, aSchematic )
|
||||
NETLIST_EXPORTER_ORCADPCB2( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aSchematic )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include <map>
|
||||
#include <search_stack.h>
|
||||
|
||||
#include <connection_graph.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <netlist.h>
|
||||
#include <sch_reference_list.h>
|
||||
#include <env_paths.h>
|
||||
|
||||
|
@ -97,7 +97,7 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl
|
|||
if( ( aCtl & NET_ADJUST_INCLUDE_PATHS ) )
|
||||
{
|
||||
// Look for the library in known search locations
|
||||
full_path = ResolveFile( lib, &Pgm().GetLocalEnvVariables(), m_project );
|
||||
full_path = ResolveFile( lib, &Pgm().GetLocalEnvVariables(), &m_schematic->Prj() );
|
||||
|
||||
if( full_path.IsEmpty() )
|
||||
{
|
||||
|
@ -135,19 +135,16 @@ bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl
|
|||
continue;
|
||||
}
|
||||
|
||||
NETLIST_OBJECT* pin = item.m_pins[activePinIndex];
|
||||
assert( pin );
|
||||
wxString netName = pin->GetNetName();
|
||||
wxString netName = item.m_pins[activePinIndex];
|
||||
|
||||
wxASSERT( m_netMap.count( netName ) );
|
||||
|
||||
if( useNetcodeAsNetName )
|
||||
{
|
||||
assert( m_netMap.count( netName ) );
|
||||
aFormatter->Print( 0, "%d ", m_netMap[netName] );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintPinNetName( netName , wxT( "N-%.6d" ), pin, useNetcodeAsNetName );
|
||||
|
||||
// Replace parenthesis with underscore to prevent parse issues with simulators
|
||||
ReplaceForbiddenChars( netName );
|
||||
|
||||
|
@ -272,30 +269,28 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl )
|
|||
// Set of reference names, to check for duplications
|
||||
std::set<wxString> refNames;
|
||||
|
||||
// Prepare list of nets generation (not used here, but...
|
||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||
m_masterList->GetItem( ii )->m_Flag = 0;
|
||||
|
||||
m_netMap.clear();
|
||||
m_netMap["GND"] = 0; // 0 is reserved for "GND"
|
||||
int netIdx = 1;
|
||||
|
||||
m_libraries.clear();
|
||||
m_ReferencesAlreadyFound.Clear();
|
||||
m_LibParts.clear();
|
||||
|
||||
UpdateDirectives( aCtl );
|
||||
|
||||
for( unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ )
|
||||
{
|
||||
SCH_SHEET_PATH sheet = sheetList[sheet_idx];
|
||||
|
||||
// Process component attributes to find Spice directives
|
||||
for( auto item : sheetList[sheet_idx].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
|
||||
for( auto item : sheet.LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
|
||||
{
|
||||
SCH_COMPONENT* comp = findNextComponent( item, &sheetList[sheet_idx] );
|
||||
SCH_COMPONENT* comp = findNextComponent( item, &sheet );
|
||||
|
||||
if( !comp )
|
||||
continue;
|
||||
|
||||
CreatePinList( comp, &sheetList[sheet_idx] );
|
||||
SPICE_ITEM spiceItem;
|
||||
spiceItem.m_parent = comp;
|
||||
|
||||
|
@ -305,7 +300,7 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl )
|
|||
|
||||
spiceItem.m_primitive = GetSpiceField( SF_PRIMITIVE, comp, aCtl )[0];
|
||||
spiceItem.m_model = GetSpiceField( SF_MODEL, comp, aCtl );
|
||||
spiceItem.m_refName = comp->GetRef( &sheetList[sheet_idx] );
|
||||
spiceItem.m_refName = comp->GetRef( &sheet );
|
||||
|
||||
// Duplicate references will result in simulation errors
|
||||
if( refNames.count( spiceItem.m_refName ) )
|
||||
|
@ -326,21 +321,26 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl )
|
|||
wxArrayString pinNames;
|
||||
|
||||
// Store pin information
|
||||
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
|
||||
for( const auto& pin : comp->GetSchPins( &sheet ) )
|
||||
{
|
||||
NETLIST_OBJECT* pin = m_SortedComponentPinList[ii];
|
||||
if( auto conn = pin->Connection( sheet ) )
|
||||
{
|
||||
const wxString& netName = conn->Name();
|
||||
|
||||
// NETLIST_EXPORTER marks removed pins by setting them to NULL
|
||||
if( !pin )
|
||||
continue;
|
||||
// Skip unconnected pins
|
||||
CONNECTION_SUBGRAPH* sg =
|
||||
m_schematic->ConnectionGraph()->FindSubgraphByName( netName, sheet );
|
||||
|
||||
spiceItem.m_pins.push_back( pin );
|
||||
pinNames.Add( pin->GetPinNumText() );
|
||||
if( !sg || sg->m_no_connect || sg->m_items.size() < 2 )
|
||||
continue;
|
||||
|
||||
// Create net mapping
|
||||
const wxString& netName = pin->GetNetName();
|
||||
if( m_netMap.count( netName ) == 0 )
|
||||
m_netMap[netName] = netIdx++;
|
||||
// Create net mapping
|
||||
spiceItem.m_pins.push_back( netName );
|
||||
pinNames.Add( pin->GetName() );
|
||||
|
||||
if( m_netMap.count( netName ) == 0 )
|
||||
m_netMap[netName] = netIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if an alternative pin sequence is available:
|
||||
|
|
|
@ -87,7 +87,7 @@ struct SPICE_ITEM
|
|||
bool m_enabled;
|
||||
|
||||
///> Array containing Standard Pin Name
|
||||
std::vector<NETLIST_OBJECT*> m_pins;
|
||||
std::vector<wxString> m_pins;
|
||||
|
||||
///> Numeric indices into m_SortedComponentPinList
|
||||
std::vector<int> m_pinSequence;
|
||||
|
@ -101,10 +101,8 @@ struct SPICE_ITEM
|
|||
class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER
|
||||
{
|
||||
public:
|
||||
NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic,
|
||||
PROJECT* aProject = nullptr ) :
|
||||
NETLIST_EXPORTER( aMasterList, aSchematic ),
|
||||
m_project( aProject )
|
||||
NETLIST_EXPORTER_PSPICE( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER( aSchematic )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -245,9 +243,6 @@ private:
|
|||
///> List of items representing schematic components in the Spice world
|
||||
SPICE_ITEM_LIST m_spiceItems;
|
||||
|
||||
///> Project object to fetch its settings (e.g. paths)
|
||||
PROJECT* m_project;
|
||||
|
||||
// Component fields that are processed during netlist export & simulation
|
||||
static const std::vector<wxString> m_spiceFields;
|
||||
};
|
||||
|
|
|
@ -67,20 +67,19 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
|
|||
switch( aFormat )
|
||||
{
|
||||
case NET_TYPE_PCBNEW:
|
||||
helper = new NETLIST_EXPORTER_KICAD(
|
||||
this, aConnectedItemsList, sch, sch->ConnectionGraph() );
|
||||
helper = new NETLIST_EXPORTER_KICAD( sch );
|
||||
break;
|
||||
|
||||
case NET_TYPE_ORCADPCB2:
|
||||
helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList, sch );
|
||||
helper = new NETLIST_EXPORTER_ORCADPCB2( sch );
|
||||
break;
|
||||
|
||||
case NET_TYPE_CADSTAR:
|
||||
helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList, sch );
|
||||
helper = new NETLIST_EXPORTER_CADSTAR( sch );
|
||||
break;
|
||||
|
||||
case NET_TYPE_SPICE:
|
||||
helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList, sch );
|
||||
helper = new NETLIST_EXPORTER_PSPICE( sch );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -89,8 +88,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
|
|||
tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT );
|
||||
fileName = tmpFile.GetFullPath();
|
||||
|
||||
helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList, sch,
|
||||
sch->ConnectionGraph() );
|
||||
helper = new NETLIST_EXPORTER_GENERIC( sch );
|
||||
executeCommandLine = true;
|
||||
}
|
||||
break;
|
||||
|
@ -193,8 +191,7 @@ bool SCH_EDIT_FRAME::prepareForNetlist()
|
|||
|
||||
void SCH_EDIT_FRAME::sendNetlistToCvpcb()
|
||||
{
|
||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, &Schematic(), Schematic().ConnectionGraph() );
|
||||
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
// @todo : trim GNL_ALL down to minimum for CVPCB
|
||||
|
|
|
@ -46,9 +46,8 @@ struct SPICE_DC_PARAMS
|
|||
class NETLIST_EXPORTER_PSPICE_SIM : public NETLIST_EXPORTER_PSPICE
|
||||
{
|
||||
public:
|
||||
NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList, SCHEMATIC* aSchematic,
|
||||
PROJECT* aProject = nullptr ) :
|
||||
NETLIST_EXPORTER_PSPICE( aMasterList, aSchematic, aProject )
|
||||
NETLIST_EXPORTER_PSPICE_SIM( SCHEMATIC* aSchematic ) :
|
||||
NETLIST_EXPORTER_PSPICE( aSchematic )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -672,8 +672,7 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName, bool aErase )
|
|||
|
||||
void SIM_PLOT_FRAME::updateNetlistExporter()
|
||||
{
|
||||
m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM(
|
||||
m_schematicFrame->BuildNetListBase(), &m_schematicFrame->Schematic(), &Prj() ) );
|
||||
m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( &m_schematicFrame->Schematic() ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ uViaDrill=0.127
|
|||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
update=Wed 20 May 2020 18:03:51 EDT
|
||||
update=Thu 21 May 2020 16:15:39 EDT
|
||||
last_client=eeschema
|
||||
[pcbnew/Netclasses/1]
|
||||
Name=pwr
|
||||
|
@ -34,6 +34,15 @@ uViaDrill=0.127
|
|||
dPairWidth=0.2
|
||||
dPairGap=0.25
|
||||
dPairViaGap=0.25
|
||||
[sheetnames]
|
||||
1=84d4d60f-6656-461e-b8d6-5d42ccee0251:
|
||||
2=00000000-0000-0000-0000-00004bf03687:buspci.sch
|
||||
3=00000000-0000-0000-0000-00004bf03683:graphic
|
||||
4=00000000-0000-0000-0000-00004bf03689:ESVIDEO-RVB
|
||||
5=00000000-0000-0000-0000-00004bf03681:pal-ntsc.sch
|
||||
6=00000000-0000-0000-0000-00004bf03685:RAMS
|
||||
7=00000000-0000-0000-0000-00004bf0367d:muxdata
|
||||
8=00000000-0000-0000-0000-00004bf0367f:modul
|
||||
[schematic_editor]
|
||||
version=1
|
||||
PageLayoutDescrFile=
|
||||
|
@ -56,12 +65,3 @@ ERC_CheckBusDriverConflicts=1
|
|||
ERC_CheckBusEntryConflicts=1
|
||||
ERC_CheckBusToBusConflicts=1
|
||||
ERC_CheckBusToNetConflicts=1
|
||||
[sheetnames]
|
||||
1=84d4d60f-6656-461e-b8d6-5d42ccee0251:
|
||||
2=00000000-0000-0000-0000-00004bf03687:buspci.sch
|
||||
3=00000000-0000-0000-0000-00004bf03683:graphic
|
||||
4=00000000-0000-0000-0000-00004bf03689:ESVIDEO-RVB
|
||||
5=00000000-0000-0000-0000-00004bf03681:pal-ntsc.sch
|
||||
6=00000000-0000-0000-0000-00004bf03685:RAMS
|
||||
7=00000000-0000-0000-0000-00004bf0367d:muxdata
|
||||
8=00000000-0000-0000-0000-00004bf0367f:modul
|
||||
|
|
|
@ -33,18 +33,24 @@
|
|||
#include <wx/string.h>
|
||||
|
||||
// Code under test
|
||||
#include <project.h>
|
||||
#include <schematic.h>
|
||||
#include <sim/netlist_exporter_pspice_sim.h>
|
||||
|
||||
class TEST_NETLIST_EXPORTER_PSPICE_SIM
|
||||
{
|
||||
public:
|
||||
TEST_NETLIST_EXPORTER_PSPICE_SIM()
|
||||
: m_netlist( new NETLIST_OBJECT_LIST ),
|
||||
m_exporter( m_netlist, nullptr )
|
||||
TEST_NETLIST_EXPORTER_PSPICE_SIM() :
|
||||
m_project(),
|
||||
m_schematic( &m_project ),
|
||||
m_exporter( &m_schematic )
|
||||
{
|
||||
}
|
||||
|
||||
NETLIST_OBJECT_LIST* m_netlist;
|
||||
PROJECT m_project;
|
||||
|
||||
SCHEMATIC m_schematic;
|
||||
|
||||
NETLIST_EXPORTER_PSPICE_SIM m_exporter;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue