200 likes | 382 Views
ECE 448: Lab 4 FIR Filters. Agenda for today. Part 1: Introduction to Experiment 4: FIR Filter Part 2: Hands-on Session: FPGA Design Flow Based on Xilinx ISE/WebPack and ModelSim. Filters. |·|. Keep the green, block the red.
E N D
ECE 448: Lab 4 FIR Filters
Agenda for today Part 1: Introduction to Experiment 4: FIR Filter Part 2: Hands-on Session: FPGA Design Flow Based on Xilinx ISE/WebPack and ModelSim
Filters |·| • Keep the green, block the red. • Blue is a Low Pass Filter (LPF) • Multiplication in frequency domain • Convolution in time domain -ω -ωs -ωp ωp ωs ω
Convolution Equations • Continuous time • Discrete time
Convolution Problems • The function g[n] is called the “filter taps” • Infinite number of taps is impossible to implement. • Not enough space to store taps! • Not enough time to compute output! • For this reason, we take a finite number of taps (normally centered at n=0)
Direct Form FIR Filter • FIR = Finite Impulse Response • Simple to implement in VHDL • Very long critical path (1 mults + M-1 adds) x(n) Z-1 Z-1 Z-1 h0 h1 h2 hM-1 y(n)
Direct Form Transform FIR Filter • Greatly reduced critical path • 1 Multiply and 1 Add • Constant regardless of filter length • Taps are reversed • Still a problem? x(n) hM-1 hM-2 hM-3 h0 Z-1 Z-1 Z-1 y(n)
Bit growth • bit_length(a*b) = bit_length(a) + bit_length(b) • bit_length(a+b) = max(bit_length(a),bit_length(b))+1 • If filter has “unity gain”, adders do not cause growth x(n) 2p p 2p p 2p 2p hM-1 hM-2 hM-3 h0 Z-1 Z-1 Z-1 Q y(n)
Serial FIR Filter • Reuse Multiplier and Accumulator (MACC) • M cycles to compute • Hardware reduced by factor of M Cycle through h(M-1) through h(0) hold x(n) for M samples y(n) valid after M samples Z-1
Optimal Hardware • All hardware can be made out of LUT/FF Combination • Possibly the best solution, maybe not • Might be better, optimal hardware • Three (3) ways to use optimal hardware • Inference • Usually best • Faster Simulation • No extra libraries • Not FPGA specific • Instantiation • CoreGen
Inference library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mult18x18 is generic ( word_size : natural := 18; signed_mult : boolean := true); port ( clk : in std_logic; a : in std_logic_vector(1*word_size-1 downto 0); b : in std_logic_vector(1*word_size-1 downto 0); c : out std_logic_vector(2*word_size-1 downto 0)); end entity mult18x18; architecture infer of mult18x18 is begin process(clk) begin if rising_edge(clk) then if signed_mult then c <= std_logic_vector(signed(a) * signed(b)); else c <= std_logic_vector(unsigned(a) * unsigned(b)); end if; end if; end process; end architecture infer;
Instantiation -- Component Declaration for MULT18X18 should be placed -- after architecture statement but before begin keyword component MULT18X18 port ( P : out STD_LOGIC_VECTOR (35 downto 0); A : in STD_LOGIC_VECTOR (17 downto 0); B : in STD_LOGIC_VECTOR (17 downto 0)); end component; -- Component Attribute specification for MULT18X18 -- should be placed after architecture declaration but -- before the begin keyword -- Attributes should be placed here -- Component Instantiation for MULT18X18 should be placed -- in architecture after the begin keyword MULT18X18_INSTANCE_NAME : MULT18X18 port map (P => user_P, A => user_A, B => user_B);
CoreGen • For more complicated hardware (like FIFOs) • Use Xilinx tools to generate the instantiation with particular settings • Will not use until future lab
Extra Information • Entity declaration entity fir_filter is port( clk : in std_logic; reset : in std_logic; -- Input signals samp_i : in std_logic; data_i : in std_logic_vector(15 downto 0); -- Output signals samp_o : out std_logic; data_o : out std_logic_vector(15 downto 0)); end entity fir_filter;
Extra Information (2) • samp_i is a one-cycle clock enable • samp_o is a one_cycle “calculation finished” signal • data_in is 16 bits (or 18 bits if you feel ambitious) • data_out is 16 bits (quantized)
Extra Information (3) • Nested types • Used for multidimensional arrays • Also used for ROM/RAM interfaces • Usually enough to infer such memory units type word_vector is array (natural range <>) of signed(15 downto 0); constant taps : word_vector(0 to 31) := ( x"0001", x"0002", x"0003", x"0004", x"0005", x"0006", x"0007", x"0008", x"0009", x"000A", x"000B", x"000C", x"000D", x"000E", x"000F", x"0010", x"0011", x"0012", x"0013", x"0014", x"0015", x"0016", x"0017", x"0018", x"0019", x"001A", x"001B", x"001C", x"001D", x"001E", x"001F", x"0020");
Extra Information (4) • Test filter with Impulse • …,zero, zero, zero, one, zero, zero, zero… • Test Circuit with ‘ramp’ taps • taps <= (x”0001”,x”0002”,x”0003”,… • Testing with ‘ramp’ helps test filter function • Replace ‘ramp’ with ‘sinc’ taps • Sinc taps are used because rectangle in freq domain is sin(x)/x=sinc(x) in time domain • Make sure ‘sinc’ comes out of filter
Part 2 Hands-on Session FPGA Design Flow Based on Xilinx ISE/WebPack & ModelSim