SDRAM 控制器(二)——初始化模块

article/2025/10/26 8:45:22

1、初始化模块

        SDRAM 的初始化是芯片上电后必须进行的一项操作,只有进行了初始化操作的 SDRAM 芯片才可被正常使用。SDRAM 的初始化是一套预先定义好的流程,除此之外的其 他操作会导致 SDRAM 出现不可预知的后果。

初始化时序图:

        CK:工作时钟,具体时钟频率视不同的芯片而不同 

        CKE:时钟使能,在整个初始化过程中都需要拉高

        COMMAND:SDRAM命令,由4根线拼接而成,分别是CS#(片选信号),RAS#(行选通信号),CAS#(列选通信号),WE#(写使能信号),通过这4根命令线,再结合SDRAM的地址、输入输出数据等,就可以对SDRAM进行各种命令操作

        DQM/DQML,DQMU:数据掩码,通过数据掩码可以实现对输入或输出数据的某一位进行“掩埋”,也就是使某一位失效

        A[9:0],A[12:11]:数据地址线,同时也可用来设置模式寄存器

        A10:数据地址线,同时也可以用来使能一些具体操作,比如控制自动预充电使能、使能预充电bank数量

        BA[1:0]:bank地址

        DQ数据:在初始化过程中无数据输出,保持高阻态就行

初始化过程:

        1.上电后需保持时钟稳定状态至少100us(各芯片时间不同),同时CKE需拉高;同时需发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

        2.对所有BANK进行预充电操作,A10拉高即是选中所有BANK

        3.进行预充电操作后需要等待一定的时间,即tRP,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

        4.等待结束后发送自动刷新指令

        5.进行自动刷新操作后需要等待一定的时间,即tRC,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

        6.重复进行发送自动刷新指令与等待tRFC,芯片不同刷新次数不同

        7.发送模式寄存器设置指令,地址总线 A0-A11 参数不同 辅助模式寄存器不同模式的设置

        8.发送模式寄存器设置指令后需要等待一定的时间、即tMRD,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

        9.tMRD等待时间结束后,SDRAM 初始化完成

补充:

预充电
        SDRAM的寻址具有独占性,所以在进行完读写操作后,如果要对同一个Bank的另一行进行寻址,就要将原来有效(ACTIVE)的行关闭,重新发送行/列地址。Bank关闭当前工作行,准备打开新行的操作就是预充电。 预充电可以通过独立的命令控制,也可以在每次发送读写命令的同时使用“A10”线控制自动进行预充电。实际上,预充电是一种对工作中所有存储阵列进行数据重写,并对行地址进行复位,以准备新行的工作。

        预充电指令除了在初始化过程中用到外,在自动刷新以及读写操作中也都会被用到。

自动刷新
        SDRAM 内部存储体是利用电容能够保持电荷以及可充放电的特性制成,而电容所存储的电荷会随时间不断流失,会造成存储数据的丢失。为保证 SDRAM 中数据的可靠性,需要对 SDRAM 进行不断刷新。

        刷新操作分两种:“自动刷新”和“自刷新”。发送命令后CKE时钟为有效时(低电平),使用自动刷新操作,否则使用自我刷新操作。不论使用何种刷新方式,都不需要外部提供地址信息,因为这个是内部操作。

        对于“自动刷新”,SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动地依次生成行地址,每收到一次命令刷新一行。在刷新过程中,所有的Bank都停止工作,而每次刷新所占用的时间为N个时钟周期。刷新结束后才可进入正常的工作状态,也就是说在这N个时钟期间内,所有工作指令只能等待而无法执行。一次次的按行刷新,刷新完所有行后,将再一次对第一行重新进行刷新操作,这个对同一行刷新操作的时间间隔,成为SDRAM的刷新周期,通常为64ms。显然,刷新会对SDRAM的性能造成影响,但这是SDRAM的特性决定的,也是SDRAM相对于SRAM取得成本优势的同时所付出的代价。

         “自刷新”则主要用于休眠模式低功耗状态下的数据保存,也就是说即使外部控制器件不工作了,SDRAM都能自己确保数据正常。在发出“自我刷新”命令后,将CKE置于无效状态(低电平),就进入自我刷新模式。此时不再依靠外部时钟工作,而是根据SDRAM内部的时钟进行刷新操作。在自我刷新期间,除了CKE之外的所有外部信号都是无效的,只有重新使CKE有效才能退出自我刷新模式并进入正常操作状态。
        因为我们平常控制SDRAM都是在正常工作状态下使用,所以一般是对SDRAM进行自动刷新操作。

模式寄存器配置:

        通过对SDRAM模式寄存器的配置可以实现对其各种工作方式、参数的控制,如突发长度BL、读潜伏期CL等。

        A12-A10:预留
        A9:读写方式,0:突发读&突发写;1:突发读&单写
        A8,A7:00:标准模式,默认
        A6,A5,A4:CAS潜伏期,分别为1、2、3、保留
        A3:突发传输方式,0:顺序;1:隔行
        A2,A1,A0:突发长度,000:1、2、4、8、全页

等待时间参数:
以下时间参数根据芯片的不同可能存在差异:

        tRP:PRECHARGE  command  period,发送预充电指令后进行下一个操作需要等待的时间

        tRFC:AUTO  REFRESH  period,发送自动刷新指令后进行下一个操作需要等待的时间

        tMRD:LOAD MODE REGISTER command to ACTIVE or REFRESH command,发送设置模式寄存器指令后进行下一个操作需要等待的时间

初始化模块可以使用状态机实现:

INIT_IDLE:上电等待状态,等待时间满足100us要求后,跳转至下一状态INIT_PRE,在此状态发送NOP指令
INIT_PRE:发送预充电指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TRP ,在此状态发送预充电指令
INIT_TRP:预充电指令等待状态、在此状态等待时间满足TRP后就跳转到下一个状态INIT_AR,在此状态发送NOP指令  
INIT_AR:发送自动刷新指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TRFC,在此状态发送自动刷新指令    
INIT_TRFC:自动刷新指令等待状态、在此状态等待时间满足TRFC时进行判断,若自动刷新次数满足要求(2次或其他手册要求)后就跳转到下一个状态INIT_MRS,在此状态发送NOP指令,若不满足自动刷新次数要求就继续进行自动刷新操作,跳转到状态INIT_AR
INIT_MRS:发送模式寄存器设置指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TMRD,在此状态发送模式寄存器设置指令     
INIT_TMRD:模式寄存器设置指令等待状态、在此状态等待时间满足TMRD后就跳转到下一个状态INIT_END,在此状态发送NOP指令    
INIT_END:初始化结束状态,完成初始化后一直停留在这个状态;在此状态发送NOP指令,并将初始化完成信号拉高以通知其他模块开始进行工作

时序图:

 仿真结果:

端口:

