Verilog기초(11) - Testbench

최보열·2022년 9월 27일
0

Verilog기초

목록 보기
11/12
post-thumbnail

이번 글에서는이전 글들에서 계속 말씀드렸던 Testbench를 좀 다뤄보고자 합니다. 왜 이제까지 미뤄왔는지는 여러 이유가 있습니다만, Verilog문법 자체에 익숙해지는 것을 원하였고, instination이며, port끼리 연결하는 개념이 정립되어야 다룰 수 있는 주제라 생각이 되어 이번 글에서 하고자 합니다.

Chip이 설계와 공정을 거쳐 PCB에 부착되기 이전의 상태까지 나오는 flow는 위의 그림과 같습니다. Spec이 결정되면 Architecture design부터 여러 과정을 거쳐서 packaging과 testing 과정까지 순차적으로 진행되는데 Verilog로 다루는 부분은 Spec부터 logic circuit design까지라고 볼 수 있습니다. 이 과정을 VLSI(Very Large Scale Integration) flow에서 front end 분야라고 많이들 부릅니다.

(SW의 front end, 공정의 front end와 다른 의미를 가지니 주의해주세요)

Front end의 업무를 말씀드리자면 Spec을 가지고 원하는 logic을 Verilog와 같은 HDL로 구현하고 해당 Verilog코드를 합성하여 gate-level 또는 netlist로 back end 엔지니어에게 넘겨주는 것입니다. Verilog코드를 합성하기 이전에 해당 logic이 제대로 동작하는지 오류를 찾기 위한 simulation이라는 과정이 존재합니다. 여기서 말하는 simulation을 하기 위해서 testbench를 작성하는 것이고요.

프로그래밍 언어는 해당 코드를 test하기 위해서 run과 debug의 과정을 가집니다. compile된 executable한 파일을 실행시키면서 원하는 결과가 나오는지 확인하는 과정이죠. 하지만 Verilog로 구현한 하드웨어는 run과 같은 개념이 존재하지 않습니다. 따라서 동작을 확인하기 위해서는 우리가 모든 발생할 수 있는 상황을 예상하고 해당 값들을 module에 집어넣어 봄으로써 결과를 확인하는 것이죠.

해당 그림은 'Verilog기초(8) - wire' 글에서 다룬 AND와 OR연산이 일어나는 module입니다. 해당 module을 '확인'하기 위해서는 어떻게 해야될까요? 바로 input port인 A와 B와 D에 '어떤 값을 넣어보고' E에 and, or연산이 정확히 되는지 '관찰'하면 됩니다. 그리고 그걸 위해서 만들어주는 module이 testbench입니다.

Verilog의 testbench는 다음과 같은 형태를 가지는데 저희가 test할려는 module을 DUT(Design Under Test)라고 지칭합니다. 해당 DUT를 Testbench라는 커다란 module에서 instination을 하고, 특정 문법들을 사용하여서 DUT에 값을 집어넣어 줍니다. 지금은 무슨 말인지 잘 이해가 안가실테니 코드를 한번 살펴봅시다.

먼저 Testbench코드의 앞부분입니다. 이전에 module을 기술할 때처럼 module의 이름을 설정해주는데 차이점은 input/output port가 존재하지 않습니다. 왜냐하면 testbench외부에서 어떤 값이 들어오는 것이 아니라 Testbench내부에서 값을 생성할 것이기 때문입니다. 대신에 reg와 wire로 선언되어 있는데 이는 일단 넘어가는게 좋습니다.

일단은 test하는 module의 input은 reg로, output은 wire로 선언해주세요.
(왜 그러는지는 공부하시면서 스스로 알게 되실껍니다)

아래에는 DUT를 inst하고 있습니다. 위의 Top내부에 DUT가 있는 그림을 생각하시면 이해가 편하실 것 같습니다. 그 다음에는 아래와 같이 원하는 값들을 input port인 A_i와 B_i, D_i에 집어넣어주면 testbench의 작성이 끝나게 됩니다.

살펴볼 내용은 initial입니다. initial은 testbench에서 사용하는 문법으로 simulation에 시작지점에 동작을 기술하는 문법입니다. always와 같이 begin end로 영역을 지정하고 내부에 값을 집어넣는 동작을 기술합니다. 명심할 내용은 Testbench는 합성을 위한 코드가 아니고, test를 위한 용도입니다. 당연히 initail구문은 합성이 안됩니다.

initial내부의 구문은 simulation이 시작될 때 수행되는데 모두 blocking을 사용하고 있기 때문에 절차적으로 수행될 것입니다. 여기서 배워야되는 문법이 하나 있는데 '#'입니다. 해당 기호 뒤에 숫자가 들어가면 숫자의 value값만큼 delay를 주게 됩니다.

(Blocking, Non-Blocking은 Verilog심화에서 다루도록 하겠습니다)

delay를 주는게 무슨 말이냐 하면 예를들어 위와같이 #0이후에 몇가지 구문이 있고 그아래 #5가 있다면 #5는 5라는 delay이후에 수행되는 것입니다. 즉 위의 코드를 해석하자면 simulation이 시작하고 0의 delay이후에 A_i에 0을, B_i에 0을, D_i에 0을 집어넣으라는 의미입니다. 그리고 5라는 delay이후에 A_i에 1을, B_i에 0을, D_i에 0을 집어넣으라는 의미입니다.

그런데 여러분은 의문이 생기실 겁니다. delay의 단위는 어떻게 되는지? 즉 5초뒤인지 5분뒤인지 모릅니다. 그러기 위해서 사용되는 문법이 timescale입니다.

module이라는 영역 외부에 timescale이라는 구문이 보이실 겁니다. 여기서 앞의 1ps라는 값이 적히게 되면 #뒤의 값이 해당 부호를 가지게 됩니다. 즉 1ps라하면 1피코세컨드가 기본 단위가 되는데 #5임으로 5피코세크 뒤에 수행되라는 의미가 됩니다.

따라서 이게 testbench의 기본 끝입니다. 여러분이 생각하는 input값들을 해당 문법들을 통해서 집어넣고, 결과를 simulation에서 수행하여 확인해보시면 됩니다.

clock generate와 timing관련된 내용은 이후 sequential회로를 다루고 다시 testbench에 관련된 글을 정리하면서 말씀드리도록 하겠습니다. 마무리로 지난 시간에 다룬 4bit full adder의 testbench를 살펴보고 어떤 구성인지 복습하며 해석해보시길 바랍니다.

다음시간은 기본적으로 자주 사용되는 combination 회로들을 하나씩 살펴보도록 하겠습니다.

REF.

profile
Computer Architecture 엔지니어 지망생 from SKKU

0개의 댓글