Создание стимулов
Часть раздела Основы путешествия по Verilog на Coddy — урок 74 из 90.
Стимул (Stimulus) — это входные значения, которые вы подаете на свою схему, чтобы проверить правильность её работы. Изменяя входные сигналы и наблюдая за выходными, вы можете убедиться, что ваша разработка ведет себя так, как ожидалось.
Представьте, что это похоже на тестирование машины: вы нажимаете разные кнопки (стимулы) и наблюдаете за тем, что происходит (выходные сигналы). Создание качественных стимулов — это важная часть написания тестбенча.
Например, посмотрите на входные сигналы (stimulus) в следующем тестбенче:
module testbench;
reg a, b;
wire c;
and_gate dut (
.a(a),
.b(b),
.c(c)
);
initial begin
// СТИМУЛЫ НАЧИНАЮТСЯ ЗДЕСЬ
// Тестовый случай 1: Оба входа равны 0
a = 0; b = 0; #10;
// Тестовый случай 2: a=0, b=1
a = 0; b = 1; #10;
// Тестовый случай 3: a=1, b=0
a = 1; b = 0; #10;
// Тестовый случай 4: Оба входа равны 1
a = 1; b = 1; #10;
// СТИМУЛЫ ЗАКАНЧИВАЮТСЯ ЗДЕСЬ
$finish;
end
endmoduleКаждое воздействие подается, затем мы ждем 10 единиц времени (#10) перед следующим воздействием. Это дает DUT время для формирования выходного сигнала.
Методы создания стимулов
| Метод | Лучше всего подходит для | Пример |
|---|---|---|
| Последовательные присваивания | Простых тестов | a = 0; b = 0; #10; |
| Цикл for | Тестирования всех комбинаций | for (i = 0; i < 4; i++) |
| Цикл repeat | Повторяющихся шаблонов | repeat (10) #5 clk = ~clk; |
| Цикл forever | Непрерывных сигналов | forever #5 clk = ~clk; |
Метод 1: Последовательные присваивания
Самый простой способ создания стимулов. Вы присваиваете значения одно за другим с задержками.
initial begin
a = 0; b = 0; #10;
a = 0; b = 1; #10;
a = 1; b = 0; #10;
a = 1; b = 1; #10;
$finish;
endМетод 2: Цикл For
Полезно, когда вы хотите протестировать все возможные комбинации входных данных.
integer i;
initial begin
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i;
#10;
end
$finish;
endЭто проверяет: 00, 01, 10, 11.
Способ 3: Цикл Repeat
Полезен для многократного повторения одного и того же воздействия (стимула).
initial begin
a = 0; b = 1;
repeat (10) begin
#10 a = ~a;
end
$finish;
endСпособ 4: Цикл Forever
Полезно для непрерывных сигналов, таких как тактовые сигналы.
initial begin
clk = 0;
forever #5 clk = ~clk;
endВажные правила
| Правило | Объяснение |
|---|---|
| Используйте задержки между назначениями стимулов | #10 дает время DUT для ответа |
Используйте reg для сигналов стимулов | Потому что они меняются со временем |
Добавьте $finish в конце | Чтобы остановить симуляцию |
Задание
Вам дан модуль логического элемента ИЛИ (OR gate). Ваша задача — добавить недостающие входные воздействия (stimulus) и операторы $display для вывода результатов.
Что нужно сделать:
Добавьте входные воздействия для проверки всех четырех комбинаций входных сигналов (00, 01, 10, 11):
- В каждой строке установите значения для
xиy - Добавьте
#10для задержки - Добавьте
$displayдля вывода результата
Оператор <strong>$display</strong> должен выглядеть следующим образом:
$display("%d %d | %d", x, y, z);Шпаргалка
Стимул (Stimulus) — это входные значения, подаваемые на DUT (тестируемое устройство) в тестбенче для проверки корректности его работы.
Методы создания стимулов
Последовательные присваивания — самый простой подход:
initial begin
a = 0; b = 0; #10;
a = 0; b = 1; #10;
$finish;
endЦикл For — проверка всех комбинаций входных данных:
integer i;
initial begin
for (i = 0; i < 4; i = i + 1) begin
{a, b} = i; #10;
end
$finish;
endЦикл Repeat — повторение стимула N раз:
repeat (10) begin
#10 a = ~a;
endЦикл Forever — непрерывные сигналы, такие как тактовые импульсы (clocks):
initial begin
clk = 0;
forever #5 clk = ~clk;
endОсновные правила
- Используйте
regдля сигналов стимулов (они изменяются во времени) - Добавляйте задержки (например,
#10) между присваиваниями, чтобы дать DUT возможность среагировать - Завершайте симуляцию с помощью
$finish
Попробуйте сами
module or_gate (
input x,
input y,
output z
);
assign z = x | y;
endmodule
module testbench;
reg x, y;
wire z;
or_gate dut (
.x(x),
.y(y),
.z(z)
);
initial begin
$display("x y | z");
$display("---------");
// TODO: Добавить входные сигналы и отображение для 0 0
// TODO: Добавить входные сигналы и отображение для 0 1
// TODO: Добавить входные сигналы и отображение для 1 0
// TODO: Добавить входные сигналы и отображение для 1 1
$finish;
end
endmoduleВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
1Введение
Что такое VerilogHardware против SoftwareУровни абстракции проектированияВаш первый модульКомментарии4Операторы. Часть 1
Арифметические операторыОператор остатка от деленияОператоры сравненияПовторение: простая математикаПобитовые операторы7Оператор Assign и логические вентили
Непрерывное присваиваниеAssign с операторамиВстроенные примитивы вентилейВентили AND, OR, NOTВентили XOR, XNORИтоги: Схемы на логических вентилях10Принятие решений
Оператор ifКонструкция if - elseПовторение: простой компараторОператор caseОператоры casex и casezПовторение: проектирование ALU5Операторы. Часть 2
Логические операторыОператоры редукцииОператоры сдвигаОператор конкатенацииУсловный операторПовторение — Испытание по операторам14Основы Testbench
Что такое TestbenchСоздание стимуловDisplay и MonitorDumpfile и DumpvarsИспользование системных задачИтоги: полный Testbench3Системы счисления
Двоичное представлениеЧисла с заданным размеромЧисла без заданного размераОтрицательные числаСпециальные значения X и ZИтоги — форматы чисел6Модули
Структура модуляВходные и выходные портыПорты InoutИнстанцирование модуляПодключение портов по имениПодключение портов по порядкуИтоги: создание модуля9Процедурные блоки
Блок alwaysБлок initialСписок чувствительностиБлокирующее присваиваниеНеблокирующее присваиваниеИтоги: always против initial