diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd index fcad1d1261b442289236e341d8284f4a1cf3da09..bcae51be4d3e714c1a7816ef2c3d98520a50dc24 100644 --- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd +++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd @@ -49,14 +49,10 @@ ENTITY tb_io_ddr IS g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation - g_cross_domain_dvr_ctlr : BOOLEAN := TRUE; -- when TRUE insert clock cross domain logic - g_ctlr_ref_clk_period : TIME := 5000 ps; -- 200 MHz - g_dvr_clk_period : TIME := 5000 ps; -- 50 MHz - g_dp_clk_period : TIME := 5000 ps; -- 200 MHz - g_mm_clk_period : TIME := 8000 ps; -- 125 MHz + g_cross_domain_dvr_ctlr : BOOLEAN := TRUE; -- when TRUE insert clock cross domain logic and also insert clock cross domain logic when g_dvr_clk_period/=c_ctlr_clk_period + g_dvr_clk_period : TIME := 5 ns; -- 200 MHz g_dp_factor : NATURAL := 4; -- 1 or power of 2, c_dp_data_w = c_ctlr_data_w / g_dp_factor - g_rd_fifo_depth : NATURAL := 512; -- default 256 because 32b*256 fits in 1 M9K, use larger to fit more read bursts eg. in case g_dp_factor>1 - g_block_len : NATURAL := 2500; -- block length for a DDR write access and read back access in number of c_ctlr_data_w words + g_block_len : NATURAL := 100; -- block length for a DDR write access and read back access in number of c_ctlr_data_w words g_nof_block : NATURAL := 2; -- number of blocks that will be written to DDR and readback from DDR g_nof_wr_per_block : NATURAL := 1; -- number of write accesses per block g_nof_rd_per_block : NATURAL := 1; -- number of read accesses per block @@ -75,15 +71,20 @@ ARCHITECTURE str of tb_io_ddr IS CONSTANT c_sim_ddr : t_c_tech_ddr := func_tech_sel_ddr(g_technology, c_tech_ddr3_sim_16k, c_tech_ddr4_sim_16k); CONSTANT c_tech_ddr : t_c_tech_ddr := func_tech_sel_ddr(g_sim_model, c_sim_ddr, c_mem_ddr); - CONSTANT c_cross_domain_dvr_ctlr : BOOLEAN := g_cross_domain_dvr_ctlr OR g_ctlr_ref_clk_period/=g_dvr_clk_period; + CONSTANT c_ctlr_ref_clk_period : TIME := sel_a_b(c_tech_ddr.name="DDR3", 5 ns, 40 ns); -- 200 MHz for DDR3 on UniBoard and 25 MHz for DDR4 on UniBoard2 + CONSTANT c_ctlr_clk_freq : NATURAL := c_tech_ddr.mts/c_tech_ddr.rsl; -- 200 MHz + CONSTANT c_ctlr_clk_period : TIME := (1000000 / c_ctlr_clk_freq) * 1 ps; -- 5000 ps + CONSTANT c_cross_domain_dvr_ctlr : BOOLEAN := g_cross_domain_dvr_ctlr OR g_dvr_clk_period/=c_ctlr_clk_period; + CONSTANT c_dp_clk_period : TIME := 5 ns; -- 200 MHz + CONSTANT c_mm_clk_period : TIME := 8 ns; -- 125 MHz CONSTANT c_ctlr_address_w : NATURAL := func_tech_ddr_ctlr_address_w(c_tech_ddr); CONSTANT c_ctlr_data_w : NATURAL := func_tech_ddr_ctlr_data_w(c_tech_ddr); CONSTANT c_dp_data_w : NATURAL := c_ctlr_data_w/g_dp_factor; - CONSTANT c_wr_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO - CONSTANT c_rd_fifo_depth : NATURAL := g_rd_fifo_depth; -- defined at DDR side of the FIFO + CONSTANT c_wr_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO + CONSTANT c_rd_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO -- Frame size for sop/eop CONSTANT c_wr_frame_size : NATURAL := 32; @@ -227,15 +228,15 @@ ARCHITECTURE str of tb_io_ddr IS BEGIN - ctlr_ref_clk <= NOT ctlr_ref_clk OR i_tb_end AFTER g_ctlr_ref_clk_period/2; + ctlr_ref_clk <= NOT ctlr_ref_clk OR i_tb_end AFTER c_ctlr_ref_clk_period/2; dvr_clk <= NOT dvr_clk OR i_tb_end AFTER g_dvr_clk_period/2; dvr_rst <= '1', '0' AFTER 100 ns; - dp_clk <= NOT dp_clk OR i_tb_end AFTER g_dp_clk_period/2; + dp_clk <= NOT dp_clk OR i_tb_end AFTER c_dp_clk_period/2; dp_rst <= '1', '0' AFTER 100 ns; - mm_clk <= NOT mm_clk OR i_tb_end AFTER g_mm_clk_period/2; + mm_clk <= NOT mm_clk OR i_tb_end AFTER c_mm_clk_period/2; mm_rst <= '1', '0' AFTER 100 ns; tb_end <= i_tb_end; diff --git a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd index ab0d752dcea1745acea5761bad9799fc75d1ddd3..b21fa8258c309623cb3db63f9bb0f399fb6470fc 100644 --- a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd +++ b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd @@ -54,13 +54,9 @@ BEGIN -- g_tech_ddr3 : t_c_tech_ddr := c_tech_ddr3_4g_800m_master; -- g_tech_ddr4 : t_c_tech_ddr := c_tech_ddr4_4g_1600m; -- g_tb_end : BOOLEAN := TRUE; -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation - -- g_cross_domain_dvr_ctlr : BOOLEAN := FALSE; -- when TRUE insert clock cross domain logic - -- g_ctlr_ref_clk_period : TIME := 5 ns; -- 200 MHz - -- g_dvr_clk_period : TIME := 5 ns; -- 50 ns - -- g_dp_clk_period : TIME := 5000 ps; -- 200 MHz - -- g_mm_clk_period : TIME := 8000 ps; -- 125 MHz + -- g_cross_domain_dvr_ctlr : BOOLEAN := FALSE; -- when TRUE insert clock cross domain logic and also insert clock cross domain logic when g_dvr_clk_period/=c_ctlr_clk_period + -- g_dvr_clk_period : TIME := 5 ns; -- 200 MHz -- g_dp_factor : NATURAL := 1; -- 1 or power of 2, c_dp_data_w = c_ctlr_data_w / g_dp_factor - -- g_rd_fifo_depth : NATURAL := 256; -- default 256 because 32b*256 fits in 1 M9K, use larger to fit more read bursts -- g_block_len : NATURAL := 64; -- block length for a DDR write access and read back access in number of c_ctlr_data_w words -- g_nof_block : NATURAL := 12; -- number of blocks that will be written to DDR and readback from DDR -- g_nof_wr_per_block : NATURAL := 1; -- number of write accesses per block @@ -69,32 +65,32 @@ BEGIN -- g_wr_flush_mode : STRING := "SYN" -- "VAL", "SOP", "SYN" gen_sim_model: IF c_sim_model=TRUE GENERATE - u_sim_model : ENTITY work.tb_io_ddr GENERIC MAP ( TRUE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 512, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); + u_sim_model : ENTITY work.tb_io_ddr GENERIC MAP ( TRUE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); END GENERATE; gen_ddr3 : IF c_sim_model=FALSE AND c_tech_ddr.name="DDR3" GENERATE - u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 512, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); - - u_fill_wrfifo_on_next_valid : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 1, 256, 1000, 2, 1, 4, 2, "VAL") PORT MAP (tb_end_vec(1)); - u_fill_wrfifo_on_next_sop : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 1, 256, 1000, 2, 3, 4, 2, "SOP") PORT MAP (tb_end_vec(2)); - u_fill_wrfifo_on_next_sync : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 1, 256, 1000, 2, 4, 1, 2, "SYN") PORT MAP (tb_end_vec(3)); - - u_cross_domain : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, TRUE, 5 ns, 5 ns, 5 ns, 8 ns, 1,8192, 2500, 1, 2, 3, 1, "VAL") PORT MAP (tb_end_vec(4)); - u_mixed_width : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 8,8192, 2500, 1, 3, 2, 1, "VAL") PORT MAP (tb_end_vec(5)); - - u_wr_burst_size_0 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 256, 2,10, 3, 3, 2, "VAL") PORT MAP (tb_end_vec(6)); - u_wr_burst_size_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 256, 1,10, 1, 1, 2, "VAL") PORT MAP (tb_end_vec(7)); - - u_cross_dvr_to_faster_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 20 ns, 5 ns, 8 ns, 1,8192, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(8)); - u_cross_dvr_to_slower_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1 ns, 5 ns, 8 ns, 1,8192, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(9)); - - u_sequencer_1_16 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 256, 64,10, 1,16, 1, "VAL") PORT MAP (tb_end_vec(10)); - u_sequencer_16_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 256, 64,10,16, 1, 1, "VAL") PORT MAP (tb_end_vec(11)); + u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); + + u_fill_wrfifo_on_next_valid : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 1, 4, 2, "VAL") PORT MAP (tb_end_vec(1)); + u_fill_wrfifo_on_next_sop : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 3, 4, 2, "SOP") PORT MAP (tb_end_vec(2)); + u_fill_wrfifo_on_next_sync : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 1, 1000, 2, 4, 1, 2, "SYN") PORT MAP (tb_end_vec(3)); + + u_cross_domain : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, TRUE, 5 ns, 1, 2500, 1, 2, 3, 1, "VAL") PORT MAP (tb_end_vec(4)); + u_mixed_width : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 8, 2500, 1, 3, 2, 1, "VAL") PORT MAP (tb_end_vec(5)); + + u_wr_burst_size_0 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2,10, 3, 3, 2, "VAL") PORT MAP (tb_end_vec(6)); + u_wr_burst_size_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 1,10, 1, 1, 2, "VAL") PORT MAP (tb_end_vec(7)); + + u_cross_dvr_to_faster_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 20 ns, 1, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(8)); + u_cross_dvr_to_slower_ctlr : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 1 ns, 1, 2500, 1, 1, 4, 1, "VAL") PORT MAP (tb_end_vec(9)); + + u_sequencer_1_16 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 64,10, 1,16, 1, "VAL") PORT MAP (tb_end_vec(10)); + u_sequencer_16_1 : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 64,10,16, 1, 1, "VAL") PORT MAP (tb_end_vec(11)); END GENERATE; -- Distinghuis between tests for DDR3 and DDR4, because the Quartus 14.1 ip_arria10 DDR4 model simulates about 40x slower than the Quartus 11.1 ip_stratixiv DDR3 uniphy model. gen_ddr4 : IF c_sim_model=FALSE AND c_tech_ddr.name="DDR4" GENERATE - u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 5 ns, 5 ns, 8 ns, 4, 512, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); + u_default : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE, 5 ns, 4, 2500, 2, 1, 1, 1, "VAL") PORT MAP (tb_end_vec(0)); END GENERATE; p_tb_end : PROCESS