SDRAM小记

一、知识点

  1. 存储单元主要由列选通三极管、存储电容、刷新放大器组成。
  2. SRAM(异步静态随机存储器)要正确存储一位数据,需要最少6个晶体管,因此,从芯片面积上来说,单片SRAM芯片的容量不可能做到很高。
  3. 工作电压:SDRAM的工作电压是3.3V,DDR的工作电压是2.5V,DDR2的工作电压是1.8V
  4. HY57V281620 芯片,容量128Mbit,数据位宽16bit,具有4个BANK,每个BANK存储32MBit的数据。每个BANK由4096*512个存储单元组成,每个存储单元存储16bit数据。
  5. 控制总线:由4条控制总线来控制SDRAM:
    片选信号CS_N,行选通信号RAS_N,列选通信号CAS_N,写使能信号WE_N。
    13位地址总线,2位BANK地址线,2位掩码DQM
  6. 为了保证SDRAM器件读写的稳定性,控制器的时钟和器件工作时钟均为100MHz,但是器件工作时钟理论向后偏移180°,考虑到布局布线延迟,实际不偏移。
  7. 为了保证存储的数据不丢失,每一行每64ms刷新一次

二、具体工作时序

  1. 上电初始化List item
module sdr_initial(
			input clk,
			input sdr_rst_n,
			input sdr_initial_en,
			
			output [19:0]init_bus,
			output reg initial_done
			);
			
		parameter clk_period = 10;//时钟周期10ns
		parameter t100us = 100000/clk_period;
		parameter tRp = 30/clk_period;//延迟30ns
		parameter tRfc =100/clk_period;//延迟100ns
		parameter tMrd = 20/clk_period;//延迟2个时钟周期
		
		parameter IDEL=7'b000_0001,//空闲态
					 s0  =7'b000_0010,//初始化状态,延迟100ns
					 s1  =7'b000_0100,//NOP过渡状态
					 s2  =7'b000_1000,//预充电
					 s3  =7'b001_0000,//自动刷新
					 s4  =7'b010_0000,//自动刷新
					 s5  =7'b100_0000;//加载模式寄存器
						 
						 
		parameter NOP = 4'b0111,//空操作命令
					 PRE = 4'b0010,//预充电命令
					 AREF= 4'b0001,//自动刷新命令
					 MEST= 4'b0000,//加载模式寄存器命令
					 ACT = 4'b0011;//激活命令
					 
		parameter ZEROS = 3'b000,//默认3个0
					 OP_CODE = 1'b0,//写突发模式设置
					 OP_MODE = 2'b00,//标准模式
					 CLs = 2,//列选通潜伏期:2
					 BT = 1'b0,//突发类型:顺序
					 BLs = 2;//突发长度:2
		
		parameter BL=(BLs==1)?3'b000:
						 (BLs==2)?3'b001:
						 (BLs==4)?3'b010:
						 (BLs==8)?3'b011:3'b111;//突发长度为1 2 4 8 或者FULL PAGE(111)
		parameter CL=(CLs==2)?3'b010:3'b011;//列选通潜伏期为2或者3
					 
					 
		 
		reg [6:0]state;
		reg [15:0]cnt;
		reg [1:0]init_ba;
		reg [12:0]init_addr;
		reg [3:0]init_cmd;
		reg init_cke;
		
		assign init_bus = {init_ba,init_addr,init_cmd,init_cke};	
		
		always@(posedge clk or negedge sdr_rst_n)
		if(!sdr_rst_n)begin
				cnt 		    <= 16'd0;
				init_cke     <= 1'd0;
				init_addr    <= 13'd0;
				init_cmd 	 <= NOP;
				initial_done <= 1'd0;
				state			 <= IDEL;
				init_ba      <= 2'd0;
							end
		else begin
			case(state)
				IDEL:
					begin
						if(sdr_initial_en)
						begin
							state <= s0;
							end
						else begin
							state        <= IDEL;
							cnt          <= 16'd0;
							init_cke     <= 1'd0;
							init_addr    <= 13'd0;
							init_cmd     <= NOP;
							initial_done <= 1'd0;
							init_ba      <= 2'd0;
								end
					end
				s0:
					begin
						if(cnt >= 9999)
							begin
							init_cke <= 1'd1;
							cnt 		<= 16'd0;
							state 	<= s1;

							end
					else 
							cnt <= cnt+1'b1;
							end
				s1:
				 begin
				 		init_addr[10] <= 1'b1;
						init_cmd 	  <= PRE;
						state 		  <= s2;
					end
					
				s2:
				begin
					if(cnt >=2)
						begin
						cnt 		<= 16'd0;
						init_cmd <= AREF;
						state 	<= s3;
						end
					else begin
						cnt 		<= cnt+1'b1;
						init_cmd <= NOP;
							end
				end
				s3:
				begin
					if(cnt >=9)
						begin
							cnt 		<= 16'd0;
							init_cmd <= AREF;
							state 	<= s4;
						end
					else begin
							cnt 		<= cnt+1'b1;
							init_cmd <= NOP;
							end
				end
				s4:
				begin
					if(cnt >=9)
						begin
							cnt       <= 16'd0;
							init_cmd  <= MEST; 
							init_addr <= {ZEROS,OP_CODE,OP_MODE,CL,BT,BL};//模式寄存器设置
							state     <= s5;
						end
					else begin
							cnt 		<= cnt+1'b1;
							init_cmd <= NOP;
							end
				end
				s5:
				begin
					if(cnt >= 1)
						begin
						initial_done <= 1'b1;
						cnt 			 <= 16'd0;
						state        <=IDEL;
						end
					else begin
						init_cmd     <= NOP;
						cnt          <= cnt+1'b1;
							end
				end
				default:begin
							cnt          <= 16'd0;
							init_cke     <= 1'd1;
							init_addr    <= 13'd0;
							init_cmd     <= NOP;
							initial_done <= 1'd0;
							state        <= IDEL;
							end
				endcase
				end
					 
//			reg [6:0]current_state;
//			reg [6:0]next_state;
//			reg [15:0]cnt;
//			
//			always@(posedge clk or negedge sdr_rst_n)
//			 if(!sdr_rst_n)
//				current_state <= IDEL;
//			 else
//				current_state <= next_state;
//				
//			always@(*)
//			begin
//				case(current_state)
//					IDEL:
//						begin
//							if(sdr_initial_en)
//								next_state = s0;
//							else
//								next_state = IDEL;
//						end
//					s0:
//						begin
//							if(cnt>=t100us-1)
//								next_state=s1;
//							else
//								next_state = current_state;
//						end
//					s1:
//						begin
//								next_state = s2;
//						end
//					s2:
//						begin
//							if(cnt>=tRp-1)
//								next_state = s3;
//							else 
//								next_state = current_state;
//						end
//					s3:
//						begin
//							if(cnt>=tRfc-1)
//								next_state = s4;
//							else	
//								next_state = current_state;
//						end
//					s4:
//						begin
//							if(cnt>=tRfc-1)
//								next_state = s5;
//							else
//								next_state = current_state;
//						end
//					s5:
//						begin
//							if(cnt>=tMrd-1)
//								next_state = IDEL;
//							else
//								next_state = current_state;
//						end
//					default:next_state=IDEL;	
//					endcase
//			end
//		
//		always@(posedge clk or negedge sdr_rst_n)
//		if(!sdr_rst_n)begin
//				cnt <= 16'd0;
//				init_cke <= 1'd0;
//				init_addr <= 13'd0;
//				init_cmd <= NOP;
//				initial_done <= 1'd0;
//			end
//		else begin
//			case(next_state)
//				IDEL:
//					begin
//						cnt <= 16'd0;
//						init_cke <= 1'd0;
//						init_addr <= 13'd0;
//						init_cmd <= NOP;
//					end
//				s0:
//					begin
//						if(cnt >= t100us-1)
//							begin
//							init_cke <= 1'd1;
//							cnt <= 16'd0;
//							end
//					else 
//					
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值