최신 모바일 기기와 IoT 디바이스에서 가장 중요한 spec은 무엇일까요? 성능도 중요하지만, 바로 배터리 수명(Battery Life)과 발열 관리입니다. 아무리 성능이 좋아도 1시간 만에 배터리가 방전되거나 손난로처럼 뜨거워지는 chip은 시장에서 살아남을 수 없습니다.
RTL 설계자가 “기능(Functionality)”만 검증하고 넘어가던 시대는 지났습니다. 이제는 전력 소모(Power Consumption)를 줄이는 디자인 스타일이 필수 역량이 되었습니다.
이번 글에서는 RTL 단계에서 적용할 수 있는 가장 효과적인 저전력 설계 기법인 Clock Gating과 Operand Isolation에 대해 다뤄보겠습니다.
1. 전력 소모의 공식: 우리가 줄일 수 있는 것은?
반도체의 소비 전력은 크게 동적 전력(Dynamic Power)과 정적 전력(Static Power)의 합으로 정의됩니다.
- Static Power (Leakage): 트랜지스터가 꺼져 있어도 새어 나가는 전류입니다. 이는 공정(Process) 기술이나 전압(Multi-Vt cell)에 크게 의존하므로 RTL 설계자가 제어하기 어렵습니다.
- Dynamic Power (Switching): 신호가 0에서 1로, 1에서 0으로 변할 때(Toggle) 발생하는 전력입니다. RTL 설계자가 줄여야 할 핵심 타겟입니다.
동적 전력의 공식은 다음과 같습니다.
- alpha (Activity Factor): 신호가 얼마나 자주 바뀌는가? (RTL 설계자의 핵심 타겟!)
- C (Capacitance): 부하 용량
- V (Voltage): 동작 전압
- f (Frequency): 동작 주파수
우리는 RTL 코드를 통해 불필요한 스위칭(α)을 0으로 만드는 것을 목표로 해야 합니다.
2. Low Power의 제왕: Clock Gating (클럭 게이팅)
디지털 회로에서 전력을 가장 많이 먹는 범인은 바로 Clock입니다. Clock tree는 chip 전체에 퍼져 있으며, 데이터가 변하지 않아도 매초 수억 번씩 진동하며 전력을 태웁니다.
(1) 문제 상황: MUX Feedback Loop
RTL에서 레지스터의 값을 유지(Hold)하기 위해 흔히 다음과 같이 코딩합니다.
// 데이터가 유효할 때만 값 업데이트, 아니면 유지
always @(posedge clk) begin
if (load_en) q <= data_in;
else q <= q; // 실제로는 MUX가 생성되어 출력(q)이 다시 입력으로 들어옴
end이 코드가 합성되면 Multiplexer(MUX)가 생성됩니다. 문제는 load_en이 0이라서 값이 변하지 않는 동안에도, Flip-Flop의 clock 핀에는 계속 clock이 공급된다는 점입니다.
(2) 해결책: Integrated Clock Gating (ICG)
데이터가 변할 필요가 없을 때는 아예 Flip-Flop에 공급되는 clock을 끊어버리는 것이 clock gating입니다.
하지만 단순히 AND 게이트로 clock을 막으면 글리치(Glitch)가 발생하여 오동작할 위험이 큽니다. 그래서 실무에서는 ICG (Integrated Clock Gating)라는 특수 셀을 사용합니다.
- 구조: Latch (Level-sensitive) + AND Gate
- 원리: Latch가 clock의 Low 구간에서 Enable 신호를 미리 잡아두어, clock의 High 구간 중간에 Enable이 변해도 글리치가 생기지 않도록 막아줍니다.
(3) RTL 코딩 가이드
다행히 최신 합성 툴(Design Compiler 등)은 우리가 코드를 잘 짜기만 하면 알아서 ICG 셀을 넣어줍니다. 이를 Auto Clock Gating이라고 합니다.
// [Good] Auto Clock Gating이 가능한 코드 스타일
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
q <= 0;
end else begin
if (load_en) begin // 이 조건문이 ICG의 Enable 신호가 됨
q <= data_in;
end
// else 구문이 없으면 '값 유지'로 판단하여 툴이 ICG를 삽입함
end
endTip: if (en) 조건문 하나가 32비트 레지스터 전체의 clock을 멈출 수 있습니다. 이는 엄청난 전력 절감 효과를 가져옵니다.
3. 무거운 연산 막기: Operand Isolation (데이터 게이팅)
클럭 다음으로 전력을 많이 먹는 것은 곱셈기(Multiplier), 덧셈기(Adder) 같은 연산기(Datapath)입니다.
(1) 문제 상황
assign result = a * b; // 곱셈기위 코드는 a나 b가 변할 때마다 곱셈기 내부의 수많은 게이트가 스위칭을 합니다. 만약 지금 이 result 값을 쓰지 않는 상황이라도(예: MUX에 의해 다른 값을 선택 중이라도), 입력이 변하면 곱셈기는 헛심을 쓰며 전력을 소모합니다.
(2) 해결책: 입력을 0으로 고정하기
연산 결과가 필요 없을 때는 입력단(a, b)의 값을 변하지 않게 막아버리는 기법입니다. 이를 Operand Isolation이라고 합니다.
// [Concept Code]
wire [31:0] a_gated, b_gated;
// valid 신호가 0이면 입력을 0으로 고정 (AND 게이트 활용)
assign a_gated = a & {32{valid}};
assign b_gated = b & {32{valid}};
assign result = a_gated * b_gated;이렇게 하면 valid가 0일 때 곱셈기 내부의 스위칭 액티비티(Switching Activity)가 0이 되어 전력을 아낄 수 있습니다. 최신 합성 툴들은 이 역시 자동으로 수행해 주기도 하지만, 복잡한 로직에서는 설계자가 직접 의도를 가지고 코딩해 주는 것이 좋습니다.
4. 결론: “동작하는 칩”을 넘어 “좋은 칩”으로
RTL 설계자가 만든 코드 한 줄이 수백만 개의 트랜지스터를 움직입니다. load_en 신호를 꼼꼼하게 설계하여 Clock Gating 효율을 높이고, 불필요한 연산이 일어나지 않도록 데이터 흐름을 제어하는 것. 이것이 바로 High Quality RTL의 핵심입니다.