diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd index f5efb874cb563d5078c987365d26233b9614b2ae..d8369af3343f23eb29b9be1661a2fc0c7ee34087 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd @@ -30,7 +30,7 @@ -- -- The DDR access starts after a dvr_en pulse. The access can be write or -- read as defined by dvr_wr_not_rd. The size of the access depends the --- address range given by dvr_start_address and dvr_end_address. The +-- address range given by dvr_start_address and dvr_nof_data. The -- dvr_done goes high when the access has finished and it goes low when a -- new access starts. -- @@ -66,7 +66,7 @@ -- dvr_wr_not_rd --*----------+---------------|->| | . | | -- dvr_done <-*--------------------------+--| | . | | -- dvr_start_address --*---------------------------->| | . | | --- dvr_end_address --*---------------------------->| | . | | +-- dvr_nof_data --*---------------------------->| | . | | -- ________ | | . | | -- rd_clk --------->|dp_fifo | | | . | | -- rd_sosi <---------|dc_mixed|<---------------------| | . | | @@ -131,8 +131,8 @@ ENTITY io_ddr IS dvr_en : IN STD_LOGIC; dvr_done : OUT STD_LOGIC; dvr_wr_not_rd : IN STD_LOGIC; - dvr_start_address : IN STD_LOGIC_VECTOR(func_tech_ddr_ctlr_address_w(g_tech_ddr)-1 DOWNTO 0); - dvr_end_address : IN STD_LOGIC_VECTOR(func_tech_ddr_ctlr_address_w(g_tech_ddr)-1 DOWNTO 0); + dvr_start_address : IN STD_LOGIC_VECTOR(func_tech_ddr_ctlr_address_w(g_tech_ddr)-1 DOWNTO 0); -- ctlr start address = dvr_start_address + dvr_nof_data : IN STD_LOGIC_VECTOR(func_tech_ddr_ctlr_address_w(g_tech_ddr)-1 DOWNTO 0); -- ctlr end address = dvr_start_address + dvr_nof_data - 1 dvr_wr_flush_en : IN STD_LOGIC := '0'; -- Write FIFO clock domain @@ -176,7 +176,7 @@ ARCHITECTURE str OF io_ddr IS SIGNAL ctlr_dvr_done : STD_LOGIC; SIGNAL ctlr_dvr_wr_not_rd : STD_LOGIC; SIGNAL ctlr_dvr_start_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); - SIGNAL ctlr_dvr_end_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL ctlr_dvr_nof_data : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); SIGNAL ctlr_dvr_wr_flush_en : STD_LOGIC := '0'; SIGNAL ctlr_init_done : STD_LOGIC; @@ -216,7 +216,7 @@ BEGIN dvr_done => dvr_done, dvr_wr_not_rd => dvr_wr_not_rd, dvr_start_address => dvr_start_address, - dvr_end_address => dvr_end_address, + dvr_nof_data => dvr_nof_data, dvr_wr_flush_en => dvr_wr_flush_en, -- DDR controller clock domain @@ -227,7 +227,7 @@ BEGIN ctlr_dvr_done => ctlr_dvr_done, ctlr_dvr_wr_not_rd => ctlr_dvr_wr_not_rd, ctlr_dvr_start_address => ctlr_dvr_start_address, - ctlr_dvr_end_address => ctlr_dvr_end_address, + ctlr_dvr_nof_data => ctlr_dvr_nof_data, ctlr_dvr_wr_flush_en => ctlr_dvr_wr_flush_en ); @@ -354,7 +354,7 @@ BEGIN dvr_en => ctlr_dvr_en, dvr_wr_not_rd => ctlr_dvr_wr_not_rd, dvr_start_address => ctlr_dvr_start_address, - dvr_end_address => ctlr_dvr_end_address, + dvr_nof_data => ctlr_dvr_nof_data, dvr_done => ctlr_dvr_done, wr_fifo_usedw => ctlr_wr_fifo_usedw, diff --git a/libraries/io/ddr/src/vhdl/io_ddr_cross_domain.vhd b/libraries/io/ddr/src/vhdl/io_ddr_cross_domain.vhd index a366680740a2de5921c46fa79585a0fe3bdc9395..cd3f9613bea004a253b2fb8f9253a15e912cfa73 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr_cross_domain.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr_cross_domain.vhd @@ -27,7 +27,7 @@ -- . If the dvr_clk=ctlr_clk then the clock domain crossing logic defaults -- to wires. However dvr_clk could also be the dp_clk or the mm_clk and then -- the clock domain crossing logic is needed. --- No need to cross dvr_start_address and dvr_end_address, because these +-- No need to cross dvr_start_address and dvr_nof_data, because these -- are stable when the dvr_en is stable. LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib; @@ -51,7 +51,7 @@ ENTITY io_ddr_cross_domain IS dvr_done : OUT STD_LOGIC; dvr_wr_not_rd : IN STD_LOGIC; dvr_start_address : IN STD_LOGIC_VECTOR; - dvr_end_address : IN STD_LOGIC_VECTOR; + dvr_nof_data : IN STD_LOGIC_VECTOR; dvr_wr_flush_en : IN STD_LOGIC := '0'; -- DDR controller clock domain @@ -62,7 +62,7 @@ ENTITY io_ddr_cross_domain IS ctlr_dvr_done : IN STD_LOGIC; ctlr_dvr_wr_not_rd : OUT STD_LOGIC; ctlr_dvr_start_address : OUT STD_LOGIC_VECTOR; - ctlr_dvr_end_address : OUT STD_LOGIC_VECTOR; + ctlr_dvr_nof_data : OUT STD_LOGIC_VECTOR; ctlr_dvr_wr_flush_en : OUT STD_LOGIC := '0' ); END io_ddr_cross_domain; @@ -80,7 +80,7 @@ BEGIN ctlr_dvr_en <= dvr_en; ctlr_dvr_wr_not_rd <= dvr_wr_not_rd; ctlr_dvr_start_address <= dvr_start_address; - ctlr_dvr_end_address <= dvr_end_address; + ctlr_dvr_nof_data <= dvr_nof_data; ctlr_dvr_wr_flush_en <= dvr_wr_flush_en; -- ctlr_clk --> dvr_clk @@ -106,7 +106,7 @@ BEGIN -- Only register into the other clock domain ctlr_dvr_wr_not_rd <= dvr_wr_not_rd WHEN rising_edge(ctlr_clk); ctlr_dvr_start_address <= dvr_start_address WHEN rising_edge(ctlr_clk); - ctlr_dvr_end_address <= dvr_end_address WHEN rising_edge(ctlr_clk); + ctlr_dvr_nof_data <= dvr_nof_data WHEN rising_edge(ctlr_clk); u_common_spulse_ctlr_dvr_wr_flush_en : ENTITY common_lib.common_spulse GENERIC MAP ( diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd index 56241115bf08cf7c06bc0b3fa5a5cd9c00b56dad..93523dd8adf5560cc763799ebd4a195cb017e164 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd @@ -25,7 +25,7 @@ -- Write or read a block of data to or from DDR memory. The data width is set -- by the DDR controller data width given by RESIZE_DDR_CTLR_DATA() and eg. -- 256 bits for DDR3 with 64 bit DQ data. The block of data is located from --- dvr_start_address to dvr_end_address. +-- dvr_start_address to dvr_nof_data. -- The io_ddr_driver takes care that the access is done in a number of bursts. -- The write burst size depends on the maximum burst size, the remaining -- block size and on the number of words available in the (external) FIFO as @@ -52,7 +52,7 @@ ENTITY io_ddr_driver IS dvr_en : IN STD_LOGIC := '1'; dvr_wr_not_rd : IN STD_LOGIC; dvr_start_address : IN STD_LOGIC_VECTOR; - dvr_end_address : IN STD_LOGIC_VECTOR; + dvr_nof_data : IN STD_LOGIC_VECTOR; dvr_done : OUT STD_LOGIC; -- Requested wr or rd sequence is done. wr_fifo_usedw : IN STD_LOGIC_VECTOR; @@ -258,7 +258,7 @@ BEGIN nxt_dvr_done <= '1'; -- assert dvr_done after s_init or keep it asserted after a finished access IF dvr_en = '1' THEN nxt_cur_address <= dvr_start_address; - nxt_address_cnt <= TO_UVEC( TO_UINT(dvr_end_address) - TO_UINT(dvr_start_address) + 1, c_ctlr_address_w); + nxt_address_cnt <= dvr_nof_data; nxt_dvr_done <= '0'; nxt_state <= s_wait1; END IF; diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd index e11294fc4f17a14f8164742e8c19d04732f69add..e42f972dfc969167ef59a19345fa8606a574b1b2 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 @@ ENTITY tb_io_ddr IS 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_dp_data_w : NATURAL := 256; -- 32 for mixed width and 256 for equal width FIFO + g_dp_data_w : NATURAL := 32; -- 32 for mixed width and 256 for equal width FIFO g_nof_repeat : NATURAL := 2; g_wr_flush_mode : STRING := "SYN" -- "VAL", "SOP", "SYN" ); @@ -66,9 +66,12 @@ ARCHITECTURE str of tb_io_ddr IS CONSTANT c_ctlr_data_w : NATURAL := func_tech_ddr_ctlr_data_w(c_tech_ddr); -- DDR access stimuli - CONSTANT c_ctlr_address_lo_arr : t_nat_natural_arr := ( 0, 517, 0, 1, 2, 1, 2, 3, 5, 1900, 1900); - CONSTANT c_ctlr_nof_address_arr : t_nat_natural_arr := (517, 507, 1024, 1, 6, 1, 1, 2, 3, 153, 153); - CONSTANT c_ctlr_wr_not_rd_arr : STD_LOGIC_VECTOR := ('1', '1', '0', '1', '1', '0', '0', '0', '0', '1', '0'); + -- . write 517 and 507 words and then read back these 1024, to verify that 2 block writes can be readback in 1 block read + -- . write 1 + 6 words and then readback the 1+1+2+3 = 7 words, in between also write 0 and read back 0 words (to verify that these are indeed void) + -- . write 1900 words and read back to verify an access can span more than one DDR address column (a_col_w=10). + CONSTANT c_ctlr_address_lo_arr : t_nat_natural_arr := ( 0, 517, 0, 1, 2, 1, 1, 1, 2, 3, 5, 1900, 1900); + CONSTANT c_ctlr_nof_address_arr : t_nat_natural_arr := (517, 507, 1024, 1, 6, 0, 0, 1, 1, 2, 3, 153, 153); + CONSTANT c_ctlr_wr_not_rd_arr : STD_LOGIC_VECTOR := ('1', '1', '0', '1', '1', '1', '0', '0', '0', '0', '0', '1', '0'); CONSTANT c_dp_factor : NATURAL := c_ctlr_data_w/g_dp_data_w; @@ -91,7 +94,7 @@ ARCHITECTURE str of tb_io_ddr IS SIGNAL dp_rst : STD_LOGIC; SIGNAL dvr_start_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); - SIGNAL dvr_end_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL dvr_nof_data : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); SIGNAL dvr_en : STD_LOGIC; SIGNAL dvr_done : STD_LOGIC; @@ -154,8 +157,8 @@ BEGIN FOR R IN 0 TO g_nof_repeat-1 LOOP FOR I IN c_ctlr_address_lo_arr'RANGE LOOP - dvr_start_address <= TO_UVEC(c_ctlr_address_lo_arr(I) , c_ctlr_address_w); - dvr_end_address <= TO_UVEC(c_ctlr_address_lo_arr(I)+c_ctlr_nof_address_arr(I)-1, c_ctlr_address_w); + dvr_start_address <= TO_UVEC(c_ctlr_address_lo_arr(I) , c_ctlr_address_w); + dvr_nof_data <= TO_UVEC(c_ctlr_nof_address_arr(I), c_ctlr_address_w); -- START ACCESS dvr_wr_not_rd <= c_ctlr_wr_not_rd_arr(I); @@ -282,7 +285,7 @@ BEGIN dvr_wr_not_rd => dvr_wr_not_rd, dvr_done => dvr_done, dvr_start_address => dvr_start_address, - dvr_end_address => dvr_end_address, + dvr_nof_data => dvr_nof_data, dvr_wr_flush_en => dvr_wr_flush_en, -- Write FIFO clock domain