From a620209c6da6d2a70dfb143841b4ed6e76ca4ed2 Mon Sep 17 00:00:00 2001 From: Erik Kooistra <kooistra@astron.nl> Date: Tue, 6 Jan 2015 15:26:05 +0000 Subject: [PATCH] Use address_cnt instead of diff_address and addresses_rem. --- libraries/io/ddr/src/vhdl/io_ddr_driver.vhd | 56 ++++++++++----------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd index bb0a310ddd..56241115bf 100644 --- a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd +++ b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd @@ -98,12 +98,10 @@ ARCHITECTURE str OF io_ddr_driver IS SIGNAL cur_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); SIGNAL nxt_cur_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); - SIGNAL diff_address : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); - - SIGNAL addresses_rem : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); -- nof words (on the user side interface) to rd/wr until end addr is reached - SIGNAL reg_addresses_rem : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); -- nof words (on the user side interface) to rd/wr until end addr is reached - - SIGNAL reg_wr_fifo_usedw : STD_LOGIC_VECTOR(wr_fifo_usedw'RANGE); -- read side depth of the write FIFO + SIGNAL address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); -- count down nof addresses = nof ctlr data words + SIGNAL nxt_address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL reg_address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0); + SIGNAL reg_wr_fifo_usedw : STD_LOGIC_VECTOR(wr_fifo_usedw'RANGE); -- available nof ctlr data words for a burst in at read side the write FIFO BEGIN @@ -116,9 +114,10 @@ BEGIN burst_wr_cnt <= (OTHERS => '0'); i_dvr_done <= '0'; cur_address <= (OTHERS=>'0'); + address_cnt <= (OTHERS=>'0'); wr_burst_size <= 0; rd_burst_size <= 0; - reg_addresses_rem <= (OTHERS=>'0'); + reg_address_cnt <= (OTHERS=>'0'); reg_wr_fifo_usedw <= (OTHERS=>'0'); prev_state <= s_idle; ELSIF rising_edge(clk) THEN @@ -126,27 +125,22 @@ BEGIN burst_wr_cnt <= nxt_burst_wr_cnt; i_dvr_done <= nxt_dvr_done; cur_address <= nxt_cur_address; + address_cnt <= nxt_address_cnt; wr_burst_size <= nxt_wr_burst_size; rd_burst_size <= nxt_rd_burst_size; - reg_addresses_rem <= addresses_rem; + reg_address_cnt <= address_cnt; reg_wr_fifo_usedw <= wr_fifo_usedw; prev_state <= state; END IF; END PROCESS; - -- End address - current address - diff_address <= SUB_UVEC(dvr_end_address, cur_address); - - -- Add 1 to diff_address to also write the last address - addresses_rem <= INCR_UVEC(diff_address, 1); - - p_wr_burst_size : PROCESS (reg_addresses_rem, reg_wr_fifo_usedw) + p_wr_burst_size : PROCESS (reg_address_cnt, reg_wr_fifo_usedw) VARIABLE v_burst_size : POSITIVE; BEGIN - -- Write burst size is at least 1 and if more then set to the smallest of g_tech_ddr.maxburstsize, addresses_rem and wr_fifo_usedw - IF UNSIGNED(reg_wr_fifo_usedw)>c_margin AND UNSIGNED(reg_addresses_rem)>c_margin THEN + -- Write burst size is at least 1 and if more then set to the smallest of g_tech_ddr.maxburstsize, address_cnt and wr_fifo_usedw + IF UNSIGNED(reg_wr_fifo_usedw)>c_margin AND UNSIGNED(reg_address_cnt)>c_margin THEN v_burst_size := g_tech_ddr.maxburstsize+c_margin; - IF v_burst_size > UNSIGNED(reg_addresses_rem) THEN v_burst_size := TO_UINT(reg_addresses_rem); END IF; + IF v_burst_size > UNSIGNED(reg_address_cnt) THEN v_burst_size := TO_UINT(reg_address_cnt); END IF; IF v_burst_size > UNSIGNED(reg_wr_fifo_usedw) THEN v_burst_size := TO_UINT(reg_wr_fifo_usedw); END IF; v_burst_size := v_burst_size - c_margin; ELSE @@ -155,13 +149,13 @@ BEGIN nxt_wr_burst_size <= v_burst_size; END PROCESS; - p_rd_burst_size : PROCESS (reg_addresses_rem) + p_rd_burst_size : PROCESS (reg_address_cnt) VARIABLE v_burst_size : POSITIVE; BEGIN - -- Read burst size is at least 1 and if more then set to the smallest of g_tech_ddr.maxburstsize and addresses_rem - IF UNSIGNED(reg_addresses_rem)>0 THEN + -- Read burst size is at least 1 and if more then set to the smallest of g_tech_ddr.maxburstsize and address_cnt + IF UNSIGNED(reg_address_cnt)>0 THEN v_burst_size := g_tech_ddr.maxburstsize; - IF v_burst_size > UNSIGNED(reg_addresses_rem) THEN v_burst_size := TO_UINT(reg_addresses_rem); END IF; + IF v_burst_size > UNSIGNED(reg_address_cnt) THEN v_burst_size := TO_UINT(reg_address_cnt); END IF; ELSE v_burst_size := 1; END IF; @@ -173,7 +167,7 @@ BEGIN p_state : PROCESS(prev_state, state, ctlr_init_done, dvr_en, dvr_wr_not_rd, i_dvr_done, ctlr_miso, burst_wr_cnt, wr_snk_in, rd_src_in, - wr_fifo_usedw, wr_burst_size, rd_burst_size, reg_addresses_rem, dvr_start_address, cur_address) + wr_fifo_usedw, wr_burst_size, rd_burst_size, reg_address_cnt, dvr_start_address, cur_address, address_cnt) BEGIN nxt_state <= state; @@ -188,6 +182,7 @@ BEGIN nxt_burst_wr_cnt <= burst_wr_cnt; nxt_dvr_done <= i_dvr_done; nxt_cur_address <= cur_address; + nxt_address_cnt <= address_cnt; CASE state IS @@ -203,7 +198,7 @@ BEGIN WHEN s_wr_request => -- Performs 1 write access and goes into s_wr_burst when requested write words >1 nxt_state <= s_wait3; - IF UNSIGNED(reg_addresses_rem) = 0 THEN -- end address reached + IF UNSIGNED(reg_address_cnt) = 0 THEN -- end address reached nxt_dvr_done <= '1'; nxt_state <= s_idle; ELSIF ctlr_miso.waitrequest_n = '1' THEN @@ -219,12 +214,13 @@ BEGIN nxt_burst_wr_cnt <= TO_DDR_CTLR_BURSTSIZE(wr_burst_size-1); -- first burst wr cycle is done here, the rest are done in s_wr_burst END IF; -- ELSE: there is only 1 word, so no need for remaining burst nxt_cur_address <= INCR_UVEC(cur_address, wr_burst_size); + nxt_address_cnt <= INCR_UVEC(address_cnt, -wr_burst_size); END IF; END IF; WHEN s_rd_request => -- Posts a read request for a burst (1...g_tech_ddr.maxburstsize) nxt_state <= s_wait3; - IF UNSIGNED(reg_addresses_rem) = 0 THEN -- end address reached + IF UNSIGNED(reg_address_cnt) = 0 THEN -- end address reached nxt_dvr_done <= '1'; nxt_state <= s_idle; ELSE @@ -234,18 +230,19 @@ BEGIN ctlr_mosi.burstbegin <= '1'; -- assert burstbegin, ctlr_mosi.burstsize <= TO_DDR_CTLR_BURSTSIZE(rd_burst_size); -- burstsize >= 1 nxt_cur_address <= INCR_UVEC(cur_address, rd_burst_size); + nxt_address_cnt <= INCR_UVEC(address_cnt, -rd_burst_size); END IF; END IF; END IF; -- This wait state is inserted between two requests when necessary, e.g. when FSM enters wr_request - -- from the state wr_request, an extra cycle is needed for reg_addresses_rem to be valid. + -- from the state wr_request, an extra cycle is needed for reg_address_cnt to be valid. WHEN s_wait3 => IF prev_state = s_wr_request THEN nxt_state <= s_wr_request; END IF; IF prev_state = s_rd_request THEN nxt_state <= s_rd_request; END IF; - -- In this cycle reg_addresses_rem is valid. This cycle is added so wr_burst_size and rd_burst_size - -- (derived from reg_addresses_rem) are valid the next cycle. + -- In this cycle reg_address_cnt is valid. This cycle is added so wr_burst_size and rd_burst_size + -- (derived from reg_address_cnt) are valid the next cycle. WHEN s_wait2 => IF dvr_wr_not_rd = '1' THEN nxt_state <= s_wr_request; @@ -253,7 +250,7 @@ BEGIN nxt_state <= s_rd_request; END IF; - -- Wait a cycle so reg_addresses_rem is valid the next cyle. + -- Wait a cycle so reg_address_cnt is valid the next cyle. WHEN s_wait1 => nxt_state <= s_wait2; @@ -261,6 +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_dvr_done <= '0'; nxt_state <= s_wait1; END IF; -- GitLab