В прошлой статье мы рассмотрели азы составления SPICE-моделей электронных схем на совсем тривиальном примере. В этой статье постараемся углубить наши знания, изучив более сложные приемы анализа схем в симуляторе Ngspice.
1. Анализ схем на постоянном токе. Параметризация схемы
Закрепляя материал предыдущей статьи, построим более сложную схему, например такую

Для расчета токов в такой схеме придется уже изрядно попотеть, например составив и решив систему уравнений, например с применением законов Кирхгофа. Система уравнений будет состоять из трех узловых уравнений и трех контурных
Решая которую, или в ручную, или применяя любой математический пакет, можно получить значения токов во всех ветвях
Теперь отдадим эту схему на съедение Ngspice, благо она уже к этому подготовлена, введением дополнительных узлов, предусматривающих включение в ветви нулевых источников-измерителей. Составим netlist
.title Test DC scheme
V1 1 0 DC 100
Vmeas1 1 2 0
R1 2 3 10
Vmeas2 3 4 0
R2 4 5 20
R3 3 6 30
Vmeas3 6 7 0
R4 5 8 40
Vmeas4 8 7 0
Vmeas5 7 9 0
R5 9 10 50
R6 12 11 60
Vmeas6 11 10 0
R7 5 12 70
R8 10 0 80
.op
.end
Выполним проверку схемы (listing), её расчет (run), выведем значения токов ветвях, воспользовавшись заботливо расставленными пробниками
ngspice 2 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
Reference value : 0.00000e+00
No. of Data Rows : 1
ngspice 3 -> print i(Vmeas1) i(Vmeas2) i(Vmeas3) i(Vmeas4) i(Vmeas5) i(Vmeas6)
i(vmeas1) = 7.134457e-01
i(vmeas2) = 3.371227e-01
i(vmeas3) = 3.763230e-01
i(vmeas4) = 1.136809e-01
i(vmeas5) = 4.900039e-01
i(vmeas6) = 2.234418e-01
ngspice 4 ->
Как видим, результат аналогичен тому, что получен путем расчета по уравнениям Кирхгофа.
Какую еще информацию мы можем получить. Например, мы можем вывести величину потенциалов в узлах схемы, воспользовавшись конструкцией v(имя узла), например так
ngspice 5 -> print v(3) v(5) v(7) v(10)
v(3) = 9.286554e+01
v(5) = 8.612309e+01
v(7) = 8.157585e+01
v(10) = 5.707566e+01
ngspice 6 ->
Это потенциалы узлов 3, 5, 7 и 10 относительно выбранного нами нулевого узла. А можем ли мы получить падения напряжения на резисторах схемы? Легко, помня о том, что напряжение есть разность потенциалов, например для резистора R3 это будет выглядеть так
ngspice 6 -> print v(3) - v(6)
v(3) - v(6) = 1.128969e+01
ngspice 7 ->
то есть для вывода результатов мы можем применять математические выражения, что немаловажно для нас в дальнейшем. Нетрудно проверить и закон Ома, например для резистора R4
ngspice 7 -> print (v(5) - v(8))/40
(v(5) - v(8))/40 = 1.136809e-01
ngspice 8 ->
получаем то же значение тока, что выводили ранее. Воспользовавшись возможностью применения арифметических операций, мы можем определить, например, эквивалентное сопротивление данной схемы
ngspice 8 -> print v(1) / i(Vmeas1)
v(1) / i(vmeas1) = 1.401648e+02
ngspice 9 ->
Важным аспектом организации SPICE-моделей является так называемая параметризация. Вместо использования конкретных числовых значений, мы можем ввести переменные, хранящие данные значения, и связать параметры между собой, используя арифметические операции. Ввод параметров выполняется с помощью директивы .param. Например так
.title Test DC scheme
.param R1=10 R2=20 R3=30 R4=40 R5=50 R6=60 R7=70 R8=80
V1 1 0 DC 100
Vmeas1 1 2 0
R1 2 3 {R1}
Vmeas2 3 4 0
R2 4 5 {R2}
R3 3 6 {R3}
Vmeas3 6 7 0
R4 5 8 {R4}
Vmeas4 8 7 0
Vmeas5 7 9 0
R5 9 10 {R5}
R6 12 11 {R6}
Vmeas6 11 10 0
R7 5 12 {R7}
R8 10 0 {R8}
.op
.end
Значения параметров подставляются в описание элементов схемы в фигурных скобках. Мы получим тот же результат
ngspice 3 -> print i(Vmeas1) i(Vmeas2) i(Vmeas3) i(Vmeas4) i(Vmeas5) i(Vmeas6)
i(vmeas1) = 7.134457e-01
i(vmeas2) = 3.371227e-01
i(vmeas3) = 3.763230e-01
i(vmeas4) = 1.136809e-01
i(vmeas5) = 4.900039e-01
i(vmeas6) = 2.234418e-01
ngspice 4 ->
Теперь мы можем использовать параметр вместо повторяющегося значения, задав его однажды, а так же связать параметры между собой, например сделать так чтобы сопротивление R2 всегда было в 2 раза больше сопротивления R1
.param R1=10 R2=2*R1 R3=30 R4=40 R5=50 R6=60 R7=70 R8=80
записав значение R2 в форме выражения. Выражения можно использовать и внутри фигурных скобок в описании элементов
R3 3 6 {3*R1}
Параметризация схемы открывает широкие возможности, и создание сложных SPICE-моделей без параметризации невозможно.
Побаловавшись с постоянным током и твердо освоив .op-анализ, перейдем к другим аспектам SPICE-моделирования.
2. Анализ переходных процессов в цепях постоянного тока
Рассмотрим такую схему

