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

Subversion Repositories all-pole_filters

[/] [all-pole_filters/] [trunk/] [Circuits/] [butterworth3.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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