Verilog와 SystemVerilog, 차이와 실무 활용

Verilog와 SystemVerilog, 차이와 실무 활용

오래 쓴 공구 상자에는 망치, 드라이버, 렌치가 들어 있습니다. 웬만한 일은 이것으로 다 할 수 있죠. 그런데 가구를 수십 개 조립해야 하는 날이 오면 전동 드라이버와 수평계, 정밀 측정기가 든 세트가 간절해집니다. 기본 공구는 그대로 쓰되, 더 크고 정확한 작업을 위한 도구가 더해진 것이죠.

디지털 칩 설계 언어도 비슷한 길을 걸었습니다. 회로를 기술하는 기본 공구가 Verilog였다면, 여기에 설계 편의 기능과 강력한 검증 도구를 더한 것이 SystemVerilog죠. 이 글에서는 Verilog와 SystemVerilog가 어떻게 다르고, 실무에서는 두 언어를 어떻게 나누어 쓰는지 정리합니다.

하드웨어 기술 언어란 무엇인가

하드웨어 기술 언어(HDL, Hardware Description Language)는 회로의 구조와 동작을 글로 표현하는 언어입니다. 겉모습은 프로그래밍 언어와 비슷하지만, 결과물이 컴퓨터에서 차례로 실행되는 명령이 아니라 동시에 동작하는 하드웨어라는 점이 다르죠.

Verilog는 1980년대 중반에 시뮬레이션 언어로 처음 만들어졌고, 이후 IEEE 1364라는 표준이 되었습니다. VHDL과 함께 대표적인 HDL로 자리 잡았죠. SystemVerilog는 Verilog를 확장한 언어로 2005년 IEEE 1800으로 표준화되었고, 2009년에는 Verilog 표준이 SystemVerilog 표준에 통합되었습니다. 그래서 오늘날 SystemVerilog는 Verilog를 포함하는 상위 언어라고 보면 됩니다.

Verilog만으로 부족해진 이유

칩이 작고 단순하던 시절에는 Verilog만으로 설계와 검증을 모두 할 수 있었습니다. 하지만 칩에 수많은 기능 블록이 들어가면서 두 가지 문제가 커졌죠.

하나는 설계 쪽입니다. Verilog는 데이터 묶음이나 블록 사이의 연결을 표현하는 수단이 부족해, 코드가 길어지고 실수가 늘었습니다. 다른 하나는 검증 쪽입니다. 입력 조합이 기하급수적으로 늘자 사람이 테스트를 하나씩 써서는 버그를 다 찾을 수 없게 되었죠. 무작위로 다양한 입력을 만들고, 어디까지 검증했는지 측정하는 도구가 필요해졌습니다. SystemVerilog는 바로 이 두 빈틈을 메우려고 나왔습니다.

Verilog와 SystemVerilog의 문법 차이

설계자의 의도를 드러내는 문법

Verilog에서는 플립플롭도, 조합 회로도 같은 always 블록으로 씁니다. 그래서 의도와 다르게 래치가 만들어져도 알아차리기 어렵죠. SystemVerilog는 always_ff, always_comb, always_latch로 의도를 나누어 쓰게 하고, 도구가 의도와 다른 회로를 경고해 줍니다.

Verilog로 쓴 플립플롭always @(posedge clk) begin
if (rst) q <= 1’b0;
else q <= d;
end

SystemVerilog로 쓴 플립플롭always_ff @(posedge clk) begin
if (rst) q <= ‘0;
else q <= d;
end

두 코드는 같은 회로를 만들지만, 두 번째 코드는 “이것은 플립플롭이다”라는 의도를 문법으로 밝힙니다. ‘0은 비트 폭에 상관없이 모든 비트를 0으로 채우는 표현이라 폭이 바뀌어도 고칠 필요가 없죠.

자료형과 연결 구조

Verilog를 처음 배우면 reg로 선언하면 레지스터(플립플롭)가 된다고 오해하기 쉽습니다. 실제로 reg는 값을 저장하는 변수일 뿐이고, 어떤 회로가 될지는 쓰는 방식이 정하죠. SystemVerilog는 이 혼란을 줄이려고 logic이라는 자료형을 도입했습니다.

그 밖에도 상태 이름을 붙이는 enum, 여러 신호를 묶는 struct, 블록 사이의 신호 묶음을 한 번에 정의하는 interface, 공통 정의를 모아 두는 package가 더해졌습니다. 신호 수십 개를 일일이 연결하던 일을 interface 하나로 처리할 수 있어 연결 실수가 크게 줄죠.

검증 언어로서의 SystemVerilog

SystemVerilog의 진짜 힘은 검증에 있습니다. 설계 코드는 실제 회로로 바뀌어야 하므로 합성 가능한 문법만 쓸 수 있지만, 테스트벤치는 시뮬레이션에서만 돌아가므로 소프트웨어 언어처럼 자유로운 문법을 쓸 수 있죠.

SystemVerilog의 주요 검증 기능

  1. 클래스: 객체 지향 방식으로 테스트 구성 요소를 재사용한다.
  2. 제약 기반 무작위 생성: 규칙을 지키는 다양한 입력을 자동으로 만든다.
  3. 어서션(SVA): 지켜져야 할 신호 규칙을 적어 두고 위반을 즉시 잡는다.
  4. 기능 커버리지: 어떤 경우를 검증했고 무엇이 남았는지 측정한다.

이 기능들 위에 표준 검증 방법론인 UVM이 만들어졌습니다. 그래서 오늘날 디지털 검증 엔지니어에게 SystemVerilog는 사실상 기본 언어가 되었죠.

실무에서 두 언어를 쓰는 방식

실무에서 Verilog와 SystemVerilog는 대체로 설계와 검증에서 쓰는 범위가 다릅니다. RTL 설계에는 Verilog나 SystemVerilog의 합성 가능한 부분을 쓰고, 테스트벤치에는 클래스와 무작위 생성, 커버리지까지 포함한 SystemVerilog 전체를 쓰죠. 새 프로젝트는 설계에도 SystemVerilog 문법을 쓰는 경우가 늘고 있지만, 오래전에 만든 검증된 Verilog 코드도 여전히 많이 재사용됩니다.

주의할 점도 있습니다. SystemVerilog의 모든 문법을 합성 도구가 지원하는 것은 아니어서, 설계 코드에 쓸 문법은 팀과 도구가 정한 규칙을 따라야 하죠. 또 언어를 바꿔도 하드웨어적 사고는 그대로 필요합니다. 블로킹 대입(=)과 논블로킹 대입(<=)의 차이처럼, 회로가 동시에 동작한다는 사실을 놓치면 어떤 언어로 써도 버그가 생깁니다.

두 언어 비교 표

구분VerilogSystemVerilog
표준IEEE 1364IEEE 1800 (2009년 Verilog 통합)
관계기본 HDLVerilog를 포함하는 확장 언어
always 블록always 하나로 모두 표현always_ff, always_comb, always_latch로 의도 구분
자료형reg, wirelogic, enum, struct 추가
연결 구조신호를 하나씩 연결interface, package로 묶어서 연결
검증 기능기본적인 테스트벤치클래스, 무작위 생성, 어서션, 커버리지
주요 쓰임RTL 설계, 기존 코드 유지보수RTL 설계와 검증 환경, UVM의 기반

핵심 정리

Verilog와 SystemVerilog는 경쟁하는 언어가 아니라 기본과 확장의 관계입니다. SystemVerilog는 Verilog를 포함하면서 always_ff, logic, interface처럼 설계 의도를 분명히 하는 문법과, 클래스, 무작위 생성, 어서션, 커버리지 같은 검증 기능을 더했죠. 실무에서는 설계에 합성 가능한 범위를, 검증에 SystemVerilog 전체를 쓰는 방식이 일반적입니다.

기본 공구 상자에 전동 공구 세트가 더해져도 망치를 쥐는 법은 여전히 중요하듯, 새 문법보다 먼저 하드웨어가 동시에 동작한다는 감각을 익혀야 합니다. 그 위에 SystemVerilog의 검증 기능을 하나씩 쌓아 가면 설계와 검증 어느 쪽으로도 길이 열립니다.

면접 대비 질문

면접 대비 질문블로킹 대입과 논블로킹 대입의 차이를 설명하고, 순차 회로에서 논블로킹 대입을 써야 하는 이유를 말해 보세요.

[답변 포인트] 블로킹 대입(=)은 같은 블록 안에서 문장 순서대로 즉시 값이 바뀌고, 논블로킹 대입(<=)은 오른쪽 값을 모두 먼저 계산한 뒤 블록 끝에서 한꺼번에 갱신된다는 차이를 설명합니다. 플립플롭들은 같은 클록 에지에서 동시에 값을 받아야 하므로, 논블로킹 대입을 써야 시뮬레이션 결과가 실제 하드웨어와 일치한다는 점을 짚습니다. 예로 두 레지스터의 값을 맞바꾸는 코드에서 블로킹 대입을 쓰면 두 값이 같아지는 문제를 들면 좋습니다.