-- ############################################################################ -- # Project : Leonardo CBT-Kernel # -- # # -- # Filename : fir.vhd # -- # # -- # Component : fir : N_taps-Wx x Wc Bits FIR (unrolled) # -- # # -- # Model : behav # -- # # -- # Designer : S. Theoharis # -- # Institute : VLSI Design Lab., University of Patras # -- # Date : 01.05.1999 # -- ############################################################################ library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; PACKAGE fir_lib IS -- Constant & SubType declarations. CONSTANT Wx : integer :=9; -- Word length for FIR's X sample. CONSTANT Wc : integer :=10; -- Word length for FIR's coefficient. CONSTANT N_taps : integer :=4; -- Number of FIR taps. i.e. 4,6,8 -- Shifter type for FIR component. TYPE fir_shifter_type IS ARRAY(N_taps-1 downto 0) OF std_ulogic_vector(Wx-1 downto 0); -- Coefficient type for FIR component. TYPE fir_coefficient_type IS ARRAY(N_taps-1 downto 0) OF std_ulogic_vector(Wc-1 downto 0); -- Definition of coefficient matrix. CONSTANT C_matrix : fir_coefficient_type := ( -- "1010100100", -- "0101110000", -- "0101010000", -- "1010110100", "0010110001", "1100100000", "0010101000", "1001100101" ); -- Function declaration. FUNCTION log2 (N : integer) RETURN integer; FUNCTION mult_shift_add (X : IN std_ulogic_vector; C : IN std_ulogic_vector; N_taps : integer) RETURN std_ulogic_vector; END fir_lib; ------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; PACKAGE BODY fir_lib IS --------------------------------------------- FUNCTION log2 (N : integer) RETURN integer IS VARIABLE temp : INTEGER; BEGIN IF N < 2 THEN RETURN 0; ELSE temp := 2; FOR i IN 1 TO (N/2) LOOP temp := 2 * temp; IF (temp = N) THEN RETURN (i+1); ELSIF (temp > N) THEN RETURN i; END IF; END LOOP; END IF; END; --------------------------------------------- FUNCTION mult_shift_add (X : IN std_ulogic_vector; C : IN std_ulogic_vector; N_taps : integer) RETURN std_ulogic_vector IS VARIABLE W : integer := X'length+C'length+log2(N_taps); VARIABLE result : std_ulogic_vector(W-1 downto 0); VARIABLE X_int,C_int,X_int_neg,t : integer; VARIABLE X_neg : std_ulogic_vector(X'length-1 downto 0); VARIABLE C_neg : std_ulogic_vector(C'length-1 downto 0); VARIABLE sign : std_ulogic; BEGIN -- Convert X operand. X_int_neg is the correct integer value of X. X_int := conv_integer(X); IF (X(X'length-1)='1') THEN X_neg := to_stdulogicvector(-X_int,X'length); ELSE X_neg := to_stdulogicvector(X_int,X'length); END IF; X_int_neg := conv_integer(X_neg); -- Convert C operand. C_neg is the correct std_ulogic_vector of C. C_int := conv_integer(C); IF (C(C'length-1)='1') THEN C_neg := to_stdulogicvector(-C_int,C'length); ELSE C_neg := to_stdulogicvector(C_int,C'length); END IF; -- What is the result's sign ? sign:= X(X'length-1) xor C(C'length-1); t:=0; FOR i IN 0 TO C_neg'length-1 LOOP IF (C_neg(i)='1') THEN t:=t+X_int_neg*(2**i); END IF; END LOOP; IF (sign='0') THEN result := to_stdulogicvector(t,W); ELSE result := to_stdulogicvector(-t,W); END IF; RETURN(result); END; END fir_lib;