41 #include <wx/tokenzr.h> 49 auto it = std::find_if( spiceItems.begin(), spiceItems.end(),
52 return item.m_refName == aSymbol;
55 if( it == spiceItems.end() )
59 return it->m_primitive != it->m_refName[0] ? wxString( it->m_primitive + it->m_refName )
71 return Format( &outputFile, aNetlistOptions );
76 msg.Printf(
_(
"Failed to create file '%s'." ), aOutFileName );
89 aNetName.Replace(
"(",
"_" );
90 aNetName.Replace(
")",
"_" );
91 aNetName.Replace(
" ",
"_" );
98 const bool useNetcodeAsNetName =
false;
120 if( full_path.IsEmpty() )
132 aFormatter->
Print( 0,
".include \"%s\"\n",
TO_UTF8( full_path ) );
135 unsigned int NC_counter = 1;
139 if( !item.m_enabled )
146 item.m_pinSequence.empty() ? item.m_pins.size() : item.m_pinSequence.size();
148 for(
size_t ii = 0; ii < pspiceNodes; ii++ )
152 size_t activePinIndex = item.m_pinSequence.empty() ? ii : item.m_pinSequence[ii];
156 if( activePinIndex >= item.m_pins.size() )
158 wxASSERT_MSG(
false,
"Used an invalid pin number in node sequence" );
162 wxString netName = item.m_pins[activePinIndex];
164 wxASSERT(
m_netMap.count( netName ) );
166 if( useNetcodeAsNetName )
179 if( netName.IsEmpty() )
186 aFormatter->
Print( 0,
"%s\n",
TO_UTF8( item.m_model ) );
192 aFormatter->
Print( 0,
".end\n" );
214 return refName.GetChar( 0 );
228 wxT(
"^([0-9\\. ]+)([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?([fFhHΩΩ𝛀𝛺𝝮]|ohm)?([-1-9 ]*)$" ) );
230 if( passiveVal.Matches( value ) )
232 wxString prefix( passiveVal.GetMatch( value, 1 ) );
233 wxString unit( passiveVal.GetMatch( value, 2 ) );
234 wxString suffix( passiveVal.GetMatch( value, 6 ) );
236 prefix.Trim(); prefix.Trim(
false );
237 unit.Trim(); unit.Trim(
false );
238 suffix.Trim(); suffix.Trim(
false );
244 value = prefix + unit + suffix;
252 return wxString(
"Y" );
257 std::vector<LIB_PIN*> pins;
263 nodeSeq +=
pin->GetNumber() +
" ";
272 return wxEmptyString;
275 wxASSERT_MSG(
false,
"Missing default value definition for a Spice field." );
276 return wxString(
"<unknown>" );
283 const wxString delimiters(
"{:,; }" );
285 std::set<wxString> refNames;
297 for(
unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ )
322 if( refNames.count( spiceItem.
m_refName ) )
324 DisplayError(
nullptr,
_(
"Multiple symbols have the same reference designator.\n" 325 "Annotation must be corrected before simulating." ) );
334 if( fieldLibFile && !fieldLibFile->
GetShownText().IsEmpty() )
337 wxArrayString pinNames;
343 spiceItem.
m_pins.push_back(
pin.netName );
344 pinNames.Add(
pin.num );
354 const wxString& nodeSeqIndexLineStr = fieldSeq->
GetShownText();
357 if( !nodeSeqIndexLineStr.IsEmpty() )
360 wxStringTokenizer tkz( nodeSeqIndexLineStr, delimiters );
362 while( tkz.HasMoreTokens() )
364 wxString pinIndex = tkz.GetNextToken();
368 seq = pinNames.Index( pinIndex );
370 if( seq != wxNOT_FOUND )
387 wxRegEx couplingK(
"^[kK][[:digit:]]*[[:space:]]+[[:alnum:]]+[[:space:]]+[[:alnum:]]+",
391 bool controlBlock =
false;
392 bool circuitBlock =
false;
394 for(
unsigned i = 0; i < sheetList.size(); i++ )
398 wxString
text = static_cast<SCH_TEXT*>( item )->GetShownText();
404 wxStringTokenizer tokenizer(
text,
"\r\n" );
407 bool directiveStarted =
false;
409 while( tokenizer.HasMoreTokens() )
411 wxString line( tokenizer.GetNextToken() );
414 line.Trim(
true ).Trim(
false );
416 wxString lowercaseline = line;
417 lowercaseline.MakeLower();
421 if( lowercaseline.StartsWith(
".inc" ) )
423 wxString lib = line.AfterFirst(
' ' );
429 if( ( lib.StartsWith(
"\"" ) && lib.EndsWith(
"\"" ) )
430 || ( lib.StartsWith(
"'" ) && lib.EndsWith(
"'" ) ) )
432 lib = lib.Mid( 1, lib.Length() - 2 );
440 else if( lowercaseline.StartsWith(
".title " ) )
442 m_title = line.AfterFirst(
' ' );
445 else if( line.StartsWith(
'.' )
448 || couplingK.Matches( line )
449 || ( directiveStarted && line.StartsWith(
'+' ) ) )
455 if( lowercaseline.IsSameAs(
".control" ) && ( !controlBlock ) )
458 if( lowercaseline.IsSameAs(
".endc" ) && controlBlock )
459 controlBlock =
false;
462 if( lowercaseline.StartsWith(
".subckt" ) && ( !circuitBlock ) )
465 if( lowercaseline.IsSameAs(
".ends" ) && circuitBlock )
466 circuitBlock =
false;
469 directiveStarted = line.StartsWith(
'.' )
470 || ( directiveStarted && line.StartsWith(
'+' ) );
488 "Spice_Netlist_Enabled",
489 "Spice_Node_Sequence",
Field Reference of part, i.e. "IC21".
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
EE_TYPE OfType(KICAD_T aType) const
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
bool Format(OUTPUTFORMATTER *aFormatter, unsigned aCtl)
wxString ResolveFile(const wxString &aFileName, const ENV_VAR_MAP *aEnvVars, const PROJECT *aProject)
Search the default paths trying to find one with the requested file.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
std::set< wxString > m_libraries
Spice libraries used by the simulated circuit.
std::vector< PIN_INFO > m_sortedSymbolPinList
Used to temporarily store and filter the list of pins of a schematic symbol when generating schematic...
This file is part of the common library.
std::list< SPICE_ITEM > m_spiceItems
Items representing schematic symbols in Spice world.
Structure to represent a schematic symbol in the Spice simulation.
std::vector< wxString > m_pins
Array containing Standard Pin Name.
static const wxString & GetSpiceFieldName(SPICE_FIELD aField)
Return a string used for a particular component field related to Spice simulation.
bool m_enabled
Whether the symbol should be used in simulation.
void Clear()
Erase the record.
std::vector< wxString > m_directives
Spice directives found in the schematic sheet.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
static bool StringToBool(const wxString &aStr)
Convert typical boolean string values (no/yes, true/false, 1/0) to a boolean value.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
SCH_SYMBOL * m_parent
Schematic symbol represented by this SPICE_ITEM.
wxString m_model
Library model (for semiconductors and subcircuits), component value (for passive components) or volta...
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
SCH_SYMBOL * findNextSymbol(EDA_ITEM *aItem, SCH_SHEET_PATH *aSheetPath)
Check if the given symbol should be processed for netlisting.
SCHEMATIC_IFACE * m_schematic
The schematic we're generating a netlist for.
virtual PROJECT & Prj() const =0
UNIQUE_STRINGS m_referencesAlreadyFound
Used for "multiple symbols per package" symbols to avoid processing a lib symbol more than once.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxString m_title
Spice simulation title found in the schematic sheet.
std::map< wxString, int > m_netMap
Map spice nodes to net codes.
Field Value of part, i.e. "3.3K".
const std::list< SPICE_ITEM > & GetSpiceItems() const
Return list of items representing schematic components in the Spice world.
static wxString GetSpiceFieldDefVal(SPICE_FIELD aField, SCH_SYMBOL *aSymbol, unsigned aCtl)
Retrieve the default value for a given field.
virtual void writeDirectives(OUTPUTFORMATTER *aFormatter, unsigned aCtl) const
Save the Spice directives.
void CreatePinList(SCH_SYMBOL *aSymbol, SCH_SHEET_PATH *aSheetPath, bool aKeepUnconnectedPins)
Find a symbol from the DrawList and builds its pin list in m_sortedSymbolPinList.
void UpdateDirectives(unsigned aCtl)
Update the vector of Spice directives placed in the schematics.
wxString GetSpiceDevice(const wxString &aSymbol) const
Return name of Spice device corresponding to a schematic symbol.
bool ProcessNetlist(unsigned aCtl)
Process the netlist to create net mapping and a list of SPICE_ITEMs.
static void ReplaceForbiddenChars(wxString &aNetName)
Replace illegal spice net name characters with an underscore.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true)
Search for a SCH_FIELD with aFieldName.
wxString UnescapeString(const wxString &aSource)
static wxString GetSpiceField(SPICE_FIELD aField, SCH_SYMBOL *aSymbol, unsigned aCtl)
Retrieve either the requested field value or the default value.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
bool WriteNetlist(const wxString &aOutFileName, unsigned aNetlistOptions) override
Write to specified output file.
SCH_SCREEN * LastScreen()
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
static const std::vector< wxString > m_spiceFields
wxChar m_primitive
Spice primitive type (.
std::vector< int > m_pinSequence
Numeric indices into m_SortedSymbolPinList.
std::set< LIB_SYMBOL *, LIB_SYMBOL_LESS_THAN > m_libParts
unique library symbols used. LIB_SYMBOL items are sorted by names
virtual SCH_SHEET_LIST GetSheets() const =0
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Base class for any item which can be embedded within the SCHEMATIC container class,...