VHDL - How should I create a clock in a testbench?

后端 未结 4 1478
你的背包
你的背包 2021-01-30 17:57

How should I create a clock in a testbench? I already have found one answer, however others on stack overflow have suggested that there are alternative or better ways of achievi

4条回答
  •  半阙折子戏
    2021-01-30 18:23

    How to use a clock and do assertions

    This example shows how to generate a clock, and give inputs and assert outputs for every cycle. A simple counter is tested here.

    The key idea is that the process blocks run in parallel, so the clock is generated in parallel with the inputs and assertions.

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity counter_tb is
    end counter_tb;
    
    architecture behav of counter_tb is
        constant width : natural := 2;
        constant clk_period : time := 1 ns;
    
        signal clk : std_logic := '0';
        signal data : std_logic_vector(width-1 downto 0);
        signal count : std_logic_vector(width-1 downto 0);
    
        type io_t is record
            load : std_logic;
            data : std_logic_vector(width-1 downto 0);
            count : std_logic_vector(width-1 downto 0);
        end record;
        type ios_t is array (natural range <>) of io_t;
        constant ios : ios_t := (
            ('1', "00", "00"),
            ('0', "UU", "01"),
            ('0', "UU", "10"),
            ('0', "UU", "11"),
    
            ('1', "10", "10"),
            ('0', "UU", "11"),
            ('0', "UU", "00"),
            ('0', "UU", "01")
        );
    begin
        counter_0: entity work.counter port map (clk, load, data, count);
    
        process
        begin
            for i in ios'range loop
                load <= ios(i).load;
                data <= ios(i).data;
                wait until falling_edge(clk);
                assert count = ios(i).count;
            end loop;
            wait;
        end process;
    
        process
        begin
            for i in 1 to 2 * ios'length loop
                wait for clk_period / 2;
                clk <= not clk;
            end loop;
            wait;
        end process;
    end behav;
    

    The counter would look like this:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all; -- unsigned
    
    entity counter is
        generic (
            width : in natural := 2
        );
        port (
            clk, load : in std_logic;
            data : in std_logic_vector(width-1 downto 0);
            count : out std_logic_vector(width-1 downto 0)
        );
    end entity counter;
    
    architecture rtl of counter is
        signal cnt : unsigned(width-1 downto 0);
    begin
        process(clk) is
        begin
            if rising_edge(clk) then
                if load = '1' then
                    cnt <= unsigned(data);
                else
                    cnt <= cnt + 1;
                end if;
            end if;
        end process;
        count <= std_logic_vector(cnt);
    end architecture rtl;
    

    Related: https://electronics.stackexchange.com/questions/148320/proper-clock-generation-for-vhdl-testbenches

提交回复
热议问题