From 68dda3e8749a49482720eb534d18cb2fc050e370 Mon Sep 17 00:00:00 2001
From: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
Date: Wed, 31 Aug 2016 23:32:24 +0200
Subject: [PATCH] swcore: swc_ll_read_data_validate supports generic number of
 write interfaces

---
 .../swc_ll_read_data_validation.vhd           | 111 +++++++++++-------
 modules/wrsw_swcore/swc_swcore_pkg.vhd        |  12 +-
 2 files changed, 75 insertions(+), 48 deletions(-)

diff --git a/modules/wrsw_swcore/swc_ll_read_data_validation.vhd b/modules/wrsw_swcore/swc_ll_read_data_validation.vhd
index 620d82c8..7e72376c 100644
--- a/modules/wrsw_swcore/swc_ll_read_data_validation.vhd
+++ b/modules/wrsw_swcore/swc_ll_read_data_validation.vhd
@@ -3,10 +3,10 @@
 -- Project    : WhiteRabbit switch
 -------------------------------------------------------------------------------
 -- File       : swc_ll_read_data_validation.vhd
--- Author     : Maciej Lipinski
+-- Author     : Maciej Lipinski, Grzegorz Daniluk
 -- Company    : CERN BE-Co-HT
 -- Created    : 2012-01-30
--- Last update: 2012-01-30
+-- Last update: 2016-08-31
 -- Platform   : FPGA-generic
 -- Standard   : VHDL'87
 -------------------------------------------------------------------------------
@@ -23,7 +23,7 @@
 -- can overtake the writting process.
 -------------------------------------------------------------------------------
 --
--- Copyright (c) 2012 CERN / BE-CO-HT
+-- Copyright (c) 2012-2016 CERN / BE-CO-HT
 --
 -- This source file is free software; you can redistribute it   
 -- and/or modify it under the terms of the GNU Lesser General   
@@ -51,16 +51,19 @@
 library ieee;
 use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
+use ieee.std_logic_misc.all;
 
 
 library work;
 use work.swc_swcore_pkg.all;
 use work.genram_pkg.all;
+use work.gencores_pkg.all;
 
 entity swc_ll_read_data_validation is
   generic(
-     g_addr_width : integer ;--:= c_swc_page_addr_width;
-     g_data_width : integer --:= c_swc_page_addr_width
+     g_addr_width : integer;
+     g_data_width : integer;
+     g_wports     : integer
   );
   port(
      clk_i                 : in std_logic;
@@ -80,10 +83,9 @@ entity swc_ll_read_data_validation is
      read_data_ready_i     : in std_logic;
      
      -- data being written to DPRAM
-     write_addr_i          : in std_logic_vector(g_addr_width - 1 downto 0);
-     write_data_i          : in std_logic_vector(g_data_width - 1 downto 0);
-     write_data_valid_i    : in std_logic;
-     write_data_ready_i    : in std_logic;
+     write_addr_i          : in t_lladr_array(g_wports-1 downto 0);
+     write_data_i          : in t_lldat_array(g_wports-1 downto 0);
+     write_data_ready_i    : in std_logic_vector(g_wports-1 downto 0);
 
      -- data read from multiport_linked_list module
      read_data_o          : out std_logic_vector(g_data_width - 1 downto 0);
@@ -94,25 +96,46 @@ entity swc_ll_read_data_validation is
 
 architecture syn of swc_ll_read_data_validation is
 
-  signal valid_data_read       : std_logic; -- data read from the DPRAM is valid (page address written)
-  signal nonvalid_data_read    : std_logic; -- data in DPRAM is not valid (the page is being written to)
-  signal valid_data_write      : std_logic; -- valid data is being written to the address we are hooked to
-  signal valid_data_write_d0   : std_logic; 
+  signal dpram_read_valid      : std_logic; -- data read from the DPRAM is valid (page address written)
+  signal dpram_read_invalid    : std_logic; -- data in DPRAM is not valid (the page is being written to)
+  signal dpram_write_match     : std_logic_vector(g_wports-1 downto 0); -- valid data is being written to the address we are hooked to
   signal wait_valid_data_write : std_logic; -- HIGH after a non-valid data was read,
   signal mask_read_req         : std_logic; -- masks the request to the RR Rabiter which governs
                                             -- the access to DPRAM 
-  signal  write_data_d0        : std_logic_vector(g_data_width - 1 downto 0);
+  signal write_data_muxed_d0 : std_logic_vector(g_data_width - 1 downto 0);
+  signal read_data_valid  : std_logic;
+  signal write_valid_in : std_logic_vector(g_wports-1 downto 0);
+  signal write_data_muxed : std_logic_vector(g_data_width-1 downto 0);
+  signal match_if_idx : integer range 0 to g_wports-1;
+  signal got_valid_match : std_logic;
+  signal got_valid_match_d0 : std_logic;
+  signal read_data_out : std_logic_vector(g_data_width - 1 downto 0);
+  signal nonvalid_data_reg : std_logic;
 begin 
 
+  -----------------------------
+  --      READ signals       --
+  -----------------------------
   -- the data being read from the Linked List DPRAM is valid,so we just need to pass it
-  valid_data_read     <= '1' when (read_data_ready_i = '1' and read_data_valid_i = '1') else '0';
+  dpram_read_valid    <= '1' when (read_data_ready_i = '1' and read_data_valid_i = '1') else '0';
   
   -- the data being read from the Linked List DPRAM is not valid (it means that data is still 
   -- being written under the  indicated address), this is the case for this module
-  nonvalid_data_read  <= '1' when (read_data_ready_i = '1' and read_data_valid_i = '0') else '0';
+  dpram_read_invalid  <= '1' when (read_data_ready_i = '1' and read_data_valid_i = '0') else '0';
   
-  -- the data being written to the Linked List DPRAM is what we are wating for and it's valid.
-  valid_data_write    <= '1' when (read_addr_i = write_addr_i and write_data_valid_i = '1' and write_data_ready_i = '1') else '0';
+  -----------------------------
+  --     WRITE signals       --
+  -----------------------------
+  GEN_WR_SIGS: for I in 0 to g_wports-1 generate
+    -- check if written data is valid
+    write_valid_in(I) <= write_data_i(I)(g_data_width-1) and write_data_ready_i(I);
+    -- the data being written to the Linked List DPRAM is what we are wating for and it's valid.
+    dpram_write_match(I) <= '1' when (read_addr_i = write_addr_i(I) and write_valid_in(I) = '1') else
+                            '0';
+  end generate;
+  got_valid_match <= or_reduce(dpram_write_match);
+  match_if_idx <= to_integer(unsigned(f_onehot_decode(dpram_write_match, g_wports)));
+  write_data_muxed <= write_data_i(match_if_idx);
 
   process(clk_i)
   begin
@@ -121,26 +144,25 @@ begin
         
         wait_valid_data_write <= '0';
         mask_read_req         <= '1';
-        valid_data_write_d0   <= '0';
-        write_data_d0         <= (others =>'0' );
+        got_valid_match_d0    <= '0';
+        write_data_muxed_d0   <= (others =>'0' );
 
       else
         
-        write_data_d0       <= write_data_i;
-        valid_data_write_d0 <= valid_data_write;
+        write_data_muxed_d0 <= write_data_muxed;
+        got_valid_match_d0  <= got_valid_match;
         
-        if(nonvalid_data_read  = '1' and 
-           valid_data_write    = '0' and valid_data_write_d0 = '0') then -- suppress the request, so we don't waste 
-          mask_read_req  <= '0';                                      -- access time to the DPRAM 
-        elsif(valid_data_write = '1' or  
-              valid_data_write = '1' or valid_data_write_d0 = '1') then -- at this point, the request (read_req_i) to 
+        if(dpram_read_invalid  = '1' and
+           got_valid_match = '0' and got_valid_match_d0 = '0') then -- suppress the request, so we don't waste
+          mask_read_req  <= '0';                                      -- access time to the DPRAM
+        elsif(got_valid_match = '1' or got_valid_match_d0 = '1') then -- at this point, the request (read_req_i) to
           mask_read_req  <= '1';                                        -- the LL should finish, and we get read for new request
         end if;
 
-        if(nonvalid_data_read = '1' and                                 -- non-valid data was read *and*
-           valid_data_write   = '0' and valid_data_write_d0 = '0') then -- the same time (or 1-cyc- before -- this is a write gap)
+        if(dpram_read_invalid = '1' and                                 -- non-valid data was read *and*
+           got_valid_match = '0' and got_valid_match_d0 = '0') then -- the same time (or 1-cyc- before -- this is a write gap)
           wait_valid_data_write  <= '1';                                -- there was no write to the address which is of interest
-        elsif(valid_data_write = '1') then                              -- so we need to wait for the proper write
+        elsif(got_valid_match = '1') then                              -- so we need to wait for the proper write
           wait_valid_data_write  <= '0';
         end if;
         
@@ -149,20 +171,25 @@ begin
     
   end process;
  
-  read_data_o <= read_data_i   when (valid_data_read  = '1' )                                   else -- normal case, the data being read is valid
-                 write_data_i  when (valid_data_write = '1'                                     and  -- the data being written is valid *and* 
-                                     (wait_valid_data_write ='1' or nonvalid_data_read = '1' )) else -- we are waiting for valid dta at that address *or*
-                                                                                                    -- we are just reading non-valid data
-                 write_data_d0 when (valid_data_write_d0 = '1'                                  and  -- there is a 1-cycle gap between writing/reading data *and* 
-                                     (wait_valid_data_write ='1' or nonvalid_data_read = '1' )) else -- we are waiting for valid dta at that address *or*
-                                                                                                    -- we are just reading non-valid data
-
+  read_data_out <= -- normal case, the data being read is valid
+                 read_data_i       when (dpram_read_valid  = '1' ) else
+                 -- the data being written is valid *and*
+                 -- we are waiting for valid dta at that address *or* we are just reading non-valid data
+                 write_data_muxed  when (got_valid_match = '1' and
+                                        (wait_valid_data_write ='1' or dpram_read_invalid = '1' )) else
+                 -- there is a 1-cycle gap between writing/reading data *and*
+                 -- we are waiting for valid dta at that address *or* we are just reading non-valid data
+                 write_data_muxed_d0 when (got_valid_match_d0 = '1' and
+                                     (wait_valid_data_write ='1' or dpram_read_invalid = '1' )) else
                  read_data_i;
 
-  read_data_valid_o <= (valid_data_read                                                        or       -- normal case
-                       (valid_data_write    and (wait_valid_data_write or nonvalid_data_read)) or       
-                       (valid_data_write_d0 and (wait_valid_data_write or nonvalid_data_read))    ) and -- reading data from LL input
+  read_data_o <= read_data_out;
+
+  read_data_valid   <= (dpram_read_valid                                                        or       -- normal case
+                       (got_valid_match    and (wait_valid_data_write or dpram_read_invalid)) or
+                       (got_valid_match_d0 and (wait_valid_data_write or dpram_read_invalid))    ) and -- reading data from LL input
                         read_req_i;                                                                  -- no request, no answer :)
-  read_req_o        <=  mask_read_req  and read_req_i;
+  read_data_valid_o <= read_data_valid;
+  read_req_o        <= mask_read_req  and read_req_i;
 
 end syn;
diff --git a/modules/wrsw_swcore/swc_swcore_pkg.vhd b/modules/wrsw_swcore/swc_swcore_pkg.vhd
index 313db950..10e04cb6 100644
--- a/modules/wrsw_swcore/swc_swcore_pkg.vhd
+++ b/modules/wrsw_swcore/swc_swcore_pkg.vhd
@@ -749,8 +749,9 @@ component  swc_multiport_pck_pg_free_module is
 
   component swc_ll_read_data_validation is
     generic(
-      g_addr_width : integer ;--:= c_swc_page_addr_width;
-      g_data_width : integer --:= c_swc_page_addr_width
+      g_addr_width : integer;--:= c_swc_page_addr_width;
+      g_data_width : integer;--:= c_swc_page_addr_width
+      g_wports     : integer
       );
     port(
       clk_i                 : in std_logic;
@@ -763,10 +764,9 @@ component  swc_multiport_pck_pg_free_module is
       read_data_valid_i     : in std_logic;
       read_data_ready_i     : in std_logic;
      
-      write_addr_i          : in std_logic_vector(g_addr_width - 1 downto 0);
-      write_data_i          : in std_logic_vector(g_data_width - 1 downto 0);
-      write_data_valid_i    : in std_logic;
-      write_data_ready_i    : in std_logic;
+      write_addr_i          : in t_lladr_array(g_wports-1 downto 0);
+      write_data_i          : in t_lldat_array(g_wports-1 downto 0);
+      write_data_ready_i    : in std_logic_vector(g_wports-1 downto 0);
 
       read_data_o           : out std_logic_vector(g_data_width - 1 downto 0);
       read_data_valid_o     : out std_logic
-- 
GitLab