From bd490884089b39a7fa46e09a6b2704396958d49f Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Fri, 8 May 2015 15:17:08 +0000
Subject: [PATCH] Corrected asserting ctlr_mosi.burstbegin for only one clock
 cycle as specified in the uniphy emi_ip.pdf manual.

---
 libraries/io/ddr/src/vhdl/io_ddr_driver.vhd | 26 ++++++++++++++++-----
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd
index 2d5beb5ba8..346fa6ea9d 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr_driver.vhd
@@ -104,6 +104,8 @@ ARCHITECTURE str OF io_ddr_driver IS
   SIGNAL dvr_done               : STD_LOGIC := '0';
   SIGNAL nxt_dvr_done           : STD_LOGIC;
 
+  SIGNAL burstbegin             : STD_LOGIC;
+  SIGNAL burstbegin_evt         : STD_LOGIC;
   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           : NATURAL  RANGE 0 TO 2**g_tech_ddr.maxburstsize_w-1 := 0;  -- count down from burst_size to 0
@@ -141,6 +143,17 @@ BEGIN
       burst_size       <= nxt_burst_size;
     END IF;
   END PROCESS;
+  
+  -- Using ctrl_mosi.burstbegin <= burstbegin simulates ok with tb_tb_io_ddr.vhd.
+  -- However according to the uniphy external memory interface user guide the ctrl_mosi.burstbegin should only be assered for one clock cycle, independent of ctrl_miso.wait_request_n.
+  -- Therefore use burstbegin_evt to assert ctrl_mosi.burstbegin.
+  u_common_evt : ENTITY common_lib.common_evt
+  PORT MAP (
+    rst      => rst,
+    clk      => clk,
+    in_sig   => burstbegin,
+    out_evt  => burstbegin_evt
+  );
 
   p_burst_size : PROCESS (address_cnt)
   BEGIN 
@@ -162,14 +175,15 @@ BEGIN
   p_state : PROCESS(prev_state, state,
                     dvr_en, dvr_wr_not_rd, dvr_start_address, dvr_nof_data,
                     ctlr_miso, wr_snk_in, rd_src_in, 
-                    burst_size, burst_wr_cnt, cur_address, address_cnt, address_cnt_is_0)
+                    burstbegin_evt, burst_size, burst_wr_cnt, cur_address, address_cnt, address_cnt_is_0)
   BEGIN  
     nxt_state              <= state;
     ctlr_mosi.address      <= RESIZE_MEM_CTLR_ADDRESS(cur_address);  -- no need to hold during burst, because the Avalon constantBurstBehaviour=FALSE (default) of the DDR IP slave
     ctlr_mosi.wrdata       <= RESIZE_MEM_CTLR_DATA(wr_snk_in.data);
     ctlr_mosi.wr           <= '0';
     ctlr_mosi.rd           <= '0';
-    ctlr_mosi.burstbegin   <= '0';                                   -- only used for legacy DDR controllers, because the controller can derive it internally by counting wr and rd accesses
+    burstbegin             <= '0';                                   -- use burstbegin and burstbegin_evt to assert ctrl_mosi.burstbegin for one clock cylce only, independent of ctrl_miso.wait_request_n
+    ctlr_mosi.burstbegin   <= burstbegin_evt;                        -- only used for legacy DDR controllers, because the controller can derive it internally by counting wr and rd accesses
     ctlr_mosi.burstsize    <= TO_MEM_CTLR_BURSTSIZE(burst_size);     -- burstsize >= 1,
                                                                      -- no need to hold during burst, because the Avalon constantBurstBehaviour=FALSE (default) of the DDR IP slave
     wr_snk_out.xon         <= '1';                                   -- xon is fixed '1'
@@ -198,8 +212,8 @@ BEGIN
           nxt_dvr_done  <= '1';              
           nxt_state     <= s_idle;
         ELSIF wr_snk_in.valid = '1' THEN
-          ctlr_mosi.wr         <= '1';
-          ctlr_mosi.burstbegin <= '1';                                -- assert burstbegin,
+          ctlr_mosi.wr  <= '1';
+          burstbegin    <= '1';                                -- assert ctlr_mosi.burstbegin for one clock cycle only
           IF ctlr_miso.waitrequest_n = '1' THEN 
             -- Always perform 1st write here             
             wr_snk_out.ready     <= '1';
@@ -219,8 +233,8 @@ BEGIN
           nxt_dvr_done  <= '1';              
           nxt_state     <= s_idle;
         ELSIF rd_src_in.ready = '1' THEN  -- the external FIFO uses almost full level assert its snk_out.ready and can then still accept the maximum rd burst of words
-          ctlr_mosi.rd         <= '1';                   
-          ctlr_mosi.burstbegin <= '1';                                -- assert burstbegin,
+          ctlr_mosi.rd  <= '1';                   
+          burstbegin    <= '1';                                -- assert ctlr_mosi.burstbegin for one clock cycle only
           IF ctlr_miso.waitrequest_n = '1' THEN
             nxt_cur_address      <= INCR_UVEC(cur_address, burst_size);  
             nxt_address_cnt      <= INCR_UVEC(address_cnt, -burst_size);
-- 
GitLab