当前位置: 首页 > news >正文

网站模板的好处网络营销论文文献

网站模板的好处,网络营销论文文献,各大网站的名字大全,wordpress仪表盘改名实验十八#xff1a;SDRAM模块① — 单字读写 笔者与SDRAM有段不短的孽缘#xff0c;它作为冤魂日夜不断纠缠笔者。笔者尝试过许多方法将其退散#xff0c;不过屡试屡败的笔者#xff0c;最终心情像橘子一样橙。《整合篇》之际#xff0c;笔者曾经大战几回儿#xff0c;不…实验十八SDRAM模块① — 单字读写 笔者与SDRAM有段不短的孽缘它作为冤魂日夜不断纠缠笔者。笔者尝试过许多方法将其退散不过屡试屡败的笔者最终心情像橘子一样橙。《整合篇》之际笔者曾经大战几回儿不过内容都是点到即止。最近它破蛊而出日夜不停“好~痛苦好~痛苦”地呻吟着吓得笔者不敢半夜如厕。疯狂之下誓要歪它不可 ... 可恶的东西笔者要它血债血还 图18.1 数据读取理想时序左物理时序右。 首先让我们来了解一下什么才是数据读取的最佳状态如图18.1所示红色箭头是上升沿绿色箭头是锁存沿。左图是理想时序读取数据的最佳状态即T0发送数据T1锁存数据。右图则是物理时序读取数据的最佳状态即T0发送数据然后数据经由 TDATA延迟然后T1锁存数据。理想状态下读取数据不用考虑任何物理因数凡是过去值都会读取成功。 图18.2 读取数据物理时序。 然而物理状态下读取数据则必须考虑物理因数但是物理时序也有所谓的理想状态即数据被TDATA推挤然后恰好停留在锁存沿的正中间。该状态之所以称为理想那是因为建立时间TSETUP与保持时间THOLD都被满足。 如图18.2所示TSETUP从数据中间向左边覆盖THOLD从数据中间向右边覆盖如果两者不完全覆盖数据那么数据的有效性就能得到保证。简言之数据是否读取成功建立时间还有保持时间都必须得到满足。但是我们也知道Verilog不能描述理想以外的东西即Verilog无力描述TDATA。话虽如此我们可以改变时钟位移来达到同样的效果。 图18.3 CLOCK1位移 -180°左图没有位移中图CLOCK2 位移 180°右图以及修正结果。 常见的理想时序最多适用在FPGA的内部而已。当描述功活动涉及FPGA的外部那么理想时序必须考虑对外的情况。如图18.3所示中间的理想时序图可以经由 CLOCK1 位移 -180°又或者 CLOCK2 位移 180° 来得到同样的效果。虽说180° 的位移是理想效果但是我们还要考虑物理路径所带来的影响。根据Alinix 301这只开发板我们必须追加 -30° 位移才能达到修正的效果。注意追加-30° 的修正时序仅仅为适用Alinix 301这只板子而已。理解完毕以后我们便可进入正题。 驱动SDRAM而言简单可以分为以下四项操作 一初始化 二刷新操作 三读操作 四写操作 初始化令SDRAM就绪刷新操作就是不失掉内容数据读操作就是从SDRAM哪里读取数据写操作就是向SDRAM写数据。其中读写操作又有单字读写多字读写还有页读写。 首先让我们来分析一下Alinx 开发板上HY57V2562GTR 这只SDRAM。根据手册这只SDRAM有256Mb的容量4个BANK即一个BANK为64Mb)频率极限为200Mhz数据保留周期为 8192 / 64ms。至于引脚定义如表18.1所示 表18.1 SDRAM的引脚定义 分类 标示 信号 说明 时钟信号 CLK S_CLK 时钟源 地址信号 BA0~1 S_BA[1:0] BANK地址 A0~A12 S_A[12:0] 读写地址行列共用A0~A12为行地址CA0~CA8为列地址 命令信号 CKE S_CKE, 时钟选拉高有效 CS S_NCS, 片选拉低有效 RAS S_NRAS, 命令选拉低有效 CAS S_NCAS, 命令选拉低有效 WE S_NWE 命令选拉低有效 数据信号 DQ0~DQ15 S_DQ[15:0] 读写数据的IO LDQMUDQM S_DQM[1:0] 遮盖数据一般拉低无视 如表18.1所示CLK为SDRAM的时钟源。CKECSRASCAS还有WE皆为命令信号五者相互组合形成以下几个常用命令结果如表18.2所示 表18.2 常用命令。 命令 CKE CS RAS CAS WE 说明 NOP 1 0 1 1 1 空命令 ACT 1 0 0 1 1 激活命令选择Bank地址与行地址 WR 1 0 1 0 0 写命令开始写数据 RD 1 0 1 0 1 读命令开始读数据 BSTP 1 0 1 1 0 停止命令停止读写 PR 1 0 0 1 0 预充命令释放选择 AR 1 0 0 0 1 刷新命令刷新内容 LMR 1 0 0 0 0 设置命令设置SDRAM l NOP为No Operation即空命令除了给空时间以外没有任何意义。 l ACT为Active即激活命令用来选择某Bank某行。 l WR为Write即写命令通知设备开始写数据。 l RD为Read即读命令通知设备开始读数据。 l BSTP为Burst Stop即停止命令禁止设备继续读写。 l PR为 Precharge即预充命令用来释放某Bank与某行的选择。 l AR为Auto Refresh即刷新命令用来刷新或者更新数据内容。 l LMR为Load Mode Register即设置命令用来配置设备参数。 Verilog则可以这样描述这些命令结果如代码18.1所示 parameter _INIT 5b01111, _NOP 5b10111, _ACT 5b10011, _RD 5b10101, _WR 5b10100, _BSTP 5b10110, _PR 5b10010, _AR 5b10001, _LMR 5b10000; 代码18.1 DQ0~DQ15为数据信号。BA0~1与A0~A12皆为地址信号其中A0~A12行列共用然而地址信号可以指向的范围如下计算 22 Bank 13 Row 9 Column × 16 bit 224 × 16 bit 1.6777216e7 × 16 bit // 16M × 16 bit 2.68435456e8 bit 262144 kbit 256 Mbits 初始化 初始化除了就绪SDRAM以外我们还要设置SDRAM内部的 Mode Register设置内容内容如表18.3所示 表18.3 Mode Register的内容。 Mode Register A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 0 0 OP Code 0 0 CAS Latency BT Burst Length A3 Burst Type 0 Sequential 1 Interleave   Burst Length A2 A1 A0 A3 0 A3 1 0 0 0 1 1 0 0 1 2 2 0 1 0 4 4 0 1 1 8 8 1 1 1 Full Page Reserved A9 Write Mode 0 Burst Read and Burst Write 1 Burst Read and Single Write A6 A5 A4 CAS Latency 0 1 0 2 0 1 1 3 如表18.3所示设置内容必须经由地址信号A12~A0。其中A2~A0表示字读写的长度实验十八为单字读写所以A2~A0设置为3’b000。A3表示读写次序1’b0表示顺序读写。A6~A4表示 CAS 延迟也可以视为读出延迟设为 3’b011是为读出更稳定。A9表示读写模式一般都是设置为1’b0。 图18.4 初始化的理想时序图。 图18.4是初始化的理想时序图其中CLOCK1为 -210°的系统时钟CLOCK2为SDRAM的时钟。rCMD为CKECSRASCAS还有WE等命令。rA为A0~A12rBA为BA0~BA1等地址信号。初始化过程如下所示 l T0满足100us l T1发送PR命令拉高所有rA与rBA。 l T1半周期SDRAM读取。 l T2满足TRP l T3发送AR命令。 l T3半周期SDRAM读取。 l T4满足TRRC l T5发送AR命令。 l T5半周期SDRAM读取。 l T6满足TRRC l T7发送LMR命令与相关Code设置内容。 l T7半周期SDRAM读取。 l T8满足TMRD。 怎么样读者是不是觉得很单纯呢事后Verilog则可以这样描述结果如代码18.2所示 1. case( i ) 2. 3. 0: // delay 100us 4. if( C1 T100US -1 ) begin C1 14d0; i i 1b1; end 5. else begin C1 C1 1b1; end 6. 7. 1: // Send Precharge Command 8. begin rCMD _PR; { rBA, rA } 15h3fff; i i 1b1; end 9. 10. 2: // wait TRP 20ns 11. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 12. else begin rCMD _NOP; C1 C1 1b1; end 13. 14. 3: // Send Auto Refresh Command 15. begin rCMD _AR; i i 1b1; end 16. 17. 4: // wait TRRC 63ns 18. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 19. else begin rCMD _NOP; C1 C1 1b1; end 20. 21. 5: // Send Auto Refresh Command 22. begin rCMD _AR; i i 1b1; end 23. 24. 6: // wait TRRC 63ns 25.    if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 26. else begin rCMD _NOP; C1 C1 1b1; end 27. 28. 7: // Send LMR Cmd. Burst Read Write, 3b011 mean CAS latecy 3, Sequential, 1 burst length 29. begin rCMD _LMR; rBA 2b11; rA {3d0,1b0,2d0,3b011,1b0, 3b000}; i i 1b1; end 30. 31. 8: // Send 2 nop CLK for tMRD 32. if( C1 TMRD -1 ) begin C1 14d0; i i 1b1; end 33. else begin rCMD _NOP; C1 C1 1b1; end 34. 35. 9: // Generate done signal 36. begin isDone 1b1; i i 1b1; end 37. 38. 10: 39. begin isDone 1b0; i 4d0; end 40. 41. endcase 代码18.2 代码18.2完全按照图18.4去驱动读者只要将i看为T就万事大吉其中步骤7发送LMR命令还有设置Code内容。至于步骤8~9则用来产生完成信号。 刷新操作 图18.5 刷新操作的理想时序图。 所谓定期刷新就是被宫掉的初始化如图18.5所示时序过程如下 l T0发送PR命令拉高所有rA与rBA视喜好而定 l T0半周期SDRAM读取。 l T1满足TRP l T2发送AR命令。 l T2半周期SDRAM读取。 l T3满足TRRC l T4发送AR命令。 l T4半周期SDRAM读取。 l T5满足TRRC Verilog 则可以这样表示结果如表18.3所示 1. case( i ) 2. 3. 0: // Send Precharge Command 4. begin rCMD _PR; i i 1b1; end 5. 6. 1: // wait TRP 20ns 7. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 8. else begin rCMD _NOP; C1 C1 1b1; end 9. 10. 2: // Send Auto Refresh Command 11. begin rCMD _AR; i i 1b1; end 12. 13. 3: // wait TRRC 63ns 14. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 15. else begin rCMD _NOP; C1 C1 1b1; end 16. 17. 4: // Send Auto Refresh Command 18. begin rCMD _AR; i i 1b1; end 19. 20. 5: // wait TRRC 63ns 21. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 22. else begin rCMD _NOP; C1 C1 1b1; end 23. 24. 6: // Generate done signal 25. begin isDone 1b1; i i 1b1; end 26. 27. 7: 28. begin isDone 1b0; i 4d0; end 29. 30. endcase 代码18.3 除了步骤6~7用来产生完成信号以外代码18.3都是据图18.5描述。SDRAM储存的内容是非常脆弱的如果我们不定期刷新内容该内容有可能会蒸发掉。根据 HY57V2562GTR这只 SDRAM它的内容储存周期为 8192 / 64ms然而定期刷新的计算如下 64ms / 8192 7.8125us 换言之每隔7.8125微妙就要刷新一次所有内容。 写操作 图18.6 写操作的理想时序图。 图18.6是写操作的理想时序图过程如下 l T1发送ACT命令BANK地址与行地址 l T1半周期SDRAM读取 l T2满足TRCD l T3发送WR命令BANK地址与列地址还有写数据 l T3半周期SDRAM读取 l T4满足TWR l T5满足TRP。 正如前面说过ACT命令式用来选择BANK地址与行地址然而关键就在T3。T3除了发送WR命令列地址还有些数据以外A10拉高是为了执行预充电。所谓预充电就是释放BANK地址行地址与列地址等的选择。因此满足TWR以后我们还要满足TRP的释放时间好让SDRAM有足够的时间自行释放选择。 Verilog则可以这样描述结果如代码18.4所示 1. case( i ) 2. 3. 0: // Set IO to output State 4. begin isOut 1b1; i i 1b1; end 5. 6. 1: // Send Active Command with Bank and Row address 7. begin rCMD _ACT; rBA iAddr[23:22]; rA iAddr[21:9]; i i 1b1; end 8. 9. 2: // wait TRCD 20ns 10. if( C1 TRCD -1 ) begin C1 14d0; i i 1b1; end 11. else begin rCMD _NOP; C1 C1 1b1; end 12. 13. 3: // Send Write cmd with row address, pull up A10 1 clk to PR 14. begin rCMD _WR; rBA iAddr[23:22]; rA { 4b0010, iAddr[8:0] }; i i 1b1; end 15. 16. 4: // wait TWR 2 clock 17. if( C1 TWR -1 ) begin C1 14d0; i i 1b1; end 18. else begin rCMD _NOP; C1 C1 1b1; end 19. 20. 5: // wait TRP 20ns 21. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 22. else begin rCMD _NOP; C1 C1 1b1; end 23. 24. 6: // Generate done signal 25. begin isDone 1b1; i i 1b1; end 26. 27. 7: 28. begin isDone 1b0; i 4d0; end 29. 30. endcase 代码18.4 根据前面的计算BA1~BA0再加上 RA12~A0与 CA8~A0以后一共有24位宽详细的位分配如表18.4所示 表18.4 Addr的位分配。 位分配 地址内容 Addr[23:22] BANK地址 Addr[219] 行地址 Addr[8:0] 列地址 如代码18.4所示步骤用来设置IO口为输出。步骤1为rA赋值行地址步骤3则为rA赋值列地址并且拉高A10以示自行预充电。步骤6~7用来产生完成信号。 读操作 图18.7 读操作的理想时序。 图18.7为读操作的理想时序大致过程如下 l T1发送ACT命令BANK地址与行地址 l T1半周期SDRAM读取 l T2满足TRCD l T3发送RD命令BANK地址与列地址 l T3半周期SDRAM读取命令。 l T4满足 CAS Latency。 l T5读取数据。 l T6满足TRP。 读操作与写操作的过程大同小异除了WR命令变成RD命令以外A10为1同样表示自行预充电余下就是满足CAS Latency。好奇的同学一定会觉得疑惑为何CL 为3呢其实没什么只是直感上觉得3这个数字比较顺眼一点。注意CL的计算方式是读取RD命令以后开始计算。 Verilog可以这样描述结果如代码18.5所示 1. case( i ) 2. 3. 0: 4. begin isOut 1b0; D1 16d0; i i 1b1; end 5. 6. 1: // Send Active command with Bank and Row address 7. begin rCMD _ACT; rBA iAddr[23:22]; rA iAddr[21:9]; i i 1b1; end 8. 9. 2: // wait TRCD 20ns 10. if( C1 TRCD -1 ) begin C1 14d0; i i 1b1; end 11. else begin rCMD _NOP; C1 C1 1b1; end 12. 13. 3: // Send Read command and column address, pull up A10 to PR. 14. begin rCMD _RD; rBA iAddr[23:22]; rA { 4b0010, iAddr[8:0]}; i i 1b1; end 15. 16. 4: // wait CL 3 clock 17. if( C1 CL -1 ) begin C1 14d0; i i 1b1; end 18. else begin rCMD _NOP; C1 C1 1b1; end 19. 20. 5: // Read Data 21. begin D1 S_DQ; i i 1b1; end 22. 23. 6: // wait TRP 20ns 24. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 25. else begin rCMD _NOP; C1 C1 1b1; end 26. 27. 7: // Generate done signal 28. begin isDone 1b1; i i 1b1; end 29. 30. 8: 31. begin isDone 1b0; i 4d0; end 32. 33. endcase 代码18.5 代码18.5完全根据图18.7描述除了步骤7~8用于产生完成信号以外。SDRAM的基本操作大致上就是这样而已完后我们便可以开始建模了。 图18.8 SDRAM基础模块的建模图。 图18.8是SDRAM基础模块的建模图SDRAM基础模块的内容包括SDRAM控制模块还有SDRAM功能模块。外围的PLL模块应用频率为133Mhz向左位移210°的CLOCK1还有133Mhz的CLOCK2。CLOCK1用作系统时钟CLOCK用作SDRAM时钟。如果PLL模块硬要分类的话它应该属于特殊性质的即时类吧 SDRAM控制模块主要负责一些操作的调度左边2位Call/Done由外部调用其中 [1]为写操作 [0]为读操作右边4位Call/Done为调用SDRAM功能模块其中 [3]为写操作 [2]为读操作 [1]为刷新 [0]为初始化。SDRAM功能模块的右边是驱动SDRAM硬件资源的顶层信号左边的问答信号被控制模块调用以外地址信号还有数据信号都直接连接外部。 sdram_funcmod.v 图18.9 SDRAM功能模块的建模图。 该说的东西笔者都已经说了具体内容我们还是来看代码吧。 1. module sdram_funcmod 2. ( 3. input CLOCK, 4. input RESET, 5. 6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE, 7. output [1:0]S_BA, 8. output [12:0]S_A, 9. output [1:0]S_DQM, 10. inout [15:0]S_DQ, 11. 12. input [3:0]iCall, 13. output oDone, 14. input [23:0]iAddr, // [23:22]BA,[21:9]Row,[8:0]Column 15. input [15:0]iData, 16. output [15:0]oData 17. ); 以上内容为相关的出入端声明。 18. parameter T100US 14d13300; 19. // tRP 20ns, tRRC 63ns, tRCD 20ns, tMRD 2CLK, tWR/tDPL 2CLK, CAS Latency 3CLK 20. parameter TRP 14d3, TRRC 14d9, TMRD 14d2, TRCD 14d3, TWR 14d2, CL 14d3; 21. parameter _INIT 5b01111, _NOP 5b10111, _ACT 5b10011, _RD 5b10101, _WR 5b10100, 22. _BSTP 5b10110, _PR 5b10010, _AR 5b10001, _LMR 5b10000; 23. 以上内容为相关的常量声明其中第18~20行的是将常量都是经由133Mhz量化。 24. reg [4:0]i; 25. reg [13:0]C1; 26. reg [15:0]D1; 27. reg [4:0]rCMD; 28. reg [1:0]rBA; 29. reg [12:0]rA; 30. reg [1:0]rDQM; 31. reg isOut; 32. reg isDone; 33. 34. always ( posedge CLOCK or negedge RESET ) 35. if( !RESET ) 36. begin 37. i 4d0; 38. C1 14d0; 39. D1 16d0; 40. rCMD _NOP; 41. rBA 2b11; 42. rA 13h1fff; 43. rDQM 2b00; 44. isOut 1b1; 45. isDone 1b0; 46. end 以上内容为相关的寄存器声明以及复位操作。 47. else if( iCall[3] ) 48. case( i ) 49. 50. 0: // Set IO to output State 51. begin isOut 1b1; i i 1b1; end 52. 53. 1: // Send Active Command with Bank and Row address 54. begin rCMD _ACT; rBA iAddr[23:22]; rA iAddr[21:9]; i i 1b1; end 55. 56. 2: // wait TRCD 20ns 57. if( C1 TRCD -1 ) begin C1 14d0; i i 1b1; end 58. else begin rCMD _NOP; C1 C1 1b1; end 59. 60. /*********************************************/ 61. 62. 3: // Send Write command with row address, pull up A10 1 clk to PR 63. begin rCMD _WR; rBA iAddr[23:22]; rA { 4b0010, iAddr[8:0] }; i i 1b1; end 64. 65. 4: // wait TWR 2 clock 66. if( C1 TWR -1 ) begin C1 14d0; i i 1b1; end 67. else begin rCMD _NOP; C1 C1 1b1; end 68. 69. 5: // wait TRP 20ns 70. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 71. else begin rCMD _NOP; C1 C1 1b1; end 72. 73. /**********************************************/ 74. 75. 6: // Generate done signal 76. begin isDone 1b1; i i 1b1; end 77. 78. 7: 79. begin isDone 1b0; i 4d0; end 80. 81. endcase 以上内容为部分核心操作。第47行的if( iCall[3] ) 表示余下内容为写操作。 82. else if( iCall[2] ) 83. case( i ) 84. 85. 0: 86. begin isOut 1b0; D1 16d0; i i 1b1; end 87. 88. 1: // Send Active command with Bank and Row address 89. begin rCMD _ACT; rBA iAddr[23:22]; rA iAddr[21:9]; i i 1b1; end 90. 91. 2: // wait TRCD 20ns 92. if( C1 TRCD -1 ) begin C1 14d0; i i 1b1; end 93. else begin rCMD _NOP; C1 C1 1b1; end 94. 95. /********************/ 96. 97. 3: // Send Read command and column address, pull up A10 to PR 98. begin rCMD _RD; rBA iAddr[23:22]; rA { 4b0010, iAddr[8:0]}; i i 1b1; end 99. 100. 4: // wait CL 3 clock 101. if( C1 CL -1 ) begin C1 14d0; i i 1b1; end 102. else begin rCMD _NOP; C1 C1 1b1; end 103. 104. /********************/ 105. 106. 5: // Read Data 107. begin D1 S_DQ; i i 1b1; end 108. 109. /********************/ 110. 111. 6: // wait TRP 20ns 112. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 113. else begin rCMD _NOP; C1 C1 1b1; end 114. 115. /********************/ 116. 117. 7: // Generate done signal 118. begin isDone 1b1; i i 1b1; end 119. 120. 8: 121. begin isDone 1b0; i 4d0; end 122. 123. endcase 以上内容为部分核心操作。第82行的if( iCall[2] ) 表示余下内容为读操作。 124. else if( iCall[1] ) 125. case( i ) 126. 127. 0: // Send Precharge Command 128. begin rCMD _PR; i i 1b1; end 129. 130. 1: // wait TRP 20ns 131. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 132. else begin rCMD _NOP; C1 C1 1b1; end 133. 134. 2: // Send Auto Refresh Command 135. begin rCMD _AR; i i 1b1; end 136. 137. 3: // wait TRRC 63ns 138. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 139. else begin rCMD _NOP; C1 C1 1b1; end 140. 141. 4: // Send Auto Refresh Command 142. begin rCMD _AR; i i 1b1; end 143. 144. 5: // wait TRRC 63ns 145. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 146. else begin rCMD _NOP; C1 C1 1b1; end 147. 148. /********************/ 149. 150. 6: // Generate done signal 151. begin isDone 1b1; i i 1b1; end 152. 153. 7: 154. begin isDone 1b0; i 4d0; end 155. 156. endcase 以上内容为部分核心操作。第124行的if( iCall[1] ) 表示余下内容为刷新操作。 157. else if( iCall[0] ) 158. case( i ) 159. 160. 0: // delay 100us 161. if( C1 T100US -1 ) begin C1 14d0; i i 1b1; end 162. else begin C1 C1 1b1; end 163. 164. /********************/ 165. 166. 1: // Send Precharge Command 167. begin rCMD _PR; { rBA, rA } 15h3fff; i i 1b1; end 168. 169. 2: // wait TRP 20ns 170. if( C1 TRP -1 ) begin C1 14d0; i i 1b1; end 171. else begin rCMD _NOP; C1 C1 1b1; end 172. 173. 3: // Send Auto Refresh Command 174. begin rCMD _AR; i i 1b1; end 175. 176. 4: // wait TRRC 63ns 177. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 178. else begin rCMD _NOP; C1 C1 1b1; end 179. 180. 5: // Send Auto Refresh Command 181. begin rCMD _AR; i i 1b1; end 182. 183. 6: // wait TRRC 63ns 184. if( C1 TRRC -1 ) begin C1 14d0; i i 1b1; end 185. else begin rCMD _NOP; C1 C1 1b1; end 186. 187. /********************/ 188. 189. 7: // Send LMR Cmd. Burst Read Write, 3b010 mean CAS latecy 3, Sequential, 1 burst length 190. begin rCMD _LMR; rBA 2b11; rA { 3d0, 1b0, 2d0, 3b011, 1b0, 3b000 }; i i 1b1; end 191. 192. 8: // Send 2 nop CLK for tMRD 193. if( C1 TMRD -1 ) begin C1 14d0; i i 1b1; end 194. else begin rCMD _NOP; C1 C1 1b1; end 195. 196. /********************/ 197. 198. 9: // Generate done signal 199. begin isDone 1b1; i i 1b1; end 200. 201. 10: 202. begin isDone 1b0; i 4d0; end 203. 204. endcase 205. 以上内容为部分核心操作。第157行的if( iCall[0] ) 表示余下内容为初始化。 206. assign { S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE } rCMD; 207. assign { S_BA, S_A } { rBA, rA }; 208. assign S_DQM rDQM; 209. assign S_DQ isOut ? iData : 16hzzzz; 210. assign oDone isDone; 211. assign oData D1; 212. 213. endmodule 以上内容为相关的输出驱动声明注意 iData直接驱动 S_DQ。 sdram_ctrlmod.v 图18.10 SDRAM控制模块的建模图。 前面说过该模块负责一些功能调用此外该模块也负责定时刷新的计算具体内容我们还是来看代码吧。 1. module sdram_ctrlmod 2. ( 3. input CLOCK, 4. input RESET, 5. input [1:0]iCall, // [1]Write, [0]Read 6. output [1:0]oDone, 7. output [3:0]oCall, 8. input iDone 9. ); 10. parameter WRITE 4d1, READ 4d4, REFRESH 4d7, INITIAL 4d8; 11. parameter TREF 11d1040; 12. 以上内容为相关的出入端声明。第10行是各个入口地址的常量声明第11行则是定时刷新的周期——7.8125us。 13. reg [3:0]i; 14. reg [10:0]C1; 15. reg [3:0]isCall; //[3]Write [2]Read [1]A.Refresh [0]Initial 16. reg [1:0]isDone; 17. 18. always ( posedge CLOCK or negedge RESET ) 19. if( !RESET ) 20. begin 21. i INITIAL; // Initial SDRam at first 22. C1 11d0; 23. isCall 4b0000; 24. isDone 2b00; 25. end 以上内容为相关的寄存器声明以及复位操作。第21行表示i首先会指向初始化。 26. else 27. case( i ) 28. 29. 0: // IDLE 30. if( C1 TREF ) begin C1 11d0; i REFRESH; end 31. else if( iCall[1] ) begin C1 C1 1b1; i WRITE; end 32. else if( iCall[0] ) begin C1 C1 1b1; i READ; end 33. else begin C1 C1 1b1; end 34. 35. /***********************/ 36. 以上内容为部分核心操作。步骤0为待机状态期间第33行的C1会一直递增如果期间没有任何读写操作而且C1的计数内容也超过 TREF那么C1会清零i指向REFRESH第30行。反之如果读写操作被使能i指向相关的步骤入口期间C1也会递增以示步骤翻转所用掉的时钟。 37. 1: //Write 38. if( iDone ) begin isCall[3] 1b0; C1 C1 1b1; i i 1b1; end 39. else begin isCall[3] 1b1; C1 C1 1b1; end 40. 41. 2: 42. begin isDone[1] 1b1; C1 C1 1b1; i i 1b1; end 43. 44. 3: 45. begin isDone[1] 1b0; C1 C1 1b1; i 4’d0; end 46. 47. /***********************/ 48.   以上内容为部分核心操作。步骤1~3是写操作。步骤1表示功能模块反馈完成信号之前C1会不停递增。当完成信号接收到手isCall[3]拉低C1递增i也递增。步骤2~3则是用来反馈写操作的完成信号期间C1也会递增。 49. 4: // Read 50. if( iDone ) begin isCall[2] 1b0; C1 C1 1b1; i i 1b1; end 51. else begin isCall[2] 1b1; C1 C1 1b1; end 52. 53. 5: 54. begin isDone[0] 1b1; C1 C1 1b1; i i 1b1; end 55. 56. 6: 57. begin isDone[0] 1b0; C1 C1 1b1; i 4d0; end 58. 59. /***********************/ 60. 以上内容为部分核心操作。步骤4~6是读操作。步骤4表示接收完成信号之前isCall[2]会不停拉高C1也会不停递增 ... 直至接收完成信号isCall[2]才会拉低然而C1也会递增。步骤5~6用反馈读操作的完成信号。 61. 7: // Auto Refresh 62. if( iDone ) begin isCall[1] 1b0; i 4d0; end 63. else begin isCall[1] 1b1; end 64. 65. /***********************/ 66. 以上内容为部分核心操作。步骤7是刷新操作接收完成信号之前 isCall[1] 会不停拉高直至接收完成信号为止isCall[1]才会拉低然后i指向步骤0。 67. 8: // Initial 68. if( iDone ) begin isCall[0] 1b0; i 4d0; end 69. else begin isCall[0] 1b1; end 70. 71. endcase 72. 73. assign oDone isDone; 74. assign oCall isCall; 75. 76. endmodule 以上内容为部分核心操作。步骤8用来执行初始化接收完成信号之前isCall[0]会不停拉高直至接收完成信号为止isCall[0]才会拉低然后i指向步骤0。第73~74行则是相关的输出驱动。整体而言除了读写操作必须反馈完成信号给上层以外其余的定期刷新还有初始化都是该内部操作所以不用反馈完成信号。 sdram_basemod.v 内容的连线部署完全依照图18.8。 1. module sdram_basemod 2. ( 3. input CLOCK, 4. input RESET, 5. 6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE, 7. output [1:0]S_BA, 8. output [12:0]S_A, 9. output [1:0]S_DQM, 10. inout [15:0]S_DQ, 11. 12. input [1:0]iCall, 13. output [1:0]oDone, 14. input [23:0]iAddr, 15. input [15:0]iData, 16. output [15:0]oData 17. ); 以上内容为相关的出入端声明第5~10行是顶层信号第12~16行是模块左右两边的信号。 18. wire [3:0]CallU1; // [3]Refresh, [2]Read, [1]Write, [0]Initial 19. 20. sdram_ctrlmod U1 21. ( 22. .CLOCK( CLOCK ), 23. .RESET( RESET ), 24. .iCall( iCall ), // top ,[1]Write [0]Read 25. .oDone( oDone ), // top ,[1]Write [0]Read 26. .oCall( CallU1 ), // U2 27. .iDone( DoneU2 ) // U2 28. ); 29. 以上内容为控制模块的实例化。 30. wire DoneU2; 31. 32. sdram_funcmod U2 33. ( 34. .CLOCK( CLOCK ), 35. .RESET( RESET ), 36. .S_CKE( S_CKE ), // top 37. .S_NCS( S_NCS ), // top 38. .S_NRAS( S_NRAS ), // top 39. .S_NCAS( S_NCAS ), // top 40. .S_NWE( S_NWE ), // top 41. .S_BA( S_BA ), // top 42. .S_A( S_A ), // top 43. .S_DQM( S_DQM ), // top 44. .S_DQ( S_DQ ), // top 45. .iCall( CallU1 ), // U1 46. .oDone( DoneU2 ), // U1 47. .iAddr( iAddr ), // top 48. .iData( iData ), // top 49. .oData( oData ) // top 50. ); 51. 52. endmodule 以上内容为功能模块的实例化。 sdram_demo.v 图18.11 实验十八的建模图。 图18.11是实验十八的建模图其中sdram_demo包含PLL模块核心操作还有SDRAM基础模块。PLL模块将50Mhz的时钟倍频为133Mhz而且左移210° 的CLOCK1还有133Mhz的CLOCK2它直接驱动S_CLK顶层信号。核心操作负责调用SDRAM基础模块并且将读写内容经由TXD发送出去。SDRAM基础模块左边的问答信号只有两位其中[1]为写 [0]为读具体内容我们还是来看代码吧。 1. module sdram_demo 2. ( 3. input CLOCK, 4. input RESET, 5. output S_CLK, 6. output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE, 7. output [12:0]S_A, 8. output [1:0]S_BA, 9. output [1:0]S_DQM, 10. inout [15:0]S_DQ, 11. output TXD 12. ); 以上内容为相关的出入端声明。 13. wire CLOCK1,CLOCK2; 14. 15. pll_module U1 16. ( 17. .inclk0 ( CLOCK ), // 50Mhz 18. .c0 ( CLOCK1 ), // 133Mhz -210 degree phase 19. .c1 ( CLOCK2 ) // 133Mhz 20. ); 21. 以上内容为PLL模块的实例化CLOCK1为133Mhz频率并且左移210°CLOCK2为133Mhz频率并且直接驱动 S_CLK。 22. wire [1:0]DoneU2; 23. wire [15:0]DataU2; 24. 25. sdram_basemod U2 26. ( 27. .CLOCK( CLOCK1 ), 28. .RESET( RESET ), 29. .S_CKE( S_CKE ), 30. .S_NCS( S_NCS ), 31. .S_NRAS( S_NRAS ), 32. .S_NCAS( S_NCAS ), 33. .S_NWE( S_NWE ), 34. .S_A( S_A ), 35. .S_BA( S_BA ), 36. .S_DQM( S_DQM ), 37. .S_DQ( S_DQ ), 38. .iCall( isCall ), 39. .oDone( DoneU2 ), 40. .iAddr( D1 ), 41. .iData( D2 ), 42. .oData( DataU2 ) 43. ); 44. 以上内容为SDRAM基础模块的实例化第40~41行表示 iAddr为D1驱动iData为D2驱动。 45. parameter B115K2 11d1157, TXFUNC 6d16; 46. 47. reg [5:0]i,Go; 48. reg [10:0]C1; 49. reg [23:0]D1; 50. reg [15:0]D2,D3; 51. reg [10:0]T; 52. reg [1:0]isCall; 53. reg rTXD; 54. 55. always ( posedge CLOCK1 or negedge RESET ) 56. if( !RESET ) 57. begin 58. i 6d0; 59. Go 6d0; 60. C1 11d0; 61. D1 24d0; 62. D2 16d0; 63. D3 16d0; 64. T 11d0; 65. isCall 2b00; 66. rTXD 1b1; 67. end 以上内容为相关的寄存器以及复位操作。第45行是波特率为115200还有伪函数入口的常量声明。   68. else 69. case( i ) 70. 71. 0: 72. if( DoneU2[1] ) begin isCall[1] 1b0; i i 1b1; end 73. else begin isCall[1] 1b1; D1 24d0; D2 16hABCD; end 74. 75. 1: 76. if( DoneU2[0] ) begin D3 DataU2; isCall[0] 1b0; i i 1b1; end 77. else begin D1 24d0; isCall[0] 1b1; end 78. 79. 2: 80. begin T { 2b11, D3[15:8], 1b0 }; i TXFUNC; Go i 1b1; end 81. 82. 3: 83. begin T { 2b11, D3[7:0], 1b0 }; i TXFUNC; Go i 1b1; end 84. 85. 4: 86. i i; 87. 88. /******************************/ 89. 以上内容为部分核心操作。步骤0将数据16’hABCD写入地址0。步骤1从地址0读出数据 16’hABCD并且暂存至D3。步骤2先发送D3的高8位步骤3则发送D3的低8位。步骤4发呆。 90. 16,17,18,19,20,21,22,23,24,25,26: 91. if( C1 B115K2 -1 ) begin C1 11d0; i i 1b1; end 92. else begin rTXD T[i - 16]; C1 C1 1b1; end 93. 94. 27: 95. i Go; 96. 97. endcase 98. 99. assign S_CLK CLOCK2; 100. assign TXD rTXD; 101. 102. endmodule 以上内容为部分核心操作。步骤16~27是发送一帧数据的伪函数。第99~100行则是相关的输出驱动。综合完毕并且下载程序如果串口调试软件出现 ABCD等两字节数据结果表示实验成功。 细节一完整的个体模块 SDRAM基础模块已经就绪完毕。 细节二其它时序参数 驱动SDRAM最大的收获莫过于学习各种稀奇古怪的时序参数虽然实验十六的IIC也有时序参数但是前者好比一粒面包屑后者则是一片面包两种时序参数有“体积”上的明确差距。笔者曾经说过时序参数即时间要求有第一层与第二层之分第一层时间要求正如IIC的时序参数打得像面包一样 ... 反之第二层时间要求宛如SDRAM的时序参数小得似面包屑一般。 SDRAM的时序参数除了 tRPTRRCTMRDCAS Latency 等这些东西以外它还有更为极为而且不能控制的时序参数。更确切来说这些时序参数都属于物理因数的范围 ... 难得有机会学习SDRAM笔者就稍微聊聊它们吧。 图18.12 时序参数①。 图18.12是读操作的部分时序当CL得到满足以后数据就会被吐出来其中 TLZTLOZ为 clock to data output in low-Z time。简单来说就是数据被出发沿吐出之前必须经过的延迟时间。根据手册133Mhz为1ns。 TAC为 access time from clock。简单来说就是有效时间。根据手册133Mhz为5.4ns TOH为 data out hold time。简单来说就是常见的 THOLD。根据手册133Mhz为2.5ns 图18.13 时序参数②。 图18.13是写操作的部分时序图然而重点家伙就是当中 T××S或者T××H。一般××是指数据的属性或者类别不过S与H都有相同的意义就是典型的TSETUP还有THOLD。笔者习惯称呼它们为寄存器特性因为只要任何一方得不到满足数据读入寄存器就得不到保证。寄存器特性好比哥布林一样数量常常多到令人喷饭如果一一分析会耗死爷爷不偿命。 图18.14 对外的理想时序。 为了用足一支竹竿扫尽一切笔者才故意向将CLOCK1左移180° 测试手气看看SDRAM能不能读出正确的结果如果不是再追加位移或者减少位移以致修正结果如图18.14所示。一般而言T××S或者T××H这些家伙都会得到满足然后乖乖就范。话虽如此同学们还须注意Verilog充其量只能满足第二层的时间要求却不能涉及解决其中我们往往只能依赖运气与直觉。当然我们可以借助静态时序分析的力量去搞定一切有兴趣的朋友请看《工具篇I》。转载于:https://www.cnblogs.com/alinx/p/4309688.html
http://www.yutouwan.com/news/171422/

相关文章:

  • 做三维特效的好网站网络游戏的利弊
  • 北京设计公司网站怎么进行网站备案
  • 网站关键词优化案例福州一站式品牌推广运营公司
  • 褚橙的网站建设软文写作范例大全
  • 十大设计创意产品网站高校网站建设需求分析报告
  • 建设商务网站的经济可行性分析石家庄网站系统开发
  • 深圳便宜的网站建设做网站的合同范文
  • 想做一个网站网页程序开发
  • 网站建设项目运作的可行性迁西县住房和城乡规划建设局网站
  • 成都网站建设软件机械网站案例分析
  • 南阳网站推广招聘市场调研ppt
  • dedecms仿站教程网站建设与运营第二次在线作业
  • 如何选定目标关键词及网站栏目名称的确定陕西网站建设哪家强
  • 辽宁城乡和住房建设部网站wordpress 适合程序员
  • 济南网站建设制作设计wordpress版本推荐
  • 怎么建设婚恋网站流程设计网站
  • 西安微信网站制作上海市虹口市容建设公司网站
  • 模板网站做外贸可以吗云服务器可以建设个人网站吗
  • 怎么做游戏推广网站网站建设界面ppt演示
  • 广东省建设执业资格注册中心官方网站小程序游戏代理加盟
  • 网站建设的内容规划电子手表网站
  • 网站制作属于什么专业做网站赚钱嘛
  • 电子商务公司网站建立WordPress输出当前网址
  • 软件开发工程师证seo是什么职业做什么的
  • wordpress文章展示余姚网站seo运营
  • 深圳做网站比较好北京公司网站建设服务
  • 太原做淘宝网站的成都市建设局官网
  • 外贸网站做开关的哪个好WordPress手机不显示
  • 学做网站论坛vip教程晋中市科技馆网站建设
  • j建设银行信用卡网站wordpress 插件 破解