[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)을 수행할 때 유용할 것입니다.

Comprehensive Functional Verification

Comprehensive Functional Verification: The Complete Industry Cycle
(공)저: Bruce Wile, John C. Goss, Wolfgang Roesner
기고가 John C. Goss, Wolfgang Roesner
Edition: illustrated, annotated
출판사: Morgan Kaufmann, 2005
ISBN 0127518037, 9780127518039
704페이지

구글에서 맛배기만 보다가 맘먹고 구입한 책. SystemVerilog를 다루지 않는 것은 좀 아쉽지만 기본 개념부터 예제까지 잘 정리되어있다. 내용도 좋지만 가격 또한 착하다. 4만원대에 판매하고 배송도 빠른 곳이 있어서 기쁜 마음으로 구입했다. 유용한 내용은 틈틈히 블로그를 통해 다뤄볼 예정

(Verilog) Setting a Net to a Logic Value

The $deposit system task allows you to set a net to a particular value and then to simulate
with the net set to that new value. The value change is propagated throughout the nets and
registers being driven by the variable that has been set. The syntax is as follows:

$deposit(variable, value);

The $deposit task can be used within any Verilog-XL procedural block. You can define the time at which the net is to be given a new value using the standard procedural constructs. The task can also be used on the interactive command line.

Use this system task as a debugging or design initialization aid. You should not use it as a
representation of actual circuitry.

Common uses for the $deposit system task include the following:

  • To initialize large portions or all of a circuit either at the beginning of or during a simulation. You can select the nodes to be deposited to yourself, or use PLI code to extract the node names.
  • To stop the simulator during a debugging session and to use the command on the interactive command line to set a new value.
  • To reset a circuit to a known state after simulation in order to retry a different debug route.
  • To set parts of a circuit to analyze intricate circuit details (common for switch level simulation).
  • To break feedback loops to set them to a known state.

In the syntax, variable is the name of the net or register whose value is being changed. The variable can be a net or register type but not a parameter, and it can be a vector or scalar object that can be expanded or compacted.

The second parameter, value, is a numerical or logical value in standard Verilog-XL notation. Bit and part selects are not allowed.

If the width of the value is smaller than the range of the variable, an error message is generated. If the width of the value is larger than the range of the variable, the MSBs are truncated and a warning is issued.

X and Z states can also be deposited.

Here are some examples of using $deposit:
$deposit(sig, 1);
$deposit(bus, ’hA2);
$deposit(bus4, ’bZ01x);

p.s. 좋은 Tip알려준 yangk에게 감사.. ^^

칩 테스트 환경 개선

지난 달에 Fab-Out된 제품의 Wafer Test를 진행 중이다.
내가 설계한 MIPI DSI IP는 이미 작년에 Demo용 Test Chip으로 제작한 바 있으나 말그대로 테스트칩이라 Demo Kit상에서 직접 테스트했었고 Wafer Test는 처음.

MIPI DSI/D-PHY Protocol이 복잡하고 고속 동작을 해야하기 때문에 Test Setup의 난이도가 매우 높다. 시작한 3주만인 오늘에서야 드디어 정상 동작이 확인되었다. 다른 Test와 병행했던 이유나 장비사정도 있었긴 하지만 어쨌건 상당히 고전한 셈. 이번 주에 Fab-Out되는 제품이 2개 더 있기 때문에 내일까지 완료하지 못하면 일정이 매우 어려워질 상황에 끝나서 다행이다.

나름 고생이었지만 얻은 바도 있다. 그동안 고질적인 문제가 Test Vector생성과 Test장비 사용을 오가는 과정이 오래걸린다는 것이었다. Test Vector는 설계 Workstation에서 생성하고 Test는 별도의 장비에서하기 때문에 Test중에 Test Vector를 다시 생성하는 것이 불가능했다. 아쉬운대로 Text파일을 에디터로 수정하는 것 이상의 Vector수정이 불가능했었고 이 때문에 Test Vector 생성에 오류가 있는 경우엔 다시 개발팀으로 돌아와야했다. Test장비는 다른 건물에 있거나 외주업체에 있는 것을 사용하기 때문에 Vector의 수정과 확인에 불필요하게 소비하는 시간이 많았다.

