今天下午将项目又推荐了一些,对之前的代码进行了下改进,使得代码更具扩展性与可维护性吧。
项目中引入了simple dual port ram,功能是对FFT处理后的数据进行转置,即按列将数据再送入FFT进行运算。
代码完全通过IP核自带控制信号进行激励与控制,使得代码的扩展性得到了加强。这里通过fft_dv来控制ram的写使能与读使能。
主模块:
module fft2d_16_top(
input clk,
input rst_n,
input fifo_wr_en,
input [63:0] srio_wr_data,
output [31:0] srio_rd_data_re,
output [31:0] srio_rd_data_im,
output [31:0] test_re,
output [31:0] test_im,
output test_fft_rfd,
output test_fft_dv,
output [4:0] test_state,
output wire [63:0] test_count,
/*move*/
output reg[7:0] ram1_addra,
output reg[7:0] ram1_addrb,
output reg[31:0] ram1_dina_re,
output reg[31:0] ram1_dina_im,
output reg ram1_ena,
output reg ram1_enb
);
parameter S_IDLE = 5'h0,
S_FFT_START = 5'h1,
S_FFT_DATA = 5'h2,
S_FFT_START2 = 5'h3;
wire [4:0] s_state;
/*FFT 参数*/
reg fft_start;//input
reg fft_fwd_inv;
reg fft_fwd_inv_we;
wire fft_rfd;//output
wire fft_dv;
wire [3:0] fft_xn_index;
wire [31:0] fft_xn_re;
wire [31:0] fft_xn_im;
wire [3:0] fft_xk_index;
wire [31:0] fft_xk_re;
wire [31:0] fft_xk_im;
wire [4:0] fft_xk_re_ex;
wire [4:0] fft_xk_im_ex;
/*fifo recv*/
reg fifo_rd_en;
wire fifo_recv_full;
wire fifo_recv_alempty;
wire [7:0] fifo_data_count;
AddrConGen addrConGen (
.clk(clk),
.rst_n(rst_n),
.fifo_recv_full(fifo_recv_full),
.fifo_data_count(fifo_data_count),
.fft_dv(fft_dv),
.s_state(s_state),
.count(test_count)
);
fifo_i64_o64 recv_fifo (
.clk(clk), // input clk
.rst(~rst_n), // input rst
.din(srio_wr_data), // input [63 : 0] din
.wr_en(fifo_wr_en), // input wr_en
.rd_en(fifo_rd_en), // input rd_en
.dout({fft_xn_re,fft_xn_im}), // output [63 : 0] dout
.full(fifo_recv_full), // output full
.almost_full(), // output almost_full
.empty(), // output empty
.almost_empty(fifo_recv_alempty), // output almost_empty
.data_count(fifo_data_count) // output [7 : 0] data_count
);
fft16 xfft16 (
.clk(clk), // input clk
.start(fft_start), // input start
.xn_re(fft_xn_re), // input [31 : 0] xn_re
.xn_im(fft_xn_im), // input [31 : 0] xn_im
.fwd_inv(fft_fwd_inv), // input fwd_inv
.fwd_inv_we(fft_fwd_inv_we), // input fwd_inv_we
.rfd(fft_rfd), // output rfd
.xn_index(fft_xn_index), // output [3 : 0] xn_index
.busy(), // output busy
.edone(), // output edone
.done(), // output done
.dv(fft_dv), // output dv
.xk_index(fft_xk_index), // output [3 : 0] xk_index
.xk_re({fft_xk_re_ex,fft_xk_re}), // output [36 : 0] xk_re
.xk_im({fft_xk_im_ex,fft_xk_im}) // output [36 : 0] xk_im
);
reg [3:0] ram1_addrb_h;
reg [3:0] ram1_addrb_l;
reg [7:0] ram1_addrb_test;
reg [7:0] ram1_addra_base;
ram64 ram1 (
.clka(clk), // input clka
.wea(ram1_ena), // input [0 : 0] wea
.addra(ram1_addra), // input [7 : 0] addra
.dina({ram1_dina_re,ram1_dina_im}), // input [63 : 0] dina
.clkb(clk), // input clkb
.enb(ram1_enb), // input enb
.addrb(ram1_addrb), // input [7 : 0] addrb
.doutb({srio_rd_data_re,srio_rd_data_im}) // output [63 : 0] doutb
);
always @(posedge clk) begin
if(~rst_n) begin
fft_start <= 0;
fft_fwd_inv <= 0;
fft_fwd_inv_we <= 0;
fifo_rd_en <= 0;
ram1_addra <= 0;
ram1_addrb <= 0;
ram1_ena <= 0;
ram1_enb <= 0;
ram1_addrb_h <= 0;
ram1_addrb_l <= 0;
ram1_addrb_test <= 0;
ram1_addra_base <= 0;
end
else
case(s_state)
S_IDLE: begin
end
S_FFT_START:begin
fft_start <= 1;
fft_fwd_inv <= 1;
fft_fwd_inv_we <= 1;
fifo_rd_en <= 1;
end
S_FFT_DATA: begin
fft_start <= ~fifo_recv_alempty;
fft_fwd_inv <= 0;
fft_fwd_inv_we <= 0;
fifo_rd_en <= ~fifo_recv_alempty;
if(fft_dv) begin //将FFT处理后的数据按行存入ram
ram1_ena <= fft_dv;
ram1_dina_re<= fft_xk_re;
ram1_dina_im<= fft_xk_im;
ram1_addra_base <= ram1_addra_base + 1;
ram1_addra <= ram1_addra_base; //fft=16
end
end
S_FFT_START2: begin
//从ram按列读出送入FFT
ram1_enb <= 1;
ram1_addrb_h <= ram1_addrb_h + 1;
ram1_addrb <= {ram1_addrb_h , ram1_addrb_l};
if(ram1_addrb_h==15) begin
ram1_addrb_l <= ram1_addrb_l + 1;
end
end
endcase
end
assign test_state = s_state;
//assign srio_rd_data_re = fft_xk_re;
//assign srio_rd_data_re = fft_xk_im;
assign test_re = fft_xk_re;
assign test_im = fft_xk_im;
assign test_fft_rfd = fft_rfd;
assign test_fft_dv = fft_dv;
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 20:40:06 02/14/2014
// Design Name:
// Module Name: AddrConGen
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module AddrConGen(
input clk,
input rst_n,
input fifo_recv_full,
input [7:0] fifo_data_count,
input fft_dv,
output reg [4:0] s_state,
output reg [63:0] count
);
reg fft_dv_pre;
reg [4:0] c_state;
parameter S_IDLE = 5'h0,
S_FFT_START = 5'h1,
S_FFT_DATA = 5'h2,
S_FFT_START2= 5'h3;
parameter C_IDLE = 5'h0,
C_FFT_START = 5'h1,
C_FFT_DATA = 5'h2,
C_FFT_START2= 5'h3;
always @(posedge clk) begin
if(~rst_n) begin
s_state <= S_IDLE;
c_state <= C_IDLE;
fft_dv_pre<= 0;
count <= 0;
end
else begin
count <= count + 1;
case(c_state)
C_IDLE: begin //0
s_state <= S_IDLE;
c_state <= C_FFT_START;
end
C_FFT_START:begin //1
if(fifo_recv_full) begin
s_state <= S_FFT_START;
c_state <= C_FFT_DATA;
end
end
C_FFT_DATA: begin
fft_dv_pre <=fft_dv;
if(fft_dv_pre && ~fft_dv) begin//dv结束
s_state <= S_FFT_START2;
c_state <= C_FFT_START2;
end
else
s_state <= S_FFT_DATA;
end
endcase
end
end
endmodule
`timescale 1ns / 1ps
// Company:
// Engineer:
//
// Create Date: 22:20:02 02/14/2014
// Design Name: fft2d_16_top
// Module Name: D:/FFT2D/FFT20140214/fft2d_0214.v
// Project Name: FFT20140214
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: fft2d_16_top
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module fft2d_0214;
// Inputs
reg clk;
reg rst_n;
reg fifo_wr_en;
reg [63:0] srio_wr_data;
// Outputs
wire [31:0] srio_rd_data_re;
wire [31:0] srio_rd_data_im;
wire [31:0] test_re ;
wire [31:0] test_im ;
wire test_fft_rfd ;
wire test_fft_dv ;
wire [4:0] test_state ;
wire [63:0] test_count ;
wire [7:0] ram1_addra;
wire [7:0] ram1_addrb;
wire[31:0] ram1_dina_re;
wire[31:0] ram1_dina_im;
wire ram1_ena;
wire ram1_enb;
// Instantiate the Unit Under Test (UUT)
fft2d_16_top uut (
.clk(clk),
.rst_n(rst_n),
.fifo_wr_en(fifo_wr_en),
.srio_wr_data(srio_wr_data),
.srio_rd_data_re(srio_rd_data_re),
.srio_rd_data_im(srio_rd_data_im),
.test_re(test_re),
.test_im(test_im),
.test_fft_rfd(test_fft_rfd),
.test_fft_dv(test_fft_dv),
.test_state(test_state),
.test_count(test_count),
.ram1_addra(ram1_addra),
.ram1_addrb(ram1_addrb),
.ram1_dina_re(ram1_dina_re),
.ram1_dina_im(ram1_dina_im),
.ram1_ena(ram1_ena),
.ram1_enb(ram1_enb)
);
reg [5:0] count;
initial begin
// Initialize Inputs
clk = 0;
rst_n = 0;
fifo_wr_en = 0;
srio_wr_data = 0;
count = 0;
#20 rst_n= 1;
end
initial begin
#10 clk= 1;
forever #5 clk=~clk;
end
always @(posedge clk) begin
if(~rst_n) begin
srio_wr_data <=0;
fifo_wr_en <=0;
count <=0;
end
else begin
if(count<=6'd3)begin
count <= count+1;
fifo_wr_en <=0;
end
else begin
count <=count;
if(srio_wr_data[63:32] >=256) begin
fifo_wr_en <=0;
end
else begin
fifo_wr_en <=1;
srio_wr_data[63:32] <= srio_wr_data[63:32] + 1;
end
end
end
end
endmodule