1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 1992-2013 jp.charras at wanadoo.fr 5 * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> 6 * Copyright (C) 1992-2021 KiCad Developers 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, you may find one here: 20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 21 * or you may search the http://www.gnu.org website for the version 2 license, 22 * or you may write to the Free Software Foundation, Inc., 23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 24 */ 25 26 #ifndef NETLIST_EXPORTER_PSPICE_H 27 #define NETLIST_EXPORTER_PSPICE_H 28 29 #include "netlist_exporter_base.h" 30 #include <list> 31 #include <map> 32 33 class PROJECT; 34 35 /// Flags for Spice netlist generation (can be combined) 36 enum SPICE_NETLIST_OPTIONS { 37 NET_ADJUST_INCLUDE_PATHS = 8, // use full paths for included files (if they are in search path) 38 NET_ADJUST_PASSIVE_VALS = 16, // reformat passive symbol values (e.g. 1M -> 1Meg) 39 NET_ALL_FLAGS = 0xffff 40 }; 41 42 enum SPICE_FIELD { 43 SF_PRIMITIVE, 44 SF_MODEL, 45 SF_ENABLED, 46 SF_NODE_SEQUENCE, 47 SF_LIB_FILE, 48 SF_END // sentinel 49 }; 50 51 ///< Basic Spice component primitives 52 enum SPICE_PRIMITIVE { 53 SP_UNKNOWN = ' ', 54 SP_RESISTOR = 'R', 55 SP_CAPACITOR = 'C', 56 SP_INDUCTOR = 'L', 57 SP_DIODE = 'D', 58 SP_BJT = 'Q', 59 SP_MOSFET = 'M', 60 SP_JFET = 'J', 61 SP_SUBCKT = 'X', 62 SP_VSOURCE = 'V', 63 SP_ISOURCE = 'I' 64 }; 65 66 /// @todo add NET_ADJUST_INCLUDE_PATHS & NET_ADJUST_PASSIVE_VALS checkboxes in the netlist 67 /// export dialog. 68 69 /** 70 * Structure to represent a schematic symbol in the Spice simulation. 71 */ 72 struct SPICE_ITEM 73 { 74 75 SCH_SYMBOL* m_parent; ///< Schematic symbol represented by this SPICE_ITEM. 76 wxChar m_primitive; ///< Spice primitive type (@see SPICE_PRIMITIVE). 77 wxString m_model; ///< Library model (for semiconductors and subcircuits), 78 ///< component value (for passive components) or 79 ///< voltage/current (for sources). 80 wxString m_refName; 81 bool m_enabled; ///< Whether the symbol should be used in simulation. 82 std::vector<wxString> m_pins; ///< Array containing Standard Pin Name 83 std::vector<int> m_pinSequence; ///< Numeric indices into m_SortedSymbolPinList 84 }; 85 86 87 /** 88 * Generate a PSPICE compatible netlist. 89 */ 90 class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER_BASE 91 { 92 public: NETLIST_EXPORTER_PSPICE(SCHEMATIC_IFACE * aSchematic)93 NETLIST_EXPORTER_PSPICE( SCHEMATIC_IFACE* aSchematic ) : 94 NETLIST_EXPORTER_BASE( aSchematic ) 95 { 96 } 97 ~NETLIST_EXPORTER_PSPICE()98 virtual ~NETLIST_EXPORTER_PSPICE() 99 { 100 } 101 102 /** 103 * Return list of items representing schematic components in the Spice world. 104 */ GetSpiceItems()105 const std::list<SPICE_ITEM>& GetSpiceItems() const 106 { 107 return m_spiceItems; 108 } 109 110 /** 111 * Return name of Spice device corresponding to a schematic symbol. 112 * 113 * @param aSymbol is the component reference. 114 * @return Spice device name or empty string if there is no such symbol in the netlist. The 115 * name is either plain reference if the first character of reference corresponds to the 116 * assigned device model type or it is the reference prefixed with a character defining 117 * the device model type. 118 */ 119 wxString GetSpiceDevice( const wxString& aSymbol ) const; 120 121 /** 122 * Write to specified output file 123 */ 124 bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ) override; 125 126 ///< @copydoc NETLIST_EXPORTER_BASE::Format() 127 bool Format( OUTPUTFORMATTER* aFormatter, unsigned aCtl ); 128 129 /** 130 * Process the netlist to create net mapping and a list of SPICE_ITEMs. 131 * It is automatically called by WriteNetlist(), but might be used separately, 132 * if only net mapping and the list of SPICE_ITEMs are required. 133 * @return True if successful. 134 */ 135 bool ProcessNetlist( unsigned aCtl ); 136 137 138 /** 139 * Replace illegal spice net name characters with an underscore. 140 */ 141 static void ReplaceForbiddenChars( wxString& aNetName ); 142 143 /** 144 * Return a map of circuit nodes to net names. 145 */ GetNetIndexMap()146 const std::map<wxString, int>& GetNetIndexMap() const 147 { 148 return m_netMap; 149 } 150 151 /** 152 * Return a vector of component field names related to Spice simulation. 153 */ GetSpiceFields()154 static const std::vector<wxString>& GetSpiceFields() 155 { 156 return m_spiceFields; 157 } 158 159 /** 160 * Return a string used for a particular component field related to Spice simulation. 161 */ GetSpiceFieldName(SPICE_FIELD aField)162 static const wxString& GetSpiceFieldName( SPICE_FIELD aField ) 163 { 164 return m_spiceFields[(int) aField]; 165 } 166 167 /** 168 * Retrieve either the requested field value or the default value. 169 */ 170 static wxString GetSpiceField( SPICE_FIELD aField, SCH_SYMBOL* aSymbol, unsigned aCtl ); 171 172 /** 173 * Retrieve the default value for a given field. 174 */ 175 static wxString GetSpiceFieldDefVal( SPICE_FIELD aField, SCH_SYMBOL* aSymbol, unsigned aCtl ); 176 177 /** 178 * Update the vector of Spice directives placed in the schematics. 179 */ 180 void UpdateDirectives( unsigned aCtl ); 181 182 /** 183 * Return a vector of Spice directives found in the schematics. 184 */ GetDirectives()185 const std::vector<wxString> GetDirectives() const 186 { 187 return m_directives; 188 } 189 190 /** 191 * Convert typical boolean string values (no/yes, true/false, 1/0) to a boolean value. 192 */ StringToBool(const wxString & aStr)193 static bool StringToBool( const wxString& aStr ) 194 { 195 if( aStr.IsEmpty() ) 196 return false; 197 198 char c = tolower( aStr[0] ); 199 200 // Different ways of saying false (no/false/0) 201 return !( c == 'n' || c == 'f' || c == '0' ); 202 } 203 204 protected: 205 /** 206 * Save the Spice directives. 207 */ 208 virtual void writeDirectives( OUTPUTFORMATTER* aFormatter, unsigned aCtl ) const; 209 210 private: 211 212 wxString m_title; ///< Spice simulation title found in the schematic sheet 213 std::vector<wxString> m_directives; ///< Spice directives found in the schematic sheet 214 std::set<wxString> m_libraries; ///< Spice libraries used by the simulated circuit 215 std::map<wxString, int> m_netMap; ///< Map spice nodes to net codes 216 std::list<SPICE_ITEM> m_spiceItems; ///< Items representing schematic symbols in Spice world 217 218 // Component fields that are processed during netlist export & simulation 219 static const std::vector<wxString> m_spiceFields; 220 }; 221 222 #endif 223