19.4.4 ROM Memories / 非公式訳

動かしてわかる CPUの作り方10講, p.196のリストは下の「定数排列を使う方法」でプログラムメモリーを構築している。
 

pp.513-515

ROMをモデル化する方法は2つあります。1つは定数排列を使う方法、もう1つはcase文を使う方法です。リスト19.1に、排列を使ってROMをモデル化する方法を示します。

リスト19.1 定数排列を使ってROMをモデル化

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

entity ROM_test is
    port (
        clock: in std_logic;
        address: in unsigned(3 downto 0);
        data_out: out unsigned(7 downto 0)
    );
end entity;

architecture rtl of ROM_test is
    signal data_out_int: natural range 0 to 255;
    type rom_contents_type is array (natural range <>) of integer range 0 to 255;
    constant rom_contents: rom_contents_type := (
        10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160
    );
begin
    data_out <= to_unsigned(data_out_int, data_out'length);
    process (clock)
    begin
        if rising_edge(clock) then
            data_out_int <= rom_contents(to_integer(address));
        end if;
    end process;
end architecture;

この方法の利点の1つは定数をパッケージに記述できることです。そうすれば、(略)。

ROMをモデル化するもう1つの方法はcase文を使う方法です。この場合、ROMオブジェクトへの割り当てはすべて、1つのcase文の中で実行することが望ましい(リスト19.2)。

リスト19.2 case文を使ってROMをモデル化

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

entity ROM_test is
    port (
        clock: in std_logic;
        address: in unsigned(3 downto 0);
        data_out: out unsigned(7 downto 0)
    );
end entity;

architecture rtl of ROM_test is
    signal address_int: natural range 0 to 15;
    signal data_out_int: natural range 0 to 255;
begin
    address_int <= to_integer(unsigned(address));
    data_out <= to_unsigned(data_out_int, data_out'length);

    process (clock)
    begin
        if rising_edge(clock) then
            case address_int is
                when 0 => data_out_int <= 10;
                when 1 => data_out_int <= 20;
                when 2 => data_out_int <= 30;
                when 3 => data_out_int <= 40;
                when 4 => data_out_int <= 50;
                when 5 => data_out_int <= 60;
                when 6 => data_out_int <= 70;
                when 7 => data_out_int <= 80;
                when 8 => data_out_int <= 90;
                when 9 => data_out_int <= 100;
                when 10 => data_out_int <= 110;
                when 11 => data_out_int <= 120;
                when 12 => data_out_int <= 130;
                when 13 => data_out_int <= 140;
                when 14 => data_out_int <= 150;
                when 15 => data_out_int <= 160;
            end case;
        end if;
    end process;
end architecture;

一般に合成ツールは上記のようなコードから自動的にROMが合成できます。しかし場合によっては、rom_block属性やツールベンダーの指定する別の属性など、合成属性(セクション19.6 に示す)を使って合成ツールにヒントを与える必要があります。