Применение Icarus Verilog для тестирования с входными данными

Содержание

Существует множество способов, с помощью которых программа на языке Verilog может получать данные из внешнего окружения во время выполнения. Аргументы можно вводить в командной строке, а большие объемы данных можно считывать из файлов. Самый простой метод — принимать аргументы из командной строки.

Рассмотрим пример работы калькулятора квадратного корня
module sqrt32(clk, rdy, reset, x, .y(acc)); input clk; output rdy; input reset; input [31:0] x; output [15:0] acc; reg [15:0] acc; reg [31:0] acc2; reg [4:0] bitl; wire [15:0] bit = 1 << bitl; wire [31:0] bit2 = 1 << (bitl << 1); wire rdy = bitl[4]; wire [15:0] guess = acc | bit; wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1); task clear; begin acc = 0; acc2 = 0; bitl = 15; end endtask initial clear; always @(reset or posedge clk) if (reset) clear; else begin if (guess2 <= x) begin acc <= guess; acc2 <= guess2; end bitl <= bitl - 1; end endmodule

Можно написать программы, которая передает устройству набор входных данных и проверяет результат на выходе. Однако мы также можем написать программу, которая принимает в командной строке целочисленное значение, используемое в качестве входного сигнала для устройства. Мы можем написать и скомпилировать эту программу, а затем передавать различные входные значения в командной строке во время выполнения без перекомпиляции моделирования.

Этот пример демонстрирует использование «$value$plusargs» для доступа к аргументам командной строки симуляции
module main; reg clk, reset; reg [31:0] x; wire [15:0] y; wire rdy; sqrt32 dut (clk, rdy, reset, x, y); always #10 clk = ~clk; initial begin clk = 0; reset = 1; if (! $value$plusargs("x=%d", x)) begin $display("ERROR: please specify +x=<value> to start."); $finish; end #35 reset = 0; wait (rdy) $display("y=%d", y); $finish; end // initial begin endmodule // main
Системная функция «$value$plusargs» принимает строковый шаблон, описывающий формат аргумента командной строки, и ссылку на переменную, которая принимает это значение. Программа «sqrt_plusargs» может быть скомпилирована и выполнена следующим образом:
> iverilog –o sqrt_plusargs.vvp sqrt_plusargs.v sqrt.v > vvp sqrt_plusargs.vvp +x=81 y=9

Все аргументы после имени файла симуляции являются расширенными аргументами команды «vvp» и передаются в выполняемый проект. Расширенные аргументы, начинающиеся с символа «+», доступны через системные функции «$test$plusargs» и «$value$plusargs».

Другой метод заключается в том, чтобы поместить набор входных значений в файл данных и написать программу для чтения этого файла. Затем мы можем отредактировать файл, добавив новые входные значения, и повторно запустить моделирование, не компилируя его снова. Преимущество этой техники заключается в том, что мы можем накопить большой набор входных значений теста и запустить его в пакетном режиме.

Этот пример
module main; reg clk, reset; reg [31:0] data[4:0]; reg [31:0] x; wire [15:0] y; wire rdy; sqrt32 dut (clk, rdy, reset, x, y); always #10 clk = ~clk; integer i; initial begin /* Load the data set from the hex file. */ $readmemh("sqrt.hex", data); for (i = 0 ; i <= 4 ; i = i + 1) begin clk = 0; reset = 1; x = data[i]; #35 reset = 0; wait (rdy) $display("y=%d", y); end $finish; end // initial begin endmodule // main
демонстрирует использование функции «$readmemh» для чтения образцов данных из файла в массив Verilog. Начнем с того, что поместим в файл «sqrt.hex» числа:
51 19 1a 18 1
Затем запустите моделирование с помощью последовательности команд:
> iverilog -o sqrt_readmem.vvp sqrt_readmem.vl sqrt.vl > vvp sqrt_readmem.vvp y=9 y=5 y=5 y=4 y=1

Эту программу достаточно легко изменить для работы с большими наборами данных или изменить файл «data.hex», чтобы он содержал другие данные. Эта техника также широко используется для моделирования алгоритмов, которые используют большие наборы данных.