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

Subversion Repositories dblclockfft

[/] [dblclockfft/] [trunk/] [rtl/] [ifftmain.v] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    ifftmain.v
4
//
5
// Project:     A General Purpose Pipelined FFT Implementation
6
//
7
// Purpose:     This is the main module in the General Purpose FPGA FFT
8
//              implementation.  As such, all other modules are subordinate
9
//      to this one.  This module accomplish a fixed size Complex FFT on
10
//      2048 data points.
11
//      The FFT is fully pipelined, and accepts as inputs two complex two's
12
//      complement samples per clock.
13
//
14
// Parameters:
15
//      i_clk   The clock.  All operations are synchronous with this clock.
16
//      i_reset Synchronous reset, active high.  Setting this line will
17
//                      force the reset of all of the internals to this routine.
18
//                      Further, following a reset, the o_sync line will go
19
//                      high the same time the first output sample is valid.
20
//      i_ce    A clock enable line.  If this line is set, this module
21
//                      will accept two complex values as inputs, and produce
22
//                      two (possibly empty) complex values as outputs.
23
//      i_left  The first of two complex input samples.  This value is split
24
//                      into two two's complement numbers, 15 bits each, with
25
//                      the real portion in the high order bits, and the
26
//                      imaginary portion taking the bottom 15 bits.
27
//      i_right This is the same thing as i_left, only this is the second of
28
//                      two such samples.  Hence, i_left would contain input
29
//                      sample zero, i_right would contain sample one.  On the
30
//                      next clock i_left would contain input sample two,
31
//                      i_right number three and so forth.
32
//      o_left  The first of two output samples, of the same format as i_left,
33
//                      only having 21 bits for each of the real and imaginary
34
//                      components, leading to 42 bits total.
35
//      o_right The second of two output samples produced each clock.  This has
36
//                      the same format as o_left.
37
//      o_sync  A one bit output indicating the first valid sample produced by
38
//                      this FFT following a reset.  Ever after, this will
39
//                      indicate the first sample of an FFT frame.
40
//
41
// Arguments:   This file was computer generated using the following command
42
//              line:
43
//
44
//              % ./fftgen -i -d ../rtl -f 2048 -2 -p 0 -n 15 -a ../bench/cpp/ifftsize.h
45
//
46
// Creator:     Dan Gisselquist, Ph.D.
47
//              Gisselquist Technology, LLC
48
//
49
////////////////////////////////////////////////////////////////////////////////
50
//
51
// Copyright (C) 2015-2018, Gisselquist Technology, LLC
52
//
53
// This program is free software (firmware): you can redistribute it and/or
54
// modify it under the terms of  the GNU General Public License as published
55
// by the Free Software Foundation, either version 3 of the License, or (at
56
// your option) any later version.
57
//
58
// This program is distributed in the hope that it will be useful, but WITHOUT
59
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
60
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
61
// for more details.
62
//
63
// You should have received a copy of the GNU General Public License along
64
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
65
// target there if the PDF file isn't present.)  If not, see
66
// <http://www.gnu.org/licenses/> for a copy.
67
//
68
// License:     GPL, v3, as defined and found on www.gnu.org,
69
//              http://www.gnu.org/licenses/gpl.html
70
//
71
//
72
////////////////////////////////////////////////////////////////////////////////
73
//
74
//
75
`default_nettype        none
76
//
77
//
78
//
79
module ifftmain(i_clk, i_reset, i_ce,
80
                i_left, i_right,
81
                o_left, o_right, o_sync);
82
        parameter       IWIDTH=15, OWIDTH=21, LGWIDTH=11;
83
        //
84
        input                                   i_clk, i_reset, i_ce;
85
        //
86
        input           [(2*IWIDTH-1):0] i_left, i_right;
87
        output  reg     [(2*OWIDTH-1):0] o_left, o_right;
88
        output  reg                             o_sync;
89
 
90
 
91
        // Outputs of the FFT, ready for bit reversal.
92
        wire    [(2*OWIDTH-1):0] br_left, br_right;
93
 
94
 
95
        wire            w_s2048;
96
        // verilator lint_off UNUSED
97
        wire            w_os2048;
98
        // verilator lint_on  UNUSED
99
        wire    [31:0]   w_e2048, w_o2048;
100
        fftstage        #(IWIDTH,IWIDTH+4,16,11,9,0,
101
                        0, 1, "icmem_e4096.hex")
102
                stage_e2048(i_clk, i_reset, i_ce,
103
                        (!i_reset), i_left, w_e2048, w_s2048);
104
        fftstage        #(IWIDTH,IWIDTH+4,16,11,9,0,
105
                        0, 1, "icmem_o4096.hex")
106
                stage_o2048(i_clk, i_reset, i_ce,
107
                        (!i_reset), i_right, w_o2048, w_os2048);
108
 
109
 
110
        wire            w_s1024;
111
        // verilator lint_off UNUSED
112
        wire            w_os1024;
113
        // verilator lint_on  UNUSED
114
        wire    [33:0]   w_e1024, w_o1024;
115
        fftstage        #(16,20,17,11,8,0,
116
                        0, 1, "icmem_e2048.hex")
117
                stage_e1024(i_clk, i_reset, i_ce,
118
                        w_s2048, w_e2048, w_e1024, w_s1024);
119
        fftstage        #(16,20,17,11,8,0,
120
                        0, 1, "icmem_o2048.hex")
121
                stage_o1024(i_clk, i_reset, i_ce,
122
                        w_s2048, w_o2048, w_o1024, w_os1024);
123
 
124
        wire            w_s512;
125
        // verilator lint_off UNUSED
126
        wire            w_os512;
127
        // verilator lint_on  UNUSED
128
        wire    [33:0]   w_e512, w_o512;
129
        fftstage        #(17,21,17,11,7,0,
130
                        0, 1, "icmem_e1024.hex")
131
                stage_e512(i_clk, i_reset, i_ce,
132
                        w_s1024, w_e1024, w_e512, w_s512);
133
        fftstage        #(17,21,17,11,7,0,
134
                        0, 1, "icmem_o1024.hex")
135
                stage_o512(i_clk, i_reset, i_ce,
136
                        w_s1024, w_o1024, w_o512, w_os512);
137
 
138
        wire            w_s256;
139
        // verilator lint_off UNUSED
140
        wire            w_os256;
141
        // verilator lint_on  UNUSED
142
        wire    [35:0]   w_e256, w_o256;
143
        fftstage        #(17,21,18,11,6,0,
144
                        0, 1, "icmem_e512.hex")
145
                stage_e256(i_clk, i_reset, i_ce,
146
                        w_s512, w_e512, w_e256, w_s256);
147
        fftstage        #(17,21,18,11,6,0,
148
                        0, 1, "icmem_o512.hex")
149
                stage_o256(i_clk, i_reset, i_ce,
150
                        w_s512, w_o512, w_o256, w_os256);
151
 
152
        wire            w_s128;
153
        // verilator lint_off UNUSED
154
        wire            w_os128;
155
        // verilator lint_on  UNUSED
156
        wire    [35:0]   w_e128, w_o128;
157
        fftstage        #(18,22,18,11,5,0,
158
                        0, 1, "icmem_e256.hex")
159
                stage_e128(i_clk, i_reset, i_ce,
160
                        w_s256, w_e256, w_e128, w_s128);
161
        fftstage        #(18,22,18,11,5,0,
162
                        0, 1, "icmem_o256.hex")
163
                stage_o128(i_clk, i_reset, i_ce,
164
                        w_s256, w_o256, w_o128, w_os128);
165
 
166
        wire            w_s64;
167
        // verilator lint_off UNUSED
168
        wire            w_os64;
169
        // verilator lint_on  UNUSED
170
        wire    [37:0]   w_e64, w_o64;
171
        fftstage        #(18,22,19,11,4,0,
172
                        0, 1, "icmem_e128.hex")
173
                stage_e64(i_clk, i_reset, i_ce,
174
                        w_s128, w_e128, w_e64, w_s64);
175
        fftstage        #(18,22,19,11,4,0,
176
                        0, 1, "icmem_o128.hex")
177
                stage_o64(i_clk, i_reset, i_ce,
178
                        w_s128, w_o128, w_o64, w_os64);
179
 
180
        wire            w_s32;
181
        // verilator lint_off UNUSED
182
        wire            w_os32;
183
        // verilator lint_on  UNUSED
184
        wire    [37:0]   w_e32, w_o32;
185
        fftstage        #(19,23,19,11,3,0,
186
                        0, 1, "icmem_e64.hex")
187
                stage_e32(i_clk, i_reset, i_ce,
188
                        w_s64, w_e64, w_e32, w_s32);
189
        fftstage        #(19,23,19,11,3,0,
190
                        0, 1, "icmem_o64.hex")
191
                stage_o32(i_clk, i_reset, i_ce,
192
                        w_s64, w_o64, w_o32, w_os32);
193
 
194
        wire            w_s16;
195
        // verilator lint_off UNUSED
196
        wire            w_os16;
197
        // verilator lint_on  UNUSED
198
        wire    [39:0]   w_e16, w_o16;
199
        fftstage        #(19,23,20,11,2,0,
200
                        0, 1, "icmem_e32.hex")
201
                stage_e16(i_clk, i_reset, i_ce,
202
                        w_s32, w_e32, w_e16, w_s16);
203
        fftstage        #(19,23,20,11,2,0,
204
                        0, 1, "icmem_o32.hex")
205
                stage_o16(i_clk, i_reset, i_ce,
206
                        w_s32, w_o32, w_o16, w_os16);
207
 
208
        wire            w_s8;
209
        // verilator lint_off UNUSED
210
        wire            w_os8;
211
        // verilator lint_on  UNUSED
212
        wire    [39:0]   w_e8, w_o8;
213
        fftstage        #(20,24,20,11,1,0,
214
                        0, 1, "icmem_e16.hex")
215
                stage_e8(i_clk, i_reset, i_ce,
216
                        w_s16, w_e16, w_e8, w_s8);
217
        fftstage        #(20,24,20,11,1,0,
218
                        0, 1, "icmem_o16.hex")
219
                stage_o8(i_clk, i_reset, i_ce,
220
                        w_s16, w_o16, w_o8, w_os8);
221
 
222
        wire            w_s4;
223
        // verilator lint_off UNUSED
224
        wire            w_os4;
225
        // verilator lint_on  UNUSED
226
        wire    [41:0]   w_e4, w_o4;
227
        qtrstage        #(20,21,11,0,1,0) stage_e4(i_clk, i_reset, i_ce,
228
                                                w_s8, w_e8, w_e4, w_s4);
229
        qtrstage        #(20,21,11,1,1,0)        stage_o4(i_clk, i_reset, i_ce,
230
                                                w_s8, w_o8, w_o4, w_os4);
231
        wire            w_s2;
232
        wire    [41:0]   w_e2, w_o2;
233
        laststage       #(21,21,0)       stage_2(i_clk, i_reset, i_ce,
234
                                        w_s4, w_e4, w_o4, w_e2, w_o2, w_s2);
235
 
236
 
237
        // Prepare for a (potential) bit-reverse stage.
238
        assign  br_left  = w_e2;
239
        assign  br_right = w_o2;
240
 
241
        wire    br_start;
242
        reg     r_br_started;
243
        initial r_br_started = 1'b0;
244
        always @(posedge i_clk)
245
                if (i_reset)
246
                        r_br_started <= 1'b0;
247
                else if (i_ce)
248
                        r_br_started <= r_br_started || w_s2;
249
        assign  br_start = r_br_started || w_s2;
250
 
251
        // Now for the bit-reversal stage.
252
        wire    br_sync;
253
        wire    [(2*OWIDTH-1):0] br_o_left, br_o_right;
254
        bitreverse      #(11,21)
255
                revstage(i_clk, i_reset,
256
                        (i_ce & br_start), br_left, br_right,
257
                        br_o_left, br_o_right, br_sync);
258
 
259
 
260
        // Last clock: Register our outputs, we're done.
261
        initial o_sync  = 1'b0;
262
        always @(posedge i_clk)
263
                if (i_reset)
264
                        o_sync  <= 1'b0;
265
                else if (i_ce)
266
                        o_sync  <= br_sync;
267
 
268
        always @(posedge i_clk)
269
                if (i_ce)
270
                begin
271
                        o_left  <= br_o_left;
272
                        o_right <= br_o_right;
273
                end
274
 
275
 
276
endmodule

powered by: WebSVN 2.1.0

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