Verilog 实现256点 基2FFT算法(频率抽取)

这是一个Verilog代码实现256点基2频率抽取FFT算法的详细解析,包括代码功能说明、代码框架及部分关键模块的展示。通过此代码,可以实现对256点复数序列的快速傅里叶变换,并且输出顺序经过调整的计算结果。
摘要由CSDN通过智能技术生成

空手套白狼的我谢谢您!免开尊口。不必说什么请教,更不要口吐莲花!
代码功能
        代码实现256点FFT蝶形算法,基2频率抽取算法。如需改为时间抽取,只需在输入端增加一级缓存,对时间序列调整顺序;同时,取消输出端的排序。

        本代码不依托于硬件平台,可只使用modelsim进行仿真,无需使用Vivado或Quartus II。

代码框架
        256点FFT示意图过于复杂,此处以8点FFT 基2频率抽取分解示意图为例进行说明。

         如图,N=8时,分为log2(8) = 3级。则当N=512时,分为log2(256)=8级。

        由于采用频率抽取,则时域信号可顺序输入,无需对时域256个数据全部缓存。

   

        同时,FFT直接计算结果为X(0)、X(128)、X(1)、X(129)……,为调整为顺序输出,则需要对计算结果进行一次缓存。然后顺序输出FFT计算结果。

        顶层代码如下:

module FFT256(
input                     clk,
input                     rst_n,
input                     in_valid,
input signed       [11:0] din_r,
input signed       [11:0] din_i,
output                    out_valid,
output reg signed  [15:0] dout_r,
output reg signed  [15:0] dout_i
);

integer i;
reg signed  [15:0] result_r[0:255];
reg signed  [15:0] result_i[0:255];
reg signed  [15:0] result_r_ns[0:255];
reg signed  [15:0] result_i_ns[0:255];
reg signed  [15:0] next_dout_r;
reg signed  [15:0] next_dout_i;
reg         [8:0]   count_y;
reg         [8:0]   next_count_y;

reg signed  [23:0] din_r_reg,din_i_reg;
reg                in_valid_reg,r7_valid,next_r7_valid;
reg         [1:0]  no8_state;
reg                s8_count,next_s8_count;
reg                next_over,over;
reg                assign_out;
reg                next_out_valid;
reg         [7:0]  y_1_delay;

wire        [23:0] out_r,out_i;
wire        [7:0]  y_1;
wire        [23:0] din_r_wire,din_i_wire;

assign out_valid     = assign_out;
assign y_1             = (count_y>8'd0)? (count_y - 8'd1) : count_y; 
assign din_r_wire    = din_r_reg;
assign din_i_wire   = din_i_reg;
/
wire [1:0]  rom128_state;
wire [23:0] rom128_w_r,rom128_w_i;
wire [23:0] shift_128_dout_r,shift_128_dout_i;
wire [23:0] radix_no1_delay_r,radix_no1_delay_i;
wire [23:0] radix_no1_op_r,radix_no1_op_i;
wire radix_no1_outvalid;

wire [1:0]  rom64_state;
wire [23:0] rom64_w_r,rom64_w_i;
wire [23:0] shift_64_dout_r,shift_64_dout_i;
wire [23:0] radix_no2_delay_r,radix_no2_delay_i;
wire [23:0] radix_no2_op_r,radix_no2_op_i;
wire radix_no2_outvalid;

wire [1:0] rom32_state;
wire [23:0]rom32_w_r,rom32_w_i;
wire [23:0]shift_32_dout_r,shift_32_dout_i;
wire [23:0]radix_no3_delay_r,radix_no3_delay_i;
wire [23:0]radix_no3_op_r,radix_no3_op_i;
wire radix_no3_outvalid;

wire [1:0] rom16_state;
wire [23:0]rom16_w_r,rom16_w_i;
wire [23:0]shift_16_dout_r,shift_16_dout_i;
wire [23:0]radix_no4_delay_r,radix_no4_delay_i;
wire [23:0]radix_no4_op_r,radix_no4_op_i;
wire radix_no4_outvalid;

wire [1:0] rom8_state;
wire [23:0]rom8_w_r,rom8_w_i;
wire [23:0]shift_8_dout_r,shift_8_dout_i;
wire [23:0]radix_no5_delay_r,radix_no5_delay_i;
wire [23:0]radix_no5_op_r,radix_no5_op_i;
wire radix_no5_outvalid;

wire [1:0] rom4_state;
wire [23:0]rom4_w_r,rom4_w_i;
wire [23:0]shift_4_dout_r,shift_4_dout_i;
wire [23:0]radix_no6_delay_r,radix_no6_delay_i;
wire [23:0]radix_no6_op_r,radix_no6_op_i;
wire radix_no6_outvalid;

wire [1:0] rom2_state;
wire [23:0]rom2_w_r,rom2_w_i;
wire [23:0]shift_2_dout_r,shift_2_dout_i;
wire [23:0]radix_no7_delay_r,radix_no7_delay_i;
wire [23:0]radix_no7_op_r,radix_no7_op_i;
wire radix_no7_outvalid;

wire [23:0]shift_1_dout_r,shift_1_dout_i;
wire [23:0]radix_no8_delay_r,radix_no8_delay_i;
wire [23:0]radix_no8_op_r,radix_no8_op_i;

Step 1///
radix2 radix_no1(
.state(rom128_state),//state ctrl
.din_a_r(shift_128_dout_r),//fb
.din_a_i(shift_128_dout_i),//fb
.din_b_r(din_r_wire),//input
.din_b_i(din_i_wire),//input
.w_r(rom128_w_r),//twindle_r
.w_i(rom128_w_i),//twindle_i
.op_r(radix_no1_op_r),
.op_i(radix_no1_op_i),
.delay_r(radix_no1_delay_r),
.delay_i(radix_no1_delay_i),
.outvalid(radix_no1_outvalid)
);
shift_128 shift_128(
.clk(clk),.rst_n(rst_n),
.in_valid(in_valid_reg),
.din_r(radix_no1_delay_r),
.din_i(radix_no1_delay_i),
.dout_r(shift_128_dout_r),
.dout_i(shift_128_dout_i)
);
ROM_128 rom128(
.clk(clk),
.in_valid(in_valid_reg),
.rst_n(rst_n),
.w_r(rom128_w_r),
.w_i(rom128_w_i),
.state(rom128_state)
);
Step 2///
radix2 radix_no2(
.state(rom64_state),//state ctrl
.din_a_r(shift_64_dout_r),//fb
.din_a_i(shift_64_dout_i),//fb
.din_b_r(radix_no1_op_r),//input
.din_b_i(radix_no1_op_i),//input
.w_r(rom64_w_r),//twindle
.w_i(rom64_w_i),//d
.op_r(radix_no2_op_r),
.op_i(radix_no2_op_i),
.delay_r(radix_no2_delay_r),
.delay_i(radix_no2_delay_i),
.outvalid(radix_no2_outvalid)
);
shift_64 shift_64(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no1_outvalid),
.din_r(radix_no2_delay_r),
.din_i(radix_no2_delay_i),
.dout_r(shift_64_dout_r),
.dout_i(shift_64_dout_i)
);
ROM_64 rom64(
.clk(clk),
.in_valid(radix_no1_outvalid),
.rst_n(rst_n),
.w_r(rom64_w_r),
.w_i(rom64_w_i),
.state(rom64_state)
);
Step 3///
radix2 radix_no3(
.state(rom32_state),//state ctrl
.din_a_r(shift_32_dout_r),//fb
.din_a_i(shift_32_dout_i),//fb
.din_b_r(radix_no2_op_r),//input
.din_b_i(radix_no2_op_i),//input
.w_r(rom32_w_r),//twindle
.w_i(rom32_w_i),//d
.op_r(radix_no3_op_r),
.op_i(radix_no3_op_i),
.delay_r(radix_no3_delay_r),
.delay_i(radix_no3_delay_i),
.outvalid(radix_no3_outvalid)
);
shift_32 shift_32(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no2_outvalid),
.din_r(radix_no3_delay_r),
.din_i(radix_no3_delay_i),
.dout_r(shift_32_dout_r),
.dout_i(shift_32_dout_i)  
);
ROM_32 rom32(
.clk(clk),
.in_valid(radix_no2_outvalid),
.rst_n(rst_n),
.w_r(rom32_w_r),
.w_i(rom32_w_i),
.state(rom32_state)
);
Step 4///
radix2 radix_no4(
.state(rom16_state),//state ctrl
.din_a_r(shift_16_dout_r),//fb
.din_a_i(shift_16_dout_i),//fb
.din_b_r(radix_no3_op_r),//input
.din_b_i(radix_no3_op_i),//input
.w_r(rom16_w_r),//twindle
.w_i(rom16_w_i),//d
.op_r(radix_no4_op_r),
.op_i(radix_no4_op_i),
.delay_r(radix_no4_delay_r),
.delay_i(radix_no4_delay_i),
.outvalid(radix_no4_outvalid)
);
shift_16 shift_16(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no3_outvalid),
.din_r(radix_no4_delay_r),
.din_i(radix_no4_delay_i),
.dout_r(shift_16_dout_r),
.dout_i(shift_16_dout_i)
);
ROM_16 rom16(
.clk(clk),
.in_valid(radix_no3_outvalid),
.rst_n(rst_n),
.w_r(rom16_w_r),
.w_i(rom16_w_i),
.state(rom16_state)
);
Step 5///
radix2 radix_no5(
.state(rom8_state),//state ctrl
.din_a_r(shift_8_dout_r),//fb
.din_a_i(shift_8_dout_i),//fb
.din_b_r(radix_no4_op_r),//input
.din_b_i(radix_no4_op_i),//input
.w_r(rom8_w_r),//twindle
.w_i(rom8_w_i),//d
.op_r(radix_no5_op_r),
.op_i(radix_no5_op_i),
.delay_r(radix_no5_delay_r),
.delay_i(radix_no5_delay_i),
.outvalid(radix_no5_outvalid)
);
shift_8 shift_8(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no4_outvalid),
.din_r(radix_no5_delay_r),
.din_i(radix_no5_delay_i),
.dout_r(shift_8_dout_r),
.dout_i(shift_8_dout_i)
);
ROM_8 rom8(
.clk(clk),
.in_valid(radix_no4_outvalid),
.rst_n(rst_n),
.w_r(rom8_w_r),
.w_i(rom8_w_i),
.state(rom8_state)
);
Step 6///
radix2 radix_no6(
.state(rom4_state),//state ctrl
.din_a_r(shift_4_dout_r),//fb
.din_a_i(shift_4_dout_i),//fb
.din_b_r(radix_no5_op_r),//input
.din_b_i(radix_no5_op_i),//input
.w_r(rom4_w_r),//twindle
.w_i(rom4_w_i),//d
.op_r(radix_no6_op_r),
.op_i(radix_no6_op_i),
.delay_r(radix_no6_delay_r),
.delay_i(radix_no6_delay_i),
.outvalid(radix_no6_outvalid)
);
shift_4 shift_4(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no5_outvalid),
.din_r(radix_no6_delay_r),
.din_i(radix_no6_delay_i),
.dout_r(shift_4_dout_r),
.dout_i(shift_4_dout_i)
);
ROM_4 rom4(
.clk(clk),
.in_valid(radix_no5_outvalid),
.rst_n(rst_n),
.w_r(rom4_w_r),
.w_i(rom4_w_i),
.state(rom4_state)
);
Step 7///
radix2 radix_no7(
.state(rom2_state),//state ctrl
.din_a_r(shift_2_dout_r),//fb
.din_a_i(shift_2_dout_i),//fb
.din_b_r(radix_no6_op_r),//input
.din_b_i(radix_no6_op_i),//input
.w_r(rom2_w_r),//twindle
.w_i(rom2_w_i),//d
.op_r(radix_no7_op_r),
.op_i(radix_no7_op_i),
.delay_r(radix_no7_delay_r),
.delay_i(radix_no7_delay_i),
.outvalid(radix_no7_outvalid)
);
shift_2 shift_2(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no6_outvalid),
.din_r(radix_no7_delay_r),
.din_i(radix_no7_delay_i),
.dout_r(shift_2_dout_r),
.dout_i(shift_2_dout_i)
);
ROM_2 rom2(
.clk(clk),
.in_valid(radix_no6_outvalid),
.rst_n(rst_n),
.w_r(rom2_w_r),
.w_i(rom2_w_i),
.state(rom2_state)
);
Step 8///
radix2 radix_no8(
.state(no8_state),//state ctrl
.din_a_r(shift_1_dout_r),//fb
.din_a_i(shift_1_dout_i),//fb
.din_b_r(radix_no7_op_r),//input
.din_b_i(radix_no7_op_i),//input
.w_r(24'd256),//twindle
.w_i(24'd0),//d
.op_r(out_r),
.op_i(out_i),
.delay_r(radix_no8_delay_r),
.delay_i(radix_no8_delay_i),
.outvalid()
);
shift_1 shift_1(
.clk(clk),.rst_n(rst_n),
.in_valid(radix_no7_outvalid),
.din_r(radix_no8_delay_r),
.din_i(radix_no8_delay_i),
.dout_r(shift_1_dout_r),
.dout_i(shift_1_dout_i)
);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值