OpenCores
URL https://opencores.org/ocsvn/all-pole_filters/all-pole_filters/trunk

Subversion Repositories all-pole_filters

[/] [all-pole_filters/] [trunk/] [Circuits/] [bessel6.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 fcorthay
--##############################################################################
2
--
3
--  bessel6
4
--      6th order Bessel lowpass filter
5
--
6
--      This circuit simulates an analog ladder filter by replacing the integral
7
--      relations of the LC elements by digital accumulators.
8
--
9
--------------------------------------------------------------------------------
10
--
11
--  Versions / Authors
12
--      1.0 Francois Corthay    first implementation
13
--
14
--  Provided under GNU LGPL licence: <http://www.gnu.org/copyleft/lesser.html>
15
--
16
--  by the electronics group of "HES-SO//Valais Wallis", in Switzerland:
17
--  <http://isi.hevs.ch/switzerland/robust-electronics.html>.
18
--
19
--------------------------------------------------------------------------------
20
--
21
--  Usage
22
--      Set the input signal bit number with the generic "inputBitNb".
23
--
24
--      Set the output signal bit number with the generic "outputBitNb". This
25
--      value must be greater or equal than "inputBitNb". The additional bits
26
--      are added as LSBs. They allow to increas the resolution as the bandwidth
27
--      is reduced.
28
--
29
--      Define the cutoff frequency with the generic "shiftBitNb". Every
30
--      increment in this value shifts the cutoff frequency down by an octave
31
--      (a factor of 2).
32
--
33
--      The input samples are read from the signal "filterIn" at the rising edge
34
--      of "clock" when "en" is '1'.
35
--
36
--      With this, a new output sample is calculated and provided on
37
--      "filterOut". The output changes at the rising edge of "clock" when "en"
38
--      is '1'. It remains stable until the next time a sample is calculated.
39
--
40
--      The "reset" signal is active high.
41
--
42
--------------------------------------------------------------------------------
43
--
44
--  Synthesis results
45
--      A circuit with 16 bit input, 16 bit output and 4 bit shift gives the
46
--      following synthesis result on a Xilinx Spartan3-1000:
47
--          Number of Slice Flip Flops:           145 out of  15,360    1%
48
--          Number of 4 input LUTs:               366 out of  15,360    2%
49
--          Average Fanout of Non-Clock Nets:    2.23
50
--
51
--##############################################################################
52
 
53
LIBRARY ieee;
54
  USE ieee.std_logic_1164.all;
55
  USE ieee.numeric_std.all;
56
 
57
ENTITY bessel6 IS
58
  GENERIC(
59
    inputBitNb  : positive := 16;
60
    outputBitNb : positive := 16;
61
    shiftBitNb  : positive := 4
62
  );
63
  PORT(
64
    clock     : IN     std_ulogic;
65
    reset     : IN     std_ulogic;
66
    en        : IN     std_ulogic;
67
    filterIn  : IN     signed (inputBitNb-1 DOWNTO 0);
68
    filterOut : OUT    signed (outputBitNb-1 DOWNTO 0)
69
  );
70
END bessel6;
71
 
72
--==============================================================================
73
 
74
ARCHITECTURE RTL OF bessel6 IS
75
 
76
  constant filterOrder : natural := 6;
77
  type natural_vector_t is array(1 to filterOrder) of natural;
78
  type integer_vector_s is array(1 to filterOrder) of integer;
79
  -- coefficients: [1, 1/2, 1/2-1/8, 1/4+1/16, 1/4-1/16, 1/16]
80
  constant t1 : natural_vector_t := (0, 1,  1, 2, 2, 4);
81
  constant s2 : integer_vector_s := (0, 0, -1, 1, 1, 0);
82
  constant t2 : natural_vector_t := (0, 0,  3, 4, 4, 0);
83
 
84
  constant additionalinternalWBitNb: positive := 4;
85
  constant internalWBitNb: positive := filterOut'length + additionalinternalWBitNb;
86
  signal inputSignalScaled : signed(internalWBitNb-1 downto 0);
87
 
88
  constant internalaccumulatorBitNb : positive := internalWBitNb + shiftBitNb;
89
  type signed_vector_accumulator is array(1 to filterOrder)
90
    of signed(internalaccumulatorBitNb-1 downto 0);
91
  type signed_vector_w is array(0 to filterOrder+1)
92
    of signed(internalWBitNb-1 downto 0);
93
  signal accumulator : signed_vector_accumulator;
94
  signal w : signed_vector_w;
95
 
96
BEGIN
97
  ------------------------------------------------------------------------------
98
                          -- Scale input signal to internal state variables size
99
  inputSignalScaled <= SHIFT_LEFT(
100
    RESIZE(filterIn, inputSignalScaled'length),
101
    filterOut'length - filterIn'length
102
  );
103
 
104
  ------------------------------------------------------------------------------
105
                                                            -- Accumulator chain
106
  process(reset, clock)
107
  begin
108
    if reset = '1' then
109
      accumulator <= (others => (others => '0'));
110
    elsif rising_edge(clock) then
111
      if en = '1' then
112
        for index in 1 to filterOrder loop
113
          accumulator(index) <= accumulator(index) + (
114
            RESIZE(w(index-1), w(index)'length+1) -
115
            RESIZE(w(index+1), w(index)'length+1)
116
          );
117
        end loop;
118
      end if;
119
    end if;
120
  end process;
121
 
122
  ------------------------------------------------------------------------------
123
                                                -- Analog filter state variables
124
  process(accumulator, w, inputSignalScaled)
125
  begin
126
    for index in 1 to filterOrder loop
127
                                           -- second shift with positive value
128
      if s2(index) = 1 then
129
        w(index) <= RESIZE(
130
          SHIFT_RIGHT(
131
            accumulator(index),
132
            t1(index) + shiftBitNb
133
          ) +
134
          SHIFT_RIGHT(
135
            accumulator(index),
136
            t2(index) + shiftBitNb
137
          ),
138
          w(index)'length
139
        );
140
                                           -- second shift with negative value
141
      elsif s2(index) = -1 then
142
        w(index) <= RESIZE(
143
          SHIFT_RIGHT(
144
            accumulator(index),
145
            t1(index) + shiftBitNb
146
          ) -
147
          SHIFT_RIGHT(
148
            accumulator(index),
149
            t2(index) + shiftBitNb
150
          ),
151
          w(index)'length
152
        );
153
                                                               -- single shift
154
      else
155
        w(index) <= RESIZE(
156
          SHIFT_RIGHT(
157
            accumulator(index),
158
            t1(index) + shiftBitNb
159
          ),
160
          w(index)'length
161
        );
162
      end if;
163
    end loop;
164
                           -- w(0) combines input and w(1) for first accumulator
165
    w(0) <= inputSignalScaled - w(1);
166
            -- w(filterOrder+1) is a copy of w(filterOrder) for last accumulator
167
    w(filterOrder+1) <= w(filterOrder);
168
  end process;
169
 
170
  ------------------------------------------------------------------------------
171
                                    -- Scale last state variables to output size
172
  filterOut <= RESIZE(w(w'high), filterOut'length);
173
 
174
END ARCHITECTURE RTL;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.