From 878cd6b077766b8cb2696d8e662190a9835c66ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch>
Date: Tue, 26 Apr 2016 15:02:12 +0200
Subject: [PATCH] common: improved gc_moving_average

---
 modules/common/gc_moving_average.vhd | 140 ++++++++-------------------
 1 file changed, 39 insertions(+), 101 deletions(-)

diff --git a/modules/common/gc_moving_average.vhd b/modules/common/gc_moving_average.vhd
index 33c3f835..c507fe45 100644
--- a/modules/common/gc_moving_average.vhd
+++ b/modules/common/gc_moving_average.vhd
@@ -6,7 +6,7 @@
 -- Author     : Tomasz Wlostowski
 -- Company    : CERN
 -- Created    : 2009-09-01
--- Last update: 2011-04-29
+-- Last update: 2016-01-27
 -- Platform   : FPGA-generic
 -- Standard   : VHDL '93
 -------------------------------------------------------------------------------
@@ -46,6 +46,7 @@ use ieee.NUMERIC_STD.all;
 
 library work;
 use work.gencores_pkg.all;
+use work.genram_pkg.all;
 
 entity gc_moving_average is
   
@@ -61,7 +62,7 @@ entity gc_moving_average is
 
     din_i      : in  std_logic_vector(g_data_width-1 downto 0);
     din_stb_i  : in  std_logic;
-    dout_o     : out std_logic_vector(g_data_width-1 downto 0);
+    dout_o     : out std_logic_vector(g_data_width+g_avg_log2-1 downto 0);
     dout_stb_o : out std_logic
     );
 
@@ -69,118 +70,55 @@ end gc_moving_average;
 
 architecture rtl of gc_moving_average is
 
-  component generic_ssram_dp_rw_rw
+  component gc_delay_line is
     generic (
-      g_width     : integer;
-      g_addr_bits : integer;
-      g_size      : integer);
+      g_delay : integer;
+      g_width : integer);
     port (
-      clk_i     : in  std_logic;
-      wr_en_a_i : in  std_logic;
-      addr_a_i  : in  std_logic_vector(g_addr_bits-1 downto 0);
-      data_a_i  : in  std_logic_vector(g_width-1 downto 0);
-      q_a_o     : out std_logic_vector(g_width-1 downto 0);
-      wr_en_b_i : in  std_logic;
-      addr_b_i  : in  std_logic_vector(g_addr_bits-1 downto 0);
-      data_b_i  : in  std_logic_vector(g_width-1 downto 0);
-      q_b_o     : out std_logic_vector(g_width-1 downto 0));
-  end component;
-
+      clk_i   : in  std_logic;
+      rst_n_i : in  std_logic;
+      d_i     : in  std_logic_vector(g_width -1 downto 0);
+      q_o     : out std_logic_vector(g_width -1 downto 0);
+      ready_o : out std_logic);
+  end component gc_delay_line;
 
+  
+  
   constant avg_steps                    : natural := 2**g_avg_log2;
-  signal read_cntr, write_cntr          : unsigned(g_avg_log2-1 downto 0);
-  signal mem_dout                       : std_logic_vector(g_data_width-1 downto 0);
-  signal ready                          : std_logic;
-  signal acc                            : signed(g_data_width+g_avg_log2 downto 0);
-  signal stb_d0, stb_d1, stb_d2, stb_d3 : std_logic;
-  signal s_dummy                        : std_logic_vector(g_data_width-1 downto 0);
+  signal delay_dout                       : std_logic_vector(g_data_width-1 downto 0);
+  signal acc                            : unsigned(g_data_width+g_avg_log2+1 downto 0);
+  signal dly_ready,delay_ready_d0, delay_ready_d1, delay_ready_d2 : std_logic;
+  
 begin  -- rtl
 
 
-
-  delay_buf : generic_ssram_dp_rw_rw
+  U_delay : gc_delay_line
     generic map (
-      g_width     => g_data_width,
-      g_addr_bits => g_avg_log2,
-      g_size      => 2**g_avg_log2
-      )
+      g_delay => avg_steps,
+      g_width => g_data_width)
     port map (
-      clk_i     => clk_i,
-      wr_en_a_i => '0',
-      addr_a_i  => std_logic_vector(read_cntr),
-      data_a_i  => s_dummy,
-      q_a_o     => mem_dout,
-
-      wr_en_b_i => din_stb_i,
-      addr_b_i  => std_logic_vector(write_cntr),
-      data_b_i  => din_i,
-      q_b_o     => open);
-
-
-  --delay_buf : generic_ssram_dualport_singleclock
-  --  generic map (
-  --    g_width     => g_data_width,
-  --    g_addr_bits => g_avg_log2,
-  --    g_size      => 2**g_avg_log2)
-  --  port map (
-  --    data_i    => din_i,
-  --    rd_addr_i => std_logic_vector(read_cntr),
-  --    clk_i     => clk_i,
-  --    wr_addr_i => std_logic_vector(write_cntr),
-  --    wr_en_i   => din_stb_i,
-  --    q_o       => mem_dout);
-
-
-  avg : process (clk_i, rst_n_i)
-  begin  -- process avg
-
-
-    if clk_i'event and clk_i = '1' then  -- rising clock edge
-      if(rst_n_i = '0') then
-        read_cntr  <= to_unsigned(1, read_cntr'length);
-        write_cntr <= to_unsigned(avg_steps, write_cntr'length);
-        ready      <= '0';
-        stb_d0     <= '0';
-        stb_d1     <= '0';
-        stb_d2     <= '0';
-        stb_d3     <= '0';
-        acc        <= (others => '0');
+      clk_i   => clk_i,
+      rst_n_i => rst_n_i,
+      d_i     => din_i,
+      q_o     => delay_dout,
+      ready_o => dly_ready);
+
+
+  avg : process (clk_i)
+  begin  -- process avgx
+    if rising_edge(clk_i) then
+      delay_ready_d2 <= delay_ready_d1;
+      delay_ready_d1 <= delay_ready_d0;
+      delay_ready_d0 <= dly_ready;
+      if rst_n_i = '0' or dly_ready /= '1' then
+        acc <= (others => '0');
       else
-        
-
-        if(read_cntr = to_unsigned(avg_steps, read_cntr'length)) then
-          ready <= '1';
-        end if;
-
-
-        if(din_stb_i = '1') then
-          acc        <= acc + signed(din_i);
-          write_cntr <= write_cntr + 1;
-          
-        else
-          
-
-          if stb_d3 = '1' then
-            read_cntr <= read_cntr + 1;
-            if(ready = '1') then
-              acc    <= acc - signed(mem_dout);
-              dout_o <= std_logic_vector(acc (g_avg_log2 + g_data_width - 1 downto g_avg_log2));
-            end if;
-          end if;
-          
-        end if;
-
-        dout_stb_o <= stb_d3 and ready;
-        stb_d0     <= din_stb_i;
-        stb_d1     <= stb_d0;
-        stb_d2     <= stb_d1;
-        stb_d3     <= stb_d2;
-        
+        acc <= acc + unsigned(din_i) - unsigned(delay_dout);
       end if;
     end if;
-  end process avg;
-  
+  end process;
 
+  dout_o <= std_logic_vector(acc(g_data_width+ g_avg_log2-1 downto 0));
   
   
 end rtl;
-- 
GitLab