From 628f874c079aadf3c3e34950287c1417a51c78b5 Mon Sep 17 00:00:00 2001 From: Charles McDowell Date: Mon, 14 Mar 2011 15:20:05 -0500 Subject: [PATCH] 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. --- eeschema/netform.cpp | 156 +++++++++++++++++++++++++++++++++---------- 1 file changed, 121 insertions(+), 35 deletions(-) diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 0fb2680075..cda8e52c03 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -48,7 +48,10 @@ #include "sch_component.h" #include "sch_text.h" #include "sch_sheet.h" -#include "template_fieldnames.h" +#include "template_fieldnames.h" +#include + + #include "xnode.h" // also nests: @@ -1195,18 +1198,26 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) wxArrayString spiceCommandAtBeginFile; wxArrayString spiceCommandAtEndFile; 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]; DateAndTime( 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; + 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; + + 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 // commands) and create text list starting by [+]pspice , or [+]gnucap @@ -1280,6 +1291,7 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) 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() ) { SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, sheet ); @@ -1287,13 +1299,77 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) break; 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 ) ) ); + + + // Write pin list: + int ActivePinIndex = 0; - // Write pin list: 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 ) continue; @@ -1314,33 +1390,43 @@ bool EXPORT_HELP::WriteNetListPspice( FILE* f, bool use_netnames ) ret |= fprintf( f, " %d", pin->GetNet() ); } } - - ret |= fprintf( f, " %s\n", - TO_UTF8( comp->GetField( VALUE )->m_Text ) ); + //Print Component Value: + ret |= fprintf( f, " %s\t\t",TO_UTF8( comp->GetField( VALUE )->m_Text ) ); + + //Show Seq Spec on same line as component using line-comment ";": + for(int jj=0;jj"); + } + //Next Netlist line record: + ret |= fprintf( f, "\n"); } } - m_SortedComponentPinList.clear(); - - // Print texts starting with [+]pspice or [+]gnucap - nbitems = spiceCommandAtEndFile.GetCount(); - if( nbitems ) - { - ret |= fprintf( f, "\n" ); - spiceCommandAtEndFile.Sort(); - for( int ii = 0; ii < nbitems; ii++ ) - { - spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN ); - spiceCommandAtEndFile[ii].Trim( true ); - spiceCommandAtEndFile[ii].Trim( false ); - ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) ); - } - } - - ret |= fprintf( f, "\n.end\n" ); - + m_SortedComponentPinList.clear(); + + // Print texts starting with [+]pspice or [+]gnucap + nbitems = spiceCommandAtEndFile.GetCount(); + if( nbitems ) + { + ret |= fprintf( f, "\n" ); + spiceCommandAtEndFile.Sort(); + for( int ii = 0; ii < nbitems; ii++ ) + { + spiceCommandAtEndFile[ii].Remove( 0, +BUFYPOS_LEN ); + spiceCommandAtEndFile[ii].Trim( true ); + spiceCommandAtEndFile[ii].Trim( false ); + ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtEndFile[ii] ) ); + } + } + + ret |= fprintf( f, "\n.end\n" ); + return ret >= 0; -} +} + bool EXPORT_HELP::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )