本文主要是介绍DRAM Command Unit(DCU),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
4.7.1 DCU功能
DCU模块提供了一种通过配置总线执行DRAM命令的方式。以下是DCU的主要目的:
1. 通过配置端口执行DRAN初始化流程
2. 提供统一的硅片测试与PHY特性测试,且不需要控制器支持
3. 提供软件可执行的DRAM命令
注意:DCU提供有限的功能,且不能替代功能模式。
4.7.2 DCU命令
用户可通过配置端口(APB或JTAG)来实现DRAM的命令,下面列表为可支持的命令
命令操作码 | 命令 | 命令描述 |
---|---|---|
0000 | NOP | PUB无操作 |
0001 | LOAD_MODE | 写模式寄存器 |
0010 | SELF_REFRESH | 使DRAM进入自刷新模式 |
0011 | REFRESH | 向DRAM发出一个自动刷新命令 |
0100 | PRECHARGE | 关闭DRAM中的某一页 |
0101 | PRECHARGE_ALL | 关闭DRAM中的所有页 |
0110 | ACTIVATE | 激活DRAM中的某一页 |
0111 | SPECIAL_CMD | 特殊命令,详见PUB文档第240页 |
1000 | WRITE | 向DRAM发出burst写命令 |
1001 | WRITE_PRECHG | 向DRAM发出burst写命令,并在写完成后关闭该页 |
1010 | READ | 向DRAM发出burst读命令 |
1011 | READ_PRECHG | 向DRAM发出burst读命令,并在写完成后关闭该页 |
1100 | ZQCAL_SHORT | 仅DDR3,向DRAM发出长ZQ校准命令 |
1101 | ZQCAL_LONG | 仅DDR3,向DRAM发出短ZQ校准命令 |
1110 | POWER_DOWN | 进入DRAM低功耗模式 |
1111 | SDRAM_NOP | 向DRAM发出NOP操作 |
PUB不会对输入到DCU的命令进行自动时序检查,也不会自动生成activate和precharge命令。所以当用户使用配置端口输入命令时,必须确认正确的NOP操作数量以保证命令之间的时序。或者使用DCU时序特性来保证DRAM的时序要求。同时用户需要生成activate与precharge名来来保证正确的页打开与关闭。
4.7.3 DCU Caches
DCU共包含三种Cache,分别是:
1. 命令Cache
2. 读数据Cache
3. 期望数据Cache
命令Cache按照顺序来存储将要执行的DRAM命令。读数据Cache捕获来自DRAM的读数据。期望数据Cache存储用来与读数据进行比较的数据。每个Cache的深度可独立的配置为4、8、16(默认16),且此深度在编译时就确定了。
每个Cache可被写或者读,通过DCUAR(DCU地址寄存器)以及DCRDR(DCU数据寄存器)。Cache中每一行的地址与Cache的整体深度相关,例如若Cache深度为16,每一行的地址为0-15。Cache中每一行被分为32位,0位是最低位。Cache中每一行的位数与PHY中bytelane的个数以及Cache的类型相关。读数据Cache与期望数据Cache仅仅存储数据,而命令Cache除了存储所有命令的编码之外,还额外存储了3位,这三位表示此条命令的重复次数。每个条目的数据部分拥有四个节拍的数据(不是很确定是不是这么翻译的)。
下图中展示了Cache字的格式。由于面积的限制,为了减小设计中Cache的尺寸,PUB中可以配置数据为32bit字与4bit掩码。在此配置下,32bit数据将被复制到每个bytelane。
在配置DCU命令Cache时,每一个组成部分都是必要的。下面列表中包含了相关信息。需要注意的是,命令Cache的宽度没有必要分割为32bit的部分,此时,在写DCUDR时最高有效低位需要被置为0已凑齐一个完整的32bit。
Name | Width Calculation | Description |
---|---|---|
DATA | 32*DWC_NO_OF_BYTES | |
MASK | 4*DWC_NO_OF_BYTES | |
ADDR | DWC_ADDR_WIDTH | |
BANK | DWC_BANK_WIDTH | |
RANK | Single Rank System = 0 | |
CMD | 4 | DRAM命令 |
TAG | 2 | |
DTP | 5 | DRAM时序参数 |
RPT | 3 | 重复次数 |
DTP参数要求是当前命令与下一个命令之间确切的最小的DRAM时序参数,PUB会根据DTP参数自动的在当前命令执行完毕之后添加SDRAM NOP操作。为了简化配置DRAM命令的时序参数配置,DTP域被简化成可选择的DRAM命令时序参数项,这些时序参数项来自于DTPR0-2,PTR1-2以及RDIMMGCR1,还有已经预先计算好的参数。此域配置为0,则表示当前命令执行完毕之后没有任何延时。
下面列表表示了DTP可选择的参数
DTP | VALUE | SOURCE REGISTER |
---|---|---|
0 | 0 | Fixed |
1 | tRP | DPTR0 |
2 | tRAS | DPTR0 |
3 | tRRD | DPTR0 |
4 | tRC | DPTR0 |
5 | tMRD | DPTR1 |
6 | tMOD | DPTR1 |
7 | tFAW | DPTR1 |
8 | tRFC | DPTR1 |
9 | tWLMRD | DPTR1 |
10 | tWLO | DPTR1 |
11 | tXS | DPTR2 |
12 | tXP | DPTR2 |
13 | tCKE | DPTR2 |
14 | tDLLK | DPTR2 |
15 | tDINITRST | PTR4 |
16 | tDINITCKELO | PTR3 |
17 | tDINICKEHI | PTR3 |
18 | tDINITZQ | PTR4 |
19 | tRPA | Computed by PUB |
20 | tPRE2ACT | Computed by PUB |
21 | tACT2RW | Computed by PUB |
22 | tRD2PRE | Computed by PUB |
23 | tWR2PRE | Computed by PUB |
24 | tRD2WR | Computed by PUB |
25 | tWR2RD | Computed by PUB |
26 | tRDA2ACT | Computed by PUB |
27 | tWRA2ACT | Computed by PUB |
28 | tDCUT0 | DCUTR |
29 | tDCUT1 | DCUTR |
30 | tDCUT2 | DCUTR |
31 | tDCUT3 | DCUTR |
当对命令Cache进行编程时,每一行含有一个3bit的RPT域。此域的含义为将当前命令执行x+1次。下表表示了RPT域的含义。
RPT | Value | Source Register | Description |
---|---|---|---|
0 | 0 | Fixed | 执行1次 |
1 | 1 | Fixed | 执行2次 |
2 | 7 | Fixed | 执行8次 |
3 | tBL | Computed by PUB | 执行一次完整的DDR Burst |
4 | tDCUT0 | DCUTR | 执行tDCUT0+1次 |
5 | tDCUT1 | DCUTR | 执行tDCUT1+1次 |
6 | tDCUT2 | DCUTR | 执行tDCUT2+1次 |
7 | tDCUT3 | DCUTR | 执行tDCUT3+1次 |
当使用tBL时,PUB将重复执行命令的次数与配置的Burst长度想匹配。尤其是在DDR3中,固定每次都是BL8时,比较有用。比如说,我配置的Burst长度为4,那么我在发送了4拍数据之后会发送NOP命令,来消耗BL8中的后四拍数据。
4.7.4 Writing or Reading DCU Caches
有两种方式可以读取或写入DCU的Cache。第一种为,先写DCUAR确定行地址与片段地址,然后再写入DCUDR。这是一种比较笨的方法,非常的耗时,所以PUB提供了一种自动增加地址的机制。通过配置DCUAR的INCA域,用户仅需要配置起始地址,随后每一次写入DCUDR的32位数据,都会写增加一次片段地址,直到当前行已经写满,然后自动跳入下一行,且片段地址变回0。
下面例子为第一种方式写入Cache,共包含4行,每行4个片段。
下面例子为第二种方式,通过自动增加地址的方式写入Cache。
4.7.5 Command Execution
一旦命令被载入命令Cache,可以通过配置DCURR里面的DINST域来触发运行Cache中的命令。在执行命令时,会从DCURR中配置的SADDR地址开始,结束于EADDR地址。命令执行可以通过配置DCURR的DINST为STOP来暂停,或者在指针到达命令cache的末端时也会自动暂停命令执行。命令执行还可以通过检查错误数量来停止,首先需要配置DCURR的SONF为1,同时配置NFAIL为你期望的错误数量,那么当你开始执行命令后,在比较读返回数据时,累计错误数量到达NFAIL时,也会自动暂停命令执行。
通过配置DCULR寄存器,可以设定SADDR至EADDR之间的命令循环执行的次数。LSADDR为循环起始地址,此地址必须大于或等于执行命令的起始地址。LEADDR为循环结束地址,次地址必须小于或等于执行命令的结束地址。DCULR寄存器中的LCNT域可配置循环的次数,而LINT可设定循环次数是否是无限次。已执行的循环次数可在DCUSR1寄存器中的LPCNT域进行查看。DCURR寄存器的DINST配置为STOP_LOOP可停止无限循环,此停止可跳出循环并继续向下执行命令,如果还有任何命令没有运行完毕。
DCULR寄存器中的IDA与XLEADDR域是没有必要配置的。IDA控制DRAM地址自动增加,XLEADDR配置期望数据的最后有效地址。
4.7.5.1 Command Cache Instructions for BL8 Reads and Writes
需要注意的是,Cache中单独一行读或者写都是不合法的,加入用户仅写入一行写,那么由于DDR3是固定BL8的,那么PUB会将下一行的数据作为后四拍数据发送出去,此时下一行的命令将会丢失。
4.7.6 Read Data Capture and Compare
用户可通过配置DCURR寄存器中的RCEN位来使能DRAM返回的读数据是否进入读数据Cache。需要注意的是,一旦读数据Cache的指针到达了Cache的最后一行,则会直接转向读数据Cache的第一行。可通过配置DCURR寄存器中的SCOF位来防止此问题出现,一旦此位设置为1,那么当指针到达最后一行时,抓取读数据将会停止。无论SCOF为设置与否,当指针到达最末你,DCUSR0的CFULL位都将被置1。
DCUGCR寄存器中的RCSW为可选择PUB开始抓取读数据的序号。例如此位设置为12,那么PUB将会从第13个读数据开始抓取。
DCURR寄存器中的XCEN可配置是否比较期望数据Cache和返回的读数据。首先,用户将期望的数据写入期望数据Cache。如果没有配置XLEADDR,那么期望数据Cache也会循环的将Cache中的数据与读数据进行比较,若配置了XLEADDR,则对比数据从XLEADDR+1位置开始绕回起始位置。若后续程序清零了XCEN,那么期望数据的指针也会随之清零。
4.7.7 DCU Status
一旦执行命令完成或者停止,DCUSR0寄存器的RDONE位会被置为1,这仅仅表示命令的执行已经完成了。用户在读取其他DCU状态寄存器时,首先要确保此位已经变为1。为了避免上一次运行的配置影响下一次,DCURR中的reset可复位一部分状态寄存器。如下图所示。
DCU Examples Single Load Command Execution
CADDR | RPT | DTP | TAG | CMD | RANK | BANK | ADDR | MASK | DATA |
---|---|---|---|---|---|---|---|---|---|
0 | 0 | tACT2RW | 00 | ACTIVATE | 0 | 0 | 0 | 0 | 0 |
1 | tBL | tWR2RD | 00 | WRITE | 0 | 0 | 0 | 0 | 0xABCD_1234 |
2 | 0 | tWR2RD | 00 | SDRAM_NOP | 0 | 0 | 0 | 0 | 0 |
3 | tBL | tRE2PRE | 00 | READ | 0 | 0 | 0 | 0 | 0 |
4 | 0 | tRP | 00 | PRECHARGE | 0 | 0 | 0 | 0 | 0 |
注释:
1. DCURR[SADDR]=0=start address
2. DCURR[EADDR]=4=end address
3. DCULR[LEADDR] = 4 = loop end address.
4. DCULR[LINF] = 1 = loop infinite around the write command.
5. DCULR[IDA] = 1 = increment the address for each iteration of the loop.
6. Accessed DRAM location: rank = 0, bank = 0, row = 0, column = 0
更多例子请参考PUB手册
这篇关于DRAM Command Unit(DCU)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!