# -----------------------------------------------------------------------------
# (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