Skip to content
Snippets Groups Projects
Commit a620209c authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Use address_cnt instead of diff_address and addresses_rem.

parent 66540bfd
No related branches found
No related tags found
No related merge requests found
...@@ -98,12 +98,10 @@ ARCHITECTURE str OF io_ddr_driver IS ...@@ -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 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 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 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 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_address_cnt : STD_LOGIC_VECTOR(c_ctlr_address_w-1 DOWNTO 0);
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); -- available nof ctlr data words for a burst in at read side the write FIFO
SIGNAL reg_wr_fifo_usedw : STD_LOGIC_VECTOR(wr_fifo_usedw'RANGE); -- read side depth of the write FIFO
BEGIN BEGIN
...@@ -116,9 +114,10 @@ BEGIN ...@@ -116,9 +114,10 @@ BEGIN
burst_wr_cnt <= (OTHERS => '0'); burst_wr_cnt <= (OTHERS => '0');
i_dvr_done <= '0'; i_dvr_done <= '0';
cur_address <= (OTHERS=>'0'); cur_address <= (OTHERS=>'0');
address_cnt <= (OTHERS=>'0');
wr_burst_size <= 0; wr_burst_size <= 0;
rd_burst_size <= 0; rd_burst_size <= 0;
reg_addresses_rem <= (OTHERS=>'0'); reg_address_cnt <= (OTHERS=>'0');
reg_wr_fifo_usedw <= (OTHERS=>'0'); reg_wr_fifo_usedw <= (OTHERS=>'0');
prev_state <= s_idle; prev_state <= s_idle;
ELSIF rising_edge(clk) THEN ELSIF rising_edge(clk) THEN
...@@ -126,27 +125,22 @@ BEGIN ...@@ -126,27 +125,22 @@ BEGIN
burst_wr_cnt <= nxt_burst_wr_cnt; burst_wr_cnt <= nxt_burst_wr_cnt;
i_dvr_done <= nxt_dvr_done; i_dvr_done <= nxt_dvr_done;
cur_address <= nxt_cur_address; cur_address <= nxt_cur_address;
address_cnt <= nxt_address_cnt;
wr_burst_size <= nxt_wr_burst_size; wr_burst_size <= nxt_wr_burst_size;
rd_burst_size <= nxt_rd_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; reg_wr_fifo_usedw <= wr_fifo_usedw;
prev_state <= state; prev_state <= state;
END IF; END IF;
END PROCESS; END PROCESS;
-- End address - current address p_wr_burst_size : PROCESS (reg_address_cnt, reg_wr_fifo_usedw)
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)
VARIABLE v_burst_size : POSITIVE; VARIABLE v_burst_size : POSITIVE;
BEGIN 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 -- 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_addresses_rem)>c_margin THEN 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; 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; 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; v_burst_size := v_burst_size - c_margin;
ELSE ELSE
...@@ -155,13 +149,13 @@ BEGIN ...@@ -155,13 +149,13 @@ BEGIN
nxt_wr_burst_size <= v_burst_size; nxt_wr_burst_size <= v_burst_size;
END PROCESS; END PROCESS;
p_rd_burst_size : PROCESS (reg_addresses_rem) p_rd_burst_size : PROCESS (reg_address_cnt)
VARIABLE v_burst_size : POSITIVE; VARIABLE v_burst_size : POSITIVE;
BEGIN BEGIN
-- Read burst size is at least 1 and if more then set to the smallest of g_tech_ddr.maxburstsize and addresses_rem -- 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_addresses_rem)>0 THEN IF UNSIGNED(reg_address_cnt)>0 THEN
v_burst_size := g_tech_ddr.maxburstsize; 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 ELSE
v_burst_size := 1; v_burst_size := 1;
END IF; END IF;
...@@ -173,7 +167,7 @@ BEGIN ...@@ -173,7 +167,7 @@ BEGIN
p_state : PROCESS(prev_state, state, ctlr_init_done, 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, 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 BEGIN
nxt_state <= state; nxt_state <= state;
...@@ -188,6 +182,7 @@ BEGIN ...@@ -188,6 +182,7 @@ BEGIN
nxt_burst_wr_cnt <= burst_wr_cnt; nxt_burst_wr_cnt <= burst_wr_cnt;
nxt_dvr_done <= i_dvr_done; nxt_dvr_done <= i_dvr_done;
nxt_cur_address <= cur_address; nxt_cur_address <= cur_address;
nxt_address_cnt <= address_cnt;
CASE state IS CASE state IS
...@@ -203,7 +198,7 @@ BEGIN ...@@ -203,7 +198,7 @@ BEGIN
WHEN s_wr_request => -- Performs 1 write access and goes into s_wr_burst when requested write words >1 WHEN s_wr_request => -- Performs 1 write access and goes into s_wr_burst when requested write words >1
nxt_state <= s_wait3; 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_dvr_done <= '1';
nxt_state <= s_idle; nxt_state <= s_idle;
ELSIF ctlr_miso.waitrequest_n = '1' THEN ELSIF ctlr_miso.waitrequest_n = '1' THEN
...@@ -219,12 +214,13 @@ BEGIN ...@@ -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 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 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_cur_address <= INCR_UVEC(cur_address, wr_burst_size);
nxt_address_cnt <= INCR_UVEC(address_cnt, -wr_burst_size);
END IF; END IF;
END IF; END IF;
WHEN s_rd_request => -- Posts a read request for a burst (1...g_tech_ddr.maxburstsize) WHEN s_rd_request => -- Posts a read request for a burst (1...g_tech_ddr.maxburstsize)
nxt_state <= s_wait3; 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_dvr_done <= '1';
nxt_state <= s_idle; nxt_state <= s_idle;
ELSE ELSE
...@@ -234,18 +230,19 @@ BEGIN ...@@ -234,18 +230,19 @@ BEGIN
ctlr_mosi.burstbegin <= '1'; -- assert burstbegin, ctlr_mosi.burstbegin <= '1'; -- assert burstbegin,
ctlr_mosi.burstsize <= TO_DDR_CTLR_BURSTSIZE(rd_burst_size); -- burstsize >= 1 ctlr_mosi.burstsize <= TO_DDR_CTLR_BURSTSIZE(rd_burst_size); -- burstsize >= 1
nxt_cur_address <= INCR_UVEC(cur_address, rd_burst_size); 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; END IF;
END IF; END IF;
-- This wait state is inserted between two requests when necessary, e.g. when FSM enters wr_request -- 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 => WHEN s_wait3 =>
IF prev_state = s_wr_request THEN nxt_state <= s_wr_request; END IF; 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; 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 -- In this cycle reg_address_cnt is valid. This cycle is added so wr_burst_size and rd_burst_size
-- (derived from reg_addresses_rem) are valid the next cycle. -- (derived from reg_address_cnt) are valid the next cycle.
WHEN s_wait2 => WHEN s_wait2 =>
IF dvr_wr_not_rd = '1' THEN IF dvr_wr_not_rd = '1' THEN
nxt_state <= s_wr_request; nxt_state <= s_wr_request;
...@@ -253,7 +250,7 @@ BEGIN ...@@ -253,7 +250,7 @@ BEGIN
nxt_state <= s_rd_request; nxt_state <= s_rd_request;
END IF; 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 => WHEN s_wait1 =>
nxt_state <= s_wait2; nxt_state <= s_wait2;
...@@ -261,6 +258,7 @@ BEGIN ...@@ -261,6 +258,7 @@ BEGIN
nxt_dvr_done <= '1'; -- assert dvr_done after s_init or keep it asserted after a finished access nxt_dvr_done <= '1'; -- assert dvr_done after s_init or keep it asserted after a finished access
IF dvr_en = '1' THEN IF dvr_en = '1' THEN
nxt_cur_address <= dvr_start_address; 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_dvr_done <= '0';
nxt_state <= s_wait1; nxt_state <= s_wait1;
END IF; END IF;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment