8点流水线型FFT的VerilogHDL实现.docx

上传人:b****3 文档编号:11560772 上传时间:2023-06-01 格式:DOCX 页数:47 大小:612.39KB
下载 相关 举报
8点流水线型FFT的VerilogHDL实现.docx_第1页
第1页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第2页
第2页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第3页
第3页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第4页
第4页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第5页
第5页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第6页
第6页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第7页
第7页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第8页
第8页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第9页
第9页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第10页
第10页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第11页
第11页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第12页
第12页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第13页
第13页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第14页
第14页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第15页
第15页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第16页
第16页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第17页
第17页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第18页
第18页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第19页
第19页 / 共47页
8点流水线型FFT的VerilogHDL实现.docx_第20页
第20页 / 共47页
亲,该文档总共47页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

8点流水线型FFT的VerilogHDL实现.docx

《8点流水线型FFT的VerilogHDL实现.docx》由会员分享,可在线阅读,更多相关《8点流水线型FFT的VerilogHDL实现.docx(47页珍藏版)》请在冰点文库上搜索。

8点流水线型FFT的VerilogHDL实现.docx

8点流水线型FFT的VerilogHDL实现

8点流水线型FFT的VerilogHDL实现

梁志明

华南理工大学

calaok@

(一)算法介绍

采用图中的结构,x0(0)~x0(7)为输入数据,位宽为16位;输出数据的位宽为32位,倒

序输出。

图38点FFT算法图

(二)系统设计

图4系统总框图

1、系统总框图如图4所示,总共包括一下几个模块:

1.。

对应三阶运算,共采用三个运算子模块:

第一阶运算模块:

对应蝶形算子只有W0(W0=1),

第二阶运算模块:

对应蝶形算子有W0、W2(W2=-j),

第三阶运算模块:

对应蝶形算子有W0、W1、W2、W3。

2.

针对各阶运算,:

第一阶控制模块;

第二阶控制模块;

第三阶控制模块。

2、各个运算模块分析。

1.第一阶运算模块:

控制模块的作用是

控制每个阶段的操

模块功能:

完成FFT第一阶蝶形运算。

模块设计:

此时蝶形算子只有W0,故蝶形运算结果为C=A+B,D=A-B。

因此,只需要对输入

数据做加减法即可。

考虑资源复用,这里定义一个16位的加法器和减法器,

2.第二阶运算模块

模块功能:

完成FFT第二阶蝶形运算。

模块设计:

第二阶运算有蝶形算子W0、W2。

对于W2蝶形运算结果为C=A+jB,D=A-jB,因

此,

对于W0算子,这里定义了一个17位有符号数加法器和减法器处理。

对于W2算子,对于运算结果的实部,可;针对虚部,对于结

果C,只需将B扩展成18位,对于结果D只用取B的补码,计算过程流程如下图。

相当于多路开关

图6第二阶运算模块

3.第三阶运算模块

这个部分是因为有

负数的出现

模块功能:

完成FFT第三阶蝶形运算。

模块设计:

第三阶运算模块:

对应蝶形算子有W0、W1、W2、W3。

采用设计要求中提示的通用

蝶形运算方法:

Rc=Ra+Rb*+(Ib-Rb)sin

Ic=Ia+Ib*+(Ib-Rb)sin

这个是蝶形运算的

通用公式

Rd=Ra-[Rb*cosaddsin+(Ib-Rb)sin]

Id=Ia-[Ib*cossubsin+(Ib-Rb)sin]

其中,

cosaddsin=cos(2πp/N)+sin(2πp/N)

cossubsin=cos(2πp/N)−sin(2πp/N)

sin=sin(2πp/N)

;这里,N=8。

根据上述公式,在进行一次蝶形运算时,只需首先确定cosaddsin,cossubsin,sin,然

后计算出(Ib-Rb)sin,Rb*cosaddsin,Ib*cossubsin,最后将结果相加减即可。

(三)仿真结果分析

1、数据输入

图7数据输入

(1)输入数据是两组连续8个的串行数据:

A=[12344321];

B=[-5-555-5-555];

数据在系统时钟的上升沿被采集。

2、最后蝶形算子运算波形

这里P的取值有0,1,2,3

图8最后蝶形算子运算波形

(1)蝶形算子运算公式为:

R=R+R⎢⎡⎣cos(2πp/N)+sin(2πp/N)⎥⎤⎦+(I-R)sin(2πp/N)

cabbb

I=I+I⎡⎣⎢cos(2πp/N)-sin(2πp/N)⎦⎥⎤(I)sin(2πp/N)

