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

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

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

      今天下午将项目又推荐了一些,对之前的代码进行了下改进,使得代码更具扩展性与可维护性吧。

     项目中引入了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

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

仿真时序图:


抱歉!评论已关闭.