19.4.5 RAM Memories / 非公式訳

pp.515-516

RAMは、排列信号、排列変数のどちらを使っても簡単に記述できます。合成ツールは一般に、排列がRAMとして使われていればそのことが認識できるため、適切なハードウェア構造を導き出してくれます。合成ツールは、適切なハードウェア構造を導き出したあと、書き込み先のFPGAで利用できるしかるべきハードウェアエレメントを選んで各メモリーを実装します。しかし設計者は、モデルを記述する前に、書き込み先のFPGAで利用できるメモリー構造の種類を確認しておくことが望ましい。専用のハードウェア構造でサポートされていない何らかの挙動(一部のFPGAにある非同期メモリー読み出しなど)をモデル化する場合は、強制的に論理回路リソースでメモリーが実装されます。

リスト19.3のコードは、同期読み出し・同期書き込みRAMの一例です。

リスト19.3 同期読み出し・同期書き込みRAM

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity RAM_test is
    generic (
        ADDRESS_WIDTH: natural := 8;
        DATA_WIDTH: natural := 8
    );
    port (
        clock: in std_logic;
        address: in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
        write_enable: std_logic;
        data_in: in std_logic_vector(DATA_WIDTH-1 downto 0);
        data_out: out std_logic_vector(DATA_WIDTH-1 downto 0)
    );
end entity;

architecture rtl of RAM_test is
    constant RAM_DEPTH: natural := 2**ADDRESS_WIDTH;
    
    type ram_contents_type is array (natural range <>) of std_logic_vector;
    signal ram_contents: ram_contents_type (0 to RAM_DEPTH-1)(DATA_WIDTH-1 downto 0);
    
    signal address_int: natural range 0 to RAM_DEPTH-1;
begin
    address_int <= to_integer(unsigned(address));

    process(clock)
    begin
        if rising_edge(clock) then
            data_out <= ram_contents(address_int);
            if write_enable then
                ram_contents(address_int) <= data_in;
            end if;
        end if;
    end process;
    
end architecture;

―――――――――――――――――――――――――――――
訳註: ここで作ったRAMは
DATA_WIDTH × RAM_DEPTH
= 8ビット × 256個 = 2048ビット
のメモリーを消費する。すべてメモリーブロックに配置された。LEの消費量は1個だけであった。