0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

単純かつ小容量の DPRAM(Dual Port RAM) を VHDL で記述(その1)

0
Last updated at Posted at 2026-05-02

はじめに

この記事では比較的単純で小容量の DPRAM(Dual Port RAM) を VHDL で記述して、AMD(旧Xilinx) の FPGA に実装してみた例を紹介します。
というのも、AMD(旧Xilinx) の FPGA にロジックを実装するための CLB(Configurable Logic Block)があり、各 CLB には6入力1出力の LUT(LookUp Table) と呼ばれるものがあります。この LUT はロジックを実装する他に、64word ×1bit のメモリとして使うことが出来ます。
はるか昔のツールでは特殊な記述方法でなければ、LUT メモリを使えなかったのですが、今時のツールならば適当に記述しても上手く実装してくれるみたいです。
そこで幾つか DPRAM を VHDL で記述してみて、その実装結果を確認してみました。この記事はその第一弾です。

リポジトリ

この記事で紹介している VHDL のソースコードや、Vivado でシミュレーションやIP の生成やサンプルデザインの実装を行うための各種スクリプトは以下の Github のリポジトリにて公開しています。

記述例その1

VHDL による記述

Entity

この記事で紹介する VHDL のモジュールは次のような entity になっています。

src/main/vhdl/dpram.vhd
entity DPRAM is
    generic (
        DATA_BITS   : integer := 32;
        ADDR_BITS   : integer :=  6;
        N           : integer :=  1
    );
    port (
        WCLK        : in  std_logic;
        WE          : in  std_logic_vector(N        -1 downto 0);
        WADDR       : in  std_logic_vector(ADDR_BITS-1 downto 0);
        WDATA       : in  std_logic_vector(DATA_BITS-1 downto 0);
        RADDR       : in  std_logic_vector(ADDR_BITS-1 downto 0);
        RDATA       : out std_logic_vector(DATA_BITS-1 downto 0)
    );
end DPRAM;

DATA_BITS でデータのビット幅、ADDR_BITS でアドレスのビット幅を指定します。
N は書き込むデータのグループ数を指定します。
例えば、DATA_BITS=32 かつ N=4 ならば、この DPRAM はバイト単位で書き込むことが出来ます。

Architecture

DPRAM のアーキテクチャの実装例を示します。ここではアーキテクチャの名前を MODEL_0 としています。

src/main/vhdl/dpram_model_0.vhd
library ieee;
use     ieee.std_logic_1164.all;
use     ieee.numeric_std.all;
architecture MODEL_0 of DPRAM is
    constant  INDEX_MIN     :  integer := 0;
    constant  INDEX_MAX     :  integer := 2**ADDR_BITS-1;
    subtype   INDEX_TYPE    is integer range INDEX_MIN to INDEX_MAX;
    function  addr_to_index(ADDR: std_logic_vector) return INDEX_TYPE is
        alias     u_addr    :  std_logic_vector(ADDR'length-1 downto 0) is ADDR;
        variable  u_index   :  unsigned(u_addr'range);
    begin
        for i in u_index'range loop
            if (u_addr(i) = '1') then
                u_index(i) := '1';
            else
                u_index(i) := '0';
            end if;
        end loop;
        return to_integer(u_index);
    end function;
    constant  WORD_BITS     :  integer := DATA_BITS/N;
    subtype   DATA_TYPE     is std_logic_vector(DATA_BITS-1 downto 0);
    type      DATA_VECTOR   is array(integer range <>) of DATA_TYPE;
    signal    ram           :  DATA_VECTOR(INDEX_MIN to INDEX_MAX);
    signal    r_index       :  INDEX_TYPE;
    signal    w_index       :  INDEX_TYPE;
begin
    w_index <= addr_to_index(WADDR);
    r_index <= addr_to_index(RADDR);
    process (WCLK) begin
        if (WCLK'event and WCLK = '1') then
            for pos in DATA_TYPE'range loop
                if (WE(pos/WORD_BITS) = '1') then
                    ram(w_index)(pos) <= WDATA(pos);
                end if;
            end loop;
        end if;
    end process;
    RDATA  <= ram(r_index);
end MODEL_0;

Vivado による実装結果

サンプル IP

上記の DPRAM の実装例を使って簡単な AXI からアクセスするための IP を作りました。
IP のトップレベルは次の URL で示される VHDL で示します。

まずはこの IP を Vivado から使えるようにします。IP を作るスクリプトは以下にあります。

KV260 でのデザイン例

IP を使って KV260 用のデザインを作りました。デザインを実装するスクリプトは以下にあります。

下図にこのデザインのブロック図を示します。

Fig.1 axi_dpram_64x32_model_0 block design

AXI_DPRAM_64x32_0 のパラメーターは RAM_ADDR_WIDTH=6RAM_DATA_WDITH=32RAM_NUM=4 に設定しています。各々が DPRAM の ADDR_WIDTH、DATA_WIDTH、N に対応します。

Utlization

上記のデザインをインプリメンターションした際の Utlization(配置配線後のCLB/FFの利用状況)を下図に示します。

Fig.2 axi_dpram_64x32_model_0 utlization

LUT as Memory の所を参照すると、64 個の LUT を使っていることが確認できます。

Schematic

どのように DPRAM が実装されているかを schematic を使って確認しました。

一番左の図が DPRAM のブロックです。
それを展開したのが左から2番目の図です。なにやら下位モジュールが32個並んています。
左から2番目の図を拡大したのが右から2番目の図です。下位モジュールの名前が RAM64X1D というのが判ります。
一番右の図が RAM64X1D の中身です。RAMD64E というのが二つ並んでいます。
これ以上展開出来無いところをみると、どうやら RAMD64E というのがプリミティブのようです。これが LUT 一個分に相当すると思われます。

Fig.3 axi_dpram_64x32_model_0 schematic

まとめ

上記の VHDL の記述では、データのビット幅に対して2個の LUT が使われることがわかりました。
最近の Vivado では、適当に記述してもこのくらいの実装はしてくれるようです。
当初はこれで満足していたのですが、実はもっと良い実装方法があります。それを次の記事で紹介します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?