Connect with us

Digital LP filter in multiplier free FPGA

Discussion in 'Electronic Design' started by markp, Nov 13, 2004.

Scroll to continue with content
  1. markp

    markp Guest

    Hi All,

    I need to implement a low pass digital filter on 12 bit ADC data in a Spatan
    IIE device, but I'd like it to be multiplier free - in other words just use
    adders and bit shifting for the coefficients. The sample rate is 12Mhz and I
    need a sharp cut-off at around 3MHz. Does anyone know of a simple design
    (IIR?) to do this, or a website/tutorial to give me some pointers? I've seen
    several websites with coefficient calculators, there are always a few
    coefficients that can't be easily calculated with bit shifting and adding.


  2. Antti Lukats

    Antti Lukats Guest

    depending what you need, one solution is very simple "digital integrator"
    its doable with only shift and add, there is some appnote or something at
    xilinx web, I used that in digital carrier frequency amplifier, and it did
    give actually very good filtering (for my application at least).

    an example digital integrator source is appended
    -- 18 Bit Digital Integrator Feedback "multiplier"
    -- constant 1 / 256 (fixed, no choices implemented)
    -- Tested and working.
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;

    library work;

    entity integrator_18bit is Port (
    rst : in std_logic;
    clk : in std_logic;
    din : in std_logic_vector(17 downto 0); -- Input: 18 Bit Unsigned
    k : in std_logic_vector(3 downto 0); -- multiplier select (not
    dout : out std_logic_vector(17 downto 0) -- Output: 18 Bit
    Unsigned INTEGER
    end integrator_18bit;

    architecture Behavioral of integrator_18bit is

    signal acc : std_logic_vector(25 downto 0);
    signal vi_minus_vo : std_logic_vector(25 downto 0);
    signal vi_minus_vo_sign_extended : std_logic_vector(7 downto 0);

    -- Microblaze "endian" conversion
    dout(0) <= acc(25); dout(1) <= acc(24); dout(2) <= acc(23); dout(3) <=
    dout(4) <= acc(21); dout(5) <= acc(20); dout(6) <= acc(19); dout(7) <=
    dout(8) <= acc(17); dout(9) <= acc(16); dout(10) <= acc(15); dout(11)
    <= acc(14);
    dout(12) <= acc(13); dout(13) <= acc(12); dout(14) <= acc(11); dout(15)
    <= acc(10);
    dout(16) <= acc(9); dout(17) <= acc(8);

    -- Error Value
    vi_minus_vo <= (din & "00000000") - acc;
    -- Sign Extension for Error Value
    with vi_minus_vo(25) select vi_minus_vo_sign_extended(7 downto 0) <=
    "00000000" when '0', "11111111" when others;

    process (clk) begin
    if (rst='1') then
    acc <= "00000000000000000000000000";
    if (clk'event and clk='1') then
    -- Accumulate
    acc <= acc + (vi_minus_vo_sign_extended(7 downto 0) & vi_minus_vo(25
    downto 8));
    end if;
    end if;
    end process;

    end Behavioral;
  3. John Larkin

    John Larkin Guest

    See zipfile in abse. If I post it here, the formatting gets lunched.

  4. markp

    markp Guest

    Thanks John. Unfortunately I've got text only news server access, any chance
    in emailing? (remove .nospam).


  5. John Larkin

    John Larkin Guest

    OK, done, I think.

  6. John Larkin

    John Larkin Guest

    Oops, K1 should be 4, 1/16. File got scrambled somehow.

  7. Ken

    Ken Guest

    I need to implement a low pass digital filter on 12 bit ADC data in a
    Hi Mark,

    I can help you out with this by automatically generating VHDL for an FIR
    implementation for your filter that uses shifts and adds.

    Please post the following details:

    Do you want the filter to run at 12MHz (i.e. full-parallel) or do you have a
    faster clock available that could be used to share hardware over multiple
    clock cycles?

    Is the filter single-rate or are you decimating?

    Input bit-width?

    Signed/unsigned input?

    Quantised filter coefficients (integers ideally but fixed-point will do) or
    more detailed spectral requirements (what -dB gain at 3MHz, pass-band ripple
    etc., start rolling off at what freq, stop rolling of at what freq. etc.)


  8. Tom Seim

    Tom Seim Guest

    You didn't say how sharp your cutoff needs to be, or how much gain
    ripple you can tolerate. You might consider a pipelined multiplier
    design. This will result in very high clock rates, permitting one
    multiplier to handle 8-16 coefficients. Several multipliers can be
    used in parallel to increase the number of coefficients even further.
    Xilinx has numerous ap notes on digital filtering techniques. Here is
    a good review of the topic:
    This is probably the best book on the subject:

  9. markp

    markp Guest

    Thanks John. I'm not really sure how to tweek this for my system, but very
    interesting stuff nonetheless. I decided in the end to go for a 'rolling
    average' type filter (rectangular) with 16 taps, and this seems to be
    working quite nicely so I think I'll stick with this.


  10. markp

    markp Guest

    Hi Ken,

    Well I've gone for a rolling average filter at the moment, but the specs
    I've got a 65MHz clock and currently dividing by 6 to give 13MHz.
    Single rate so far.
    12 bit ADC data.
    -3db @ 3MHz, 4th order Butterworth type roll-off ideally, unity gain


  11. markp

    markp Guest

    Thanks Tom! Interesting stuff.

  12. markp

    markp Guest

    Thanks! I'll have a look at this.

  13. Ken

    Ken Guest

    Hi Mark,
    OK - do you want the filter to run at 13MHz (I thought you said 12 before?)
    and use more area or run at 65MHz and use less area?

    I can generate something immediately for you that would run at 13MHz.


  14. mtx

    mtx Guest

    Dear Mark,
    Seems to be a half-band filter (half of the Nyquist freq of 6 MHz) so, when
    you use a FIR filter you can leave out half of the taps. The Xilinx core
    generator can generate a nice filter for you. For the tap values use some
    FIR design tool, look at for a free one, it can
    export to Xilinx .coe files.
    Henk van Kampen
  15. Ray Andraka

    Ray Andraka Guest


    You can use a distributed arithmetic filter if you take advantage of the higher
    clocks. With a 65 MHz clock, you have 5 clocks (13 MHz is 1/5 of 65, not 1/6)
    pixel available. By using a two bit parallel distributed arithmetic filter you
    get a quite compact filter. DA 'hides' the coefficient multiplies by summing
    all the
    bit partial products from all the taps before doing the shift-accumulate. The
    II has DLLs in it that can easily be used to double the 65 MHz clock to obtain a
    130 MHz
    clock. Doing that will cut the physical size of the filter in half, since then
    you'd be able to
    handle a 10 bit input with the serial filter. DA Filter designs at 130 MHz are
    quite acheivable
    in any of the SpartanII devices. I have a tutorial on distributed arithmetic on
    my website at . Also, the xilinx Coregen includes a
    filter generator
    that will create a distributed filter given a set of coefficients and a number
    of parameters. The
    major drawback to the coregen filter is that you cannot look inside to see how
    it works nor to
    improve the design. You can also take advantage of coefficient symmetry to
    reduce the filter
    size, and if it is acceptable to have the filter characteristic symmetic about
    Fs/4 you can use a
    half-band filter which has all the odd coefficients except the center one equal
    to zero.

    --Ray Andraka, P.E.
    President, the Andraka Consulting Group, Inc.
    401/884-7930 Fax 401/884-7950

    "They that give up essential liberty to obtain a little
    temporary safety deserve neither liberty nor safety."
    -Benjamin Franklin, 1759
  16. Pete Fraser

    Pete Fraser Guest

    But previously you said a sharp cutoff. You won't get that with an average.
    If your clock is at 12 MHz, and you want an LPF with a 3MHz
    cutoff, I would use a half-band filter.

    All even coefficients will be 0 (with the exception of a0 at 0.5).
    Also, the filter is symmetric in the time domain allowing you
    to use a folded ladder topology to use half the "multipliers".

    This will give you a response that's skew symmetric around fs/4.
  17. It would seem that if the coefficients are constants it would not
    be hard to generate the appropriate shift and add hardware, pipelined
    as appropriate. Presumably you could use adders and subtractors, and
    the design could be optimized toward minimizing the number of
    adder/subtractor stages. (I think that can be done, but I haven't
    tried to do it.)

    -- glen
  18. Guest

    See <<>> for one product
    that can do exactly this (and more). You can for example create
    multiplier-free filters in two styles with optional pipelining.

    There are many other products in the marketplace for filter code
    generation; just look around.

    Disclaimer: I work for The MathWorks.
  19. Alan

    Alan Guest

    Hi Mark,

    If you need synthesizable VHDL, testbenches etc, our software Tyd-IP Code
    Generator and ONEoverT Digital Filter
    Designer will give you all you need. There are other development packages
    out there also. Have a look around to make sure
    you get exactly what you need.

    Good Luck
  20. markp

    markp Guest

    Thanks Henk, this seems a nice tool. I'll have a play!

Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day