LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; library work; use work.mips_types.all; use work.mips_util_pkg.all; ENTITY tb_cam IS END tb_cam; ARCHITECTURE behavior OF tb_cam IS constant CLK_PERIOD : time := 10 ns; constant DATA_WIDTH : integer := 20; constant CAM_NUM_ENTRIES : integer := 32; signal CLK_O : std_logic := '1'; signal RST_O : std_logic := '1'; signal cam_we : std_logic := '0'; signal cam_re : std_logic := '0'; signal cam_vld : std_logic := '0'; signal cam_rdy : std_logic := '-'; signal cam_addr : unsigned(lg2(CAM_NUM_ENTRIES)-1 downto 0) := (others => '0'); signal cam_data : unsigned(DATA_WIDTH-1 downto 0) := (others => '0'); signal cam_hit : unsigned (CAM_NUM_ENTRIES-1 downto 0); signal cam_hit_vld : std_logic := '-'; BEGIN inst_cam: entity work.cam GENERIC MAP ( NUM_ENTRIES => CAM_NUM_ENTRIES, DATA_WIDTH => DATA_WIDTH, CAM_RAM_MAX_WIDTH => 15 ) PORT MAP ( rst => RST_O, clk => CLK_O, rdy => cam_rdy, re => cam_re, we => cam_we, vld => cam_vld, addr => cam_addr, din => cam_data, hit => cam_hit, hit_vld => cam_hit_vld ); CLK_GEN: process begin wait for CLK_PERIOD/2; CLK_O <= not CLK_O; end process; STIMULUS: process variable result : unsigned(31 downto 0); procedure cam_entry_write(index : integer; data : unsigned; valid : std_logic) is begin cam_data <= data; cam_addr <= to_unsigned(index, lg2(CAM_NUM_ENTRIES)); cam_vld <= valid; cam_we <= '1'; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_we <= '0'; end procedure cam_entry_write; procedure cam_lookup(data : unsigned) is begin cam_data <= data; cam_re <= '1'; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_re <= '0'; end procedure cam_lookup; begin wait for 6*CLK_PERIOD; RST_O <= '0'; wait for 60*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_entry_write(1, X"CAFE_1", '1'); cam_entry_write(2, X"CAFE_2", '1'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_lookup(X"CAFE_1"); cam_lookup(X"CAFE_2"); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; -- overwrite cam_entry_write(2, X"BEEF_2", '1'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; -- overwrite entry cam_entry_write(2, X"CAFE_2", '1'); -- new entry cam_entry_write(3, X"CAFE_3", '1'); cam_entry_write(4, X"CAFE_4", '1'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_entry_write(1, X"CAFE_1", '0'); cam_entry_write(2, X"CAFE_2", '0'); cam_entry_write(3, X"CAFE_3", '0'); cam_entry_write(4, X"CAFE_4", '0'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_lookup(X"BEEF_2"); cam_lookup(X"CAFE_1"); cam_lookup(X"CAFE_2"); cam_lookup(X"CAFE_3"); cam_lookup(X"CAFE_4"); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_entry_write(1, X"CAFE_1", '1'); cam_entry_write(2, X"CAFE_2", '1'); cam_entry_write(3, X"CAFE_3", '1'); cam_entry_write(4, X"CAFE_4", '1'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_lookup(X"CAFE_1"); cam_lookup(X"CAFE_2"); cam_lookup(X"CAFE_3"); cam_lookup(X"CAFE_4"); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; cam_entry_write(7, X"CAFE_7", '0'); wait for 8*CLK_PERIOD; wait until rising_edge(CLK_O) and cam_rdy = '1'; wait; end process; END;