KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sim_model_source.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2022 Mikolaj Wielgus
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
22
23#include <cctype>
24#include <cstring>
25#include <fmt/format.h>
26
27
28namespace
29{
30 bool isWordChar( char c )
31 {
32 return std::isalnum( static_cast<unsigned char>( c ) ) != 0 || c == '_';
33 }
34
35 // Rewrite numeric literals inside a brace expression from KiCad SI notation to SPICE
36 // notation. KiCad uses 'M' for mega and 'P' for peta, while ngspice (case-insensitive)
37 // reads 'M' as milli and 'P' as pico, so a verbatim copy of "{t_start + 1M}" silently
38 // changes the value by nine orders of magnitude. Identifiers, operators, and whitespace
39 // are passed through; only tokens that begin where a number can legally start are
40 // rewritten via SIM_VALUE::ToSpice, which falls back to the original text when a token
41 // is not a recognizable number.
42 std::string rewriteBraceExpression( const std::string& aBrace )
43 {
44 std::string result;
45 std::size_t pos = 0;
46
47 while( pos < aBrace.size() )
48 {
49 const char c = aBrace[pos];
50 const bool prevIsWord = pos > 0 && isWordChar( aBrace[pos - 1] );
51 const bool digitStart = std::isdigit( static_cast<unsigned char>( c ) ) != 0;
52 const bool dotDigitStart = c == '.'
53 && pos + 1 < aBrace.size()
54 && std::isdigit( static_cast<unsigned char>( aBrace[pos + 1] ) ) != 0;
55
56 if( prevIsWord || ( !digitStart && !dotDigitStart ) )
57 {
58 result.push_back( c );
59 ++pos;
60 continue;
61 }
62
63 const std::size_t numStart = pos;
64
65 while( pos < aBrace.size() && std::isdigit( static_cast<unsigned char>( aBrace[pos] ) ) )
66 ++pos;
67
68 if( pos < aBrace.size() && aBrace[pos] == '.' )
69 {
70 ++pos;
71
72 while( pos < aBrace.size() && std::isdigit( static_cast<unsigned char>( aBrace[pos] ) ) )
73 ++pos;
74 }
75
76 if( pos < aBrace.size() && ( aBrace[pos] == 'e' || aBrace[pos] == 'E' ) )
77 {
78 const std::size_t expStart = pos++;
79
80 if( pos < aBrace.size() && ( aBrace[pos] == '+' || aBrace[pos] == '-' ) )
81 ++pos;
82
83 const std::size_t expDigits = pos;
84
85 while( pos < aBrace.size() && std::isdigit( static_cast<unsigned char>( aBrace[pos] ) ) )
86 ++pos;
87
88 // Bare 'e' with no following digits is an SI suffix candidate, not a float
89 // exponent. Roll back so the suffix scan below can claim it.
90 if( pos == expDigits )
91 pos = expStart;
92 }
93
94 // Optional single-letter SI prefix. Reject when followed by another alpha char,
95 // since that means the prefix is the start of an identifier (e.g. "1Meg" — leave
96 // ngspice's spelling untouched).
97 if( pos < aBrace.size()
98 && std::strchr( "afpnumkKMGTPE", aBrace[pos] ) != nullptr
99 && ( pos + 1 >= aBrace.size() || !std::isalpha( static_cast<unsigned char>( aBrace[pos + 1] ) ) ) )
100 {
101 ++pos;
102 }
103
104 result.append( SIM_VALUE::ToSpice( aBrace.substr( numStart, pos - numStart ) ) );
105 }
106
107 return result;
108 }
109
110 // Tokenize a PWL value string and convert each field to SPICE notation.
111 //
112 // The PWL value may contain plain numeric points ("0 0 1u 0 2u 1"), SI-notation unit
113 // prefixes (e.g. "1M" for mega -> "1Meg"), or simulator parameter references and
114 // arithmetic expressions wrapped in braces ("{t_start + 1u}"). Whitespace is the field
115 // separator except inside braces, whose contents are routed through
116 // rewriteBraceExpression so SI numeric literals inside the expression match the
117 // notation used outside it.
118 std::string formatPwlValues( const std::string& aInput )
119 {
120 std::string result;
121 std::size_t pos = 0;
122
123 auto isSpace =
124 []( char c )
125 {
126 return std::isspace( static_cast<unsigned char>( c ) ) != 0;
127 };
128
129 while( pos < aInput.size() )
130 {
131 while( pos < aInput.size() && isSpace( aInput[pos] ) )
132 ++pos;
133
134 if( pos >= aInput.size() )
135 break;
136
137 const std::size_t start = pos;
138 int braceDepth = 0;
139
140 while( pos < aInput.size() && ( braceDepth > 0 || !isSpace( aInput[pos] ) ) )
141 {
142 if( aInput[pos] == '{' )
143 ++braceDepth;
144 else if( aInput[pos] == '}' && braceDepth > 0 )
145 --braceDepth;
146
147 ++pos;
148 }
149
150 std::string token = aInput.substr( start, pos - start );
151
152 if( token.front() == '{' )
153 result.append( rewriteBraceExpression( token ) );
154 else
155 result.append( SIM_VALUE::ToSpice( token ) );
156
157 result.append( " " );
158 }
159
160 return result;
161 }
162}
163
164
165std::string SPICE_GENERATOR_SOURCE::ModelLine( const SPICE_ITEM& aItem ) const
166{
167 return "";
168}
169
170std::string SPICE_GENERATOR_SOURCE::TunerCommand( const SPICE_ITEM& aItem, double aValue ) const
171{
172 std::string result = "";
173
174 switch( aItem.model->GetType() )
175 {
176 case SIM_MODEL::TYPE::V: // VDC/IDC: it is clear which parameter should be used
177 case SIM_MODEL::TYPE::I:
178 result = fmt::format( "alter @{}={:g}",
179 aItem.model->SpiceGenerator().ItemName( aItem ),
180 aValue );
181 break;
182
183 default:
184 break; // other sources: unclear which parameter the user wants
185 }
186 return result;
187}
188
189std::string SPICE_GENERATOR_SOURCE::ItemLine( const SPICE_ITEM& aItem ) const
190{
191 SPICE_ITEM item = aItem;
192
193 std::string ac = "";
194 std::string dc = "";
195
196 if( const SIM_MODEL::PARAM* ac_param = m_model.FindParam( "ac" ) )
197 ac = SIM_VALUE::ToSpice( ac_param->value );
198 if( const SIM_MODEL::PARAM* dc_param = m_model.FindParam( "dc" ) )
199 dc = SIM_VALUE::ToSpice( dc_param->value );
200
201 bool emptyLine = true;
202 item.modelName = "";
203
204 // @FIXME
205 // the keyword "DC" refers to both offset of a sine source, and value for DC analysis
206 // Because of this, both values are always equal in a sine source.
207 //
208 // suggestion: rename the sine parameter from "DC" to "offset"
209
210 if( dc != "" )
211 {
212 emptyLine = false;
213 item.modelName += fmt::format( "DC {} ", dc );
214 }
215
216 if( m_model.GetSpiceInfo().functionName != ""
217 && m_model.GetType() != SIM_MODEL::TYPE::V // DC-only sources are already processed
218 && m_model.GetType() != SIM_MODEL::TYPE::I )
219 {
220 std::string args = "";
221
222 switch( m_model.GetType() )
223 {
224 case SIM_MODEL::TYPE::V_PWL:
225 case SIM_MODEL::TYPE::I_PWL:
226 args = formatPwlValues( m_model.GetParam( 0 ).value );
227 break;
228
229 case SIM_MODEL::TYPE::V_WHITENOISE:
230 case SIM_MODEL::TYPE::I_WHITENOISE:
231 args.append( getParamValueString( "rms", "0" ) + " " );
232 args.append( getParamValueString( "dt", "0" ) + " " );
233 args.append( "0 0 0 0 0 " );
234 break;
235
236 case SIM_MODEL::TYPE::V_PINKNOISE:
237 case SIM_MODEL::TYPE::I_PINKNOISE:
238 args.append( "0 " );
239 args.append( getParamValueString( "dt", "0" ) + " " );
240 args.append( getParamValueString( "slope", "0" ) + " " );
241 args.append( getParamValueString( "rms", "0" ) + " " );
242 args.append( "0 0 0 " );
243 break;
244
245 case SIM_MODEL::TYPE::V_BURSTNOISE:
246 case SIM_MODEL::TYPE::I_BURSTNOISE:
247 args.append( "0 0 0 0 " );
248 args.append( getParamValueString( "ampl", "0" ) + " " );
249 args.append( getParamValueString( "tcapt", "0" ) + " " );
250 args.append( getParamValueString( "temit", "0" ) + " " );
251 break;
252
253 case SIM_MODEL::TYPE::V_RANDUNIFORM:
254 case SIM_MODEL::TYPE::I_RANDUNIFORM:
255 args.append( "1 " );
256 args.append( getParamValueString( "ts", "0" ) + " " );
257 args.append( getParamValueString( "td", "0" ) + " " );
258 args.append( getParamValueString( "range", "1" ) + " " );
259 args.append( getParamValueString( "offset", "0" ) + " " );
260 break;
261
262 case SIM_MODEL::TYPE::V_RANDGAUSSIAN:
263 case SIM_MODEL::TYPE::I_RANDGAUSSIAN:
264 args.append( "2 " );
265 args.append( getParamValueString( "ts", "0" ) + " " );
266 args.append( getParamValueString( "td", "0" ) + " " );
267 args.append( getParamValueString( "stddev", "1" ) + " " );
268 args.append( getParamValueString( "mean", "0" ) + " " );
269 break;
270
271 case SIM_MODEL::TYPE::V_RANDEXP:
272 case SIM_MODEL::TYPE::I_RANDEXP:
273 args.append( "3 " );
274 args.append( getParamValueString( "ts", "0" ) + " " );
275 args.append( getParamValueString( "td", "0" ) + " " );
276 args.append( getParamValueString( "mean", "1" ) + " " );
277 args.append( getParamValueString( "offset", "0" ) + " " );
278 break;
279
280 case SIM_MODEL::TYPE::V_RANDPOISSON:
281 case SIM_MODEL::TYPE::I_RANDPOISSON:
282 args.append( "4 " );
283 args.append( getParamValueString( "ts", "0" ) + " " );
284 args.append( getParamValueString( "td", "0" ) + " " );
285 args.append( getParamValueString( "lambda", "1" ) + " " );
286 args.append( getParamValueString( "offset", "0" ) + " " );
287 break;
288
289 default:
290 for( int ii = 0; ii < m_model.GetParamCount(); ++ii )
291 {
292 const SIM_MODEL::PARAM& param = m_model.GetParam( ii );
293
294 if( ac != "" && ( param.Matches( "ac" ) || param.Matches( "ph" ) ) )
295 continue;
296
297 std::string argStr = SIM_VALUE::ToSpice( param.value );
298
299 if( argStr != "" )
300 args.append( argStr + " " );
301 }
302
303 // ngspice 46+ changed the PULSE PER default from TSTOP to TR+TF+PW, which turns a
304 // single-shot pulse into a continuous pulse train. When the user has not provided
305 // PER or NP, force a single pulse by appending PER=0 (lets ngspice apply its
306 // internal default) and NP=1.
307 if( m_model.GetType() == SIM_MODEL::TYPE::V_PULSE
308 || m_model.GetType() == SIM_MODEL::TYPE::I_PULSE )
309 {
310 const SIM_MODEL::PARAM* perParam = m_model.FindParam( "per" );
311 const SIM_MODEL::PARAM* npParam = m_model.FindParam( "np" );
312
313 bool perSet = perParam && SIM_VALUE::ToSpice( perParam->value ) != "";
314 bool npSet = npParam && SIM_VALUE::ToSpice( npParam->value ) != "";
315
316 if( !perSet && !npSet )
317 args.append( "0 1 " );
318 }
319
320 break;
321 }
322
323 emptyLine = false;
324 item.modelName += fmt::format( "{}( {}) ", m_model.GetSpiceInfo().functionName, args );
325 }
326 else
327 {
328 switch( m_model.GetType() )
329 {
330 case SIM_MODEL::TYPE::V_VCL:
331 case SIM_MODEL::TYPE::I_VCL:
332 item.modelName += fmt::format( "{} ", getParamValueString( "gain", "1.0" ) );
333 emptyLine = false;
334 break;
335
336 case SIM_MODEL::TYPE::V_CCL:
337 case SIM_MODEL::TYPE::I_CCL:
338 item.modelName += fmt::format( "{} {} ",
339 getParamValueString( "control", "V?" ),
340 getParamValueString( "gain", "1.0" ) );
341 emptyLine = false;
342 break;
343
344 default:
345 break;
346 }
347 }
348
349 if( ac != "" )
350 {
351 std::string ph = "";
352
353 if( const SIM_MODEL::PARAM* ph_param = m_model.FindParam( "ph" ) )
354 ph = SIM_VALUE::ToSpice( ph_param->value );
355
356 emptyLine = false;
357 item.modelName += fmt::format( "AC {} {} ", ac, ph );
358 }
359
360 std::string portnum = "";
361
362 if( const SIM_MODEL::PARAM* portnum_param = m_model.FindParam( "portnum" ) )
363 portnum = SIM_VALUE::ToSpice( portnum_param->value );
364
365 if( portnum != "" )
366 {
367 item.modelName += fmt::format( "portnum {} ", portnum );
368
369 std::string z0 = "";
370
371 if( const SIM_MODEL::PARAM* z0_param = m_model.FindParam( "z0" ) )
372 z0 = SIM_VALUE::ToSpice( z0_param->value );
373
374 if( z0 != "" )
375 item.modelName += fmt::format( "z0 {} ", z0 );
376 }
377
378 if( emptyLine )
379 item.modelName = SIM_VALUE::ToSpice( m_model.GetParam( 0 ).value );
380
381 return SPICE_GENERATOR::ItemLine( item );
382}
383
384
385std::string SPICE_GENERATOR_SOURCE::getParamValueString( const std::string& aParamName,
386 const std::string& aDefaultValue ) const
387{
388 std::string result = "";
389
390 if ( m_model.FindParam( aParamName ) )
391 result = SIM_VALUE::ToSpice( m_model.FindParam( aParamName )->value );
392
393 if( result == "" )
394 result = aDefaultValue;
395
396 return result;
397}
398
399
401 SIM_MODEL( aType, std::make_unique<SPICE_GENERATOR_SOURCE>( *this ),
402 std::make_unique<SIM_MODEL_SOURCE_SERIALIZER>( *this ) )
403{
404 for( const SIM_MODEL::PARAM::INFO& paramInfo : makeParamInfos( aType ) )
405 AddParam( paramInfo );
406}
407
408
409void SIM_MODEL_SOURCE::doSetParamValue( int aParamIndex, const std::string& aValue )
410{
411 // Sources are special. All preceding parameter values must be filled. If they are not, fill
412 // them out automatically. If a value is nulled, delete everything after it.
413 if( aValue.empty() )
414 {
415 for( int paramIndex = aParamIndex; paramIndex < GetParamCount(); ++paramIndex )
416 m_params.at( aParamIndex ).value = "";
417 }
418 else
419 {
420 for( int paramIndex = 0; paramIndex < aParamIndex; ++paramIndex )
421 {
422 if( GetParam( paramIndex ).value == "" )
423 {
424 double dummy;
425 wxString defaultValue = m_params.at( aParamIndex ).info.defaultValue;
426
427 if( !defaultValue.ToDouble( &dummy ) )
428 defaultValue = wxT( "0" );
429
430 m_params.at( aParamIndex ).value = defaultValue;
431 SIM_MODEL::SetParamValue( paramIndex, defaultValue.ToStdString() );
432 }
433 }
434 }
435
436 return SIM_MODEL::doSetParamValue( aParamIndex, aValue );
437}
438
439
440const std::vector<SIM_MODEL::PARAM::INFO>& SIM_MODEL_SOURCE::makeParamInfos( TYPE aType )
441{
442 static std::vector<PARAM::INFO> vdc = makeDcParamInfos( "y", "V" );
443 static std::vector<PARAM::INFO> idc = makeDcParamInfos( "y", "A" );
444
445 static std::vector<PARAM::INFO> vsin = makeSinParamInfos( "y", "V" );
446 static std::vector<PARAM::INFO> isin = makeSinParamInfos( "y", "A" );
447
448 static std::vector<PARAM::INFO> vpulse = makePulseParamInfos( "y", "V" );
449 static std::vector<PARAM::INFO> ipulse = makePulseParamInfos( "y", "A" );
450
451 static std::vector<PARAM::INFO> vexp = makeExpParamInfos( "y", "V" );
452 static std::vector<PARAM::INFO> iexp = makeExpParamInfos( "y", "A" );
453
454 static std::vector<PARAM::INFO> vam = makeAMParamInfos( "y", "V" );
455 static std::vector<PARAM::INFO> iam = makeAMParamInfos( "y", "A" );
456
457 static std::vector<PARAM::INFO> vsffm = makeSFFMParamInfos( "y", "V" );
458 static std::vector<PARAM::INFO> isffm = makeSFFMParamInfos( "y", "A" );
459
460 static std::vector<PARAM::INFO> vcvs = makeVcParamInfos( "" );
461 static std::vector<PARAM::INFO> ccvs = makeCcParamInfos( "ohm" );
462 static std::vector<PARAM::INFO> vpwl = makePwlParamInfos( "y", "Voltage", "V" );
463
464 static std::vector<PARAM::INFO> vccs = makeVcParamInfos( "S" );
465 static std::vector<PARAM::INFO> cccs = makeCcParamInfos( "" );
466 static std::vector<PARAM::INFO> ipwl = makePwlParamInfos( "y", "Current", "A" );
467
468 static std::vector<PARAM::INFO> vwhitenoise = makeWhiteNoiseParamInfos( "y", "V" );
469 static std::vector<PARAM::INFO> iwhitenoise = makeWhiteNoiseParamInfos( "y", "A" );
470
471 static std::vector<PARAM::INFO> vpinknoise = makePinkNoiseParamInfos( "y", "V" );
472 static std::vector<PARAM::INFO> ipinknoise = makePinkNoiseParamInfos( "y", "A" );
473
474 static std::vector<PARAM::INFO> vburstnoise = makeBurstNoiseParamInfos( "y", "V" );
475 static std::vector<PARAM::INFO> iburstnoise = makeBurstNoiseParamInfos( "y", "A" );
476
477 static std::vector<PARAM::INFO> vrandomuniform = makeRandomUniformParamInfos( "y", "V" );
478 static std::vector<PARAM::INFO> irandomuniform = makeRandomUniformParamInfos( "y", "A" );
479
480 static std::vector<PARAM::INFO> vrandomnormal = makeRandomNormalParamInfos( "y", "V" );
481 static std::vector<PARAM::INFO> irandomnormal = makeRandomNormalParamInfos( "y", "A" );
482
483 static std::vector<PARAM::INFO> vrandomexp = makeRandomExpParamInfos( "y", "V" );
484 static std::vector<PARAM::INFO> irandomexp = makeRandomExpParamInfos( "y", "A" );
485
486 static std::vector<PARAM::INFO> vrandompoisson = makeRandomPoissonParamInfos( "y", "V" );
487 static std::vector<PARAM::INFO> irandompoisson = makeRandomPoissonParamInfos( "y", "A" );
488
489 switch( aType )
490 {
491 case TYPE::V: return vdc;
492 case TYPE::I: return idc;
493 case TYPE::V_SIN: return vsin;
494 case TYPE::I_SIN: return isin;
495 case TYPE::V_PULSE: return vpulse;
496 case TYPE::I_PULSE: return ipulse;
497 case TYPE::V_EXP: return vexp;
498 case TYPE::I_EXP: return iexp;
499 case TYPE::V_AM: return vam;
500 case TYPE::I_AM: return iam;
501 case TYPE::V_SFFM: return vsffm;
502 case TYPE::I_SFFM: return isffm;
503 case TYPE::V_VCL: return vcvs;
504 case TYPE::V_CCL: return ccvs;
505 case TYPE::V_PWL: return vpwl;
506 case TYPE::I_VCL: return vccs;
507 case TYPE::I_CCL: return cccs;
508 case TYPE::I_PWL: return ipwl;
509 case TYPE::V_WHITENOISE: return vwhitenoise;
510 case TYPE::I_WHITENOISE: return iwhitenoise;
511 case TYPE::V_PINKNOISE: return vpinknoise;
512 case TYPE::I_PINKNOISE: return ipinknoise;
513 case TYPE::V_BURSTNOISE: return vburstnoise;
514 case TYPE::I_BURSTNOISE: return iburstnoise;
515 case TYPE::V_RANDUNIFORM: return vrandomuniform;
516 case TYPE::I_RANDUNIFORM: return irandomuniform;
517 case TYPE::V_RANDGAUSSIAN: return vrandomnormal;
518 case TYPE::I_RANDGAUSSIAN: return irandomnormal;
519 case TYPE::V_RANDEXP: return vrandomexp;
520 case TYPE::I_RANDEXP: return irandomexp;
521 case TYPE::V_RANDPOISSON: return vrandompoisson;
522 case TYPE::I_RANDPOISSON: return irandompoisson;
523 default:
524 wxFAIL_MSG( "Unhandled SIM_MODEL type in SIM_MODEL_SOURCE" );
525 static std::vector<SIM_MODEL::PARAM::INFO> empty;
526 return empty;
527 }
528}
529
530
531std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeDcParamInfos( const std::string& aPrefix,
532 const std::string& aUnit )
533{
534 std::vector<PARAM::INFO> paramInfos;
535 PARAM::INFO paramInfo;
536
537 paramInfo.name = "dc";
538 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
539 paramInfo.unit = aUnit;
540 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
541 paramInfo.defaultValue = "0";
542 paramInfo.description = "DC value";
543 paramInfos.push_back( paramInfo );
544
545 appendAcParamInfos( paramInfos, aUnit );
546 appendSpParamInfos( paramInfos, aUnit );
547 return paramInfos;
548}
549
550
551std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSinParamInfos( const std::string& aPrefix,
552 const std::string& aUnit )
553{
554 std::vector<PARAM::INFO> paramInfos;
555 PARAM::INFO paramInfo;
556
557 paramInfo.name = "dc";
558 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
559 paramInfo.unit = aUnit;
560 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
561 paramInfo.defaultValue = "";
562 paramInfo.description = "DC offset";
563 paramInfos.push_back( paramInfo );
564
565 paramInfo.name = "ampl";
566 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
567 paramInfo.unit = aUnit;
568 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
569 paramInfo.defaultValue = "";
570 paramInfo.description = "Amplitude";
571 paramInfos.push_back( paramInfo );
572
573 paramInfo.name = "f";
574 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
575 paramInfo.unit = "Hz";
576 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
577 paramInfo.defaultValue = "1/tstop";
578 paramInfo.description = "Frequency";
579 paramInfos.push_back( paramInfo );
580
581 paramInfo.name = "td";
582 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
583 paramInfo.unit = "s";
584 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
585 paramInfo.defaultValue = "0";
586 paramInfo.description = "Delay";
587 paramInfos.push_back( paramInfo );
588
589 paramInfo.name = "theta";
590 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
591 paramInfo.unit = "1/s";
592 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
593 paramInfo.defaultValue = "0";
594 paramInfo.description = "Damping factor";
595 paramInfos.push_back( paramInfo );
596
597 paramInfo.name = "phase";
598 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
599 paramInfo.unit = "°";
600 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
601 paramInfo.defaultValue = "0";
602 paramInfo.description = "Phase";
603 paramInfos.push_back( paramInfo );
604
605 appendAcParamInfos( paramInfos, aUnit );
606 appendSpParamInfos( paramInfos, aUnit );
607 return paramInfos;
608}
609
610
611std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePulseParamInfos( const std::string& aPrefix,
612 const std::string& aUnit )
613{
614 std::vector<PARAM::INFO> paramInfos;
615 PARAM::INFO paramInfo;
616
617 paramInfo.name = aPrefix + "1";
618 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
619 paramInfo.unit = aUnit;
620 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
621 paramInfo.defaultValue = "";
622 paramInfo.description = "Initial value";
623 paramInfos.push_back( paramInfo );
624
625 paramInfo.name = aPrefix + "2";
626 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
627 paramInfo.unit = aUnit;
628 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
629 paramInfo.defaultValue = "";
630 paramInfo.description = "Pulsed value";
631 paramInfos.push_back( paramInfo );
632
633 paramInfo.name = "td";
634 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
635 paramInfo.unit = "s";
636 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
637 paramInfo.defaultValue = "0";
638 paramInfo.description = "Delay";
639 paramInfos.push_back( paramInfo );
640
641 paramInfo.name = "tr";
642 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
643 paramInfo.unit = "s";
644 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
645 paramInfo.defaultValue = "tstep";
646 paramInfo.description = "Rise time";
647 paramInfos.push_back( paramInfo );
648
649 paramInfo.name = "tf";
650 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
651 paramInfo.unit = "s";
652 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
653 paramInfo.defaultValue = "tstep";
654 paramInfo.description = "Fall time";
655 paramInfos.push_back( paramInfo );
656
657 paramInfo.name = "tw"; // Ngspice calls it "pw".
658 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
659 paramInfo.unit = "s";
660 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
661 paramInfo.defaultValue = "tstop";
662 paramInfo.description = "Pulse width";
663 paramInfos.push_back( paramInfo );
664
665 paramInfo.name = "per";
666 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
667 paramInfo.unit = "s";
668 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
669 paramInfo.defaultValue = "tstop";
670 paramInfo.description = "Period";
671 paramInfos.push_back( paramInfo );
672
673 paramInfo.name = "np";
674 paramInfo.type = SIM_VALUE::TYPE_INT;
675 paramInfo.unit = "";
676 paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
677 paramInfo.defaultValue = "";
678 paramInfo.description = "Number of pulses";
679 paramInfos.push_back( paramInfo );
680
681 appendAcParamInfos( paramInfos, aUnit );
682 appendSpParamInfos( paramInfos, aUnit );
683 return paramInfos;
684}
685
686
687std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeExpParamInfos( const std::string& aPrefix,
688 const std::string& aUnit )
689{
690 std::vector<PARAM::INFO> paramInfos;
691 PARAM::INFO paramInfo;
692
693 paramInfo.name = aPrefix + "1";
694 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
695 paramInfo.unit = aUnit;
696 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
697 paramInfo.defaultValue = "";
698 paramInfo.description = "Initial value";
699 paramInfos.push_back( paramInfo );
700
701 paramInfo.name = aPrefix + "2";
702 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
703 paramInfo.unit = aUnit;
704 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
705 paramInfo.defaultValue = "";
706 paramInfo.description = "Pulsed value";
707 paramInfos.push_back( paramInfo );
708
709 paramInfo.name = "td1";
710 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
711 paramInfo.unit = "s";
712 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
713 paramInfo.defaultValue = "0";
714 paramInfo.description = "Rise delay time";
715 paramInfos.push_back( paramInfo );
716
717 paramInfo.name = "tau1";
718 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
719 paramInfo.unit = "s";
720 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
721 paramInfo.defaultValue = "tstep";
722 paramInfo.description = "Rise time constant";
723 paramInfos.push_back( paramInfo );
724
725 paramInfo.name = "td2";
726 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
727 paramInfo.unit = "s";
728 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
729 paramInfo.defaultValue = "td1+tstep";
730 paramInfo.description = "Fall delay time";
731 paramInfos.push_back( paramInfo );
732
733 paramInfo.name = "tau2";
734 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
735 paramInfo.unit = "s";
736 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
737 paramInfo.defaultValue = "tstep";
738 paramInfo.description = "Fall time constant";
739 paramInfos.push_back( paramInfo );
740
741 appendAcParamInfos( paramInfos, aUnit );
742 appendSpParamInfos( paramInfos, aUnit );
743 return paramInfos;
744}
745
746
747std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeAMParamInfos( const std::string& aPrefix,
748 const std::string& aUnit )
749{
750 std::vector<PARAM::INFO> paramInfos;
751 PARAM::INFO paramInfo;
752
753 paramInfo.name = "vo";
754 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
755 paramInfo.unit = aUnit;
756 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
757 paramInfo.defaultValue = "";
758 paramInfo.description = "Overall offset";
759 paramInfos.push_back( paramInfo );
760
761 paramInfo.name = "vmo";
762 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
763 paramInfo.unit = aUnit;
764 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
765 paramInfo.defaultValue = "";
766 paramInfo.description = "Modulation signal offset";
767 paramInfos.push_back( paramInfo );
768
769 paramInfo.name = "vma";
770 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
771 paramInfo.unit = aUnit;
772 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
773 paramInfo.defaultValue = "";
774 paramInfo.description = "Modulation signal amplitude";
775 paramInfos.push_back( paramInfo );
776
777 paramInfo.name = "fm";
778 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
779 paramInfo.unit = "Hz";
780 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
781 paramInfo.defaultValue = "5/tstop";
782 paramInfo.description = "Modulation signal frequency";
783 paramInfos.push_back( paramInfo );
784
785 paramInfo.name = "fc";
786 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
787 paramInfo.unit = "Hz";
788 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
789 paramInfo.defaultValue = "500/tstop";
790 paramInfo.description = "Carrier signal frequency";
791 paramInfos.push_back( paramInfo );
792
793 paramInfo.name = "td";
794 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
795 paramInfo.unit = "s";
796 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
797 paramInfo.defaultValue = "0";
798 paramInfo.description = "Overall delay";
799 paramInfos.push_back( paramInfo );
800
801 paramInfo.name = "phasem";
802 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
803 paramInfo.unit = "°";
804 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
805 paramInfo.defaultValue = "0";
806 paramInfo.description = "Modulation signal phase";
807 paramInfos.push_back( paramInfo );
808
809 paramInfo.name = "phasec";
810 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
811 paramInfo.unit = "°";
812 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
813 paramInfo.defaultValue = "0";
814 paramInfo.description = "Carrier signal phase";
815 paramInfos.push_back( paramInfo );
816
817 appendAcParamInfos( paramInfos, aUnit );
818 appendSpParamInfos( paramInfos, aUnit );
819 return paramInfos;
820}
821
822
823std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeSFFMParamInfos( const std::string& aPrefix,
824 const std::string& aUnit )
825{
826 std::vector<PARAM::INFO> paramInfos;
827 PARAM::INFO paramInfo;
828
829 paramInfo.name = "vo";
830 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
831 paramInfo.unit = aUnit;
832 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
833 paramInfo.defaultValue = "";
834 paramInfo.description = "DC offset";
835 paramInfos.push_back( paramInfo );
836
837 paramInfo.name = "va";
838 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
839 paramInfo.unit = aUnit;
840 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
841 paramInfo.defaultValue = "";
842 paramInfo.description = "Amplitude";
843 paramInfos.push_back( paramInfo );
844
845 paramInfo.name = "fm";
846 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
847 paramInfo.unit = "Hz";
848 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
849 paramInfo.defaultValue = "5/tstop";
850 paramInfo.description = "Modulating frequency";
851 paramInfos.push_back( paramInfo );
852
853 paramInfo.name = "mdi";
854 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
855 paramInfo.unit = "";
856 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
857 paramInfo.defaultValue = "";
858 paramInfo.description = "Modulation index";
859 paramInfos.push_back( paramInfo );
860
861 paramInfo.name = "fc";
862 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
863 paramInfo.unit = "Hz";
864 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
865 paramInfo.defaultValue = "500/tstop";
866 paramInfo.description = "Carrier frequency";
867 paramInfos.push_back( paramInfo );
868
869 paramInfo.name = "phasem";
870 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
871 paramInfo.unit = "°";
872 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
873 paramInfo.defaultValue = "0";
874 paramInfo.description = "Modulating signal phase";
875 paramInfos.push_back( paramInfo );
876
877 paramInfo.name = "phasec";
878 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
879 paramInfo.unit = "°";
880 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
881 paramInfo.defaultValue = "0";
882 paramInfo.description = "Carrier signal phase";
883 paramInfos.push_back( paramInfo );
884
885 appendAcParamInfos( paramInfos, aUnit );
886 appendSpParamInfos( paramInfos, aUnit );
887 return paramInfos;
888}
889
890
891std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeCcParamInfos( const std::string& aGainUnit )
892{
893 std::vector<PARAM::INFO> paramInfos;
894 PARAM::INFO paramInfo;
895
896 paramInfo.name = "gain";
897 paramInfo.id = 1;
898 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
899 paramInfo.unit = aGainUnit;
900 paramInfo.description = "Gain";
901 paramInfos.push_back( paramInfo );
902
903 paramInfo.name = "control";
904 paramInfo.id = 2;
905 paramInfo.type = SIM_VALUE::TYPE_STRING;
906 paramInfo.unit = "";
907 paramInfo.description = "Controlling voltage source";
908 paramInfos.push_back( paramInfo );
909
910 return paramInfos;
911}
912
913
914std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeVcParamInfos( const std::string& aGainUnit )
915{
916 std::vector<PARAM::INFO> paramInfos;
917 PARAM::INFO paramInfo;
918
919 paramInfo.name = "gain";
920 paramInfo.id = 1;
921 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
922 paramInfo.unit = aGainUnit;
923 paramInfo.description = "Gain";
924 paramInfos.push_back( paramInfo );
925
926 return paramInfos;
927}
928
929
930std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePwlParamInfos( const std::string& aPrefix,
931 const std::string& aQuantity,
932 const std::string& aUnit )
933{
934 std::vector<PARAM::INFO> paramInfos;
935 PARAM::INFO paramInfo;
936
937 paramInfo.name = "pwl";
938 paramInfo.type = SIM_VALUE::TYPE_STRING;
939 paramInfo.unit = "s," + aUnit;
940 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
941 paramInfo.defaultValue = "";
942 paramInfo.description = aUnit == "V" ? "Time-voltage points" : "Time-current points";
943 paramInfos.push_back( paramInfo );
944
945 appendAcParamInfos( paramInfos, aUnit );
946 appendSpParamInfos( paramInfos, aUnit );
947 return paramInfos;
948}
949
950
951std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeWhiteNoiseParamInfos( const std::string& aPrefix,
952 const std::string& aUnit )
953{
954 std::vector<PARAM::INFO> paramInfos;
955 PARAM::INFO paramInfo;
956
957 paramInfo.name = "rms";
958 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
959 paramInfo.unit = aUnit;
960 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
961 paramInfo.defaultValue = "0";
962 paramInfo.description = "White noise RMS amplitude";
963 paramInfos.push_back( paramInfo );
964
965 paramInfo.name = "dt";
966 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
967 paramInfo.unit = "s";
968 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
969 paramInfo.defaultValue = "0";
970 paramInfo.description = "Time step";
971 paramInfos.push_back( paramInfo );
972
973 appendAcParamInfos( paramInfos, aUnit );
974 appendSpParamInfos( paramInfos, aUnit );
975 return paramInfos;
976}
977
978
979std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makePinkNoiseParamInfos( const std::string& aPrefix,
980 const std::string& aUnit )
981{
982 std::vector<PARAM::INFO> paramInfos;
983 PARAM::INFO paramInfo;
984
985 paramInfo.name = "rms";
986 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
987 paramInfo.unit = "";
988 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
989 paramInfo.defaultValue = "0";
990 paramInfo.description = "1/f noise RMS amplitude";
991 paramInfos.push_back( paramInfo );
992
993 paramInfo.name = "slope";
994 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
995 paramInfo.unit = "";
996 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
997 paramInfo.defaultValue = "1";
998 paramInfo.description = "1/f noise exponent";
999 paramInfos.push_back( paramInfo );
1000
1001 paramInfo.name = "dt";
1002 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1003 paramInfo.unit = "s";
1004 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1005 paramInfo.defaultValue = "0";
1006 paramInfo.description = "Time step";
1007 paramInfos.push_back( paramInfo );
1008
1009 appendAcParamInfos( paramInfos, aUnit );
1010 appendSpParamInfos( paramInfos, aUnit );
1011 return paramInfos;
1012}
1013
1014
1015std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeBurstNoiseParamInfos( const std::string& aPrefix,
1016 const std::string& aUnit )
1017{
1018 std::vector<PARAM::INFO> paramInfos;
1019 PARAM::INFO paramInfo;
1020
1021 paramInfo.name = "ampl";
1022 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1023 paramInfo.unit = aUnit;
1024 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1025 paramInfo.defaultValue = "0";
1026 paramInfo.description = "Burst noise amplitude";
1027 paramInfos.push_back( paramInfo );
1028
1029 paramInfo.name = "tcapt";
1030 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1031 paramInfo.unit = "s";
1032 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1033 paramInfo.defaultValue = "0";
1034 paramInfo.description = "Burst noise trap capture time";
1035 paramInfos.push_back( paramInfo );
1036
1037 paramInfo.name = "temit";
1038 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1039 paramInfo.unit = "s";
1040 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1041 paramInfo.defaultValue = "0";
1042 paramInfo.description = "Burst noise trap emission time";
1043 paramInfos.push_back( paramInfo );
1044
1045 appendAcParamInfos( paramInfos, aUnit );
1046 appendSpParamInfos( paramInfos, aUnit );
1047 return paramInfos;
1048}
1049
1050
1051std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomUniformParamInfos( const std::string& aPrefix,
1052 const std::string& aUnit )
1053{
1054 std::vector<PARAM::INFO> paramInfos;
1055 PARAM::INFO paramInfo;
1056
1057 paramInfo.name = "ts";
1058 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1059 paramInfo.unit = "s";
1060 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1061 paramInfo.defaultValue = "";
1062 paramInfo.description = "Individual voltage duration";
1063 paramInfos.push_back( paramInfo );
1064
1065 paramInfo.name = "td";
1066 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1067 paramInfo.unit = "s";
1068 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1069 paramInfo.defaultValue = "0";
1070 paramInfo.description = "Delay";
1071 paramInfos.push_back( paramInfo );
1072
1073 paramInfo.name = "range";
1074 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1075 paramInfo.unit = aUnit;
1076 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1077 paramInfo.defaultValue = "1";
1078 paramInfo.description = "Range";
1079 paramInfos.push_back( paramInfo );
1080
1081 paramInfo.name = "offset";
1082 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1083 paramInfo.unit = aUnit;
1084 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1085 paramInfo.defaultValue = "0";
1086 paramInfo.description = "Offset";
1087 paramInfos.push_back( paramInfo );
1088
1089 appendAcParamInfos( paramInfos, aUnit );
1090 appendSpParamInfos( paramInfos, aUnit );
1091 return paramInfos;
1092}
1093
1094
1095std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomNormalParamInfos( const std::string& aPrefix,
1096 const std::string& aUnit )
1097{
1098 std::vector<PARAM::INFO> paramInfos;
1099 PARAM::INFO paramInfo;
1100
1101 paramInfo.name = "ts";
1102 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1103 paramInfo.unit = "s";
1104 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1105 paramInfo.defaultValue = "";
1106 paramInfo.description = "Individual voltage duration";
1107 paramInfos.push_back( paramInfo );
1108
1109 paramInfo.name = "td";
1110 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1111 paramInfo.unit = "s";
1112 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1113 paramInfo.defaultValue = "0";
1114 paramInfo.description = "Delay";
1115 paramInfos.push_back( paramInfo );
1116
1117 paramInfo.name = "stddev";
1118 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1119 paramInfo.unit = aUnit;
1120 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1121 paramInfo.defaultValue = "1";
1122 paramInfo.description = "Standard deviation";
1123 paramInfos.push_back( paramInfo );
1124
1125 paramInfo.name = "mean";
1126 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1127 paramInfo.unit = aUnit;
1128 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1129 paramInfo.defaultValue = "0";
1130 paramInfo.description = "Mean";
1131 paramInfos.push_back( paramInfo );
1132
1133 appendAcParamInfos( paramInfos, aUnit );
1134 appendSpParamInfos( paramInfos, aUnit );
1135 return paramInfos;
1136}
1137
1138
1139std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomExpParamInfos( const std::string& aPrefix,
1140 const std::string& aUnit )
1141{
1142 std::vector<PARAM::INFO> paramInfos;
1143 PARAM::INFO paramInfo;
1144
1145 paramInfo.name = "ts";
1146 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1147 paramInfo.unit = "s";
1148 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1149 paramInfo.defaultValue = "";
1150 paramInfo.description = "Individual voltage duration";
1151 paramInfos.push_back( paramInfo );
1152
1153 paramInfo.name = "td";
1154 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1155 paramInfo.unit = "s";
1156 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1157 paramInfo.defaultValue = "0";
1158 paramInfo.description = "Delay";
1159 paramInfos.push_back( paramInfo );
1160
1161 paramInfo.name = "mean";
1162 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1163 paramInfo.unit = aUnit;
1164 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1165 paramInfo.defaultValue = "1";
1166 paramInfo.description = "Mean";
1167 paramInfos.push_back( paramInfo );
1168
1169 paramInfo.name = "offset";
1170 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1171 paramInfo.unit = aUnit;
1172 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1173 paramInfo.defaultValue = "0";
1174 paramInfo.description = "Offset";
1175 paramInfos.push_back( paramInfo );
1176
1177 appendAcParamInfos( paramInfos, aUnit );
1178 appendSpParamInfos( paramInfos, aUnit );
1179 return paramInfos;
1180}
1181
1182
1183std::vector<SIM_MODEL::PARAM::INFO> SIM_MODEL_SOURCE::makeRandomPoissonParamInfos( const std::string& aPrefix,
1184 const std::string& aUnit )
1185{
1186 std::vector<PARAM::INFO> paramInfos;
1187 PARAM::INFO paramInfo;
1188
1189 paramInfo.name = "ts";
1190 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1191 paramInfo.unit = "s";
1192 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1193 paramInfo.defaultValue = "";
1194 paramInfo.description = "Individual voltage duration";
1195 paramInfos.push_back( paramInfo );
1196
1197 paramInfo.name = "td";
1198 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1199 paramInfo.unit = "s";
1200 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1201 paramInfo.defaultValue = "0";
1202 paramInfo.description = "Delay";
1203 paramInfos.push_back( paramInfo );
1204
1205 paramInfo.name = "lambda";
1206 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1207 paramInfo.unit = aUnit;
1208 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1209 paramInfo.defaultValue = "1";
1210 paramInfo.description = "Lambda";
1211 paramInfos.push_back( paramInfo );
1212
1213 paramInfo.name = "offset";
1214 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1215 paramInfo.unit = aUnit;
1216 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::PRINCIPAL;
1217 paramInfo.defaultValue = "0";
1218 paramInfo.description = "Offset";
1219 paramInfos.push_back( paramInfo );
1220
1221 appendAcParamInfos( paramInfos, aUnit );
1222 appendSpParamInfos( paramInfos, aUnit );
1223 return paramInfos;
1224}
1225
1226void SIM_MODEL_SOURCE::appendAcParamInfos( std::vector<PARAM::INFO>& aParamInfos, const std::string& aUnit )
1227{
1228 PARAM::INFO paramInfo;
1229
1230 paramInfo.name = "ac";
1231 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1232 paramInfo.unit = aUnit;
1233 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::AC;
1234 paramInfo.defaultValue = "0";
1235 paramInfo.description = "AC magnitude";
1236 aParamInfos.push_back( paramInfo );
1237
1238 paramInfo.name = "ph";
1239 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1240 paramInfo.unit = "°";
1241 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::AC;
1242 paramInfo.defaultValue = "0";
1243 paramInfo.description = "AC phase";
1244 aParamInfos.push_back( paramInfo );
1245}
1246
1247void SIM_MODEL_SOURCE::appendSpParamInfos( std::vector<PARAM::INFO>& aParamInfos,
1248 const std::string& aUnit )
1249{
1250 PARAM::INFO paramInfo;
1251
1252 if( !strcmp( aUnit.c_str(), "V" ) )
1253 {
1254 paramInfo.name = "portnum";
1255 paramInfo.type = SIM_VALUE::TYPE_INT;
1256 paramInfo.unit = "";
1257 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::S_PARAM;
1258 paramInfo.defaultValue = "";
1259 paramInfo.description = "Port number";
1260 aParamInfos.push_back( paramInfo );
1261
1262 paramInfo.name = "z0";
1263 paramInfo.type = SIM_VALUE::TYPE_FLOAT;
1264 paramInfo.unit = "Ohm";
1265 paramInfo.category = SIM_MODEL::PARAM::CATEGORY::S_PARAM;
1266 paramInfo.defaultValue = "";
1267 paramInfo.description = "Internal impedance";
1268 aParamInfos.push_back( paramInfo );
1269 }
1270}
1271
1272
1273std::vector<std::string> SIM_MODEL_SOURCE::GetPinNames() const
1274{
1275 if( GetDeviceType() == SIM_MODEL::DEVICE_T::E || GetDeviceType() == SIM_MODEL::DEVICE_T::G )
1276 return { "+", "-", "C+", "C-" };
1277 else
1278 return { "+", "-" };
1279}
1280
1282{
1283 switch( GetType() )
1284 {
1285 case SIM_MODEL::TYPE::V: // VDC/IDC: it is clear which parameter should be used
1286 case SIM_MODEL::TYPE::I:
1287 return &GetParam( 0 );
1288
1289 default:
1290 break; // other sources: unclear which parameter the user wants
1291 }
1292 return nullptr;
1293}
static void appendAcParamInfos(std::vector< PARAM::INFO > &aParamInfos, const std::string &aUnit)
static std::vector< PARAM::INFO > makeBurstNoiseParamInfos(const std::string &aPrefix, const std::string &aUnit)
std::vector< std::string > GetPinNames() const override
const PARAM * GetTunerParam() const override
static const std::vector< PARAM::INFO > & makeParamInfos(TYPE aType)
static std::vector< PARAM::INFO > makeExpParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeAMParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeRandomNormalParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< SIM_MODEL::PARAM::INFO > makeVcParamInfos(const std::string &aGainUnit)
static void appendSpParamInfos(std::vector< PARAM::INFO > &aParamInfos, const std::string &aUnit)
SIM_MODEL_SOURCE(TYPE aType)
static std::vector< PARAM::INFO > makeRandomExpParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeSFFMParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeRandomUniformParamInfos(const std::string &aPrefix, const std::string &aUnit)
void doSetParamValue(int aParamIndex, const std::string &aValue) override
static std::vector< PARAM::INFO > makeRandomPoissonParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeDcParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makePulseParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makePinkNoiseParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makeSinParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< PARAM::INFO > makePwlParamInfos(const std::string &aPrefix, const std::string &aQuantity, const std::string &aUnit)
static std::vector< PARAM::INFO > makeWhiteNoiseParamInfos(const std::string &aPrefix, const std::string &aUnit)
static std::vector< SIM_MODEL::PARAM::INFO > makeCcParamInfos(const std::string &aGainUnit)
void AddParam(const PARAM::INFO &aInfo)
const SPICE_GENERATOR & SpiceGenerator() const
Definition sim_model.h:429
virtual const PARAM & GetParam(unsigned aParamIndex) const
SIM_MODEL()=delete
int GetParamCount() const
Definition sim_model.h:488
DEVICE_T GetDeviceType() const
Definition sim_model.h:470
virtual void doSetParamValue(int aParamIndex, const std::string &aValue)
std::vector< PARAM > m_params
Definition sim_model.h:552
void SetParamValue(int aParamIndex, const std::string &aValue, SIM_VALUE::NOTATION aNotation=SIM_VALUE::NOTATION::SI)
TYPE GetType() const
Definition sim_model.h:471
@ TYPE_STRING
Definition sim_value.h:67
static std::string ToSpice(const std::string &aString)
std::string ModelLine(const SPICE_ITEM &aItem) const override
std::string ItemLine(const SPICE_ITEM &aItem) const override
std::string TunerCommand(const SPICE_ITEM &aItem, double aValue) const override
std::string getParamValueString(const std::string &aParamName, const std::string &aDefaultValue) const
virtual std::string ItemName(const SPICE_ITEM &aItem) const
virtual std::string ItemLine(const SPICE_ITEM &aItem) const
const SIM_MODEL & m_model
static bool empty(const wxTextEntryBase *aCtrl)
static bool isSpace(char cc)
Test for whitespace.
Definition dsnlexer.cpp:444
bool isWordChar(const wxUniChar &c)
Definition eda_item.cpp:312
STL namespace.
SIM_MODEL::TYPE TYPE
Definition sim_model.cpp:54
std::vector< FAB_LAYER_COLOR > dummy
bool Matches(const std::string &aName) const
Definition sim_model.h:393
std::string value
Definition sim_model.h:398
std::string modelName
const SIM_MODEL * model
wxString result
Test unit parsing edge cases and error handling.