fft_8.v
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/07/16 11:15:56
// Design Name:
// Module Name: fft_8
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module fft_8(
// input ena
input clk,
input reset,
// input data
input din_ena,
input signed [9:0] din_re0,
input signed [9:0] din_im0,
input signed [9:0] din_re1,
input signed [9:0] din_im1,
input signed [9:0] din_re2,
input signed [9:0] din_im2,
input signed [9:0] din_re3,
input signed [9:0] din_im3,
input signed [9:0] din_re4,
input signed [9:0] din_im4,
input signed [9:0] din_re5,
input signed [9:0] din_im5,
input signed [9:0] din_re6,
input signed [9:0] din_im6,
input signed [9:0] din_re7,
input signed [9:0] din_im7,
// output data
output dout_ena,
output signed [12:0] dout_re0,
output signed [12:0] dout_im0,
output signed [12:0] dout_re1,
output signed [12:0] dout_im1,
output signed [12:0] dout_re2,
output signed [12:0] dout_im2,
output signed [12:0] dout_re3,
output signed [12:0] dout_im3,
output signed [12:0] dout_re4,
output signed [12:0] dout_im4,
output signed [12:0] dout_re5,
output signed [12:0] dout_im5,
output signed [12:0] dout_re6,
output signed [12:0] dout_im6,
output signed [12:0] dout_re7,
output signed [12:0] dout_im7
);
// FFT_1
reg fft1_ena;
reg signed [10:0] fft1_re0;
reg signed [10:0] fft1_im0;
reg signed [10:0] fft1_re1;
reg signed [10:0] fft1_im1;
reg signed [10:0] fft1_re2;
reg signed [10:0] fft1_im2;
reg signed [10:0] fft1_re3;
reg signed [10:0] fft1_im3;
reg signed [10:0] fft1_re4;
reg signed [10:0] fft1_im4;
reg signed [10:0] fft1_re5;
reg signed [10:0] fft1_im5;
reg signed [10:0] fft1_re6;
reg signed [10:0] fft1_im6;
reg signed [10:0] fft1_re7;
reg signed [10:0] fft1_im7;
always @ (posedge clk)
if(!reset)
// reset the device
begin
fft1_ena <=0;
fft1_re0 <=0;
fft1_im0 <=0;
fft1_re1 <=0;
fft1_im1 <=0;
fft1_re2 <=0;
fft1_im2 <=0;
fft1_re3 <=0;
fft1_im3 <=0;
fft1_re4 <=0;
fft1_im4 <=0;
fft1_re5 <=0;
fft1_im5 <=0;
fft1_re6 <=0;
fft1_im6 <=0;
fft1_re7 <=0;
fft1_im7 <=0;
end
else if(din_ena)
begin
fft1_ena <= 1;
fft1_re0 <= din_re0 + din_re4;
fft1_im0 <= din_im0 + din_im4;
fft1_re1 <= din_re0 - din_re4;
fft1_im1 <= din_im0 - din_im4;
fft1_re2 <= din_re2 + din_re6;
fft1_im2 <= din_im2 + din_im6;
fft1_re3 <= din_re2 - din_re6;
fft1_im3 <= din_im2 - din_im6;
fft1_re4 <= din_re1 + din_re5;
fft1_im4 <= din_im1 + din_im5;
fft1_re5 <= din_re1 - din_re5;
fft1_im5 <= din_im1 - din_im5;
fft1_re6 <= din_re3 + din_re7;
fft1_im6 <= din_im3 + din_im7;
fft1_re7 <= din_re3 - din_re7;
fft1_im7 <= din_im3 - din_im7;
end
else
fft1_ena <= 0;
//FFT_2
wire fft2_ena1_d0;
wire signed [9:0] fft2_f1im;
wire signed [10:0] fft2_im3_d0;
wire signed [2:0] fft2_b1lim;
wire signed [9:0] fft2_f1re;
wire signed [10:0] fft2_re3_d0;
wire signed [2:0] fft2_b1lre;
cmpy_0 commul22 (
.aclk(clk), // input wire aclk
.s_axis_a_tvalid(fft1_ena), // input wire s_axis_a_tvalid
.s_axis_a_tdata({4'd0,fft1_im3,1'd0,4'd0,fft1_re3,1'd0}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(1'b1), // input wire s_axis_b_tvalid
.s_axis_b_tdata({8'b11111111,8'b10000000,8'd0,8'b00000000}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(fft2_ena1_d0), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({fft2_f1im,fft2_im3_d0,fft2_b1lim,fft2_f1re,fft2_re3_d0,fft2_b1lre}) // output wire [47 : 0] m_axis_dout_tdata
);
wire fft2_ena2_d0;
wire signed [9:0] fft2_f2im;
wire signed [10:0] fft2_im7_d0;
wire signed [2:0] fft2_b2lim;
wire signed [9:0] fft2_f2re;
wire signed [10:0] fft2_re7_d0;
wire signed [2:0] fft2_b2lre;
cmpy_0 commul24 (
.aclk(clk), // input wire aclk
.s_axis_a_tvalid(fft1_ena), // input wire s_axis_a_tvalid
.s_axis_a_tdata({4'd0,fft1_im7,1'd0,4'd0,fft1_re7,1'd0}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(1'b1), // input wire s_axis_b_tvalid
.s_axis_b_tdata({8'b11111111,8'b10000000,8'd0,8'b00000000}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(fft2_ena2_d0), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({fft2_f2im,fft2_im7_d0,fft2_b2lim,fft2_f2re,fft2_re7_d0,fft2_b2lre}) // output wire [47 : 0] m_axis_dout_tdata
);
reg fft2_ena;
reg signed [11:0] fft2_re0;
reg signed [11:0] fft2_im0;
reg signed [11:0] fft2_re1;
reg signed [11:0] fft2_im1;
reg signed [11:0] fft2_re2;
reg signed [11:0] fft2_im2;
reg signed [11:0] fft2_re3;
reg signed [11:0] fft2_im3;
reg signed [11:0] fft2_re4;
reg signed [11:0] fft2_im4;
reg signed [11:0] fft2_re5;
reg signed [11:0] fft2_im5;
reg signed [11:0] fft2_re6;
reg signed [11:0] fft2_im6;
reg signed [11:0] fft2_re7;
reg signed [11:0] fft2_im7;
always @ (posedge clk)
if(!reset)
begin
fft2_ena <= 0;
fft2_re0 <= 0;
fft2_im0 <= 0;
fft2_re1 <= 0;
fft2_im1 <= 0;
fft2_re2 <= 0;
fft2_im2 <= 0;
fft2_re3 <= 0;
fft2_im3 <= 0;
fft2_re4 <= 0;
fft2_im4 <= 0;
fft2_re5 <= 0;
fft2_im5 <= 0;
fft2_re6 <= 0;
fft2_im6 <= 0;
fft2_re7 <= 0;
fft2_im7 <= 0;
end
else if(fft2_ena2_d0&&fft2_ena1_d0)
begin
fft2_ena <=1;
fft2_re0 <= fft1_re0 + fft1_re2;
fft2_im0 <= fft1_im0 + fft1_im2;
fft2_re2 <= fft1_re0 - fft1_re2;
fft2_im2 <= fft1_im0 - fft1_im2;
fft2_re1 <= fft1_re1 + fft2_re3_d0;
fft2_im1 <= fft1_im1 + fft2_im3_d0;
fft2_re3 <= fft1_re1 - fft2_re3_d0;
fft2_im3 <= fft1_im1 - fft2_im3_d0;
fft2_re4 <= fft1_re4 + fft1_re6;
fft2_im4 <= fft1_im4 + fft1_im6;
fft2_re6 <= fft1_re4 - fft1_re6;
fft2_im6 <= fft1_im4 - fft1_im6;
fft2_re5 <= fft1_re5 + fft2_re7_d0;
fft2_im5 <= fft1_im5 + fft2_im7_d0;
fft2_re7 <= fft1_re5 - fft2_re7_d0;
fft2_im7 <= fft1_im5 - fft2_im7_d0;
end
else
fft2_ena <= 0;
// FFT_3
wire fft3_ena1_d0;
wire signed [5:0] fft3_f1im;
wire signed [11:0] fft3_im5_d0;
wire signed [5:0] fft3_b1lim;
wire signed [5:0] fft3_f1re;
wire signed [11:0] fft3_re5_d0;
wire signed [5:0] fft3_b1lre;
cmpy_0 commul32 (
.aclk(clk), // input wire aclk
.s_axis_a_tvalid(fft2_ena), // input wire s_axis_a_tvalid
.s_axis_a_tdata({4'd0,fft2_im5,4'd0,fft2_re5}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(1'b1), // input wire s_axis_b_tvalid
.s_axis_b_tdata({4'd0,12'b101001011000,4'd0,12'b010110101000}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(fft3_ena1_d0), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({fft3_f1im,fft3_im5_d0,fft3_b1lim,fft3_f1re,fft3_re5_d0,fft3_b1lre}) // output wire [47 : 0] m_axis_dout_tdata
);
wire fft3_ena2_d0;
wire signed [5:0] fft3_f2im;
wire signed [11:0] fft3_im6_d0;
wire signed [5:0] fft3_b2lim;
wire signed [5:0] fft3_f2re;
wire signed [11:0] fft3_re6_d0;
wire signed [5:0] fft3_b2lre;
cmpy_0 commul33 (
.aclk(clk), // input wire aclk
.s_axis_a_tvalid(fft2_ena), // input wire s_axis_a_tvalid
.s_axis_a_tdata({4'd0,fft2_im6,4'd0,fft2_re6}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(1'b1), // input wire s_axis_b_tvalid
.s_axis_b_tdata({4'd0,12'b100000000000,4'd0,12'b000000000000}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(fft3_ena2_d0), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({fft3_f2im,fft3_im6_d0,fft3_b2lim,fft3_f2re,fft3_re6_d0,fft3_b2lre}) // output wire [47 : 0] m_axis_dout_tdata
);
wire fft3_ena3_d0;
wire signed [5:0] fft3_f3im;
wire signed [11:0] fft3_im7_d0;
wire signed [5:0] fft3_b3lim;
wire signed [5:0] fft3_f3re;
wire signed [11:0] fft3_re7_d0;
wire signed [5:0] fft3_b3lre;
cmpy_0 commul34 (
.aclk(clk), // input wire aclk
.s_axis_a_tvalid(fft2_ena), // input wire s_axis_a_tvalid
.s_axis_a_tdata({4'd0,fft2_im7,4'd0,fft2_re7}), // input wire [31 : 0] s_axis_a_tdata
.s_axis_b_tvalid(1'b1), // input wire s_axis_b_tvalid
.s_axis_b_tdata({4'd0,12'b101001011000,4'd0,12'b101001011000}), // input wire [31 : 0] s_axis_b_tdata
.m_axis_dout_tvalid(fft3_ena3_d0), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata({fft3_f3im,fft3_im7_d0,fft3_b3lim,fft3_f3re,fft3_re7_d0,fft3_b3lre}) // output wire [47 : 0] m_axis_dout_tdata
);
reg fft3_ena;
reg signed [12:0] fft3_re0;
reg signed [12:0] fft3_im0;
reg signed [12:0] fft3_re1;
reg signed [12:0] fft3_im1;
reg signed [12:0] fft3_re2;
reg signed [12:0] fft3_im2;
reg signed [12:0] fft3_re3;
reg signed [12:0] fft3_im3;
reg signed [12:0] fft3_re4;
reg signed [12:0] fft3_im4;
reg signed [12:0] fft3_re5;
reg signed [12:0] fft3_im5;
reg signed [12:0] fft3_re6;
reg signed [12:0] fft3_im6;
reg signed [12:0] fft3_re7;
reg signed [12:0] fft3_im7;
always @ (posedge clk)
if(!reset)
begin
fft3_ena <= 0;
fft3_re0 <= 0;
fft3_im0 <= 0;
fft3_re1 <= 0;
fft3_im1 <= 0;
fft3_re2 <= 0;
fft3_im2 <= 0;
fft3_re3 <= 0;
fft3_im3 <= 0;
fft3_re4 <= 0;
fft3_im4 <= 0;
fft3_re5 <= 0;
fft3_im5 <= 0;
fft3_re6 <= 0;
fft3_im6 <= 0;
fft3_re7 <= 0;
fft3_im7 <= 0;
end
else if(fft3_ena1_d0&&fft3_ena2_d0&&fft3_ena3_d0)
begin
fft3_ena <=1'b1;
fft3_re0 <= fft2_re0 + fft2_re4;
fft3_im0 <= fft2_im0 + fft2_im4;
fft3_re4 <= fft2_re0 - fft2_re4;
fft3_im4 <= fft2_im0 - fft2_im4;
fft3_re1 <= fft2_re1 + fft3_re5_d0;
fft3_im1 <= fft2_im1 + fft3_im5_d0;
fft3_re5 <= fft2_re1 - fft3_re5_d0;
fft3_im5 <= fft2_im1 - fft3_im5_d0;
fft3_re2 <= fft2_re2 + fft3_re6_d0;
fft3_im2 <= fft2_im2 + fft3_im6_d0;
fft3_re6 <= fft2_re2 - fft3_re6_d0;
fft3_im6 <= fft2_im2 - fft3_im6_d0;
fft3_re3 <= fft2_re3 + fft3_re7_d0;
fft3_im3 <= fft2_im3 + fft3_im7_d0;
fft3_re7 <= fft2_re3 - fft3_re7_d0;
fft3_im7 <= fft2_im3 - fft3_im7_d0;
end
else
fft3_ena <= 0;
assign dout_ena = fft3_ena;
assign dout_re0 = fft3_re0;
assign dout_im0 = fft3_im0;
assign dout_re1 = fft3_re1;
assign dout_im1 = fft3_im1;
assign dout_re2 = fft3_re2;
assign dout_im2 = fft3_im2;
assign dout_re3 = fft3_re3;
assign dout_im3 = fft3_im3;
assign dout_re4 = fft3_re4;
assign dout_im4 = fft3_im4;
assign dout_re5 = fft3_re5;
assign dout_im5 = fft3_im5;
assign dout_re6 = fft3_re6;
assign dout_im6 = fft3_im6;
assign dout_re7 = fft3_re7;
assign dout_im7 = fft3_im7;
endmodule
fft_8_tb.v
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/07/16 17:56:18
// Design Name:
// Module Name: fft_8_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module fft_8_tb(
);
reg aclk;
reg rst;
reg din_ena;
wire dout_ena;
reg [9:0] din_re0;
reg [9:0] din_im0;
reg [9:0] din_re1;
reg [9:0] din_im1;
reg [9:0] din_re2;
reg [9:0] din_im2;
reg [9:0] din_re3;
reg [9:0] din_im3;
reg [9:0] din_re4;
reg [9:0] din_im4;
reg [9:0] din_re5;
reg [9:0] din_im5;
reg [9:0] din_re6;
reg [9:0] din_im6;
reg [9:0] din_re7;
reg [9:0] din_im7;
wire [12:0] dout_re0;
wire [12:0] dout_im0;
wire [12:0] dout_re1;
wire [12:0] dout_im1;
wire [12:0] dout_re2;
wire [12:0] dout_im2;
wire [12:0] dout_re3;
wire [12:0] dout_im3;
wire [12:0] dout_re4;
wire [12:0] dout_im4;
wire [12:0] dout_re5;
wire [12:0] dout_im5;
wire [12:0] dout_re6;
wire [12:0] dout_im6;
wire [12:0] dout_re7;
wire [12:0] dout_im7;
initial
begin
#0 aclk = 0;
rst = 0;
#10
rst = 1;
din_ena = 1;
din_re0 = 10'b0000000000;
din_im0 = 10'b0000000000;
din_re1 = 10'b0000000000;
din_im1 = 10'b0000000000;
din_re2 = 10'b0010000000;
din_im2 = 10'b0000000000;
din_re3 = 10'b0000000000;
din_im3 = 10'b0000000000;
din_re4 = 10'b0100000000;
din_im4 = 10'b0000000000;
din_re5 = 10'b0000000000;
din_im5 = 10'b0000000000;
din_re6 = 10'b0000000000;
din_im6 = 10'b0000000000;
din_re7 = 10'b0000000000;
din_im7 = 10'b0000000000;
forever
#5 aclk =~aclk;
end
fft_8 fft81(
.clk(aclk),
.reset(rst),
.din_ena(din_ena),
.din_re0(din_re0),
.din_im0(din_im0),
.din_re1(din_re1),
.din_im1(din_im1),
.din_re2(din_re2),
.din_im2(din_im2),
.din_re3(din_re3),
.din_im3(din_im3),
.din_re4(din_re4),
.din_im4(din_im4),
.din_re5(din_re5),
.din_im5(din_im5),
.din_re6(din_re6),
.din_im6(din_im6),
.din_re7(din_re7),
.din_im7(din_im7),
.dout_ena(dout_ena),
.dout_re0(dout_re0),
.dout_im0(dout_im0),
.dout_re1(dout_re1),
.dout_im1(dout_im1),
.dout_re2(dout_re2),
.dout_im2(dout_im2),
.dout_re3(dout_re3),
.dout_im3(dout_im3),
.dout_re4(dout_re4),
.dout_im4(dout_im4),
.dout_re5(dout_re5),
.dout_im5(dout_im5),
.dout_re6(dout_re6),
.dout_im6(dout_im6),
.dout_re7(dout_re7),
.dout_im7(dout_im7)
);
endmodule
输出结果dout中的数的构成是:
共13位其中5位整数,8位小数。
模拟结果在波形图里应该如下设置:
输出结果如下:
可以看到会有一些误差存在,因为在使用ip核进行计算的时候,直接对小数乘法部分进行了截断处理,会造成误差。
和matlab结果对比: