# Руководство по установке и эксплуатации симулятора Verilog - Icarus Verilog
<div style="text-align: justify ">
Icarus Verilog — компилятор языка описания аппаратуры Verilog, который можно использовать для верификации цифровых схем. Поддерживает версии 1995, 2001 и 2005, частично SystemVerilog и некоторые расширения. Компилятор доступен для всех основных операционных систем (Windows, Linux, Mac Os). Для работы с программой необходимо следовать нижеприведенным шагам:
</div>
### 1. Установка Icarus Verilog
1. Установка программы для ОС Arch Linux осуществляется следующей инструкцией
```bash
pamac install iverilog
```
2. После установки убедитесь в корректности, запросив текущую версию программы
``` bash
iverilog --version
```
3. Удаление производится следующей инструкцией
``` bash
pamac remove iverilog
```
### 2. Эксплуатация программы для симуляции
<div style="text-align: justify">
Для симуляции проекта при помощи Icarus Verilog необходимо создать два файла Verilog/SystemVerilog - тестируемый модуль и тестбенч.
</br>
Далее работа с инструментом будет рассмотрена на примере симуляции алгоритма WAKE.
</div>
1. Создайте verilog-файл wake.sv и сохраните его в отдельной директории
``` verilog
module wake(
input [31:0] idata,
input [127:0] key,
input clk,
input rst,
input valid,
output reg [31:0] odata
);
reg [127:0] t_key;
reg [31:0] t_data;
reg [255:0][31:0] S = {
32'h22af2841, 32'hd997bc35, 32'hb9a2f21d, 32'h07bc41ac,
32'h1e7a46a1, 32'h88dae03e, 32'h0a99f9c0, 32'h1d2ad35e,
32'h91a04200, 32'hedcd1001, 32'he8154938, 32'h008c9f65, 32'h62d669f6, 32'hc575ef12, 32'hb35d40ea, 32'h9cf36ca1, 32'ha22807b5, 32'hddb0c54a, 32'h96cb1be3,
32'h358c806e, 32'hf5e6a8d6, 32'ha11fb4a7, 32'h70156f55,
32'hbb5a98e2, 32'hc67a7c60, 32'h623a3f68, 32'hf7263eb7,
32'hc872a0f5, 32'h41951553, 32'hbcbb5b90, 32'h3c0fe333,
32'h3d0de2e5, 32'h52986017, 32'he760ed2b, 32'h7fbe69f2,
32'h236f5ae2, 32'hb51e2e4b, 32'h00d10dc0, 32'h00c5980c,
32'ha72dd687, 32'hf1b2cb69, 32'hd614545f, 32'h1c87c480,
32'h391f72ca, 32'hd411c236, 32'h0b68a297, 32'h8d80611d,
32'hde51cb88, 32'h513dc9e4, 32'he329f09d, 32'h59133c31,
32'h22a5a386, 32'h3dc76ec0, 32'h8fe48a05, 32'h3e2236a4,
32'h810f6e77, 32'h2d78e48f, 32'h0fa981c8, 32'h6f2e1eaf,
32'h9b119f2a, 32'h74209d6b, 32'hbf7ccad2, 32'h8bfabd4f,
32'h186f5b1e, 32'hbd85c83b, 32'ha80c0433, 32'h3b471df3,
32'h506e6a1a, 32'h72a22815, 32'h5a364922, 32'hfe036378,
32'hf606633b, 32'h17a6802a, 32'h927ee3e2, 32'h6612921a,
32'h548fed07, 32'h0846b6f7, 32'h13f712a5, 32'h5b2f808e,
32'he7a14859, 32'h4849cfb1, 32'h2810aaf2, 32'h8f5199c2,
32'h89c8a372, 32'h913415b1, 32'hfc2efacf, 32'h34469b6e,
32'hd5a437a3, 32'ha2f3c289, 32'h7ba139c1, 32'hbe745df3,
32'h7b8b78f7, 32'hdf868138, 32'h4515a406, 32'h5b1890d8,
32'h89c63463, 32'h73019616, 32'hcf16f211, 32'h52ba4923,
32'hee0e1d8d, 32'hfebe1f2a, 32'hdc54cc32, 32'h508c70b6,
32'hec91234d, 32'h09c51cf4, 32'h03379098, 32'h0411e536,
32'h97573a1d, 32'h5c8fe13e, 32'haba31398, 32'hcade78ee,
32'h9c587594, 32'hb5a700fd, 32'hcd5d846b, 32'hc45760f7,
32'h7a24ddd3, 32'h498ec21e, 32'hec4fc6dd, 32'hf3804e5c,
32'hc7597718, 32'hd499ebbd, 32'h88835d0e, 32'h9987cff1,
32'h6c1d2001, 32'h8bbc3e50, 32'h41af417b, 32'hbee494e1,
32'h9cac75a9, 32'hef6f26db, 32'hddcb0532, 32'hc7fbf08,
32'h985bd7a, 32'haf1ccd4c, 32'h5603e237, 32'h9ecf434c,
32'hfa008a08, 32'hd41905ed, 32'ha562e923, 32'he1230d84,
32'h2b9cc546, 32'h4dcce999, 32'h77ac1249, 32'hef3b13df,
32'h4aa4358d, 32'h0095d104, 32'h5f5fa35c, 32'h83ba549f,
32'hc012d8b3, 32'h5f331cf0, 32'ha1efb983, 32'hf45eb42b,
32'h9998821d, 32'h83534316, 32'hb66d057d, 32'h3573ca61,
32'hca8b455f, 32'hd7bb6945, 32'h6e56e40f, 32'hdc6813cb,
32'h326ccc38, 32'h2ecc636f, 32'hbb7b54c2, 32'h3bb40d26,
32'h0437fa35, 32'h95917e33, 32'hba74aaa8, 32'ha49597d,
32'h7b6ffc92, 32'h4424c40e, 32'h12327843, 32'hbd3ae5ae,
32'h34619aa4, 32'h18a4651e, 32'hc641ee7d, 32'hd789df3b,
32'h147f7249, 32'h02085091, 32'habb14e20, 32'h2fae7c28,
32'h9f775fbf, 32'h5d63afc3, 32'h82d0d3c9, 32'hda0e49a3,
32'h207faacc, 32'hbd855fc7, 32'h2457d29e, 32'h083cbac1,
32'hf3afb1cd, 32'h9c5b3cf0, 32'hc4181af0, 32'ha8f863d4,
32'h1b3ea4c2, 32'h5c731f84, 32'hb4f47549, 32'h67221f2d,
32'h0ce37058, 32'h6d2fac28, 32'h249a4813, 32'he47efaaf,
32'h6b9f2ca7, 32'h1f29b510, 32'h411c284e, 32'hec4d257c,
32'h3ca5e54c, 32'hd8db65b7, 32'h1b2a0ed9, 32'h9bff91e0,
32'hcfa0d100, 32'h4e10cb6e, 32'he51e21fc, 32'h13af4066,
32'hbde364a8, 32'ha4557ac4, 32'h3302be4d, 32'haaf1cebc,
32'h640ac738, 32'h94ce5c0d, 32'hc47d15f8, 32'h82f704ed,
32'h6fe950ac, 32'h52ba6e8e, 32'h60db0824, 32'hdbaeabf1,
32'hafe3cc29, 32'h87687894, 32'hb1f3a94f, 32'h1ab10eb3,
32'hf41ef3ca, 32'haac5df3a, 32'hd1a11d28, 32'hdaff0dd2,
32'h00d1aa57, 32'h69cd597d, 32'h510382f7, 32'h99e155fc,
32'h6c90af05, 32'h3b9909a9, 32'hb6a6cb68, 32'h990c97ca,
32'hc4d259a8, 32'h5b1d54bb, 32'hf94a3e44, 32'h6c2301cd,
32'h7069f0fb, 32'ha1c7f2d9, 32'h7e7e3cf4, 32'haf49dd7d,
32'h54cc33d3, 32'h2a915e42, 32'h8124fbca, 32'h957b58bd,
32'hb4f2806c, 32'h23ea92ec, 32'hfcddfd2, 32'hb058e1fc,
32'h6b6ec507
};
reg [1:0][31:0] R3;
reg [1:0][31:0] R4;
reg [1:0][31:0] R5;
reg [1:0][31:0] R6;
always @(posedge clk or negedge rst) begin
if (!rst) begin
t_key <= 1'b0;
t_data <= 1'b0;
end
else if (valid) begin
t_key <= key;
t_data <= idata;
end
end
always @(t_key or t_data) begin
R3[0] = t_key[127:96];
R4[0] = t_key[95:64];
R5[0] = t_key[63:32];
R6[0] = t_key[31:0];
R3[1] = ((R3[0] + R6[0]) >> 8) ^ S[(R3[0] + R6[0]) & 255];
R4[1] = ((R4[0] + R3[1]) >> 8) ^ S[(R4[0] + R3[1]) & 255];
R5[1] = ((R5[0] + R4[1]) >> 8) ^ S[(R5[0] + R4[1]) & 255];
R6[1] = ((R6[0] + R5[1]) >> 8) ^ S[(R6[0] + R5[1]) & 255];
odata <= t_data ^ R6[1];
end
endmodule
```
2. Создайте файл тестбенча - tb_wake.sv
``` verilog
`include "wake.sv"
`timescale 1ps/1ps
module wake_tb();
reg [31:0] idata;
reg [127:0] key;
reg clk = 1'b1;
reg rst = 1'b1;
reg valid;
reg [31:0] odata;
always
#5 clk = ~clk;
wake uut(
.idata(idata),
.key(key),
.clk(clk),
.rst(rst),
.valid(valid),
.odata(odata)
);
initial begin
rst = 1'b1;
valid = 1'b1;
idata = 32'h00000000;
key = 128'h6C656769746F73696E61726875736E69;
#100
$display("input data = %h", idata, ", key = %h", key, ", output data = %h", odata);
idata = 32'he7718c8b;
key = 128'h6C656769746F73696E61726875736E69;
#100
$display("input data = %h", idata, ", key = %h", key, ", output data = %h", odata);
idata = 32'h11111111;
key = 128'h11111111111111111111111111111111;
#100
$display("input data = %h", idata, ", key = %h", key, ", output data = %h", odata);
idata = 32'hbe58b378;
key = 128'h11111111111111111111111111111111;
#100
$display("input data = %h", idata, ", key = %h", key, ", output data = %h", odata);
$finish;
end
initial
begin
$dumpfile("out.vcd");
$dumpvars(0,tb_wake);
end
endmodule
```
<div style="text-align: justify">
Данный тестбенч устанавливает начальные значения входных сигналов и позволяет симулировать работу алгоритма для 4-х пар входных сигналов (idata, key), проверяя корректность зашифрования и расшифрования. Так же создается файл .vcd, в который записывается dump симуляции для дальнейшего просмотра waveform.
</div>
3. Скомпилируйте проект в файл .vvp следующей инструкцией
``` bash
iverilog -Wall -g2012 -o test_wake tb_wake.sv
```
4. Запустите симулятор командой
``` bash
vvp test_wake
```
<div style="text-align: justify">
В терминал будут выведены результаты симуляции, и в рабочей директории будет создан файл out.vcd.
</div>
5. Откройте waveform через GTKWave
```bash
gtkwave out.vcd
```

<div style="text-align: justify">
После выполнения команды будет открыто окно с графическим интерфейсом GTKWave. Для просмотра необходимо выбрать сигналы, которые нужно вызуализировать. В итоге мы получаем визуализацию изменения значений входных и выходных сигналов с течением времени.
</div>