KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema/test_netlist_exporter_spice.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 KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25#include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?).
28#include <mock_pgm_base.h>
29#include <locale_io.h>
30
31
32
33BOOST_FIXTURE_TEST_SUITE( NetlistExporterSpice, TEST_NETLIST_EXPORTER_SPICE_FIXTURE )
34
35
37{
39
40 const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
41 MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
42
43 TestNetlist( "rectifier" );
44 TestTranPoint( 0, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
45 TestTranPoint( 9250e-6, { { "V(/in)", 5 }, { "V(/out)", 4.26 } } );
46 TestTranPoint( 10e-3, { { "V(/in)", 0 }, { "V(/out)", 4.24 } } );
47}
48
49// FIXME: Fails due to some nondeterminism, seems related to convergence problems.
50
51/*BOOST_AUTO_TEST_CASE( Chirp )
52{
53 LOCALE_IO dummy;
54 TestNetlist( "chirp", { "V(/out)", "I(R1)" } );
55}*/
56
57
59{
61 // Instead of Simulation_SPICE:OPAMP, we use Amplifier_Operational:MCP6001-OT because its pins
62 // are not ordered by pin numbers, which is a possible failure condition.
63
64 const MOCK_PGM_BASE& program = static_cast<MOCK_PGM_BASE&>( Pgm() );
65 MOCK_EXPECT( program.GetLocalEnvVariables ).returns( ENV_VAR_MAP() );
66
67 TestNetlist( "opamp" );
68 TestTranPoint( 0, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
69 TestTranPoint( 250e-6, { { "V(/in)", 500e-3 }, { "V(/out)", 1 } } );
70 TestTranPoint( 500e-6, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
71 TestTranPoint( 750e-6, { { "V(/in)", -500e-3 }, { "V(/out)", -1 } } );
72 TestTranPoint( 1e-3, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
73}
74
75
77{
79 // This test intentionally uses non-inferred voltage sources to test them.
80
81 TestNetlist( "npn_ce_amp" );
82 TestTranPoint( 900e-6, { { "V(/in)", 0 }, { "V(/out)", 5.32 } } );
83 TestTranPoint( 925e-6, { { "V(/in)", 10e-3 }, { "V(/out)", 5.30 } } );
84 TestTranPoint( 950e-6, { { "V(/in)", 0 }, { "V(/out)", 5.88 } } );
85 TestTranPoint( 975e-6, { { "V(/in)", -10e-3 }, { "V(/out)", 5.91 } } );
86 TestTranPoint( 1e-3, { { "V(/in)", 0 }, { "V(/out)", 5.32 } } );
87}
88
89// Incomplete. TODO.
91{
93 TestNetlist( "rlc" );
94 TestTranPoint( 9.43e-3, { { "V(/Vp)", -19e-3 }, { "I(Rs1)", 19e-3 } } );
95 TestTranPoint( 9.74e-3, { { "V(/Vp)", 19e-3 }, { "I(Rs1)", -19e-3 } } );
96}
97
98
99BOOST_AUTO_TEST_CASE( Potentiometers )
100{
101 TestNetlist( "potentiometers" );
102 TestOpPoint( 0.5, "V(/out1)" );
103 TestOpPoint( 0.7, "V(/out2)" );
104 TestOpPoint( 0.9, "V(/out3)" );
105}
106
107
109{
111 TestNetlist( "tlines" );
112 TestTranPoint( 910e-6, { { "V(/z0_in)", 1 }, { "V(/z0_out)", 0 },
113 { "V(/rlgc_in)", 1 }, { "V(/rlgc_out)", 0 } } );
114 TestTranPoint( 970e-6, { { "V(/z0_in)", 0 }, { "V(/z0_out)", 1 },
115 { "V(/rlgc_in)", 0 }, { "V(/rlgc_out)", 1 } } );
116}
117
118
119/*BOOST_AUTO_TEST_CASE( Sources )
120{
121 LOCALE_IO dummy;
122 TestNetlist( "sources", { "V(/vdc)", "V(/idc)",
123 "V(/vsin)", "V(/isin)",
124 "V(/vpulse)", "V(/ipulse)",
125 "V(/vexp)", "V(/iexp)",
126 "V(/vpwl)", "V(/ipwl)",
127 "V(/vbehavioral)", "V(/ibehavioral)" } );
128
129 // TODO: Make some tests for random and noise sources, e.g. check their RMS or spectra.
130 //"V(/vwhitenoise)", "V(/iwhitenoise)",
131 //"V(/vpinknoise)", "V(/ipinknoise)",
132 //"V(/vburstnoise)", "V(/iburstnoise)",
133 //"V(/vranduniform)", "V(/iranduniform)",
134 //"V(/vrandnormal)", "V(/iranduniform)",
135 //"V(/vrandexp)", "V(/irandexp)",
136}*/
137
138
140{
142 TestNetlist( "cmos_not" );
143 TestTranPoint( 0, { { "V(/in)", 2.5 }, { "V(/out)", 2.64 } } );
144 TestTranPoint( 250e-6, { { "V(/in)", 5 }, { "V(/out)", 0.013 } } );
145 TestTranPoint( 500e-6, { { "V(/in)", 2.5 }, { "V(/out)", 2.64 } } );
146 TestTranPoint( 750e-6, { { "V(/in)", 0 }, { "V(/out)", 5 } } );
147 TestTranPoint( 1e-3, { { "V(/in)", 2.5 }, { "V(/out)", 2.64 } } );
148}
149
150
151/*BOOST_AUTO_TEST_CASE( InstanceParams )
152{
153 // TODO.
154 //TestNetlist( "instance_params", {} );
155}*/
156
157
158BOOST_AUTO_TEST_CASE( FliegeFilter )
159{
161 // We test a multi-unit part here, as Fliege topology uses two op amps (power supply pins are a
162 // third part).
163
164 TestNetlist( "fliege_filter" );
165 TestACPoint( 0.8e3, { { "V(/in)", 1 }, { "V(/out)", 1 } } );
166 TestACPoint( 1.061e3, { { "V(/in)", 1 }, { "V(/out)", 0 } } );
167 TestACPoint( 1.2e3, { { "V(/in)", 1 }, { "V(/out)", 1 } } );
168}
169
170
172{
174 TestNetlist( "switches" );
175 TestTranPoint( 0.5e-3, { { "V(/inswv)", 0 }, { "V(/outswv)", 0 } } );
176 TestTranPoint( 1.5e-3, { { "V(/inswv)", 1 }, { "V(/outswv)", 5 } } );
177 TestTranPoint( 2.5e-3, { { "V(/inswv)", 0 }, { "V(/outswv)", 0 } } );
178
179 // TODO: Current switch, when it's fixed in Ngspice.
180}
181
182
183// This test is sometimes failing on certain platforms for unknown reasons
184// Disabling it for now so that it doesn't prevent packages from building
185#if 0
186BOOST_AUTO_TEST_CASE( Directives )
187{
189 TestNetlist( "directives" );
190 TestTranPoint( 9.25e-3, { { "V(/in)", 1 }, { "V(/out)", -900e-3 }, { "I(XR1)", 1e-3 } } );
191 TestTranPoint( 9.50e-3, { { "V(/in)", 0 }, { "V(/out)", 0 }, { "I(XR1)", 1e-3 } } );
192 TestTranPoint( 9.75e-3, { { "V(/in)", -1 }, { "V(/out)", 900e-3 }, { "I(XR1)", 1e-3 } } );
193 TestTranPoint( 10e-3, { { "V(/in)", 0 }, { "V(/out)", 0 }, { "I(XR1)", 1e-3 } } );
194}
195#endif
196
197
198// This test is flaky and fails on ngspice-42 / Linux.
199// Please replace it with something that is more stable
200#if 0
201BOOST_AUTO_TEST_CASE( LegacyLaserDriver )
202{
204
205 TestNetlist( "legacy_laser_driver" );
206
207 if( m_abort )
208 return;
209
210 // Test D1 current before the pulse
211 TestTranPoint( 95e-9, { { "I(D1)", 0 } } );
212 // Test D1 current during the pulse
213 TestTranPoint( 110e-9, { { "I(D1)", 0.770 } }, 0.1 );
214 // Test D1 current after the pulse
215 TestTranPoint( 150e-9, { { "I(D1)", 0 } } );
216}
217#endif
218
219
220BOOST_AUTO_TEST_CASE( LegacyPotentiometer )
221{
222 TestNetlist( "legacy_pot" );
223 TestOpPoint( 0.5, "V(/out1)" );
224 TestOpPoint( 0.7, "V(/out2)" );
225 TestOpPoint( 0.9, "V(/out3)" );
226}
227
228
229BOOST_AUTO_TEST_CASE( LegacyPspice )
230{
232 TestNetlist( "legacy_pspice" );
233 TestACPoint( 190, { { "V(/VIN)", pow( 10, -186e-3 / 20 ) },
234 { "V(VOUT)", pow( 10, 87e-3 / 20 ) } } );
235}
236
237
238BOOST_AUTO_TEST_CASE( LegacyRectifier )
239{
241 TestNetlist( "legacy_rectifier" );
242 TestTranPoint( 0, { { "V(/signal_in)", 0 },
243 { "V(/rect_out)", 0 } } );
244 TestTranPoint( 9.75e-3, { { "V(/signal_in)", 1.5 },
245 { "V(/rect_out)", 823e-3 } } );
246}
247
248
249BOOST_AUTO_TEST_CASE( LegacySallenKey )
250{
252 TestNetlist( "legacy_sallen_key" );
253
254 if( m_abort )
255 return;
256
257 TestACPoint( 1, { { "V(/lowpass)", pow( 10, 0.0 / 20 ) } } );
258 TestACPoint( 1e3, { { "V(/lowpass)", pow( 10, -2.9 / 20 ) } } );
259}
260
261
262/*BOOST_AUTO_TEST_CASE( LegacySources )
263{
264 LOCALE_IO dummy;
265 TestNetlist( "legacy_sources", { "V(/vam)", "V(/iam)",
266 "V(/vdc)", "V(/idc)",
267 "V(/vexp)", "V(/iexp)",
268 "V(/vpulse)", "V(/ipulse)",
269 "V(/vpwl)", "V(/ipwl)",
270 "V(/vsffm)", "V(/isffm)",
271 "V(/vsin)", "V(/isin)" } );
272 //"V(/vtrnoise)", "V(/itrnoise)",
273 //"V(/vtrrandom)", "V(/itrrandom)" } );
274}*/
275
276
278{
280 // Amplifier_Operational:AD797 model is used to test symbols that have more pins than the model.
281
282 TestNetlist( "legacy_opamp" );
283 TestTranPoint( 0, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
284 TestTranPoint( 250e-6, { { "V(/in)", 500e-3 }, { "V(/out)", 1 } } );
285 TestTranPoint( 500e-6, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
286 TestTranPoint( 750e-6, { { "V(/in)", -500e-3 }, { "V(/out)", -1 } } );
287 TestTranPoint( 1e-3, { { "V(/in)", 0 }, { "V(/out)", 0 } } );
288}
289
290
291BOOST_AUTO_TEST_SUITE_END()
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
virtual ENV_VAR_MAP & GetLocalEnvVariables() const
Definition: pgm_base.cpp:923
BOOST_AUTO_TEST_CASE(Rectifier)
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
PGM_SINGLE_TOP program
std::vector< FAB_LAYER_COLOR > dummy