47#include <boost/algorithm/string/case_conv.hpp>
49#include <pegtl/contrib/parse_tree.hpp>
62 case DEVICE_T::R:
return {
"R",
"Resistor",
true };
63 case DEVICE_T::C:
return {
"C",
"Capacitor",
true };
64 case DEVICE_T::L:
return {
"L",
"Inductor",
true };
65 case DEVICE_T::TLINE:
return {
"TLINE",
"Transmission Line",
true };
66 case DEVICE_T::SW:
return {
"SW",
"Switch",
true };
68 case DEVICE_T::D:
return {
"D",
"Diode",
true };
69 case DEVICE_T::NPN:
return {
"NPN",
"NPN BJT",
true };
70 case DEVICE_T::PNP:
return {
"PNP",
"PNP BJT",
true };
72 case DEVICE_T::NJFET:
return {
"NJFET",
"N-channel JFET",
true };
73 case DEVICE_T::PJFET:
return {
"PJFET",
"P-channel JFET",
true };
75 case DEVICE_T::NMOS:
return {
"NMOS",
"N-channel MOSFET",
true };
76 case DEVICE_T::PMOS:
return {
"PMOS",
"P-channel MOSFET",
true };
77 case DEVICE_T::NMES:
return {
"NMES",
"N-channel MESFET",
true };
78 case DEVICE_T::PMES:
return {
"PMES",
"P-channel MESFET",
true };
80 case DEVICE_T::V:
return {
"V",
"Voltage Source",
true };
81 case DEVICE_T::I:
return {
"I",
"Current Source",
true };
83 case DEVICE_T::KIBIS:
return {
"IBIS",
"IBIS Model",
false };
85 case DEVICE_T::SUBCKT:
return {
"SUBCKT",
"Subcircuit",
false };
86 case DEVICE_T::XSPICE:
return {
"XSPICE",
"XSPICE Code Model",
true };
87 case DEVICE_T::SPICE:
return {
"SPICE",
"Raw Spice Element",
true };
89 default: wxFAIL;
return {};
100 case TYPE::R:
return { DEVICE_T::R,
"",
"Ideal" };
101 case TYPE::R_POT:
return { DEVICE_T::R,
"POT",
"Potentiometer" };
102 case TYPE::R_BEHAVIORAL:
return { DEVICE_T::R,
"=",
"Behavioral" };
104 case TYPE::C:
return { DEVICE_T::C,
"",
"Ideal" };
105 case TYPE::C_BEHAVIORAL:
return { DEVICE_T::C,
"=",
"Behavioral" };
107 case TYPE::L:
return { DEVICE_T::L,
"",
"Ideal" };
108 case TYPE::L_MUTUAL:
return { DEVICE_T::L,
"MUTUAL",
"Mutual" };
109 case TYPE::L_BEHAVIORAL:
return { DEVICE_T::L,
"=",
"Behavioral" };
111 case TYPE::TLINE_Z0:
return { DEVICE_T::TLINE,
"",
"Characteristic impedance" };
112 case TYPE::TLINE_RLGC:
return { DEVICE_T::TLINE,
"RLGC",
"RLGC" };
114 case TYPE::SW_V:
return { DEVICE_T::SW,
"V",
"Voltage-controlled" };
115 case TYPE::SW_I:
return { DEVICE_T::SW,
"I",
"Current-controlled" };
117 case TYPE::D:
return { DEVICE_T::D,
"",
"" };
119 case TYPE::NPN_VBIC:
return { DEVICE_T::NPN,
"VBIC",
"VBIC" };
120 case TYPE::PNP_VBIC:
return { DEVICE_T::PNP,
"VBIC",
"VBIC" };
121 case TYPE::NPN_GUMMELPOON:
return { DEVICE_T::NPN,
"GUMMELPOON",
"Gummel-Poon" };
122 case TYPE::PNP_GUMMELPOON:
return { DEVICE_T::PNP,
"GUMMELPOON",
"Gummel-Poon" };
124 case TYPE::NPN_HICUM2:
return { DEVICE_T::NPN,
"HICUML2",
"HICUM level 2" };
125 case TYPE::PNP_HICUM2:
return { DEVICE_T::PNP,
"HICUML2",
"HICUM level 2" };
128 case TYPE::NJFET_SHICHMANHODGES:
return { DEVICE_T::NJFET,
"SHICHMANHODGES",
"Shichman-Hodges" };
129 case TYPE::PJFET_SHICHMANHODGES:
return { DEVICE_T::PJFET,
"SHICHMANHODGES",
"Shichman-Hodges" };
130 case TYPE::NJFET_PARKERSKELLERN:
return { DEVICE_T::NJFET,
"PARKERSKELLERN",
"Parker-Skellern" };
131 case TYPE::PJFET_PARKERSKELLERN:
return { DEVICE_T::PJFET,
"PARKERSKELLERN",
"Parker-Skellern" };
133 case TYPE::NMES_STATZ:
return { DEVICE_T::NMES,
"STATZ",
"Statz" };
134 case TYPE::PMES_STATZ:
return { DEVICE_T::PMES,
"STATZ",
"Statz" };
135 case TYPE::NMES_YTTERDAL:
return { DEVICE_T::NMES,
"YTTERDAL",
"Ytterdal" };
136 case TYPE::PMES_YTTERDAL:
return { DEVICE_T::PMES,
"YTTERDAL",
"Ytterdal" };
137 case TYPE::NMES_HFET1:
return { DEVICE_T::NMES,
"HFET1",
"HFET1" };
138 case TYPE::PMES_HFET1:
return { DEVICE_T::PMES,
"HFET1",
"HFET1" };
139 case TYPE::NMES_HFET2:
return { DEVICE_T::NMES,
"HFET2",
"HFET2" };
140 case TYPE::PMES_HFET2:
return { DEVICE_T::PMES,
"HFET2",
"HFET2" };
142 case TYPE::NMOS_VDMOS:
return { DEVICE_T::NMOS,
"VDMOS",
"VDMOS" };
143 case TYPE::PMOS_VDMOS:
return { DEVICE_T::PMOS,
"VDMOS",
"VDMOS" };
144 case TYPE::NMOS_MOS1:
return { DEVICE_T::NMOS,
"MOS1",
"Classical quadratic (MOS1)" };
145 case TYPE::PMOS_MOS1:
return { DEVICE_T::PMOS,
"MOS1",
"Classical quadratic (MOS1)" };
146 case TYPE::NMOS_MOS2:
return { DEVICE_T::NMOS,
"MOS2",
"Grove-Frohman (MOS2)" };
147 case TYPE::PMOS_MOS2:
return { DEVICE_T::PMOS,
"MOS2",
"Grove-Frohman (MOS2)" };
148 case TYPE::NMOS_MOS3:
return { DEVICE_T::NMOS,
"MOS3",
"MOS3" };
149 case TYPE::PMOS_MOS3:
return { DEVICE_T::PMOS,
"MOS3",
"MOS3" };
150 case TYPE::NMOS_BSIM1:
return { DEVICE_T::NMOS,
"BSIM1",
"BSIM1" };
151 case TYPE::PMOS_BSIM1:
return { DEVICE_T::PMOS,
"BSIM1",
"BSIM1" };
152 case TYPE::NMOS_BSIM2:
return { DEVICE_T::NMOS,
"BSIM2",
"BSIM2" };
153 case TYPE::PMOS_BSIM2:
return { DEVICE_T::PMOS,
"BSIM2",
"BSIM2" };
154 case TYPE::NMOS_MOS6:
return { DEVICE_T::NMOS,
"MOS6",
"MOS6" };
155 case TYPE::PMOS_MOS6:
return { DEVICE_T::PMOS,
"MOS6",
"MOS6" };
156 case TYPE::NMOS_BSIM3:
return { DEVICE_T::NMOS,
"BSIM3",
"BSIM3" };
157 case TYPE::PMOS_BSIM3:
return { DEVICE_T::PMOS,
"BSIM3",
"BSIM3" };
158 case TYPE::NMOS_MOS9:
return { DEVICE_T::NMOS,
"MOS9",
"MOS9" };
159 case TYPE::PMOS_MOS9:
return { DEVICE_T::PMOS,
"MOS9",
"MOS9" };
160 case TYPE::NMOS_B4SOI:
return { DEVICE_T::NMOS,
"B4SOI",
"BSIM4 SOI (B4SOI)" };
161 case TYPE::PMOS_B4SOI:
return { DEVICE_T::PMOS,
"B4SOI",
"BSIM4 SOI (B4SOI)" };
162 case TYPE::NMOS_BSIM4:
return { DEVICE_T::NMOS,
"BSIM4",
"BSIM4" };
163 case TYPE::PMOS_BSIM4:
return { DEVICE_T::PMOS,
"BSIM4",
"BSIM4" };
168 case TYPE::NMOS_B3SOIFD:
return { DEVICE_T::NMOS,
"B3SOIFD",
"B3SOIFD (BSIM3 FD-SOI)" };
169 case TYPE::PMOS_B3SOIFD:
return { DEVICE_T::PMOS,
"B3SOIFD",
"B3SOIFD (BSIM3 FD-SOI)" };
170 case TYPE::NMOS_B3SOIDD:
return { DEVICE_T::NMOS,
"B3SOIDD",
"B3SOIDD (BSIM3 SOI)" };
171 case TYPE::PMOS_B3SOIDD:
return { DEVICE_T::PMOS,
"B3SOIDD",
"B3SOIDD (BSIM3 SOI)" };
172 case TYPE::NMOS_B3SOIPD:
return { DEVICE_T::NMOS,
"B3SOIPD",
"B3SOIPD (BSIM3 PD-SOI)" };
173 case TYPE::PMOS_B3SOIPD:
return { DEVICE_T::PMOS,
"B3SOIPD",
"B3SOIPD (BSIM3 PD-SOI)" };
176 case TYPE::NMOS_HISIM2:
return { DEVICE_T::NMOS,
"HISIM2",
"HiSIM2" };
177 case TYPE::PMOS_HISIM2:
return { DEVICE_T::PMOS,
"HISIM2",
"HiSIM2" };
178 case TYPE::NMOS_HISIMHV1:
return { DEVICE_T::NMOS,
"HISIMHV1",
"HiSIM_HV1" };
179 case TYPE::PMOS_HISIMHV1:
return { DEVICE_T::PMOS,
"HISIMHV1",
"HiSIM_HV1" };
180 case TYPE::NMOS_HISIMHV2:
return { DEVICE_T::NMOS,
"HISIMHV2",
"HiSIM_HV2" };
181 case TYPE::PMOS_HISIMHV2:
return { DEVICE_T::PMOS,
"HISIMHV2",
"HiSIM_HV2" };
183 case TYPE::V:
return { DEVICE_T::V,
"DC",
"DC", };
184 case TYPE::V_SIN:
return { DEVICE_T::V,
"SIN",
"Sine" };
185 case TYPE::V_PULSE:
return { DEVICE_T::V,
"PULSE",
"Pulse" };
186 case TYPE::V_EXP:
return { DEVICE_T::V,
"EXP",
"Exponential" };
189 case TYPE::V_PWL:
return { DEVICE_T::V,
"PWL",
"Piecewise linear" };
190 case TYPE::V_WHITENOISE:
return { DEVICE_T::V,
"WHITENOISE",
"White noise" };
191 case TYPE::V_PINKNOISE:
return { DEVICE_T::V,
"PINKNOISE",
"Pink noise (1/f)" };
192 case TYPE::V_BURSTNOISE:
return { DEVICE_T::V,
"BURSTNOISE",
"Burst noise" };
193 case TYPE::V_RANDUNIFORM:
return { DEVICE_T::V,
"RANDUNIFORM",
"Random uniform" };
194 case TYPE::V_RANDNORMAL:
return { DEVICE_T::V,
"RANDNORMAL",
"Random normal" };
195 case TYPE::V_RANDEXP:
return { DEVICE_T::V,
"RANDEXP",
"Random exponential" };
197 case TYPE::V_BEHAVIORAL:
return { DEVICE_T::V,
"=",
"Behavioral" };
200 case TYPE::I_SIN:
return {
DEVICE_T::I,
"SIN",
"Sine" };
201 case TYPE::I_PULSE:
return {
DEVICE_T::I,
"PULSE",
"Pulse" };
202 case TYPE::I_EXP:
return {
DEVICE_T::I,
"EXP",
"Exponential" };
205 case TYPE::I_PWL:
return {
DEVICE_T::I,
"PWL",
"Piecewise linear" };
206 case TYPE::I_WHITENOISE:
return {
DEVICE_T::I,
"WHITENOISE",
"White noise" };
207 case TYPE::I_PINKNOISE:
return {
DEVICE_T::I,
"PINKNOISE",
"Pink noise (1/f)" };
208 case TYPE::I_BURSTNOISE:
return {
DEVICE_T::I,
"BURSTNOISE",
"Burst noise" };
209 case TYPE::I_RANDUNIFORM:
return {
DEVICE_T::I,
"RANDUNIFORM",
"Random uniform" };
210 case TYPE::I_RANDNORMAL:
return {
DEVICE_T::I,
"RANDNORMAL",
"Random normal" };
211 case TYPE::I_RANDEXP:
return {
DEVICE_T::I,
"RANDEXP",
"Random exponential" };
213 case TYPE::I_BEHAVIORAL:
return {
DEVICE_T::I,
"=",
"Behavioral" };
215 case TYPE::SUBCKT:
return { DEVICE_T::SUBCKT,
"",
"Subcircuit" };
216 case TYPE::XSPICE:
return { DEVICE_T::XSPICE,
"",
"" };
218 case TYPE::KIBIS_DEVICE:
return { DEVICE_T::KIBIS,
"DEVICE",
"Device" };
219 case TYPE::KIBIS_DRIVER_DC:
return { DEVICE_T::KIBIS,
"DCDRIVER",
"DC driver" };
220 case TYPE::KIBIS_DRIVER_RECT:
return { DEVICE_T::KIBIS,
"RECTDRIVER",
"Rectangular wave driver" };
221 case TYPE::KIBIS_DRIVER_PRBS:
return { DEVICE_T::KIBIS,
"PRBSDRIVER",
"PRBS driver" };
223 case TYPE::RAWSPICE:
return { DEVICE_T::SPICE,
"",
"" };
225 default: wxFAIL;
return {};
234 case TYPE::R:
return {
"R",
"" };
235 case TYPE::R_POT:
return {
"A",
"" };
236 case TYPE::R_BEHAVIORAL:
return {
"R",
"",
"",
"0",
false,
true };
238 case TYPE::C:
return {
"C",
"" };
239 case TYPE::C_BEHAVIORAL:
return {
"C",
"",
"",
"0",
false,
true };
241 case TYPE::L:
return {
"L",
"" };
242 case TYPE::L_MUTUAL:
return {
"K",
"" };
243 case TYPE::L_BEHAVIORAL:
return {
"L",
"",
"",
"0",
false,
true };
246 case TYPE::TLINE_Z0:
return {
"O",
"LTRA" };
247 case TYPE::TLINE_RLGC:
return {
"O",
"LTRA" };
249 case TYPE::SW_V:
return {
"S",
"SW" };
250 case TYPE::SW_I:
return {
"W",
"CSW" };
252 case TYPE::D:
return {
"D",
"D" };
254 case TYPE::NPN_VBIC:
return {
"Q",
"NPN",
"",
"4" };
255 case TYPE::PNP_VBIC:
return {
"Q",
"PNP",
"",
"4" };
256 case TYPE::NPN_GUMMELPOON:
return {
"Q",
"NPN",
"",
"1",
true };
257 case TYPE::PNP_GUMMELPOON:
return {
"Q",
"PNP",
"",
"1",
true };
258 case TYPE::NPN_HICUM2:
return {
"Q",
"NPN",
"",
"8" };
259 case TYPE::PNP_HICUM2:
return {
"Q",
"PNP",
"",
"8" };
261 case TYPE::NJFET_SHICHMANHODGES:
return {
"J",
"NJF",
"",
"1",
true };
262 case TYPE::PJFET_SHICHMANHODGES:
return {
"J",
"PJF",
"",
"1",
true };
263 case TYPE::NJFET_PARKERSKELLERN:
return {
"J",
"NJF",
"",
"2" };
264 case TYPE::PJFET_PARKERSKELLERN:
return {
"J",
"PJF",
"",
"2" };
266 case TYPE::NMES_STATZ:
return {
"Z",
"NMF",
"",
"1",
true };
267 case TYPE::PMES_STATZ:
return {
"Z",
"PMF",
"",
"1",
true };
268 case TYPE::NMES_YTTERDAL:
return {
"Z",
"NMF",
"",
"2" };
269 case TYPE::PMES_YTTERDAL:
return {
"Z",
"PMF",
"",
"2" };
270 case TYPE::NMES_HFET1:
return {
"Z",
"NMF",
"",
"5" };
271 case TYPE::PMES_HFET1:
return {
"Z",
"PMF",
"",
"5" };
272 case TYPE::NMES_HFET2:
return {
"Z",
"NMF",
"",
"6" };
273 case TYPE::PMES_HFET2:
return {
"Z",
"PMF",
"",
"6" };
275 case TYPE::NMOS_VDMOS:
return {
"M",
"VDMOS NCHAN", };
276 case TYPE::PMOS_VDMOS:
return {
"M",
"VDMOS PCHAN", };
277 case TYPE::NMOS_MOS1:
return {
"M",
"NMOS",
"",
"1",
true };
278 case TYPE::PMOS_MOS1:
return {
"M",
"PMOS",
"",
"1",
true };
279 case TYPE::NMOS_MOS2:
return {
"M",
"NMOS",
"",
"2" };
280 case TYPE::PMOS_MOS2:
return {
"M",
"PMOS",
"",
"2" };
281 case TYPE::NMOS_MOS3:
return {
"M",
"NMOS",
"",
"3" };
282 case TYPE::PMOS_MOS3:
return {
"M",
"PMOS",
"",
"3" };
283 case TYPE::NMOS_BSIM1:
return {
"M",
"NMOS",
"",
"4" };
284 case TYPE::PMOS_BSIM1:
return {
"M",
"PMOS",
"",
"4" };
285 case TYPE::NMOS_BSIM2:
return {
"M",
"NMOS",
"",
"5" };
286 case TYPE::PMOS_BSIM2:
return {
"M",
"PMOS",
"",
"5" };
287 case TYPE::NMOS_MOS6:
return {
"M",
"NMOS",
"",
"6" };
288 case TYPE::PMOS_MOS6:
return {
"M",
"PMOS",
"",
"6" };
289 case TYPE::NMOS_BSIM3:
return {
"M",
"NMOS",
"",
"8" };
290 case TYPE::PMOS_BSIM3:
return {
"M",
"PMOS",
"",
"8" };
291 case TYPE::NMOS_MOS9:
return {
"M",
"NMOS",
"",
"9" };
292 case TYPE::PMOS_MOS9:
return {
"M",
"PMOS",
"",
"9" };
293 case TYPE::NMOS_B4SOI:
return {
"M",
"NMOS",
"",
"10" };
294 case TYPE::PMOS_B4SOI:
return {
"M",
"PMOS",
"",
"10" };
295 case TYPE::NMOS_BSIM4:
return {
"M",
"NMOS",
"",
"14" };
296 case TYPE::PMOS_BSIM4:
return {
"M",
"PMOS",
"",
"14" };
301 case TYPE::NMOS_B3SOIFD:
return {
"M",
"NMOS",
"",
"55" };
302 case TYPE::PMOS_B3SOIFD:
return {
"M",
"PMOS",
"",
"55" };
303 case TYPE::NMOS_B3SOIDD:
return {
"M",
"NMOS",
"",
"56" };
304 case TYPE::PMOS_B3SOIDD:
return {
"M",
"PMOS",
"",
"56" };
305 case TYPE::NMOS_B3SOIPD:
return {
"M",
"NMOS",
"",
"57" };
306 case TYPE::PMOS_B3SOIPD:
return {
"M",
"PMOS",
"",
"57" };
309 case TYPE::NMOS_HISIM2:
return {
"M",
"NMOS",
"",
"68" };
310 case TYPE::PMOS_HISIM2:
return {
"M",
"PMOS",
"",
"68" };
311 case TYPE::NMOS_HISIMHV1:
return {
"M",
"NMOS",
"",
"73",
false,
false,
"1.2.4" };
312 case TYPE::PMOS_HISIMHV1:
return {
"M",
"PMOS",
"",
"73",
false,
false,
"1.2.4" };
313 case TYPE::NMOS_HISIMHV2:
return {
"M",
"NMOS",
"",
"73",
false,
false,
"2.2.0" };
314 case TYPE::PMOS_HISIMHV2:
return {
"M",
"PMOS",
"",
"73",
false,
false,
"2.2.0" };
316 case TYPE::V:
return {
"V",
"",
"DC" };
317 case TYPE::V_SIN:
return {
"V",
"",
"SIN" };
318 case TYPE::V_PULSE:
return {
"V",
"",
"PULSE" };
319 case TYPE::V_EXP:
return {
"V",
"",
"EXP" };
322 case TYPE::V_PWL:
return {
"V",
"",
"PWL" };
323 case TYPE::V_WHITENOISE:
return {
"V",
"",
"TRNOISE" };
324 case TYPE::V_PINKNOISE:
return {
"V",
"",
"TRNOISE" };
325 case TYPE::V_BURSTNOISE:
return {
"V",
"",
"TRNOISE" };
326 case TYPE::V_RANDUNIFORM:
return {
"V",
"",
"TRRANDOM" };
327 case TYPE::V_RANDNORMAL:
return {
"V",
"",
"TRRANDOM" };
328 case TYPE::V_RANDEXP:
return {
"V",
"",
"TRRANDOM" };
330 case TYPE::V_BEHAVIORAL:
return {
"B" };
332 case TYPE::I:
return {
"I",
"",
"DC" };
333 case TYPE::I_PULSE:
return {
"I",
"",
"PULSE" };
334 case TYPE::I_SIN:
return {
"I",
"",
"SIN" };
335 case TYPE::I_EXP:
return {
"I",
"",
"EXP" };
338 case TYPE::I_PWL:
return {
"I",
"",
"PWL" };
339 case TYPE::I_WHITENOISE:
return {
"I",
"",
"TRNOISE" };
340 case TYPE::I_PINKNOISE:
return {
"I",
"",
"TRNOISE" };
341 case TYPE::I_BURSTNOISE:
return {
"I",
"",
"TRNOISE" };
342 case TYPE::I_RANDUNIFORM:
return {
"I",
"",
"TRRANDOM" };
343 case TYPE::I_RANDNORMAL:
return {
"I",
"",
"TRRANDOM" };
344 case TYPE::I_RANDEXP:
return {
"I",
"",
"TRRANDOM" };
346 case TYPE::I_BEHAVIORAL:
return {
"B" };
348 case TYPE::SUBCKT:
return {
"X" };
349 case TYPE::XSPICE:
return {
"A" };
351 case TYPE::KIBIS_DEVICE:
return {
"X" };
352 case TYPE::KIBIS_DRIVER_DC:
return {
"X" };
353 case TYPE::KIBIS_DRIVER_RECT:
return {
"X" };
354 case TYPE::KIBIS_DRIVER_PRBS:
return {
"X" };
357 case TYPE::RAWSPICE:
return {};
359 default: wxFAIL;
return {};
373 if( deviceTypeFieldValue !=
"" )
375 for(
TYPE type : TYPE_ITERATOR() )
377 if( typeFieldValue ==
TypeInfo( type ).fieldValue )
385 if( typeFieldValue !=
"" )
393 return typeFromLegacyFields;
402 if(
GetFieldValue( &aFields, SIM_MODEL_RAW_SPICE::LEGACY_TYPE_FIELD ) !=
""
407 return TYPE::RAWSPICE;
418 const std::vector<LIB_PIN*>& aPins )
426 const std::vector<LIB_PIN*>& aPins )
449 std::unique_ptr<SIM_MODEL> model =
Create( aType );
454 model->ReadDataFields(
static_cast<const std::vector<SCH_FIELD>*
>(
nullptr ), aPins );
469 const std::vector<LIB_PIN*>& aPins,
473 std::unique_ptr<SIM_MODEL> model;
478 model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
480 model = std::make_unique<SIM_MODEL_RAW_SPICE>();
487 model->SetBaseModel( *aBaseModel );
489 model->ReadDataFields(
static_cast<const std::vector<SCH_FIELD>*
>(
nullptr ), aPins );
505 const std::vector<LIB_PIN*>& aPins,
506 const std::vector<T>& aFields,
515 std::unique_ptr<SIM_MODEL> model;
520 model = std::make_unique<SIM_MODEL_SPICE_FALLBACK>( type );
522 model = std::make_unique<SIM_MODEL_RAW_SPICE>();
529 model->SetBaseModel( *aBaseModel );
531 model->ReadDataFields( &aFields, aPins );
545 const std::vector<LIB_PIN*>& aPins,
546 const std::vector<SCH_FIELD>& aFields,
550 const std::vector<LIB_PIN*>& aPins,
551 const std::vector<LIB_FIELD>& aFields,
557 const std::vector<LIB_PIN*>& aPins,
558 bool aResolved,
REPORTER* aReporter )
565 model->ReadDataFields( &aFields, aPins );
580 if( modelData.empty() )
583 model = std::make_unique<SIM_MODEL_RAW_SPICE>( modelData );
587 model->createPins( aPins );
603template std::unique_ptr<SIM_MODEL>
SIM_MODEL::Create(
const std::vector<SCH_FIELD>& aFields,
604 const std::vector<LIB_PIN*>& aPins,
605 bool aResolved,
REPORTER* aReporter );
606template std::unique_ptr<SIM_MODEL>
SIM_MODEL::Create(
const std::vector<LIB_FIELD>& aFields,
607 const std::vector<LIB_PIN*>& aPins,
608 bool aResolved,
REPORTER* aReporter );
615 static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
620 for(
const T& field : *aFields )
622 if( field.GetName() == aFieldName )
624 return aResolve ? field.GetShownText( 0,
false ).ToStdString()
625 : field.GetText().ToStdString();
644 const std::string& aValue )
646 static_assert( std::is_same<T, SCH_FIELD>::value || std::is_same<T, LIB_FIELD>::value );
648 auto fieldIt = std::find_if( aFields.begin(), aFields.end(),
651 return f.GetName() == aFieldName;
654 if( fieldIt != aFields.end() )
657 aFields.erase( fieldIt );
659 fieldIt->SetText( aValue );
667 if constexpr( std::is_same<T, SCH_FIELD>::value )
669 wxASSERT( aFields.size() >= 1 );
672 aFields.emplace_back(
VECTOR2I(), aFields.size(), parent, aFieldName );
674 else if constexpr( std::is_same<T, LIB_FIELD>::value )
676 aFields.emplace_back( aFields.size(), aFieldName );
679 aFields.back().SetText( aValue );
683template void SIM_MODEL::SetFieldValue<SCH_FIELD>( std::vector<SCH_FIELD>& aFields,
684 const wxString& aFieldName,
685 const std::string& aValue );
686template void SIM_MODEL::SetFieldValue<LIB_FIELD>( std::vector<LIB_FIELD>& aFields,
687 const wxString& aFieldName,
688 const std::string& aValue );
707 for(
int modelPinIndex = 0; modelPinIndex <
GetPinCount(); ++modelPinIndex )
710 return modelPinIndex;
732 return fmt::format(
"{} ({})",
733 aModel->GetDeviceInfo().fieldValue,
734 aModel->GetTypeInfo().description );
740 "base class: '%s', but is '%s'" ),
741 describe( &aBaseModel ),
742 describe(
this ) ) );
751 std::vector<std::reference_wrapper<const PIN>> pins;
753 for(
int modelPinIndex = 0; modelPinIndex <
GetPinCount(); ++modelPinIndex )
754 pins.emplace_back(
GetPin( modelPinIndex ) );
761 if( aPinIndex >= 0 && aPinIndex < (
int)
m_pins.size() )
762 m_pins.at( aPinIndex ).symbolPinNumber = aSymbolPinNumber;
767 const std::string& aSymbolPinNumber )
771 if(
pin.name == aPinName )
773 pin.symbolPinNumber = aSymbolPinNumber;
780 int aPinIndex = (int) strtol( aPinName.c_str(),
nullptr, 10 );
782 if( aPinIndex < 1 || aPinIndex > (
int)
m_pins.size() )
785 m_pins[ --aPinIndex ].symbolPinNumber = aSymbolPinNumber;
800 std::string lowerParamName = boost::to_lower_copy( aParamName );
802 std::vector<std::reference_wrapper<const PARAM>> params =
GetParams();
804 for(
int ii = 0; ii < (int) params.size(); ++ii )
806 if( params[ii].get().info.name == lowerParamName )
818 return idx >= 0 ? &
GetParam( idx ) :
nullptr;
824 std::vector<std::reference_wrapper<const PARAM>> params;
827 params.emplace_back(
GetParam( i ) );
850 m_params.at( aParamIndex ).value = aValue;
857 std::string value = aValue;
885 return std::make_unique<SIM_MODEL_IDEAL>( aType );
888 return std::make_unique<SIM_MODEL_R_POT>();
891 return std::make_unique<SIM_MODEL_L_MUTUAL>();
893 case TYPE::R_BEHAVIORAL:
894 case TYPE::C_BEHAVIORAL:
895 case TYPE::L_BEHAVIORAL:
896 case TYPE::V_BEHAVIORAL:
897 case TYPE::I_BEHAVIORAL:
898 return std::make_unique<SIM_MODEL_BEHAVIORAL>( aType );
901 case TYPE::TLINE_RLGC:
902 return std::make_unique<SIM_MODEL_TLINE>( aType );
906 return std::make_unique<SIM_MODEL_SWITCH>( aType );
922 case TYPE::V_WHITENOISE:
923 case TYPE::I_WHITENOISE:
924 case TYPE::V_PINKNOISE:
925 case TYPE::I_PINKNOISE:
926 case TYPE::V_BURSTNOISE:
927 case TYPE::I_BURSTNOISE:
928 case TYPE::V_RANDUNIFORM:
929 case TYPE::I_RANDUNIFORM:
930 case TYPE::V_RANDNORMAL:
931 case TYPE::I_RANDNORMAL:
932 case TYPE::V_RANDEXP:
933 case TYPE::I_RANDEXP:
936 return std::make_unique<SIM_MODEL_SOURCE>( aType );
939 return std::make_unique<SIM_MODEL_SUBCKT>();
942 return std::make_unique<SIM_MODEL_XSPICE>( aType );
944 case TYPE::KIBIS_DEVICE:
945 case TYPE::KIBIS_DRIVER_DC:
946 case TYPE::KIBIS_DRIVER_RECT:
947 case TYPE::KIBIS_DRIVER_PRBS:
948 return std::make_unique<SIM_MODEL_KIBIS>( aType );
951 return std::make_unique<SIM_MODEL_RAW_SPICE>();
954 return std::make_unique<SIM_MODEL_NGSPICE>( aType );
974 std::unique_ptr<SIM_MODEL_SERIALIZER> aSerializer ) :
975 m_baseModel( nullptr ),
976 m_serializer(
std::
move( aSerializer ) ),
977 m_spiceGenerator(
std::
move( aSpiceGenerator ) ),
980 m_isStoredInValue( false )
996 for(
unsigned modelPinIndex = 0; modelPinIndex < pinNames.size(); ++modelPinIndex )
998 wxString pinName = pinNames[ modelPinIndex ];
999 bool optional =
false;
1001 if( pinName.StartsWith(
'<' ) && pinName.EndsWith(
'>' ) )
1003 pinName = pinName.Mid( 1, pinName.Length() - 2 );
1007 if( modelPinIndex < aSymbolPins.size() )
1009 AddPin( { pinNames.at( modelPinIndex ),
1010 aSymbolPins[ modelPinIndex ]->GetNumber().ToStdString() } );
1012 else if( !optional )
1014 AddPin( { pinNames.at( modelPinIndex ),
"" } );
1020template <
typename T>
1022 const std::vector<LIB_PIN*>& aPins )
1039template <
typename T>
1070 if ( param.
value ==
"" )
1075 wxCHECK( baseModel,
false );
1077 std::string baseValue = baseModel->
m_params[ii].value;
1079 if( param.
value == baseValue )
1095template <
class T_symbol,
class T_field>
1098 wxString* aModelType, wxString* aModelParams, wxString* aPinMap )
1127 auto convertNotation =
1128 [&](
const wxString& units ) -> wxString
1132 if( units == wxS(
"µ" ) || units == wxS(
"μ" ) )
1137 if( units == wxT(
"M" ) )
1138 return wxT(
"Meg" );
1142 if( units.Capitalize() == wxT(
"Meg" ) )
1149 auto convertSeparators =
1150 []( wxString* mantissa )
1152 mantissa->Replace( wxS(
" " ), wxEmptyString );
1154 wxChar ambiguousSeparator =
'?';
1155 wxChar thousandsSeparator =
'?';
1156 bool thousandsSeparatorFound =
false;
1157 wxChar decimalSeparator =
'?';
1158 bool decimalSeparatorFound =
false;
1161 for(
int ii = (
int) mantissa->length() - 1; ii >= 0; --ii )
1163 wxChar c = mantissa->GetChar( ii );
1165 if( c >=
'0' && c <=
'9' )
1169 else if( c ==
'.' || c ==
',' )
1171 if( decimalSeparator !=
'?' || thousandsSeparator !=
'?' )
1175 if( c == decimalSeparator )
1177 if( thousandsSeparatorFound )
1179 else if( decimalSeparatorFound )
1182 decimalSeparatorFound =
true;
1184 else if( c == thousandsSeparator )
1189 thousandsSeparatorFound =
true;
1192 else if( ambiguousSeparator !=
'?' )
1197 if( c == ambiguousSeparator )
1200 thousandsSeparator = ambiguousSeparator;
1201 thousandsSeparatorFound =
true;
1202 decimalSeparator = c ==
'.' ?
',' :
'.';
1208 decimalSeparator = ambiguousSeparator;
1209 decimalSeparatorFound =
true;
1210 thousandsSeparator = c;
1211 thousandsSeparatorFound =
true;
1223 ambiguousSeparator = c;
1227 decimalSeparator = c;
1228 decimalSeparatorFound =
true;
1229 thousandsSeparator = c ==
'.' ?
',' :
'.';
1242 if( decimalSeparator ==
'?' && thousandsSeparator ==
'?' )
1244 decimalSeparator =
'.';
1245 thousandsSeparator =
',';
1248 mantissa->Replace( thousandsSeparator, wxEmptyString );
1249 mantissa->Replace( decimalSeparator,
'.' );
1254 wxString prefix = aSymbol.GetPrefix();
1258 std::vector<LIB_PIN*> pins = aSymbol.GetAllLibPins();
1265 if( pins.size() != 2 )
1268 if( ( ( *aDeviceType ==
"R" || *aDeviceType ==
"L" || *aDeviceType ==
"C" )
1269 && aModelType->IsEmpty() )
1271 (
library.IsEmpty() && modelName.IsEmpty()
1272 && aDeviceType->IsEmpty()
1273 && aModelType->IsEmpty()
1275 && ( prefix.StartsWith(
"R" ) || prefix.StartsWith(
"L" ) || prefix.StartsWith(
"C" ) ) ) )
1277 if( aModelParams->IsEmpty() )
1279 wxRegEx idealVal( wxT(
"^"
1281 "([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
1282 "([fFhHΩΩ𝛀𝛺𝝮rR]|ohm)?"
1284 "([fFhHΩΩ𝛀𝛺𝝮rR]|ohm)?"
1287 if( idealVal.Matches( value ) )
1289 wxString valueMantissa( idealVal.GetMatch( value, 1 ) );
1290 wxString valueExponent( idealVal.GetMatch( value, 2 ) );
1291 wxString valueFraction( idealVal.GetMatch( value, 6 ) );
1293 if( !convertSeparators( &valueMantissa ) )
1296 if( valueMantissa.Contains( wxT(
"." ) ) || valueFraction.IsEmpty() )
1298 aModelParams->Printf( wxT(
"%s=\"%s%s\"" ),
1299 prefix.Left(1).Lower(),
1301 convertNotation( valueExponent ) );
1305 aModelParams->Printf( wxT(
"%s=\"%s.%s%s\"" ),
1306 prefix.Left(1).Lower(),
1309 convertNotation( valueExponent ) );
1314 *aModelType = wxT(
"=" );
1315 aModelParams->Printf( wxT(
"%s=\"%s\"" ), prefix.Left(1).Lower(), value );
1319 if( aDeviceType->IsEmpty() )
1320 *aDeviceType = prefix.Left( 1 );
1322 if( aPinMap->IsEmpty() )
1323 aPinMap->Printf( wxT(
"%s=+ %s=-" ), pins[0]->GetNumber(), pins[1]->GetNumber() );
1328 if( ( ( *aDeviceType == wxT(
"V" ) || *aDeviceType == wxT(
"I" ) )
1329 && aModelType->IsEmpty() )
1331 ( aDeviceType->IsEmpty()
1332 && aModelType->IsEmpty()
1334 && ( prefix.StartsWith(
"V" ) || prefix.StartsWith(
"I" ) ) ) )
1336 if( aModelParams->IsEmpty() && !value.IsEmpty() )
1338 if( value.StartsWith( wxT(
"DC " ) ) )
1339 value = value.Right( value.Length() - 3 );
1341 wxRegEx sourceVal( wxT(
"^"
1343 "([fFpPnNuUmMkKgGtTμµ𝛍𝜇𝝁 ]|M(e|E)(g|G))?"
1349 if( sourceVal.Matches( value ) )
1351 wxString valueMantissa( sourceVal.GetMatch( value, 1 ) );
1352 wxString valueExponent( sourceVal.GetMatch( value, 2 ) );
1353 wxString valueFraction( sourceVal.GetMatch( value, 6 ) );
1355 if( !convertSeparators( &valueMantissa ) )
1358 if( valueMantissa.Contains( wxT(
"." ) ) || valueFraction.IsEmpty() )
1360 aModelParams->Printf( wxT(
"dc=\"%s%s\"" ),
1362 convertNotation( valueExponent ) );
1366 aModelParams->Printf( wxT(
"dc=\"%s.%s%s\"" ),
1369 convertNotation( valueExponent ) );
1374 aModelParams->Printf( wxT(
"dc=\"%s\"" ), value );
1378 if( aDeviceType->IsEmpty() )
1379 *aDeviceType = prefix.Left( 1 );
1381 if( aModelType->IsEmpty() )
1382 *aModelType = wxT(
"DC" );
1384 if( aPinMap->IsEmpty() )
1385 aPinMap->Printf( wxT(
"%s=+ %s=-" ), pins[0]->GetNumber(), pins[1]->GetNumber() );
1394template bool SIM_MODEL::InferSimModel<SCH_SYMBOL, SCH_FIELD>(
SCH_SYMBOL& aSymbol,
1395 std::vector<SCH_FIELD>* aFields,
1398 wxString* aDeviceType,
1399 wxString* aModelType,
1400 wxString* aModelParams,
1401 wxString* aPinMap );
1402template bool SIM_MODEL::InferSimModel<LIB_SYMBOL, LIB_FIELD>(
LIB_SYMBOL& aSymbol,
1403 std::vector<LIB_FIELD>* aFields,
1406 wxString* aDeviceType,
1407 wxString* aModelType,
1408 wxString* aModelParams,
1409 wxString* aPinMap );
1412template <
typename T_symbol,
typename T_field>
1426 if( deviceType->GetShownText( 0,
false ).Lower() == wxS(
"pot" ) )
1430 wxString pinMap = pins->GetText();
1431 pinMap.Replace( wxS(
"=+" ), wxS(
"=r1" ) );
1432 pinMap.Replace( wxS(
"=-" ), wxS(
"=r0" ) );
1433 pins->SetText( pinMap );
1446 m_Attributes.m_Visible =
false;
1451 FIELD_INFO(
const wxString& aText, T_field* aField ) :
1453 m_Attributes( aField->GetAttributes() ),
1454 m_Pos( aField->GetPosition() )
1457 bool IsEmpty() {
return m_Text.IsEmpty(); }
1459 T_field CreateField( T_symbol* aSymbol,
const wxString& aFieldName )
1461 T_field field( aSymbol, -1, aFieldName );
1463 field.SetText( m_Text );
1464 field.SetAttributes( m_Attributes );
1465 field.SetPosition( m_Pos );
1477 []( T_field* aField )
1480 return wxString( wxEmptyString );
1482 wxRegEx regex( wxT(
"([^a-z])(M)(e|E)(g|G)($|[^a-z])" ) );
1483 wxString value = aField->GetText();
1486 regex.ReplaceAll( &value, wxT(
"\\1\\2\\5" ) );
1491 auto generateDefaultPinMapFromSymbol =
1492 [](
const std::vector<LIB_PIN*>& sourcePins )
1499 for(
unsigned ii = 0; ii < sourcePins.size(); ++ii )
1502 pinMap.Append( wxS(
" " ) );
1505 sourcePins[ii]->GetNumber(),
1512 wxString prefix = aSymbol.GetPrefix();
1513 T_field* valueField = aSymbol.FindField( wxT(
"Value" ) );
1514 std::vector<LIB_PIN*> sourcePins = aSymbol.GetAllLibPins();
1516 std::sort( sourcePins.begin(), sourcePins.end(),
1519 return StrNumCmp( lhs->GetNumber(), rhs->GetNumber(), true ) < 0;
1522 FIELD_INFO spiceDeviceInfo;
1523 FIELD_INFO spiceModelInfo;
1524 FIELD_INFO spiceTypeInfo;
1525 FIELD_INFO spiceLibInfo;
1526 FIELD_INFO spiceParamsInfo;
1527 FIELD_INFO pinMapInfo;
1528 bool modelFromValueField =
false;
1530 if( aSymbol.FindField( wxT(
"Spice_Primitive" ) )
1531 || aSymbol.FindField( wxT(
"Spice_Node_Sequence" ) )
1532 || aSymbol.FindField( wxT(
"Spice_Model" ) )
1533 || aSymbol.FindField( wxT(
"Spice_Netlist_Enabled" ) )
1534 || aSymbol.FindField( wxT(
"Spice_Lib_File" ) ) )
1536 if( T_field* primitiveField = aSymbol.FindField( wxT(
"Spice_Primitive" ) ) )
1538 spiceDeviceInfo = FIELD_INFO( primitiveField->GetText(), primitiveField );
1539 aSymbol.RemoveField( primitiveField );
1542 if( T_field* nodeSequenceField = aSymbol.FindField( wxT(
"Spice_Node_Sequence" ) ) )
1544 const wxString delimiters(
"{:,; }" );
1545 const wxString& nodeSequence = nodeSequenceField->GetText();
1548 if( nodeSequence !=
"" )
1550 wxStringTokenizer tkz( nodeSequence, delimiters );
1552 for(
long modelPinNumber = 1; tkz.HasMoreTokens(); ++modelPinNumber )
1554 long symbolPinNumber = 1;
1555 tkz.GetNextToken().ToLong( &symbolPinNumber );
1557 if( modelPinNumber != 1 )
1558 pinMap.Append(
" " );
1560 pinMap.Append(
wxString::Format(
"%ld=%ld", symbolPinNumber, modelPinNumber ) );
1564 pinMapInfo = FIELD_INFO( pinMap, nodeSequenceField );
1565 aSymbol.RemoveField( nodeSequenceField );
1568 if( T_field* modelField = aSymbol.FindField( wxT(
"Spice_Model" ) ) )
1570 spiceModelInfo = FIELD_INFO( getSIValue( modelField ), modelField );
1571 aSymbol.RemoveField( modelField );
1575 spiceModelInfo = FIELD_INFO( getSIValue( valueField ), valueField );
1576 modelFromValueField =
true;
1579 if( T_field* netlistEnabledField = aSymbol.FindField( wxT(
"Spice_Netlist_Enabled" ) ) )
1581 wxString netlistEnabled = netlistEnabledField->GetText().Lower();
1583 if( netlistEnabled.StartsWith( wxT(
"0" ) )
1584 || netlistEnabled.StartsWith( wxT(
"n" ) )
1585 || netlistEnabled.StartsWith( wxT(
"f" ) ) )
1588 netlistEnabledField->SetText( wxT(
"0" ) );
1592 aSymbol.RemoveField( netlistEnabledField );
1596 if( T_field* libFileField = aSymbol.FindField( wxT(
"Spice_Lib_File" ) ) )
1598 spiceLibInfo = FIELD_INFO( libFileField->GetText(), libFileField );
1599 aSymbol.RemoveField( libFileField );
1606 if( T_field* legacyType = aSymbol.FindField( wxT(
"Sim_Type" ) ) )
1611 if( T_field* legacyDevice = aSymbol.FindField( wxT(
"Sim_Device" ) ) )
1616 if( T_field* legacyPins = aSymbol.FindField( wxT(
"Sim_Pins" ) ) )
1618 bool isPassive = prefix.StartsWith( wxT(
"R" ) )
1619 || prefix.StartsWith( wxT(
"L" ) )
1620 || prefix.StartsWith( wxT(
"C" ) );
1624 wxArrayString pinIndexes;
1628 if( isPassive && pinIndexes.size() == 2 && sourcePins.size() == 2 )
1630 if( pinIndexes[0] == wxT(
"2" ) )
1632 pinMap.Printf( wxT(
"%s=- %s=+" ),
1633 sourcePins[0]->GetNumber(),
1634 sourcePins[1]->GetNumber() );
1638 pinMap.Printf( wxT(
"%s=+ %s=-" ),
1639 sourcePins[0]->GetNumber(),
1640 sourcePins[1]->GetNumber() );
1645 for(
unsigned ii = 0; ii < pinIndexes.size(); ++ii )
1648 pinMap.Append( wxS(
" " ) );
1651 sourcePins[ii]->GetNumber(),
1652 pinIndexes[ ii ] ) );
1657 legacyPins->SetText( pinMap );
1660 if( T_field* legacyParams = aSymbol.FindField( wxT(
"Sim_Params" ) ) )
1668 wxString spiceDeviceType = spiceDeviceInfo.m_Text.Trim(
true ).Trim(
false );
1669 wxString spiceLib = spiceLibInfo.m_Text.Trim(
true ).Trim(
false );
1670 wxString spiceModel = spiceModelInfo.m_Text.Trim(
true ).Trim(
false );
1672 bool libraryModel =
false;
1673 bool inferredModel =
false;
1674 bool internalModel =
false;
1676 if( !spiceLib.IsEmpty() )
1681 std::vector<T_field> emptyFields;
1684 emptyFields, sourcePins );
1687 libraryModel =
false;
1689 libraryModel =
true;
1691 if( pinMapInfo.IsEmpty() )
1696 model.
model.SIM_MODEL::createPins( sourcePins );
1699 if( pinMapInfo.IsEmpty() )
1700 pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
1703 else if( ( spiceDeviceType ==
"R" || spiceDeviceType ==
"L" || spiceDeviceType ==
"C" )
1704 && prefix.StartsWith( spiceDeviceType )
1705 && modelFromValueField )
1707 inferredModel =
true;
1714 wxStringTokenizer tokenizer( spiceModel, wxT(
"() " ), wxTOKEN_STRTOK );
1716 if( tokenizer.HasMoreTokens() )
1718 spiceTypeInfo.m_Text = tokenizer.GetNextToken();
1719 spiceTypeInfo.m_Text.MakeUpper();
1730 if( spiceTypeInfo.m_Text == wxT(
"DC" ) && tokenizer.CountTokens() == 1 )
1732 wxCHECK( valueField, );
1733 valueField->SetText( tokenizer.GetNextToken() );
1734 modelFromValueField =
false;
1738 for(
int ii = 0; tokenizer.HasMoreTokens(); ++ii )
1740 model->SetParamValue( ii, tokenizer.GetNextToken().ToStdString(),
1746 spiceParamsInfo = spiceModelInfo;
1747 spiceParamsInfo.m_Text = wxString( model->Serializer().GenerateParams() );
1750 internalModel =
true;
1752 if( pinMapInfo.IsEmpty() )
1755 model->createPins( sourcePins );
1756 pinMapInfo.m_Text = wxString( model->Serializer().GeneratePins() );
1773 aSymbol.AddField( libraryField );
1775 T_field nameField = spiceModelInfo.CreateField( &aSymbol,
SIM_NAME_FIELD );
1776 aSymbol.AddField( nameField );
1779 if( !spiceParamsInfo.IsEmpty() )
1781 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol,
SIM_PARAMS_FIELD );
1782 aSymbol.AddField( paramsField );
1785 if( modelFromValueField )
1786 valueField->SetText( wxT(
"${SIM.NAME}" ) );
1788 else if( inferredModel )
1793 else if( internalModel )
1796 aSymbol.AddField( deviceField );
1798 T_field typeField = spiceTypeInfo.CreateField( &aSymbol,
SIM_TYPE_FIELD );
1799 aSymbol.AddField( typeField );
1801 if( !spiceParamsInfo.IsEmpty() )
1803 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol,
SIM_PARAMS_FIELD );
1804 aSymbol.AddField( paramsField );
1807 if( modelFromValueField )
1808 valueField->SetText( wxT(
"${SIM.PARAMS}" ) );
1812 if( spiceDeviceType.IsEmpty() && spiceLib.IsEmpty() )
1814 spiceParamsInfo = spiceModelInfo;
1818 spiceParamsInfo.m_Text.Printf( wxT(
"type=\"%s\" model=\"%s\" lib=\"%s\"" ),
1819 spiceDeviceType, spiceModel, spiceLib );
1825 aSymbol.AddField( deviceField );
1827 T_field paramsField = spiceParamsInfo.CreateField( &aSymbol,
SIM_PARAMS_FIELD );
1828 aSymbol.AddField( paramsField );
1830 if( modelFromValueField )
1833 valueField = aSymbol.FindField( wxT(
"Value" ) );
1836 valueField->SetText( wxT(
"${SIM.PARAMS}" ) );
1842 if( pinMapInfo.IsEmpty() )
1843 pinMapInfo.m_Text = generateDefaultPinMapFromSymbol( sourcePins );
1846 if( !pinMapInfo.IsEmpty() )
1848 T_field pinsField = pinMapInfo.CreateField( &aSymbol,
SIM_PINS_FIELD );
1849 aSymbol.AddField( pinsField );
1854template void SIM_MODEL::MigrateSimModel<SCH_SYMBOL, SCH_FIELD>(
SCH_SYMBOL& aSymbol,
1856template void SIM_MODEL::MigrateSimModel<LIB_SYMBOL, LIB_FIELD>(
LIB_SYMBOL& aSymbol,
constexpr EDA_IU_SCALE schIUScale
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const wxString Problem() const
what was the problem?
Define a library symbol object.
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
Base class for any item which can be embedded within the SCHEMATIC container class,...
static constexpr auto DIFF_FIELD
SIM_MODEL & CreateModel(SIM_MODEL::TYPE aType, const std::vector< LIB_PIN * > &aPins)
static constexpr auto LEGACY_LIB_FIELD
static constexpr auto LEGACY_MODEL_FIELD
static constexpr auto LEGACY_ENABLED_FIELD
Serializes/deserializes a SIM_MODEL for storage in LIB_FIELDs/SCH_FIELDs.
std::string GeneratePins() const
int FindModelPinIndex(const std::string &aSymbolPinNumber)
static std::unique_ptr< SIM_MODEL > Create(TYPE aType, const std::vector< LIB_PIN * > &aPins, REPORTER *aReporter)
const PARAM & GetBaseParam(unsigned aParamIndex) const
void AddParam(const PARAM::INFO &aInfo)
bool IsStoredInValue() const
static bool InferSimModel(T_symbol &aSymbol, std::vector< T_field > *aFields, bool aResolve, SIM_VALUE_GRAMMAR::NOTATION aNotation, wxString *aDeviceType, wxString *aModelType, wxString *aModelParams, wxString *aPinMap)
virtual std::vector< std::string > GetPinNames() const
virtual bool requiresSpiceModelLine(const SPICE_ITEM &aItem) const
std::vector< PIN > m_pins
static INFO TypeInfo(TYPE aType)
std::vector< std::reference_wrapper< const PIN > > GetPins() const
static SPICE_INFO SpiceInfo(TYPE aType)
void ReadDataFields(const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
const SIM_MODEL_SERIALIZER & Serializer() const
static void SetFieldValue(std::vector< T > &aFields, const wxString &aFieldName, const std::string &aValue)
static TYPE ReadTypeFromFields(const std::vector< T > &aFields)
static std::string GetFieldValue(const std::vector< T > *aFields, const wxString &aFieldName, bool aResolve=true)
virtual const PARAM & GetParam(unsigned aParamIndex) const
void createPins(const std::vector< LIB_PIN * > &aSymbolPins)
virtual void SetBaseModel(const SIM_MODEL &aBaseModel)
void doWriteFields(std::vector< T > &aFields) const
int GetParamCount() const
void SetPinSymbolPinNumber(int aPinIndex, const std::string &aSymbolPinNumber)
void AddPin(const PIN &aPin)
static DEVICE_INFO DeviceInfo(DEVICE_T aDeviceType)
const PIN & GetPin(unsigned aIndex) const
const PARAM * FindParam(const std::string &aParamName) const
virtual void doSetParamValue(int aParamIndex, const std::string &aValue)
std::vector< PARAM > m_params
const PARAM & GetParamOverride(unsigned aParamIndex) const
static void MigrateSimModel(T_symbol &aSymbol, const PROJECT *aProject)
static TYPE InferTypeFromLegacyFields(const std::vector< T > &aFields)
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
virtual void SwitchSingleEndedDiff(bool aDiff)
std::vector< std::reference_wrapper< const PARAM > > GetParams() const
void WriteFields(std::vector< T > &aFields) const
std::unique_ptr< SIM_MODEL_SERIALIZER > m_serializer
virtual int doFindParam(const std::string &aParamName) const
void doReadDataFields(const std::vector< T > *aFields, const std::vector< LIB_PIN * > &aPins)
const SIM_MODEL * m_baseModel
static std::string Normalize(double aValue)
static std::string ConvertNotation(const std::string &aString, NOTATION aFromNotation, NOTATION aToNotation)
static double ToDouble(const std::string &aString, double aDefault=NAN)
A wrapper for reporting to a wxString object.
bool HasMessage() const override
Returns true if the reporter client is non-empty.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
#define THROW_IO_ERROR(msg)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
#define SIM_DEVICE_TYPE_FIELD
#define SIM_LIBRARY_FIELD
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
std::vector< std::string > enumValues
bool isSpiceInstanceParam
std::string symbolPinNumber
static constexpr auto NOT_CONNECTED
std::string inlineTypeString
std::string baseModelName