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.
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; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.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 INTEGER k : in std_logic_vector(3 downto 0); -- multiplier select (not implemented) 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);
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.)
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:
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.
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
formatting link
for a free one, it can export to Xilinx .coe files. Regards, Henk van Kampen
You can use a distributed arithmetic filter if you take advantage of the higher available clocks. With a 65 MHz clock, you have 5 clocks (13 MHz is 1/5 of 65, not 1/6) per pixel available. By using a two bit parallel distributed arithmetic filter you can 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 Spartan 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
formatting link
. 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.
markp wrote:
--
--Ray Andraka, P.E. President, the Andraka Consulting Group, Inc.
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.
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.)
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.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.