diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd index df0516bd64487a6cbe6a785f6c03d58aae17ad61..415db0eb043d291231670c9a737ab42ac9839141 100644 --- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd +++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd @@ -50,7 +50,7 @@ END ENTITY tb_io_ddr; ARCHITECTURE str of tb_io_ddr IS CONSTANT c_ctlr_ref_clk_period : TIME := 5 ns; -- 200 MHz - CONSTANT c_dp_clk_period : TIME := 5 ns; -- 200 MHz + CONSTANT c_dp_clk_period : TIME := 5000 ps; -- 200 MHz CONSTANT c_tech_ddr : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; @@ -62,6 +62,10 @@ ARCHITECTURE str of tb_io_ddr IS (OTHERS=>'0'), TO_UVEC( 3, c_tech_ddr_max.a_row_w), TO_UVEC(2**c_tech_ddr_4g.a_col_w-1, c_tech_ddr_max.a_col_w)); + -- DDR access stimuli + CONSTANT c_address_lo_arr : t_nat_natural_arr := ( 0, 517, 0, 1, 2, 1, 2, 3, 5, 1900, 1900); + CONSTANT c_nof_address_arr : t_nat_natural_arr := (517, 507, 1024, 1, 6, 1, 1, 2, 3, 153, 153); + CONSTANT c_wr_not_rd_arr : STD_LOGIC_VECTOR := ('1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '0'); CONSTANT c_ctlr_data_w : NATURAL := func_tech_ddr_ctlr_data_w(c_tech_ddr); --CONSTANT c_dp_data_w : NATURAL := 32; @@ -113,16 +117,16 @@ BEGIN dp_clk <= NOT dp_clk OR tb_end AFTER c_dp_clk_period/2; dp_rst <= '1', '0' AFTER 100 ns; - dvr_start_addr <= c_tech_ddr_addr_lo; - dvr_end_addr <= c_ddr_addr_hi; - p_stimuli : PROCESS + VARIABLE v_addr_lo : t_tech_ddr_addr; + VARIABLE v_addr_hi : t_tech_ddr_addr; BEGIN tb_end <= '0'; dvr_en <= '0'; src_diag_en <= '0'; dvr_wr_not_rd <= '0'; snk_diag_en <= '0'; + expected_cnt <= 0; proc_common_wait_until_high(ctlr_clk, ctlr_init_done); proc_common_wait_some_cycles(ctlr_clk, 2); -- Give the driver FSM a cycle to go into idle mode @@ -131,31 +135,31 @@ BEGIN src_diag_en <= '1'; snk_diag_en <= '1'; - -- START WRITE - dvr_wr_not_rd <= '1'; - dvr_en <= '1'; - proc_common_wait_some_cycles(ctlr_clk, 1); - dvr_en <= '0'; + FOR I IN c_address_lo_arr'RANGE LOOP + v_addr_lo := func_tech_ddr_dq_address(TO_DDR_CTLR_ADDRESS(4*c_address_lo_arr(I)) , c_tech_ddr); + v_addr_hi := func_tech_ddr_dq_address(TO_DDR_CTLR_ADDRESS(4*c_address_lo_arr(I)+4*c_nof_address_arr(I)-1), c_tech_ddr); + + dvr_start_addr <= v_addr_lo; + dvr_end_addr <= v_addr_hi; + + -- START ACCESS + dvr_wr_not_rd <= c_wr_not_rd_arr(I); + dvr_en <= '1'; + proc_common_wait_some_cycles(ctlr_clk, 1); + dvr_en <= '0'; + + -- ACCESS DONE + proc_common_wait_until_lo_hi(ctlr_clk, dvr_done); + + IF c_wr_not_rd_arr(I)='0' THEN + expected_cnt <= expected_cnt + c_nof_address_arr(I)*c_dp_factor; + + ASSERT snk_diag_res_val = '1' REPORT "[ERROR] DIAG_RES INVALID!" SEVERITY FAILURE; + ASSERT snk_diag_res = '0' REPORT "[ERROR] NON-ZERO DIAG_RES!" SEVERITY FAILURE; + END IF; + END LOOP; - -- WRITE DONE - proc_common_wait_some_cycles(ctlr_clk, 10); - proc_common_wait_until_high(ctlr_clk, dvr_done); - - -- START READ - dvr_wr_not_rd <= '0'; - dvr_en <= '1'; - proc_common_wait_some_cycles(ctlr_clk, 1); - dvr_en <= '0'; - - -- READ DONE - proc_common_wait_some_cycles(ctlr_clk, 10); - proc_common_wait_until_high(ctlr_clk, dvr_done); - - expected_cnt <= 1024*c_dp_factor; - proc_common_wait_some_cycles(ctlr_clk, 500*c_dp_factor); -- 'Done' means all requests are posted. Wait for the last read data to arrive. - - ASSERT snk_diag_res_val = '1' REPORT "[ERROR] DIAG_RES INVALID!" SEVERITY FAILURE; - ASSERT snk_diag_res = '0' REPORT "[ERROR] NON-ZERO DIAG_RES!" SEVERITY FAILURE; + proc_common_wait_some_cycles(ctlr_clk, 500); ASSERT UNSIGNED(snk_val_cnt) = expected_cnt REPORT "[ERROR] Unexpected number of read data!" SEVERITY FAILURE; REPORT "[OK] Test passed." SEVERITY NOTE;