pp.549-551
ここでは、想定されるすべてのケースのうち3つのみをテストする(テキストにはないダイム、ダイムを足した)。
library ieee; use ieee.std_logic_1164.all; entity vending_machine_fsm_tb is end; architecture testbench of vending_machine_fsm_tb is signal clock: std_ulogic := '0'; signal reset: std_ulogic; signal nickel_in: std_ulogic; signal dime_in: std_ulogic; signal dispense: std_ulogic; signal amount: std_ulogic_vector(3 downto 0); constant CLOCK_PERIOD: time := 20 ns; -- 50 MHz constant COMBINATIONAL_DELAY: time := 6 ns; begin duv: entity work.vending_machine_fsm port map ( clock => clock, reset => reset, nickel_in => nickel_in, dime_in => dime_in, dispense => dispense, amount => amount ); -- 50 MHzクロックを生成 clock <= not clock after CLOCK_PERIOD / 2; test_sequencer: process type test_data_type is record nickel: std_logic; dime: std_logic; dispense: std_logic; amount: std_logic_vector(3 downto 0); end record; type test_data_array_type is array (natural range <>) of test_data_type; -- クロック立ち上がりを待ってさらに信号が落ち着くのを少し待つためのプロシージャ procedure wait_clock_edge is begin wait until rising_edge(clock); wait for COMBINATIONAL_DELAY; end; -- デフォルト状態(全部ゼロ)にしてから少し待つためのプロシージャ procedure reset_with_default_inputs is begin nickel_in <= '0'; dime_in <= '0'; reset <= '0'; wait_clock_edge; end; -- 全体をリセットして初期状態にあるかどうかを確かめるためのプロシージャ procedure test_reset is begin report "test_reset"; reset_with_default_inputs; assert dispense = '0' report "dispense IS NOT 0 following reset" severity failure; assert amount = "0000" report "amount IS NOT 0000 following reset" severity failure; end; -- テストデータをDUVに与えるとともに、期待値と実際の出力とを照合するためのプロシージャ procedure test_input_sequence(name: string; seq: test_data_array_type) is begin report "test_input_sequence: " & name; reset_with_default_inputs; for i in seq'range loop -- テストデータをDUVに与えてクロックを待つ、をテストデータの数だけ繰り返す。 nickel_in <= seq(i).nickel; dime_in <= seq(i).dime; wait_clock_edge; -- 期待値とDUVの出力とを照合する。 assert dispense = seq(i).dispense report "dispense IS NOT " & to_string(seq(i).dispense) severity failure; assert amount = seq(i).amount report "amount IS NOT " & to_string(seq(i).amount) severity failure; end loop; end; begin test_reset; -- 全体をリセットして初期状態にあるかどうかを確かめて、 test_input_sequence( name => "nickel, nickel, nickel", -- これが、ニッケルを3回連続して投入するときのテストデータと期待値 seq => ( (nickel => '1', dime => '0', dispense => '0', amount => 4d"05"), (nickel => '1', dime => '0', dispense => '0', amount => 4d"10"), (nickel => '1', dime => '0', dispense => '1', amount => 4d"15"), (nickel => '0', dime => '0', dispense => '0', amount => 4d"00") ) ); test_input_sequence( name => "nickel, dime", -- これが、ニッケル、ダイムの順に投入するときのテストデータと期待値 seq => ( (nickel => '1', dime => '0', dispense => '0', amount => 4d"05"), (nickel => '0', dime => '1', dispense => '1', amount => 4d"15"), (nickel => '0', dime => '0', dispense => '0', amount => 4d"00") ) ); test_input_sequence( name => "dime, dime", -- これが、ダイム、ダイムの順に投入するときのテストデータと期待値 seq => ( (nickel => '0', dime => '1', dispense => '0', amount => 4d"10"), (nickel => '0', dime => '1', dispense => '1', amount => 4d"15"), (nickel => '0', dime => '0', dispense => '0', amount => 4d"00") ) ); report "End of testbench. All tests completed successfully."; std.env.finish; end process; end;
実行結果: