FPGA之SDRAM控制器设计(四)

FPGA之SDRAM控制器设计(四):

读模块设计:

下面是带有自动预充电的读时序图。图上所示的突发长度BL为4,本次设计中一开始初始化时BL为2,所以只读取两个突发长度(4字节)

读状态转移图

读模块设计:

`include	"head.v"

module	read(
		input				clk,
		input				capture_clk,
		input				soft_rst_n,
		input				rd_en,
		input	[12:0]		row,
		input	[9:0]		col,
		input	[1:0]		ba,
		input	[15:0]		sdr_dq,
		output	[19:0]		rd_bus,
		output	reg			rd_done,
		output	reg	[31:0]	rdata
);

reg		[15:0]		cap_dq;//由主控发出的时钟信号驱动,和clk也差180°
reg		[15:0]		syn_dq;//由clk驱动
reg					load_h;
reg					load_l;
reg		[12:0]		rd_a;
reg		[1:0]		rd_ba;
reg		[3:0]		rd_cmd;
reg					rd_cke;
reg		[4:0]		cnt;
reg		[2:0]		state;

localparam		s0 = 3'b000;
localparam		s1 = 3'b001;
localparam		s2 = 3'b010;
localparam		s3 = 3'b011;
localparam		s4 = 3'b100;
localparam		s5 = 3'b101; 

assign rd_bus={rd_cmd,rd_a,rd_ba,rd_cke};

always @(posedge clk)
	if(soft_rst_n == 1'b0)
		begin
			rd_done <= 1'b0;
			cnt <= 'd0;
			rd_cmd <= `NOP;
			rd_a <= 'd0;
			rd_ba <= 'd0;
			rd_cke <= 1'b1;
			load_h <= 1'b0;
			load_l <= 1'b0;
			state <= s0;
		end
	else
		case (state)
			s0 : if(rd_en == 1'b0)
					state <= s0;
				 else
				 	begin
				 		rd_cmd <= `ACT;
				 		rd_a <= row;
				 		rd_ba <= ba;
				 		rd_done <= 1'b0;
				 		//rd_cke <= 1'b1;
				 		state <= s1;	
				 	end
			s1 : if(cnt < `tRCD -1)
					begin
						cnt	<= cnt + 1'b1;
						rd_cmd <= `NOP;
						state <= s1;	
					end
				 else
				 	begin
				 		rd_cmd <= `RD;
				 		rd_a[9:0] <= col;
				 		rd_a[10] <= 1'b1;
				 		rd_ba <= ba;
				 		cnt	<= 'd0;		
				 		state <= s2;
				 	end
				 	
			s2 : 	if(cnt < `CL + `SL -1)
						begin
							rd_cmd <= `NOP;
							cnt <= cnt + 1'b1;
							state <= s2;	
						end
					else		//BL字数2读完
						begin
							load_l <= 1'b1;
							cnt	<= 'd0;
							state <= s3;	
						end
		
			s3 : begin
					load_l <= 0;
					load_h <= 1;
					state <= s4;
				 end
				 
			s4 : begin
					rd_done <= 1'b1;
					load_h <= 1'b0;
					state <= s5;
				 end
			s5 : begin
					rd_done <= 1'b0;
					state <= s0;
				 end
		endcase


always @(posedge capture_clk)
		begin
			cap_dq <= sdr_dq;
		end
		
always @(posedge clk)
		begin
			syn_dq <= cap_dq;
		end
		
always @(posedge clk)
	begin
		if(soft_rst_n == 1'b0)
			rdata <= 'd0;
		else if(load_l == 1'b1)
			rdata[15:0] <= syn_dq;
		else if(load_h == 1'b1)
			rdata[31:16] <= syn_dq;
	end
	
	     
	
endmodule

读时序仿真:

report:

猜你喜欢

转载自blog.csdn.net/qq_41754003/article/details/107997972