信号名称         位宽       属性            描述
init_clk              1           输入      100M时钟信号
init_rst_n          1           输入       复位信号,低电平有效
init_addr         13           输出       SDRAM地址总线
init_cmd           4           输出       SDRAM命令,组成{CS#,RAS#,CAS#,WE#}
init_bank          2           输出       BANK地址,共4个BANK
init_end            1           输出       初始化完成信号,初始化完成后拉高,其他时间保持低电平

代码:

//----------------------------------------------------------------------------------------------------
//--SDRAM初始化模块
//----------------------------------------------------------------------------------------------------
module SDRAM_INIT(input              sys_clk				,input		       sys_rst_n 			,output reg [3:0]   init_cmd    			,output reg [1:0]   init_ba				,output reg [12:0]  init_addr			,output		       init_end		
);parameter  		INIT_IDLE = 3'b000,INIT_PRE  = 3'b001,INIT_TRP  = 3'b011,INIT_AR   = 3'b010,INIT_TRFC = 3'b110,INIT_MRS  = 3'b111,INIT_TMRD = 3'b101,INIT_END  = 3'b100;parameter 	  WAIT_MAX = 15'd20_000;parameter     TRP   =  3'd2,TRFC  =  3'd7,TMRD  =  3'd3;parameter     NOP        = 4'b0111,P_CHARGE = 4'b0010,AUTO_REF   = 4'b0001,M_REG_SET = 4'b0000;wire				wait_end			;
wire				TRP_end				;
wire				TRFC_end			;
wire				TMRD_end			;reg 	[2:0]       init_state			;
reg     [14:0]		cnt_200us			;
reg		[2:0]		cnt_clk				;
reg					cnt_clk_rst			;
reg		[3:0]		cnt_aref			;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)init_state <= INIT_IDLE;else  begincase(init_state)INIT_IDLE  :if(wait_end == 1'b1)init_state <= INIT_PRE   ;else;INIT_PRE   :   init_state <= INIT_TRP		 ;INIT_TRP   :if(TRP_end == 1'b1)init_state <= INIT_AR    ;else;INIT_AR    :init_state <= INIT_TRFC		 ;INIT_TRFC  :if(TRFC_end == 1'b1 )if(cnt_aref == 4'd8)init_state <= INIT_MRS	 ;elseinit_state <= INIT_AR	 ;else;INIT_MRS   :init_state <= INIT_TMRD		 ;INIT_TMRD  :if(TMRD_end == 1'b1)init_state <= INIT_END	 ;else;INIT_END   :init_state <= INIT_END		 ;default : init_state <= INIT_IDLE;endcaseend
//上电等待200us
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)cnt_200us <= 15'd0;else if(cnt_200us == WAIT_MAX)cnt_200us <= WAIT_MAX;elsecnt_200us <= cnt_200us + 1'b1;//200us标志信号计数器
assign  wait_end = (cnt_200us == WAIT_MAX - 1'b1)? 1'b1 : 1'b0;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)cnt_clk <= 3'd0;else if(cnt_clk_rst == 1'b1)cnt_clk <= 3'd0;elsecnt_clk <= cnt_clk + 1'b1;always @(*)begin case(init_state)INIT_IDLE : cnt_clk_rst <= 1'b1;INIT_TRP  : cnt_clk_rst <= (TRP_end == 1'b1)? 1'b1 : 1'b0 ;INIT_TRFC : cnt_clk_rst <= (TRFC_end == 1'b1)? 1'b1 : 1'b0;INIT_TMRD : cnt_clk_rst <= (TMRD_end == 1'b1)? 1'b1 : 1'b0;INIT_END  : cnt_clk_rst <= 1'b1;default : cnt_clk_rst <= 1'b0  ;endcase
end
//如何判断先后顺序?不看状态只看cnt_clk计数?应该是在各自的状态下才进行计数?是的,后边修改了
assign  TRP_end  = (init_state == INIT_TRP && cnt_clk == TRP) ? 1'b1 : 1'b0;
assign  TRFC_end = (init_state == INIT_TRFC && cnt_clk == TRFC)? 1'b1 : 1'b0;
assign	TMRD_end = (init_state == INIT_TMRD && cnt_clk == TMRD)? 1'b1 : 1'b0;//自动刷新次数计数  刷新次数为8    1,2,3,4,5,6,7,8共8次。
always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)cnt_aref <= 4'd0;else if(init_state == INIT_IDLE)cnt_aref <= 4'd0;else if(init_state == INIT_AR)cnt_aref <= cnt_aref + 1'b1;elsecnt_aref <= cnt_aref;always @(posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)begininit_cmd    <=  NOP		;init_ba     <= 2'b11	;init_addr   <= 13'h1fff ;endelsecase(init_state)INIT_IDLE,INIT_TRP,INIT_TRFC,INIT_TMRD,INIT_END : begin init_cmd    <=  NOP		 ;init_ba     <=  2'b11	 ;init_addr   <=  13'h1fff ;endINIT_PRE :begin init_cmd    <=  P_CHARGE	 ;init_ba     <=  2'b11	 ;init_addr   <=  13'h1fff ;endINIT_AR  :begin init_cmd    <=  AUTO_REF ;init_ba     <=  2'b11	 ;init_addr   <=  13'h1fff ;end			INIT_MRS :begin init_cmd    <=  M_REG_SET ;init_ba     <=  2'b00	 ;init_addr   <=  {3'b000,1'b0,2'b00,3'b011,1'b0,3'b111} ;enddefault : begin init_cmd    <=  NOP		 ;init_ba     <=  2'b11	 ;init_addr   <=  13'h1fff ;end				endcase
assign  init_end = (init_state == INIT_END) ? 1'b1 : 1'b0;endmodule

仿真代码:

//----------------------------------------------------------------------------------------------------
//--SDRAM初始化仿真测试
//----------------------------------------------------------------------------------------------------
`timescale 1ns/1ns
module SDRAM_INIT_tb();wire   	clk50m			;
wire    clk100m			;
wire    clk100m_shift	;
wire    locked			;
wire    rst_n 			;wire [3:0]  init_cmd	;
wire [1:0]	init_ba		;
wire [12:0] init_addr	;
wire		init_end	;reg   sys_clk 			;
reg   sys_rst_n			;initial begin sys_clk  = 1'b1;sys_rst_n 	<= 1'b0;#30sys_rst_n	<= 1'b1;end
always #10  sys_clk <= ~sys_clk;	assign rst_n = sys_rst_n & locked ;	defparam    sdram_model_plus_inst.addr_bits = 13;
defparam    sdram_model_plus_inst.data_bits = 16;
defparam    sdram_model_plus_inst.col_bits = 9;
defparam    sdram_model_plus_inst.mem_sizes = 2*1024*1024;clk_gen	clk_gen_inst
(.areset ( ~sys_rst_n),.inclk0 ( sys_clk ),.c0 ( clk50m	 ),.c1 ( clk100m	 ),.c2 ( clk100m_shift ),.locked	( locked )
);SDRAM_INIT SDRAM_INIT_inst(.  sys_clk		(clk100m)	,.  sys_rst_n 	(rst_n)		,.  init_cmd    	(init_cmd)	,.  init_ba		(init_ba)	,.  init_addr	(init_addr)	,.  init_end		(init_end)
);      sdram_model_plus  sdram_model_plus_inst
(				.Dq     ()     		  	  , .Addr	(init_addr)       , .Ba		(init_ba)		  , .Clk	(clk100m_shift)	  , .Cke	(1'b1)		 	  , .Cs_n	(init_cmd[3])     , .Ras_n	(init_cmd[2])	  , .Cas_n	(init_cmd[1])     , .We_n	(init_cmd[0])     , .Dqm	(2'b00)		 	  ,.Debug  (1'b1)
);                      endmodule


http://chatgpt.dhexx.cn/article/LUN2WZC3.shtml

相关文章

SDRAM详细介绍

概念介绍&#xff1a; SDRAM&#xff1a;Synchronous Dynamic Random Access Memory&#xff0c;同步动态随机存储器。同步是指其时钟频率和CPU前端总线的系统时钟相同&#xff0c;并且内部命令的发送与数据的传输都以它为基准&#xff1b;动态是指存储阵列需要不断的刷新来保证…

sdram简易控制器设计

耗时一周&#xff0c;终于完成sdram简易控制器的所有代码设计&#xff0c;其中感谢开源骚客 – 邓堪文老师在b站发布的相关视频学习教材&#xff1b;其中仿真模块及所使用到的sdram仿真文件来源于开源骚客&#xff1b; 因为时间较为紧迫&#xff0c;其中就不做代码的一些注释&…

基于FPGA的SDRAM控制器设计(一)

基于FPGA的SDRAM控制器设计&#xff08;一&#xff09; 1. SDRAM控制器整体框架2.UART_RX模块3.UART_TX模块4. RX与TX模块的整合5.需要注意的问题6.代码7.参考资料 1. SDRAM控制器整体框架 图1.1整体框架 PC端通过串口模块UART_RX发送读写命令以及数据到Cmd_encode模块&#xf…

基于FPGA的SDRAM控制器设计(1)

基于FPGA的SDRAM初始化配置 SDRAM简述SDRAM的引脚及作用SDRAM初始化时序控制SDRAM上电时序代码SDRAM测试模块的代码仿真测试结果参考文献总结 SDRAM简述 SDRAM&#xff08; Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存储器。同步是指 Me…

FPGA进阶(3):SDRAM读写控制器的设计与验证

文章目录 第50讲&#xff1a;SDRAM读写控制器的设计与验证理论部分设计与实现1. sdram_ctrlsdram_initsdram_a_refsdram_writesdram_readsdram_arbitsdram_ctrl 2. sdram_topfifo_ctrlsdram_top 3. uart_sdramuart_rxuart_txfifo_readuart_sdram 第50讲&#xff1a;SDRAM读写控…

SDRAM

简介、优缺点、历史 1、译为“同步动态随机存取内存”&#xff0c;区别于异步DRAM。SRAM是异步静态存储器。 2、同步(Synchronous)&#xff1a;与通常的异步 DRAM 不同&#xff0c; SDRAM 存在一个同步接口&#xff0c;其工作时钟的时钟频率与对应控制器(CPU/FPGA上的读写控制…

关于SDRAM存储器

一、对SDRAM的初步认识 1.1 什么是SDRAM SDRAM&#xff08;Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存取存储器。 同步&#xff1a;工作频率与对应控制器的系统时钟频率相同&#xff0c;且内存内部的命令以及数据的传输都以此为基准 …

内存控制器与SDRAM

内存接口概念&#xff1a; 通常ARM芯片内置的内存很少&#xff0c;要运行Linux&#xff0c;需要扩展内存。ARM9扩展内存使用SDRAM内存&#xff0c;ARM11使用 DDR SDRAM。S3C2440通常外接32位64MBytes的SDRAM&#xff0c;采用两片16位32M的SDRAM芯片&#xff0c;SDRAM芯片通过地…

SDRAM驱动篇之简易SDRAM控制器的verilog代码实现

在Kevin写的上一篇博文《SDRAM理论篇之基础知识及操作时序》中&#xff0c;已经把SDRAM工作的基本原理和SDRAM初始化、读、写及自动刷新操作的时序讲清楚了&#xff0c;在这一片博文中&#xff0c;Kevin来根据在上一篇博文中分析的思路来把写一个简单的SDRAM控制器。 我们在上一…

FPGA之SDRAM控制器设计(一)

MT48LC128M4A2 – 32 Meg x 4 x 4 banks是512M SRAM&#xff0c;总体概述如下图 分别从上电初始化&#xff0c;刷新&#xff0c;写&#xff0c;读四个部分进行设计&#xff0c;此外还包含主控状态机&#xff0c;一个顶层。 1&#xff1a;上电初始化 整体架构&#xff1a;从控…

内存控制器与SDRAM【赞】

原文链接&#xff1a;https://blog.csdn.net/qq_31216691/article/details/87115697 内存接口概念&#xff1a; 通常ARM芯片内置的内存很少&#xff0c;要运行Linux&#xff0c;需要扩展内存。ARM9扩展内存使用SDRAM内存&#xff0c;ARM11使用 DDR SDRAM。S3C2440通常外接32位6…

SDRAM 介绍

目录 1、名词解释 2、SDRAM 内部结构 3、SDRAM 外部信号描述 4、SDRAM 命令 4.1、COMMAND INHIBIT 4.2、NO OERATION 4.3、ACTIVE 4.4、LOAD MODE REGISTER (LMR) 4.5、READ 4.6、WRITE 4.7、PRECHARGE 4.8、BURST TERMINATE 4.9、REFRESH 4.9.1、AUTO REFRESH …

SDRAM控制器操作时序

此为学习http://dengkanwen.com/137.html整理的笔记&#xff0c;侵删&#xff01; SDRAM工作原理 内部的状态跳转图 我们所需关注的几个地方&#xff1a; 1&#xff09;粗黑线表示在该状态下会自动跳转到另一个状态&#xff0c;细黑线表示需要给命令才会跳转。 2&#xff09…

SDR SDRAM控制器设计

目录 前言 1、关于刷新 2、关于数据中心对齐 3、SDRAM芯片手册介绍 3.1SDRAM芯片的管脚 3.2 SDRAM指令集 3.3 模式寄存器 3.4 关于SDRAM上电初始化和装载模式寄存器 3.5 SDRAM刷新时序 3.6 关于写访问 3.7 关于突发访问 4、FPGA工程设计 4.1状态机设计 5、仿真测试…

【GD32】从零开始学GD32单片机高级篇——外部存储器控制器EXMC详解+SDRAM读写例程

目录 简介外部设备地址映射NOR和PSRAM的地址映射NAND/PC Card地址映射SDRAM地址映射 NOR/PSRAM控制器接口描述控制时序模式1模式2 NAND Flash或PC Card控制器接口描述控制时序 SDRAM控制器接口描述控制时序突发读操作突发写操作读写FIFO跨边界读写操作低功耗模式自刷新模式掉电…

初识内存控制器和SDRAM【一文了解】

原文链接&#xff1a;https://blog.csdn.net/qq_36243942/article/details/85596249 目录 1.引入内存控制器 2.不同位宽内存设备之间的连接 3.如何确定芯片的访问地址 4.分析读写NOR FLASH的读写时序 5.SDRAM初识 6.编程读/写 SDRAM 附录&#xff1a;源代码 1.引入内存控制器 我…

存储控制器(SDRAM操作)

什么是存储控制器 2440是32位单片机&#xff0c;进行数据访问时通过32位地址访问。 CPU发出32位地址信号给存储控制器&#xff0c;存储控制器根据地址信号设置片选信号及地址总线&#xff0c;将相应数据通过数据总线传回存储控制器&#xff0c;存储控制器将收到的数据以字节为…

数字IC实践项目(2)——高速SDRAM控制器的设计与综合(入门级工程项目)

数字IC实践项目&#xff08;2&#xff09;—高速SDRAM控制器的设计与综合&#xff08;入门级工程项目&#xff09; 写在前面的话项目简介和学习目的SDRAM简介SDRAM控制器简介完整项目框图SDRAM控制器项目框图SDRAM初始化模块SDRAM自动刷新模块SDRAM写模块SDRAM读模块SDRAM仲裁机…

SDRAM控制器——仲裁模块的实现

前面一文中&#xff0c;我们已经对SDRAM的上电初始化、自动刷新以及突发读写进行了学习。 本文跟着大佬学习SDRAM中的仲裁模块。 仲裁机制 仲裁&#xff08;arbit&#xff09;&#xff1a;在FPGA中&#xff0c;当多个source源同时发出请求&#xff0c;容易导致操作冲突&#x…

SDRAM读写控制器

第1节 –作者&#xff1a;小黑同学 本文为明德扬原创及录用文章&#xff0c;转载请注明出处&#xff01; 1.1 总体设计 1.1.1 概述 同步动态随机存取内存&#xff08;synchronous dynamic randon-access menory&#xff0c;简称SDRAM&#xff09;是有一个同步接口的动态随…