반도체 설계의 중심에는 RTL(Register Transfer Level) 설계가 있습니다. RTL은 하드웨어의 동작을 ‘데이터가 레지스터 사이를 어떻게 이동하고 처리되는가’라는 관점에서 기술하는 설계 방식입니다. 이 RTL을 기술할 때 주로 사용되는 대표적인 언어는 Verilog HDL입니다.
RTL이란 무엇인가
RTL(Register Transfer Level)은 하드웨어를 추상화하여 설계하는 표현 단계입니다. 트랜지스터 수준(Transistor Level)보다 한 단계 위, 그리고 알고리즘 수준(System Level)보다 한 단계 아래의 수준에서 하드웨어를 기술합니다.
즉, RTL은 다음 두 가지를 중심으로 동작합니다.
- 데이터가 저장되는 위치(Register)
- 데이터가 전송(Transfer)되는 경로 및 제어 로직
이 단계에서 설계자는 동작을 클록(Clock)과 리셋(Reset) 신호를 기준으로 기술하며, 이후 합성(Synthesis) 툴이 이렇게 설계된 RTL을 게이트 회로로 변환합니다. 따라서 RTL은 “하드웨어 구현을 위한 설계도”라고 할 수 있습니다.
Verilog 설계의 기본 구조
Verilog로 RTL을 작성할 때는 기본적으로 모듈(Module) 단위로 구성됩니다.
module counter (
input clk,
input resetn,
output reg [3:0] count
);
always @(posedge clk or negedge resetn) begin
if (!resetn)
count <= 4'b0000;
else
count <= count + 1;
end
endmodule
위 RTL은 가장 기본적인 4비트 동기식 카운터를 구현한 것 입니다.
여기서 핵심은 다음과 같습니다.
- always 블록: 클록이나 입력 조건에 따라 동작하는 하드웨어 블록
- posedge clk: 상승 엣지에서 트리거되는 동기 회로
- non-blocking 할당(
<=): 레지스터 갱신 시 사용
Verilog는 단순한 프로그래밍 언어가 아니라, 병렬 동작하는 하드웨어의 구조를 기술하는 언어입니다.
조합 논리와 순차 논리의 구분
RTL 설계에서 가장 중요한 개념은 조합 논리(Combinational Logic)와 순차 논리(Sequential Logic)의 구분입니다. 처음 RTL 설계를 하시는 엔지니어 분들이 많이 혼란을 겪게 되는 부분입니다.
- 조합 논리: 입력이 바뀌면 즉시 출력이 바뀌는 회로
- 예: 산술 연산기(ALU), 비교기
- Verilog 예시:
assign sum = a + b;
- 순차 논리: 클록 신호에 따라 상태가 저장되는 회로
- 예: 레지스터, 상태 머신(FSM)
- Verilog 예시:
always @(posedge clk) q <= d;
이 두 가지 논리를 명확히 이해하고 구분해서 사용하지 않으면 합성 결과가 예기치 않게 변형되거나, 시뮬레이션과 실제 하드웨어가 불일치하는 문제가 발생할 수 있습니다.
좋은 RTL 설계의 핵심 원칙
실무에서 효율적이고 합성에 친화적인 RTL을 작성하려면 아래 네 가지 원칙을 지켜야 합니다.
- 동기식 설계(Synchronous Design)
모든 상태 변화는 클록 엣지에서만 바뀌도록 설계해야 합니다.
비동기식 로직은 타이밍 문제와 글리치(glitch)를 발생시킬 수 있습니다. - 리셋 처리 명확화
모든 플립플롭은 리셋 조건을 명확히 정의해야 합니다.
리셋이 불명확하여 초기화가 제대로 진행되지 않으면 원치 않은 동작을 하는 칩을 만날 수 있습니다. - 블로킹(
=) vs 논블로킹(<=) 구분
조합 논리에는 블로킹, 순차 논리에는 논블로킹 할당을 사용해야 합니다.
이는 설계의 정확성과 합성 결과에 직접적인 영향을 줍니다. - 코딩 가이드라인 준수
Naming, indentation, comment 규칙을 일관되게 적용해 다른 엔지니어와의 협업 효율을 높입니다.
FSM(Finite State Machine) 설계 원리
많은 디지털 회로는 “상태”를 기반으로 동작합니다. 많은 데이터 통신 제어기나 프로토콜 핸들러는 유한 상태 기계(FSM) 형태로 구현됩니다.
Verilog로 FSM을 설계할 때는 보통 다음과 같은 구조를 사용합니다.
always @(posedge clk or negedge resetn) begin
if (!resetn)
state <= IDLE;
else begin
case (state)
IDLE: if (start) state <= RUN;
RUN: if (done) state <= IDLE;
endcase
end
end
FSM 설계 시 주의할 점은 모든 상태 전이가 정의되어야 하며, 항상 디폴트(default) 상태를 명시해야 시뮬레이션 및 합성 시 오류를 방지할 수 있습니다.
합성 친화적 설계와 검증
RTL 설계는 합성을 전제로 하므로 시뮬레이션에서는 정상적으로 동작을 하는 것 처럼 보이더라도 합성을 거쳐서 실제 하드웨어를 만들 었을 때는 다르게 동작할 수 있습니다. 따라서 합성 친화적인 코딩 스타일이 매우 중요합니다.
- 비합성 요소(
#delay,$display,initial블록 등)는 실제 회로에 반영되지 않습니다. - 비결정적 신호(
x,z)는 검증에서는 유용하지만 합성 시 제거됩니다. - 정적 타이밍 분석(STA)과 연계해 타이밍 제약을 동시에 고려해야 합니다.
RTL 검증 단계에서는 Testbench를 작성해 다양한 입력 케이스를 시뮬레이션하며 기능 커버리지(Function Coverage)를 통해 테스트의 완전성을 확인합니다.