組み合わせ論理回路のためのテストベンチ / リニアテストベンチ

(ModelSimの使いかたは動かしてわかる CPUの作り方10講, pp.154-159)
 

pp.530-536
下のモジュールは、入力された09の値に応じて7セグメントLED用の信号を出力する回路である。このモジュールのためのテストベンチを作る。

library ieee;
use ieee.std_logic_1164.all;

entity bcd_to_7seg is
    port (
        bcd: in std_logic_vector(3 downto 0);
        seven_seg: out std_logic_vector(6 downto 0)
    );
end;

architecture rtl of bcd_to_7seg is
begin
    with bcd select seven_seg <=
        "0111111" when x"0",
        "0000110" when x"1",
        "1011011" when x"2",
        "1001111" when x"3",
        "1100110" when x"4",
        "1101101" when x"5",
        "1111101" when x"6",
        "0000111" when x"7",
        "1111111" when x"8",
        "1101111" when x"9",
        "0000000" when others;
end;

↓ これがテストベンチ。1本の実行スレッドですべてが起こるため「リニアテストベンチ」と呼ばれる。

library ieee;
use ieee.std_logic_1164.all;
use std.env.finish;

-- ここでは「DUV名_tb」という名前にする。
entity bcd_to_7seg_tb is
-- テストベンチは閉じたシステムであり、自己完結的環境であるため入出力ポートはない。
end;

architecture testbench of bcd_to_7seg_tb is
   -- DUVとやりとりするのに必要な信号をすべて定義する。
   -- 混乱を避けるため、この信号名はDUVのポート名と同じにする。
    signal bcd: std_logic_vector(3 downto 0);
    signal seven_seg: std_logic_vector(6 downto 0);
begin
   -- workライブラリから目的のDUVを直接実体化する。
    duv: entity work.bcd_to_7seg
        port map(
            bcd => bcd,
            seven_seg => seven_seg
        );

    stimuli_and_checker: process
       -- 期待される入出力の関係を真理値表で記述する。
       -- 小さな真理値表は定数排列で指定するのがよい。
       -- ここでは入力、出力をrecordタイプとしてひとつにまとめた。
        type stimulus_response_type is record
            bcd: std_logic_vector(3 downto 0);
            seven_segment: std_logic_vector(6 downto 0);
        end record;

        type stimulus_response_array_type is array (natural range <>) of stimulus_response_type;

        constant TEST_DATA: stimulus_response_array_type := (
            (x"0", "0111111"),
            (x"1", "0000110"),
            (x"2", "1011011"),
            (x"3", "1001111"),
            (x"4", "1100110"),
            (x"5", "1101101"),
            (x"6", "1111101"),
            (x"7", "0000111"),
            (x"8", "1111111"),
            (x"9", "1101111"),
            (x"a", "0000000"),
            (x"b", "0000000"),
            (x"c", "0000000"),
            (x"d", "0000000"),
            (x"e", "0000000"),
            (x"f", "0000000")
        );

        constant TEST_PERIOD: time := 10 ms;
    begin
        for i in TEST_DATA'range loop
            report "Testing DUV with input " & to_string(TEST_DATA(i).bcd);
           -- テストベンチの真理値表の入力値をDUVの入力に与えて、
            bcd <= TEST_DATA(i).bcd;
            wait for TEST_PERIOD;

           -- テストベンチの真理値表の出力値とDUVの出力値とを比較する。
            assert seven_seg = TEST_DATA(i).seven_segment
                report "Error: DUV.seven_seg /= TEST_DATA.seven_seg"
                severity failure;
        end loop;

        report "End of testbench. All tests passed.";
        finish; -- finishプロシージャでシミュレーションを終える。終えなくてもよい。
    end process;
end;



――――――――――――――――――――――
ためしにDUVの"1101101" when x"5","1100001" when x"5",に変えた場合。severityfailureにしているのでシミュレーションが停止する。