From 674906088f1e639ddb9668d79adcce92f1c8af2b Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Thu, 12 Feb 2015 09:53:28 +0000
Subject: [PATCH] Added tx_cnt_arr to MM reg. Added g_mm_broadcast to select
 for single or multi MM port control.

---
 .../base/diag/src/vhdl/mms_diag_tx_seq.vhd    | 146 ++++++++++++------
 1 file changed, 98 insertions(+), 48 deletions(-)

diff --git a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
index f36ac1e53b..9e5c5e6a6b 100644
--- a/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
+++ b/libraries/base/diag/src/vhdl/mms_diag_tx_seq.vhd
@@ -24,17 +24,28 @@
 -- Description:
 --
 --   Each DP stream has its own diag_tx_seq, because each stream can have its
---   own flow control.
---
---   One MM control register sets all g_nof_streams:
+--   own flow control. Each DP stream also has its own MM control register to
+--   support reading tx_cnt per stream.
 --
 --   31             24 23             16 15              8 7               0  wi
 --  |-----------------|-----------------|-----------------|-----------------|
 --  |                                            select = [1], enable = [0] |  0
 --  |-----------------------------------------------------------------------|
---  |                                   init[31: 0]                         |  1
+--  |                                   init[31:0]                          |  1
+--  |-----------------------------------------------------------------------|
+--  |                                 tx_cnt[31:0]                          |  2
 --  |-----------------------------------------------------------------------|
 --
+-- . g_nof_streams
+--   The MM control register for stream I in 0:g_nof_streams-1 starts at word
+--   index wi = I * 2**c_mm_reg.adr_w.
+--
+-- . g_mm_broadcast
+--   Use default g_mm_broadcast=FALSE for multiplexed individual MM access to
+--   each reg_mosi_arr/reg_miso_arr MM port. When g_mm_broadcast=TRUE then a
+--   write access to MM port [0] is passed on to all ports and a read access
+--   is done from MM port [0]. The other MM array ports cannot be read then.
+--
 -- . g_seq_dat_w
 --   The g_seq_dat_w must be >= 1. The DP streaming data field is
 --   c_dp_stream_data_w bits wide and the REPLICATE_DP_DATA() is used to wire
@@ -48,6 +59,12 @@
 -- . diag_init
 --   Note that MM diag_init has c_word_w=32 bits, so if g_seq_dat_w is wider
 --   then the MSbits are 0 and if it is smaller, then the MSbits are ignored.
+--
+-- . tx_cnt
+--   Counts the number of valid output data that was transmitted onstream 0
+--   since diag_en went active. An incrementing tx_cnt shows that data is
+--   being transmitted.
+--
 
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.std_logic_1164.ALL;
@@ -57,8 +74,9 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY mms_diag_tx_seq IS
   GENERIC (
-    g_nof_streams : NATURAL := 1;
-    g_seq_dat_w   : NATURAL := c_word_w  -- >= 1, test sequence data width
+    g_mm_broadcast : BOOLEAN := FALSE;
+    g_nof_streams  : NATURAL := 1;
+    g_seq_dat_w    : NATURAL := c_word_w  -- >= 1, test sequence data width
   );
   PORT (
     -- Clocks and reset
@@ -82,33 +100,43 @@ ARCHITECTURE str OF mms_diag_tx_seq IS
   
   -- Define the actual size of the MM slave register
   CONSTANT c_mm_reg      : t_c_mem  := (latency  => 1,
-                                        adr_w    => 1,
+                                        adr_w    => 2,
                                         dat_w    => c_word_w,       -- Use MM bus data width = c_word_w = 32 for all MM registers
-                                        nof_dat  => 2,
+                                        nof_dat  => 3,
                                         init_sl  => '0');
 
-  TYPE t_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
+  CONSTANT c_reg_slv_w   : NATURAL := c_mm_reg.nof_dat*c_mm_reg.dat_w;
+  
+  TYPE t_reg_slv_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_reg_slv_w-1 DOWNTO 0);
+  TYPE t_seq_dat_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0);
   TYPE t_replicate_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_dp_stream_data_w-1 DOWNTO 0);
   
+  SIGNAL reg_mosi_arr          : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL reg_miso_arr          : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
+  
   -- Registers in dp_clk domain
-  SIGNAL ctrl_reg       : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL ctrl_reg_arr          : t_reg_slv_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+  SIGNAL stat_reg_arr          : t_reg_slv_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+  
+  SIGNAL diag_en_arr           : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL diag_sel_arr          : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
   
-  SIGNAL diag_en        : STD_LOGIC;
-  SIGNAL diag_sel       : STD_LOGIC;
-  SIGNAL diag_init_mm   : STD_LOGIC_VECTOR(c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
-  SIGNAL diag_init      : STD_LOGIC_VECTOR(g_seq_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL diag_init_mm_arr      : t_slv_32_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));  -- can use t_slv_32_arr because c_mm_reg.dat_w = c_word_w = 32 fixed
+  SIGNAL diag_init_arr         : t_seq_dat_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
   
-  SIGNAL tx_dat_arr     : t_dat_arr(g_nof_streams-1 DOWNTO 0);
-  SIGNAL tx_val_arr     : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
-  SIGNAL tx_req_arr     : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_cnt_arr            : t_slv_32_arr(g_nof_streams-1 DOWNTO 0);  -- can use t_slv_32_arr because c_mm_reg.dat_w = c_word_w = 32 fixed
+  SIGNAL tx_dat_arr            : t_seq_dat_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_val_arr            : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_req_arr            : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0);
 
-  SIGNAL tx_replicate_arr  : t_replicate_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL tx_replicate_dat_arr  : t_dp_data_slv_arr(g_nof_streams-1 DOWNTO 0);
   
 BEGIN
 
   gen_nof_streams: FOR I IN 0 to g_nof_streams-1 GENERATE
     u_diag_tx_seq: ENTITY WORK.diag_tx_seq
     GENERIC MAP (
+      g_cnt_w    => c_word_w,
       g_dat_w    => g_seq_dat_w
     )
     PORT MAP (
@@ -116,53 +144,75 @@ BEGIN
       clk      => dp_clk,
 
       -- Write and read back registers:
-      diag_en  => diag_en,
-      diag_sel => diag_sel,
-      diag_dat => diag_init,
+      diag_en  => diag_en_arr(I),
+      diag_sel => diag_sel_arr(I),
+      diag_dat => diag_init_arr(I),
 
       -- Streaming
       diag_req => tx_req_arr(I),
+      out_cnt  => tx_cnt_arr(I),
       out_dat  => tx_dat_arr(I),
       out_val  => tx_val_arr(I)
     );
     
     tx_req_arr(I) <= tx_src_in_arr(I).ready;
     
+    tx_replicate_dat_arr(I) <= REPLICATE_DP_DATA(tx_dat_arr(I));
     
-    tx_replicate_arr(I) <= REPLICATE_DP_DATA(tx_dat_arr(I));
-    
-    -- for some reason the intermediate tx_replicate_arr() signal is needed, otherwise the assignment to the tx_src_out_arr().data field remains void in the Wave window
-    tx_src_out_arr(I).data  <= tx_replicate_arr(I);
+    -- for some reason the intermediate tx_replicate_dat_arr() signal is needed, otherwise the assignment to the tx_src_out_arr().data field remains void in the Wave window
+    tx_src_out_arr(I).data  <= tx_replicate_dat_arr(I);
     tx_src_out_arr(I).valid <= tx_val_arr(I);
-  END GENERATE;
 
-  -- Register mapping
-  diag_en      <= ctrl_reg(                           0);  -- address 0, data bit [0]
-  diag_sel     <= ctrl_reg(                           1);  -- address 0, data bit [1]
-  diag_init_mm <= ctrl_reg(2*c_word_w-1 DOWNTO c_word_w);  -- address 1, data bits [31:0]
+    -- Register mapping
+    diag_en_arr(I)      <= ctrl_reg_arr(I)(                           0);  -- address 0, data bit [0]
+    diag_sel_arr(I)     <= ctrl_reg_arr(I)(                           1);  -- address 0, data bit [1]
+    diag_init_mm_arr(I) <= ctrl_reg_arr(I)(2*c_word_w-1 DOWNTO c_word_w);  -- address 1, data bits [31:0]
+    
+    diag_init_arr(I)    <= RESIZE_UVEC(diag_init_mm_arr(I), g_seq_dat_w);
+  
+    p_stat_reg : PROCESS(ctrl_reg_arr(I), tx_cnt_arr)
+    BEGIN
+      -- Default write / readback:
+      stat_reg_arr(I) <= ctrl_reg_arr(I);                                 -- address 0, 1: control read back
+      -- Status read only:
+      stat_reg_arr(I)(3*c_word_w-1 DOWNTO 2*c_word_w) <= tx_cnt_arr(I);   -- address 2: read tx_cnt
+    END PROCESS;
   
-  diag_init    <= RESIZE_UVEC(diag_init_mm, g_seq_dat_w);
+    u_reg : ENTITY common_lib.common_reg_r_w_dc
+    GENERIC MAP (
+      g_cross_clock_domain => TRUE,
+      g_readback           => FALSE,  -- must use FALSE for write/read or read only register when g_cross_clock_domain=TRUE
+      g_reg                => c_mm_reg
+    )
+    PORT MAP (
+      -- Clocks and reset
+      mm_rst      => mm_rst,
+      mm_clk      => mm_clk,
+      st_rst      => dp_rst,
+      st_clk      => dp_clk,
+      
+      -- Memory Mapped Slave in mm_clk domain
+      sla_in      => reg_mosi_arr(I),
+      sla_out     => reg_miso_arr(I),
+      
+      -- MM registers in dp_clk domain
+      in_reg      => stat_reg_arr(I),  -- connect out_reg to in_reg for write and readback register
+      out_reg     => ctrl_reg_arr(I)
+    );
+  END GENERATE;
 
-  u_reg : ENTITY common_lib.common_reg_r_w_dc
+  -- Combine the internal array of mm interfaces for the bg_data to one array that is connected to the port of the MM bus
+  u_mem_mux : ENTITY common_lib.common_mem_mux
   GENERIC MAP (
-    g_cross_clock_domain => TRUE,
-    g_readback           => TRUE,  -- using TRUE fits for write and readback register
-    g_reg                => c_mm_reg
+    g_broadcast   => g_mm_broadcast,    
+    g_nof_mosi    => g_nof_streams,
+    g_mult_addr_w => c_mm_reg.adr_w
   )
   PORT MAP (
-    -- Clocks and reset
-    mm_rst      => mm_rst,
-    mm_clk      => mm_clk,
-    st_rst      => dp_rst,
-    st_clk      => dp_clk,
-    
-    -- Memory Mapped Slave in mm_clk domain
-    sla_in      => reg_mosi,
-    sla_out     => reg_miso,
-    
-    -- MM registers in dp_clk domain
-    in_reg      => ctrl_reg,  -- connect out_reg to in_reg for write and readback register
-    out_reg     => ctrl_reg
+    mosi     => reg_mosi,
+    miso     => reg_miso,
+    mosi_arr => reg_mosi_arr,
+    miso_arr => reg_miso_arr
   );
   
 END str;
-- 
GitLab