FPGA的a_7系列芯片对ddr3的控制

1.原理图——————这次设计的数据流是产生数据的模块是image-ctrl模块、ddr3控制模块、hdmi-buffer、vga-ctrl模块、以及hdmi转换模块。

               该模块的有2个操作始终,其中vga_clk 65M是用来产生数据的,ui_clk为ddr3控制模块的写入数据与地址的时钟,跨时钟域数据传输将32bit的图像数据转换为128bit的数据。rd_en信号的产生是由image-fifo的读出计数器产生的。而参数为何是14是因为当ddr3中存在16个数据时,对应的fifo 读出来的计数是14因而参数为14。

             这是ddr3的整个模块的控制信号,信号过多,因此在程序中做了详细介绍。

    

        这是hdmi-buffer的控制模块,是将ddr3存储的数据读出来,然后数据传给vga模块,最终通过hdmi-ctrl将数据转换为差分信号,再以单bit形式显示在显示器上。

2.关键程序

`timescale 1ns / 1ps

module ddr3_bank_ctrl(
		
	input	wire			ui_clk_sync_rst			,	//经过ddr3 ip核后产生的高有效复位信号①
    input	wire			ui_clk					,	//经过ddr3 产生的100M时钟②
    input	wire			calib_complete			,	//calib_done③
    input	wire			rd_data_valid			,	//ddr3输出的有效数据使能信号④
    
    output	wire				ddr3_app_en			,	//ddr3的命令使能信号⑤
    input	wire				app_rdy				,	//ddr3输入的读准备信号⑥
    output 	wire[2:0]			app_cmd				,	//读写命令控制⑦
    output	wire[27:0]			out_addr			, 	//输入到ddr3的地址⑧
    output	wire				app_wdf_wren		,	//写使能信号⑨
    input	wire				app_wdf_rdy			,	//ddr3输入的写准备信号⑩
    output	wire[127:0]			out_data			,	//输入到ddr3的数据①
    
    //input	wire				clk_125M			,	//输入到读写fifo的数据使能时钟②
    input	wire				wf_wren				,	//输入到写fifo的地址数据使能信号③
    input	wire[127:0]			data_in				,	//输入写fifo的数据④
    input	wire[31:0]			data_addr			,	//输入写ffio的地址⑤                 	
    
    output	wire				app_wdf_end			,	//ddr3对应的写结束信号⑥
    output 	wire[15:0]			app_wdf_mask		,	//ddr3的掩码⑦
    
    input wire 	[31 : 0] 		rd_addr				,	//输入到读fifo的地址
    input  wire [127 : 0] 		ddr3_out_data		,	//ddr3输出的数据最终输入到读数据的fifo
    output wire [8 : 0] 		rdfifo_cnt			,	//fifo缓存的数据计数
    output wire [127 : 0] 		rdfifo_data			,	//fifo最终输出的数据
    input	wire				rd_fifo_en_data		,	//fifo最终输出的数据的使能信号
    input  wire				    rd_fifo_en			
		
    );
 

reg						wdfl_detect		; 	//是wdfL
reg						rdfl_detect		;	//读数据监测
reg						write_cycle		;	//写循环
reg						read_cycle		;	//读循环
reg			[3:0]		ddr3_burst_cnt	;	//写完成16计数
reg			[3:0]		rdddr3_burst_cnt;	//读完成16计数
wire 		[8 : 0] 	wdfl_rd_cnt		;
wire 		[8 : 0] 	rdf1_rd_cnt		;
wire		[3:0]		rc_data			;
wire		[3:0]		rd_data			;
wire		[27:0]		WR_addr			;
wire		[27:0]		RD_addr			;
wire					rdflcmd_rd_en	;
reg			[2:0]		state			;
parameter	IDLE	=	3'b001			;
parameter	WRITE	=	3'b010			;
parameter	READ	=	3'b100			;


assign		app_wdf_mask	=	16'd0;	
assign		app_wdf_wren	=	app_wdf_rdy&write_cycle&app_rdy;             //写数据使能
assign		app_wdf_end		=	app_wdf_wren;
assign		rdflcmd_rd_en	=	read_cycle&app_rdy;
assign		ddr3_app_en		=	(write_cycle)?app_wdf_wren:rdflcmd_rd_en;	//ddr3的使能信号
assign		app_cmd			=	(state==READ)?3'b001:3'd0;
assign		out_addr		=	(state==WRITE)?WR_addr:RD_addr;
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)
		state<=IDLE;
		else case (state)
				IDLE:		if(calib_complete==1)
								state<=WRITE;
				WRITE:		if((wdfl_rd_cnt<14&&wdfl_detect==1)||
								(ddr3_burst_cnt==15&&app_wdf_wren==1))
							state<=READ;
							
				READ:		if((rdf1_rd_cnt<14&&rdfl_detect==1)||
								(rdddr3_burst_cnt==15&&rdflcmd_rd_en==1&&app_rdy==1))
							state<=WRITE;
				default:	state<=IDLE;	
				endcase

always@(posedge	ui_clk)
		if(ui_clk_sync_rst)
			wdfl_detect<=1'b0;
		else if((calib_complete==1&&state==IDLE )||((rdf1_rd_cnt<14&&rdfl_detect==1)||
				(rdddr3_burst_cnt==15&&rdflcmd_rd_en==1&&app_rdy==1)))
			wdfl_detect<=1'b1;
		else wdfl_detect<=1'b0;
		
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)			
			rdfl_detect<='d0;
		else if	((wdfl_rd_cnt<14&&wdfl_detect==1)||
				(ddr3_burst_cnt==15&&app_wdf_wren==1))
			rdfl_detect<=1'b1;
		else rdfl_detect<='d0;
	
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)
			write_cycle<=1'b0;
		else if(app_wdf_wren == 1&& ddr3_burst_cnt==15)  //
			write_cycle<=1'b0;
		else if(wdfl_detect==1'b1&&wdfl_rd_cnt>=14)
			write_cycle<=1'b1;
			
			
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)
			ddr3_burst_cnt<='d0;
		else if(ddr3_burst_cnt==15 && write_cycle == 1)
			ddr3_burst_cnt<='d0;
		else if(app_wdf_wren==1)
			ddr3_burst_cnt<=ddr3_burst_cnt+1'b1;
					
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)
			read_cycle<=1'b0;
		else if(rdflcmd_rd_en == 1&& rdddr3_burst_cnt==15)  //
			read_cycle<=1'b0;
		else if(rdfl_detect==1'b1&&rdf1_rd_cnt>=14)
			read_cycle<=1'b1;
			
always@(posedge	ui_clk)
		if(ui_clk_sync_rst)	
			rdddr3_burst_cnt<='d0;
		else if(rdddr3_burst_cnt==15&&read_cycle==1&&app_rdy==1)
			rdddr3_burst_cnt<='d0;
		else if(read_cycle==1&&app_rdy==1)	
			rdddr3_burst_cnt<=rdddr3_burst_cnt+1'b1;	
			
fifo_generator_512 fifo_generator_512_inst (
  .wr_clk(ui_clk),                // input wire wr_clk
  .rd_clk(ui_clk),                // input wire rd_clk
  .din(data_in),                      // input wire [127 : 0] din
  .wr_en(wf_wren),                  // input wire wr_en
  .rd_en(app_wdf_wren),                  // input wire rd_en   展示忘记了
  .dout(out_data),                    // output wire [127 : 0] dout
  .full(),                    // output wire full
  .empty(),                  // output wire empty
  .rd_data_count(wdfl_rd_cnt)  // output wire [8 : 0] rd_data_count
);

fifo_cmd_256_32 fifo_cmd_256_32_inst (
  .wr_clk(ui_clk),  // input wire wr_clk
  .rd_clk(ui_clk),  // input wire rd_clk
  .din(data_addr),        // input wire [31 : 0] din
  .wr_en(wf_wren),    // input wire wr_en
  .rd_en(app_wdf_wren),    // input wire rd_en
  .dout({rc_data,WR_addr}),      // output wire [31 : 0] dout
  .full(),      // output wire full
  .empty()    // output wire empty
);

rd_data_128_512 rd_data_128_512_inst (
  .wr_clk(ui_clk),                // input wire wr_clk
  .rd_clk(ui_clk),                // input wire rd_clk
  .din(ddr3_out_data),                      // input wire [127 : 0] 
  .wr_en(rd_data_valid),                  // input wire wr_en
  .rd_en(rd_fifo_en_data),                  // input wire rd_en
  .dout(rdfifo_data),               // output wire [127 : 0] dout
  .full(),                    // output wire full
  .empty(),                  // output wire empty
  .rd_data_count(rdfifo_cnt)  // output wire [8 : 0] rdfifo_cnt
);

rcmd_fifo_32_512 rcmd_fifo_32_512_inst (
  .wr_clk(ui_clk	),                // input wire wr_clk
  .rd_clk(ui_clk	),                // input wire rd_clk
  .din	 (rd_addr	),                // input wire [31 : 0] rd_addr
  .wr_en(rd_fifo_en	),                // input wire wr_en
  .rd_en(rdflcmd_rd_en),              // input wire rd_en
  .dout({rd_data,RD_addr}),           // output wire [31 : 0] dout
  .full(),                    		  // output wire full
  .empty(),                  		  // output wire empty
  .rd_data_count(rdf1_rd_cnt)         // output wire [8 : 0] rdf1_rd_cnt
);
endmodule

3.仿真结果

           最终数据以当行计数拉高的时候,显示四组0-255。

4.中秋节快乐

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值