# ----------------------------------------------------------------------------- # (C) Bibix # The content below includes confidential, proprietary information of # Bibix. All use, disclosure, and/or reproduction is prohibited # unless authorized in writing. All rights reserved. # ----------------------------------------------------------------------------- # File : fir_gen.arx # Description : generic FIR filter, following Example 3.1 of Meyer-Baese # Author : Sabih Gerez, Bibix # Creation date: March 30, 2011 # ----------------------------------------------------------------------------- # $Rev: 119 $ # $Author: sabih $ # $Date: 2011-04-25 01:14:47 +0200 (Mon, 25 Apr 2011) $ # $Log$ # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # General remarks # # This design is inspired by Example 3.1 of Meyer-Baese, but not # exactly the same: # - Fixed-point data types are used instead of signed/unsigned bitvectors. # - Coefficient and input-data word lengths have not been chosen equal. # - There are no fractional bits in input and output data. # - No pipelined multiplier is instantiated; combinational # multiplication is used instead. # # Some other disputable design choices have been left as is: # - All adders have the same width, viz. the width necessary at the # end of the chain. # - The final result is truncated, but the register holding the # result has the width before truncation (synthesis tool may # eliminate the redundancy). # ----------------------------------------------------------------------------- component top # GENERICS # input-data word length w1d: generic integer = 9 # coefficient word length w1c: generic integer = 9 # multiplier-output word length # w2: generic integer = 18 # adder width # w3: generic integer = 19 # output-data word length w4: generic integer = 11 # number of filter stages L: generic integer = 4 # GENERIC TYPES # input data T_d_in: generic type = signed(w1d) # coefficients T_coeff: generic type = signed(w1c,1) # output data T_d_out: generic type = signed(w4) # I/O load_x: in bit x_in: in T_d_in c_in: in T_coeff y_out: out T_d_out type # multiplier result T_mult: signed(w1c+w1d, 1+w1d) # adder result T_add: signed(w1c+w1d+ceil(log2(L))-1, w1d+ceil(log2(L))) register # storage for coefficients c: array[L] of T_coeff = 0 # storage of adder results a: array[L] of T_add = 0 # storage of input data x: T_d_in = 0 variable # output before truncation y: T_add # multiplication results p: array[L] of T_mult begin # store inputs if load_x == 0 # storing a coefficient implies shifting the previous ones c[L-1] = c_in for i in 0:L-2 c[i] = c[i+1] end else x = x_in end # main output before truncation y = a[0] # multiplications for i in 0:L-1 p[i] = c[i] * x end # store results of additions; first tap does not need an addition a[L-1] = p[L-1] for i in 0:L-2 a[i] = p[i] + a[i+1] end # main output, implies truncation y_out = y end