[Verilog] 새로 컴파일하지 않고 테스트 입력/조건을 바꾸는 방법

Compiled-code방식 Verilog 시뮬레이터는 크게 세단계로 동작합니다.

  1. Compile: Verilog Code의 문법을 체크하고, 해석하고(parse/analyze)하고 Compile한다.
  2. Elaboration: 계층구조(design hierarchy)를 구축하고 신호들을 연결하고 초기값을 계산한다.
  3. Simulation: 회로의 동작을 시뮬레이션한다.

복잡하게 나누어 생각하고 싶지 않은 분들도 계실텐데, C프로그램을 해보신 분들이라면 쉽게 이해할 수 있습니다.

  1. Compiler: C컴파일러를 이용해서 C 코드를 Object코드로 만드는 것과 유사합니다.
  2. Elaboration: Object코드를 Linker로 연결해서 실행화일(Executable)을 만드는 것과 유사합니다. C Code건, 어셈블리코드건 언어에 관계없이 Object코드는 동일한 것과 같이 Elaboration은 VHDL와 Verilog를 구분하지 않습니다.
  3. Simulation: 실행화일(Executable)을 실행하는 것과 같습니다.

여기서 주목할 부분은 프로그램을 실행할때 매번 새로 컴파일하지 않고 실행화일만 실행하듯이, 시뮬레이션도 컴파일 과정을 생략할 수가 있다는 것입니다.

컴파일에 소요되는 시간이 전체 시뮬레이션에서 차지하는 시간이 크지 않은 경우도 많지만, 설계가 복잡하고 매우 다양한 경우에 대해서 시뮬레이션(regression)을 할 경우, 이 시간을 줄이는 것이 적지않은 효과가 있습니다.

물론 Verilog 소스코드가 변경된 경우라면 새로 컴파일을 해야합니다만, 사진이 바뀌고 모니터 해상도가 바뀌었다고 포토샵을 새로 컴파일하지 않듯이, 시뮬레이션 입력, 조건만 바뀌었을 경우엔 새로 컴파일 할 필요가 없습니다.

Cadence NC-Verilog를 기준으로 설명해보겠습니다.
NC-Verilog는 두가지 방법으로 실행이 가능한 데 single-step으로 실행하는 command인 ncverilog과 3-step으로 실행하는 command인 ncvlog, ncelab, ncsim이 있습니다.

3-step으로 실행하는 경우엔 마지막 단계인 ncsim만 반복적으로 실행하면 됩니다.

$ ncvlog subblock1.v subblock2.v topmodule.v
$ ncelab topmodule
$ ncsim topmodule
$ ncsim topmodule (재실행)

ncverilog를 사용하는 경우엔 ncverilog -R 옵션을 이용하면 마지막 simulation단계만 실행하게 됩니다.
3-step으로 실행하는 경우엔 마지막 단계인 ncsim만 반복적으로 실행하면 됩니다.

$ ncverilog subblock1.v subblock2.v topmodule.v
$ ncverilog -R (재실행)

이렇게 컴파일을 하지 않고 시뮬레이션만 다시 실행하면서 입력을 바꾸는 방법은 다음과 같습니다.
1. 외부파일을 사용하는 방법
Image processing을 하는 회로라고 가정하면 입력은 주로 사진 데이터입니다. 시뮬레이션 중에 사진 파일을 읽어서 사용하도록 만들면, 사진 파일만 바꿔주면 컴파일과정없이 시뮬레이션을 할 수 있습니다. 대신 외부파일을 읽어들이는 부분(parser)를 Verilog나 C언어로 구현해야합니다.

Verilog로 구현하는 경우엔 C언어와 유사한 $fopen, $fscanf을 이용하면 됩니다. 단, 텍스트파일만 읽을 수 있으므로 PPM과 같은 ASCII 데이터의 파일 format을 사용해야합니다.

C언어를 이용하는 경우 원하는대로 프로그램을 작성하여 decoding이 필요없는 BMP를 비롯, 다양한 입력을 읽어들일 수 있습니다. Verilog의 PLI(Programing Language Interface)나 SystemVerilog의 DPI(Direct Programming Interface)를 이용하면 됩니다.

