首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA图像处理项目(二)--FIFO FFT RAM

FPGA图像处理项目(二)--FIFO FFT RAM

今天下午将项目又推荐了一些,对之前的代码进行了下改进,使得代码更具扩展性与可维护性吧。
项目中引入了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

testbench模块:
`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

仿真时序图:



来源:兔美酱的博客
记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表