KiCad PCB EDA Suite
Loading...
Searching...
No Matches
spice_generator.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
21
#include <
sim/spice_generator.h
>
22
23
#include <boost/algorithm/string/predicate.hpp>
24
#include <boost/algorithm/string/trim.hpp>
25
#include <fmt/core.h>
26
27
28
std::string
SPICE_GENERATOR::ModelName
(
const
SPICE_ITEM
& aItem )
const
29
{
30
if
( aItem.
baseModelName
==
""
)
31
return
fmt::format(
"__{}"
, aItem.
refName
);
32
33
if
(
m_model
.requiresSpiceModelLine( aItem ) )
34
return
fmt::format(
"{}.{}"
, aItem.
refName
, aItem.
baseModelName
);
35
36
return
aItem.
baseModelName
;
37
}
38
39
40
std::string
SPICE_GENERATOR::ModelLine
(
const
SPICE_ITEM
& aItem )
const
41
{
42
if
( !
m_model
.requiresSpiceModelLine( aItem ) )
43
return
""
;
44
45
std::string
result
;
46
47
result
.append( fmt::format(
".model {} "
, aItem.
modelName
) );
48
size_t
indentLength =
result
.length();
49
50
const
SIM_MODEL::SPICE_INFO
& spiceInfo =
m_model
.GetSpiceInfo();
51
result
.append( spiceInfo.
modelType
);
52
53
if
( !spiceInfo.
isDefaultLevel
&& !spiceInfo.
level
.empty() )
54
result
.append( fmt::format(
" level={}"
, spiceInfo.
level
) );
55
56
if
( !spiceInfo.
version
.empty() )
57
result
.append( fmt::format(
" version={}"
, spiceInfo.
version
) );
58
59
result
.append(
"\n"
);
60
61
for
(
int
ii = 0; ii <
m_model
.GetParamCount(); ++ii )
62
{
63
const
SIM_MODEL::PARAM
& param =
m_model
.GetParam( ii );
64
65
if
( param.
info
.
isSpiceInstanceParam
)
66
continue
;
67
68
std::string
name
;
69
std::string value;
70
71
if
( !param.
info
.
spiceModelName
.empty() )
72
{
73
name
= param.
info
.
spiceModelName
;
74
}
75
else
76
{
77
// Because of collisions with instance parameters, we append some model parameters
78
// with "_".
79
if
( boost::ends_with( param.
info
.
name
,
"_"
) )
80
name
= param.
info
.
name
.substr( 0, param.
info
.
name
.length() - 1 );
81
else
82
name
= param.
info
.
name
;
83
}
84
85
value =
SIM_VALUE::ToSpice
( param.
value
);
86
87
if
( value ==
""
)
88
continue
;
89
90
if
( param.
info
.
category
== SIM_MODEL::PARAM::CATEGORY::FLAGS )
91
{
92
if
( value ==
"1"
)
93
result
.append( fmt::format(
"+{}\n"
,
name
) );
94
}
95
else
96
{
97
result
.append( fmt::format(
"+{}{}={}\n"
,
98
std::string( indentLength - 1,
' '
),
99
name
,
100
value ) );
101
}
102
}
103
104
// Don't send SPICE empty models.
105
if
(
result
.length() == indentLength + 1
/* line ending */
)
106
result
.clear();
107
108
return
result
;
109
}
110
111
112
std::string
SPICE_GENERATOR::ItemLine
(
const
SPICE_ITEM
& aItem )
const
113
{
114
SPICE_ITEM
item = aItem;
115
116
if
( item.
pinNumbers
.empty() )
117
{
118
for
(
int
i = 0; i <
m_model
.GetPinCount(); ++i )
119
item.
pinNumbers
.push_back( fmt::format(
"{}"
, i + 1 ) );
120
}
121
122
if
( item.
pinNetNames
.empty() )
123
{
124
for
(
const
SIM_MODEL_PIN
&
pin
:
GetPins
() )
125
item.
pinNetNames
.push_back(
pin
.modelPinName );
126
}
127
128
std::string
result
;
129
result
.append(
ItemName
( aItem ) );
130
result
.append(
ItemPins
( aItem ) );
131
result
.append(
ItemModelName
( aItem ) );
132
result
.append(
ItemParams
() );
133
result
.append(
"\n"
);
134
return
result
;
135
}
136
137
138
std::string
SPICE_GENERATOR::ItemName
(
const
SPICE_ITEM
& aItem )
const
139
{
140
if
( aItem.
refName
!=
""
&& boost::starts_with( aItem.
refName
,
m_model
.GetSpiceInfo().itemType ) )
141
return
aItem.
refName
;
142
else
143
return
fmt::format(
"{}{}"
,
m_model
.GetSpiceInfo().itemType, aItem.
refName
);
144
}
145
146
147
std::string
SPICE_GENERATOR::ItemPins
(
const
SPICE_ITEM
& aItem )
const
148
{
149
std::string
result
;
150
int
ncCounter = 0;
151
152
for
(
const
SIM_MODEL_PIN
&
pin
:
GetPins
() )
153
{
154
auto
it = std::find( aItem.
pinNumbers
.begin(), aItem.
pinNumbers
.end(),
155
pin
.symbolPinNumber );
156
157
if
( it == aItem.
pinNumbers
.end() )
158
{
159
result
.append( fmt::format(
" NC-{}-{}"
, aItem.
refName
, ncCounter++ ) );
160
}
161
else
162
{
163
long
symbolPinIndex = std::distance( aItem.
pinNumbers
.begin(), it );
164
result
.append( fmt::format(
" {}"
, aItem.
pinNetNames
.at( symbolPinIndex ) ) );
165
}
166
}
167
168
return
result
;
169
}
170
171
172
std::string
SPICE_GENERATOR::ItemModelName
(
const
SPICE_ITEM
& aItem )
const
173
{
174
return
fmt::format(
" {}"
, aItem.
modelName
);
175
}
176
177
178
std::string
SPICE_GENERATOR::ItemParams
()
const
179
{
180
std::string
result
;
181
182
for
(
int
ii = 0; ii <
m_model
.GetParamCount(); ++ii )
183
{
184
const
SIM_MODEL::PARAM
& param =
m_model
.GetParam( ii );
185
186
if
( !param.
info
.
isSpiceInstanceParam
)
187
continue
;
188
189
std::string
name
= param.
info
.
spiceInstanceName
.empty() ? param.
info
.
name
190
: param.
info
.
spiceInstanceName
;
191
std::string value =
SIM_VALUE::ToSpice
( param.
value
);
192
193
if
( param.
info
.
category
== SIM_MODEL::PARAM::CATEGORY::FLAGS )
194
{
195
if
( value ==
"1"
)
196
result
.append( fmt::format(
" {}"
,
name
) );
197
}
198
else
199
{
200
if
( value !=
""
)
201
result
.append( fmt::format(
" {}={}"
,
name
, value ) );
202
}
203
}
204
205
return
result
;
206
}
207
208
209
std::string
SPICE_GENERATOR::TunerCommand
(
const
SPICE_ITEM
& aItem,
double
aValue )
const
210
{
211
// No tuning available by default.
212
return
""
;
213
}
214
215
216
std::vector<std::string>
SPICE_GENERATOR::CurrentNames
(
const
SPICE_ITEM
& aItem )
const
217
{
218
return
{ fmt::format(
"I({})"
,
ItemName
( aItem ) ) };
219
}
220
221
222
std::string
SPICE_GENERATOR::Preview
(
const
SPICE_ITEM
& aItem )
const
223
{
224
std::string spiceCode =
ModelLine
( aItem );
225
226
std::string itemLine =
ItemLine
( aItem );
227
228
if
( spiceCode !=
""
)
229
spiceCode.append(
"\n"
);
230
231
spiceCode.append( itemLine );
232
return
boost::trim_copy( spiceCode );
233
}
234
235
name
const char * name
Definition
DXF_plotter.cpp:61
SIM_VALUE::ToSpice
static std::string ToSpice(const std::string &aString)
Definition
sim_value.cpp:414
SPICE_GENERATOR::ItemName
virtual std::string ItemName(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:138
SPICE_GENERATOR::ItemPins
virtual std::string ItemPins(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:147
SPICE_GENERATOR::ItemLine
virtual std::string ItemLine(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:112
SPICE_GENERATOR::ModelLine
virtual std::string ModelLine(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:40
SPICE_GENERATOR::GetPins
virtual std::vector< std::reference_wrapper< const SIM_MODEL_PIN > > GetPins() const
Definition
spice_generator.h:64
SPICE_GENERATOR::ItemParams
virtual std::string ItemParams() const
Definition
spice_generator.cpp:178
SPICE_GENERATOR::m_model
const SIM_MODEL & m_model
Definition
spice_generator.h:69
SPICE_GENERATOR::Preview
virtual std::string Preview(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:222
SPICE_GENERATOR::ItemModelName
virtual std::string ItemModelName(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:172
SPICE_GENERATOR::TunerCommand
virtual std::string TunerCommand(const SPICE_ITEM &aItem, double aValue) const
Definition
spice_generator.cpp:209
SPICE_GENERATOR::ModelName
virtual std::string ModelName(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:28
SPICE_GENERATOR::CurrentNames
virtual std::vector< std::string > CurrentNames(const SPICE_ITEM &aItem) const
Definition
spice_generator.cpp:216
spice_generator.h
SIM_MODEL::PARAM::INFO::spiceModelName
std::string spiceModelName
Definition
sim_model.h:383
SIM_MODEL::PARAM::INFO::category
CATEGORY category
Definition
sim_model.h:378
SIM_MODEL::PARAM::INFO::name
std::string name
Definition
sim_model.h:373
SIM_MODEL::PARAM::INFO::spiceInstanceName
std::string spiceInstanceName
Definition
sim_model.h:384
SIM_MODEL::PARAM::INFO::isSpiceInstanceParam
bool isSpiceInstanceParam
Definition
sim_model.h:381
SIM_MODEL::PARAM
Definition
sim_model.h:312
SIM_MODEL::PARAM::value
std::string value
Definition
sim_model.h:397
SIM_MODEL::PARAM::info
const INFO & info
Definition
sim_model.h:398
SIM_MODEL::SPICE_INFO
Definition
sim_model.h:300
SIM_MODEL::SPICE_INFO::isDefaultLevel
bool isDefaultLevel
Definition
sim_model.h:305
SIM_MODEL::SPICE_INFO::modelType
std::string modelType
Definition
sim_model.h:302
SIM_MODEL::SPICE_INFO::level
std::string level
Definition
sim_model.h:304
SIM_MODEL::SPICE_INFO::version
std::string version
Definition
sim_model.h:307
SIM_MODEL_PIN
Definition
sim_model.h:66
SPICE_ITEM
Definition
spice_generator.h:30
SPICE_ITEM::refName
std::string refName
Definition
spice_generator.h:31
SPICE_ITEM::modelName
std::string modelName
Definition
spice_generator.h:35
SPICE_ITEM::pinNetNames
std::vector< std::string > pinNetNames
Definition
spice_generator.h:33
SPICE_ITEM::baseModelName
std::string baseModelName
Definition
spice_generator.h:34
SPICE_ITEM::pinNumbers
std::vector< std::string > pinNumbers
Definition
spice_generator.h:32
pin
KIBIS_PIN * pin
Definition
test_kibis.cpp:117
result
wxString result
Test unit parsing edge cases and error handling.
Definition
test_text_eval_numeric_compat.cpp:598
src
eeschema
sim
spice_generator.cpp
Generated on Fri Jun 26 2026 00:05:36 for KiCad PCB EDA Suite by
1.13.2