Симуляция verilog кода с помощью Icarus-Verilog

При сколь-нибудь сложном проектировании с использованием verilog возникает необходимость симуляции, для проверки корректности работы блока схемы. Для простых случаев, раньше можно было воспользоватся встроенным в Quartus симулятором. Но он уже давно выпилен из Quartus IDE. Взамен нам предлагают использовать ModelSim. Проблема в том, что он бесплатный только для простых проектов. И еще одна проблема - его интерфейс слишком перегружен. И еще одна - сложность установки в linux.

К счастью существует open source альтернатива, в виде Icarus-Verilog, которая лишена вышеперечисленных недостатков.

Для windows, перейти по ссылке http://bleyer.org/icarus/, скачать дистрибутив, установить.

Для linux. Программа включена в стандартный ubuntu репозиторий.

sudo apt-get install iverilog gtkwave

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

module counter (
    input wire reset,
    input wire clk,
    output reg out_clk
);

reg[15:0] counter; 

always @ (posedge clk or posedge reset)
begin
    if (reset)
    begin
        out_clk <= 0;
        counter <= 0;
    end
    else
    begin
        counter <= counter + 1;
        if(counter == 16'd10)
        begin
            counter <= 16'd0;
            out_clk <= ~out_clk;    
        end
    end 
end
endmodule

Важное замечание. На данный момент, icarus-verilog умеет симулировать только схемы, у которых определены начальные значения всех регистров, обычно путем сигнала reset.

Теперь нам нужен модуль тестирования. Вот он:

module test_counter;

reg reset, clk;
wire data_cnt;

//устанавливаем экземпляр тестируемого модуля
counter counter_inst(reset, clk, data_cnt);

//моделируем сигнал тактовой частоты
always
    #10 clk = ~clk;

//от начала времени...
initial
begin
    clk = 0;
    reset = 0;

    //через временной интервал "50" подаем сигнал сброса
    #50 reset = 1;

    //еще через время "4" снимаем сигнал сброса
    #4 reset = 0;

    //пауза длительностью "50"
    #50;
end

//заканчиваем симуляцию в момент времени "400"
initial
begin
    #400 $finish;
end

//создаем файл VCD для последующего анализа сигналов
initial
begin
    $dumpfile("out.vcd");
    $dumpvars(0,test_counter);
end

//наблюдаем на некоторыми сигналами системы
initial
    $monitor($stime,, clk,,, data_cnt); 

endmodule

Для получения временных диаграмм нужна следующая последовательность команд:

iverilog -o qqq counter.v tcounter.v
vvp qqq

Собственно теперь мы можем увидеть вывод работы симулятора в консоль. Для более наглядного представления в графическом виде, можно использовать программу gtkwave. Набираем в командной строке:

gtkwave out.vcd

Появится окно, в котором слева есть окошко со списком сигналов проекта. Нужно выбрать необходимые сигналы и добавить их в график с помощью кнопки "Append".

gtkwave verilog icarus