수성컴전자방입니다. Verilog는 하드웨어를 설계할 때 사용할 수 있는 언어입니다. Verilog를 컴파일하기 위해서 여러 가지 tool을 사용할 수 있는데요, 오늘은 Icarus Verilog(iverilog)를 사용해 보려고 합니다. Icarus Verilog는 터미널 명령어로 사용하기 때문에 Visual Studio Code의 터미널에서도 사용하실 수 있습니다. 또한 Icarus Verilog는 원래 Linux에서 작동하는 프로그램이지만 이 글에서는 Windows에 설치해 보겠습니다.
목차
1. Icarus Verilog 설치하기
2. 간단한 소스 코드와 testbench 사용해 보기
3. testvector 사용 방법
4. 번외) Visual Studio Code에서 Verilog 확장 사용하기
5. 글 마무리
6. 참고 자료
1. Icarus Verilog 설치하기
1.1. http://iverilog.icarus.com에 접속합니다.
1.2. 위 스크린샷에서 파란색 동그라미 친 부분을 클릭합니다.
1.1~1.2. https://iverilog.fandom.com/wiki/Installation_Guide에 접속하시면 됩니다.
1.3. Windows 문단 하위에 있는 Installers를 클릭합니다.(Installation Guide 2.7.2번 문단)
1.4. Icarus Verilog for Windows를 클릭합니다.
1.5. 64-bit를 사용하실 경우 iverilog-v12-20220611-x64_setup을 클릭합니다. 아마 요즘은 대부분 64-bit를 쓰실 것 같습니다. 다만, 32-bit를 사용하실 경우 iverilog-10.0-x86_setup을 설치합니다. 32-bit는 최신 버전이 10.0이군요…
1.6. I accept the agreement를 클릭하고 Next를 클릭합니다.
1.7. 현재 버전의 Icarus Verilog for Windows는 공백이 있는 경로에 설치하는 것을 지원하지 않는다고 합니다. 따라서 Program Files 폴더에 설치할 수 없습니다. Next를 클릭합니다.
1.8. 설치 경로 지정 화면입니다. 그냥 그대로 두면 문제 될 것 없습니다. Next를 클릭합니다.
1.9. 둘 다 선택된 채로 Next를 클릭합니다.
1.10. Next를 클릭합니다.
1.11. Add executable folder(s) to the user PATH에 체크합니다. 그러면 Icarus Verilog 관련 파일들(이 들어있는 폴더들)이 환경 변수 PATH에 추가되어, 터미널에서 iverilog를 사용할 수 있게 됩니다.
1.12. Install을 클릭합니다.
1.13. Finish를 클릭합니다.
1.14. 터미널(Windows+X→터미널)에서 iverilog -v 명령을 실행하여 설치가 잘 이루어졌는지 확인하실 수 있습니다.
1.15. gtkwave 명령을 실행하면 GTKWave가 실행됩니다. 이 프로그램을 이용하여 Waveform을 확인할 수 있습니다.
2. 간단한 소스 코드와 testbench 사용해 보기
먼저 예제 코드를 보여드리겠습니다. Verilog 문법은 어느 정도 아신다고 가정하고 설명 드리겠습니다.
_and2.v
module _and2(a, b, y);
input a, b;
output y;
assign y=a&b;
endmodule
a와 b가 input이고 y가 output인 2-input AND module입니다.
tb_and2.v
`timescale 1ns/100ps
module tb_and2;
reg a, b;
wire y;
_and2 dut(a, b, y);
// Icarus Verilog part
initial begin
$dumpfile("test_out.vcd"); // any file name possible
$dumpvars;
end
initial begin
#0 a=0; b=0;
#10 a=1; b=0;
#10 a=0; b=1;
#10 a=1; b=1;
#10 $finish;
end
endmodule;
여기서는 몇 가지 설명 드릴 것이 있습니다.
[Line 10~13]
dumpfile을 생성하는 부분입니다.
Line 11에서 dumpfile의 이름을 지정합니다. 저는 test_out.vcd로 했습니다.
Line 12의 $dumpvars;
는 모든 module과 variable의 waveform을 저장하게 합니다. 구체적인 내용은 아래와 같습니다.
$dumpvars; //현재 Testbench의 모든 variable
$dumpvars(0, 모듈명); //지정한 모듈 하위의 모든 submodule
$dumpvars(1, 모듈명); //지정한 모듈만
$dumpvars(2, 모듈명); //지정한 모듈의 1 level 하위 module까지만
…
[Line 20]
$finish
를 통해 testbench 실행을 마칩니다.
2.1. _and2.v와 tb_and2.v를 한 폴더 안에 넣었다고 가정하고 진행하겠습니다.(다른 폴더에 있어도 되는데 그러면 명령어로 상대 경로를 입력하셔야 합니다.)
2.2. 터미널(스크린샷은 VS Code→터미널→새 터미널로 터미널을 실행한 것. 1.14번처럼 Windows Terminal을 사용해도 괜찮음.)에서 iverilog -o test .\and2.v .\tb_and2.v 명령을 실행합니다.
그러면 test라는 파일이 생성됩니다. 위의 명령어에서 -o test로 파일명을 지정한 것입니다. 만약 ‘-o test
‘를 쓰지 않으면 a.out이 생성됩니다. C언어(GCC)랑 비슷하죠?
2.3. 리눅스라면 그냥 test 파일을 실행할 수 있겠지만 Windows에서는 불가능하므로 vvp를 사용합니다.
vvp test (또는 vvp .\test) 명령을 실행합니다.
그러면 test_out.vcd 파일이 생성됩니다.
2.4. gtkwave .\test_out.vcd 명령을 실행합니다. 그러면 GTKWave 창이 뜹니다.
2.5. GTKWave 창에서 tb_and2를 클릭합니다.
2.6. 왼쪽 중간 쯤 있는 모든 변수를 선택(Ctrl+A 가능)한 후 Insert를 클릭합니다.
2.7. 그러면 변수들이 추가됩니다. 축소(Ctrl+휠아래로)하세요.
2.8. waveform을 한 눈에 보실 수 있습니다.
3. testvector 사용 방법
_and2.v는 그대로 사용하고 testbench만 tb_usingvector.v를 새로 만들어 쓰겠습니다.
`timescale 1ns/100ps
module tb_usingvector;
reg clk, reset;
reg a, b, yexpected;
wire y;
reg [31:0] vectornum, errors; //bookkeeping variables
reg [31:0] testvectors[0:10000]; //array of testvectors
//instantiate device under test
_and2 dut(a, b, y);
// Icarus Verilog part
initial begin
$dumpfile("test_out.vcd"); // any file name possible
$dumpvars; // instance name required
end
//generate clock
always begin
clk=1; #5; clk=0; #5;
end
//at start of test, load vectors and pulse reset
initial begin
$readmemb("./testvector.tv", testvectors); //Put testvector file at the directory of executable file.
vectornum=0; errors=0;
reset=1; #27; reset=0;
end
//apply test vectors on rising edge of clk
always @(posedge clk)
begin
#1; {a, b, yexpected}=testvectors[vectornum];
end
//check results on falling edge of clk
always @(negedge clk)
if(~reset) begin //skip during reset==1
if(y!==yexpected) begin
$display("Error: inputs=%b", {a, b});
$display(" outputs=%b (%b expected)", y, yexpected);
errors=errors+1;
end
//increment array index and read next testvector
vectornum=vectornum+1;
if(testvectors[vectornum]===32'bx) begin
$display("%d tests completed with %d errors.", vectornum, errors);
$finish;
end
end
endmodule;
Line 8에서 배열의 길이를 선언할 때 [10000:0] 말고 [0:10000]으로 하시기 바랍니다. 이는 1364-2001 states에서 lowest address가 default start address이기 때문입니다.
Line 14~17은 dumpfile을 생성하는 부분입니다.
Line 26에서 ./testvector.tv 파일을 읽어 와서(이 파일은 컴파일로 생성되는 실행 파일 경로와 동일 경로에 있음.) 한 줄씩 testvectors 배열에 저장합니다.
Line 28에서 처음에는 reset=1이었다가 27ns 후 reset=0이 됩니다. Line 39에 의해 reset=0일 때에만 작동합니다.
Line 32~35에서는 클럭(clk)의 posedge(rising edge)에 testvectors[vectornum]을 a, b, yexpected에 불러오도록 합니다.
Line 37~52에서 클럭(clk)의 negedge(falling edge)에 self-checking을 합니다. 즉, 오류(Error)가 발생하면 $display
문으로 알려줍니다.
최종적으로는 error의 개수를 알려주고 종료($finish
)합니다.
아래는 testvector.tv입니다.
00_0
10_0
01_0
11_1
3.1. _and2.v, tb_usingvector, testvector.tv를 한 폴더 안에 넣었다고 가정하고 진행하겠습니다.
3.2. iverilog -o test ._and2.v .\tb_usingvector.v 명령을 실행합니다.
3.3. vvp test (또는 vvp .\test) 명령을 실행합니다.
그러면 터미널 창에 오류가 있는지의 여부와 오류 개수가 출력됩니다.
3.4. gtkwave .\test_out.vcd 명령을 실행합니다. 그러면 GTKWave 창이 뜹니다.
3.5. GTKWave 창에서 tb_usingvector를 클릭합니다.
3.6. 왼쪽 중간 쯤 있는 모든 변수를 선택(Ctrl+A 가능)한 후 Insert를 클릭합니다.
3.7. 그러면 변수들이 추가됩니다. 축소(Ctrl+휠아래로)하세요.
2.8. waveform을 한 눈에 보실 수 있으며, error 개수도 함께 보실 수 있습니다.
4. 번외) Visual Studio Code에서 Verilog 확장 사용하기
Visual Studio Code에서 코딩하는 경우 Verilog-HDL/SystemVerilog/Bluespec SystemVerilog를 사용하면 코드에 색상이 적용되어 편리합니다.
5. 글 마무리
이렇게 오늘은 Icarus Verilog 사용 방법을 알아보았습니다. Icarus Verilog는 단점이 있는데요, 바로 RTL View(회로도)를 볼 수 없다는 것입니다. 사용 시 유의하시기 바랍니다. 제 글을 읽어 주셔서 감사합니다.
6. 참고 자료
1) David Money Harris, Sarah L. Harris. 2013. Digial Design and Computer Architecture. 2nd Edition. Elsevier Korea L.L.C.
2) 군잉. 2019. “IcarusVerilog // Verilog 연습환경 만들기”, whatever. (2023. 01. 31. 방문). https://blog.naver.com/doksg/221699215846
3) pikamon. 2022. “[VSCode] Verilog 편집 환경 설정(Verilog Extension)”, pikamon.log. (2023. 01. 31. 방문). https://velog.io/@pikamon/VSCode-1
4) HDL 엔지니어. 2022. “Icarus Verilog 사용법 및 유용한 팁”, Verilog HDL 설계 길잡이. (2023. 01. 31. 방문). https://verilog-hdl-design.tistory.com/entry/Icarus-Verilog-Tips
5) 씽쏭. 2023. “Verilog VCD Dump”, 오늘의 배움. (2023. 01. 31. 방문). https://ssings.tistory.com/2
6) toolic 외 1명. 2021. “Icarus Verilog warning $readmemh: Standard inconsistency, following 1364-2005”, stackoverflow. (2023. 01. 31. 방문). https://stackoverflow.com/questions/66824196/icarus-verilog-warning-readmemh-standard-inconsistency-following-1364-2005