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