From 61f16974f28d9078e750b7aa3fd18910c7068a29 Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Fri, 12 Jun 2015 07:49:17 +0000
Subject: [PATCH] Provide streaming access to IO_DDR using a Tx seq and a Rx
 seq with optional DB RAM.

---
 libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd | 244 +++++++-----------
 1 file changed, 93 insertions(+), 151 deletions(-)

diff --git a/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd
index f8782e879b..77aa8eac19 100644
--- a/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd
+++ b/libraries/io/ddr/src/vhdl/mms_io_ddr_diag.vhd
@@ -19,14 +19,29 @@
 --
 -------------------------------------------------------------------------------
 
--- Purpose: Provide streaming access to IO_DDR using a BG and a DB
+-- Purpose: Provide streaming access to IO_DDR using a Tx seq and a Rx seq with optional DB RAM
 -- Description:
---                                   
---       BG ----> IO_DDR ----> DB
---        |         |          |
---        |         |          |
---   MM --+---------+----------+--
+--   The BG Tx seq stream writes the DDR and the read stream is passed on to the DB Rx seq. The BG
+--   block generation and BG RAM are not used. The DB RAM can be used for extra read data monitoring.
+--   The DDR write and read access is controlled via the driver MM interface of the mms_io_ddr.
 --
+--                              DB RAM
+--        Tx seq --> IO_DDR --> Rx seq
+--           |         |          |
+--           |         |          |
+--      MM --+---------+----------+--
+--
+-- Remark:
+-- . The ratio of g_dp_data_w and func_tech_ddr_ctlr_data_w(g_io_tech_ddr)must be a power of 2 due to the mixed width FIFO. By
+--   using a wider g_dp_data_w the DDR data access rate can be increased to the maximum that is possible for the DDR memory.
+--   - For DDR3 with ctrl_data_w = dq_w * rsl = 64 * 4 = 256 choose g_dp_data_w e.g. 16, 32, 64, 128, 256, 512.
+--   - For DDR4 with ctrl_data_w = dq_w * rsl = 72 * 8 = 576 choose g_dp_data_w e.g. 18, 36, 72, 144, 288, 576, 1152.
+-- . The DB RAM gets refilled with new read data from the DDR after the last word has been read via the MM.
+-- . The DB RAM only captures the lowest c_word_w=32 bits of the g_dp_data_w. This fits the MM bus data width
+--   and it is sufficient because typically g_dp_seq_dat_w <= c_word_w.
+-- . This component could have user write input and user read output. The constraint is that the user DDR access is suitable for:
+--   - MM control of the mms_io_ddr to issue a write or a read access.
+--   - g_wr_flush_mode="VAL" in the io_ddr, because that the Tx seq source does not use "SOP" or "SYNC"
 
 LIBRARY IEEE, common_lib, dp_lib, diag_lib, technology_lib, tech_ddr_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
@@ -40,68 +55,28 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL;
 
 ENTITY mms_io_ddr_diag IS
   GENERIC (
-    ---------------------------------------------------------------------------
-    -- IO_DDR
-    ---------------------------------------------------------------------------
-    g_io_technology              : NATURAL := c_tech_select_default;
-    g_io_tech_ddr                : t_c_tech_ddr;
-    g_io_cross_domain_dvr_ctlr   : BOOLEAN := TRUE;
-    g_io_cross_domain_delay_len  : NATURAL := c_meta_delay_len;
-    g_io_wr_data_w               : NATURAL := 32;
-    g_io_wr_fifo_depth           : NATURAL := 256;     -- >=16                             , defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K
-    g_io_rd_fifo_depth           : NATURAL := 256;     -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K
-    g_io_rd_fifo_af_margin       : NATURAL := 4 + 1*64;  -- < g_rd_fifo_depth and sufficient to fit one or more rd burst accesses of g_tech_ddr.maxburstsize each
-    g_io_rd_data_w               : NATURAL := 32;
-    g_io_wr_flush_mode           : STRING := "VAL";  -- "VAL", "SOP", "SYN"
-    g_io_wr_flush_use_channel    : BOOLEAN := FALSE;
-    g_io_wr_flush_start_channel  : NATURAL := 0;
-    g_io_wr_flush_nof_channels   : POSITIVE := 1;
+    -- System
+    g_technology      : NATURAL := c_tech_select_default;
     
-    ---------------------------------------------------------------------------
-    -- DIAG block generator
-    ---------------------------------------------------------------------------
-    -- Generate configurations
-    g_bg_use_usr_input      : BOOLEAN := FALSE;
-    g_bg_use_bg             : BOOLEAN := TRUE;
-    g_bg_use_tx_seq         : BOOLEAN := FALSE;
-    -- General
-    g_bg_nof_streams        : POSITIVE := 1;
-    -- BG settings
-    g_bg_use_bg_buffer_ram  : BOOLEAN := TRUE;
-    g_bg_buf_dat_w          : POSITIVE := 32;
-    g_bg_buf_addr_w         : POSITIVE := 7;                -- Waveform buffer size 2**g_buf_addr_w nof samples
-    g_bg_file_index_arr     : t_nat_natural_arr := array_init(0, 128, 1);  -- default use the instance index as file index 0, 1, 2, 3, 4 ...
-    g_bg_file_name_prefix   : STRING := "data/bf_in_data";  -- Path to the hex files that contain the initial data for the memories. The sequence number and ".hex" are added within the entity.
-    g_bg_diag_block_gen_rst : t_diag_block_gen := c_diag_block_gen_rst;
-    -- User input multiplexer option
-    g_bg_usr_bypass_xonoff  : BOOLEAN := FALSE;
-    -- Tx_seq
-    g_bg_seq_dat_w          : NATURAL := 32;  -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_buf_dat_w
+    g_dp_data_w       : NATURAL := 32;  -- DP data width, func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_dp_data_w must be a power of 2 due to the mixed width FIFO
+    g_dp_seq_dat_w    : NATURAL := 32;  -- >= 1, test sequence data width. Choose g_dp_seq_dat_w <= g_dp_data_w. The seq data gets replicated to fill g_dp_data_w.
+    g_dp_fifo_depth   : NATURAL := 2048;  -- >= 2048, write FIFO depth and read FIFO depth at DP side of the FIFOs
+    
+    -- IO_DDR
+    g_io_tech_ddr     : t_c_tech_ddr;
     
-    ---------------------------------------------------------------------------
     -- DIAG data buffer
-    ---------------------------------------------------------------------------
-    -- Generate configurations
-    g_db_use_db       : BOOLEAN := TRUE;
-    g_db_use_rx_seq   : BOOLEAN := FALSE;
-    -- General
-    g_db_nof_streams  : POSITIVE := 16;    -- each stream gets an data buffer
-    -- DB settings
-    g_db_data_type    : t_diag_data_type_enum := e_data;      -- define the sosi field that gets stored: e_data=data, e_complex=im&re, e_real=re, e_imag=im
-    g_db_data_w       : NATURAL := 32;     -- the g_data_w is the width of the data, re, im values or of the combined im&re value
-    g_db_buf_nof_data : NATURAL := 1024;   -- nof words per data buffer
-    g_db_buf_use_sync : BOOLEAN := FALSE;  -- when TRUE start filling the buffer at the in_sync, else after the last word was read
-    -- Rx_seq
-    g_db_seq_dat_w    : NATURAL := 32  -- >= 1, test sequence data width. Choose g_seq_dat_w <= g_data_w
+    g_db_use_db       : BOOLEAN := FALSE;
+    g_db_buf_nof_data : NATURAL := 1024    -- nof words per data buffer
   );
   PORT (
     ---------------------------------------------------------------------------
     -- System
     ---------------------------------------------------------------------------
-    mm_clk           : IN  STD_LOGIC;
-    mm_rst           : IN  STD_LOGIC;
-    dp_clk           : IN  STD_LOGIC;
-    dp_rst           : IN  STD_LOGIC;
+    mm_rst              : IN  STD_LOGIC;
+    mm_clk              : IN  STD_LOGIC;
+    dp_rst              : IN  STD_LOGIC;
+    dp_clk              : IN  STD_LOGIC;  -- use alternative external clock or externally connect to ctlr_clk_out
     
     ---------------------------------------------------------------------------
     -- IO_DDR
@@ -121,25 +96,11 @@ ENTITY mms_io_ddr_diag IS
     reg_io_ddr_mosi     : IN    t_mem_mosi := c_mem_mosi_rst;  -- register for DDR controller status info
     reg_io_ddr_miso     : OUT   t_mem_miso;
 
-    dvr_clk             : IN    STD_LOGIC;
-    dvr_rst             : IN    STD_LOGIC;
-
-    -- Write FIFO clock domain
-    wr_clk              : IN    STD_LOGIC;
-    wr_rst              : IN    STD_LOGIC;
-
-    wr_fifo_usedw       : OUT   STD_LOGIC_VECTOR(ceil_log2(g_io_wr_fifo_depth * (func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_io_wr_data_w) )-1 DOWNTO 0);  -- for monitoring purposes
-    wr_sosi             : IN    t_dp_sosi;
-    wr_siso             : OUT   t_dp_siso;
-
-    -- Read FIFO clock domain
-    rd_clk              : IN    STD_LOGIC;
-    rd_rst              : IN    STD_LOGIC;
-
-    rd_fifo_usedw       : OUT   STD_LOGIC_VECTOR(ceil_log2(g_io_rd_fifo_depth * (func_tech_ddr_ctlr_data_w(g_io_tech_ddr)/g_io_rd_data_w) )-1 DOWNTO 0);
-    rd_sosi             : OUT   t_dp_sosi;
-    rd_siso             : IN    t_dp_siso;
+    -- Write / read FIFO status for monitoring purposes (in dp_clk domain)
+    wr_fifo_usedw       : OUT   STD_LOGIC_VECTOR(ceil_log2(g_dp_fifo_depth)-1 DOWNTO 0);
+    rd_fifo_usedw       : OUT   STD_LOGIC_VECTOR(ceil_log2(g_dp_fifo_depth)-1 DOWNTO 0);
 
+    -- DDR3 pass on termination control from master to slave controller
     term_ctrl_out       : OUT   t_tech_ddr3_phy_terminationcontrol;
     term_ctrl_in        : IN    t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst;
 
@@ -154,24 +115,14 @@ ENTITY mms_io_ddr_diag IS
     phy4_ou             : OUT   t_tech_ddr4_phy_ou;
 
     ---------------------------------------------------------------------------
-    -- DIAG block generator
+    -- DIAG Tx seq
     ---------------------------------------------------------------------------
     -- MM interface
-    reg_bg_ctrl_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  -- BG control register (one for all streams)
-    reg_bg_ctrl_miso : OUT t_mem_miso;
-    ram_bg_data_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  -- BG buffer RAM (one per stream)
-    ram_bg_data_miso : OUT t_mem_miso;
     reg_tx_seq_mosi  : IN  t_mem_mosi := c_mem_mosi_rst;  -- Tx seq control (one per stream because c_reg_tx_seq_broadcast=FALSE)
     reg_tx_seq_miso  : OUT t_mem_miso;
-    -- ST interface
-    bg_sync          : IN  STD_LOGIC := '1';              -- block generator enable sync pulse in ST dp_clk domain
-    usr_siso_arr     : OUT t_dp_siso_arr(g_bg_nof_streams-1 DOWNTO 0);  -- connect when g_use_usr_input=TRUE, else leave not connected
-    usr_sosi_arr     : IN  t_dp_sosi_arr(g_bg_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst);
-    out_siso_arr     : IN  t_dp_siso_arr(g_bg_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);  -- Default xon='1'
-    out_sosi_arr     : OUT t_dp_sosi_arr(g_bg_nof_streams-1 DOWNTO 0);  -- Output SOSI that contains the waveform data
-
+    
     ---------------------------------------------------------------------------
-    -- DIAG data buffer
+    -- DIAG rx seq with optional data buffer
     ---------------------------------------------------------------------------
     -- MM interface
     reg_data_buf_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  -- DB control register (one per stream)
@@ -181,17 +132,23 @@ ENTITY mms_io_ddr_diag IS
     ram_data_buf_miso : OUT t_mem_miso;
 
     reg_rx_seq_mosi   : IN  t_mem_mosi := c_mem_mosi_rst;  -- Rx seq control register (one per streams)
-    reg_rx_seq_miso   : OUT t_mem_miso;
-
-    -- ST interface
-    db_sync           : IN  STD_LOGIC := '0';  -- input sync pulse in ST dp_clk domain that starts data buffer when g_use_in_sync = TRUE
-    in_sosi_arr       : IN t_dp_sosi_arr(g_db_nof_streams-1 DOWNTO 0)
+    reg_rx_seq_miso   : OUT t_mem_miso
   );
 END mms_io_ddr_diag;
 
 
 ARCHITECTURE str OF mms_io_ddr_diag IS
 
+  CONSTANT c_io_wr_fifo_depth      : NATURAL := (g_dp_fifo_depth * g_dp_data_w) / func_tech_ddr_ctlr_data_w(g_io_tech_ddr);     -- >=16                             , defined at DDR side of the FIFO
+  CONSTANT c_io_rd_fifo_depth      : NATURAL := (g_dp_fifo_depth * g_dp_data_w) / func_tech_ddr_ctlr_data_w(g_io_tech_ddr);     -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO, default 256 because 32b*256 fits in 1 M9K
+  CONSTANT c_io_rd_fifo_af_margin  : NATURAL := 4 + 1*64;  -- < c_io_rd_fifo_depth and sufficient to fit one or more rd burst accesses of g_io_tech_ddr.maxburstsize each
+    
+  SIGNAL bg_siso_arr     : t_dp_siso_arr(0 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);  -- Default xon='1'
+  SIGNAL bg_sosi_arr     : t_dp_sosi_arr(0 DOWNTO 0);                             -- Output SOSI that contains the waveform data
+
+  SIGNAL db_siso_arr     : t_dp_siso_arr(0 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);  -- Default ready='1'
+  SIGNAL db_sosi_arr     : t_dp_sosi_arr(0 DOWNTO 0);
+
 BEGIN
 
   ------------------------------------------------------------------------------
@@ -199,19 +156,19 @@ BEGIN
   ------------------------------------------------------------------------------
   u_mms_io_ddr : ENTITY work.mms_io_ddr
   GENERIC MAP (
-    g_technology              => g_io_technology,
+    g_technology              => g_technology,
     g_tech_ddr                => g_io_tech_ddr,
-    g_cross_domain_dvr_ctlr   => g_io_cross_domain_dvr_ctlr,
-    g_cross_domain_delay_len  => g_io_cross_domain_delay_len,
-    g_wr_data_w               => g_io_wr_data_w,
-    g_wr_fifo_depth           => g_io_wr_fifo_depth,
-    g_rd_fifo_depth           => g_io_rd_fifo_depth,
-    g_rd_fifo_af_margin       => g_io_rd_fifo_af_margin,
-    g_rd_data_w               => g_io_rd_data_w,
-    g_wr_flush_mode           => g_io_wr_flush_mode,
-    g_wr_flush_use_channel    => g_io_wr_flush_use_channel,
-    g_wr_flush_start_channel  => g_io_wr_flush_start_channel,
-    g_wr_flush_nof_channels   => g_io_wr_flush_nof_channels
+    g_cross_domain_dvr_ctlr   => TRUE,  -- cross between mm_clk and ctlr_clk_in
+    g_cross_domain_delay_len  => c_meta_delay_len,
+    g_wr_data_w               => g_dp_data_w,
+    g_wr_fifo_depth           => c_io_wr_fifo_depth,
+    g_rd_fifo_depth           => c_io_rd_fifo_depth,
+    g_rd_fifo_af_margin       => c_io_rd_fifo_af_margin,
+    g_rd_data_w               => g_dp_data_w,
+    g_wr_flush_mode           => "VAL",
+    g_wr_flush_use_channel    => FALSE,
+    g_wr_flush_start_channel  => 0,
+    g_wr_flush_nof_channels   => 1
   )
   PORT MAP (
     -- DDR reference clock
@@ -233,24 +190,24 @@ BEGIN
     reg_io_ddr_mosi     => reg_io_ddr_mosi,
     reg_io_ddr_miso     => reg_io_ddr_miso,
 
-    dvr_clk             => dvr_clk,
-    dvr_rst             => dvr_rst,
+    dvr_clk             => mm_clk,
+    dvr_rst             => mm_rst,
 
     -- Write FIFO clock domain
-    wr_clk              => wr_clk,
-    wr_rst              => wr_rst,
+    wr_clk              => dp_clk,
+    wr_rst              => dp_rst,
 
     wr_fifo_usedw       => wr_fifo_usedw,
-    wr_sosi             => wr_sosi,
-    wr_siso             => wr_siso,
+    wr_sosi             => bg_sosi_arr(0),
+    wr_siso             => bg_siso_arr(0),
 
     -- Read FIFO clock domain
-    rd_clk              => rd_clk,
-    rd_rst              => rd_rst,
+    rd_clk              => dp_clk,
+    rd_rst              => dp_rst,
 
     rd_fifo_usedw       => rd_fifo_usedw,
-    rd_sosi             => rd_sosi,
-    rd_siso             => rd_siso,
+    rd_sosi             => db_sosi_arr(0),
+    rd_siso             => db_siso_arr(0),
 
     term_ctrl_out       => term_ctrl_out,
     term_ctrl_in        => term_ctrl_in,
@@ -267,27 +224,20 @@ BEGIN
   );
 
   -----------------------------------------------------------------------------
-  -- DIAG Block Generator
+  -- DIAG Tx seq
   -----------------------------------------------------------------------------
   u_mms_diag_block_gen: ENTITY diag_lib.mms_diag_block_gen
   GENERIC MAP (
     -- Generate configurations
-    g_use_usr_input      => g_bg_use_usr_input,
-    g_use_bg             => g_bg_use_bg,
-    g_use_tx_seq         => g_bg_use_tx_seq,
+    g_use_usr_input      => FALSE,
+    g_use_bg             => FALSE,
+    g_use_tx_seq         => TRUE,
     -- General
-    g_nof_streams        => g_bg_nof_streams,
+    g_nof_streams        => 1,
     -- BG settings
-    g_use_bg_buffer_ram  => g_bg_use_bg_buffer_ram,
-    g_buf_dat_w          => g_bg_buf_dat_w,
-    g_buf_addr_w         => g_bg_buf_addr_w,
-    g_file_index_arr     => g_bg_file_index_arr,
-    g_file_name_prefix   => g_bg_file_name_prefix,
-    g_diag_block_gen_rst => g_bg_diag_block_gen_rst,
-    -- User input multiplexer option
-    g_usr_bypass_xonoff  => g_bg_usr_bypass_xonoff,
+    g_use_bg_buffer_ram  => FALSE,
     -- Tx_seq
-    g_seq_dat_w          => g_bg_seq_dat_w
+    g_seq_dat_w          => g_dp_seq_dat_w
   )
   PORT MAP (
     -- System
@@ -295,38 +245,31 @@ BEGIN
     mm_clk           => mm_clk,
     dp_rst           => dp_rst,
     dp_clk           => dp_clk,
-    en_sync          => bg_sync,
     -- MM interface
-    reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
-    reg_bg_ctrl_miso => reg_bg_ctrl_miso,
-    ram_bg_data_mosi => ram_bg_data_mosi,
-    ram_bg_data_miso => ram_bg_data_miso,
     reg_tx_seq_mosi  => reg_tx_seq_mosi,
     reg_tx_seq_miso  => reg_tx_seq_miso,
     -- ST interface
-    usr_siso_arr     => usr_siso_arr,
-    usr_sosi_arr     => usr_sosi_arr,
-    out_siso_arr     => out_siso_arr,
-    out_sosi_arr     => out_sosi_arr
+    out_siso_arr     => bg_siso_arr,
+    out_sosi_arr     => bg_sosi_arr
   );
-
+  
   -----------------------------------------------------------------------------
-  -- DIAG Data Buffer
+  -- DIAG Rx seq with optional Data Buffer
   -----------------------------------------------------------------------------
   u_mms_diag_data_buffer: ENTITY diag_lib.mms_diag_data_buffer
   GENERIC MAP (
     -- Generate configurations
     g_use_db       => g_db_use_db,
-    g_use_rx_seq   => g_db_use_rx_seq,
+    g_use_rx_seq   => TRUE,
     -- General
-    g_nof_streams  => g_db_nof_streams,
+    g_nof_streams  => 1,
     -- DB settings
-    g_data_type    => g_db_data_type,
-    g_data_w       => g_db_data_w,
+    g_data_type    => e_data,      -- define the sosi field that gets stored: e_data=data, e_complex=im&re, e_real=re, e_imag=im,
+    g_data_w       => c_word_w,    -- only capture the lowest c_word_w=32 bits of the g_dp_data_w
     g_buf_nof_data => g_db_buf_nof_data,
-    g_buf_use_sync => g_db_buf_use_sync,
+    g_buf_use_sync => FALSE,       -- when TRUE start filling the buffer at the in_sync, else after the last word was read,
     -- Rx_seq
-    g_seq_dat_w    => g_db_seq_dat_w
+    g_seq_dat_w    => g_dp_seq_dat_w
   )
   PORT MAP (
     -- System
@@ -343,8 +286,7 @@ BEGIN
     reg_rx_seq_miso   => reg_rx_seq_miso,
 
     -- ST interface
-    in_sync           => db_sync,
-    in_sosi_arr       => in_sosi_arr
+    in_sosi_arr       => db_sosi_arr
   );
 
 END str;
-- 
GitLab