玩转VHDL014-SDR驱动器

2020-02-02 11:28发布

014-SDR.rar (3.25 KB, 下载次数: 2) 2017-11-10 14:51 上传 点击文件名下载附件


SDR驱动器FPGA需大量数据缓存时要使用外部RAM。外部RAM分为SRAMDRAM两大类。静态的SRAM操作比较简单,但容量通常不大。动态的DRAM容量大但控制复杂。DRAM又可分为SDRDDR两类。DDR除了双沿读写外,其他与SDR类似。本文介绍SDR读写驱动并给出完整代码,对于DDR,只需稍作修改。
SDR概念简介
SDR,有的地方也写作SDRAM,是Synchronous DRAM的简称。全名译为同步动态随机存储器。SDR内部为行列层结构。在SDR芯片英文手册中,行用row表示,列用column表示,层用bank表示。列有时也简称为colSDR主要引脚有CLK, CKE, nCS, nRAS, nCAS, nWE, ADR, BADQ。分别表示时钟、时钟使能、片选、列选、行选、写使能、地址、层地址和输入输出数据。以下在不引起混淆的情况下简称输入输出数据为数据。SDR还有字节掩码引脚,我们在使用时恒接有效,不进行单字节控制。上述引脚中CLK上升沿为有效,其他以n开头的控制引脚表示低电平有效,否则高电平有效。ADR地址分时承载行地址和列地址。
SDR操作简介
SDR在上电后读写数据之前需要进行初始化,初始化主要完成对SDR工作模式的设置。SDR在不进行读写操作的空闲期间需要刷新refresh操作,以维持其存储的数据。刷新操作是逐行刷新,实际刷新周期必需不大于手册要求,通常为64ms。如果实际应用写入的数据保证在64ms内读取,也可不刷新。为了使驱动更具一般性,我们不考虑这种特殊应用。在读写SDR某一单元之前,需要对此单元所在行进行激活(ACTIVE)。激活后可按列顺序或随机读写。读写后需要进行预充电PRECHARGE操作,预充电后方可访问其他行。关于不同层的问题,在这里不作讨论也几乎没有必要,可简单把层地址看作行地址高位或地位。那么读写SDR可表述为三步:激活行、列读写、预充电。SDR驱动器对外接口只有读写操作,其他操作在驱动器内完成。
SDR驱动框架设计
本帖选用型号为HY57V561620SDR为例,叙述驱动设计,简称为HY57VSDR操作简介中可看出,一次从一行中读写多列可实现较大吞吐量。所以,驱动程序设计成从起始地址开始顺序读取一个或多个单元的方式。读写过程以请求响应方式完成。为叙述方便,定义读写SDR的模块单元为用户。用户可能为1个,也可能为多个。本帖着力介绍用户为1个的单用户驱动,并在附件SDR.rar中一并给出多用户驱动。多用户驱动只是在单用户驱动的基础上增加仲裁机制。附件中SDRAM_HY57V.vhd是单用户驱动器,用户个数可指定的驱动器SDRAM_HY57V_UN.vhd被称为多用户驱动器。多用户驱动器中类属参数UN表示用户个数,当UN=1时功能同单用户驱动器。
SDR驱动框架设计思想贯穿在驱动模块引脚描述中介绍。单用户驱动模块命名为SDRAM_HY57V,模块实体如下:Entity SDRAM_HY57V is port(1.      DQ                               : inoutstd_vector(15 downto 0);              BA                                : outstd_vector(1 downto 0);         ADR                             : out std_vector(12downto 0);         CKE,nCS,nWE            : out std_logic;5.      nRAS,nCAS                 : out std_logic;         clock                            : in std_logic;           glbRst                         : in std_logic;         wrReq,rdReq            : in std_logic;         dWrite                        : in std_vector(0 to15);10.   wrAdr,rdAdr              : in std_vector(23 downto 0);         wrLen,rdLen              : in std_vector(0 to 9);         qRead                         : out std_vector(0 to15);         qEn,getNext              : out std_logic;         wrAck,rdAck              : out std_logic;15.   bgnWr,bgnRd            : out std_logic         );End SDRAM_HY57V;

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
ucx
2020-02-02 18:15
SDR驱动器实现

以SDRAM_HY57V.vhd为例。为行文语句流畅,下文在不引起混淆的情况下简记<读或写操作>为<操作>。

由于HY57V每行512列,所以限制一次请求操作长度≯512。每次操作之前需要激活,操作完成后需要预充电,所以定义一个10位计数器sn(在文件第30行)。sn在初始化阶段以及初始化后无操作时总是从0到524计数,然后回到0,即sn计数周期为525。clock频率在50M~100M范围时,sn的计数周期是5.25 ~ 10.5us。sn计数周期溢出标志pLst在48行赋值。

HY57V手册要求初始化过程为:上电后200us以上无操作,接着8个或以上自动刷新操作完成,再进行模式设置操作,然后就可以正常读写操作了。

驱动器定义初始化计数器cInit为7位(行31),cInit在上电或复位归0,然后以pLst为使能计数到64停止。cInit在0~62为无操作时间,>200us。cInit=63为初始化配置时间,在51行用tInit指示。cInit≥64为正常工作时间,在32行用wking指示。

HY57V的刷新操作分为两种,一种是用户以CLK为节拍主动刷新,称为自动刷新;另一种是CKE无效,HY57V按照其内部定时刷新,称为自刷新。驱动器采用以自刷新为主的刷新方式。在无操作的情况下,sn从0到524计数,此时sn在16到511之间为自刷新时间,最后在sn=516时一次自动刷新。自动刷新命令是参照手册建议添加。

下面按照代码文件,部分讲解代码实现。

行53:query <= wking and sn=8; query为查看读写请求时刻。那么sn=8表示一次操作的起始,sn=7则对应一次操作的终止。行57的phRAS在sn=11时刻,用于激活命令。行52的preCharge在sn=4时刻用于预充电命令。所以操作是按照激活、读写、预充电的顺序。

行66~71:用query锁存首地址和长度信息,acsing表示有操作,acsWR表示有写操作。那么acsing and not acsWR表示有读操作。代码中wrReq在rdReq之后,表示wrReq的优先级高于rdReq。如果wrReq和rdReq在query时刻同时有效,则优先处理wrReq。

行72:sn在初始化和无操作时计数周期为525。

行73~74:在初始化阶段无读写操作。

行62:auFrsh_init初始化时15次自动刷新,符合手册要求。

行63:auFrsh_exitSelf退出自刷新的自动刷新。

行58:rwCmd读写命令,用于控制列选nCAS引脚。

行59:wrCmd写命令,用于控制nWE引脚。

行75:AL9B行内地址。FPGA不同于CPU,地址累加不需要额外的时间。故,把SDR设置成非突发模式,地址累加由AL9B完成。

行87:数值9X"20"是模式设置参数。CAS Latency=2,在读操作时按照CL=2时序处理。突发长度为1即不突发,吻合行75所述。

行115:qEn <= rding(3);是按照CL=2延时所得。

行108:getNext根据写时序所得。

行78~89:根据手册中操作命令所得。

行92~99:用时序逻辑实现时钟上沿对齐。

行106~112:握手的响应信号时序实现。

多用户驱动器

SDRAM_HY57V_UN在SDRAM_HY57V上增加了仲裁机制,仲裁采用优先级法实现。任一用户的写优先级高于所有用户的读优先级,读或写操作内部,小序号用户优先级高于大序号用户优先级。

小结

SDR驱动器根据FPGA特点设置了SDR的工作方式,对外提供了请求响应方式的读写操作接口。多种响应方式,方便用户进行读写控制。对SDR的接口中未给出CLK,需要上层电路通过锁相环产生,本人在实际应用中CLK选用50M~96M,设置CLK相对于clock时延240度均正常工作。实际使用的FPGA不同,可能需要对240度时延作小范围调整。

一周热门 更多>