Skip to content
Snippets Groups Projects
Commit 878cd6b0 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski
Browse files

common: improved gc_moving_average

parent b5fa01bb
Branches
Tags
No related merge requests found
......@@ -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;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment