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

FPGA图像处理项目(一)--FIFO与FFT

FPGA图像处理项目(一)--FIFO与FFT

最近这个项目是要通过SRIO将图像解析数据送到XILINX FPGA通过FFT处理再用SRIO传回主控,我准备用FIFO来做一个数据的缓冲池,然后按行做FFT运算,中间结果按行存入RAM中,之后按列进行FFT运算,再存入RAM,最后传入FIFO,经过SRIO传回主控。
昨天算是对FIFO有了一定了解(因为光一个fifo文档就300多页,我想一个看似简单的IP核其实想用好还真的不容易),对于本项目也够用了。今天把FIFO和FFT连在一起用了一下,各个模块搭好后,进行仿真测试,在这一过程中问题还是很多的,对于FFT参数的控制和激励一定要非常仔细,必须要一点点仿真一点点把握各个模块之间的时序关系。
接触FPGA也有半年多,其实这半年来FPGA用的也不是很多,一直断断续续的,这样真的不好。因为自己是计算机学院的学生,所以周围的师兄师姐都没有做FPGA的,基本都是自己一个人摸索吧,有些时候一个简单的问题都会让我困扰很久,也许这时候只需要一个稍微懂一点FPGA的给我一点拨也就通了,但是我想有时候只有在遇到困难才能让人真正的提高,这种提高不仅仅是知识上的,我想很多东西是说不清的。项目要一点点推进,每个环节都需要严格的仿真才能继续进行,加油,我想这个项目完成以后我一定会收获不少!
废话不多,下面把今天的一点工作进展进行下记录。这面两个模块一个是主模块,一个是地址与控制信号生成模块。这里按各个状态来描述:
1. S_IDLE状态--向FIFO传输1-256个数据(实部是1-256,虚部都是0):这里通过判断fifo_recv_full来进行状态跳转,当fifo_recv_full为高时说明256个数据已经传输完毕,跳转到S_FFT_START状态
2. S_FFT_START状态--拉高fft_start信号,以及使能FIFO的读信号fifo_rd_en信号,具体变化请看图1。这里一个关键问题就是,什么时候拉低fft_start信号,这里考虑fifo_data_count信号,我的方法是当前时钟周期fifo_data_count=2时,状态跳转到S_FFT_START_OVER,并传送倒数第二个数据;下一时钟周期s_state=S_FFT_START_OVER,并拉低fft_start,并传送最后一个数据;再下一个时候周期检测到fft_start为低,不再接收数据。具体参见图4.
最后通过MATLAB仿真结果完全正确。后面将继续实现对按行进行FFT后的数据的按列FFT。有问题的同学请留言~
主模块
module fft2d_16_top(
input clk,
input rst_n,

input         fifo_wr_en,
input [63:0] srio_wr_data,
output        [36:0]        srio_rd_data_re,
output        [36: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
);

parameter S_IDLE         =        5'h0,
S_FFT_START         =        5'h1,
S_FFT_START_OVER         =        5'h2;

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        [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),
.s_state(s_state)

);
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(), // 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(srio_rd_data_re), // output [36 : 0] xk_re
.xk_im(srio_rd_data_im) // output [36 : 0] xk_im
);

always @(posedge clk)        begin
if(~rst_n)        begin
fft_start         <= 0;
fft_fwd_inv         <= 0;
fft_fwd_inv_we        <= 0;

fifo_rd_en         <= 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_START_OVER:        begin
fft_start         <= 0;
fft_fwd_inv         <= 0;
fft_fwd_inv_we        <= 0;
fifo_rd_en         <= 1;
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_xn_re;
assign test_im         = fft_xn_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,
output reg [4:0] s_state
);

reg        [4:0]        c_state;
parameter        S_IDLE         = 5'h0,
S_FFT_START =        5'h1,
S_FFT_START_OVER        =        5'h2;

parameter        C_IDLE         =        5'h0,
C_FFT_START =        5'h1,
C_FFT_START_OVER        =        5'h2,
C_FFT_DV        = 5'h3;

always @(posedge clk) begin
if(~rst_n) begin
s_state <= S_IDLE;
c_state <= C_IDLE;
end
else
case(c_state)
C_IDLE:         begin
s_state         <= S_IDLE;
c_state         <= C_FFT_START;
end
C_FFT_START:begin
if(fifo_recv_full)        begin
s_state         <= S_FFT_START;
c_state         <= C_FFT_START_OVER;
end
end
C_FFT_START_OVER:        begin
if(fifo_data_count==2) begin
s_state        <= S_FFT_START_OVER;
c_state <= C_FFT_DV;
end
end
endcase
end

endmodule
仿真图:



记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表