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