VHDL 자가 검증 테스트벤치 구축 실전 가이드
자가 검증 테스트벤치는 수동 검사 없이 DUT(시험 대상 장치)의 정확성을 자동으로 검증하는 VHDL 프로그램입니다. 실행하면 OK 또는 Failed 상태를 자동 보고하므로 신뢰할 수 있는 VHDL 개발에 필수적인 도구입니다.
모든 VHDL 모듈은 연관된 자가 검증 테스트벤치를 가져야 합니다. 이렇게 하면 DUT 자체, 서브모듈, 인터페이스 변경 시 회귀 버그가 조용히 생기는 걸 방지할 수 있습니다. 잘 만든 테스트벤치는 미묘한 버그에 대한 첫 번째 방어선입니다.
시험 대상 장치(DUT)
간단하면서도 설명하기 좋은 DUT로 이진-그레이 코드 변환기를 쓰겠습니다. 전체 RTL 구현은 아래와 같습니다.
library ieee; use ieee.std_logic_1164.all; entity gray_converter is port ( bin : in std_logic_vector; gray : out std_logic_vector ); end gray_converter; architecture rtl of gray_converter is begin process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; end process; end architecture;
그레이 코드는 연속된 값 사이에 비트 하나만 바뀌는 이진 인코딩 방식으로, 직렬 통신과 디지털 카운터에서 오류 확률을 최소화합니다. 아래 표는 4비트 값의 매핑을 보여줍니다.
| 십진수 | 이진수 | 그레이 |
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
테스트벤치 골격
아래는 DUT를 인스턴스화하고 필요한 시그널을 선언한 최소 테스트벤치입니다. VHDL-2008 기능인 std.env.finish로 시뮬레이션을 깔끔하게 종료합니다.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.env.finish; entity gray_converter_tb is end gray_converter_tb; architecture sim of gray_converter_tb is signal bin : std_logic_vector(3 downto 0) := (others => '0'); signal gray : std_logic_vector(3 downto 0); DUT : entity work.gray_converter(rtl) port map ( bin => bin, gray => gray ); end architecture;
ModelSim 같은 VHDL-2008 준수 시뮬레이터에서 이 파일을 컴파일하려면 파일 언어 버전을 2008로 설정해야 할 수 있습니다. ModelSim에서는 파일을 우클릭해 Properties → VHDL → Use 1076-2008을 선택하세요.
전수 입력 생성
다음 단계는 가능한 모든 4비트 값을 완전히 훑는 것입니다. 전수 테스트가 모든 코너 케이스를 검증하므로 선호됩니다.
PROC_SEQUENCE : process begin -- Iterate over every 4‑bit value for i in 0 to 2**bin'length - 1 loop bin <= std_logic_vector(to_unsigned(i, bin'length)); wait for 10 ns; end loop; -- 초기 상태로 랩어라운드 bin <= (others => '0'); wait for 10 ns; report "Test: OK"; finish; end process;
10ns 지연은 임의 값입니다. DUT가 순수 조합 논리이므로 양수 값이면 아무거나 상관없습니다. 마지막 finish 문으로 시뮬레이션을 우아하게 끝냅니다.
DUT 출력 검증
단순히 "Test: OK"를 출력하는 건 출력이 틀려도 의미 없습니다. 정확성을 강제하려면 DUT의 그레이 출력을 그레이 코드 기본 속성인 '연속 출력은 정확히 한 비트만 달라야 한다'와 비교해야 합니다.
PROC_CHECKER : process variable prev : std_logic_vector(gray'range); variable count : integer; begin wait on bin; prev := gray; -- 조합 논리 안정화 대기 wait for 1 ns; count := 0; for i in gray'range loop if gray(i) /= prev(i) then count := count + 1; end if; end loop; assert count = 1 report integer'image(count) & " bits changed, should have been 1" severity failure; end process;
이 프로세스는 bin 변경을 감시하고, 이전 그레이 출력을 저장한 뒤 전파 대기 후 다른 비트 수를 세어 정확히 1개인지 어서트합니다. 어서션 실패 시 시뮬레이터가 즉시 멈춰 "Test: OK" 메시지가 나오지 않게 합니다.
테스트벤치 실행
ModelSim에서 시뮬레이션을 시작하고 run -all을 실행합니다. 성공적인 실행은 다음과 같이 끝납니다:
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
테스트벤치 강건성 테스트
체커가 결함을 잡아내는지 확인하려면 DUT에 임시로 에러를 주입해 보세요. 예: gray(3)을 0으로 강제합니다.
process(bin) is begin gray(gray'high) <= bin(bin'high); for i in bin'high - 1 downto bin'low loop gray(i) <= bin(i + 1) xor bin(i); end loop; -- Stuck-at-zero 결함 에뮬레이션 gray(3) <= '0'; end process;
이제 테스트벤치를 실행하면 어서션 실패가 발생하며 정확히 몇 비트가 바뀌었는지 표시합니다:
VSIM 2> run -all # ** Failure: 0 bits changed, should have been 1 # Time: 81 ns Iteration: 0 Process: /gray_converter_tb/PROC_CHECKER File: gray_converter_tb.vhd # Break in Process PROC_CHECKER at ray_converter_tb.vhd line 61
자가 검증 테스트벤치 시작하기
모든 VHDL 모듈에 자가 검증 테스트벤치를 작성하는 습관을 들이세요. 회귀를 조기에 잡아 시간을 아끼고 설계 의도를 명확히 기록합니다. 테스트벤치는 합성 가능할 필요 없지만, 명확하고 유지보수하기 쉬우며 최신 VHDL 구문을 써서 가독성과 효율성을 높여야 합니다.
더 깊은 학습을 원하면 명세부터 FPGA 프로토타입까지 전체 설계 흐름을 다루면서 엄격한 검증 관행을 강조하는 고급 강의를 고려해 보세요.
2020년 10월 12일 업데이트: VHDL 및 FPGA 강의를 완료했습니다. 아래 이미지를 클릭해 자세히 알아보세요.
도트 매트릭스 VHDL 및 FPGA 강의 자세히 보기!
오픈:
미정.