cab+b-R

b

R=R{R⎡⎣⎢cos(2πp/N)+sin(2πp/N)⎤⎦⎥+(I-R)sin(2πp/N)}

d-bbb

a

I=I{I⎡⎣⎢cos(2πp/N)-sin(2πp/N)⎤⎦⎥(I)sin(2πp/N)}

d-b+b-R

a

b

输入信号对应:

Imul_Ra->Ra

Imul_Ia->Ia

Imul_Rb->Rb

Imul_Ib->Ib

输入a和b,输出是c

和d

Imulc_Rout->Rc

Imulc_Iout->Ic

Imuld_Rout->Rd

Imuld_Iout->Id

波形上的输入信号为实际大小的有符号数,由于在

3、输出信号波形

图9输出信号波形

输出结果最后经过了排序,。

出数据为经过位数扩展后的数据,

(1)当输入数据为A=[12344321]时,MATLAB运算的数据为:

20.0000

-5.8284-2.4142i

0

-0.1716-0.4142i

0

-0.1716+0.4142i

0

-5.8284+2.4142i

硬件运算的结果为:

10240

-2984-1236i

0

-88-212i

0

-88+212i

0

-2984+1236i

(2)当输入数据为B=[-5-555-5-555]时,MATLAB运算的数据为:

0

0

-20.0000+20.0000i

0

0

0

-20.0000-20.0000i

0

硬件运算结果为:

0

0

-10240+10240i

0

0

0

-10240-10240i

0

(四)源程序

(1)add16.v

moduleadd16(a,b,out);

input[15:

0]a,b;

output[16:

0]out;

reg[16:

0]out;

两个数相加,所以

要扩展一位数

wire[16:

0]a1={a[15],a[15:

0]};

wire[16:

0]b1={b[15],b[15:

0]};

always@(a1orb1)

begin

out=a1+b1;

end

这里的目的是什么

呢?

好像就是避免

溢出进位造成结果

不正确?

endmodule

(2)sub16.v

modulesub16(a,b,out);

input[15:

0]a,b;

output[16:

0]out;

reg[16:

0]out;

wire[16:

0]a1={a[15],a[15:

0]};

wire[16:

0]b1={b[15],b[15:

0]};

always@(a1orb1)

begin

out=a1-b1;

end

endmodule

(3)add17.v

moduleadd17(a,b,out);

input[16:

0]a,b;

output[17:

0]out;

reg[17:

0]out;

wire[17:

0]a1={a[16],a[16:

0]};

wire[17:

0]b1={b[16],b[16:

0]};

always@(a1orb1)

begin

out=a1+b1;

end

endmodule

(4)sub17.v

modulesub17(a,b,out);

input[16:

0]a,b;

output[17:

0]out;

reg[17:

0]out;

wire[17:

0]a1={a[16],a[16:

0]};

wire[17:

0]b1={b[16],b[16:

0]};

always@(a1orb1)

begin

out=a1-b1;

end

endmodule

(5)addw2_17.v

moduleaddw2_17(a,b,Rout,Iout);

input[16:

0]a,b;

output[17:

0]Rout,Iout;

reg[17:

0]Rout,Iout;

wire[17:

0]a1={a[16],a[16:

0]};

wire[17:

0]b1={b[16],b[16:

0]};

always@(a1orb1)

begin

Rout=a1;

Iout=18'b0-b1;

end

endmodule

(6)subw2_17.v

modulesubw2_17(a,b,Rout,Iout);

input[16:

0]a,b;

output[17:

0]Rout,Iout;

reg[17:

0]Rout,Iout;

wire[17:

0]a1={a[16],a[16:

0]};

wire[17:

0]b1={b[16],b[16:

0]};

always@(a1orb1)

begin

Rout=a1;

Iout=b1;

end

endmodule

(7)Imul.v

moduleImul(p,

Ra_in,Ia_in,

Rb_in,Ib_in,

Rc_out,Ic_out,

Rd_out,Id_out

);

input[1:

0]p;

好像是可以取值为

0,1,2,3

input[17:

0]Ra_in,Ia_in,Rb_in,Ib_in;

output[31:

0]Rc_out,Ic_out;

reg[31:

0]Rc_out,Ic_out;

output[31:

0]Rd_out,Id_out;

reg[31:

0]Rd_out,Id_out;

wire[18:

0]Rb_in1={Rb_in[17],Rb_in[17:

0]};

wire[18:

0]Ib_in1={Ib_in[17],Ib_in[17:

0]};

reg[10:

0]cosaddsin,cossubsin,sin;

always@(p)

begin

case(p)

难道这就是传说的

扩大了512倍

endcase

end

wire[18:

0]IR=Ib_in1-Rb_in1;

wire[29:

0]R_sin;

mult19_11mult19_11(

.dataa(IR),

.datab(sin),

.result(R_sin));

wire[28:

0]R_cosaddsin;

mult18_11mult18_11A(

.dataa(Rb_in),

.datab(cosaddsin),

.result(R_cosaddsin));

reg[30:

0]R_Ra;

always@(Ra_in)

begin

if(Ra_in[17]==1'b1)

begin

R_Ra={4'hf,~{~Ra_in[17:

0]+18'b1,9'b0}+27'b1};

end

else

begin

R_Ra={4'b0,Ra_in[17:

0],9'b0};

end

end

wire[30:

0]R_cosaddsin1={R_cosaddsin[28],R_cosaddsin[28],R_cosaddsin[28:

0]};

reg[30:

0]RRc;

always@(R_RaorR_cosaddsin1)

begin

RRc=R_Ra+R_cosaddsin1;

end

wire[31:

0]R_sin1={R_sin[29],R_sin[29],R_sin[29:

0]};

wire[31:

0]RRc1={RRc[30],RRc[30:

0]};

always@(R_sin1orRRc1)

begin

Rc_out=R_sin1+RRc1;

end

//***********************************************************

wire[28:

0]R_cossubsin;

mult18_11mult18_11B(

.dataa(Ib_in),

.datab(cossubsin),

.result(R_cossubsin));

reg[30:

0]R_Ia;

always@(Ia_in)

begin

if(Ia_in[17]==1'b1)

begin

R_Ia={4'hf,~{~Ia_in[17:

0]+18'b1,9'b0}+27'b1};

end

else

begin

R_Ia={4'b0,Ia_in[17:

0],9'b0};

end

end

wire[30:

0]R_cossubsin1={R_cossubsin[28],R_cossubsin[28],R_cossubsin[28:

0]};

reg[30:

0]RIc;

always@(R_IaorR_cossubsin1)

begin

RIc=R_Ia+R_cossubsin1;

end

wire[31:

0]RIc1={RIc[30],RIc[30:

0]};

always@(R_sin1orRIc1)

begin

Ic_out=R_sin1+RIc1;

end

//*****************************************************************************

*************

//*****************************************************************************

*************

reg[30:

0]RRd;

always@(R_RaorR_cosaddsin1)

begin

RRd=R_Ra-R_cosaddsin1;

end

wire[31:

0]RRd1={RRd[30],RRd[30:

0]};

always@(R_sin1orRRd1)

begin

Rd_out=RRd1-R_sin1;

end

//***********************************************************

reg[30:

0]RId;

always@(R_IaorR_cossubsin1)

begin

RId=R_Ia-R_cossubsin1;

end

wire[31:

0]RId1={RId[30],RId[30:

0]};

always@(R_sin1orRId1)

begin

Id_out=RId1-R_sin1;

end

endmodule

(8)FFT.v

moduleFFT(clk,

rst_n,

data_in,

data_in_ready,

data_out_R,

data_out_I,

data_out_ready

);

//************************************************************************

inputclk,rst_n;

input[15:

0]data_in;

inputdata_in_ready;

output[31:

0]data_out_R,data_out_I;

outputdata_out_ready;

reg[31:

0]data_out_R,data_out_I;

regworking;

regdata_out_ready_reg;

wireworking_flag=working||data_in_ready;

wiredata_out_ready=data_out_ready_reg;

//DatacollectProcess*****************************************************

reg[2:

0]collect_cnt;

always@(posedgeclkornegedgerst_n)

if(!

rst_n)

begin

collect_cnt<=3'd0;

end

elseif(working_flag==1'b0)

begin

collect_cnt<=3'd0;

end

else

begin

collect_cnt<=collect_cnt+3'b1;

end

reg[15:

0]x0_reg0;

reg[15:

0]x0_reg1;

reg[15:

0]x0_reg2;

reg[15:

0]x0_reg3;

reg[15:

0]x0_regn;

always@(posedgeclkornegedgerst_n)

if(!

rst_n)

begin

x0_reg0<=16'b0;

x0_reg1<=16'b0;

x0_reg2<=16'b0;

x0_reg3<=16'b0;

x0_regn<=16'b0;

end

elseif(working_flag==1'b1)

begin

case(collect_cnt)

3'd0:

x0_reg0<=data_in;

3'd1:

x0_reg1<=data_in;

3'd2:

x0_reg2<=data_in;

3'd3:

x0_reg3<=data_in;

default:

x0_regn<=data_in;

endcase

end

//*********************************************************************

//Level1

reg[16:

0]x1_reg0;

reg[16:

0]x1_reg1;

reg[16:

0]x1_reg2;

reg[16:

0]x1_reg3;

reg[16:

0]x1_reg4;

reg[16:

0]x1_reg5;

reg[16:

0]x1_reg6;

reg[16:

0]x1_reg7;

reg[15:

0]x0add_a,x0add_b;

wire[16:

0]x0add_out;

add16add16(.a(x0add_a),.b(x0add_b),.out(x0add_out));

reg[15:

0]x0sub_a,x0sub_b;

wire[16:

0]x0sub_out;

sub16sub16(.a(x0sub_a),.b(x0sub_b),.out(x0sub_out));

always@(collect_cntorx0_reg0orx0_reg1orx0_reg2orx0_reg3orx0_regn)

begin

case(collect_cnt)

3'd5:

begin

x0add_a<=x0_reg0;

x0add_b<=x0_regn;

x0sub_a<=x0_reg0;

x0sub_b<=x0_regn;

end

3'd6:

begin

x0add_a<=x0_reg1;

x0add_b<=x0_regn;

x0sub_a<=x0_reg1;

x0sub_b<=x0_regn;

end

3'd7:

begin

x0add_a<=x0_reg2;

x0add_b<=x0_regn;

x0sub_a<=x0_reg2;

x0sub_b<=x0_regn;

end

3'd0:

begin

x0add_a<=x0_reg3;

x0add_b<=x0_regn;

x0sub_a<=x0_reg3;

x0sub_b<=x0_regn;

end

default:

begin

x0add_a<=16'b0;

x0add_b<=16'b0;

x0sub_a<=16'b0;

x0sub_b<=16'b0;

x0add_a<=16'b0;

x0add_b<=16'b0;

x0sub_a<=16'b0;

x0sub_b<=16'b0;

end

endcase

end

always@(posedgeclkornegedgerst_n)

if(!

rst_n)

begin

x1_reg0<=17'b0;

x1_reg1<=17'b0;

x1_reg2<=17'b0;

x1_reg3<=17'b0;

x1_reg4<=17'b0;

x1_reg5<=17'b0;

x1_reg6<=17'b0;

x1_reg7<=17'b0;

end

else

begin

case(collect_cnt)

3'd5:

begin

x1_reg0<=x0add_out;

x1_reg4<=x0sub_out;

end

3'd6:

begin

x1_reg1<=x0add_out;

x1_reg5<=x0sub_out;

end

3'd7:

begin

x1_reg2<=x0add_out;

x1_reg6<=x0sub_out;

end

3'd0:

begin

x1_reg3<=x0add_out;

x1_reg7<=x0sub_out;

end

default:

;

endcase

end

//************************************************************************

//Level2

reg[17:

0]x2_reg0;

reg[17:

0]x2_reg1;

reg[17:

0]x2_reg2;

reg[17:

0]x2_reg3;

reg[17:

0]x2_reg4_R,x2_reg4_I;

reg[17:

0]x2_reg5_R,x2_reg5_I;

reg[17:

0]x2_reg6_R,x2_reg6_I;

reg[17:

0]x2_reg7_R,x2_reg7_I;

reg[16:

0]x1add_a,x1add_b;

wire[17:

0]x1add_out;

add17add17(.a(x1add_a),.b(x1add_b),.out(x1add_out));

reg[16:

0]x1sub_a,x1sub_b;

wire[17:

0]x1sub_out;

sub17sub17(.a(x1sub_a),.b(x1sub_b),.out(x1sub_out));

reg[16:

0]x1addw2_a,x1addw2_b;

wire[17:

0]x1addw2_Rout,x1addw2_Iout;

addw2_17

addw2_17(.a(x1addw2_a),.b(x1addw2_b),.Rout(x1addw2_Rout),.Iout(x1addw2_Iout));

reg[16:

0]x1subw2_a,x1subw2_b;

wire[17:

0]x1subw2_Rout,x1subw2_Iout;

subw2_17subw2_17(.a(x1subw2_a),.b(x1subw2_b),.Rout(x1subw2_Rout),.Iout(x1subw2_Iout));

always@(collect_cntorx1_reg0orx1_reg1orx1_reg2orx1_reg3orx1_reg4orx1_reg5or

x1_reg

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2