# Руководство по установке и эксплуатации симулятора 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 ``` ![](https://hackmd.io/_uploads/S1DCv7_Vn.jpg) <div style="text-align: justify"> После выполнения команды будет открыто окно с графическим интерфейсом GTKWave. Для просмотра необходимо выбрать сигналы, которые нужно вызуализировать. В итоге мы получаем визуализацию изменения значений входных и выходных сигналов с течением времени. </div>