네이버 이웃 추가 / GitHub Profile / 카카오톡 채널 추가 / 방명록 / 이용 안내

Windows에서 Icarus Verilog 설치 및 사용법(feat. VS Code)

수성컴 | 2023. 01. 28.
Windows에서 Icarus Verilog 설치 및 사용법(feat. VS Code)

수성컴전자방입니다. 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 설치하기

iverilog-site
1.1. http://iverilog.icarus.com에 접속합니다.
1.2. 위 스크린샷에서 파란색 동그라미 친 부분을 클릭합니다.
1.1~1.2. https://iverilog.fandom.com/wiki/Installation_Guide에 접속하시면 됩니다.

iverilog-wiki
1.3. Windows 문단 하위에 있는 Installers를 클릭합니다.(Installation Guide 2.7.2번 문단)

iverilog-wiki-installers
1.4. Icarus Verilog for Windows를 클릭합니다.

bleyer
1.5. 64-bit를 사용하실 경우 iverilog-v12-20220611-x64_setup을 클릭합니다. 아마 요즘은 대부분 64-bit를 쓰실 것 같습니다. 다만, 32-bit를 사용하실 경우 iverilog-10.0-x86_setup을 설치합니다. 32-bit는 최신 버전이 10.0이군요…

Setup
1.6. I accept the agreement를 클릭하고 Next를 클릭합니다.

Information
1.7. 현재 버전의 Icarus Verilog for Windows는 공백이 있는 경로에 설치하는 것을 지원하지 않는다고 합니다. 따라서 Program Files 폴더에 설치할 수 없습니다. Next를 클릭합니다.

Select Destination Location
1.8. 설치 경로 지정 화면입니다. 그냥 그대로 두면 문제 될 것 없습니다. Next를 클릭합니다.

Select Components
1.9. 둘 다 선택된 채로 Next를 클릭합니다.

Select Start Menu Folder
1.10. Next를 클릭합니다.

Select Additional Tasks
1.11. Add executable folder(s) to the user PATH에 체크합니다. 그러면 Icarus Verilog 관련 파일들(이 들어있는 폴더들)이 환경 변수 PATH에 추가되어, 터미널에서 iverilog를 사용할 수 있게 됩니다.

Ready to Install
1.12. Install을 클릭합니다.

설치완료
1.13. Finish를 클릭합니다.

터미널에서 iverilog 버전 확인
1.14. 터미널(Windows+X→터미널)에서 iverilog -v 명령을 실행하여 설치가 잘 이루어졌는지 확인하실 수 있습니다.

터미널에서 gtkwave 실행
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를 한 폴더 안에 넣었다고 가정하고 진행하겠습니다.(다른 폴더에 있어도 되는데 그러면 명령어로 상대 경로를 입력하셔야 합니다.)

VS Code 터미널에서 iverilog
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)랑 비슷하죠?

VS Code 터미널에서 vvp
2.3. 리눅스라면 그냥 test 파일을 실행할 수 있겠지만 Windows에서는 불가능하므로 vvp를 사용합니다.
vvp test (또는 vvp .\test) 명령을 실행합니다.
그러면 test_out.vcd 파일이 생성됩니다.

VS Code 터미널에서 gtkwave
2.4. gtkwave .\test_out.vcd 명령을 실행합니다. 그러면 GTKWave 창이 뜹니다.
2.5. GTKWave 창에서 tb_and2를 클릭합니다.

GTKWave에서 모듈 선택 Insert
2.6. 왼쪽 중간 쯤 있는 모든 변수를 선택(Ctrl+A 가능)한 후 Insert를 클릭합니다.

GTKWave에 waveform 나타남
2.7. 그러면 변수들이 추가됩니다. 축소(Ctrl+휠아래로)하세요.

GTKWave로 waveform 확인
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를 한 폴더 안에 넣었다고 가정하고 진행하겠습니다.

VS Code 터미널에서 iverilog와 vvp
3.2. iverilog -o test ._and2.v .\tb_usingvector.v 명령을 실행합니다.
3.3. vvp test (또는 vvp .\test) 명령을 실행합니다.
그러면 터미널 창에 오류가 있는지의 여부와 오류 개수가 출력됩니다.

VS Code 터미널에서 gtkwave
3.4. gtkwave .\test_out.vcd 명령을 실행합니다. 그러면 GTKWave 창이 뜹니다.
3.5. GTKWave 창에서 tb_usingvector를 클릭합니다.

GTKWave에서 모듈 선택 Insert
3.6. 왼쪽 중간 쯤 있는 모든 변수를 선택(Ctrl+A 가능)한 후 Insert를 클릭합니다.

GTKWave에 waveform 나타남
3.7. 그러면 변수들이 추가됩니다. 축소(Ctrl+휠아래로)하세요.

GTKWave로 waveform 확인
2.8. waveform을 한 눈에 보실 수 있으며, error 개수도 함께 보실 수 있습니다.

4. 번외) Visual Studio Code에서 Verilog 확장 사용하기

vscode-extention
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