Eeschema: intermediate netlist : fix duplicate pins in list of nets, with multi parts per package.

This commit is contained in:
jean-pierre charras 2011-02-10 18:49:04 +01:00
parent 0cb6cd8c02
commit 90c130b600
2 changed files with 77 additions and 70 deletions

View File

@ -127,7 +127,7 @@ class EXPORT_HELP
* <ul> * <ul>
* <li> "?" if pin not connected * <li> "?" if pin not connected
* <li> "netname" for global net (like gnd, vcc .. * <li> "netname" for global net (like gnd, vcc ..
* <li> "netname_sheetnumber" for the usual nets * <li> "/path/netname" for the usual nets
* </ul> * </ul>
*/ */
static void sprintPinNetName( wxString* aResult, const wxString& aNetNameFormat, NETLIST_OBJECT* aPin ); static void sprintPinNetName( wxString* aResult, const wxString& aNetNameFormat, NETLIST_OBJECT* aPin );
@ -135,11 +135,11 @@ class EXPORT_HELP
/** /**
* Function findNextComponentAndCreatePinList * Function findNextComponentAndCreatePinList
* finds a "suitable" component from the DrawList and optionally builds * finds a "suitable" component from the DrawList and optionally builds
* its pin list int m_SortedComponentPinList. The list is sorted by pin num. * its pin list in m_SortedComponentPinList. The list is sorted by pin num.
* A suitable component is a "new" real component (power symbols are not * A suitable component is a "new" real component
* considered). * (power symbols and virtual components that have their reference starting by '#'are skipped).
*/ */
SCH_COMPONENT* findNextComponentAndCreatPinList( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath ); SCH_COMPONENT* findNextComponentAndCreatePinList( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
SCH_COMPONENT* findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath ); SCH_COMPONENT* findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
@ -158,9 +158,9 @@ class EXPORT_HELP
void eraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ); void eraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList );
/** /**
* Function addPintToComponentPinList * Function addPinToComponentPinList
* adds a new pin description to the pin list m_SortedComponentPinList. * adds a new pin description to the pin list m_SortedComponentPinList.
* A.a pin description is a pointer to the corresponding structure * A pin description is a pointer to the corresponding structure
* created by BuildNetList() in the table g_NetObjectslist. * created by BuildNetList() in the table g_NetObjectslist.
*/ */
bool addPinToComponentPinList( SCH_COMPONENT* Component, bool addPinToComponentPinList( SCH_COMPONENT* Component,
@ -242,22 +242,20 @@ public:
/** /**
* Function WriteGENERICNetList * Function WriteGENERICNetList
* creates a generic netlist, now in XML. * creates a generic netlist, now in XML.
* @param frame = the parent SCH_EDIT_FRAME frame
* @param aOutFileName = the full filename of the file to create * @param aOutFileName = the full filename of the file to create
* @return bool - true if there were no errors, else false. * @return bool - true if there were no errors, else false.
*/ */
bool WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aOutFileName ); bool WriteGENERICNetList( const wxString& aOutFileName );
/** /**
* Function WriteNetListPCBNEW * Function WriteNetListPCBNEW
* generates a net list file (Format 2 improves ORCAD PCB) * generates a net list file (Format 2 improves ORCAD PCB)
* *
* @param frame = the parent SCH_EDIT_FRAME frame
* @param f = the file to write to * @param f = the file to write to
* @param with_pcbnew if true, then format Pcbnew (OrcadPcb2 + reviews and lists of net),<p> * @param with_pcbnew if true, then use Pcbnew format (OrcadPcb2 + a list of net),<p>
* else output ORCADPCB2 strict format. * else use ORCADPCB2 basic format.
*/ */
bool WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_pcbnew ); bool WriteNetListPCBNEW( FILE* f, bool with_pcbnew );
/** /**
* Function WriteNetListCADSTAR * Function WriteNetListCADSTAR
@ -287,22 +285,21 @@ public:
* .. B * T3 1 * .. B * T3 1
*U1 * 14 *U1 * 14
*/ */
void WriteNetListCADSTAR( SCH_EDIT_FRAME* frame, FILE* f ); void WriteNetListCADSTAR( FILE* f );
/** /**
* Function WriteNetListPspice * Function WriteNetListPspice
* generates a netlist file in PSPICE format. * generates a netlist file in PSPICE format.
* <p> * <p>
* All graphics text commentary by a [.-+] PSpice or [.-+] gnucap * All graphics text starting by [.-+] PSpice or [.-+] gnucap
* Are considered in placing orders in the netlist * are seen as spice directives and put in netlist
* [.-] Or PSpice gnucap are beginning * .-PSpice or .-gnucap put at beginning of the netlist
* + + Gnucap and PSpice are ultimately NetList * .+PSpice or .-genucap are put at end of the netList
* @param frame = the parent SCH_EDIT_FRAME frame
* @param f = the file to write to * @param f = the file to write to
* @param use_netnames if true, then nodes are identified by the netname, * @param use_netnames = true, to use netnames in netlist,
* else by net number. * false to use net number.
*/ */
bool WriteNetListPspice( SCH_EDIT_FRAME* frame, FILE* f, bool use_netnames ); bool WriteNetListPspice( FILE* f, bool use_netnames );
/** /**
* Function MakeCommandLine * Function MakeCommandLine
@ -385,22 +382,22 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
switch( aFormat ) switch( aFormat )
{ {
case NET_TYPE_PCBNEW: case NET_TYPE_PCBNEW:
ret = helper.WriteNetListPCBNEW( this, f, true ); ret = helper.WriteNetListPCBNEW( f, true );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_ORCADPCB2: case NET_TYPE_ORCADPCB2:
ret = helper.WriteNetListPCBNEW( this, f, false ); ret = helper.WriteNetListPCBNEW( f, false );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_CADSTAR: case NET_TYPE_CADSTAR:
helper.WriteNetListCADSTAR( this, f ); helper.WriteNetListCADSTAR( f );
fclose( f ); fclose( f );
break; break;
case NET_TYPE_SPICE: case NET_TYPE_SPICE:
ret = helper.WriteNetListPspice( this, f, aUse_netnames ); ret = helper.WriteNetListPspice( f, aUse_netnames );
fclose( f ); fclose( f );
break; break;
@ -411,7 +408,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
D(printf("tmpFile:'%s'\n", CONV_TO_UTF8( tmpFile.GetFullPath() ) );) D(printf("tmpFile:'%s'\n", CONV_TO_UTF8( tmpFile.GetFullPath() ) );)
ret = helper.WriteGENERICNetList( this, tmpFile.GetFullPath() ); ret = helper.WriteGENERICNetList( tmpFile.GetFullPath() );
if( !ret ) if( !ret )
break; break;
@ -542,7 +539,7 @@ SCH_COMPONENT* EXPORT_HELP::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH*
} }
SCH_COMPONENT* EXPORT_HELP::findNextComponentAndCreatPinList( EDA_ITEM* aItem, SCH_COMPONENT* EXPORT_HELP::findNextComponentAndCreatePinList( EDA_ITEM* aItem,
SCH_SHEET_PATH* aSheetPath ) SCH_SHEET_PATH* aSheetPath )
{ {
wxString ref; wxString ref;
@ -863,6 +860,9 @@ XNODE* EXPORT_HELP::makeGenericListOfNets()
if( nitem->m_Type != NET_PIN ) if( nitem->m_Type != NET_PIN )
continue; continue;
if( nitem->m_Flag != 0 ) // Redundant pin, skip it
continue;
comp = (SCH_COMPONENT*) nitem->m_Link; comp = (SCH_COMPONENT*) nitem->m_Link;
// Get the reference for the net name and the main parent component // Get the reference for the net name and the main parent component
@ -953,7 +953,7 @@ XNODE* EXPORT_HELP::makeGenericComponents()
{ {
for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() ) for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
SCH_COMPONENT* comp = findNextComponent( schItem, path ); SCH_COMPONENT* comp = findNextComponentAndCreatePinList( schItem, path );
if( !comp ) if( !comp )
break; // No component left break; // No component left
@ -1025,8 +1025,12 @@ XNODE* EXPORT_HELP::makeGenericComponents()
#include <wx/wfstream.h> // wxFFileOutputStream #include <wx/wfstream.h> // wxFFileOutputStream
bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aOutFileName ) bool EXPORT_HELP::WriteGENERICNetList( const wxString& aOutFileName )
{ {
// Prepare list of nets generation
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0;
#if 0 #if 0
// this code seems to work now, for S-expression support. // this code seems to work now, for S-expression support.
@ -1038,7 +1042,7 @@ bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aO
{ {
L_error: L_error:
wxString msg = _( "Failed to create file " ) + aOutFileName; wxString msg = _( "Failed to create file " ) + aOutFileName;
DisplayError( frame, msg ); DisplayError( NULL, msg );
} }
else else
{ {
@ -1080,7 +1084,7 @@ bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aO
if( ( out = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL ) if( ( out = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
{ {
wxString msg = _( "Failed to create file " ) + aOutFileName; wxString msg = _( "Failed to create file " ) + aOutFileName;
DisplayError( frame, msg ); DisplayError( NULL, msg );
return false; return false;
} }
@ -1097,7 +1101,7 @@ bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aO
{ {
for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() ) for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() )
{ {
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( schItem, path ); SCH_COMPONENT* comp = findNextComponentAndCreatePinList( schItem, path );
if( !comp ) if( !comp )
break; // No component left break; // No component left
@ -1163,7 +1167,7 @@ bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aO
} }
bool EXPORT_HELP::WriteNetListPspice( SCH_EDIT_FRAME* frame, FILE* f, bool use_netnames ) bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames )
{ {
int ret = 0; int ret = 0;
char Line[1024]; char Line[1024];
@ -1181,6 +1185,10 @@ bool EXPORT_HELP::WriteNetListPspice( SCH_EDIT_FRAME* frame, FILE* f, bool use_n
ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n", NETLIST_HEAD_STRING, Line ); ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n", NETLIST_HEAD_STRING, Line );
// Prepare list of nets generation (not used here, but...
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0;
// Create text list starting by [.-]pspice , or [.-]gnucap (simulator // Create text list starting by [.-]pspice , or [.-]gnucap (simulator
// commands) and create text list starting by [+]pspice , or [+]gnucap // commands) and create text list starting by [+]pspice , or [+]gnucap
// (simulator commands) // (simulator commands)
@ -1255,7 +1263,7 @@ bool EXPORT_HELP::WriteNetListPspice( SCH_EDIT_FRAME* frame, FILE* f, bool use_n
{ {
for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() ) for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() )
{ {
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( item, sheet ); SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet );
if( !comp ) if( !comp )
break; break;
@ -1316,7 +1324,7 @@ bool EXPORT_HELP::WriteNetListPspice( SCH_EDIT_FRAME* frame, FILE* f, bool use_n
} }
bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_pcbnew ) bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
{ {
wxString field; wxString field;
wxString footprint; wxString footprint;
@ -1333,8 +1341,11 @@ bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_
else else
ret |= fprintf( f, "( { %s created %s }\n", NETLIST_HEAD_STRING, dateBuf ); ret |= fprintf( f, "( { %s created %s }\n", NETLIST_HEAD_STRING, dateBuf );
// Create netlist module section // Prepare list of nets generation
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0;
// Create netlist module section
m_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
@ -1343,7 +1354,7 @@ bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_
{ {
for( EDA_ITEM* item = path->LastDrawList(); item; item = item->Next() ) for( EDA_ITEM* item = path->LastDrawList(); item; item = item->Next() )
{ {
SCH_COMPONENT* comp = findNextComponentAndCreatPinList( item, path ); SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, path );
if( !comp ) if( !comp )
break; break;
@ -1494,7 +1505,11 @@ bool EXPORT_HELP::addPinToComponentPinList( SCH_COMPONENT* aComponent,
return false; return false;
} }
/*
* remove duplicate pins from aPinList (list of pins relative to a given component)
* (i.e. set pointer to duplicate pins to NULL in this list).
* also set .m_Flag member of "removed" NETLIST_OBJECT pins to 1
*/
void EXPORT_HELP::eraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList ) void EXPORT_HELP::eraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
{ {
if( aPinList.size() == 0 ) // Trivial case: component with no pin if( aPinList.size() == 0 ) // Trivial case: component with no pin
@ -1519,27 +1534,34 @@ void EXPORT_HELP::eraseDuplicatePins( NETLIST_OBJECT_LIST& aPinList )
if( aPinList[jj] == NULL ) // Already removed if( aPinList[jj] == NULL ) // Already removed
continue; continue;
// other pin num end of duplicate list. // if other pin num, stop search,
// because all pins having the same number are consecutive in list.
if( aPinList[idxref]->m_PinNum != aPinList[jj]->m_PinNum ) if( aPinList[idxref]->m_PinNum != aPinList[jj]->m_PinNum )
break; break;
if( aPinList[idxref]->m_FlagOfConnection == PAD_CONNECT ) if( aPinList[idxref]->m_FlagOfConnection == PAD_CONNECT )
{
aPinList[jj]->m_Flag = 1;
aPinList[jj] = NULL; aPinList[jj] = NULL;
}
else /* the reference pin is not connected: remove this pin if the else /* the reference pin is not connected: remove this pin if the
* other pin is connected */ * other pin is connected */
{ {
if( aPinList[jj]->m_FlagOfConnection == PAD_CONNECT ) if( aPinList[jj]->m_FlagOfConnection == PAD_CONNECT )
{ {
aPinList[idxref]->m_Flag = 1;
aPinList[idxref] = NULL; aPinList[idxref] = NULL;
idxref = jj; idxref = jj;
} }
else // the 2 pins are not connected: remove the tested pin, else // the 2 pins are not connected: remove the tested pin,
// and continue ... { // and continue ...
aPinList[jj]->m_Flag = 1;
aPinList[jj] = NULL; aPinList[jj] = NULL;
} }
} }
} }
} }
}
void EXPORT_HELP::findAllInstancesOfComponent( SCH_COMPONENT* aComponent, void EXPORT_HELP::findAllInstancesOfComponent( SCH_COMPONENT* aComponent,
@ -1634,6 +1656,9 @@ bool EXPORT_HELP::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjects
if( aObjectsList[ii]->m_Type != NET_PIN ) if( aObjectsList[ii]->m_Type != NET_PIN )
continue; continue;
if( aObjectsList[ii]->m_Flag != 0 ) // Redundant pin, skip it
continue;
comp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link; comp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link;
// Get the reference for the net name and the main parent component // Get the reference for the net name and the main parent component
@ -1674,7 +1699,7 @@ bool EXPORT_HELP::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjects
static wxString StartLine( wxT( "." ) ); static wxString StartLine( wxT( "." ) );
void EXPORT_HELP::WriteNetListCADSTAR( SCH_EDIT_FRAME* frame, FILE* f ) void EXPORT_HELP::WriteNetListCADSTAR( FILE* f )
{ {
wxString StartCmpDesc = StartLine + wxT( "ADD_COM" ); wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
wxString msg; wxString msg;
@ -1692,6 +1717,10 @@ void EXPORT_HELP::WriteNetListCADSTAR( SCH_EDIT_FRAME* frame, FILE* f )
fprintf( f, "\"%s\"\n", CONV_TO_UTF8( Title ) ); fprintf( f, "\"%s\"\n", CONV_TO_UTF8( Title ) );
fprintf( f, "\n" ); fprintf( f, "\n" );
// Prepare list of nets generation
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0;
// Create netlist module section // Create netlist module section
m_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
@ -1701,7 +1730,7 @@ void EXPORT_HELP::WriteNetListCADSTAR( SCH_EDIT_FRAME* frame, FILE* f )
{ {
for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() ) for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
{ {
DrawList = Component = findNextComponentAndCreatPinList( DrawList, sheet ); DrawList = Component = findNextComponentAndCreatePinList( DrawList, sheet );
if( Component == NULL ) if( Component == NULL )
break; break;
@ -1748,9 +1777,6 @@ void EXPORT_HELP::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjects
SCH_COMPONENT* Cmp; SCH_COMPONENT* Cmp;
wxString NetName; wxString NetName;
for( ii = 0; ii < aObjectsList.size(); ii++ )
aObjectsList[ii]->m_Flag = 0;
for( ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( ii = 0; ii < g_NetObjectslist.size(); ii++ )
{ {
// Get the NetName of the current net : // Get the NetName of the current net :
@ -1829,24 +1855,5 @@ void EXPORT_HELP::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST& aObjects
} }
aObjectsList[ii]->m_Flag = 1; aObjectsList[ii]->m_Flag = 1;
// Search for redundant pins to avoid generation of the same connection
// more than once.
for( unsigned jj = ii + 1; jj < aObjectsList.size(); jj++ )
{
if( aObjectsList[jj]->GetNet() != NetCode )
break;
if( aObjectsList[jj]->m_Type != NET_PIN )
continue;
SCH_COMPONENT* tstcmp =
(SCH_COMPONENT*) aObjectsList[jj]->m_Link;
wxString p = Cmp->GetPath( &( aObjectsList[ii]->m_SheetList ) );
wxString tstp = tstcmp->GetPath( &( aObjectsList[jj]->m_SheetList ) );
if( p.Cmp( tstp ) != 0 )
continue;
if( aObjectsList[jj]->m_PinNum == aObjectsList[ii]->m_PinNum )
aObjectsList[jj]->m_Flag = 1;
}
} }
} }

View File

@ -126,10 +126,10 @@
<pin num="1" type="passive"/> <pin num="1" type="passive"/>
<pin num="2" type="passive"/> <pin num="2" type="passive"/>
</pins> </pins>
Output pin list is ( pin num = net name ) Output pin list is ( <pin num> <net name> )
something like something like
( 1 = VCC ) ( 1 VCC )
( 2 = GND ) ( 2 GND )
--> -->
<xsl:template name="build_pin_list" match="pin"> <xsl:template name="build_pin_list" match="pin">
<xsl:param name="cmp_ref" select="0" /> <xsl:param name="cmp_ref" select="0" />
@ -137,7 +137,7 @@
<!-- write pin numner and separator --> <!-- write pin numner and separator -->
<xsl:text> ( </xsl:text> <xsl:text> ( </xsl:text>
<xsl:value-of select="@num"/> <xsl:value-of select="@num"/>
<xsl:text> = </xsl:text> <xsl:text> </xsl:text>
<!-- search net name in nets section and write it: --> <!-- search net name in nets section and write it: -->
<xsl:variable name="pinNum" select="@num" /> <xsl:variable name="pinNum" select="@num" />