diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd index 8a91295a14c756bef34e5da15016791a507e2340..bf0f59d644ee316e563df54c4d5ca868d9acb3f1 100644 --- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd +++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_controller.vhd @@ -116,6 +116,7 @@ ARCHITECTURE rtl OF ddrctrl_controller IS -- writing signals wr_burst_en : STD_LOGIC; + wr_bursts_ready : NATURAL; -- reading signals outp_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); @@ -127,7 +128,7 @@ ARCHITECTURE rtl OF ddrctrl_controller IS wr_sosi : t_dp_sosi; END RECORD; - CONSTANT c_t_reg_init : t_reg := (RESET, '0', '0', TO_UVEC(g_max_adr, c_adr_w), (OTHERS => '0'), 0, '1', '1', '0', (OTHERS => '0'), 0, '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init); + CONSTANT c_t_reg_init : t_reg := (RESET, '0', '0', TO_UVEC(g_max_adr, c_adr_w), (OTHERS => '0'), 0, '1', '1', '0', 0, (OTHERS => '0'), 0, '0', c_mem_ctlr_mosi_rst, c_dp_sosi_init); -- signals for readability @@ -140,7 +141,7 @@ BEGIN q_reg <= d_reg WHEN rising_edge(clk); -- put the input data into c_v and fill the output vector from c_v - p_state : PROCESS(q_reg, rst, inp_of, inp_sosi, inp_adr, inp_bsn_adr, inp_data_stopped, dvr_miso, rd_fifo_usedw, stop_in) + p_state : PROCESS(q_reg, rst, inp_of, inp_sosi, inp_adr, inp_bsn_adr, inp_data_stopped, dvr_miso, rd_fifo_usedw, wr_fifo_usedw, stop_in) VARIABLE v : t_reg := c_t_reg_init; @@ -175,31 +176,33 @@ BEGIN WHEN START_WRITING => -- this state generates the first write burst. - IF TO_UINT(wr_fifo_usedw) > g_burstsize AND dvr_miso.done = '1' AND v.wr_burst_en = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN + IF q_reg.wr_bursts_ready >= 1 AND dvr_miso.done = '1' AND v.wr_burst_en = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN v.dvr_mosi.address(c_adr_w-1 DOWNTO 0) := TO_UVEC(TO_UINT(q_reg.last_adr_to_write_to(c_adr_w-1 DOWNTO 0))+q_reg.stop_burstsize, c_adr_w); - v.dvr_mosi.wr := '1'; - v.dvr_mosi.rd := '0'; - v.dvr_mosi.burstbegin := '1'; + v.dvr_mosi.wr := '1'; + v.dvr_mosi.rd := '0'; + v.dvr_mosi.burstbegin := '1'; v.dvr_mosi.burstsize(dvr_mosi.burstsize'length-1 DOWNTO 0) := TO_UVEC(g_burstsize-q_reg.stop_burstsize, dvr_mosi.burstsize'length); - v.wr_burst_en := '0'; - v.wr_burst_en := '1'; - v.state := WRITING; + v.wr_burst_en := '0'; + v.wr_burst_en := '1'; + v.state := WRITING; ELSE - v.dvr_mosi.burstbegin := '0'; - v.state := START_WRITING; + v.dvr_mosi.burstbegin := '0'; + v.state := START_WRITING; END IF; + v.wr_bursts_ready := TO_UINT(wr_fifo_usedw(g_wr_fifo_uw_w-1 DOWNTO c_bitshift_w)); WHEN WRITING => -- this state generates the rest of the write bursts, it also checks if there is a stop signal or if it needs to stop writing. - IF TO_UINT(wr_fifo_usedw) > g_burstsize AND dvr_miso.done = '1' AND q_reg.wr_burst_en = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN + v.wr_bursts_ready := TO_UINT(wr_fifo_usedw(g_wr_fifo_uw_w-1 DOWNTO c_bitshift_w)); + IF q_reg.wr_bursts_ready >= 1 AND dvr_miso.done = '1' AND q_reg.wr_burst_en = '1' AND q_reg.dvr_mosi.burstbegin = '0' THEN v.dvr_mosi.burstbegin := '1'; v.wr_burst_en := '0'; - IF inp_adr < g_burstsize-1 THEN - v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize, dvr_mosi.address'length); + IF inp_adr < (g_burstsize*q_reg.wr_bursts_ready)-1 THEN + v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize-(g_burstsize*(q_reg.wr_bursts_ready-1)), dvr_mosi.address'length); v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE - v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); + v.dvr_mosi.address := TO_UVEC(inp_adr-(g_burstsize*q_reg.wr_bursts_ready), dvr_mosi.address'length); v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; @@ -209,8 +212,10 @@ BEGIN v.dvr_mosi.wr := '1'; v.dvr_mosi.rd := '0'; - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN - v.wr_burst_en := '1'; + IF NOT (q_reg.wr_bursts_ready = 0) AND q_reg.dvr_mosi.burstbegin = '0'THEN + v.wr_burst_en := '1'; + ELSIF q_reg.wr_bursts_ready = 0 THEN + v.wr_burst_en := '0'; END IF; IF stop_in = '1' THEN @@ -241,17 +246,20 @@ BEGIN -- still a write cyle -- if adr mod g_burstsize = 0 -- this makes sure that only ones every 64 writes a writeburst is started. - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN + v.wr_bursts_ready := TO_UINT(wr_fifo_usedw(g_wr_fifo_uw_w-1 DOWNTO c_bitshift_w)); + IF NOT (q_reg.wr_bursts_ready = 0) AND q_reg.dvr_mosi.burstbegin = '0'THEN v.wr_burst_en := '1'; + ELSIF q_reg.wr_bursts_ready = 0 THEN + v.wr_burst_en := '0'; END IF; IF dvr_miso.done = '1' AND q_reg.wr_burst_en = '1' THEN v.dvr_mosi.burstbegin := '1'; v.wr_burst_en := '0'; - IF inp_adr < g_burstsize-1 THEN - v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize, dvr_mosi.address'length); + IF inp_adr < (g_burstsize*q_reg.wr_bursts_ready)-1 THEN + v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize-(g_burstsize*(q_reg.wr_bursts_ready-1)), dvr_mosi.address'length); v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE - v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); + v.dvr_mosi.address := TO_UVEC(inp_adr-(g_burstsize*q_reg.wr_bursts_ready), dvr_mosi.address'length); v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; @@ -278,7 +286,7 @@ BEGIN -- wait until the write burst is finished IF inp_data_stopped = '0' THEN v.state := STOP_WRITING; - ELSIF dvr_miso.done = '1' AND q_reg.dvr_mosi.burstbegin = '0' AND q_reg.wr_burst_en = '0' THEN + ELSIF dvr_miso.done = '1' AND q_reg.dvr_mosi.burstbegin = '0' AND q_reg.wr_burst_en = '0' AND q_reg.wr_bursts_ready = 0 THEN v.state := LAST_WRITE_BURST; ELSE v.state := STOP_WRITING; @@ -288,17 +296,20 @@ BEGIN -- still receiving write data. -- if adr mod g_burstsize = 0 -- this makes sure that only ones every 64 writes a writeburst is started. - IF TO_UVEC(inp_adr, c_adr_w)(c_bitshift_w-1 DOWNTO 0) = c_zeros AND q_reg.dvr_mosi.burstbegin = '0'THEN + v.wr_bursts_ready := TO_UINT(wr_fifo_usedw(g_wr_fifo_uw_w-1 DOWNTO c_bitshift_w)); + IF NOT (q_reg.wr_bursts_ready = 0) AND q_reg.dvr_mosi.burstbegin = '0'THEN v.wr_burst_en := '1'; + ELSIF q_reg.wr_bursts_ready = 0 THEN + v.wr_burst_en := '0'; END IF; IF dvr_miso.done = '1' AND q_reg.wr_burst_en = '1' THEN v.dvr_mosi.burstbegin := '1'; v.wr_burst_en := '0'; - IF inp_adr < g_burstsize-1 THEN - v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize, dvr_mosi.address'length); + IF inp_adr < (g_burstsize*q_reg.wr_bursts_ready)-1 THEN + v.dvr_mosi.address := TO_UVEC(g_max_adr-g_last_burstsize-(g_burstsize*q_reg.wr_bursts_ready-1), dvr_mosi.address'length); v.dvr_mosi.burstsize := TO_UVEC(g_last_burstsize, dvr_mosi.burstsize'length); ELSE - v.dvr_mosi.address := TO_UVEC(inp_adr-g_burstsize, dvr_mosi.address'length); + v.dvr_mosi.address := TO_UVEC(inp_adr-(g_burstsize*q_reg.wr_bursts_ready), dvr_mosi.address'length); v.dvr_mosi.address(c_bitshift_w-1 DOWNTO 0) := c_zeros(c_bitshift_w-1 DOWNTO 0); -- makes sure that a burst is only started on a multiple of g_burstsize v.dvr_mosi.burstsize := TO_UVEC(g_burstsize, dvr_mosi.burstsize'length); END IF; diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd index 881d039d0bfc8bbea512fcebfc74ac169d3b9801..906aacc14b2b26474621265a62b1cca5ad144c19 100644 --- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd +++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd @@ -137,7 +137,7 @@ ARCHITECTURE tb OF tb_ddrctrl IS -- signals for running test SIGNAL in_data_cnt : NATURAL := 0; -- signal which contains the amount of times there has been input data for ddrctrl_repack.vhd SIGNAL test_running : STD_LOGIC := '0'; -- signal to tell wheter the testing has started - SIGNAL bsn_cnt : NATURAL := 0; + SIGNAL bsn_cnt : NATURAL := g_block_size-1; -- signals for checking the output data