Commit 628f874c authored by Charles McDowell's avatar Charles McDowell Committed by Dick Hollenbeck

The following patch adds two features to the standard SpiceNetlister:

F1.) Allows you to disable a component from the Netlist. Useful for connectors etc.
To exclude a component from the Spice Netlist add [Spice_Netlist_Enabled] user FIELD set to: N

F2.) Allows you to adapt to simulation libraries that require the netlist node sequence to be in a different order.
To reorder the component spice node sequence add [Spice_Node_Sequence] user FIELD and define sequence: 2,1,0 I am using LTSpice, but this holds true for any SPICE subcircuit.

Note1: Patch maintains existing SpiceNetlister behavior as far as I can tell
------------------------------------------------------------------
Updated Patch from Prior release:
New Changes consists of:
1.) Now allowing user to put in less Nodes then exist on the actual part.
2.) Now echoing Schematic Sheet Netlist components come from. This helps users segment the netlist in to understandable blocks of code that mimic the schematic sheets.
3.) Retested.
parent fe6890a9
...@@ -48,7 +48,10 @@ ...@@ -48,7 +48,10 @@
#include "sch_component.h" #include "sch_component.h"
#include "sch_text.h" #include "sch_text.h"
#include "sch_sheet.h" #include "sch_sheet.h"
#include "template_fieldnames.h" #include "template_fieldnames.h"
#include <wx/tokenzr.h>
#include "xnode.h" // also nests: <wx/xml/xml.h> #include "xnode.h" // also nests: <wx/xml/xml.h>
...@@ -1195,18 +1198,26 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ...@@ -1195,18 +1198,26 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames )
wxArrayString spiceCommandAtBeginFile; wxArrayString spiceCommandAtBeginFile;
wxArrayString spiceCommandAtEndFile; wxArrayString spiceCommandAtEndFile;
wxString msg; wxString msg;
wxString netName; wxString netName;
#define BUFYPOS_LEN 4
#define WORSE_CASE_PIN_COUNT 500
long int NodeSeqIndexArray[WORSE_CASE_PIN_COUNT];
int NodeSeqIndex=0;
#define BUFYPOS_LEN 4
wxChar bufnum[BUFYPOS_LEN + 1]; wxChar bufnum[BUFYPOS_LEN + 1];
DateAndTime( Line ); DateAndTime( Line );
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... // Prepare list of nets generation (not used here, but...
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ ) for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
g_NetObjectslist[ii]->m_Flag = 0; g_NetObjectslist[ii]->m_Flag = 0;
ret |= fprintf( f, "* To exclude a component from the Spice Netlist add [Spice_Netlist_Enabled] user FIELD set to: N\n");
ret |= fprintf( f, "* To reorder the component spice node sequence add [Spice_Node_Sequence] user FIELD and define sequence: 2,1,0\n");
// 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
...@@ -1280,6 +1291,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ...@@ -1280,6 +1291,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames )
for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() ) for( SCH_SHEET_PATH* sheet = sheetList.GetFirst(); sheet; sheet = sheetList.GetNext() )
{ {
fprintf(f,"*Sheet Name:%s\n",TO_UTF8(sheet->PathHumanReadable()));
for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() ) for( EDA_ITEM* item = sheet->LastDrawList(); item; item = item->Next() )
{ {
SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet ); SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet );
...@@ -1287,13 +1299,77 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ...@@ -1287,13 +1299,77 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames )
break; break;
item = comp; item = comp;
//Check if Component should be excluded from Netlist
#define SPICE_ENB_FIELD wxT("Spice_Netlist_Enabled")
//Reset NodeSeqIndex Count:
NodeSeqIndex=0;
//Initialize NodeSeqArray to all UNUSED:
#define UNUSED_NODE_FLAG -1
memset(NodeSeqIndexArray,UNUSED_NODE_FLAG,sizeof(NodeSeqIndexArray[WORSE_CASE_PIN_COUNT]));
//Check to see if Component should be removed from Spice Netlist:
wxString DisableStr = wxT("N");
SCH_FIELD* Netlist_Enabled_obj = comp->FindField(SPICE_ENB_FIELD);
if(Netlist_Enabled_obj!=NULL){
wxString Netlist_Enabled_Value = Netlist_Enabled_obj->m_Text;
if(Netlist_Enabled_Value.IsEmpty()) break;
if(Netlist_Enabled_Value.IsNull()) break;
if( Netlist_Enabled_Value.CmpNoCase(DisableStr)==0 ){
continue;
}
}
//Check if Alternative Pin Sequence is Available:
#define SPICE_SEQ_FIELD wxT("Spice_Node_Sequence")
SCH_FIELD* Spice_Seq_obj = comp->FindField(SPICE_SEQ_FIELD);
if(Spice_Seq_obj!=NULL){
//Get String containing the Sequence of Nodes:
wxString NodeSeqIndexLineStr = Spice_Seq_obj->m_Text;
//Verify Field Exists and is not empty:
if(NodeSeqIndexLineStr.IsEmpty()) break;
if(NodeSeqIndexLineStr.IsNull()) break;
//Parse Sequence List Textbox into List of Integer Array:
wxString Delimeters = wxT("{:,; }");
wxStringTokenizer tkz(NodeSeqIndexLineStr, Delimeters);
while ( tkz.HasMoreTokens() ){
wxString NodeSeqIndexStr = tkz.GetNextToken();
if( (NodeSeqIndexStr.IsNumber()) && (NodeSeqIndex < WORSE_CASE_PIN_COUNT) ){
if(NodeSeqIndexStr.ToLong(&NodeSeqIndexArray[NodeSeqIndex],10)){
if(NodeSeqIndexArray[NodeSeqIndex]>=0){
NodeSeqIndex++;
}
}
}
}
}
ret |= fprintf( f, "%s ", TO_UTF8( comp->GetRef( sheet ) ) ); ret |= fprintf( f, "%s ", TO_UTF8( comp->GetRef( sheet ) ) );
// Write pin list:
int ActivePinIndex = 0;
// Write pin list:
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ ) for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{ {
NETLIST_OBJECT* pin = m_SortedComponentPinList[ii]; //Case of Alt Sequence definition with Unused/Invalid Node index:
//Valid used Node Indexes are in the set {0,1,2,...m_SortedComponentPinList.size()-1}
long int MaxPartPinList = m_SortedComponentPinList.size();
if( (NodeSeqIndex!=0) ){
if( (NodeSeqIndexArray[ii] <= UNUSED_NODE_FLAG) ||
(NodeSeqIndexArray[ii] >= MaxPartPinList) ){
continue;
}
}
//Case of Alt Pin Sequence in control:
if(NodeSeqIndex!=0){
ActivePinIndex = NodeSeqIndexArray[ii];
}
//Case of Standard Pin Sequence in control:
else{
ActivePinIndex = ii;
}
NETLIST_OBJECT* pin = m_SortedComponentPinList[ActivePinIndex];
if( !pin ) if( !pin )
continue; continue;
...@@ -1314,33 +1390,43 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ...@@ -1314,33 +1390,43 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames )
ret |= fprintf( f, " %d", pin->GetNet() ); ret |= fprintf( f, " %d", pin->GetNet() );
} }
} }
//Print Component Value:
ret |= fprintf( f, " %s\n", ret |= fprintf( f, " %s\t\t",TO_UTF8( comp->GetField( VALUE )->m_Text ) );
TO_UTF8( comp->GetField( VALUE )->m_Text ) );
//Show Seq Spec on same line as component using line-comment ";":
for(int jj=0;jj<NodeSeqIndex;jj++){
if(jj==0) fprintf(f,";Node Sequence Spec.<");
fprintf(f, "%d",NodeSeqIndexArray[jj]);
if(jj<NodeSeqIndex-1) fprintf(f,",");
else fprintf(f,">");
}
//Next Netlist line record:
ret |= fprintf( f, "\n");
} }
} }
m_SortedComponentPinList.clear(); m_SortedComponentPinList.clear();
// Print texts starting with [+]pspice or [+]gnucap // Print texts starting with [+]pspice or [+]gnucap
nbitems = spiceCommandAtEndFile.GetCount(); nbitems = spiceCommandAtEndFile.GetCount();
if( nbitems ) if( nbitems )
{ {
ret |= fprintf( f, "\n" ); ret |= fprintf( f, "\n" );
spiceCommandAtEndFile.Sort(); spiceCommandAtEndFile.Sort();
for( int ii = 0; ii < nbitems; ii++ ) for( int ii = 0; ii < nbitems; ii++ )
{ {
spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN ); spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN );
spiceCommandAtEndFile[ii].Trim( true ); spiceCommandAtEndFile[ii].Trim( true );
spiceCommandAtEndFile[ii].Trim( false ); spiceCommandAtEndFile[ii].Trim( false );
ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) ); ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) );
} }
} }
ret |= fprintf( f, "\n.end\n" ); ret |= fprintf( f, "\n.end\n" );
return ret >= 0; return ret >= 0;
} }
bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew ) bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment