1 | -- FMT FAU Erlangen -----------------------------------------------
|
2 | -- moving_average: --
|
3 | -- this module generates a parametrized moving average over --
|
4 | -- two's complement dividable ranges with an parallel in parallel--
|
5 | -- out data set. --
|
6 | -- For the usage just set your desired data and shift width as a --
|
7 | -- Bit statement. --
|
8 | -- --
|
9 | -------------------------------------------------------------------
|
10 |
|
11 | -- Programming style ----------------------------------------------
|
12 | -- parameter prefix | description --
|
13 | -- g_ | generic, for entity declatation --
|
14 | -- i_ | input, for entity declatation --
|
15 | -- o_ | output, for entity declatation --
|
16 | -- io_ | in-/output, for entity declatation --
|
17 | -- c_ | constant, for architecture declatation --
|
18 | -- t_ | type, for architecture declatation --
|
19 | -- w_ | wire, used for internal signals --
|
20 | -- tb_ | testbench, used for internal signals --
|
21 | -- p_ | process, used for process labels --
|
22 | -- inst_ | instantiate, used fpr component instan- --
|
23 | -- tiation --
|
24 | -- --
|
25 | -- parameter suffix | description --
|
26 | -- _reg | regular signal, for register (synchron) --
|
27 | -- _next | next signal, for register (asynchron) --
|
28 | -- _s | synchronised --
|
29 | -- --
|
30 | -------------------------------------------------------------------
|
31 |
|
32 | -- Revision History -----------------------------------------------
|
33 | -- Version: | Author: | Mod. Date: | Changes Made: --
|
34 | -- 0.1 | Koehnen | 05/09/17: | Module developement --
|
35 | -------------------------------------------------------------------
|
36 |
|
37 | library ieee;
|
38 | use ieee.std_logic_1164.all;
|
39 | use ieee.numeric_std.all;
|
40 | use ieee.math_real.all;
|
41 |
|
42 |
|
43 | entity moving_average is
|
44 | generic(
|
45 | g_data_width : positive := 4;
|
46 | g_shift_width : positive := 2
|
47 | );
|
48 | port(
|
49 | i_clk : in std_logic;
|
50 | i_clear : in std_logic;
|
51 | i_data : in std_logic_vector(g_data_width-1 downto 0);
|
52 | o_data : out std_logic_vector(g_data_width-1 downto 0)
|
53 | );
|
54 | end entity moving_average;
|
55 |
|
56 |
|
57 | architecture behavioral of moving_average is
|
58 |
|
59 | -- constants
|
60 | constant c_shift_range : integer := integer(2.0**real(g_shift_width));
|
61 |
|
62 | -- typedeclaration
|
63 | type t_Q_temp is array (0 to c_shift_range-1) of std_logic_vector(g_data_width-1 downto 0);
|
64 | type t_sum is array (0 to c_shift_range) of unsigned(g_data_width+g_shift_width-1 downto 0);
|
65 | -- g_shift_width also increments the length of guardbits which needed for the summation
|
66 | -- evidence: ceil(log2(2**g_shift_width)) == g_shift_width
|
67 |
|
68 | -- signals
|
69 | signal w_Q_temp : t_Q_temp;
|
70 | signal w_sum : t_sum := (others => (others => '0'));
|
71 |
|
72 | -- components
|
73 | component shift_reg_pipo is
|
74 | generic(
|
75 | data_width : positive := 4
|
76 | );
|
77 | port(
|
78 | clk : in std_logic;
|
79 | clear : in std_logic;
|
80 | D: in std_logic_vector(g_data_width-1 downto 0);
|
81 | Q: out std_logic_vector(g_data_width-1 downto 0)
|
82 | );
|
83 | end component shift_reg_pipo;
|
84 |
|
85 |
|
86 | begin
|
87 |
|
88 | -- parallel in parallel out (PIPO) shift register
|
89 | p_shift_gen : for I in 1 to c_shift_range-1 generate
|
90 | pipo_I : shift_reg_pipo
|
91 | generic map(
|
92 | data_width => g_data_width
|
93 | )
|
94 | port map(
|
95 | clk => i_clk,
|
96 | clear => i_clear,
|
97 | D => w_Q_temp(I-1), -- first element in loop is w_Q_temp(0)
|
98 | Q => w_Q_temp(I)
|
99 | );
|
100 | end generate p_shift_gen;
|
101 |
|
102 | -- summation
|
103 | p_sum_gen : for I in 1 to c_shift_range generate
|
104 | w_sum(I) <= w_sum(I-1) + unsigned(w_Q_temp(I-1)); -- summs up every shifted value
|
105 | end generate p_sum_gen;
|
106 |
|
107 | -- connect shift register
|
108 | w_Q_temp(0) <= i_data(g_data_width-1 downto 0); -- allocates first data element to array
|
109 |
|
110 | -- divide/shift Bits
|
111 | o_data <= std_logic_vector(w_sum(c_shift_range)(g_data_width+g_shift_width-1 downto g_shift_width)); -- trimm last sum vector to devide by k*2
|
112 |
|
113 | end architecture behavioral;
|