现在的位置: 首页 > 综合 > 正文

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

2014年06月08日 ⁄ 综合 ⁄ 共 4261字 ⁄ 字号 评论关闭

    最近这个项目是要通过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

仿真图:

抱歉!评论已关闭.