Оглавление


§ Icarus: verilog

Как и всегда, я начинаю разговор о создании очередного процессора на Icarus Verilog. Буду рассказывать о той же самой последовательности действий, которые считаю наиболее обычной. Мне нравится связка IVerilog + Gtkwave + Verilator. Если первые два работают как в Linux, так и в Windows, то Verilator почему-то работает только под Linux. Вкратце о том, что делает каждый из программных пакетов:
  • Icarus Verilog — это компилятор, который преобразует файлы v, sv в промежуточные дампы
  • VVP — симулятор полученных дампов, выдает по итогу результат в виде сигналов
  • Gtkwave — графический просмотрщик полученных сигналов
  • Verilator — транслятор Verilog кода в C++ код
С помощью библиотеки SDL1.2 или SDL2 можно сделать окно с видеоадаптером, который позволит с помощью верилятора видеть экран таким, каким бы он был в реальной схеме. Для меня в свое время это было потрясающим открытием, и я до сих пор пользуюсь данным методом. Следует помнить, что это лишь один из методов, а не единственный. Верилятор обладает огромными возможностями к созданию абсолютно любой логической схемы.
Для того чтобы начать тестировать код, необходимо создать два файла, обычно я их называю: 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), и добавить сигналы на схему.
Snimok_ekrana_2024-05-27_11-57-36.png
Справа в виде сигналов будут выведены только тактовые генераторы на 100 и 25 мгц, и также регистр reset_n, который необходим для сброса процессора и других модулей.