Попробуем смоделировать переходный процесс в этой цепи, полагая что в начальный момент времени ток в ней не тек. Результат, конечно же, очевиден - ток будет нарастать экспоненциально, с постоянной времени T = L / R = 10 мс, и ассимптотически приближаться к значению E / R = 5 А. Заставим Ngspice показать нам данный переходный процесс на графике.
Построим модель следующим образом
*
* Переходный процесс в LR-цепи
*
.title LR-circuit demo
*
* Параметры модели
*
.param E=100 L=200m R=20
*
* Структурное описание схемы
*
V1 in 0 DC {E}
L1 in out {L}
Vmeas out 1 0
R1 1 0 {R}
*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 50m uic
.end
Кстати, обратим внимание на то, что некоторые узлы схемы заданы не номерами, а символическими именами. Это допускается синтаксисом, и может служить удобным способом обозначать важные узлы схемы. Узел 1 добавлен для врезки в цепь измерителя тока Vmeas.
Новой здесь является директива .tran, задающая анализ переходного процесса (Transient Analysis). Полный её синтаксис выглядит так
.tran tstep tstop <tstart <tmax>> <uic>
где
tstep - шаг интегрирования
tstop - конечное время интегрирования
tstart - начальное время интегрирования
tmax - максимальный шаг интегрирования. Если он не задан, симулятор принимает его равным (tstop - tstart) / 50
uic - признак того, что выполняется анализ переходного процесса, с начальными условиями, по умолчанию - нулевыми
Параметры, указанные в треугольных скобках могут быть опущены.
Данная директива предписывает симулятору составить и решить систему дифференциальных уравнений относительно потенциалов в узлах схемы. Испробуем это, однако теперь нам потребуется построить график, поэтому запускаем графический вариант Ngspice
D:\work\Projects\ngspice>ngspice LR-scheme.cir
и мы увидим вот такое окно

внизу которого есть поле для ввода команд. Запускаем симуляцию
Circuit: LR-circuit demo
ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
Operating point simulation skipped by 'uic',
now using transient initial conditions.
No. of Data Rows : 5011
ngspice 2 ->
Нам сообщают, что проведен анализ при температуре 27 градусов Цельсия, тип использованного решателя ОДУ, указывается на то, что расчет рабочей точки по постоянному току пропущен, благодаря указанию параметра uic и используются начальные условия. Так как начальных условий мы не задали, они полагаются нулевыми. Далее выводится число точек (во времени) для которых произведен расчет по всем узлам схемы - 5011. Как получить график? Даем команду
ngspice 2 -> plot i(Vmeas)
ngspice 3 ->
и возникает графическое окно с графиком зависимости тока в цепи от времени.

