XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets() { XNODE* xnets = node( wxT( "nets" ) ); // auto_ptr if exceptions ever get used. wxString netCodeTxt; wxString netName; wxString ref; wxString sNet = wxT( "net" ); wxString sName = wxT( "name" ); wxString sCode = wxT( "code" ); wxString sRef = wxT( "ref" ); wxString sPin = wxT( "pin" ); wxString sNode = wxT( "node" ); wxString sFmtd = wxT( "%d" ); XNODE* xnet = 0; int netCode; int lastNetCode = -1; int sameNetcodeCount = 0; /* output: <net code="123" name="/cfcard.sch/WAIT#"> <node ref="R23" pin="1"/> <node ref="U18" pin="12"/> </net> */ m_LibParts.clear(); // must call this function before using m_LibParts. for( unsigned ii = 0; ii < m_masterList->size(); ii++ ) { NETLIST_OBJECT* nitem = m_masterList->GetItem( ii ); SCH_COMPONENT* comp; // New net found, write net id; if( ( netCode = nitem->GetNet() ) != lastNetCode ) { sameNetcodeCount = 0; // item count for this net netName = nitem->GetNetName(); lastNetCode = netCode; } if( nitem->m_Type != NET_PIN ) 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 ) { xnets->AddChild( xnet = node( sNet ) ); netCodeTxt.Printf( sFmtd, netCode ); xnet->AddAttribute( sCode, netCodeTxt ); xnet->AddAttribute( sName, netName ); } XNODE* xnode; xnet->AddChild( xnode = node( sNode ) ); xnode->AddAttribute( sRef, ref ); xnode->AddAttribute( sPin, nitem->GetPinNumText() ); } return xnets; }
bool NETLIST_EXPORTER_CADSTAR::writeListOfNets( FILE* f ) { int ret = 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 netName; for( ii = 0; ii < m_masterList->size(); ii++ ) { NETLIST_OBJECT* nitem = m_masterList->GetItem( ii ); // Get the NetName of the current net : if( ( NetCode = nitem->GetNet() ) != lastNetCode ) { netName = nitem->GetNetName(); netcodeName = wxT( "\"" ); 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; } if( nitem->m_Type != NET_PIN ) continue; if( nitem->m_Flag != 0 ) continue; Cmp = nitem->GetComponentParent(); wxString refstr = Cmp->GetRef( &nitem->m_SheetPath ); if( refstr[0] == '#' ) continue; // Power supply symbols. switch( print_ter ) { case 0: { char buf[5]; wxString str_pinnum; strncpy( buf, (char*) &nitem->m_PinNum, 4 ); buf[4] = 0; str_pinnum = FROM_UTF8( buf ); InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ), GetChars( InitNetDesc ), GetChars( refstr ), GetChars( str_pinnum ), GetChars( netcodeName ) ); } 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 ), (char*) &nitem->m_PinNum ); print_ter++; break; default: ret |= fprintf( f, " %s %.4s\n", TO_UTF8( refstr ), (char*) &nitem->m_PinNum ); break; } nitem->m_Flag = 1; } return ret >= 0; }
bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) { // Netlist options const bool useNetcodeAsNetName = false;//aCtl & NET_USE_NETCODES_AS_NETNAMES; if( !ProcessNetlist( aCtl ) ) return false; aFormatter->Print( 0, ".title KiCad schematic\n" ); // Write .include directives for( auto lib : m_libraries ) { wxString full_path; if( ( aCtl & NET_ADJUST_INCLUDE_PATHS ) && m_paths ) { // Look for the library in known search locations full_path = m_paths->FindValidPath( lib ); if( full_path.IsEmpty() ) { DisplayError( NULL, wxString::Format( _( "Could not find library file %s" ), lib ) ); full_path = lib; } } aFormatter->Print( 0, ".include \"%s\"\n", (const char*) full_path.c_str() ); } for( const auto& item : m_spiceItems ) { if( !item.m_enabled ) continue; aFormatter->Print( 0, "%c%s ", item.m_primitive, (const char*) item.m_refName.c_str() ); // Pins to node mapping int activePinIndex = 0; for( unsigned ii = 0; ii < item.m_pins.size(); ii++ ) { // Case of Alt Sequence definition with Unused/Invalid Node index: // Valid used Node Indexes are in the set // {0,1,2,...m_item.m_pin.size()-1} if( !item.m_pinSequence.empty() ) { // All Vector values must be less <= max package size // And Total Vector size should be <= package size if( ( (unsigned) item.m_pinSequence[ii] < item.m_pins.size() ) && ( ii < item.m_pinSequence.size() ) ) { // Case of Alt Pin Sequence in control good Index: activePinIndex = item.m_pinSequence[ii]; } else { // Case of Alt Pin Sequence in control Bad Index or not using all // pins for simulation: wxASSERT_MSG( false, "Used an invalid pin number in node sequence" ); continue; } } // Case of Standard Pin Sequence in control: else { activePinIndex = ii; } NETLIST_OBJECT* pin = item.m_pins[activePinIndex]; assert( pin ); wxString netName = pin->GetNetName(); 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 ); if( netName.IsEmpty() ) netName = wxT( "?" ); aFormatter->Print( 0, "%s ", TO_UTF8( netName ) ); } } aFormatter->Print( 0, "%s\n", (const char*) item.m_model.c_str() ); } // Print out all directives found in the text fields on the schematics writeDirectives( aFormatter, aCtl ); aFormatter->Print( 0, ".end\n" ); return true; }
bool NETLIST_EXPORTER_GENERIC::writeListOfNets( FILE* f, NETLIST_OBJECT_LIST& aObjectsList ) { int ret = 0; int netCode; int lastNetCode = -1; int sameNetcodeCount = 0; wxString netName; wxString ref; wxString netcodeName; char firstItemInNet[256]; for( unsigned ii = 0; ii < aObjectsList.size(); ii++ ) { SCH_COMPONENT* comp; NETLIST_OBJECT* nitem = aObjectsList[ii]; // New net found, write net id; if( ( netCode = nitem->GetNet() ) != lastNetCode ) { sameNetcodeCount = 0; // Items count for this net netName = nitem->GetNetName(); netcodeName.Printf( wxT( "Net %d " ), netCode ); netcodeName << wxT( "\"" ) << netName << wxT( "\"" ); // Add the netname without prefix, in cases we need only the // "short" netname netcodeName += wxT( " \"" ) + nitem->GetShortNetName() + wxT( "\"" ); lastNetCode = netCode; } if( nitem->m_Type != NET_PIN ) 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; // Pseudo component (Like Power symbol) // Print the pin list for this net, use special handling if // 2 or more items are connected: // if first item for this net found, defer printing this connection // until a second item will is found if( ++sameNetcodeCount == 1 ) { snprintf( firstItemInNet, sizeof(firstItemInNet), " %s %.4s\n", TO_UTF8( ref ), (const char*) &aObjectsList[ii]->m_PinNum ); } // Second item for this net found, print the Net name, and the // first item if( sameNetcodeCount == 2 ) { ret |= fprintf( f, "%s\n", TO_UTF8( netcodeName ) ); ret |= fputs( firstItemInNet, f ); } if( sameNetcodeCount >= 2 ) ret |= fprintf( f, " %s %.4s\n", TO_UTF8( ref ), (const char*) &nitem->m_PinNum ); } return ret >= 0; }
bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl ) { const wxString delimiters( "{:,; }" ); SCH_SHEET_LIST sheetList( g_RootSheet ); // 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(); UpdateDirectives( aCtl ); for( unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ ) { // Process component attributes to find Spice directives for( EDA_ITEM* item = sheetList[sheet_idx].LastDrawList(); item; item = item->Next() ) { SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, &sheetList[sheet_idx] ); if( !comp ) break; item = comp; SPICE_ITEM spiceItem; spiceItem.m_parent = comp; // Obtain Spice fields SCH_FIELD* fieldLibFile = comp->FindField( GetSpiceFieldName( SF_LIB_FILE ) ); SCH_FIELD* fieldSeq = comp->FindField( GetSpiceFieldName( SF_NODE_SEQUENCE ) ); 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] ); // Duplicate references will result in simulation errors if( refNames.count( spiceItem.m_refName ) ) { DisplayError( NULL, wxT( "There are duplicate components. " "You need to annotate schematics first." ) ); return false; } refNames.insert( spiceItem.m_refName ); // Check to see if component should be removed from Spice netlist spiceItem.m_enabled = StringToBool( GetSpiceField( SF_ENABLED, comp, aCtl ) ); if( fieldLibFile && !fieldLibFile->GetText().IsEmpty() ) m_libraries.insert( fieldLibFile->GetText() ); wxArrayString pinNames; // Store pin information for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ ) { NETLIST_OBJECT* pin = m_SortedComponentPinList[ii]; // NETLIST_EXPORTER marks removed pins by setting them to NULL if( !pin ) continue; spiceItem.m_pins.push_back( pin ); pinNames.Add( pin->GetPinNumText() ); // Create net mapping const wxString& netName = pin->GetNetName(); if( m_netMap.count( netName ) == 0 ) m_netMap[netName] = netIdx++; } // Check if an alternative pin sequence is available: if( fieldSeq ) { // Get the string containing the sequence of nodes: wxString nodeSeqIndexLineStr = fieldSeq->GetText(); // Verify field exists and is not empty: if( !nodeSeqIndexLineStr.IsEmpty() ) { // Get Alt Pin Name Array From User: wxStringTokenizer tkz( nodeSeqIndexLineStr, delimiters ); while( tkz.HasMoreTokens() ) { wxString pinIndex = tkz.GetNextToken(); int seq; // Find PinName In Standard List assign Standard List Index to Name: seq = pinNames.Index( pinIndex ); if( seq != wxNOT_FOUND ) spiceItem.m_pinSequence.push_back( seq ); } } } m_spiceItems.push_back( spiceItem ); } } return true; }