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

Subversion Repositories wdsp

[/] [wdsp/] [trunk/] [rtl/] [vhdl/] [WISHBONE_FFT/] [fft_core_pipeline1.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 parrado
-- N point FFT 
2
-- Uses R2^2SDF algorithm 
3
-- 
4
-- Generics used: 
5
-- N - number of points taken - powers of 2 only, ranging f 8 to 1024 points. 
6
-- input_ width - bit width  of the input vector 
7
--  twiddle  width - width of the twiddle factors stored in the ROM 
8
-- add_g - Adder growth - Adders grow 0 or 1 bits each time they are used 
9
--         Exculdes adders in the complex multiplier (that is handled by mult_g) 
10
-- mult_g - multiplier growth - 0 to twiddle_width+        1 - Growth during the complex 
11
--   multiplier stages 
12
--  
13
-- Width of output vector is as follows (num_stages=log2(N): 
14
--    N      width 
15
--   8,16    input_width + (num_stages * add_g) + mult_g 
16
--   32,64   input_width + (num_            stages * add_g) + 2*mult_g 
17
-- 128,256    input_width + (num_stage            s * add_g) + 3*mult_g 
18
-- 512,1024   input_width + (num_stages            * add_g) + 4*mult_g 
19
--  
20
-- Due to the way this system was made parameterizable, there are many signals 
21
-- that will remain unconnected.  This is normal. 
22
--  
23
-- Default generics are for a simple 64 point FFT 
24
 
25
-- Each stage with complex multiplier introduces a 1/2 gain
26
 
27
--Changes made by Alex-Parrado to the original version of Adam Robert Miller
28
 
29
        --Pipeline registers and clock enables, have been added. Clock frequency above of 100 MHz for all FFT sizes
30
 
31
        --Synchronous ROMs for proper RAM block inferring. MATLAB scripts have been modified.
32
 
33
 
34
 
35
LIBRARY ieee;
36
USE ieee.std_logic_1164.ALL;
37
 
38
USE ieee.numeric_std.ALL;
39
--USE ieee.std_logic_arith.ALL; 
40
use ieee.math_real.all;
41
use work.fft_pkg .all;
42
 
43
entity fft_core_pipeline1 is
44
  generic (
45
        input_width : integer :=16;
46
   twiddle_width : integer :=16;
47
   N : integer :=1024;
48
   add_g : integer:=0;--1;  --Either 0 or 1 only. 
49
   mult_g : integer:=0--9  --Can be any number from 0 to twiddle_width+1 
50
   );
51
  port (  clock : in std_logic;
52
   resetn : in std_logic;
53
   enable : in std_logic;
54
        clear : in std_logic;
55
        enable_out: out std_logic;
56
        frame_ready: out std_logic;
57
        index : out std_logic_vector(integer(ceil(log2(real((N)))))-1 downto 0);
58
      xin_r : in std_logic_vector(input_width-1 downto 0);
59
      xin_i : in std_logic_vector(input_width-1 downto 0);
60
      Xout_r : out std_logic_vector (input_width+((integer(ceil(log2(real((N)))))-1)/2)*mult_g+integer(ceil(log2(real((N)))))*add_g-1 downto 0);
61
      Xout_i : out std_logic_vector (input_width+((integer(ceil(log2(real((N)))))-1)/2)*mult_g+integer(ceil(log2(real((N)))))*add_g-1 downto 0)
62
   );
63
end fft_core_pipeline1;
64
 
65
architecture structure of fft_core_pipeline1 is
66
--Signal declarations 
67
constant num_stages: integer :=integer(ceil(log2(real((N)))));
68
signal control: std_logic_vector(num_stages-1 downto 0);
69
signal bit_reverse_index: std_logic_vector(num_stages-1 downto 0);
70
type stage_array is array (1 to num_stages-1) of
71
 std_logic_vector(input_width+(num_stages*add_g)+(((num_stages-1)/2)*mult_g)-1  downto 0);
72
signal stoscon_r: stage_array;
73
signal  stoscon_i: stage_array;
74
type rom_array is array (1 to (num_stages-1)/2) of std_logic_vector(twiddle_width-1 downto 0);
75
signal rtoscon_r: rom_array;
76
signal rtoscon_i: rom_array;
77
 
78
type enables_array is array (0 to num_stages+1) of std_logic_vector(0 downto 0);
79
signal enables: enables_array;
80
 
81
 
82
type counter_registers_array is array (0 to num_stages+1) of std_logic_vector(num_stages-1 downto 0);
83
signal counter_registers: counter_registers_array;
84
 
85
--
86
 
87
signal xin_r_reg :  std_logic_vector(input_width-1 downto 0);
88
signal xin_i_reg :  std_logic_vector(input_width-1 downto 0);
89
 
90
signal t_ff: std_logic_vector(0 downto 0);
91
signal en_t_ff:std_logic_vector(0 downto 0);
92
signal clear_t_ff:std_logic;
93
 
94
 
95
--component declarations 
96
component counterhle
97
  generic (width : integer);
98
 
99
  port (   clock : in std_logic;
100
   resetn : in std_logic;
101
   enable :  in std_logic;
102
        clear : in std_logic;
103
      countout :  out std_logic_vector(width-1 downto 0)
104
    );
105
end component;
106
 
107
component rom1
108
  generic (
109
                data_width :  integer;
110
                address_width : integer);
111
  port (
112
      clk: in std_logic;
113
                address: IN     std_logic_vector (address_width-1 DOWNTO 0);
114
        datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0);
115
        datai     : OUT    std_logic_vector (data_width-1  DOWNTO 0)
116
    );
117
end component;
118
 
119
component rom2
120
  generic (
121
        data_width : integer;
122
        address_width : integer);
123
  port  (
124
  clk: in std_logic;
125
        address    : IN     std_logic_vector (address_width-1 DOWNTO 0);
126
    datar     : OUT     std_logic_vector (data_width-1 DOWNTO 0);
127
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)
128
   );
