[FPGA] Block memory 모듈 설정 및 사용 가이드

FPGA 합성 시에는 clock wiz(DCM)와 마찬가지로 memory도 vivado에서 block memory로 생성하여 bit를 생성합니다.

Block memory 생성 방법

먼저 Vivado 창의 가장 왼쪽의 Project manager에서 IP Catalog를 선택합니다.

vivado 메뉴에서 IP Catalog 선택
vivado 메뉴에서 IP Catalog 선택

IP Catalog를 선택하면 다음과 같은 창이 나오는데 memory를 검색하고 Block Memory Generator를 선택합니다.

IP Catalog 선택 시 나오는 창
IP Catalog 선택 시 나오는 창
Block Memory Generator 선택
모듈 선택

그러면 다음과 같은 창이 나옵니다. 여기서 memory의 옵션을 설정할 수 있습니다.

Block Memory 옵션 창
옵션 창

자, 이제 어떤 값을 어떻게 수정해야 할까요?? 그걸 알기 위해서는 우선 일반적인 ASIC architecture 설계에서 메모리 인스턴스가 어떻게 되어있는지 알아야 합니다.

input  wire        clk        ;
input  wire        data0_cs   ;
input  wire [10:0] data0_addr ;
input  wire [ 3:0] data0_we   ;
input  wire [31:0] data0_wdata;
output wire [31:0] data0_rdata;

spsram_2048x32 u_mem0 (
     .CLK     (clk         )
    ,.CEN     (~data0_cs   )
    ,.WEN     (~(|data0_we))
    ,.BWEN    (~data0_we   )
    ,.A       ( data0_addr )
    ,.D       ( data0_wdata)
    ,.Q       ( data0_rdata)
);
  • CLK: memory input clock
  • CEN: chip enable signal (active low)
  • WEN: write enable signal (active low)
  • BWEN: byte write enable signal (active low)
  • A: address signal
  • D: memory write(input) data
  • Q: memory read(output) data

여기서 주의 깊게 봐야 하는 건 memory의 type, we, width / depth입니다. 하나하나 살펴볼까요??

Memory type

대부분 메모리 인스턴스 이름에 나와 있습니다. 여기서는 spsram이라고 되어있는데요, 이는 single port ram이라는 뜻입니다. 그럼 다른 type은 어떤 게 있을까요?

  • single port ram (sp ram)
  • simple dual port ram (tp ram)
  • true dual port ram (dp ram)

각각 memory 들의 특징을 block diagram을 보면서 이해해 봅시다.

Single port ram(sp ram)

sp ram은 말 그대로 memory의 port가 하나(A)뿐인 memory입니다.

Single port ram block diagram
Single Port ram block diagram

Simple dual port ram (tp ram)

tp ram은 memory에 두 개의 memory port가 있지만(A, B) chip enable signal(ena)과 write enable signal(wea)을 두 port가 공유하고 있습니다. 그래서 한 port는 쓰기용으로, 다른 한 port는 읽기 용으로 사용합니다.

Simple Dual Port RAM block diagram
Simple Dual Port RAM block diagram

True dual port ram (dp ram)

dp ram은 두 개의 memory port(A, B) 모두 각각의 ena signal(ena, enb)과 wen signal(wea, web)이 있어서 모든 memory port가 읽기와 쓰기가 가능한 memory입니다. 그래서 tp ram과 다르게 dina, dinb, douta, doutb signal이 있는 것을 알 수 있습니다.

True Dual Port RAM block diagram

Write enable(we)

we를 이해하기 위해 memory의 port를 확인해 봅시다.

Memory u_mem0 (
     .clka       ()
    ,.ena        ()
    ,.wea        ()
    ,.addra      ()
    ,.dina       ()
    ,.douta      ()
);
  • addra: address signal
  • dina: memory write(input) data
  • douta: memory read(output) data

당연히 clk가 있고, en, we, addr, data_in, data_out이 있습니다. en은 enable이고 we는 write enable입니다. en은 1-bit signal이지만 we은 1-bit일 수도 있고 아닐 수도 있습니다. 왜냐하면 byte write를 할지 data width를 한 번에 write 할지 정할 수 있기 때문입니다. 만약 data_width가 32-bit라고 한다면 byte write enable을 할 때는 we는 4-bit signal이 될 것이고 byte write enable을 하지 않으면 we는 1-bit signal이 됩니다.

1-byte는 8-bit 또는 9-bit로 설정할 수 있고(근데 대부분 당연히 8-bit로 설정하겠죠?) byte write enable 설정을 하면 뒤에 나올 data width는 8(or 9) x n 만 입력할 수 있습니다. (ex 8-bit로 설정하면 data_width는 8, 16, 24, 32… 만 설정 가능)

여기까지 설정해 볼까요?

옵션 설정
옵션 설정

Width / Depth

width와 depth도 인스턴스 이름에 나와 있습니다. spsram_2048x32라고 되어있는데요, 여기서 2048이 depth, 32가 width입니다. depth와 width를 설정하면 memory의 addra, dina, douta가 자동으로 바뀝니다.

옵션 설정 후
옵션 설정 후

그럼 다음과 같이 수정하면 되겠네요.

input  wire        clk        ;
input  wire        data0_cs   ;
input  wire [10:0] data0_addr ;
input  wire [ 3:0] data0_we   ;
input  wire [31:0] data0_wdata;
output wire [31:0] data0_rdata;

`ifdef FPGA
spsram_2048x32_FPGA u_mem0_FPGA (
     .clka       (clk        )
    ,.ena        (data0_cs   )
    ,.wea        (data0_we   )
    ,.addra      (data0_addr )
    ,.dina       (data0_wdata)
    ,.douta      (data0_rdata)
);
`else
spsram_2048x32 u_mem0 (
     .CLK     (clk         )
    ,.CEN     (~data0_cs   )
    ,.WEN     (~(|data0_we))
    ,.BWEN    (~data0_we   )
    ,.A       ( data0_addr )
    ,.D       ( data0_wdata)
    ,.Q       ( data0_rdata)
);
`endif

ena, wea의 polarity는 정확하게 기억이 안나네요;;;; 죄송합니다. ㅠㅠ

ROM code(boot loader) setting

컴퓨터나 SoC는 ROM(Read-Only Memory)이 있어서 부트할 시에 ROM에 내장된 boot loader(부트로더)를 불러와 실행해야 합니다. 그러면 보드 test를 위해 bit 파일을 합성할 때는 이러한 boot loader를 어떻게 메모리 block에 넣을 수 있을까요?

그건 Memory Generator 설정에서 할 수 있습니다. 실행할 boot loader를 아래 그림과 같이 ‘Other options’에서 넣어줄 수 있습니다. ROM으로 사용할 block에서 해당 부트로더 파일을 load하고 bit를 합성하면 보드에 bit를 다운받자마자 정해진 프로그램이 실행됩니다.

Boot loader 설정
Boot loader 설정

참조: Xilinx Memory Generator Data sheet

Similar Posts