Мы задали время моделирования 50 мс, равное пяти постоянным времени данной цепи и выполнили интегрирование с шагом 10 мкс, это заложено в настройки анализа
.tran 10u 50m uic
Обратим внимание на то, что допускается применение десятичных приставок: m означает "мили", u - "микро". Подробный список десятичных приставок можно увидеть в документации в Ngspice, не будем подробно останавливаться на этом.
Если требуется получить таблицу данных, даем команду
ngspice 3 -> print i(Vmeas) > results.txt
ngspice 4 ->
Получая файл results.txt следующего содержания (фрагмент)
LR-circuit demo
Transient Analysis Mon Sep 22 16:04:01 2025
--------------------------------------------------------------------------------
Index time i(Vmeas)
--------------------------------------------------------------------------------
0 1.000000e-07 2.000030e+00
1 2.000000e-07 2.000060e+00
2 4.000000e-07 2.000120e+00
3 8.000000e-07 2.000240e+00
4 1.600000e-06 2.000480e+00
5 3.200000e-06 2.000960e+00
6 6.400000e-06 2.001919e+00
7 1.000000e-05 2.002999e+00
8 1.064000e-05 2.003190e+00
9 1.192000e-05 2.003574e+00
10 1.448000e-05 2.004341e+00
11 1.960000e-05 2.005874e+00
12 2.960000e-05 2.008867e+00
13 3.960000e-05 2.011857e+00
14 4.960000e-05 2.014843e+00
15 5.960000e-05 2.017827e+00
16 6.960000e-05 2.020808e+00
17 7.960000e-05 2.023785e+00
18 8.960000e-05 2.026760e+00
19 9.960000e-05 2.029732e+00
20 1.096000e-04 2.032700e+00
21 1.196000e-04 2.035666e+00
22 1.296000e-04 2.038629e+00
23 1.396000e-04 2.041589e+00
24 1.496000e-04 2.044546e+00
25 1.596000e-04 2.047500e+00
26 1.696000e-04 2.050451e+00
27 1.796000e-04 2.053399e+00
28 1.896000e-04 2.056344e+00
29 1.996000e-04 2.059286e+00
который затем можно использовать для обработки результатов расчета сторонними средствами.
А что если нам нужны ненулевые начальные условия? Их можно задать для всех реактивных элементов схемы, написав например следующее
L1 in out {L} ic=2.0
В описании индуктивности это означает начальную величину тока, протекающего в ней. Получаем следующий результат

Как видим, нарастание тока в цепи начинается с 2 ампер. Аналогично можно проиллюстрировать затухание тока. Для этого зададим его начальное значение, а источник либо уберем из схемы, либо обнулим его напряжение
*
* Переходный процесс в LR-цепи
*
.title LR-circuit demo
*
* Параметры модели
*
.param E=0 L=200m R=20
*
* Структурное описание схемы
*
V1 in 0 DC {E}
L1 in out {L} ic=10.0
Vmeas out 1 0
R1 1 0 {R}
*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 50m uic
.print v(out)
.end

Как видно, описание индуктивности начинается с литеры "L" и похоже на описание резистора. Конечно, как и у резистора, параметров намного больше, но нет смысла останавливаться на этом, я позволю себя отослать читателя к документации.
Аналогично можно выполнить анализ переходных процессов с емкостью. Следующая модель иллюстрирует процесс заряда конденсатора

*
* Переходный процесс в LR-цепи
*
.title RC-circuit demo
*
* Параметры модели
*
.param E=100 C=1000u R=20
*
* Структурное описание схемы
*
V1 in 0 DC {E}
R1 in out {R}
Vmeas out 1 0
C1 1 0 {C}
*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 100m uic
.end
Circuit: RC-circuit demo
ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
Operating point simulation skipped by 'uic',
now using transient initial conditions.
No. of Data Rows : 10011
ngspice 2 -> plot v(out) i(Vmeas)
ngspice 3 ->

