Please give some comments on my FIR

E

Edison

The FIR uses many FPGA resource.How to reduce the resource.The coefficients
are from matlab.
Would any one give me advice on it or give me the fir example as the
reference.




library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_signed.all;

entity fir is

(
clk:in std_logic;
x:in std_logic_vector(15 downto 0);
q:eek:ut std_logic_vector(31 downto 0)
);
end fir;

architecture afir of fir is
signal x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18:
std_logic_vector(15 downto 0);
signal s1,s2,s3,s4,s5,s6,s7,s8,s9:std_logic_vector(15 downto 0);
signal y1,y2,y3,y4,y5,y6,y7,y8,y9:std_logic_vector(31 downto 0);
constant h1:std_logic_vector:="0000000010001000"; --136
constant h2:std_logic_vector:="1111111010011010"; -- -358
constant h3:std_logic_vector:="0000000101110101"; --373
constant h4:std_logic_vector:="0000000010101110"; --174
constant h5:std_logic_vector:="1111110110000000"; -- -1280
constant h6:std_logic_vector:="0000100011001000"; --2248
constant h7:std_logic_vector:="1111100100111000"; -- -1736
constant h8:std_logic_vector:="1111011101111101"; -- -2179
constant h9:std_logic_vector:="0100101001001011"; --19019
begin
process(clk)
begin
if(clk'event and clk='1')then

x18<=x17;
x17<=x16;
x16<=x15;
x15<=x14;
x14<=x13;
x13<=x12;
x12<=x11;
x11<=x10;
x10<=x9;
x9<=x8;
x8<=x7;
x7<=x6;
x6<=x5;
x5<=x4;
x4<=x3;
x3<=x2;
x2<=x1;
x1<=x;

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then

s1<=signed(x1)+signed(x18);
s2<=signed(x2)+signed(x17);
s3<=signed(x3)+signed(x16);
s4<=signed(x4)+signed(x15);
s5<=signed(x5)+signed(x14);
s6<=signed(x6)+signed(x13);
s7<=signed(x7)+signed(x12);
s8<=signed(x8)+signed(x11);
s9<=signed(x9)+signed(x10);

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then

y1<=s
igned(s1)*signed(h1);
y2<=signed(s2)*signed(h2);
y3<=signed(s3)*signed(h3);
y4<=signed(s4)*signed(h4);
y5<=signed(s5)*signed(h5);
y6<=signed(s6)*signed(h6);
y7<=signed(s7)*signed(h7);
y8<=signed(s8)*signed(h8);
y9<=signed(s9)*signed(h9);

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then

q<=signed(y1)+signed(y2)+signed(y3)+signed(y4)+signed(y5)
+signed(y6)+signed(y7)+signed(y8)+signed(y9);

end if;
end process;
end afir;
 
N

Niv

Edison said:
The FIR uses many FPGA resource.How to reduce the resource.The coefficients
are from matlab.
Would any one give me advice on it or give me the fir example as the
reference.




library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_signed.all;

entity fir is

(
clk:in std_logic;
x:in std_logic_vector(15 downto 0);
q:eek:ut std_logic_vector(31 downto 0)
);
end fir;

architecture afir of fir is
signal x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18:
std_logic_vector(15 downto 0);
signal s1,s2,s3,s4,s5,s6,s7,s8,s9:std_logic_vector(15 downto 0);
signal y1,y2,y3,y4,y5,y6,y7,y8,y9:std_logic_vector(31 downto 0);
constant h1:std_logic_vector:="0000000010001000"; --136
constant h2:std_logic_vector:="1111111010011010"; -- -358
constant h3:std_logic_vector:="0000000101110101"; --373
constant h4:std_logic_vector:="0000000010101110"; --174
constant h5:std_logic_vector:="1111110110000000"; -- -1280
constant h6:std_logic_vector:="0000100011001000"; --2248
constant h7:std_logic_vector:="1111100100111000"; -- -1736
constant h8:std_logic_vector:="1111011101111101"; -- -2179
constant h9:std_logic_vector:="0100101001001011"; --19019
begin
process(clk)
begin
if(clk'event and clk='1')then

x18<=x17;
x17<=x16;
x16<=x15;
x15<=x14;
x14<=x13;
x13<=x12;
x12<=x11;
x11<=x10;
x10<=x9;
x9<=x8;
x8<=x7;
x7<=x6;
x6<=x5;
x5<=x4;
x4<=x3;
x3<=x2;
x2<=x1;
x1<=x;

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then


s1<=signed(x1)+signed(x18);
s2<=signed(x2)+signed(x17);
s3<=signed(x3)+signed(x16);
s4<=signed(x4)+signed(x15);
s5<=signed(x5)+signed(x14);
s6<=signed(x6)+signed(x13);
s7<=signed(x7)+signed(x12);
s8<=signed(x8)+signed(x11);
s9<=signed(x9)+signed(x10);

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then

y1<=signed(s1)*signed(h1);
y2<=signed(s2)*signed(h2);
y3<=signed(s3)*signed(h3);
y4<=signed(s4)*signed(h4);
y5<=signed(s5)*signed(h5);
y6<=signed(s6)*signed(h6);
y7<=signed(s7)*signed(h7);
y8<=signed(s8)*signed(h8);
y9<=signed(s9)*signed(h9);

end if;
end process;
process(clk)
begin
if(clk'event and clk='1') then

q<=signed(y1)+signed(y2)+signed(y3)+signed(y4)+signed(y5)
+signed(y6)+signed(y7)+signed(y8)+signed(y9);

end if;
end process;
end afir;

-- A bit tidier perhaps, but no real change.
-- Can do all in one Process as well:

FIR : process(clk)
begin
if rising_edge(clk) then

-- This bit can probably be done in a loop as well by declaring the X's as
an array of type SLV, (or something).
-- Just browsing so I thought I'd stick in my 2 pennyworth.!

x18<=x17;
x17<=x16;
x16<=x15;
x15<=x14;
x14<=x13;
x13<=x12;
x12<=x11;
x11<=x10;
x10<=x9;
x9<=x8;
x8<=x7;
x7<=x6;
x6<=x5;
x5<=x4;
x4<=x3;
x3<=x2;
x2<=x1;
x1<=x;

q <= (OTHERS => '0'); --default assignment
FOR i IN 1 TO 9 LOOP
s(i) <= signed x(i) + signed x(18-i);
y(i) <= signed s(i)* signed h(i);
q <= q + signed y(i); -- will need to make q
type buffer or declare q_int as signal & then q <= q_int;
END LOOP;

end if;
end process FIR;

Niv.

Will the Gurus out there tell me that this is OK or garbage!, Niv
 
J

Jonathan Bromley

Edison said:
The FIR uses many FPGA resource.How to reduce the resource.
The coefficients are from matlab.
Would any one give me advice on it or give me the
fir example as the reference.

1) You folded the filter to take advantage of symmetry in the coefficients.
That's good, and saves about 50% of the resources.

2) You have implemented the "canonical" representation of a FIR filter,
in which you do all the multiplies and then add together all the
products. This gives you a very large and slow adder tree on the
output. Find out about "systolic" implementation instead; it
will allow you to create a much faster filter structure, although
there will be almost exactly the same amount of hardware.

3) Your current structure allows you to process one data item, and
return one result, on each clock cycle. If you absolutely must
have this level of performance, then you are certain to get a
very big design. But in many applications you can run the FPGA
clock faster than the data clock. This means that you can
run a given data item through a single multiplier and adder
multiple times, consuming several clock cycles to process one
input datum. This can give you a much smaller implementation.

4) There are many possible DSP tricks for reducing the amount
of calculation you need to do. They have nothing to do with
VHDL, though, and you'll get much more help on comp.dsp
(but watch out for the gurus with their very heavy-duty maths!)

5) Bit-serial arithmetic is a great tool for minimising hardware
requirements in DSP applications. See Ray Andraka's superb
website for more ideas about this - www.andraka.com

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top