프로그래밍/Verilog

Verilog HDL 모듈, 포트, 테스트벤치

반응형


+ 모듈 (module)


베릴로그의 모듈은 C의 함수(function) 단위와 비슷하며, 베릴로그 설계를 위한 기본적인 블록 단위이다.
module <모듈 이름> (포트 목록); 으로 시작하며, endmodule로 끝난다.

또한 하나의 모듈은 하나의 파일로 구성된다. 확장자는 .v 이다.

 

* 예시

 


module example(inp1, inp2, inp3, inp4, result);
   input inp1, inp2, inp3, inp4;
   output result;
   wire t1, t2;

   and (t1, inp1, inp2);
   and (t2, inp3, inp4);
   nor (result, t1, 2t);
endmodule






+ 포트 (port)


포트는 모듈과 모듈을 연결할 수 있는 인터페이스 이다.

<키워드> [범위] <포트 이름> 의 형태로 선언하며, 그 종류에는 input, output, inout 이 있다.

input은 입력포트이며, output은 출력 포트, inout은 양방향 포트이다.

모든 포트는 wire로 선언된다. 단, output 포트의 경우 포트의 값 변경이 필요하다면 같은 이름으로 reg를 선언해야한다.

 

포트를 연결할 때는 다음과 같은 규칙을 따른다.


  • 내부 입력 포트는 반드시 net 형, 외부 입력 포트는 reg 또는 net 변수와 연결될 수 있다.
  • 내부 출력 포트는 reg 또는 net 형, 외부 출력 포트는 반드시 net 변수와 연결되야 한다.
  • 내부 양방향성(입출력) 포트는 반드시 net 형, 외부 양방향성 포트는 반드시 net 변수와 연결되야 한다.
  • 같은 비트 수끼리 연결해야 한다.

 

포트를 연결할 때는 c언어에서 함수에 인자 값 전달하듯이 인자 순서대로 연결할 수 있으며, 또는 순서에 상관없이 이름에 각각 할당할 수 있다.



* 예시


module adder(x, y, c_out, c_in, sum);
   // ...
endmodule 

// 위치에 의한 포트 연결
adder adder1(inp1, inp2, carry_out, carry_in, sum_out);
// 이름에 의한 포트 연결
adder adder2(.sum(sum_out), .c_out(carry_out), .c_in(carry_in), .x(inp1), .y(inp2));






+ 테스트벤치 (testbench)


테스트벤치는 HDL 로 설계한 논리회로를 시뮬레이션 검증을 하기 위해 사용한다. FPGA 등의 기계가 없이 테스트를 할 수 있으므로 회로 테스트에 용이하다.

테스트 모듈에서 검증하고 싶은 모듈을 호출하여 와이어 들의 값을 확인할 수 있다.

테스트벤치에서는 시스템 태스크 키워드(system task keyword)들이 사용된다. 그 종류는 다음과 같다.


  • $display : 화면 출력 태스크이다. 변수 값, 문자열, 수식 등을 출력하는 용도로 사용한다. C의 printf와 용법이 비슷하다.
  • $monitor : 모니터링 태스크이다. 연결한 레지스터나 와이어의 값이 변할 때마다 그 값을 계속해서 출력한다.
  • $stop : 시뮬레이션을 중단하거나, 신호의 값을 알아내고자 할 때 사용한다.
  • $finish : 시뮬레이션을 멈추기 위해 사용한다.
  • $time : 시뮬레이션의 현재 시간을 나타낸다.


 

* 예시


module stimulus;
   wire	[3:0]	highM, lowM, highS, lowS, highD, lowD;
   reg	clock;	        // Clock
   reg	[3:0] keyData;	// Start, Reset, Stop keys for stopwatch
   wire	[3:0] keyScan;
   wire	[6:0] segments;	// 7-segments
   wire	[5:0] setSeg;	// Position of segment

   // Calling the module
   project watch(clock, keyData, keyScan, segments, setSeg, highM, lowM, highS, lowS, highD, lowD);

   always begin	// Clock period
      #5 clock = ~clock;
   end

   initial begin
      clock = 1'b0;
      keyData = 4'b1111;	// Initializing
      #20 keyData = 4'b0111;	// Start key on
      #50 keyData = 4'b1111;	// Start button off
      #2000 $stop;
   end

   initial $monitor($time, " > %d%dmin %d%dsec %d%dds", highM, lowM, highS, lowS, highD, lowD);
endmodule




반응형