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