지난 1편에서 SRAM의 포트 구조와 기본 개념을 다뤘다면, 이번에는 ‘실전 코드(RTL)’의 영역입니다.
단순히 reg를 선언해서 툴이 알아서 만들어주기를 바라는 방식(Inference)은 편하지만, 정밀한 제어가 어렵습니다. 때문에 숙련된 FPGA 엔지니어나 ASIC 설계자는 제조사가 제공하는 메모리 매크로(Macro)를 직접 인스턴스(Instantiation)하여 사용합니다.
이번 글에서는 FPGA(Xilinx XPM)와 ASIC(Foundry Library) 환경에서 각각 메모리를 인스턴스하는 코드를 1:1로 비교해 보고, 그 속에 숨겨진 결정적인 차이점들을 분석해 보겠습니다.
1. FPGA 방식: XPM 매크로 인스턴싱 (Xilinx 예시)
최신 Xilinx FPGA 설계에서는 IP Catalog(GUI)를 쓰지 않고, 코드 내에서 XPM(Xilinx Parameterized Macro)을 직접 불러 쓰는 추세입니다. 이 방식은 ASIC 라이브러리를 갖다 쓰는 것과 구조적으로 매우 비슷합니다.
하지만 핀(Pin)의 구성을 잘 확인해야 합니다.
// 1. FPGA Style: XPM Instantiation
// Xilinx에서 제공하는 표준 매크로를 직접 인스턴싱합니다.
module fpga_sram_wrapper (
input wire clk,
input wire en, // Active High
input wire we, // Active High
input wire [10:0] addr,
input wire [31:0] wdata,
output wire [31:0] rdata
);
// xpm_memory_spram: Xilinx Single Port RAM Macro
xpm_memory_spram #(
// --- Parameters (기능 설정) ---
.MEMORY_SIZE (2048 * 32), // 용량 (Bit 단위)
.MEMORY_PRIMITIVE ("block"), // BRAM 사용
.READ_LATENCY (1), // Output Register 사용 (1 cycle)
.WRITE_DATA_WIDTH_A (32),
.READ_DATA_WIDTH_A (32),
.ADDR_WIDTH_A (11)
) u_xpm_sram (
// --- Functional Ports (Active High 위주) ---
.clka (clk),
.rsta (1'b0), // Reset (사용 안 함, 사용할 때도 있)
.ena (en), // Enable: Active High ('1'일 때 동작)
.wea (we), // Write Enable: Active High
.addra (addr),
.dina (wdata),
.douta (rdata)
);
endmodule특징: 파라미터(Parameter)를 통해 용량과 레이턴시를 설정하며, 제어 신호(ena, wea)가 Active High로 설계되어 있습니다.
2. ASIC 방식: 파운드리 라이브러리 인스턴스
반면, 파운드리(TSMC, Samsung, GF 등)의 Memory Compiler로 생성한 ASIC 메모리는 형태는 비슷해 보이지만, 물리적 제어 핀들이 전면에 드러납니다.
// 2. ASIC Style: Vendor Library Instantiation
// 파운드리 28nm 공정의 블랙박스 모델을 연결합니다.
module asic_sram_wrapper (
input wire clk,
input wire user_en, // 사용자는 Active High를 원함
input wire user_we, // 사용자는 Active High를 원함
input wire [10:0] user_addr,
input wire [31:0] user_wdata,
output wire [31:0] user_rdata
);
// ASIC SRAM 인스턴싱 (Vendor Specific Name)
// SP_HD_RVT_2048x32: Single Port, High Density, Regular VT
SP_HD_RVT_2048x32 u_sram_macro (
// --- Functional Pins (주의: Active Low!) ---
.CLK (clk),
.CEN (~user_en), // Chip Enable (Active Low) -> 반전 필요!
.WEN (~user_we), // Global Write Enable (Active Low) -> 반전 필요!
.A (user_addr),
.D (user_wdata),
.Q (user_rdata),
// --- Physical / Yield Pins (수율/전압 제어) ---
.EMA (3'b010), // Extra Margin Adjustment (전압 마진 조절)
.EMAW (2'b00), // Write Assist Setting
.RET1N (1'b1) // Retention Mode (1=Normal, 0=Sleep)
);
endmodule두 코드 모두 ‘인스턴스’ 방식을 사용했지만, 그 내용은 확연히 다릅니다. 핵심적인 차이 3가지를 분석해 봅시다.
3. 핵심 차이점 ①: 파라미터 vs 하드코딩
FPGA의 XPM 코드를 보면 .MEMORY_SIZE 같은 파라미터(Parameter)가 있습니다.
- FPGA: 엔지니어가 코드 상에서 숫자를
2048에서4096으로 바꾸기만 하면, 합성 툴이 알아서 내부적으로 BRAM 자원을 2개, 4개로 늘려서 붙여줍니다. 매우 유연합니다. - ASIC: 코드 상에 파라미터가 없습니다.
SP_HD_RVT_2048x32라는 이름 자체가 이미 만들어진(Hardened) 물리적 덩어리입니다. 용량을 바꾸고 싶다면 Memory Compiler를 다시 돌려서 새로운 이름의 라이브러리를 받아와야 합니다.
4. 핵심 차이점 ②: 극성의 반전 (Polarity Trap)
가장 큰 함정은 제어 신호의 극성입니다.
- FPGA (
ena,wea): XPM 매뉴얼을 보면 기본적으로 Active High입니다. “Enable=1″일 때 켜집니다. 직관적입니다. - ASIC (
CEN,GWEN): 대부분의 상용 SRAM은 Active Low를 사용합니다.- 위 코드의
~user_en을 보시면, ASIC 라이브러리의CEN(Chip Enable) 핀은 ‘0’일 때 동작하므로, 사용자의 ‘1’ 신호를 반드시 NOT(~)으로 뒤집어서 넣어줘야 합니다. - 이 실수는 ASIC porting 과정에서 가장 빈번하게 발생하는 실수입니다.
- 위 코드의
5. 핵심 차이점 ③: 추상화 뒤에 숨은 물리 핀 (EMA, DFT)
FPGA 코드(XPM)에는 없지만 ASIC 코드에는 있는 핀들이 있습니다. 바로 칩의 수율(Yield)과 테스트(Test)를 위한 핀들입니다.
- EMA (Extra Margin Adjustment): 공정 미세화로 인해 칩마다 성능 편차가 생길 때, 이 핀의 값을 조절(예:
3'b010->3'b011)하여 SRAM 내부 타이밍 마진을 강제로 늘립니다. 죽은 칩을 살려내는 ‘심폐소생술’ 핀입니다.
6. 마무리
FPGA의 XPM 인스턴싱과 ASIC의 Standard Cell 인스턴싱은 겉보기에 비슷해 보이지만, “유연함(FPGA) vs 최적화(ASIC)”라는 명확한 차이를 보여줍니다.
FPGA 엔지니어가 ASIC 설계를 시작할 때, 단순히 “SRAM 모듈 이름만 바꾸면 되겠지”라고 생각하면 오산입니다. CEN의 극성을 확인하고, EMA 값을 데이터시트에서 찾아 넣는 등 물리적인 스펙(Physical Spec)을 꼼꼼히 챙기는 자세가 필요합니다.
참고: AMD