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