2. $test$plusargs, $value$plusargs 를 이용하는 방법

$test$plusargs()는 Verilog-1995에도 존재했던 기능이고, $value$plusargs()는 Verilog-2001에서 확장된 기능입니다.

간단한 예로 시뮬레이션 결과를 waveform으로 저장하면 시뮬레이션 속도가 상당히 느려지고, 저장공간을 많이 차지할 수 있습니다. 따라서 필요한 경우에만 signal dump를 받게 되는데 이를 위해 대개 사용하는 방법은 다음과 같습니다.,

1. Verilog코드를 수정해서 $dumpvars와 같은 구문을 주석으로 처리한 뒤 새로 컴파일합니다.

initial
begin
      // $dumpvars;
end

2. `ifdef / `ifndef 를 이용하는 방법. command line에서 설정이 가능하므로 보다 깔끔한 방법이지만, 이 방법 역시 새로 컴파일을 해야합니다.

initial
begin
     `ifndef nodump
            $dumpvars;
     `endif
end

$ncverilog +define+nodump …..

이런 경우 $test$plusargs를 이용하면 됩니다. +define을 사용하는 것과 유사하지만 새로이 컴파일을 할 필요가 없습니다. (-R 옵션에 주목)

initial
begin
      if(!$test$plusargs(“nodump”))
             $dumpvars;
end

$ ncverilog -R  (dump파일 생성)
$ ncverilog -R +nodump (dump파일 생성 안함)

참고로, 간단히 설명하기 위해 dumpvars를 사용했는데, vcd형식보다 shm이나 fsdb형식을 사용하면 속도,용량에 개선 효과가 있습니다.

$value$plusargs 를 이용하면 command line에서 10진수, 16진수, 2진수, 실수 등 보다 상세한 입력이 가능합니다.

$value$plusargs (string, variable)
%b – binary conversion
%d – decimal conversion
%e – real exponential conversion
%f – real decimal conversion
%g – real decimal or exponential conversion
%h – hexadecimal conversion
%o – octal conversion
%s – string (no conversion)
%x – (undergound equivalent for %h)

예제로 클럭 주파수를 바꾸는 경우를 살펴봅시다.

filename: test.v

module test;

reg     clock = 0;
real    clock_h_period;
always #clock_h_period
       clock = !clock;
initial begin
       if(!$value$plusargs(“clock_h=%F”, clock_h_period)) begin
               clock_h_period = 10;
       end
       $monitor(“%t %b”, $time, clock);
       #100 $finish;
end
endmodule

$ ncverilog test.v +nocopyright
Loading snapshot worklib.test:v ……………….. Done
ncsim> source …/tools/inca/files/ncsimrc
ncsim> run
                  0 1
                 10 0
                 20 1
                 30 0
                 40 1
                 50 0
                 60 1
                 70 0
                 80 1
                 90 0
Simulation complete via $finish(1) at time 100 NS + 0
./test.v:15     #100 $finish;
ncsim> exit
$ ncverilog -R +clock_h=20 +nocopyright
Loading snapshot worklib.test:v ……………….. Done
ncsim> source …/tools/inca/files/ncsimrc
ncsim> run
                  0 1
                 20 0
                 40 1
                 60 0
                 80 1
Simulation complete via $finish(1) at time 100 NS + 0
./test.v:15     #100 $finish;
ncsim> exit

반복 회수를 입력하거나, Random 값 생성에 사용할 seed입력(@KyonghoKim의 코멘트)하거나 다양한 환경적인 변수에 대한 반복적인 시뮬레이션(regression)을 수행할 때 유용할 것입니다.

3 thoughts on “[Verilog] 새로 컴파일하지 않고 테스트 입력/조건을 바꾸는 방법

    • 설계를 주로 하는 사람들은 주로 합성가능한 문법만 관심을 갖다보니, Verilog-1995 기능 중에도 안쓰는게 많은 듯.

      툴 기능도 쓰던 형태로만 계속 우려먹고, 프로젝트 일정에 쫓겨서 매뉴얼도 잘 안보고 ^^;;;

Leave a Reply to 김지훈 Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>