We can update you automatically when this page changes.
To receive regular notification of updates to our Model of the
Month section, click here.
The VHDL code presented in this month's Model of the Month will show you how to describe a typical reference model in VHDL. Well use a 32-tap FIR filter as an example. For a discussion of the advantages of reference models, please refer to our Tip of the Month page. Letss look at some of the highlights of this model.
Most obviously, the model is a single clocked process. The core of the FIR algorithm is embedded in the function sum_of_products which implements the chain of multiply-accumulations. The current data input is the signal a, which is added to the data_table, the set of data inputs sampled over the last N clock cycles (in this example N is 32), courtesy of the shift_fifo function. The coefficients for the filter arrive on the two-dimensional b input; they are stored in the coefficient_table_var array. For the sum_of_products function, the data_table data set has to be re-ordered which is where the reverse_order function comes in.
This FIR model allows bit-level performance modelling. Note that the output wordlength is 21 bits. The input data and coefficients are both 8 bit wordlength:
As the model is clocked and operates on bit-level data, this FIR filter description can be used (and indeed was used) as a reference model for the design of a synthesisable FIR filter.
You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Acknowledgements page for more details).
-- FIR Filter Model -- -- +-----------------------------+ -- | Copyright 1996 DOULOS | -- | Library: DSP | -- | designer : Tim Pagden | -- | opened: 30 Sep 1995 | -- +-----------------------------+ -- Architectures: -- 19.11.95 behavioural library maths; library matrix; library vfp; library dsp; architecture behavioural of FIR_32tap_8_8 is use maths.maths_functions.all; use matrix.matrix_class.all; use vfp.generic_functions.all; use vfp.generic_conversions.all; use vfp.mixed_operators.all; use vfp.twos_complement_types.all; constant number_of_taps: integer := 32; signal data_table: single_vector(number_of_taps-1 downto 0); signal coefficient_table: single_vector(number_of_taps-1 downto 0); begin -- y <= sum_over (0, k-1, a((k-1)-i), b(i)) -- coefficient_table <= b; fir_algorithm: process (clock) variable data_out : single; variable fir_result : single; variable data_table_var: single_vector(number_of_taps-1 downto 0); -- the coeff table assignment really ought to be handled at the entity interface variable coefficient_table_var: single_vector(number_of_taps-1 downto 0); variable tmp2 : single; variable num_taps_minus_1 : integer; variable y_result : twos_complement(20 downto 0); begin if posedge (clock) then -- data_table_var := data_table(number_of_taps-1) & data_table(number_of_taps-2 downto 0); -- putting the coeff table in a loop like this allows dynamic coeff updating for i in 0 to number_of_taps-1 loop coefficient_table_var(i) := single(to_integer(b(i)))/127.0; end loop; data_table_var := data_table; tmp2 := single(to_integer(to_twos_complement(a))); data_table_var := shift_fifo (data_table_var, tmp2); data_table <= data_table_var; num_taps_minus_1 := number_of_taps-1; fir_result := sum_of_products ( lower_limit => 0, upper_limit => number_of_taps-1, a_in => reverse_order(data_table_var), b_in => coefficient_table_var ); y_result := y_result = integer(fir_result); y <= to_std_ulogic_vector(y_result); end if; end process; end behavioural;
ASIC Design and Project
Services
Doulos Training Courses
Copyright 1995-1996 Doulos
This page was last updated 26th May 1996.
We welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk