Оглавление
§ Icarus: verilog
Как и всегда, я начинаю разговор о создании очередного процессора на Icarus Verilog. Буду рассказывать о той же самой последовательности действий, которые считаю наиболее обычной. Мне нравится связка IVerilog + Gtkwave + Verilator. Если первые два работают как в Linux, так и в Windows, то Verilator почему-то работает только под Linux. Вкратце о том, что делает каждый из программных пакетов:- Icarus Verilog — это компилятор, который преобразует файлы v, sv в промежуточные дампы
- VVP — симулятор полученных дампов, выдает по итогу результат в виде сигналов
- Gtkwave — графический просмотрщик полученных сигналов
- Verilator — транслятор Verilog кода в C++ код
Для того чтобы начать тестировать код, необходимо создать два файла, обычно я их называю:
makefile
и tb.v
. В первом файле записываются правила сборки, чтобы не писать каждый раз руками одно и то же, а во втором тестовый код. Начну пока что рассказ с tb.v
:1`timescale 10ns / 1ns 2module tb; 3// --------------------------------------------------------------------- 4reg reset_n = 0, clock_100 = 0, clock_25 = 0; 5// --------------------------------------------------------------------- 6always #0.5 clock_100 = ~clock_100; // Генератор частоты 100 мгц 7always #2.0 clock_25 = ~clock_25; // И 25 мгц 8// --------------------------------------------------------------------- 9initial begin $dumpfile("tb.vcd"); $dumpvars(0, tb); end 10initial begin #2.5 reset_n = 1; #2000 $finish; end 11// --------------------------------------------------------------------- 12endmoduleРазберу почти каждую строку кода. Начну с первой:
timescale 10ns / 1ns
. В ней указывается метрика. Первое значение 10ns — это условное обозначение единицы этой метрики, то есть, если мы где-то в файле указываем #1
, то это будет считаться продолжительностью 10 нс. Второй же параметр означает минимальный синтезируемый отрезок времени, то есть, всего лишь 1 нс. Это точно также как если бы 1 миллиметр относился к 1 см, в отношении 1/10.Далее у нас идут 3 регистра: reset_n — симуляция нажатия кнопки сброса, вначале он становится 0, а через непродолжительное время 1, а также тактовые генераторы 100 и 25 мгц.
В общем блоке
initial ... end
объявляются некоторые заранее известные значения, при этом, растянутые во времени. При самом начальном этапе, устанавливаются стартовые значения $dumpfile и $dumpvars, которые указывают компилятору, в какие файлы требуется выгружать результат, и откуда.Спустя #2.5 единиц времени, что равняется 2.5 x 10ns = 25 ns, устанавливается значение
reset_n = 1
. Спустя #2000 единиц времени, а именно 20 микросекунд, симуляция проекта завершается с помощью директивы $finish.На этом самый первый тестовый файл завершен. Теперь осталось только скомпилировать его, и выполнить.
§ Сборка проекта
Поскольку я пользуюсь Linux, то мне привычнее использовать файл makefile вместо bat-файлов. На Windows также можно установить поддержку makefile, для этого необходимо скачать определенное ПО, именуемое GNU Make.1all: ica 2ica: 3 iverilog -g2005-sv -DICARUS=1 -o tb.qqq tb.v 4 vvp tb.qqq >> /dev/null 5 rm tb.qqq 6vcd: 7 gtkwave tb.vcd 8wave: 9 gtkwave tb.gtkw 10clean: 11 rm -rf obj_dir tb tb.vcd tb.gtkwЗдесь, при запуске
make
, выбирается правило сборки ica
, которое запускает компиляцию iverilog
.- Опция
-g2005-sv
задает поддержку возможности System Verilog; -
-DICARUS=1
передает объявление ICARUS, равное 1, для того, чтобы программы на верилоге могли проверить, с какого окружения запускаются; -
-o tb.qqq
параметр указывает, куда будет экспортированы результаты -
tb.v
является исходным файлом
vvp
, который переводит транслированное значение tb.qqq
в другое представление, например, в tb.vcd (это зависит только от того, есть ли $dumpfile). Файл tb.qqq
удаляется за ненадобностью.§ Запуск отладчика сигналов Gtkwave
Для его запуска достаточно набрать либоgtkwave tb.vcd
, либо воспользоваться make vcd
командой. Откроется пустое окно, где потребуется выбрать слева модуль (в данном случае это tb), и добавить сигналы на схему.Справа в виде сигналов будут выведены только тактовые генераторы на 100 и 25 мгц, и также регистр reset_n, который необходим для сброса процессора и других модулей.