129
end component;
130
 
131
component rom3
132
  generic (
133
        data_width : integer;
134
        address_width : integer);
135
  port  (
136
  clk: in std_logic;
137
        address    : IN     std_logic_vector (address_width-1 DOWNTO 0);
138
    datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0);
139
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)
140
    );
141
end component;
142
 
143
component rom4
144
  generic (
145
        data_width : integer;
146
        address_width : integer);
147
  port  (
148
  clk: in std_logic;
149
        address    : IN     std_logic_vector (address_width-1 DOWNTO 0);
150
    datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0);
151
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)
152
   );
153
end component;
154
 
155
component stage_I
156
     generic  (
157
                data_width : INTEGER;
158
                add_g : INTEGER;
159
                shift_stages : INTEGER);
160
  port  (
161
                prvs_r :in std_logic_vector(data_width-1-add_g downto 0);
162
                prvs_i :in std_logic_vector(data_width-1-add_g downto 0);
163
                s :in std_logic;
164
                clock : in std_logic;
165
                enable: in std_logic;
166
                resetn : in std_logic;
167
   tonext_r :out std_logic_vector(data_width-1 downto 0);
168
   tonext_i :out std_logic_vector(data_width-1 downto 0));
169
end component;
170
 
171
component stage_II
172
     generic  (
173
                data_width : INTEGER;
174
                add_g : INTEGER;
175
                mult_g : INTEGER;
176
                twiddle_width : INTEGER;
177
                shift_stages : INTEGER
178
                );
179
  port  (
180
                prvs_r :in std_logic_vector(data_width-1-add_g downto 0);
181
                prvs_i :in std_logic_vector(data_width-1-add_g downto 0) ;
182
                t :in std_logic;
183
                s :in std_logic;
184
                clock : in std_logic;
185
                enable: in std_logic;
186
                resetn : in std_logic;
187
                fromrom_r :in std_logic_vector (twiddle_width-1 downto 0) ;
188
                fromrom_i :in std_logic_vector(twiddle_width-1 downto 0);
189
                tonext_r :out std_logic_vector(data_width+mult_g-1 downto 0);
190
                tonext_i :out std_logic_vector(data_width+mult_g-1 downto 0));
191
end component;
192
 
193
component stage_I_last
194
  generic  (
195
                data_width : INTEGER;
196
                add_g : INTEGER
197
                );
198
  port (
199
                prvs_r :in std_logic_vector(data_width-1-add_g downto 0);
200
                prvs_i :in std_logic_vector(data_width-1-add_g downto 0);
201
        s :in std_logic; clock : in std_logic; resetn : in std_logic;
202
                  enable: in std_logic;
203
                tonext_r :out std_logic_vector(data_width-1 downto 0);
204
                tonext_i :out std_logic_vector(data_width-1 downto 0));
205
end component;
206
 
207
component stage_II_last
208
  generic  (
209
                data_width : INTEGER;
210
                add_g : INTEGER
211
                );
212
  port  (
213
                prvs_r :in std_logic_vector(data_width-1-add_g downto 0);
214
                prvs_i :in std_logic_vector(data_width-1-add_g downto 0);
215
                t :in std_logic;
216
                s :in std_logic;
217
                clock : in std_logic;
218
                enable: in std_logic;
219
                resetn :  in std_logic;
220
                tonext_r :out std_logic_vector(data_width-1 downto 0);
221
                tonext_i :out std_logic_vector(data_width-1 downto 0));
222
end component;
223
 
224
component shiftreg1
225
  generic (
226
                data_width : integer
227
);
228
  port (
229
                clock : IN std_logic;
230
                enable: in std_logic;
231
                clear: in std_logic;
232
        read_data  : OUT    std_logic_vector (data_width-1 DOWNTO 0);
233
        write_data : IN     std_logic_vector (data_width-1 DOWNTO 0);
234
                resetn     : IN     std_logic
235
                );
236
end component;
237
 
238
begin
239
 
240
controller : component counterhle
241
     generic map (
242
                width=>num_stages
243
)
244
  port map (
245
                clock=>clock,
246
                resetn=>resetn,
247
                clear => clear,
248
                enable=>enable,
249
                countout=>control
250
                );
251
 
252
 
253
-- Counter, pipeline registers
254
counter_registers(0)<=control;
255
forcounterregs: for i in 0 to num_stages generate
256
counterregi: shiftreg1
257
generic  map(
258
                data_width=>num_stages
259
)
260
  port map (
261
                clock=>clock,
262
                enable=>'1',
263
                clear => clear,
264
        read_data=>counter_registers(i+1),
265
        write_data=>counter_registers(i),
266
                resetn=>resetn
267
                );
268
 
269
end generate;
270
 
271
 
272
--Enable, pipeline registers
273
enables(0)(0)<=enable;
274
forenablesregs: for i in 0 to num_stages generate
275
enableregi: shiftreg1
276
generic  map(
277
                data_width=>1
278
)
279
  port map (
280
                clock=>clock,
281
                enable=>'1',
282
                clear => clear,
283
        read_data=>enables(i+1),
284
        write_data=>enables(i),
285
                resetn=>resetn
286
                );
287
 
288
end generate;
289
 
290
 
291
 
292
--Input registers
293
reginputr: shiftreg1
294
generic  map(
295
                data_width=>input_width
296
)
297
  port map (
298
                clock=>clock,
299
                enable=>'1',
300
                clear => '0',
301
        read_data=>xin_r_reg,
302
        write_data=>xin_r,
303
                resetn=>resetn
304
                );
305
 
306
reginputi: shiftreg1
307
generic  map(
308
                data_width=>input_width
309
)
310
  port map (
311
                clock=>clock,
312
                enable=>'1',
313
                clear => '0',
314
        read_data=>xin_i_reg,
315
        write_data=>xin_i,
316
                resetn=>resetn
317
                );
318
 
319
 
320
stages : for i in 1 to num_stages generate
321
--  constan ity : in r :=i rem 2;  t par tege
322
--  constant shift_stages : integer := 2**(num_stages - i); 
323
--  consta nt rom_loc : integer :=i/2; 
324
--  constant data_width : integer :=input_width + (i*add_g) + (((i-1)/2)*mult_g); 
325
--  constant s: integer :      =(num_stages-i); 
326
--  constant t    : integer :=(num_stages-i+1); 
327
     initial_stage: if i=1 generate
328
    initial_stage_I :  component stage_I
329
      generic map (
330
                data_width=>input_width + (i*add_g)+(((i-1)/2)*mult_g),
331
                add_g=>add_g,
332
                shift_stages=>2**(num_stages - i))
333
    port map (
334
                prvs_r=>xin_r_reg,prvs_i=>xin_i_reg,s=>counter_registers(i)((num_stages-i)),
335
                clock=>clock,
336
                enable=>enables(i)(0),
337
                resetn=>resetn,
338
                tonext_r=>stoscon_r(i)(input_width+(i*add_g) + (( (i-1)/2)*mult_g)-1 downto 0),
339
        tonext_i=>stoscon_i(i)(input_width+ (i*add_g) + (( (i-1)/2)*mult_g)-1 downto 0));
340
  end generate initial_stage;
341
 
342
  even_stages: if ((i rem 2)=0) and (i/=num_stages) generate
343
    inner_stage_II : component stage_II
344
      generic map (
345
                data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g),
346
                add_g=>add_g,mult_g=>mult_g,
347
                twiddle_width=>twiddle_width,
348
                shift_stages=>2**(num_stages - i)
349
                )
350
    port map (
351
                prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i -1)/2)*mult_g)-1-add_g downto 0),
352
                prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
353
                t=>counter_registers(i)((num_stages-i+1)),
354
                s=>counter_registers(i)((num_stages-i)),clock=>clock,resetn=>resetn,
355
                enable=>enables(i)(0),
356
                fromrom_r=>rtoscon_r(i/2),fromrom_i=>rtoscon_i(i/2),
357
        tonext_r=>stoscon_r(i)(input_width + (i*add_g) + (((i-1)/2)*mult_g)+mult_g-1 downto 0),
358
        tonext_i=>stoscon_i(i)(input_width +  (i*add_g) + (((i-1)/2)*mult_g)+mult_g-1 downto 0)
359
                );
360
 
361
    first_rom: if (i/2)=1 generate
362
    rom_1 : component rom1
363
 
364
    generic map (
365
                data_width=>twiddle_width,
366
                address_width=>(num_stages-i+1)+1
367
                )
368
      port map (
369
                clk=>clock,
370
                address=>counter_registers(i-1)((num_stages-i+1) downto 0 ),
371
                datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2));
372
  end   generate first_rom;
373
 
374
       second_rom: if (i/2)=2 generate
375
    rom_2 : component rom2
376
     generic map (
377
                data_width=>twiddle_width,
378
                address_width=>(num_stages-i+1)+1
379
                )
380
    port map (
381
         clk=>clock,
382
                address=>counter_registers(i-1)((num_stages-i+1  ) downto 0),
383
                datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
384
                );
385
  end generate second_rom;
386
 
387
    third_rom: if (i/2)=3 generate
388
   rom_3 : component rom3
389
    generic map (
390
 
391
                data_width  =>twiddle_width,
392
                address_width=>(num_stages-i+1)+1
393
                )
394
    port map (
395
         clk=>clock,
396
                address=>counter_registers(i-1)((num_stages-i+1) downto 0),
397
                datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
398
                );
399
    end generate third_rom;
400
 
401
    fourth_rom: if (i/2)=4 generate
402
    rom_4 : component rom4
403
     generic map (
404
                data_width=>twiddle_width,
405
                address_width=>(num_stages-i+1)+1
406
                )
407
    port map (
408
         clk=>clock,
409
                address=>counter_registers(i-1)((num_stages-i+1) downto 0),
410
                datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
411
                );
412
  end generate fourth_rom;
413
 
414
  end generate even_stages;
415
 
416
 
417
 
418
  odd_stages: if (((i rem 2)=1) and (i/=num_stages)) and (i/=1)
419
  generate
420
    inner_stage_I : component stage_I
421
         generic map (
422
                data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g),
423
                add_g=>add_g,
424
                shift_stages=>2**(num_stages - i)
425
                )
426
   port map (
427
                prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
428
                prvs_i=>stoscon_i(i-1)(input_width + (i*add_g)  + (((i-1)/2)*mult_g)-1-add_g downto 0),
429
                s=>counter_registers(i)( (num_stages-i)),
430
                enable=>enables(i)(0),
431
                clock=>clock,
432
                resetn=>resetn,
433
                tonext_r=>stoscon_r(i)(input_width+ (i*add_g) + ( ((i -1)/2)*mult_g)-1 downto 0),
434
                tonext_i=>stoscon_i(i)(input_width +  (i*add_g) + ( ((i- 1)/2)*mult_g)-1 downto 0)
435
                );
436
  end generate odd_stages;
437
 
438
  end_on_even: if (i=num_stages) and ((i rem 2)=0) generate
439
    last_stage_II : component stage_II_last
440
      generic map (
441
                data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g),
442
                add_g=>add_g
443
                )
444
   port map (
445
                prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
446
                prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
447
                t=>counter_registers(i)((num_stages-i+1)),
448
                s=>counter_registers(i)((num_stages-i)),clock=>clock ,
449
                resetn=>resetn,
450
                enable=>enables(i)(0),
451
                tonext_r=>Xout_r,
452
                tonext_i=>Xout_i
453
                );
454
  end generate end_on_even;
455
 
456
  end_on_odd: if (i=num_stages) and ((i rem 2)=1) generate
457
    last_stage_I : component stage_I_last
458
      generic map (
459
                data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g), add_g=>add_g
460
                )
461
   port map (
462
                prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
463
                prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0),
464
                s=>counter_registers(i)( (num_stages-i)),
465
                clock=>clock,
466
                enable=>enables(i)(0),
467
                resetn=>resetn,
468
                tonext_r=>Xout_r,
469
                tonext_i=>Xout_i
470
                );
471
 
472
 
473
  end generate end_on_odd;
474
 
475
end generate stages;
476
 
477
--Frequency bin with bit reversal
478
bit_reverse_index<=std_logic_vector(unsigned(counter_registers(num_stages+1))+1);
479
 
480
bit_reverse: for i in 0 to num_stages-1 generate
481
                        index(i)<=bit_reverse_index(num_stages-1-i);
482
 
483
end generate;
484
 
485
 
486
--T flip-flop for enable_out generation control
487
 
488
tff: shiftreg1 generic  map(
489
                data_width=>1
490
)
491
  port map (
492
                clock=>clock,
493
                enable=>((en_t_ff(0) or clear_t_Ff) and enables(num_stages)(0))  or clear,
494
                clear => clear or clear_t_ff,
495
        read_data=>t_ff,
496
        write_data=>en_t_ff,
497
                resetn=>resetn
498
                );
499
 
500
 
501
 
502
en_t_ff(0)<= '1' when (unsigned(counter_registers(num_stages+1))=(N-1)) else '0';
503
clear_t_ff <= '1' when (unsigned(counter_registers(num_stages+1))=(N-1) and t_ff(0)='1') else '0';
504
 
505
--Enable out includes pipeline latency 
506
enable_out<=enables(num_stages+1)(0) when (t_ff="1")  else '0' ;
507
 
508
 
509
--Frame ready, falling edge detector
510
 
511
process(resetn,clock)
512
      variable detect : std_ulogic_vector (1 downto 0);
513
   begin
514
      if resetn ='0' then
515
         detect := "00";
516
 
517
      elsif rising_edge(clock) then
518
 
519
                if (clear ='1') then
520
 
521
                frame_ready<='0';
522
 
523
                else
524
 
525
         detect(1) := detect(0); -- record last value of sync in detect(1)
526
         detect(0) := t_ff(0) ; --record current sync in detect(0)
527
 
528
         if detect = "01" then -- rising_edge
529
 
530
                        frame_ready<='0';
531
 
532
         elsif detect = "10" then --falling_edge
533
 
534
frame_ready<='1';
535
 
536
 
537
         end if;
538
 
539
                        end if;
540
 
541
      end if;
542
end process;
543
 
544
 
545
 
546
 
547
end;

powered by: WebSVN 2.1.0

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