diff --git a/libraries/base/axi4/tb/vhdl/tb_axi4_lite_ram.vhd b/libraries/base/axi4/tb/vhdl/tb_axi4_lite_ram.vhd index 0200575c3d23547e3f9e22e7214dd9009778c82b..295b8d0fdcfff5abbd1b8be9cc75612e23cdc820 100644 --- a/libraries/base/axi4/tb/vhdl/tb_axi4_lite_ram.vhd +++ b/libraries/base/axi4/tb/vhdl/tb_axi4_lite_ram.vhd @@ -36,26 +36,25 @@ USE common_lib.common_pkg.ALL; USE common_lib.common_mem_pkg.ALL; USE work.axi4_lite_pkg.ALL; - ENTITY tb_axi4_lite_ram IS END tb_axi4_lite_ram; ARCHITECTURE tb OF tb_axi4_lite_ram IS - CONSTANT mm_clk_period : TIME := 40 ns; - CONSTANT usr_clk_period : TIME := 10 ns; + CONSTANT c_mm_clk_period : TIME := 40 ns; + CONSTANT c_usr_clk_period : TIME := 10 ns; CONSTANT c_reset_len : NATURAL := 16; - CONSTANT dat_w : INTEGER := 32; - CONSTANT adr_w : INTEGER := 8; + CONSTANT c_dat_w : INTEGER := 32; + CONSTANT c_adr_w : INTEGER := 8; CONSTANT c_mm_usr_ram : t_c_mem := (latency => 1, - adr_w => 5, - dat_w => 8, + c_adr_w => 5, + c_dat_w => 8, nof_dat => 32, init_sl => '0'); - CONSTANT ram_addr_base : NATURAL := to_integer(shift_right(to_unsigned(0, 32), ceil_log2(c_mm_usr_ram.nof_dat))) ; + CONSTANT c_ram_addr_base : NATURAL := to_integer(shift_right(to_unsigned(0, 32), ceil_log2(c_mm_usr_ram.nof_dat))) ; SIGNAL mm_rst : STD_LOGIC; SIGNAL mm_clk : STD_LOGIC := '0'; @@ -64,128 +63,122 @@ ARCHITECTURE tb OF tb_axi4_lite_ram IS SIGNAL sim_finished : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0'; - - SIGNAL rd_dat : STD_LOGIC_VECTOR(dat_w-1 DOWNTO 0); - SIGNAL wr_dat : STD_LOGIC_VECTOR(dat_w-1 DOWNTO 0); + SIGNAL rd_dat : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0); + SIGNAL wr_dat : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0); SIGNAL wr_val : STD_LOGIC; SIGNAL rd_val : STD_LOGIC; SIGNAL reg_wren : STD_LOGIC; SIGNAL reg_rden : STD_LOGIC; - SIGNAL wr_adr : STD_LOGIC_VECTOR(adr_w-1 DOWNTO 0); - SIGNAL rd_adr : STD_LOGIC_VECTOR(adr_w-1 DOWNTO 0); + SIGNAL wr_adr : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0); + SIGNAL rd_adr : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0); SIGNAL ram_wr_en : STD_LOGIC; SIGNAL ram_rd_en : STD_LOGIC; - SIGNAL ram_adr : STD_LOGIC_VECTOR(c_mm_usr_ram.adr_w-1 DOWNTO 0); - SIGNAL ram_rd_dat : STD_LOGIC_VECTOR(c_mm_usr_ram.dat_w-1 DOWNTO 0); + SIGNAL ram_adr : STD_LOGIC_VECTOR(c_mm_usr_ram.c_adr_w-1 DOWNTO 0); + SIGNAL ram_rd_dat : STD_LOGIC_VECTOR(c_mm_usr_ram.c_dat_w-1 DOWNTO 0); SIGNAL axi_copi : t_axi4_lite_copi; SIGNAL axi_cipo : t_axi4_lite_cipo; BEGIN - - - mm_clk <= NOT mm_clk OR sim_finished AFTER mm_clk_period/2; - mm_rst <= '1', '0' AFTER mm_clk_period*c_reset_len; - - usr_clk <= NOT usr_clk OR sim_finished AFTER usr_clk_period/2; - usr_rst <= '1', '0' AFTER usr_clk_period*c_reset_len; - - u_mem_to_axi4_lite : ENTITY work.mem_to_axi4_lite + mm_clk <= NOT mm_clk OR sim_finished AFTER c_mm_clk_period/2; + mm_rst <= '1', '0' AFTER c_mm_clk_period*c_reset_len; + + usr_clk <= NOT usr_clk OR sim_finished AFTER c_usr_clk_period/2; + usr_rst <= '1', '0' AFTER c_usr_clk_period*c_reset_len; + + u_mem_to_axi4_lite : ENTITY work.mem_to_axi4_lite + GENERIC MAP ( + g_c_adr_w => c_adr_w, + g_c_dat_w => c_dat_w) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + axi4_lite_in => axi_copi, + axi4_lite_out => axi_cipo, + wren => reg_wren, + rden => reg_rden, + wr_adr => wr_adr, + wr_dat => wr_dat, + wr_val => wr_val, + wr_busy => '0', + rd_adr => rd_adr, + rd_dat => rd_dat, + rd_busy => '0', + rd_val => rd_val + ); + + ram_wr_en <= reg_wren AND is_true(c_ram_addr_base = UNSIGNED(wr_adr(wr_adr'LENGTH-1 DOWNTO c_mm_usr_ram.c_adr_w))); + ram_rd_en <= reg_rden AND is_true(c_ram_addr_base = UNSIGNED(rd_adr(rd_adr'LENGTH-1 DOWNTO c_mm_usr_ram.c_adr_w))); + + ram_adr <= wr_adr(c_mm_usr_ram.c_adr_w-1 DOWNTO 0) WHEN ram_wr_en = '1' ELSE rd_adr(c_mm_usr_ram.c_adr_w-1 DOWNTO 0); + + u_ram : ENTITY common_lib.common_ram_crw_crw + GENERIC MAP ( + g_ram => c_mm_usr_ram, + g_true_dual_port => TRUE) + PORT MAP ( + rst_a => mm_rst, + rst_b => usr_rst, + clk_a => mm_clk, + clk_b => usr_clk, + clken_a => '1', + clken_b => '1', + wr_en_a => ram_wr_en, + wr_dat_a => wr_dat(c_mm_usr_ram.c_dat_w-1 DOWNTO 0), + adr_a => ram_adr, + rd_en_a => ram_rd_en, + rd_dat_a => ram_rd_dat, + rd_val_a => rd_val, + wr_en_b => '0', + wr_dat_b => X"00", + adr_b => "00000", + rd_en_b => '0', + rd_dat_b => OPEN, + rd_val_b => OPEN + ); + + u_ram_wr_val : ENTITY common_lib.common_pipeline GENERIC MAP ( - g_adr_w => adr_w, - g_dat_w => dat_w) + g_pipeline => c_mm_usr_ram.latency, + g_in_c_dat_w => 1, + g_out_c_dat_w => 1 + ) PORT MAP ( - rst => mm_rst, - clk => mm_clk, - axi4_lite_in => axi_copi, - axi4_lite_out => axi_cipo, - wren => reg_wren, - rden => reg_rden, - wr_adr => wr_adr, - wr_dat => wr_dat, - wr_val => wr_val, - wr_busy => '0', - rd_adr => rd_adr, - rd_dat => rd_dat, - rd_busy => '0', - rd_val => rd_val); - - - ram_wr_en <= reg_wren AND is_true(ram_addr_base = unsigned(wr_adr(wr_adr'length-1 downto c_mm_usr_ram.adr_w))); - ram_rd_en <= reg_rden AND is_true(ram_addr_base = unsigned(rd_adr(rd_adr'length-1 downto c_mm_usr_ram.adr_w))); - - ram_adr <= wr_adr(c_mm_usr_ram.adr_w-1 downto 0) WHEN ram_wr_en = '1' ELSE - rd_adr(c_mm_usr_ram.adr_w-1 downto 0); - - u_ram : ENTITY common_lib.common_ram_crw_crw - GENERIC MAP ( - g_ram => c_mm_usr_ram, - g_true_dual_port => TRUE) - PORT MAP ( - rst_a => mm_rst, - rst_b => usr_rst, - clk_a => mm_clk, - clk_b => usr_clk, - clken_a => '1', - clken_b => '1', - wr_en_a => ram_wr_en, - wr_dat_a => wr_dat(c_mm_usr_ram.dat_w-1 downto 0), - adr_a => ram_adr, - rd_en_a => ram_rd_en, - rd_dat_a => ram_rd_dat, - rd_val_a => rd_val, - wr_en_b => '0', - wr_dat_b => X"00", - adr_b => "00000", - rd_en_b => '0', - rd_dat_b => OPEN, - rd_val_b => OPEN + clk => mm_clk, + clken => '1', + in_dat(0) => ram_wr_en, + out_dat(0) => wr_val ); - u_ram_wr_val : ENTITY common_lib.common_pipeline - GENERIC MAP ( - g_pipeline => c_mm_usr_ram.latency, - g_in_dat_w => 1, - g_out_dat_w => 1) - PORT MAP ( - clk => mm_clk, - clken => '1', - in_dat(0) => ram_wr_en, - out_dat(0) => wr_val); - - rd_dat <= "000000000000000000000000" & ram_rd_dat WHEN rd_val = '1' ELSE (OTHERS => '0'); - - - -- - tb : PROCESS - - variable data_in : t_slv_32_arr(0 TO 10); - BEGIN - - axi_lite_init (mm_rst, mm_clk, axi_cipo, axi_copi); - - -- Read and write a number of words to memory - for i in 0 to 10 loop - data_in(i) := std_logic_vector(to_unsigned(57+i, 32)); - end loop; - axi_lite_transaction (mm_clk, axi_cipo, axi_copi, 0, true, data_in, mask => c_mask_zeros); - - - for i in 0 to 10 loop - data_in(i) := std_logic_vector(to_unsigned(57+i, 32)); - end loop; - axi_lite_transaction (mm_clk, axi_cipo, axi_copi, 0, false, data_in, validate => true); - - - - sim_finished <= '1'; - tb_end <= '1'; - wait for 1 us; - REPORT "Finished Simulation" SEVERITY FAILURE; - WAIT; - END PROCESS tb; - - + rd_dat <= RESIZE_UVEC(ram_rd_dat, c_dat_w) WHEN rd_val = '1' ELSE (OTHERS => '0'); + + -- Testbench writes a number of words to memory and then reads them back trough the AXI interface. + -- It uses the axi_lite_transaction to write, read and verify the data. + tb : PROCESS + VARIABLE data_in : t_slv_32_arr(0 TO 10); + BEGIN + axi_lite_init (mm_rst, mm_clk, axi_cipo, axi_copi); + + -- Read and write a number of words to memory + FOR i IN 0 TO 10 LOOP + data_in(i) := std_logic_vector(to_unsigned(57+i, 32)); + END LOOP; + axi_lite_transaction (mm_clk, axi_cipo, axi_copi, 0, true, data_in, mask => c_mask_zeros); + + + FOR i IN 0 TO 10 LOOP + data_in(i) := std_logic_vector(to_unsigned(57+i, 32)); + END LOOP; + axi_lite_transaction (mm_clk, axi_cipo, axi_copi, 0, false, data_in, validate => true); + + + + sim_finished <= '1'; + tb_end <= '1'; + WAIT FOR 1 us; + REPORT "Finished Simulation" SEVERITY FAILURE; + WAIT; + END PROCESS tb; END tb;