babyworm님이 안되는 게 어디있어?에서 언급했 듯, 그동안 당연시 생각했던 과정을 개선하였다. 장기간 테스트를 하면서 불편이 컸기에 노트북 PC에서 Test Vector 생성이 가능하도록 환경을 구축하였다. Windows XP에 Cadence LDV 5.1을 설치하였고, cygwin, tcsh, xterm, vim을 설치하여 Workstation과 동일한 환경을 설정하였다.

테스트엔지니어가 작업하는 동안 vector를 새로 생성하고 확인하거나 수정하여 바로바로 FTP로 upload해서 결과를 보는 이 편리함. 미리 완벽한 vector를 만들어 가야한다는 부담감과 스트레스도 전혀없고, vector수정을 기다리는 테스트엔지니어 눈치볼 일도 각자 손가락 빨일도 없다.
왜 그동안 이렇게 안했었는지… ^^

PC에 simulation환경을 setup하는 과정은 조만간 간단히 정리해 올려야겠다.

Intel의 MID (Mobile Internet Device)

지금 내가 하고 있는 일에 만족하는 이유는 좋은 회사들과 함께 일할 기회가 많기 때문이다.
지난 주(3월 7일)에 Intel과 함께 MID(Mobile Internet Device)의 개발에 관련하여 회의를 하였다.

MID는 작년 IDF에서 처음 발표되고 올해 CES에 공개되면서 많은 관심을 끌었다.
아래 사진과 동영상을 보면 짐작할 수 있듯이 화려한 모습과 기능을 자랑한다. (Full-browsing이되는 아이폰이라고 보면 될 듯)
사진만 보면 이미 출시된 것 같지만 사실 저건 모형(mock-up)이다. Backlight가 있어서 사진은 그럴싸하지만 실제로 보면 모형티가 좀 난다.

MID에 사용되는 화면의 구동칩을 우리회사에서 개발할 가능성이 적지 않은데 문제는 일정이 얼마나 Intel과 정렬(align) 되는 가이다. 또 System-level Verification을 지원해달라는 요청을 받았다. 내가 직접 만든 모델링을 Intel의 Platform에서 검증할 수 있다면 도움이 많이 될 것 같은데 시간이 부족하여 쉽지않을 것 같다.

Intel의 MID (Mobile Internet Device)

관련 글:
http://blogs.intel.com/technology/2007/09/breaking_barriers_unleashing_c.html
http://www.infoworld.com/article/07/09/19/Intel-details-Moorestown-platform-for-ultramobile-PCs_1.html
http://www.extremetech.com/article2/0,1697,2185295,00.asp

Assertion-Based Verification 세미나

오늘 Cadence에서 방문하여 Assertion-Based Verification에 관한 세미나를 했다.
SystemVerilog를 사용하므로서 Verilog에서 assertion을 쉽게 사용할 수 있는 지 알기쉽게 잘 설명해주었다. 본래 이틀짜리 교육코스가 있으나 Lab과정을 생략하고 요약하여 2시간동안 진행하였다.
SystemVerilog가 주목을 받고 표준화된 것이 2006년인데도 이미 주요 EDA툴들이 지원할 뿐만아니라 사용하기에도 편해진 것을 보면 CAD툴들의 발전속도는 정말 빠른 것 같다.

인상적인 내용은
- assertion을 이용하여 black-box design을 white-box design으로 만든다.
- assertion watches for forbidden behavior and tracks expected behavior.
- assertion은 design engineer와 verification engineer 모두가 사용하는 것이 바람직하다.
- code coverage의 부족함을 functional coverage로 확장한다.
- Formal Analysis을 이용하여 기본 module에 대해서는 testbench없이 검증한다.

설계자들은 쉽게 사용환경이나 언어를 바꾸지 않으려는 습성이 있기때문에 한순간 모든 설계자들에게 SystemVerilog의 사용을 강요할 수는 없다.
Verilog에 open-source verification library를 연동하여 사용하도록 유도하는 것이 조금 더 접근이 쉬울 것인지 아예 SystemVerilog를 사용하도록 점차 유도 해야하는 것인지 두 가지 모두 고민해야할 듯.