или его разряд, при задании напряжения источника равным нулю, а начально напряжения конденсатора через начальные условия симуляции
C1 1 0 {C} ic=200

Как видим, не смотря на очевидную низкоуровневость, в данном случае всё довольно просто, и легко распространяется на более сложные цепи.
3. Анализ цепей на переменном токе. Построение частотных характеристик
Не составит труда подать синусоидальное переменное напряжение на ту же цепь с катушкой и резистором.

Для этого предусмотрен специальный тип источника напряжения
*
* Переходный процесс в LR-цепи
* при синосоидальном входном напряжении
*
.title LR-circuit demo
*
* Параметры модели
*
.param Um=100 L=200m R=20 f=50
*
* Структурное описание схемы
*
V1 in 0 sin(0 {Um} {f})
L1 in out {L}
Vmeas out 1 0
R1 1 0 {R}
*
* Вид моделирования - анализ переходного процесса
* (Transient Analysis)
*
.tran 10u 100m
.end
Инструкцией в строке 15 мы задаем источник синусоидального напряжения с постоянной составляющей равной 0, амплитудой E=100 В и частотой f = 50 Гц. И получить графики напряжения на входе и выходе схемы

Однако, рассмотрение этого процесса во временной области малоинтересно. Гораздо больший интерес представляет собой реакция схемы на подачу напряжения произвольной частоты. Такую информацию дают нам амплитудные (АЧХ) и фазовые (ФЧХ) частотные характеристики. Ngspice предоставляет инструменты для их построения. Для этого составим такую модель
*
* Построение АЧХ и ФЧХ для LR-цепи
*
.title LR AC-analysis
*
* Параметры модели
*
.param L=200m R=20
*
* Структурное описание схемы
*
V1 in 0 dc 0 ac 1
L1 in out {L}
Vmeas out 1 0
R1 1 0 {R}
*
* Вид моделирования - анализ на переменном токе
*
.ac lin 1000 0.01 1k
.end
Обратите внимание на описание источника
V1 in 0 dc 0 ac 1
Указывается имя источника, узлы его подключения, уточняется что отсутствует постоянная составляющая (dc 0) и указывается амплитуда переменной составляющей (ac 1) равная 1 В. При этом полагается что напряжение является синусоидальным переменной частоты, которая задается в режиме моделирования
.ac lin 1000 0.01 1k
Здесь указывается что следует выполнить малосигнальный анализ схемы на переменном токе (.ac) с линейным отображением амплитуды (lin). Далее указывается количество точек на графике (1000) и диапазон частот, данном случае от 0.01 до 1000 Гц. Загрузив модель и выполнив симуляцию, мы можем построить АЧХ и ФЧХ, за что отвечает команда в 7 строке
ngspice 1 -> run
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
No. of Data Rows : 1000
ngspice 2 -> plot v(out) phase(v(out))
ngspice 3 ->

Такой график выглядит не сильно презентабельно, так как АЧХ и ФЧХ лучше изображать в логарифмическом масштабе по оси частот. Это легко сделать, указав это требование в команде построения графиков параметром xlog (логарифмический масштаб по оси абсцисс)
ngspice 3 -> plot v(out) phase(v(out)) xlog
ngspice 4 ->

получая вполне узнаваемые кривые.
Заключение и выводы
Мы довольно бегло пробежались по основным возможностям симулятора Ngspice. Использовать его напрямую можно, но всё же не совсем удобно. Лучше, всё же применять его в качестве бэкэнда в составе более дружественных к пользователю симуляторов, например Qucs-S. Целью всего этого повествования является освоение базового синтаксиса Ngspice. Я умышленно упустил описание анализа схем на постоянном токе с построением разверток (DC Transfer Function), задаваемый директивой .dc. Более наглядно его применение выглядит при исследовании характеристик полупроводниковых приборов. А к полупроводниковым прибором мы закономерно придем уже в следующей статье. Так что благодарю читателей за внимание и до новых встреч!
engine9
Спасибо за методический материал, тема очень интересная.