diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd index 80cdc38fcde798cd02020ae064ea0513487e7c04..78a8131c28ad7ad011327dce86b848b03bfa94fd 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd @@ -82,17 +82,17 @@ ARCHITECTURE str OF io_ddr_driver IS SIGNAL dvr_wr_not_rd : STD_LOGIC; SIGNAL dvr_start_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_done : STD_LOGIC; + SIGNAL dvr_done : STD_LOGIC := '0'; SIGNAL nxt_dvr_done : STD_LOGIC; - SIGNAL burst_size : POSITIVE RANGE 1 TO 2**g_tech_ddr.maxburstsize_w-1; -- burst size >= 1 + SIGNAL burst_size : POSITIVE RANGE 1 TO 2**g_tech_ddr.maxburstsize_w-1 := 1; -- burst size >= 1 SIGNAL nxt_burst_size : POSITIVE; - SIGNAL burst_wr_cnt : STD_LOGIC_VECTOR(g_tech_ddr.maxburstsize_w-1 DOWNTO 0); -- count down from burst_size to 0 - SIGNAL nxt_burst_wr_cnt : STD_LOGIC_VECTOR(g_tech_ddr.maxburstsize_w-1 DOWNTO 0); + SIGNAL burst_wr_cnt : NATURAL RANGE 0 TO 2**g_tech_ddr.maxburstsize_w-1 := 0; -- count down from burst_size to 0 + SIGNAL nxt_burst_wr_cnt : NATURAL RANGE 0 TO 2**g_tech_ddr.maxburstsize_w-1; - SIGNAL cur_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL cur_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0) := (OTHERS=>'0'); 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); -- count down nof addresses = nof ctlr data words + 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); BEGIN @@ -107,21 +107,16 @@ BEGIN p_clk : PROCESS(rst, clk) BEGIN IF rst='1' THEN - state <= s_init; - burst_wr_cnt <= (OTHERS=>'0'); - dvr_done <= '0'; - cur_address <= (OTHERS=>'0'); - address_cnt <= (OTHERS=>'0'); - burst_size <= 1; - prev_state <= s_idle; + state <= s_init; + prev_state <= s_init; ELSIF rising_edge(clk) THEN - state <= nxt_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; - prev_state <= state; + 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; END IF; END PROCESS; @@ -155,10 +150,10 @@ BEGIN ctlr_mosi.burstsize <= (OTHERS => '0'); wr_snk_out.ready <= '0'; - nxt_burst_wr_cnt <= burst_wr_cnt; nxt_dvr_done <= '0'; nxt_cur_address <= cur_address; nxt_address_cnt <= address_cnt; + nxt_burst_wr_cnt <= burst_wr_cnt; CASE state IS @@ -167,8 +162,8 @@ BEGIN IF wr_snk_in.valid = '1' THEN -- it is allowed that valid is not always active during a burst wr_snk_out.ready <= '1'; -- wr side uses latency of 0, so wr_snk_out.ready<='1' acknowledges a successful write request. ctlr_mosi.wr <= '1'; - nxt_burst_wr_cnt <= INCR_UVEC(burst_wr_cnt, -1); - IF UNSIGNED(burst_wr_cnt) = 1 THEN -- check for the last cycle of this burst sequence + 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 END IF; END IF; @@ -187,7 +182,7 @@ BEGIN ctlr_mosi.burstsize <= TO_MEM_CTLR_BURSTSIZE(burst_size); -- burstsize >= 1 nxt_cur_address <= INCR_UVEC(cur_address, burst_size); nxt_address_cnt <= INCR_UVEC(address_cnt, -burst_size); - nxt_burst_wr_cnt <= TO_UVEC(burst_size-1, g_tech_ddr.maxburstsize_w); + nxt_burst_wr_cnt <= burst_size-1; -- Return for next wr request or perform any remaining writes in this burst nxt_state <= s_wait; IF burst_size > 1 THEN @@ -228,12 +223,13 @@ BEGIN END IF; WHEN s_idle => + nxt_cur_address <= dvr_start_address; + nxt_address_cnt <= dvr_nof_data; + nxt_burst_wr_cnt <= 0; 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 <= dvr_nof_data; - nxt_dvr_done <= '0'; - nxt_state <= s_wait; + nxt_dvr_done <= '0'; + nxt_state <= s_wait; END IF; WHEN OTHERS => -- s_init