diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd index 78a8131c28ad7ad011327dce86b848b03bfa94fd..32ad80ecf3458b0b0e92b43baa3d19edb425eba4 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd @@ -94,6 +94,8 @@ ARCHITECTURE str OF io_ddr_driver IS SIGNAL nxt_cur_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); SIGNAL address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0) := (OTHERS=>'0'); -- count down nof addresses = nof ctlr data words SIGNAL nxt_address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL address_cnt_is_0 : STD_LOGIC; + SIGNAL nxt_address_cnt_is_0 : STD_LOGIC; BEGIN @@ -110,13 +112,14 @@ BEGIN state <= s_init; prev_state <= s_init; ELSIF rising_edge(clk) THEN - state <= nxt_state; - prev_state <= state; - burst_wr_cnt <= nxt_burst_wr_cnt; - dvr_done <= nxt_dvr_done; - cur_address <= nxt_cur_address; - address_cnt <= nxt_address_cnt; - burst_size <= nxt_burst_size; + state <= nxt_state; + prev_state <= state; + burst_wr_cnt <= nxt_burst_wr_cnt; + dvr_done <= nxt_dvr_done; + cur_address <= nxt_cur_address; + address_cnt <= nxt_address_cnt; + address_cnt_is_0 <= nxt_address_cnt_is_0; + burst_size <= nxt_burst_size; END IF; END PROCESS; @@ -132,13 +135,15 @@ BEGIN END IF; END PROCESS; + nxt_address_cnt_is_0 <= '1' WHEN UNSIGNED(nxt_address_cnt) = 0 ELSE '0'; + rd_src_out.valid <= ctlr_miso.rdval; rd_src_out.data <= RESIZE_DP_DATA(ctlr_miso.rddata); p_state : PROCESS(prev_state, state, dvr_en, dvr_wr_not_rd, dvr_start_address, dvr_nof_data, ctlr_miso, wr_snk_in, rd_src_in, - burst_size, burst_wr_cnt, cur_address, address_cnt) + burst_size, burst_wr_cnt, cur_address, address_cnt, address_cnt_is_0) BEGIN nxt_state <= state; @@ -164,15 +169,15 @@ BEGIN ctlr_mosi.wr <= '1'; nxt_burst_wr_cnt <= burst_wr_cnt-1; IF burst_wr_cnt = 1 THEN -- check for the last cycle of this burst sequence - nxt_state <= s_wr_request; -- initiate a new wr burst or goto idle via the wr_request state + nxt_state <= s_wr_request; -- initiate a new wr burst or goto idle via the wr_request state, simulation shows this does not cost a cycle END IF; END IF; END IF; WHEN s_wr_request => -- Performs 1 write access and goes into s_wr_burst when requested write words >1 - IF UNSIGNED(address_cnt) = 0 THEN -- end address reached + IF address_cnt_is_0 = '1' THEN -- end address reached nxt_dvr_done <= '1'; - nxt_state <= s_idle; + nxt_state <= s_idle; ELSIF ctlr_miso.waitrequest_n = '1' THEN IF wr_snk_in.valid = '1' THEN -- Always perform 1st write here @@ -192,7 +197,7 @@ BEGIN END IF; WHEN s_rd_request => -- Posts a read request for a burst (1...g_tech_ddr.maxburstsize) - IF UNSIGNED(address_cnt) = 0 THEN -- end address reached + IF address_cnt_is_0 = '1' THEN -- end address reached nxt_dvr_done <= '1'; nxt_state <= s_idle; ELSE