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
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;
......
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