明德扬就业班现正火热招生中,课程主要传授至简设计法,100天的课程足以满足岗位需要,包就业推荐,详情点击咨询...

DIT-FFT至简设计实现法

发布时间:2017-07-13

设计目的: 本项目展示如何用至简设计法实现复杂的DIT-FFT蝶形运算,无论是该项目的模块划分、读写处理操作还是计数器设计,都始终基于“至简设计”的原则,我们只用简易的代码结构就能清晰实现复杂的运算功能。

只要掌握“至简设计法“,就能轻松应对任何复杂的项目,在我们这里,只有复杂的项目,但是没有复杂的代码实现方法,“至简设计法”具有通用性,任何复杂的功能模块都可以分解为类似于如下实现DIT-FFT运算过程的简易代码实现步骤。

1、 蝶形运算至简实现过程

至简设计法案例

1按时间抽取的基2-FFT算法蝶形运算流图(N=8)


1、1 模块划分

至简设计法案例

2 蝶形运算模块框图


1、1、1 奇数轮蝶形运算

至简设计法案例

3 第奇数轮蝶形运算流图


1、1、2 偶数轮蝶形运算

至简设计法案例

4   第偶数轮蝶形运算流图


2、至简设计代码实现(附录部分代码)

  1
  2
  3 parameter  N   = 512;//定义参数,N=512,表示512点的FFT
  4 parameter LOGN = 9;// LONG表示轮数,512点需要9轮的FFT蝶形运算
  5
  6 /*********www.mdy-edu.com 明德扬科教 注释开始****************
  7
  8 设计三个计数器作为本模块功能的基本架构,其它信号与基本架构对齐
  9
 10 **********www.mdy-edu.com 明德扬科教 注释结束****************/
 11
 12 //读RAM计数器设计
 13
 14 always @(posedge clk or negedge rst_n)begin
 15     if(!rst_n)begin
 16         cnt0 <= 0;
 17     end
 18     else if(add_cnt0)begin
 19         if(end_cnt0)
 20             cnt0 <= 0;
 21         else
 22             cnt0 <= cnt0 + 1;
 23     end
 24 end
 25
 26 assign add_cnt0 = flag;
 27 assign end_cnt0 = add_cnt0 && cnt0== (1<<cnt2)-1 ;
 28
 29 always @(posedge clk or negedge rst_n)begin 
 30     if(!rst_n)begin
 31         cnt1 <= 0;
 32     end
 33     else if(add_cnt1)begin
 34         if(end_cnt1)
 35             cnt1 <= 0;
 36         else
 37             cnt1 <= cnt1 + 1;
 38     end
 39 end
 40
 41 assign add_cnt1 = end_cnt0;
 42 assign end_cnt1 = add_cnt1 && cnt1==(N>>(cnt2+1))-1 ;
 43
 44 always @(posedge clk or negedge rst_n)begin
 45     if(!rst_n)begin
 46         cnt2 <= 0;
 47     end
 48     else if(add_cnt2)begin
 49         if(end_cnt2)
 50             cnt2 <= 0;
 51         else
 52             cnt2 <= cnt2 + 1;
 53     end
 54 end
 55
 56 assign add_cnt2 = end_cnt1;
 57 assign end_cnt2 = add_cnt2 && cnt2==LOGN-1 ;
 58
 59
 60 //写RAM计数器设计
 61
 62 always @(posedge clk or negedge rst_n)begin
 63     if(!rst_n)begin
 64         wr_cnt0 <= 0;
 65     end
 66     else if(add_wr_cnt0)begin
 67         if(end_wr_cnt0)
 68             wr_cnt0 <= 0;
 69         else
 70             wr_cnt0 <= wr_cnt0 + 1;
 71     end
 72 end
 73
 74 assign add_wr_cnt0 = fft_dout_vld;
 75 assign end_wr_cnt0 = add_wr_cnt0 && wr_cnt0==(1<<wr_cnt2)-1 ;
 76
 77 always @(posedge clk or negedge rst_n)begin 
 78     if(!rst_n)begin
 79         wr_cnt1 <= 0;
 80     end
 81     else if(add_wr_cnt1)begin
 82         if(end_wr_cnt1)
 83             wr_cnt1 <= 0;
 84         else
 85             wr_cnt1 <= wr_cnt1 + 1;
 86     end
 87 end
 88
 89 assign add_wr_cnt1 = end_wr_cnt0;
 90 assign end_wr_cnt1 = add_wr_cnt1 && wr_cnt1==(N>>(wr_cnt2+1))-1 ;
 91
 92 always @(posedge clk or negedge rst_n)begin
 93     if(!rst_n)begin
 94         wr_cnt2 <= 0;
 95     end
 96     else if(add_wr_cnt2)begin
 97         if(end_wr_cnt2)
 98             wr_cnt2 <= 0;
 99         else
100             wr_cnt2 <= wr_cnt2 + 1;
101     end
102 end
103
104 assign add_wr_cnt2 = end_wr_cnt1;
105 assign end_wr_cnt2 = add_wr_cnt2 && wr_cnt2==LOGN-1 ;
106  
107 //读地址设计
108 assign rd_addr0 = cnt0 + 2*cnt1*(1<<cnt2);
109 assign rd_addr1 = rd_addr0 + (1<<cnt2);
110
111 //写地址设计
112 assign wr_addr0 =  wr_cnt0 + 2*wr_cnt1*(1<<wr_cnt2);
113 assign wr_addr1 = wr_addr0 + (1<<wr_cnt2);
114
115 //RAM1与RAM2读写交替设计
116 assign fir_rd   = wr_cnt2[0]==0;    
117 assign fir_wr   = wr_cnt2[0]==1;
118 assign sen_rd   = wr_cnt2[0]==1;
119 assign sen_wr   = wr_cnt2[0]==0;
120
121 //addr_0
122 always  @(posedge clk or negedge rst_n)begin
123     if(rst_n==1'b0)begin
124         addr_0 <= 0;
125     end
126     else if(fir_rd) begin
127         addr_0 <= rd_addr0;
128     end
129     else begin
130         addr_0 <= wr_addr0;
131     end
132 end
133
134 //wdata_0
135 always  @(posedge clk or negedge rst_n)begin
136     if(rst_n==1'b0)begin
137         wdata_0 <= 0;
138     end
139     else begin
140         wdata_0 <= fft_dout0;
141     end
142 end
143
144 //wrreq_0
145 always  @(posedge clk or negedge rst_n)begin
146     if(rst_n==1'b0)begin
147         wrreq_0 <= 0;
148     end
149     else if(fir_wr) begin
150         wrreq_0 <= fft_dout_vld;
151     end
152     else begin
153         wrreq_0 <= 0;
154     end
155 end
156
157
158 //addr_1
159 always  @(posedge clk or negedge rst_n)begin
160     if(rst_n==1'b0)begin
161         addr_1 <= 0;
162     end
163     else if(fir_rd) begin
164         addr_1 <= rd_addr1;
165     end
166     else begin
167         addr_1 <= wr_addr1;
168     end
169 end
170
171 //wdata_1
172 always  @(posedge clk or negedge rst_n)begin
173     if(rst_n==1'b0)begin
174         wdata_1 <= 0;
175     end
176     else begin
177         wdata_1 <= fft_dout1;
178     end
179 end
180
181 //wrreq_1
182 always  @(posedge clk or negedge rst_n)begin
183     if(rst_n==1'b0)begin
184         wrreq_1 <= 0;
185     end
186     else if(fir_wr)begin
187         wrreq_1 <= fft_dout_vld;
188     end
189     else begin
190         wrreq_1 <=  0;
191     end
192 end
193
194 //fft_din0
195 always  @(posedge clk or negedge rst_n)begin
196     if(rst_n==1'b0)begin
197         fft_din0 <= 0;
198     end
199     else if(fir_rd) begin
200         fft_din0 <= q0;
201     end
202     else begin
203         fft_din0 <= q2;
204     end
205 end
206
207 //fft_din1  
208 always  @(posedge clk or negedge rst_n)begin
209     if(rst_n==1'b0)begin
210         fft_din1 <= 0;
211     end
212     else if(fir_rd) begin
213         fft_din1 <= q1;
214     end
215     else begin
216         fft_din1 <= q3;
217     end
218 end
219
220 always  @(posedge clk or negedge rst_n)begin
221     if(rst_n==1'b0)begin
222         flag <= 0;
223     end
224     else if(en || (end_wr_cnt1 && end_wr_cnt2==0)) begin
225         flag <= 1;
226     end
227     else if(end_cnt1)begin
228         flag <= 0;
229     end
230 end
231
232
233 //addr_2
234 always  @(posedge clk or negedge rst_n)begin
235     if(rst_n==1'b0)begin
236         addr_2 <= 0;
237     end
238     else if(sen_rd) begin
239         addr_2 <= rd_addr0;
240     end
241     else begin
242         addr_2 <= wr_addr0;
243     end
244 end
245
246 //wdata_2
247 always  @(posedge clk or negedge rst_n)begin
248     if(rst_n==1'b0)begin
249         wdata_2 <= 0;
250     end
251     else begin
252         wdata_2 <= fft_dout0;
253     end
254 end
255
256 //wrreq_2
257 always  @(posedge clk or negedge rst_n)begin
258     if(rst_n==1'b0)begin
259         wrreq_2 <= 0;
260     end
261     else if(sen_wr) begin
262         wrreq_2 <= fft_dout_vld;
263     end
264     else begin
265         wrreq_2 <= 0;
266     end
267 end
268
269 //addr_3
270 always  @(posedge clk or negedge rst_n)begin
271     if(rst_n==1'b0)begin
272         addr_3 <= 0;
273     end
274     else if(sen_rd) begin
275         addr_3 <= rd_addr1;
276     end
277     else begin
278         addr_3 <= wr_addr1;
279     end
280 end
281
282 //wdata_3
283 always  @(posedge clk or negedge rst_n)begin
284     if(rst_n==1'b0)begin
285         wdata_3 <= 0;
286     end
287     else begin
288         wdata_3 <= fft_dout1;
289     end
290 end
291
292 //wrreq_3
293 always  @(posedge clk or negedge rst_n)begin
294     if(rst_n==1'b0)begin
295         wrreq_3 <= 0;
296     end
297     else if(sen_wr)begin
298         wrreq_3 <= fft_dout_vld;
299     end
300     else begin
301         wrreq_3 <=  0;
302     end
303 end
304


技术交流QQ群:544453837

更多FPGA技术资讯:明德扬科教

点击了解>>至简设计法


免费申请试听课程

  •   
  •   
  •   
  •  
  • 提  交
  • FPGA教育领域第一品牌
  • 咨询热线:020-39002701
  • 技术老师:1411324938
  • 技术Q群:97925396