クロック同期回路のためのテストベンチ / UART RXモジュール / モジュラーテストベンチ

pp.544-547

前回は、テストデータの生成と、DUVを動かすための低レベル処理とがごっちゃになっていた。今度は、DUVと直接やり取りする働きをdriverに担わせる。

↓ これがテストベンチ:

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

entity uart_rx_tb is
end;

architecture testbench of uart_rx_tb is
    signal reset: std_logic;
    signal clock: std_logic := '0';
    signal rxd: std_logic := '1';
    signal rx_strobe: std_logic;
    signal rx_data: std_logic_vector(7 downto 0);

   -- Interface signals between the stimulus and driver processes
    signal transaction_data: std_logic_vector(7 downto 0);
    signal transaction_done: boolean;

    constant BIT_INTERVAL: time := 8.7 us;
    constant BYTE_RX_TIMEOUT: time := 11 * BIT_INTERVAL;
begin
    duv: entity work.uart_rx port map(
        clock => clock,
        reset => reset,
        rx_data => rx_data,
        rx_strobe => rx_strobe,
        rxd => rxd
        );

    clock <= not clock after 5 ns;
    reset <= '1', '0' after 20 ns;

    stimuli_generator: process
    begin
        wait until not reset;

       -- Send to the driver all characters from 0-255, one at a time
        for i in 0 to 255 loop
           -- Writing to signal send_data resumes the driver process
            transaction_data <= std_logic_vector(to_unsigned(i, 8));
           -- Wait until driver has completed the transmit operation
           -- driverプロセスの処理が終わるのを待ってループを繰り返す。
            wait on transaction_done'transaction;
        end loop;

        wait for BIT_INTERVAL;
        report "End of testbench. All tests passed.";
        std.env.finish;
    end process;

   -- Convert the byte value on send_data to transitions on the rxd pin.
   -- Notifies completion with a transaction on send_done.
    driver: process
        variable tx_buffer: std_logic_vector(9 downto 0);
    begin
       -- Wait until stimulus generator requests a transmit operation
       -- テストデータがやってくるのを待ってプロセスを開始する。
        wait on transaction_data'transaction;

       -- Add stop and start bits, and send value one bit at a time
       -- ストップビット+テストデータ+スタートビットを作って、LSBから1ビットずつ送る。
        tx_buffer := '1' & transaction_data & '0';
        for i in tx_buffer'reverse_range loop
            rxd <= tx_buffer(i);
            wait for BIT_INTERVAL;
        end loop;

       -- DUVにテストデータを与え終えたらstimuli_generatorプロセスに合図を送る。
        transaction_done <= true; -- 何かをアサインすればいいだけなのでfalseでもよい。
    end process;

    response_checker: process
        variable expected_byte: std_logic_vector(7 downto 0);
    begin
       -- Make a copy of the high-level stimulus sent to the driver
        wait on transaction_data'transaction;
        expected_byte := transaction_data;

       -- Wait until the DUV acknowledges a reception or a timeout occurs
        wait until rx_strobe for BYTE_RX_TIMEOUT;

       -- Compare the actual and expected values of the DUV outputs
        assert rx_strobe /= '1'
            report "rx_strobe is 1"
            severity note;
        assert rx_strobe = '1'
            report "rx_strobe IS NOT 1"
            severity failure;

        assert rx_data /= expected_byte
            report "rx_data is " & to_string(rx_data)
            severity note;
        assert rx_data = expected_byte
            report "rx_data IS NOT " & to_string(rx_data)
            severity failure;
    end process;
end;

実行結果: