OpenCores
URL https://opencores.org/ocsvn/fir_filter/fir_filter/trunk

Subversion Repositories fir_filter

[/] [fir_filter/] [tags/] [FIR_low_area.vhd] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 arroxo2
 
2
--  CREATION DATE .......:  02 Jul 2007 (Filtro_FIR.vhd)
3
--  AUTHOR ..............:  DIEGO PARDO (arroxo2@yahoo.es)
4
--  REVISION ............:  2.0
5
--  LAST UPDATE .........:  08 April 2015
6
--  UPDATED BY ..........:  DIEGO PARDO 
7
 
8
--  TITLE "CONFIGURABLE FIR FILTER";
9
--
10
--  Generic VHDL (suitable for ALTERA, XILINX, MICROSEMI, etc)
11
--  Low resources occupation (fixed-point implementation)
12
--
13
 
14
 
15
--=============================================================================
16
--============================= LOCAL PACKAGE =================================
17
--=============================================================================
18
 
19
LIBRARY ieee;
20
USE ieee.std_logic_1164.all;
21
USE ieee.std_logic_arith.all;
22
USE ieee.std_logic_signed.all;
23
USE ieee.math_real.all;
24
 
25
 
26
PACKAGE fir_package IS
27
 
28
    CONSTANT max_coef: NATURAL:= 128;   -- (increase if needed)
29
    TYPE COEFF_ARRAY IS ARRAY (0 to max_coef-1) OF REAL;
30
    FUNCTION decimal_to_signed (c_real: IN REAL; CONSTANT precision: IN NATURAL) RETURN SIGNED;
31
 
32
END fir_package;
33
 
34
 
35
PACKAGE body fir_package IS
36
 
37
    FUNCTION decimal_to_signed (c_real: IN REAL; CONSTANT precision: IN NATURAL) RETURN SIGNED IS
38
    -- SIGNED = REAL / 2^(-precision) = REAL * 2^precision, with IEEE rounding
39
        CONSTANT RESOLUCION : REAL := "**"(2,REAL(INTEGER(precision)));
40
    BEGIN
41
        RETURN (SIGNED(CONV_STD_LOGIC_VECTOR(INTEGER(ROUND ("*"(c_real,RESOLUCION))),precision+1)));
42
    END FUNCTION;
43
 
44
END fir_package;
45
 
46
 
47
 
48
--=============================================================================
49
--================================== ENTITY ===================================
50
--=============================================================================
51
 
52
LIBRARY work;
53
USE WORK.fir_package.all;
54
 
55
LIBRARY ieee;
56
USE ieee.std_logic_1164.all;
57
USE ieee.std_logic_arith.all;
58
USE ieee.std_logic_signed.all;
59
USE ieee.math_real.all;
60
 
61
--.............................................................................
62
-- GAIN                1.0
63
-- SATURATION CONTROL  Yes (output)
64
-- OUTPUT ROUNDING     Yes (IEEE)
65
-- IMPLEMENTED BY      Fixed-Point (configurable resolution)
66
-- 3rd-PARTY IPs       No (generic VHDL)
67
--.............................................................................
68
 
69
ENTITY FIR_low_area IS
70
    GENERIC(
71
        data_length  : NATURAL     := 8;                   -- input/output length (number of bits)
72
        data_signed  : BOOLEAN     := false;               -- input/output type (signed or unsigned)
73
        improv_t     : BOOLEAN     := false;               -- minimal timing improvement by adding one extra output cycle delay (use only if needed)        
74
        bits_resol   : NATURAL     := 16;                  -- number of bits for the internal operations with decimals in fixed point. Recommended: bits_resol > taps. THIS SETTING IS CRITICAL FOR P&R RESULTS (MAX FREQ)
75
        taps         : NATURAL     := 5;                   -- =order+1, 2 coefficients as minimum (order=1)
76
        coefficients : COEFF_ARRAY :=(                     -- normalized coefficients bi: (bo,b1, ..., bN). They must be symmetric (but sign)
77
                                     -0.11735685282030676,
78
                                      0.23471370564061372,
79
                                      0.7066280917835991,
80
                                      0.23471370564061372,
81
                                     -0.11735685282030676,
82
                                      OTHERS=>0.0)         -- (always end with "others=>0.0")
83
    );
84
    PORT(
85
        areset       : IN    STD_LOGIC;                    -- active high                            
86
        sreset       : IN    STD_LOGIC;                    -- active high    
87
        clock_fs     : IN    STD_LOGIC;
88
        enable       : IN    STD_LOGIC;
89
        xn           : IN    STD_LOGIC_VECTOR(data_length-1 DOWNTO 0);   -- FILTER INPUT  (any fixed-point format, e.g. whole numbers)
90
        yn           : OUT   STD_LOGIC_VECTOR(data_length-1 DOWNTO 0)    -- FILTER OUTPUT (keeps same fixed-point format of input)
91
    );
92
END FIR_low_area;
93
 
94
 
95
 
96
ARCHITECTURE FIR_low_area_arch OF FIR_low_area IS
97
 
98
    type ENTRADA_xn IS ARRAY (taps-2 DOWNTO 0) OF SIGNED(data_length DOWNTO 0);   -- A(data_length,0) : x[n-k]
99
    type VALORES_h  IS ARRAY (taps-1 DOWNTO 0) OF SIGNED(bits_resol  DOWNTO 0);   -- A(0,bits_resol)  : h[n-k]
100
 
101
    SIGNAL REGISTRO_xn  : ENTRADA_xn;
102
 
103
    SIGNAL yn_1, yn_2   : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0);
104
    SIGNAL yn_aux       : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0);  -- yn_1 + yn_2
105
    SIGNAL yn_comb      : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0);
106
    SIGNAL yn_sync      : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0);
107
 
108
    SIGNAL yn_unsigned  : STD_LOGIC_VECTOR(data_length-1 DOWNTO 0);
109
    SIGNAL yn_signed    : STD_LOGIC_VECTOR(data_length-1 DOWNTO 0);
110
 
111
    CONSTANT SIGNED_MAX : INTEGER :=      2**(yn'length-1)-1;
112
    CONSTANT SIGNED_MIN : INTEGER := -1 * 2**(yn'length-1);
113
 
114
 
115
BEGIN
116
 
117
 
118
    ASSERT (bits_resol >= 4)
119
    REPORT "PLEASE INCREASE RESOLUTION BITS (result will be poor)" SEVERITY FAILURE;
120
 
121
        -- pragma translate_off
122
        process
123
          VARIABLE sum_coeff : real;
124
        begin
125
      sum_coeff := 0.0;
126
      FOR ind IN 0 TO (taps-1) LOOP
127
        sum_coeff := sum_coeff + coefficients(ind);
128
      END LOOP;
129
      ASSERT sum_coeff = 1.0
130
      REPORT "COEFFICIENTS ARE NOT NORMALIZED" SEVERITY WARNING;
131
          wait;
132
        end process;
133
        -- pragma translate_on
134
 
135
 
136
    -- =======================================================================================
137
    --  HALF FILTERING OPERATIONS (1/2)  
138
    --  (DOES NOT INCLUDE INITIAL AND FINAL COEFFICIENTS, INCLUDES CENTRE COEFFICIENT (WHEN "taps" EVEN)
139
    -- =======================================================================================
140
 
141
    process1:
142
    PROCESS (clock_fs, areset)
143
        VARIABLE xn_a_pares : SIGNED (data_length+1 DOWNTO 0);                            -- to sum x[n-k] with symmetric coefficients
144
        VARIABLE REGISTRO_h : VALORES_h := (OTHERS => (OTHERS => '0'));                   -- it stores the coefficients (avoids registers)
145
        VARIABLE producto   : SIGNED (data_length+1+bits_resol+1 DOWNTO 0);               -- product of xn_a_pares by symmetric coefficient
146
        VARIABLE yn_aux     : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0); -- partial sum
147
        VARIABLE signos_bi  : STD_LOGIC_VECTOR (1 DOWNTO 0);                              -- signs of the symmetric coefficients             
148
        VARIABLE indice1    : NATURAL;
149
        VARIABLE margen     : NATURAL;
150
 
151
    BEGIN
152
        IF (areset = '1') THEN
153
            yn_1 <= (OTHERS => '0');
154
 
155
        ELSIF rising_edge(clock_fs) THEN
156
          IF (sreset = '1') THEN
157
            yn_1 <= (OTHERS => '0');
158
          ELSE
159
 
160
            IF (enable = '1') THEN
161
 
162
                -- variable avoids h[n] register, REGISTRO_h(0) = bN 
163
                FOR ind IN 0 TO (taps-1) LOOP
164
                    REGISTRO_h(ind) := decimal_to_signed (coefficients(taps-1-ind),bits_resol);
165
                END LOOP;
166
 
167
                yn_aux := (OTHERS => '0');
168
 
169
                -- symmetric coefficients (but first and last ones):
170
                -- In this cycle x[n-k] has not been applied yet to the shift register of x[n]
171
                IF (taps > 3) THEN
172
 
173
                    indice1 := (taps/2)+(taps MOD 2);
174
                    margen  := ((taps-1)-(taps/2))/2 - (taps MOD 2);
175
 
176
                    FOR i IN indice1 TO (indice1 + margen) LOOP
177
 
178
                        -- symmetric bi signs 
179
                        signos_bi(1):= REGISTRO_h(i)(bits_resol);
180
                        signos_bi(0):= REGISTRO_h(taps-1-i)(bits_resol);
181
 
182
                        CASE signos_bi IS
183
                            WHEN "00"   => xn_a_pares:= "+"( CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
184
                            WHEN "01"   => xn_a_pares:= "+"( CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
185
                            WHEN "10"   => xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
186
                            WHEN OTHERS => xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
187
                        END CASE;
188
 
189
                        producto := "*"(xn_a_pares, ABS(REGISTRO_h(i)));
190
                        yn_aux   := "+"(yn_aux, producto);
191
                    END LOOP;
192
                END IF;
193
 
194
                --------------------------------------------------------------- 
195
                -- central coefficient operation (when taps is even)
196
                ---------------------------------------------------------------
197
                -- non-symmetric coefficient
198
 
199
                IF (taps MOD 2)/=0 THEN
200
                    producto := "*"(CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps/2))),data_length+2), REGISTRO_h(taps/2));
201
                    yn_aux   := "+"(yn_aux, producto);
202
                END IF;
203
 
204
                --------------------------------------------------------------- 
205
                -- output of processo1
206
                ---------------------------------------------------------------
207
                -- yn_1 has decimal part (bits_resol bits)
208
 
209
                yn_1 <= yn_aux;
210
 
211
            END IF;
212
          END IF;
213
        END IF;
214
    END PROCESS process1;
215
 
216
 
217
    -- =======================================================================================
218
    --  HALF FILTERING OPERATIONS (2/2)  
219
    --  (INCLUDINF INITIAL AND FINAL COEFFICIENTS)
220
    -- =======================================================================================
221
 
222
    process2:
223
    PROCESS (clock_fs, areset)
224
        VARIABLE xn_a_pares : SIGNED (data_length+1 DOWNTO 0);                            -- to sum x[n-k] with symmetric coefficients
225
        VARIABLE REGISTRO_h : VALORES_h := (OTHERS => (OTHERS => '0'));                   -- it stores the coefficients (avoids registers)
226
        VARIABLE producto   : SIGNED (data_length+1+bits_resol+1 DOWNTO 0);               -- product of xn_a_pares by symmetric coefficient
227
        VARIABLE yn_aux     : SIGNED (data_length+1+bits_resol+1+(taps-2) DOWNTO 0); -- partial sum
228
        VARIABLE signos_bi  : STD_LOGIC_VECTOR (1 DOWNTO 0);                              -- signs of the symmetric coefficients
229
        VARIABLE indice1    : NATURAL;
230
        VARIABLE margen     : NATURAL;
231
 
232
    BEGIN
233
        IF (areset = '1') THEN
234
            yn_2 <= (OTHERS => '0');
235
 
236
        ELSIF rising_edge(clock_fs) THEN
237
          IF (sreset = '1') THEN
238
            yn_2 <= (OTHERS => '0');
239
          ELSE
240
 
241
            IF (enable = '1') THEN
242
 
243
                -- variable avoids h[n] register, REGISTRO_h(0) = bN   
244
                FOR ind IN 0 TO (taps-1) LOOP
245
                    REGISTRO_h(ind) := decimal_to_signed (coefficients(taps-1-ind),bits_resol);
246
                END LOOP;
247
 
248
 
249
                yn_aux := (OTHERS => '0');
250
 
251
                -- symmetric coefficients (but first and last ones). When taps < 7 the operations are resolved by process1:
252
                -- In this cycle x[n-k] has not been applied yet to the shift register of x[n]
253
                IF (taps > 6) THEN
254
 
255
                    indice1 := (taps/2)+(taps MOD 2);
256
                    margen  := ((taps-1)-(taps/2))/2 - (taps MOD 2);
257
 
258
                    FOR i IN (indice1 + margen + 1) TO (taps-2) LOOP
259
 
260
                        -- symmetric bi signs 
261
                        signos_bi(1):= REGISTRO_h(i)(bits_resol);
262
                        signos_bi(0):= REGISTRO_h(taps-1-i)(bits_resol);
263
 
264
                        CASE signos_bi IS
265
                            WHEN "00"   => xn_a_pares:= "+"( CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
266
                            WHEN "01"   => xn_a_pares:= "+"( CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
267
                            WHEN "10"   => xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
268
                            WHEN OTHERS => xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(signed(REGISTRO_xn(i))),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(taps-1-i))),data_length+2));
269
                        END CASE;
270
 
271
                        producto:= "*"(xn_a_pares, ABS(REGISTRO_h(i)));
272
                        yn_aux  := "+"(yn_aux, producto);
273
                    END LOOP;
274
                END IF;
275
 
276
                ----------------------------------------------------------------                                                
277
                -- first and last coefficients operation (symmetric)
278
                ----------------------------------------------------------------               
279
                -- The initial coefficient multiplies x[n] (not registered yet)             
280
 
281
                signos_bi(1):= REGISTRO_h(taps-1)(bits_resol);
282
                signos_bi(0):= REGISTRO_h(0)(bits_resol);
283
 
284
                CASE signos_bi IS
285
 
286
                    WHEN "00"   => if (data_signed = true) then
287
                                     xn_a_pares:= "+"( CONV_SIGNED(conv_integer(  signed(xn)),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
288
                                   else
289
                                     xn_a_pares:= "+"( CONV_SIGNED(conv_integer(unsigned(xn)),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
290
                                   end if;
291
                    WHEN "01"   => if (data_signed = true) then
292
                                     xn_a_pares:= "+"( CONV_SIGNED(conv_integer(  signed(xn)),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
293
                                   else
294
                                     xn_a_pares:= "+"( CONV_SIGNED(conv_integer(unsigned(xn)),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
295
                                   end if;
296
                    WHEN "10"   => if (data_signed = true) then
297
                                     xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(  signed(xn)),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
298
                                   else
299
                                     xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(unsigned(xn)),data_length+2),  CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
300
                                   end if;
301
                    WHEN OTHERS => if (data_signed = true) then
302
                                     xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(  signed(xn)),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
303
                                   else
304
                                     xn_a_pares:= "+"(-CONV_SIGNED(conv_integer(unsigned(xn)),data_length+2), -CONV_SIGNED(conv_integer(signed(REGISTRO_xn(0))),data_length+2));
305
                                   end if;
306
                END CASE;
307
 
308
                producto := "*"(xn_a_pares, ABS(REGISTRO_h(taps-1)));
309
                yn_aux   := "+"(yn_aux, producto);
310
 
311
                --------------------------------------------------------------- 
312
                -- output of processo2
313
                ---------------------------------------------------------------             
314
                -- yn_2 has decimal part (bits_resol bits)
315
 
316
                yn_2 <= yn_aux;
317
 
318
            END IF;
319
          END IF;
320
        END IF;
321
    END PROCESS process2;
322
 
323
 
324
    -- =======================================================================================
325
    --  SHIT REGISTER: x[n-k]
326
    -- =======================================================================================
327
 
328
    process_reg:
329
    PROCESS (clock_fs, areset)
330
    BEGIN
331
        IF (areset = '1') THEN
332
            REGISTRO_xn <= (OTHERS => (OTHERS => '0'));
333
 
334
        ELSIF rising_edge(clock_fs) THEN
335
          IF (sreset = '1') THEN
336
            REGISTRO_xn <= (OTHERS => (OTHERS => '0'));
337
          ELSE
338
 
339
            IF (enable = '1')THEN
340
 
341
                ---------------------------------------------------------------
342
                -- x[n-k], it is not applied instantaneously (scheduled)  
343
                ---------------------------------------------------------------             
344
                -- right-shift
345
 
346
                FOR i IN 0 TO (taps-3) LOOP        -- (ignored when taps=2)
347
                    REGISTRO_xn(i)<= REGISTRO_xn(i+1);
348
                END LOOP;
349
 
350
                if (data_signed = true) then
351
                  REGISTRO_xn(taps-2) <= CONV_SIGNED(conv_integer(  signed(xn)),data_length+1);
352
                else
353
                  REGISTRO_xn(taps-2) <= CONV_SIGNED(conv_integer(unsigned(xn)),data_length+1);
354
                end if;
355
 
356
            END IF;
357
          END IF;
358
        END IF;
359
 
360
    END PROCESS process_reg;
361
 
362
 
363
    -- =======================================================================================
364
    --  OUTPUT (neither saturation control nor IEEE rounding)
365
    -- =======================================================================================
366
    -- SUM of process1 and process2 outputs
367
 
368
    yn_comb <= yn_1 + yn_2;
369
    yn_sync <= yn_1 + yn_2 when rising_edge(clock_fs);
370
 
371
    yn_aux  <= yn_sync when (improv_t = true) else yn_comb;
372
 
373
 
374
    --------------------------------------------------------------- 
375
    -- OUTPUT (with saturation control and IEEE rounding)
376
    ---------------------------------------------------------------
377
 
378
    -- yn_aux of type A(_,bits_resol): 
379
    --                  whole part:   'LEFT downto bits_resol 
380
    --                  decimal part: (bits_resol-1) downto 0           
381
    --
382
    --                 |<------------------------------------------ yn_aux ------------------------------------------->|
383
    --                  [yn_aux'left] ..... [bits_resol+data_length-1] ..... [bits_resol]   [bits_resol-1] .........[0]
384
    --                                     |<------------ yn_signed/unsigned ------------>|<----- (decimal part) ----->|
385
 
386
 
387
    -- unsigned output:
388
    yn_unsigned <=
389
      (OTHERS => '0') WHEN yn_aux(bits_resol+data_length+1) = '1'                                                                                                                                          ELSE -- negative overflow 
390
      (OTHERS => '1') WHEN yn_aux(bits_resol+data_length)   = '1'                                                                                                                                          ELSE -- positive overflow                                                                          
391
      STD_LOGIC_VECTOR(yn_aux(bits_resol+data_length-1 DOWNTO bits_resol))+1 WHEN yn_aux(bits_resol-1) = '1' and STD_LOGIC_VECTOR(yn_aux(bits_resol+data_length-1 downto bits_resol)) /= (yn'range => '1') ELSE -- positive IEEE rounding (avoids positive overflow)
392
      STD_LOGIC_VECTOR(yn_aux(bits_resol+data_length-1 DOWNTO bits_resol));                                                                                                                                     -- truncated
393
 
394
    -- signed output:
395
    yn_signed   <=
396
      STD_LOGIC_VECTOR(CONV_SIGNED(SIGNED_MIN,data_length)) WHEN yn_aux(bits_resol+data_length) = '1' and yn_aux(bits_resol+data_length-1) = '0'                                              ELSE -- negative overflow 
397
      STD_LOGIC_VECTOR(CONV_SIGNED(SIGNED_MAX,data_length)) WHEN yn_aux(bits_resol+data_length) = '0' and yn_aux(bits_resol+data_length-1) = '1'                                              ELSE -- positive overflow
398
      STD_LOGIC_VECTOR(yn_aux(bits_resol+data_length-1 DOWNTO bits_resol))+1 WHEN yn_aux(bits_resol-1) = '1' and                                                                                   -- positive or negative IEEE rounding (avoids positive overflow)
399
        (yn_aux(bits_resol+data_length-1) = '1' or STD_LOGIC_VECTOR(yn_aux(bits_resol+data_length-2 downto bits_resol)) /= (yn_aux(bits_resol+data_length-2 downto bits_resol)'range => '1')) ELSE
400
      STD_LOGIC_VECTOR(signed(yn_aux(bits_resol+data_length-1 DOWNTO bits_resol)));                                                                                                                -- truncated
401
 
402
    -- FINAL OUTPUT
403
    yn <= yn_signed when (data_signed = true) else yn_unsigned;
404
 
405
 
406
END FIR_low_area_arch;
407
 
408
 
409
 
410
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
411
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
412
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
413
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
414
 
415
 
416
-------------------------------------------------------------------------------
417
--                                DESCRIPTION 
418
-------------------------------------------------------------------------------
419
--          
420
------------------
421
-- DELAY
422
------------------
423
--  clock_fs period x taps
424
--
425
------------------
426
-- AREA
427
------------------
428
--  bits_resol  stablishes the precision of the filtering operations (resources)
429
--
430
------------------
431
-- OUTPUT ERROR
432
------------------
433
--  maximum output error: 
434
-- 
435
--             ------------------------------------------------------
436
--            | taps * [2^(-bits_resol)] * [(2^data_length)-1)] |
437
--             ------------------------------------------------------
438
-- (taps = order+1)
439
--
440
------------------------------------------------------------------------------
441
-- Operations:
442
------------------------------------------------------------------------------
443
--
444
--          h[n] = A(0,bits_resol) with resolution = 2^(-bits_resol)
445
--          x[n] = A(data_length,0)
446
--
447
--  y[n] = sum{x[n-k] x h[k]}
448
--          x[n-i] x h[i] = A(data_length,0) x A(0,bits_resol) = A(data_length+0+1,bits_resol)
449
--          y[n] = A(data_length+1+[taps]-1,bits_resol) 
450
--
451
------------------------------------------------------------------------------
452
-- Implementation:
453
------------------------------------------------------------------------------
454
--
455
--  -FIR direct form II-
456
--
457
--  3 process() in parallel:
458
--
459
--    process1():    1/2 part of the filtering operations
460
--    process2():    2/2 part of the filtering operations
461
--    process_reg(): x[n-k]
462
--
463
--  FIR filters have symmetric coefficients (but sign):
464
--
465
--  e.g. taps=5 and positive h[n] coefficients: 
466
--      x[n-3]*h(3) + x[n-1]*h[1] = (x[n-3]+x[n-1])*h[3], because h[1]=h[3]
467
--
468
---------------
469
-- 
470
--  x: products by means of process1() and centre coefficient
471
--  o: products by means of process2() and first-last coefficients
472
--
473
--
474
--   taps  bi                              prod process1()               prod process2()
475
--
476
--      2       x x                             0                             1   bo=b1
477
--      3       o x o                           1   b1                        1   bo=b2
478
--      4       o x x o                         1   b1=b2                     1   bo=b3       
479
--      5       o x x x o                       2   b1=b3, b2                 1   bo=b4       
480
--      6       o x x x x o                     2   b1=b4, b2=b3              1   bo=b5           
481
--      7       o o x x x o o                   2   b2=b4, b3                 2   bo=b6,  b1=b5 
482
--      8       o o x x x x o o                 2   b2=b5, b3=b4              2   bo=b7,  b1=b6
483
--      9       o o x x x x x o o               3   b2=b6, b3=b5, b4          2   bo=b8,  b1=b7
484
--      10      o o x x x x x x o o             3   b2=b7, b3=b6, b4=b5       2   bo=b9,  b1=b8
485
--      11      o o o x x x x x o o o           3   b3=b7, b4=b6, b5          3   bo=b10, b1=b9,  b2=b8
486
--      12      o o o x x x x x x o o o         3   b3=b8, b4=b7, b5=b6       3   bo=b11, b1=b10, b2=b9
487
--      13      o o o x x x x x x x o o o       4   b3=b9, b4=b8, b5=b7, b6   3   bo=b12, b1=b11, b2=b10
488
--      14      o o o o x x x x x x o o o o     4   b4=b9, b5=b8, b6=b7       4   bo=b13, b1=b12, b2=b11, b3=b10
489
--      15      o o o o x x x x x x x o o o o   4   b4=b10,b5=b9, b6=b8, b7   4   bo=b14, b1=b13, b2=b12, b3=b11
490
--     (etc)...
491
 
492
-------------------------------------------------------------------------------
493
-- Fixed-Point Arithmetic: An Introduction
494
--   Randy Yates
495
--   March 3, 2001 11:52
496
-------------------------------------------------------------------------------
497
--
498
-- A(a,b):  a = whole part, b = decimal part
499
--  
500
--          length             = (a+b) +1 bits (sign)
501
--          resolution (steps) =  2^(-b)
502
--          maximum value      =  2^a - 2^(-b)
503
--          minimum value      = -2^(-a)
504
--
505
-- Operations:
506
--
507
--          A(x,y) * A(z,n)         =   A(x+z+1,y+n), length = (x+z+1+y+n) +1 bits (sign)
508
--          A(x,y) + A(x,y)         =   A(x+1,y)    , length = (x+1+y) +1 bits (sign)
509
--          A(x,y) + A(x,y) + A(x,y)=   A(x+2,y)    , length = (x+2+y) +1 bits (sign)
510
-- 
511
 
512
------------------------------------------------------------------------------          
513
--                 TYPES CONVERSION (OF CONSTANT VALUES)
514
------------------------------------------------------------------------------
515
--
516
--      REAL -> INTEGER -> STD_LOGIC_VECTOR -> SIGNED:
517
--
518
--          SIGNED(CONV_STD_LOGIC_VECTOR(INTEGER(ROUND(<real_value>))))
519
--
520
--      SIGNED -> STD_LOGIC_VECTOR -> INTEGER -> REAL:
521
--
522
--          ROUND(REAL(CONV_INTEGER(CONV_STD_LOGIC_VECTOR(<signed_value>))))
523
--

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.