PageRenderTime 381ms CodeModel.GetById 108ms RepoModel.GetById 1ms app.codeStats 2ms

/grlib-gpl-1.1.0-b4113/lib/micron/ddr/ddr3.v

https://github.com/shmele/leon3
V | 4136 lines | 3967 code | 79 blank | 90 comment | 223 complexity | 45b3fdda80adcde112979602458017ef MD5 | raw file
Possible License(s): GPL-2.0
  1. /****************************************************************************************
  2. *
  3. * File Name: ddr3.v
  4. * Version: 1.60
  5. * Model: BUS Functional
  6. *
  7. * Dependencies: ddr3_model_parameters.vh
  8. *
  9. * Description: Micron SDRAM DDR3 (Double Data Rate 3)
  10. *
  11. * Limitation: - doesn't check for average refresh timings
  12. * - positive ck and ck_n edges are used to form internal clock
  13. * - positive dqs and dqs_n edges are used to latch data
  14. * - test mode is not modeled
  15. * - Duty Cycle Corrector is not modeled
  16. * - Temperature Compensated Self Refresh is not modeled
  17. * - DLL off mode is not modeled.
  18. *
  19. * Note: - Set simulator resolution to "ps" accuracy
  20. * - Set DEBUG = 0 to disable $display messages
  21. *
  22. * Disclaimer This software code and all associated documentation, comments or other
  23. * of Warranty: information (collectively "Software") is provided "AS IS" without
  24. * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
  25. * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  26. * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
  27. * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
  28. * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
  29. * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
  30. * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
  31. * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
  32. * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
  33. * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
  34. * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
  35. * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
  36. * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
  37. * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
  38. * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  39. * DAMAGES. Because some jurisdictions prohibit the exclusion or
  40. * limitation of liability for consequential or incidental damages, the
  41. * above limitation may not apply to you.
  42. *
  43. * Copyright 2003 Micron Technology, Inc. All rights reserved.
  44. *
  45. * Rev Author Date Changes
  46. * ---------------------------------------------------------------------------------------
  47. * 0.41 JMK 05/12/06 Removed auto-precharge to power down error check.
  48. * 0.42 JMK 08/25/06 Created internal clock using ck and ck_n.
  49. * TDQS can only be enabled in EMR for x8 configurations.
  50. * CAS latency is checked vs frequency when DLL locks.
  51. * Improved checking of DQS during writes.
  52. * Added true BL4 operation.
  53. * 0.43 JMK 08/14/06 Added checking for setting reserved bits in Mode Registers.
  54. * Added ODTS Readout.
  55. * Replaced tZQCL with tZQinit and tZQoper
  56. * Fixed tWRPDEN and tWRAPDEN during BC4MRS and BL4MRS.
  57. * Added tRFC checking for Refresh to Power-Down Re-Entry.
  58. * Added tXPDLL checking for Power-Down Exit to Refresh to Power-Down Entry
  59. * Added Clock Frequency Change during Precharge Power-Down.
  60. * Added -125x speed grades.
  61. * Fixed tRCD checking during Write.
  62. * 1.00 JMK 05/11/07 Initial release
  63. * 1.10 JMK 06/26/07 Fixed ODTH8 check during BLOTF
  64. * Removed temp sensor readout from MPR
  65. * Updated initialization sequence
  66. * Updated timing parameters
  67. * 1.20 JMK 09/05/07 Updated clock frequency change
  68. * Added ddr3_dimm module
  69. * 1.30 JMK 01/23/08 Updated timing parameters
  70. * 1.40 JMK 12/02/08 Added support for DDR3-1866 and DDR3-2133
  71. * renamed ddr3_dimm.v to ddr3_module.v and added SODIMM support.
  72. * Added multi-chip package model support in ddr3_mcp.v
  73. * 1.50 JMK 05/04/08 Added 1866 and 2133 speed grades.
  74. * 1.60 MYY 07/10/09 Merging of 1.50 version and pre-1.0 version changes
  75. *****************************************************************************************/
  76. // DO NOT CHANGE THE TIMESCALE
  77. // MAKE SURE YOUR SIMULATOR USES "PS" RESOLUTION
  78. `timescale 1ps / 1ps
  79. // model flags
  80. // `define MODEL_PASR
  81. module ddr3 (
  82. rst_n,
  83. ck,
  84. ck_n,
  85. cke,
  86. cs_n,
  87. ras_n,
  88. cas_n,
  89. we_n,
  90. dm_tdqs,
  91. ba,
  92. addr,
  93. dq,
  94. dqs,
  95. dqs_n,
  96. tdqs_n,
  97. odt
  98. );
  99. `define x1Gb
  100. `define sg187E
  101. `define x16
  102. /* `include "ddr3_model_parameters.vh" */
  103. /****************************************************************************************
  104. *
  105. * Disclaimer This software code and all associated documentation, comments or other
  106. * of Warranty: information (collectively "Software") is provided "AS IS" without
  107. * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
  108. * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  109. * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
  110. * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
  111. * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
  112. * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
  113. * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
  114. * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
  115. * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
  116. * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
  117. * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
  118. * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
  119. * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
  120. * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
  121. * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  122. * DAMAGES. Because some jurisdictions prohibit the exclusion or
  123. * limitation of liability for consequential or incidental damages, the
  124. * above limitation may not apply to you.
  125. *
  126. * Copyright 2003 Micron Technology, Inc. All rights reserved.
  127. *
  128. ****************************************************************************************/
  129. // Parameters current with 1Gb and 2Gb datasheet rev D
  130. // Timing parameters based on Speed Grade
  131. // SYMBOL UNITS DESCRIPTION
  132. // ------ ----- -----------
  133. `ifdef x1Gb // 1Gb parameters
  134. `ifdef sg094E // sg094E is equivalent to the JEDEC DDR3-2133 (13-13-13) speed bin
  135. parameter TCK_MIN = 937.5; // tCK ps Minimum Clock Cycle Time
  136. parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
  137. parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
  138. parameter TERR_2PER = 73; // tERR(2per) ps Accumulated Error (2-cycle)
  139. parameter TERR_3PER = 85; // tERR(3per) ps Accumulated Error (3-cycle)
  140. parameter TERR_4PER = 98; // tERR(4per) ps Accumulated Error (4-cycle)
  141. parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
  142. parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
  143. parameter TERR_7PER = 117; // tERR(7per) ps Accumulated Error (7-cycle)
  144. parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
  145. parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
  146. parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
  147. parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
  148. parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
  149. parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
  150. parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
  151. parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  152. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  153. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  154. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  155. parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
  156. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  157. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  158. parameter TDIPW = 275; // tDIPW ps DQ and DM input Pulse Width
  159. parameter TIPW = 455; // tIPW ps Control and Address input Pulse Width
  160. parameter TIS = 35; // tIS ps Input Setup Time
  161. parameter TIH = 75; // tIH ps Input Hold Time
  162. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  163. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  164. parameter TRCD = 12187; // tRCD ps Active to Read/Write command time
  165. parameter TRP = 12187; // tRP ps Precharge command period
  166. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  167. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  168. parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
  169. parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
  170. parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
  171. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  172. parameter TAA_MIN = 12187; // TAA ps Internal READ command to first data
  173. parameter CL_TIME = 12187; // CL ps Minimum CAS Latency
  174. `else `ifdef sg094 // sg094 is equivalent to the JEDEC DDR3-2133 (14-14-14) speed bin
  175. parameter TCK_MIN = 937.5; // tCK ps Minimum Clock Cycle Time
  176. parameter TJIT_PER = 50; // tJIT(per) ps Period JItter
  177. parameter TJIT_CC = 100; // tJIT(cc) ps Cycle to Cycle jitter
  178. parameter TERR_2PER = 73; // tERR(2per) ps Accumulated Error (2-cycle)
  179. parameter TERR_3PER = 85; // tERR(3per) ps Accumulated Error (3-cycle)
  180. parameter TERR_4PER = 98; // tERR(4per) ps Accumulated Error (4-cycle)
  181. parameter TERR_5PER = 105; // tERR(5per) ps Accumulated Error (5-cycle)
  182. parameter TERR_6PER = 111; // tERR(6per) ps Accumulated Error (6-cycle)
  183. parameter TERR_7PER = 117; // tERR(7per) ps Accumulated Error (7-cycle)
  184. parameter TERR_8PER = 121; // tERR(8per) ps Accumulated Error (8-cycle)
  185. parameter TERR_9PER = 125; // tERR(9per) ps Accumulated Error (9-cycle)
  186. parameter TERR_10PER = 128; // tERR(10per)ps Accumulated Error (10-cycle)
  187. parameter TERR_11PER = 132; // tERR(11per)ps Accumulated Error (11-cycle)
  188. parameter TERR_12PER = 134; // tERR(12per)ps Accumulated Error (12-cycle)
  189. parameter TDS = 5; // tDS ps DQ and DM input setup time relative to DQS
  190. parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
  191. parameter TDQSQ = 70; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  192. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  193. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  194. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  195. parameter TDQSCK = 175; // tDQSCK ps DQS output access time from CK/CK#
  196. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  197. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  198. parameter TDIPW = 275; // tDIPW ps DQ and DM input Pulse Width
  199. parameter TIPW = 455; // tIPW ps Control and Address input Pulse Width
  200. parameter TIS = 35; // tIS ps Input Setup Time
  201. parameter TIH = 75; // tIH ps Input Hold Time
  202. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  203. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  204. parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
  205. parameter TRP = 13125; // tRP ps Precharge command period
  206. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  207. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  208. parameter TAON = 180; // tAON ps RTT turn-on from ODTLon reference
  209. parameter TWLS = 122; // tWLS ps Setup time for tDQS flop
  210. parameter TWLH = 122; // tWLH ps Hold time of tDQS flop
  211. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  212. parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
  213. parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
  214. `else `ifdef sg107F // sg107F is equivalent to the JEDEC DDR3-1866 (12-12-12) speed bin
  215. parameter TCK_MIN = 15e3/14; // tCK ps Minimum Clock Cycle Time
  216. parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
  217. parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
  218. parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
  219. parameter TERR_3PER = 103; // tERR(3per) ps Accumulated Error (3-cycle)
  220. parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
  221. parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
  222. parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
  223. parameter TERR_7PER = 140; // tERR(7per) ps Accumulated Error (7-cycle)
  224. parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
  225. parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
  226. parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
  227. parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
  228. parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
  229. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  230. parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
  231. parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  232. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  233. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  234. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  235. parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
  236. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  237. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  238. parameter TDIPW = 300; // tDIPW ps DQ and DM input Pulse Width
  239. parameter TIPW = 505; // tIPW ps Control and Address input Pulse Width
  240. parameter TIS = 50; // tIS ps Input Setup Time
  241. parameter TIH = 100; // tIH ps Input Hold Time
  242. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  243. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  244. parameter TRCD = 12857; // tRCD ps Active to Read/Write command time
  245. parameter TRP = 12857; // tRP ps Precharge command period
  246. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  247. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  248. parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
  249. parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
  250. parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
  251. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  252. parameter TAA_MIN = 12857; // TAA ps Internal READ command to first data
  253. parameter CL_TIME = 12857; // CL ps Minimum CAS Latency
  254. `else `ifdef sg107E // sg107E is equivalent to the JEDEC DDR3-1866 (13-13-13) speed bin
  255. parameter TCK_MIN = 15e3/14; // tCK ps Minimum Clock Cycle Time
  256. parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
  257. parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
  258. parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
  259. parameter TERR_3PER = 103; // tERR(3per) ps Accumulated Error (3-cycle)
  260. parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
  261. parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
  262. parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
  263. parameter TERR_7PER = 140; // tERR(7per) ps Accumulated Error (7-cycle)
  264. parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
  265. parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
  266. parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
  267. parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
  268. parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
  269. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  270. parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
  271. parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  272. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  273. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  274. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  275. parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
  276. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  277. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  278. parameter TDIPW = 300; // tDIPW ps DQ and DM input Pulse Width
  279. parameter TIPW = 505; // tIPW ps Control and Address input Pulse Width
  280. parameter TIS = 50; // tIS ps Input Setup Time
  281. parameter TIH = 100; // tIH ps Input Hold Time
  282. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  283. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  284. parameter TRCD = 13928; // tRCD ps Active to Read/Write command time
  285. parameter TRP = 13928; // tRP ps Precharge command period
  286. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  287. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  288. parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
  289. parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
  290. parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
  291. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  292. parameter TAA_MIN = 13928; // TAA ps Internal READ command to first data
  293. parameter CL_TIME = 13928; // CL ps Minimum CAS Latency
  294. `else `ifdef sg107 // sg107 is equivalent to the JEDEC DDR3-1866 (14-14-14) speed bin
  295. parameter TCK_MIN = 15e3/14; // tCK ps Minimum Clock Cycle Time
  296. parameter TJIT_PER = 60; // tJIT(per) ps Period JItter
  297. parameter TJIT_CC = 120; // tJIT(cc) ps Cycle to Cycle jitter
  298. parameter TERR_2PER = 88; // tERR(2per) ps Accumulated Error (2-cycle)
  299. parameter TERR_3PER = 103; // tERR(3per) ps Accumulated Error (3-cycle)
  300. parameter TERR_4PER = 117; // tERR(4per) ps Accumulated Error (4-cycle)
  301. parameter TERR_5PER = 126; // tERR(5per) ps Accumulated Error (5-cycle)
  302. parameter TERR_6PER = 133; // tERR(6per) ps Accumulated Error (6-cycle)
  303. parameter TERR_7PER = 140; // tERR(7per) ps Accumulated Error (7-cycle)
  304. parameter TERR_8PER = 145; // tERR(8per) ps Accumulated Error (8-cycle)
  305. parameter TERR_9PER = 150; // tERR(9per) ps Accumulated Error (9-cycle)
  306. parameter TERR_10PER = 154; // tERR(10per)ps Accumulated Error (10-cycle)
  307. parameter TERR_11PER = 158; // tERR(11per)ps Accumulated Error (11-cycle)
  308. parameter TERR_12PER = 161; // tERR(12per)ps Accumulated Error (12-cycle)
  309. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  310. parameter TDH = 20; // tDH ps DQ and DM input hold time relative to DQS
  311. parameter TDQSQ = 80; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  312. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  313. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  314. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  315. parameter TDQSCK = 200; // tDQSCK ps DQS output access time from CK/CK#
  316. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  317. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  318. parameter TDIPW = 300; // tDIPW ps DQ and DM input Pulse Width
  319. parameter TIPW = 505; // tIPW ps Control and Address input Pulse Width
  320. parameter TIS = 50; // tIS ps Input Setup Time
  321. parameter TIH = 100; // tIH ps Input Hold Time
  322. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  323. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  324. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  325. parameter TRP = 15000; // tRP ps Precharge command period
  326. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  327. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  328. parameter TAON = 200; // tAON ps RTT turn-on from ODTLon reference
  329. parameter TWLS = 140; // tWLS ps Setup time for tDQS flop
  330. parameter TWLH = 140; // tWLH ps Hold time of tDQS flop
  331. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  332. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  333. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  334. `else `ifdef sg125F // sg125F is equivalent to the JEDEC DDR3-1600 (9-9-9) speed bin
  335. parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
  336. parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
  337. parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
  338. parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
  339. parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
  340. parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
  341. parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
  342. parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
  343. parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
  344. parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
  345. parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
  346. parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
  347. parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
  348. parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
  349. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  350. parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
  351. parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  352. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  353. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  354. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  355. parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
  356. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  357. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  358. parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
  359. parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
  360. parameter TIS = 170; // tIS ps Input Setup Time
  361. parameter TIH = 120; // tIH ps Input Hold Time
  362. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  363. parameter TRC = 46250; // tRC ps Active to Active/Auto Refresh command time
  364. parameter TRCD = 11250; // tRCD ps Active to Read/Write command time
  365. parameter TRP = 11250; // tRP ps Precharge command period
  366. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  367. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  368. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  369. parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
  370. parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
  371. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  372. parameter TAA_MIN = 11250; // TAA ps Internal READ command to first data
  373. parameter CL_TIME = 11250; // CL ps Minimum CAS Latency
  374. `else `ifdef sg125E // sg125E is equivalent to the JEDEC DDR3-1600 (10-10-10) speed bin
  375. parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
  376. parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
  377. parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
  378. parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
  379. parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
  380. parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
  381. parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
  382. parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
  383. parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
  384. parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
  385. parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
  386. parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
  387. parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
  388. parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
  389. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  390. parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
  391. parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  392. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  393. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  394. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  395. parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
  396. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  397. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  398. parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
  399. parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
  400. parameter TIS = 170; // tIS ps Input Setup Time
  401. parameter TIH = 120; // tIH ps Input Hold Time
  402. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  403. parameter TRC = 47500; // tRC ps Active to Active/Auto Refresh command time
  404. parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
  405. parameter TRP = 12500; // tRP ps Precharge command period
  406. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  407. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  408. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  409. parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
  410. parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
  411. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  412. parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
  413. parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
  414. `else `ifdef sg125 // sg125 is equivalent to the JEDEC DDR3-1600 (11-11-11) speed bin
  415. parameter TCK_MIN = 1250; // tCK ps Minimum Clock Cycle Time
  416. parameter TJIT_PER = 70; // tJIT(per) ps Period JItter
  417. parameter TJIT_CC = 140; // tJIT(cc) ps Cycle to Cycle jitter
  418. parameter TERR_2PER = 103; // tERR(2per) ps Accumulated Error (2-cycle)
  419. parameter TERR_3PER = 122; // tERR(3per) ps Accumulated Error (3-cycle)
  420. parameter TERR_4PER = 136; // tERR(4per) ps Accumulated Error (4-cycle)
  421. parameter TERR_5PER = 147; // tERR(5per) ps Accumulated Error (5-cycle)
  422. parameter TERR_6PER = 155; // tERR(6per) ps Accumulated Error (6-cycle)
  423. parameter TERR_7PER = 163; // tERR(7per) ps Accumulated Error (7-cycle)
  424. parameter TERR_8PER = 169; // tERR(8per) ps Accumulated Error (8-cycle)
  425. parameter TERR_9PER = 175; // tERR(9per) ps Accumulated Error (9-cycle)
  426. parameter TERR_10PER = 180; // tERR(10per)ps Accumulated Error (10-cycle)
  427. parameter TERR_11PER = 184; // tERR(11per)ps Accumulated Error (11-cycle)
  428. parameter TERR_12PER = 188; // tERR(12per)ps Accumulated Error (12-cycle)
  429. parameter TDS = 10; // tDS ps DQ and DM input setup time relative to DQS
  430. parameter TDH = 45; // tDH ps DQ and DM input hold time relative to DQS
  431. parameter TDQSQ = 100; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  432. parameter TDQSS = 0.27; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  433. parameter TDSS = 0.18; // tDSS tCK DQS falling edge to CLK rising (setup time)
  434. parameter TDSH = 0.18; // tDSH tCK DQS falling edge from CLK rising (hold time)
  435. parameter TDQSCK = 225; // tDQSCK ps DQS output access time from CK/CK#
  436. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  437. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  438. parameter TDIPW = 360; // tDIPW ps DQ and DM input Pulse Width
  439. parameter TIPW = 560; // tIPW ps Control and Address input Pulse Width
  440. parameter TIS = 170; // tIS ps Input Setup Time
  441. parameter TIH = 120; // tIH ps Input Hold Time
  442. parameter TRAS_MIN = 35000; // tRAS ps Minimum Active to Precharge command time
  443. parameter TRC = 48750; // tRC ps Active to Active/Auto Refresh command time
  444. parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
  445. parameter TRP = 13125; // tRP ps Precharge command period
  446. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  447. parameter TCKE = 5000; // tCKE ps CKE minimum high or low pulse width
  448. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  449. parameter TWLS = 165; // tWLS ps Setup time for tDQS flop
  450. parameter TWLH = 165; // tWLH ps Hold time of tDQS flop
  451. parameter TWLO = 7500; // tWLO ps Write levelization output delay
  452. parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
  453. parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
  454. `else `ifdef sg15E // sg15E is equivalent to the JEDEC DDR3-1333H (9-9-9) speed bin
  455. parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
  456. parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
  457. parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
  458. parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
  459. parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
  460. parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
  461. parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
  462. parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
  463. parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
  464. parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
  465. parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
  466. parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
  467. parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
  468. parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
  469. parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
  470. parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
  471. parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  472. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  473. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  474. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  475. parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
  476. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  477. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  478. parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
  479. parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
  480. parameter TIS = 190; // tIS ps Input Setup Time
  481. parameter TIH = 140; // tIH ps Input Hold Time
  482. parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
  483. parameter TRC = 49500; // tRC ps Active to Active/Auto Refresh command time
  484. parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
  485. parameter TRP = 13125; // tRP ps Precharge command period
  486. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  487. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  488. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  489. parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
  490. parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
  491. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  492. parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
  493. parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
  494. `else `ifdef sg15 // sg15 is equivalent to the JEDEC DDR3-1333J (10-10-10) speed bin
  495. parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
  496. parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
  497. parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
  498. parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
  499. parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
  500. parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
  501. parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
  502. parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
  503. parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
  504. parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
  505. parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
  506. parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
  507. parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
  508. parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
  509. parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
  510. parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
  511. parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  512. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  513. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  514. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  515. parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
  516. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  517. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  518. parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
  519. parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
  520. parameter TIS = 190; // tIS ps Input Setup Time
  521. parameter TIH = 140; // tIH ps Input Hold Time
  522. parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
  523. parameter TRC = 51000; // tRC ps Active to Active/Auto Refresh command time
  524. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  525. parameter TRP = 15000; // tRP ps Precharge command period
  526. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  527. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  528. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  529. parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
  530. parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
  531. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  532. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  533. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  534. `else `ifdef sg187E // sg187E is equivalent to the JEDEC DDR3-1066F (7-7-7) speed bin
  535. parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
  536. parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
  537. parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
  538. parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
  539. parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
  540. parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
  541. parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
  542. parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
  543. parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
  544. parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
  545. parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
  546. parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
  547. parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
  548. parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
  549. parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
  550. parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
  551. parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  552. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  553. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  554. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  555. parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
  556. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  557. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  558. parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
  559. parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
  560. parameter TIS = 275; // tIS ps Input Setup Time
  561. parameter TIH = 200; // tIH ps Input Hold Time
  562. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  563. parameter TRC = 50625; // tRC ps Active to Active/Auto Refresh command time
  564. parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
  565. parameter TRP = 13125; // tRP ps Precharge command period
  566. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  567. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  568. parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
  569. parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
  570. parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
  571. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  572. parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
  573. parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
  574. `else `ifdef sg187 // sg187 is equivalent to the JEDEC DDR3-1066G (8-8-8) speed bin
  575. parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
  576. parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
  577. parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
  578. parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
  579. parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
  580. parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
  581. parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
  582. parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
  583. parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
  584. parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
  585. parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
  586. parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
  587. parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
  588. parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
  589. parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
  590. parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
  591. parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  592. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  593. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  594. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  595. parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
  596. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  597. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  598. parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
  599. parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
  600. parameter TIS = 275; // tIS ps Input Setup Time
  601. parameter TIH = 200; // tIH ps Input Hold Time
  602. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  603. parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
  604. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  605. parameter TRP = 15000; // tRP ps Precharge command period
  606. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  607. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  608. parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
  609. parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
  610. parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
  611. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  612. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  613. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  614. `else `ifdef sg25E // sg25E is equivalent to the JEDEC DDR3-800D (5-5-5) speed bin
  615. parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
  616. parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
  617. parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
  618. parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
  619. parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
  620. parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
  621. parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
  622. parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
  623. parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
  624. parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
  625. parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
  626. parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
  627. parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
  628. parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
  629. parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
  630. parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
  631. parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  632. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  633. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  634. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  635. parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
  636. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  637. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  638. parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
  639. parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
  640. parameter TIS = 350; // tIS ps Input Setup Time
  641. parameter TIH = 275; // tIH ps Input Hold Time
  642. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  643. parameter TRC = 50000; // tRC ps Active to Active/Auto Refresh command time
  644. parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
  645. parameter TRP = 12500; // tRP ps Precharge command period
  646. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  647. parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
  648. parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
  649. parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
  650. parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
  651. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  652. parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
  653. parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
  654. `else `define sg25 // sg25 is equivalent to the JEDEC DDR3-800E (6-6-6) speed bin
  655. parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
  656. parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
  657. parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
  658. parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
  659. parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
  660. parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
  661. parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
  662. parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
  663. parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
  664. parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
  665. parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
  666. parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
  667. parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
  668. parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
  669. parameter TDS = 125; // tDS ps DQ and DM input setup time relative to DQS
  670. parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
  671. parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  672. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  673. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  674. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  675. parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
  676. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  677. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  678. parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
  679. parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
  680. parameter TIS = 350; // tIS ps Input Setup Time
  681. parameter TIH = 275; // tIH ps Input Hold Time
  682. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  683. parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
  684. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  685. parameter TRP = 15000; // tRP ps Precharge command period
  686. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  687. parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
  688. parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
  689. parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
  690. parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
  691. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  692. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  693. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  694. `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
  695. `ifdef x16
  696. `ifdef sg094E
  697. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  698. parameter TFAW = 30000; // tFAW ps (2KB page size) Four Bank Activate window
  699. `else `ifdef sg094
  700. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  701. parameter TFAW = 30000; // tFAW ps (2KB page size) Four Bank Activate window
  702. `else `ifdef sg107F
  703. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  704. parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
  705. `else `ifdef sg107E
  706. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  707. parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
  708. `else `ifdef sg107
  709. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  710. parameter TFAW = 35000; // tFAW ps (2KB page size) Four Bank Activate window
  711. `else `ifdef sg125F
  712. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  713. parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
  714. `else `ifdef sg125E
  715. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  716. parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
  717. `else `ifdef sg125
  718. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  719. parameter TFAW = 40000; // tFAW ps (2KB page size) Four Bank Activate window
  720. `else `ifdef sg15E
  721. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  722. parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
  723. `else `ifdef sg15
  724. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  725. parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
  726. `else // sg187E, sg187, sg25, sg25E
  727. parameter TRRD = 10000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  728. parameter TFAW = 50000; // tFAW ps (2KB page size) Four Bank Activate window
  729. `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
  730. `else // x4, x8
  731. `ifdef sg094E
  732. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  733. parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
  734. `else `ifdef sg094
  735. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  736. parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
  737. `else `ifdef sg107F
  738. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  739. parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
  740. `else `ifdef sg107E
  741. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  742. parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
  743. `else `ifdef sg107
  744. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  745. parameter TFAW = 25000; // tFAW ps (1KB page size) Four Bank Activate window
  746. `else `ifdef sg125F
  747. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  748. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  749. `else `ifdef sg125E
  750. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  751. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  752. `else `ifdef sg125
  753. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  754. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  755. `else `ifdef sg15E
  756. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  757. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  758. `else `ifdef sg15
  759. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  760. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  761. `else `ifdef sg187E
  762. parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  763. parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
  764. `else `ifdef sg187
  765. parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  766. parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
  767. `else // sg25, sg25E
  768. parameter TRRD = 10000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  769. parameter TFAW = 40000; // tFAW ps (1KB page size) Four Bank Activate window
  770. `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
  771. `endif
  772. // Timing Parameters
  773. // Mode Register
  774. parameter CL_MIN = 5; // CL tCK Minimum CAS Latency
  775. parameter CL_MAX = 14; // CL tCK Maximum CAS Latency
  776. parameter AL_MIN = 0; // AL tCK Minimum Additive Latency
  777. parameter AL_MAX = 2; // AL tCK Maximum Additive Latency
  778. parameter WR_MIN = 5; // WR tCK Minimum Write Recovery
  779. parameter WR_MAX = 16; // WR tCK Maximum Write Recovery
  780. parameter BL_MIN = 4; // BL tCK Minimum Burst Length
  781. parameter BL_MAX = 8; // BL tCK Minimum Burst Length
  782. parameter CWL_MIN = 5; // CWL tCK Minimum CAS Write Latency
  783. parameter CWL_MAX = 10; // CWL tCK Maximum CAS Write Latency
  784. // Clock
  785. parameter TCK_MAX = 3300; // tCK ps Maximum Clock Cycle Time
  786. parameter TCH_AVG_MIN = 0.47; // tCH tCK Minimum Clock High-Level Pulse Width
  787. parameter TCL_AVG_MIN = 0.47; // tCL tCK Minimum Clock Low-Level Pulse Width
  788. parameter TCH_AVG_MAX = 0.53; // tCH tCK Maximum Clock High-Level Pulse Width
  789. parameter TCL_AVG_MAX = 0.53; // tCL tCK Maximum Clock Low-Level Pulse Width
  790. parameter TCH_ABS_MIN = 0.43; // tCH tCK Minimum Clock High-Level Pulse Width
  791. parameter TCL_ABS_MIN = 0.43; // tCL tCK Maximum Clock Low-Level Pulse Width
  792. parameter TCKE_TCK = 3; // tCKE tCK CKE minimum high or low pulse width
  793. parameter TAA_MAX = 20000; // TAA ps Internal READ command to first data
  794. // Data OUT
  795. parameter TQH = 0.38; // tQH ps DQ output hold time from DQS, DQS#
  796. // Data Strobe OUT
  797. parameter TRPRE = 0.90; // tRPRE tCK DQS Read Preamble
  798. parameter TRPST = 0.30; // tRPST tCK DQS Read Postamble
  799. // Data Strobe IN
  800. parameter TDQSH = 0.45; // tDQSH tCK DQS input High Pulse Width
  801. parameter TDQSL = 0.45; // tDQSL tCK DQS input Low Pulse Width
  802. parameter TWPRE = 0.90; // tWPRE tCK DQS Write Preamble
  803. parameter TWPST = 0.30; // tWPST tCK DQS Write Postamble
  804. // Command and Address
  805. parameter TZQCS = 64; // tZQCS tCK ZQ Cal (Short) time
  806. parameter TZQINIT = 512; // tZQinit tCK ZQ Cal (Long) time
  807. parameter TZQOPER = 256; // tZQoper tCK ZQ Cal (Long) time
  808. parameter TCCD = 4; // tCCD tCK Cas to Cas command delay
  809. parameter TCCD_DG = 2; // tCCD_DG tCK Cas to Cas command delay to different group
  810. parameter TRAS_MAX = 60e9; // tRAS ps Maximum Active to Precharge command time
  811. parameter TWR = 15000; // tWR ps Write recovery time
  812. parameter TMRD = 4; // tMRD tCK Load Mode Register command cycle time
  813. parameter TMOD = 15000; // tMOD ps LOAD MODE to non-LOAD MODE command cycle time
  814. parameter TMOD_TCK = 12; // tMOD tCK LOAD MODE to non-LOAD MODE command cycle time
  815. parameter TRRD_TCK = 4; // tRRD tCK Active bank a to Active bank b command time
  816. parameter TRRD_DG = 3000; // tRRD_DG ps Active bank a to Active bank b command time to different group
  817. parameter TRRD_DG_TCK = 2; // tRRD_DG tCK Active bank a to Active bank b command time to different group
  818. parameter TRTP = 7500; // tRTP ps Read to Precharge command delay
  819. parameter TRTP_TCK = 4; // tRTP tCK Read to Precharge command delay
  820. parameter TWTR = 7500; // tWTR ps Write to Read command delay
  821. parameter TWTR_DG = 3750; // tWTR_DG ps Write to Read command delay to different group
  822. parameter TWTR_TCK = 4; // tWTR tCK Write to Read command delay
  823. parameter TWTR_DG_TCK = 2; // tWTR_DG tCK Write to Read command delay to different group
  824. parameter TDLLK = 512; // tDLLK tCK DLL locking time
  825. // Refresh - 1Gb
  826. parameter TRFC_MIN = 110000; // tRFC ps Refresh to Refresh Command interval minimum value
  827. parameter TRFC_MAX =70312500; // tRFC ps Refresh to Refresh Command Interval maximum value
  828. // Power Down
  829. parameter TXP_TCK = 3; // tXP tCK Exit power down to a valid command
  830. parameter TXPDLL = 24000; // tXPDLL ps Exit precharge power down to READ or WRITE command (DLL-off mode)
  831. parameter TXPDLL_TCK = 10; // tXPDLL tCK Exit precharge power down to READ or WRITE command (DLL-off mode)
  832. parameter TACTPDEN = 1; // tACTPDEN tCK Timing of last ACT command to power down entry
  833. parameter TPRPDEN = 1; // tPREPDEN tCK Timing of last PRE command to power down entry
  834. parameter TREFPDEN = 1; // tARPDEN tCK Timing of last REFRESH command to power down entry
  835. parameter TCPDED = 1; // tCPDED tCK Command pass disable/enable delay
  836. parameter TPD_MAX =TRFC_MAX; // tPD ps Power-down entry-to-exit timing
  837. parameter TXPR = 120000; // tXPR ps Exit Reset from CKE assertion to a valid command
  838. parameter TXPR_TCK = 5; // tXPR tCK Exit Reset from CKE assertion to a valid command
  839. // Self Refresh
  840. parameter TXS = 120000; // tXS ps Exit self refesh to a non-read or write command
  841. parameter TXS_TCK = 5; // tXS tCK Exit self refesh to a non-read or write command
  842. parameter TXSDLL = TDLLK; // tXSRD tCK Exit self refresh to a read or write command
  843. parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit.
  844. parameter TCKSRE = 10000; // tCKSRE ps Valid Clock requirement after self refresh entry (SRE)
  845. parameter TCKSRE_TCK = 5; // tCKSRE tCK Valid Clock requirement after self refresh entry (SRE)
  846. parameter TCKSRX = 10000; // tCKSRX ps Valid Clock requirement prior to self refresh exit (SRX)
  847. parameter TCKSRX_TCK = 5; // tCKSRX tCK Valid Clock requirement prior to self refresh exit (SRX)
  848. parameter TCKESR_TCK = 4; // tCKESR tCK Minimum CKE low width for Self Refresh entry to exit timing
  849. // ODT
  850. parameter TAOF = 0.7; // tAOF tCK RTT turn-off from ODTLoff reference
  851. parameter TAONPD = 8500; // tAONPD ps Asynchronous RTT turn-on delay (Power-Down with DLL frozen)
  852. parameter TAOFPD = 8500; // tAONPD ps Asynchronous RTT turn-off delay (Power-Down with DLL frozen)
  853. parameter ODTH4 = 4; // ODTH4 tCK ODT minimum HIGH time after ODT assertion or write (BL4)
  854. parameter ODTH8 = 6; // ODTH8 tCK ODT minimum HIGH time after write (BL8)
  855. parameter TADC = 0.7; // tADC tCK RTT dynamic change skew
  856. // Write Levelization
  857. parameter TWLMRD = 40; // tWLMRD tCK First DQS pulse rising edge after tDQSS margining mode is programmed
  858. parameter TWLDQSEN = 25; // tWLDQSEN tCK DQS/DQS delay after tDQSS margining mode is programmed
  859. parameter TWLOE = 2000; // tWLOE ps Write levelization output error
  860. // Size Parameters based on Part Width
  861. `ifdef x4
  862. parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
  863. parameter ADDR_BITS = 14; // MAX Address Bits
  864. parameter ROW_BITS = 14; // Set this parameter to control how many Address bits are used
  865. parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used
  866. parameter DQ_BITS = 4; // Set this parameter to control how many Data bits are used **Same as part bit width**
  867. parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
  868. `else `ifdef x8
  869. parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
  870. parameter ADDR_BITS = 14; // MAX Address Bits
  871. parameter ROW_BITS = 14; // Set this parameter to control how many Address bits are used
  872. parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
  873. parameter DQ_BITS = 8; // Set this parameter to control how many Data bits are used **Same as part bit width**
  874. parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
  875. `else `define x16
  876. parameter DM_BITS = 2; // Set this parameter to control how many Data Mask bits are used
  877. parameter ADDR_BITS = 13; // MAX Address Bits
  878. parameter ROW_BITS = 13; // Set this parameter to control how many Address bits are used
  879. parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
  880. parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used **Same as part bit width**
  881. parameter DQS_BITS = 2; // Set this parameter to control how many Dqs bits are used
  882. `endif `endif
  883. // Size Parameters
  884. parameter BA_BITS = 3; // Set this parmaeter to control how many Bank Address bits are used
  885. parameter MEM_BITS = 15; // Set this parameter to control how many write data bursts can be stored in memory. The default is 2^10=1024.
  886. parameter AP = 10; // the address bit that controls auto-precharge and precharge-all
  887. parameter BC = 12; // the address bit that controls burst chop
  888. parameter BL_BITS = 3; // the number of bits required to count to BL_MAX
  889. parameter BO_BITS = 2; // the number of Burst Order Bits
  890. `ifdef QUAD_RANK
  891. `define DUAL_RANK // also define DUAL_RANK
  892. parameter CS_BITS = 4; // Number of Chip Select Bits
  893. parameter RANKS = 4; // Number of Chip Selects
  894. `else `ifdef DUAL_RANK
  895. parameter CS_BITS = 2; // Number of Chip Select Bits
  896. parameter RANKS = 2; // Number of Chip Selects
  897. `else
  898. parameter CS_BITS = 2; // Number of Chip Select Bits
  899. parameter RANKS = 1; // Number of Chip Selects
  900. `endif `endif
  901. // Simulation parameters
  902. parameter RZQ = 240; // termination resistance
  903. parameter PRE_DEF_PAT = 8'hAA; // value returned during mpr pre-defined pattern readout
  904. parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors
  905. parameter DEBUG = 0; // Turn on Debug messages
  906. parameter BUS_DELAY = 0; // delay in nanoseconds
  907. parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads
  908. parameter RANDOM_SEED = 711689044; //seed value for random generator.
  909. parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe
  910. parameter RDQSEN_PST = 1; // DQS driving time after last read strobe
  911. parameter RDQS_PRE = 2; // DQS low time prior to first read strobe
  912. parameter RDQS_PST = 1; // DQS low time after last read strobe
  913. parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data
  914. parameter RDQEN_PST = 0; // DQ/DM driving time after last read data
  915. parameter WDQS_PRE = 2; // DQS half clock periods prior to first write strobe
  916. parameter WDQS_PST = 1; // DQS half clock periods after last write strobe
  917. // check for legal cas latency based on the cas write latency
  918. function valid_cl;
  919. input [3:0] cl;
  920. input [3:0] cwl;
  921. case ({cwl, cl})
  922. `ifdef sg094E
  923. {4'd5, 4'd5 },
  924. {4'd5, 4'd6 },
  925. {4'd6, 4'd7 },
  926. {4'd6, 4'd8 },
  927. {4'd7, 4'd9 },
  928. {4'd7, 4'd10},
  929. {4'd8, 4'd10},
  930. {4'd8, 4'd11},
  931. {4'd8, 4'd12},
  932. {4'd9, 4'd12},
  933. {4'd9, 4'd13},
  934. {4'd9, 4'd14},
  935. {4'd10, 4'd13},
  936. {4'd10, 4'd14}: valid_cl = 1;
  937. `else `ifdef sg094
  938. {4'd5, 4'd6 },
  939. {4'd6, 4'd7 },
  940. {4'd6, 4'd8 },
  941. {4'd7, 4'd10},
  942. {4'd8, 4'd11},
  943. {4'd8, 4'd12},
  944. {4'd9, 4'd13},
  945. {4'd9, 4'd14},
  946. {4'd10, 4'd14}: valid_cl = 1;
  947. `else `ifdef sg107F
  948. {4'd5, 4'd6 },
  949. {4'd6, 4'd7 },
  950. {4'd6, 4'd8 },
  951. {4'd7, 4'd9 },
  952. {4'd7, 4'd10},
  953. {4'd8, 4'd11},
  954. {4'd8, 4'd12},
  955. {4'd9, 4'd12},
  956. {4'd9, 4'd13},
  957. {4'd9, 4'd14}: valid_cl = 1;
  958. `else `ifdef sg107E
  959. {4'd5, 4'd6 },
  960. {4'd6, 4'd8 },
  961. {4'd7, 4'd10},
  962. {4'd8, 4'd12},
  963. {4'd9, 4'd13},
  964. {4'd9, 4'd14}: valid_cl = 1;
  965. `else `ifdef sg107
  966. {4'd5, 4'd6 },
  967. {4'd6, 4'd8 },
  968. {4'd7, 4'd10},
  969. {4'd8, 4'd12},
  970. {4'd9, 4'd14}: valid_cl = 1;
  971. `else `ifdef sg125F
  972. {4'd5, 4'd5 },
  973. {4'd5, 4'd6 },
  974. {4'd6, 4'd7 },
  975. {4'd6, 4'd8 },
  976. {4'd7, 4'd8 },
  977. {4'd7, 4'd9 },
  978. {4'd7, 4'd10},
  979. {4'd8, 4'd9 },
  980. {4'd8, 4'd10},
  981. {4'd8, 4'd11}: valid_cl = 1;
  982. `else `ifdef sg125E
  983. {4'd5, 4'd5 },
  984. {4'd5, 4'd6 },
  985. {4'd6, 4'd7 },
  986. {4'd6, 4'd8 },
  987. {4'd7, 4'd9 },
  988. {4'd7, 4'd10},
  989. {4'd8, 4'd10},
  990. {4'd8, 4'd11}: valid_cl = 1;
  991. `else `ifdef sg125
  992. {4'd5, 4'd6 },
  993. {4'd6, 4'd7 },
  994. {4'd6, 4'd8 },
  995. {4'd7, 4'd9 },
  996. {4'd7, 4'd10},
  997. {4'd8, 4'd11}: valid_cl = 1;
  998. `else `ifdef sg15E
  999. {4'd5, 4'd6 },
  1000. {4'd6, 4'd7 },
  1001. {4'd6, 4'd8 },
  1002. {4'd7, 4'd9 },
  1003. {4'd7, 4'd10}: valid_cl = 1;
  1004. `else `ifdef sg15
  1005. {4'd5, 4'd6 },
  1006. {4'd6, 4'd8 },
  1007. {4'd7, 4'd10}: valid_cl = 1;
  1008. `else `ifdef sg187E
  1009. {4'd5, 4'd6 },
  1010. {4'd6, 4'd7 },
  1011. {4'd6, 4'd8 }: valid_cl = 1;
  1012. `else `ifdef sg187
  1013. {4'd5, 4'd6 },
  1014. {4'd6, 4'd8 }: valid_cl = 1;
  1015. `else `ifdef sg25E
  1016. {4'd5, 4'd5 },
  1017. {4'd5, 4'd6 }: valid_cl = 1;
  1018. `else `ifdef sg25
  1019. {4'd5, 4'd6 }: valid_cl = 1;
  1020. `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif `endif
  1021. default : valid_cl = 0;
  1022. endcase
  1023. endfunction
  1024. // find the minimum valid cas write latency
  1025. function [3:0] min_cwl;
  1026. input period;
  1027. real period;
  1028. min_cwl = (period >= 2500.0) ? 5:
  1029. (period >= 1875.0) ? 6:
  1030. (period >= 1500.0) ? 7:
  1031. (period >= 1250.0) ? 8:
  1032. (period >= 15e3/14) ? 9:
  1033. 10; // (period >= 937.5)
  1034. endfunction
  1035. // find the minimum valid cas latency
  1036. function [3:0] min_cl;
  1037. input period;
  1038. real period;
  1039. reg [3:0] cwl;
  1040. reg [3:0] cl;
  1041. begin
  1042. cwl = min_cwl(period);
  1043. for (cl=CL_MAX; cl>=CL_MIN; cl=cl-1) begin
  1044. if (valid_cl(cl, cwl)) begin
  1045. min_cl = cl;
  1046. end
  1047. end
  1048. end
  1049. endfunction
  1050. `elsif x2Gb // 2Gb parts
  1051. // SYMBOL UNITS DESCRIPTION
  1052. // ------ ----- -----------
  1053. `ifdef sg15E // sg15E is equivelant to the JEDEC DDR3-1333H (9-9-9) speed bin
  1054. parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
  1055. parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
  1056. parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
  1057. parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
  1058. parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
  1059. parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
  1060. parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
  1061. parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
  1062. parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
  1063. parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
  1064. parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
  1065. parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
  1066. parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
  1067. parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
  1068. parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
  1069. parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
  1070. parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1071. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1072. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1073. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1074. parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
  1075. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  1076. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  1077. parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
  1078. parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
  1079. parameter TIS = 190; // tIS ps Input Setup Time
  1080. parameter TIH = 140; // tIH ps Input Hold Time
  1081. parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
  1082. parameter TRC = 49500; // tRC ps Active to Active/Auto Refresh command time
  1083. parameter TRCD = 13500; // tRCD ps Active to Read/Write command time
  1084. parameter TRP = 13500; // tRP ps Precharge command period
  1085. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  1086. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  1087. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  1088. parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
  1089. parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
  1090. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1091. parameter TAA_MIN = 13500; // TAA ps Internal READ command to first data
  1092. parameter CL_TIME = 13500; // CL ps Minimum CAS Latency
  1093. `else `ifdef sg15 // sg15 is equivelant to the JEDEC DDR3-1333J (10-10-10) speed bin
  1094. parameter TCK_MIN = 1500; // tCK ps Minimum Clock Cycle Time
  1095. parameter TJIT_PER = 80; // tJIT(per) ps Period JItter
  1096. parameter TJIT_CC = 160; // tJIT(cc) ps Cycle to Cycle jitter
  1097. parameter TERR_2PER = 118; // tERR(2per) ps Accumulated Error (2-cycle)
  1098. parameter TERR_3PER = 140; // tERR(3per) ps Accumulated Error (3-cycle)
  1099. parameter TERR_4PER = 155; // tERR(4per) ps Accumulated Error (4-cycle)
  1100. parameter TERR_5PER = 168; // tERR(5per) ps Accumulated Error (5-cycle)
  1101. parameter TERR_6PER = 177; // tERR(6per) ps Accumulated Error (6-cycle)
  1102. parameter TERR_7PER = 186; // tERR(7per) ps Accumulated Error (7-cycle)
  1103. parameter TERR_8PER = 193; // tERR(8per) ps Accumulated Error (8-cycle)
  1104. parameter TERR_9PER = 200; // tERR(9per) ps Accumulated Error (9-cycle)
  1105. parameter TERR_10PER = 205; // tERR(10per)ps Accumulated Error (10-cycle)
  1106. parameter TERR_11PER = 210; // tERR(11per)ps Accumulated Error (11-cycle)
  1107. parameter TERR_12PER = 215; // tERR(12per)ps Accumulated Error (12-cycle)
  1108. parameter TDS = 30; // tDS ps DQ and DM input setup time relative to DQS
  1109. parameter TDH = 65; // tDH ps DQ and DM input hold time relative to DQS
  1110. parameter TDQSQ = 125; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1111. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1112. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1113. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1114. parameter TDQSCK = 255; // tDQSCK ps DQS output access time from CK/CK#
  1115. parameter TQSH = 0.40; // tQSH tCK DQS Output High Pulse Width
  1116. parameter TQSL = 0.40; // tQSL tCK DQS Output Low Pulse Width
  1117. parameter TDIPW = 400; // tDIPW ps DQ and DM input Pulse Width
  1118. parameter TIPW = 620; // tIPW ps Control and Address input Pulse Width
  1119. parameter TIS = 190; // tIS ps Input Setup Time
  1120. parameter TIH = 140; // tIH ps Input Hold Time
  1121. parameter TRAS_MIN = 36000; // tRAS ps Minimum Active to Precharge command time
  1122. parameter TRC = 51000; // tRC ps Active to Active/Auto Refresh command time
  1123. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  1124. parameter TRP = 15000; // tRP ps Precharge command period
  1125. parameter TXP = 6000; // tXP ps Exit power down to a valid command
  1126. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  1127. parameter TAON = 250; // tAON ps RTT turn-on from ODTLon reference
  1128. parameter TWLS = 195; // tWLS ps Setup time for tDQS flop
  1129. parameter TWLH = 195; // tWLH ps Hold time of tDQS flop
  1130. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1131. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  1132. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  1133. `else `ifdef sg187E // sg187E is equivelant to the JEDEC DDR3-1066F (7-7-7) speed bin
  1134. parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
  1135. parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
  1136. parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
  1137. parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
  1138. parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
  1139. parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
  1140. parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
  1141. parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
  1142. parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
  1143. parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
  1144. parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
  1145. parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
  1146. parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
  1147. parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
  1148. parameter TDS = 25; // tDS ps DQ and DM input setup time relative to DQS
  1149. parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
  1150. parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1151. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1152. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1153. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1154. parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
  1155. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  1156. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  1157. parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
  1158. parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
  1159. parameter TIS = 125; // tIS ps Input Setup Time
  1160. parameter TIH = 200; // tIH ps Input Hold Time
  1161. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  1162. parameter TRC = 50625; // tRC ps Active to Active/Auto Refresh command time
  1163. parameter TRCD = 13125; // tRCD ps Active to Read/Write command time
  1164. parameter TRP = 13125; // tRP ps Precharge command period
  1165. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  1166. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  1167. parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
  1168. parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
  1169. parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
  1170. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1171. parameter TAA_MIN = 13125; // TAA ps Internal READ command to first data
  1172. parameter CL_TIME = 13125; // CL ps Minimum CAS Latency
  1173. `else `ifdef sg187 // sg187 is equivelant to the JEDEC DDR3-1066G (8-8-8) speed bin
  1174. parameter TCK_MIN = 1875; // tCK ps Minimum Clock Cycle Time
  1175. parameter TJIT_PER = 90; // tJIT(per) ps Period JItter
  1176. parameter TJIT_CC = 180; // tJIT(cc) ps Cycle to Cycle jitter
  1177. parameter TERR_2PER = 132; // tERR(2per) ps Accumulated Error (2-cycle)
  1178. parameter TERR_3PER = 157; // tERR(3per) ps Accumulated Error (3-cycle)
  1179. parameter TERR_4PER = 175; // tERR(4per) ps Accumulated Error (4-cycle)
  1180. parameter TERR_5PER = 188; // tERR(5per) ps Accumulated Error (5-cycle)
  1181. parameter TERR_6PER = 200; // tERR(6per) ps Accumulated Error (6-cycle)
  1182. parameter TERR_7PER = 209; // tERR(7per) ps Accumulated Error (7-cycle)
  1183. parameter TERR_8PER = 217; // tERR(8per) ps Accumulated Error (8-cycle)
  1184. parameter TERR_9PER = 224; // tERR(9per) ps Accumulated Error (9-cycle)
  1185. parameter TERR_10PER = 231; // tERR(10per)ps Accumulated Error (10-cycle)
  1186. parameter TERR_11PER = 237; // tERR(11per)ps Accumulated Error (11-cycle)
  1187. parameter TERR_12PER = 242; // tERR(12per)ps Accumulated Error (12-cycle)
  1188. parameter TDS = 25; // tDS ps DQ and DM input setup time relative to DQS
  1189. parameter TDH = 100; // tDH ps DQ and DM input hold time relative to DQS
  1190. parameter TDQSQ = 150; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1191. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1192. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1193. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1194. parameter TDQSCK = 300; // tDQSCK ps DQS output access time from CK/CK#
  1195. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  1196. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  1197. parameter TDIPW = 490; // tDIPW ps DQ and DM input Pulse Width
  1198. parameter TIPW = 780; // tIPW ps Control and Address input Pulse Width
  1199. parameter TIS = 125; // tIS ps Input Setup Time
  1200. parameter TIH = 200; // tIH ps Input Hold Time
  1201. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  1202. parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
  1203. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  1204. parameter TRP = 15000; // tRP ps Precharge command period
  1205. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  1206. parameter TCKE = 5625; // tCKE ps CKE minimum high or low pulse width
  1207. parameter TAON = 300; // tAON ps RTT turn-on from ODTLon reference
  1208. parameter TWLS = 245; // tWLS ps Setup time for tDQS flop
  1209. parameter TWLH = 245; // tWLH ps Hold time of tDQS flop
  1210. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1211. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  1212. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  1213. `else `ifdef sg25E // sg25E is equivelant to the JEDEC DDR3-800D (5-5-5) speed bin
  1214. parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
  1215. parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
  1216. parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
  1217. parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
  1218. parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
  1219. parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
  1220. parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
  1221. parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
  1222. parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
  1223. parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
  1224. parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
  1225. parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
  1226. parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
  1227. parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
  1228. parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
  1229. parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
  1230. parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1231. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1232. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1233. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1234. parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
  1235. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  1236. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  1237. parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
  1238. parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
  1239. parameter TIS = 200; // tIS ps Input Setup Time
  1240. parameter TIH = 275; // tIH ps Input Hold Time
  1241. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  1242. parameter TRC = 50000; // tRC ps Active to Active/Auto Refresh command time
  1243. parameter TRCD = 12500; // tRCD ps Active to Read/Write command time
  1244. parameter TRP = 12500; // tRP ps Precharge command period
  1245. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  1246. parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
  1247. parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
  1248. parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
  1249. parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
  1250. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1251. parameter TAA_MIN = 12500; // TAA ps Internal READ command to first data
  1252. parameter CL_TIME = 12500; // CL ps Minimum CAS Latency
  1253. `else `define sg25 // sg25 is equivelant to the JEDEC DDR3-800E (6-6-6) speed bin
  1254. parameter TCK_MIN = 2500; // tCK ps Minimum Clock Cycle Time
  1255. parameter TJIT_PER = 100; // tJIT(per) ps Period JItter
  1256. parameter TJIT_CC = 200; // tJIT(cc) ps Cycle to Cycle jitter
  1257. parameter TERR_2PER = 147; // tERR(2per) ps Accumulated Error (2-cycle)
  1258. parameter TERR_3PER = 175; // tERR(3per) ps Accumulated Error (3-cycle)
  1259. parameter TERR_4PER = 194; // tERR(4per) ps Accumulated Error (4-cycle)
  1260. parameter TERR_5PER = 209; // tERR(5per) ps Accumulated Error (5-cycle)
  1261. parameter TERR_6PER = 222; // tERR(6per) ps Accumulated Error (6-cycle)
  1262. parameter TERR_7PER = 232; // tERR(7per) ps Accumulated Error (7-cycle)
  1263. parameter TERR_8PER = 241; // tERR(8per) ps Accumulated Error (8-cycle)
  1264. parameter TERR_9PER = 249; // tERR(9per) ps Accumulated Error (9-cycle)
  1265. parameter TERR_10PER = 257; // tERR(10per)ps Accumulated Error (10-cycle)
  1266. parameter TERR_11PER = 263; // tERR(11per)ps Accumulated Error (11-cycle)
  1267. parameter TERR_12PER = 269; // tERR(12per)ps Accumulated Error (12-cycle)
  1268. parameter TDS = 75; // tDS ps DQ and DM input setup time relative to DQS
  1269. parameter TDH = 150; // tDH ps DQ and DM input hold time relative to DQS
  1270. parameter TDQSQ = 200; // tDQSQ ps DQS-DQ skew, DQS to last DQ valid, per group, per access
  1271. parameter TDQSS = 0.25; // tDQSS tCK Rising clock edge to DQS/DQS# latching transition
  1272. parameter TDSS = 0.20; // tDSS tCK DQS falling edge to CLK rising (setup time)
  1273. parameter TDSH = 0.20; // tDSH tCK DQS falling edge from CLK rising (hold time)
  1274. parameter TDQSCK = 400; // tDQSCK ps DQS output access time from CK/CK#
  1275. parameter TQSH = 0.38; // tQSH tCK DQS Output High Pulse Width
  1276. parameter TQSL = 0.38; // tQSL tCK DQS Output Low Pulse Width
  1277. parameter TDIPW = 600; // tDIPW ps DQ and DM input Pulse Width
  1278. parameter TIPW = 900; // tIPW ps Control and Address input Pulse Width
  1279. parameter TIS = 200; // tIS ps Input Setup Time
  1280. parameter TIH = 275; // tIH ps Input Hold Time
  1281. parameter TRAS_MIN = 37500; // tRAS ps Minimum Active to Precharge command time
  1282. parameter TRC = 52500; // tRC ps Active to Active/Auto Refresh command time
  1283. parameter TRCD = 15000; // tRCD ps Active to Read/Write command time
  1284. parameter TRP = 15000; // tRP ps Precharge command period
  1285. parameter TXP = 7500; // tXP ps Exit power down to a valid command
  1286. parameter TCKE = 7500; // tCKE ps CKE minimum high or low pulse width
  1287. parameter TAON = 400; // tAON ps RTT turn-on from ODTLon reference
  1288. parameter TWLS = 325; // tWLS ps Setup time for tDQS flop
  1289. parameter TWLH = 325; // tWLH ps Hold time of tDQS flop
  1290. parameter TWLO = 9000; // tWLO ps Write levelization output delay
  1291. parameter TAA_MIN = 15000; // TAA ps Internal READ command to first data
  1292. parameter CL_TIME = 15000; // CL ps Minimum CAS Latency
  1293. `endif `endif `endif `endif `endif
  1294. `ifdef x16
  1295. `ifdef sg15E
  1296. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  1297. parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
  1298. `else `ifdef sg15
  1299. parameter TRRD = 7500; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  1300. parameter TFAW = 45000; // tFAW ps (2KB page size) Four Bank Activate window
  1301. `else // sg187E, sg187, sg25, sg25E
  1302. parameter TRRD = 10000; // tRRD ps (2KB page size) Active bank a to Active bank b command time
  1303. parameter TFAW = 50000; // tFAW ps (2KB page size) Four Bank Activate window
  1304. `endif `endif
  1305. `else // x4, x8
  1306. `ifdef sg15E
  1307. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  1308. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  1309. `else `ifdef sg15
  1310. parameter TRRD = 6000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  1311. parameter TFAW = 30000; // tFAW ps (1KB page size) Four Bank Activate window
  1312. `else `ifdef sg187E
  1313. parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  1314. parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
  1315. `else `ifdef sg187
  1316. parameter TRRD = 7500; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  1317. parameter TFAW = 37500; // tFAW ps (1KB page size) Four Bank Activate window
  1318. `else // sg25, sg25E
  1319. parameter TRRD = 10000; // tRRD ps (1KB page size) Active bank a to Active bank b command time
  1320. parameter TFAW = 40000; // tFAW ps (1KB page size) Four Bank Activate window
  1321. `endif `endif `endif `endif
  1322. `endif
  1323. // Timing Parameters
  1324. // Mode Register
  1325. parameter CL_MIN = 5; // CL tCK Minimum CAS Latency
  1326. parameter CL_MAX = 11; // CL tCK Maximum CAS Latency
  1327. parameter AL_MIN = 0; // AL tCK Minimum Additive Latency
  1328. parameter AL_MAX = 2; // AL tCK Maximum Additive Latency
  1329. parameter WR_MIN = 5; // WR tCK Minimum Write Recovery
  1330. parameter WR_MAX = 12; // WR tCK Maximum Write Recovery
  1331. parameter BL_MIN = 4; // BL tCK Minimum Burst Length
  1332. parameter BL_MAX = 8; // BL tCK Minimum Burst Length
  1333. parameter CWL_MIN = 5; // CWL tCK Minimum CAS Write Latency
  1334. parameter CWL_MAX = 8; // CWL tCK Maximum CAS Write Latency
  1335. // Clock
  1336. parameter TCK_MAX = 3300; // tCK ps Maximum Clock Cycle Time
  1337. parameter TCH_AVG_MIN = 0.47; // tCH tCK Minimum Clock High-Level Pulse Width
  1338. parameter TCL_AVG_MIN = 0.47; // tCL tCK Minimum Clock Low-Level Pulse Width
  1339. parameter TCH_AVG_MAX = 0.53; // tCH tCK Maximum Clock High-Level Pulse Width
  1340. parameter TCL_AVG_MAX = 0.53; // tCL tCK Maximum Clock Low-Level Pulse Width
  1341. parameter TCH_ABS_MIN = 0.43; // tCH tCK Minimum Clock High-Level Pulse Width
  1342. parameter TCL_ABS_MIN = 0.43; // tCL tCK Maximum Clock Low-Level Pulse Width
  1343. parameter TCKE_TCK = 3; // tCKE tCK CKE minimum high or low pulse width
  1344. parameter TAA_MAX = 20000; // TAA ps Internal READ command to first data
  1345. // Data OUT
  1346. parameter TQH = 0.38; // tQH ps DQ output hold time from DQS, DQS#
  1347. // Data Strobe OUT
  1348. parameter TRPRE = 0.90; // tRPRE tCK DQS Read Preamble
  1349. parameter TRPST = 0.30; // tRPST tCK DQS Read Postamble
  1350. // Data Strobe IN
  1351. parameter TDQSH = 0.45; // tDQSH tCK DQS input High Pulse Width
  1352. parameter TDQSL = 0.45; // tDQSL tCK DQS input Low Pulse Width
  1353. parameter TWPRE = 0.90; // tWPRE tCK DQS Write Preamble
  1354. parameter TWPST = 0.30; // tWPST tCK DQS Write Postamble
  1355. // Command and Address
  1356. parameter TZQCS = 64; // tZQCS tCK ZQ Cal (Short) time
  1357. parameter TZQINIT = 512; // tZQinit tCK ZQ Cal (Long) time
  1358. parameter TZQOPER = 256; // tZQoper tCK ZQ Cal (Long) time
  1359. parameter TCCD = 4; // tCCD tCK Cas to Cas command delay
  1360. parameter TCCD_DG = 2; // tCCD_DG tCK Cas to Cas command delay to different group
  1361. parameter TRAS_MAX =70312500; // tRAS ps Maximum Active to Precharge command time
  1362. parameter TWR = 15000; // tWR ps Write recovery time
  1363. parameter TMRD = 4; // tMRD tCK Load Mode Register command cycle time
  1364. parameter TMOD = 15000; // tMOD ps LOAD MODE to non-LOAD MODE command cycle time
  1365. parameter TMOD_TCK = 12; // tMOD tCK LOAD MODE to non-LOAD MODE command cycle time
  1366. parameter TRRD_TCK = 4; // tRRD tCK Active bank a to Active bank b command time
  1367. parameter TRRD_DG = 3000; // tRRD_DG ps Active bank a to Active bank b command time to different group
  1368. parameter TRRD_DG_TCK = 2; // tRRD_DG tCK Active bank a to Active bank b command time to different group
  1369. parameter TRTP = 7500; // tRTP ps Read to Precharge command delay
  1370. parameter TRTP_TCK = 4; // tRTP tCK Read to Precharge command delay
  1371. parameter TWTR = 7500; // tWTR ps Write to Read command delay
  1372. parameter TWTR_DG = 3750; // tWTR_DG ps Write to Read command delay to different group
  1373. parameter TWTR_TCK = 4; // tWTR tCK Write to Read command delay
  1374. parameter TWTR_DG_TCK = 2; // tWTR_DG tCK Write to Read command delay to different group
  1375. parameter TDLLK = 512; // tDLLK tCK DLL locking time
  1376. // Refresh - 2Gb
  1377. parameter TRFC_MIN = 160000; // tRFC ps Refresh to Refresh Command interval minimum value
  1378. parameter TRFC_MAX =70312500; // tRFC ps Refresh to Refresh Command Interval maximum value
  1379. // Power Down
  1380. parameter TXP_TCK = 3; // tXP tCK Exit power down to a valid command
  1381. parameter TXPDLL = 24000; // tXPDLL ps Exit precharge power down to READ or WRITE command (DLL-off mode)
  1382. parameter TXPDLL_TCK = 10; // tXPDLL tCK Exit precharge power down to READ or WRITE command (DLL-off mode)
  1383. parameter TACTPDEN = 1; // tACTPDEN tCK Timing of last ACT command to power down entry
  1384. parameter TPRPDEN = 1; // tPREPDEN tCK Timing of last PRE command to power down entry
  1385. parameter TREFPDEN = 1; // tARPDEN tCK Timing of last REFRESH command to power down entry
  1386. parameter TCPDED = 1; // tCPDED tCK Command pass disable/enable delay
  1387. parameter TPD_MAX =TRFC_MAX; // tPD ps Power-down entry-to-exit timing
  1388. parameter TXPR = 170000; // tXPR ps Exit Reset from CKE assertion to a valid command
  1389. parameter TXPR_TCK = 5; // tXPR tCK Exit Reset from CKE assertion to a valid command
  1390. // Self Refresh
  1391. parameter TXS = 170000; // tXS ps Exit self refesh to a non-read or write command
  1392. parameter TXS_TCK = 5; // tXS tCK Exit self refesh to a non-read or write command
  1393. parameter TXSDLL = TDLLK; // tXSRD tCK Exit self refresh to a read or write command
  1394. parameter TISXR = TIS; // tISXR ps CKE setup time during self refresh exit.
  1395. parameter TCKSRE = 10000; // tCKSRE ps Valid Clock requirement after self refresh entry (SRE)
  1396. parameter TCKSRE_TCK = 5; // tCKSRE tCK Valid Clock requirement after self refresh entry (SRE)
  1397. parameter TCKSRX = 10000; // tCKSRX ps Valid Clock requirement prior to self refresh exit (SRX)
  1398. parameter TCKSRX_TCK = 5; // tCKSRX tCK Valid Clock requirement prior to self refresh exit (SRX)
  1399. parameter TCKESR_TCK = 4; // tCKESR tCK Minimum CKE low width for Self Refresh entry to exit timing
  1400. // ODT
  1401. parameter TAOF = 0.7; // tAOF tCK RTT turn-off from ODTLoff reference
  1402. parameter TAONPD = 9000; // tAONPD ps Asynchronous RTT turn-on delay (Power-Down with DLL frozen)
  1403. parameter TAOFPD = 9000; // tAONPD ps Asynchronous RTT turn-off delay (Power-Down with DLL frozen)
  1404. parameter ODTH4 = 4; // ODTH4 tCK ODT minimum HIGH time after ODT assertion or write (BL4)
  1405. parameter ODTH8 = 6; // ODTH8 tCK ODT minimum HIGH time after write (BL8)
  1406. parameter TADC = 0.7; // tADC tCK RTT dynamic change skew
  1407. // Write Levelization
  1408. parameter TWLMRD = 40; // tWLMRD tCK First DQS pulse rising edge after tDQSS margining mode is programmed
  1409. parameter TWLDQSEN = 25; // tWLDQSEN tCK DQS/DQS delay after tDQSS margining mode is programmed
  1410. parameter TWLOE = 2000; // tWLOE ps Write levelization output error
  1411. // Size Parameters based on Part Width
  1412. `ifdef x4
  1413. parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
  1414. parameter ADDR_BITS = 15; // MAX Address Bits
  1415. parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
  1416. parameter COL_BITS = 11; // Set this parameter to control how many Column bits are used
  1417. parameter DQ_BITS = 4; // Set this parameter to control how many Data bits are used **Same as part bit width**
  1418. parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
  1419. `else `ifdef x8
  1420. parameter DM_BITS = 1; // Set this parameter to control how many Data Mask bits are used
  1421. parameter ADDR_BITS = 15; // MAX Address Bits
  1422. parameter ROW_BITS = 15; // Set this parameter to control how many Address bits are used
  1423. parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
  1424. parameter DQ_BITS = 8; // Set this parameter to control how many Data bits are used **Same as part bit width**
  1425. parameter DQS_BITS = 1; // Set this parameter to control how many Dqs bits are used
  1426. `else `define x16
  1427. parameter DM_BITS = 2; // Set this parameter to control how many Data Mask bits are used
  1428. parameter ADDR_BITS = 14; // MAX Address Bits
  1429. parameter ROW_BITS = 14; // Set this parameter to control how many Address bits are used
  1430. parameter COL_BITS = 10; // Set this parameter to control how many Column bits are used
  1431. parameter DQ_BITS = 16; // Set this parameter to control how many Data bits are used **Same as part bit width**
  1432. parameter DQS_BITS = 2; // Set this parameter to control how many Dqs bits are used
  1433. `endif `endif
  1434. // Size Parameters
  1435. parameter BA_BITS = 3; // Set this parmaeter to control how many Bank Address bits are used
  1436. parameter MEM_BITS = 15; // Set this parameter to control how many write data bursts can be stored in memory. The default is 2^10=1024.
  1437. parameter AP = 10; // the address bit that controls auto-precharge and precharge-all
  1438. parameter BC = 12; // the address bit that controls burst chop
  1439. parameter BL_BITS = 3; // the number of bits required to count to BL_MAX
  1440. parameter BO_BITS = 2; // the number of Burst Order Bits
  1441. `ifdef QUAD_RANK
  1442. `define DUAL_RANK // also define DUAL_RANK
  1443. parameter CS_BITS = 4; // Number of Chip Select Bits
  1444. parameter RANKS = 4; // Number of Chip Selects
  1445. `else `ifdef DUAL_RANK
  1446. parameter CS_BITS = 2; // Number of Chip Select Bits
  1447. parameter RANKS = 2; // Number of Chip Selects
  1448. `else
  1449. parameter CS_BITS = 2; // Number of Chip Select Bits
  1450. parameter RANKS = 1; // Number of Chip Selects
  1451. `endif `endif
  1452. // Simulation parameters
  1453. parameter RZQ = 240; // termination resistance
  1454. parameter PRE_DEF_PAT = 8'hAA; // value returned during mpr pre-defined pattern readout
  1455. parameter STOP_ON_ERROR = 1; // If set to 1, the model will halt on command sequence/major errors
  1456. parameter DEBUG = 0; // Turn on Debug messages
  1457. parameter BUS_DELAY = 0; // delay in nanoseconds
  1458. parameter RANDOM_OUT_DELAY = 0; // If set to 1, the model will put a random amount of delay on DQ/DQS during reads
  1459. parameter RANDOM_SEED = 711689044; //seed value for random generator.
  1460. parameter RDQSEN_PRE = 2; // DQS driving time prior to first read strobe
  1461. parameter RDQSEN_PST = 1; // DQS driving time after last read strobe
  1462. parameter RDQS_PRE = 2; // DQS low time prior to first read strobe
  1463. parameter RDQS_PST = 1; // DQS low time after last read strobe
  1464. parameter RDQEN_PRE = 0; // DQ/DM driving time prior to first read data
  1465. parameter RDQEN_PST = 0; // DQ/DM driving time after last read data
  1466. parameter WDQS_PRE = 2; // DQS half clock periods prior to first write strobe
  1467. parameter WDQS_PST = 1; // DQS half clock periods after last write strobe
  1468. // check for legal cas latency based on the cas write latency
  1469. function valid_cl;
  1470. input [3:0] cl;
  1471. input [3:0] cwl;
  1472. case ({cwl, cl})
  1473. `ifdef sg15E
  1474. {4'd5, 4'd6 },
  1475. {4'd6, 4'd8 },
  1476. {4'd7, 4'd9 },
  1477. {4'd7, 4'd10}: valid_cl = 1;
  1478. `else `ifdef sg15
  1479. {4'd5, 4'd6 },
  1480. {4'd6, 4'd8 },
  1481. {4'd7, 4'd10}: valid_cl = 1;
  1482. `else `ifdef sg187E
  1483. {4'd5, 4'd6 },
  1484. {4'd6, 4'd7 },
  1485. {4'd6, 4'd8 }: valid_cl = 1;
  1486. `else `ifdef sg187
  1487. {4'd5, 4'd6 },
  1488. {4'd6, 4'd8 }: valid_cl = 1;
  1489. `else `ifdef sg25E
  1490. {4'd5, 4'd5 },
  1491. {4'd5, 4'd6 }: valid_cl = 1;
  1492. `else `ifdef sg25
  1493. {4'd5, 4'd6 }: valid_cl = 1;
  1494. `endif `endif `endif `endif `endif `endif
  1495. default : valid_cl = 0;
  1496. endcase
  1497. endfunction
  1498. // find the minimum valid cas write latency
  1499. function [3:0] min_cwl;
  1500. input period;
  1501. real period;
  1502. min_cwl = (period >= 2500.0) ? 5:
  1503. (period >= 1875.0) ? 6:
  1504. (period >= 1500.0) ? 7:
  1505. 8; //(period >= 1250.0)
  1506. endfunction
  1507. // find the minimum valid cas latency
  1508. function [3:0] min_cl;
  1509. input period;
  1510. real period;
  1511. reg [3:0] cwl;
  1512. reg [3:0] cl;
  1513. begin
  1514. cwl = min_cwl(period);
  1515. for (cl=CL_MAX; cl>=CL_MIN; cl=cl-1) begin
  1516. if (valid_cl(cl, cwl)) begin
  1517. min_cl = cl;
  1518. end
  1519. end
  1520. end
  1521. endfunction
  1522. `endif
  1523. parameter check_strict_mrbits = 1;
  1524. parameter check_strict_timing = 1;
  1525. parameter feature_pasr = 1;
  1526. parameter feature_truebl4 = 0;
  1527. // text macros
  1528. `define DQ_PER_DQS DQ_BITS/DQS_BITS
  1529. `define BANKS (1<<BA_BITS)
  1530. `define MAX_BITS (BA_BITS+ROW_BITS+COL_BITS-BL_BITS)
  1531. `define MAX_SIZE (1<<(BA_BITS+ROW_BITS+COL_BITS-BL_BITS))
  1532. `define MEM_SIZE (1<<MEM_BITS)
  1533. `define MAX_PIPE 4*CL_MAX
  1534. // Declare Ports
  1535. input rst_n;
  1536. input ck;
  1537. input ck_n;
  1538. input cke;
  1539. input cs_n;
  1540. input ras_n;
  1541. input cas_n;
  1542. input we_n;
  1543. inout [DM_BITS-1:0] dm_tdqs;
  1544. input [BA_BITS-1:0] ba;
  1545. input [ADDR_BITS-1:0] addr;
  1546. inout [DQ_BITS-1:0] dq;
  1547. inout [DQS_BITS-1:0] dqs;
  1548. inout [DQS_BITS-1:0] dqs_n;
  1549. output [DQS_BITS-1:0] tdqs_n;
  1550. input odt;
  1551. // clock jitter
  1552. real tck_avg;
  1553. time tck_sample [TDLLK-1:0];
  1554. time tch_sample [TDLLK-1:0];
  1555. time tcl_sample [TDLLK-1:0];
  1556. time tck_i;
  1557. time tch_i;
  1558. time tcl_i;
  1559. real tch_avg;
  1560. real tcl_avg;
  1561. time tm_ck_pos;
  1562. time tm_ck_neg;
  1563. real tjit_per_rtime;
  1564. integer tjit_cc_time;
  1565. real terr_nper_rtime;
  1566. //DDR3 clock jitter variables
  1567. real tjit_ch_rtime;
  1568. real duty_cycle;
  1569. // clock skew
  1570. real out_delay;
  1571. integer dqsck [DQS_BITS-1:0];
  1572. integer dqsck_min;
  1573. integer dqsck_max;
  1574. integer dqsq_min;
  1575. integer dqsq_max;
  1576. integer seed;
  1577. // Mode Registers
  1578. reg [ADDR_BITS-1:0] mode_reg [`BANKS-1:0];
  1579. reg burst_order;
  1580. reg [BL_BITS:0] burst_length;
  1581. reg blotf;
  1582. reg truebl4;
  1583. integer cas_latency;
  1584. reg dll_reset;
  1585. reg dll_locked;
  1586. integer write_recovery;
  1587. reg low_power;
  1588. reg dll_en;
  1589. reg [2:0] odt_rtt_nom;
  1590. reg [1:0] odt_rtt_wr;
  1591. reg odt_en;
  1592. reg dyn_odt_en;
  1593. reg [1:0] al;
  1594. integer additive_latency;
  1595. reg write_levelization;
  1596. reg duty_cycle_corrector;
  1597. reg tdqs_en;
  1598. reg out_en;
  1599. reg [2:0] pasr;
  1600. integer cas_write_latency;
  1601. reg asr; // auto self refresh
  1602. reg srt; // self refresh temperature range
  1603. reg [1:0] mpr_select;
  1604. reg mpr_en;
  1605. reg odts_readout;
  1606. integer read_latency;
  1607. integer write_latency;
  1608. // cmd encoding
  1609. parameter // {cs, ras, cas, we}
  1610. LOAD_MODE = 4'b0000,
  1611. REFRESH = 4'b0001,
  1612. PRECHARGE = 4'b0010,
  1613. ACTIVATE = 4'b0011,
  1614. WRITE = 4'b0100,
  1615. READ = 4'b0101,
  1616. ZQ = 4'b0110,
  1617. NOP = 4'b0111,
  1618. // DESEL = 4'b1xxx,
  1619. PWR_DOWN = 4'b1000,
  1620. SELF_REF = 4'b1001
  1621. ;
  1622. reg [8*9-1:0] cmd_string [9:0];
  1623. initial begin
  1624. cmd_string[LOAD_MODE] = "Load Mode";
  1625. cmd_string[REFRESH ] = "Refresh ";
  1626. cmd_string[PRECHARGE] = "Precharge";
  1627. cmd_string[ACTIVATE ] = "Activate ";
  1628. cmd_string[WRITE ] = "Write ";
  1629. cmd_string[READ ] = "Read ";
  1630. cmd_string[ZQ ] = "ZQ ";
  1631. cmd_string[NOP ] = "No Op ";
  1632. cmd_string[PWR_DOWN ] = "Pwr Down ";
  1633. cmd_string[SELF_REF ] = "Self Ref ";
  1634. end
  1635. // command state
  1636. reg [`BANKS-1:0] active_bank;
  1637. reg [`BANKS-1:0] auto_precharge_bank;
  1638. reg [`BANKS-1:0] write_precharge_bank;
  1639. reg [`BANKS-1:0] read_precharge_bank;
  1640. reg [ROW_BITS-1:0] active_row [`BANKS-1:0];
  1641. reg in_power_down;
  1642. reg in_self_refresh;
  1643. reg [3:0] init_mode_reg;
  1644. reg init_dll_reset;
  1645. reg init_done;
  1646. integer init_step;
  1647. reg zq_set;
  1648. reg er_trfc_max;
  1649. reg odt_state;
  1650. reg odt_state_dly;
  1651. reg dyn_odt_state;
  1652. reg dyn_odt_state_dly;
  1653. reg prev_odt;
  1654. wire [7:0] calibration_pattern = 8'b10101010; // value returned during mpr pre-defined pattern readout
  1655. wire [7:0] temp_sensor = 8'h01; // value returned during mpr temp sensor readout
  1656. reg [1:0] mr_chk;
  1657. reg rd_bc;
  1658. integer banki;
  1659. // cmd timers/counters
  1660. integer ref_cntr;
  1661. integer odt_cntr;
  1662. integer ck_cntr;
  1663. integer ck_txpr;
  1664. integer ck_load_mode;
  1665. integer ck_refresh;
  1666. integer ck_precharge;
  1667. integer ck_activate;
  1668. integer ck_write;
  1669. integer ck_read;
  1670. integer ck_zqinit;
  1671. integer ck_zqoper;
  1672. integer ck_zqcs;
  1673. integer ck_power_down;
  1674. integer ck_slow_exit_pd;
  1675. integer ck_self_refresh;
  1676. integer ck_freq_change;
  1677. integer ck_odt;
  1678. integer ck_odth8;
  1679. integer ck_dll_reset;
  1680. integer ck_cke_cmd;
  1681. integer ck_bank_write [`BANKS-1:0];
  1682. integer ck_bank_read [`BANKS-1:0];
  1683. integer ck_group_activate [1:0];
  1684. integer ck_group_write [1:0];
  1685. integer ck_group_read [1:0];
  1686. time tm_txpr;
  1687. time tm_load_mode;
  1688. time tm_refresh;
  1689. time tm_precharge;
  1690. time tm_activate;
  1691. time tm_write_end;
  1692. time tm_power_down;
  1693. time tm_slow_exit_pd;
  1694. time tm_self_refresh;
  1695. time tm_freq_change;
  1696. time tm_cke_cmd;
  1697. time tm_ttsinit;
  1698. time tm_bank_precharge [`BANKS-1:0];
  1699. time tm_bank_activate [`BANKS-1:0];
  1700. time tm_bank_write_end [`BANKS-1:0];
  1701. time tm_bank_read_end [`BANKS-1:0];
  1702. time tm_group_activate [1:0];
  1703. time tm_group_write_end [1:0];
  1704. // pipelines
  1705. reg [`MAX_PIPE:0] al_pipeline;
  1706. reg [`MAX_PIPE:0] wr_pipeline;
  1707. reg [`MAX_PIPE:0] rd_pipeline;
  1708. reg [`MAX_PIPE:0] odt_pipeline;
  1709. reg [`MAX_PIPE:0] dyn_odt_pipeline;
  1710. reg [BL_BITS:0] bl_pipeline [`MAX_PIPE:0];
  1711. reg [BA_BITS-1:0] ba_pipeline [`MAX_PIPE:0];
  1712. reg [ROW_BITS-1:0] row_pipeline [`MAX_PIPE:0];
  1713. reg [COL_BITS-1:0] col_pipeline [`MAX_PIPE:0];
  1714. reg prev_cke;
  1715. // data state
  1716. reg [BL_MAX*DQ_BITS-1:0] memory_data;
  1717. reg [BL_MAX*DQ_BITS-1:0] bit_mask;
  1718. reg [BL_BITS-1:0] burst_position;
  1719. reg [BL_BITS:0] burst_cntr;
  1720. reg [DQ_BITS-1:0] dq_temp;
  1721. reg [31:0] check_write_postamble;
  1722. reg [31:0] check_write_preamble;
  1723. reg [31:0] check_write_dqs_high;
  1724. reg [31:0] check_write_dqs_low;
  1725. reg [15:0] check_dm_tdipw;
  1726. reg [63:0] check_dq_tdipw;
  1727. // data timers/counters
  1728. time tm_rst_n;
  1729. time tm_cke;
  1730. time tm_odt;
  1731. time tm_tdqss;
  1732. time tm_dm [15:0];
  1733. time tm_dqs [15:0];
  1734. time tm_dqs_pos [31:0];
  1735. time tm_dqss_pos [31:0];
  1736. time tm_dqs_neg [31:0];
  1737. time tm_dq [63:0];
  1738. time tm_cmd_addr [22:0];
  1739. reg [8*7-1:0] cmd_addr_string [22:0];
  1740. initial begin
  1741. cmd_addr_string[ 0] = "CS_N ";
  1742. cmd_addr_string[ 1] = "RAS_N ";
  1743. cmd_addr_string[ 2] = "CAS_N ";
  1744. cmd_addr_string[ 3] = "WE_N ";
  1745. cmd_addr_string[ 4] = "BA 0 ";
  1746. cmd_addr_string[ 5] = "BA 1 ";
  1747. cmd_addr_string[ 6] = "BA 2 ";
  1748. cmd_addr_string[ 7] = "ADDR 0";
  1749. cmd_addr_string[ 8] = "ADDR 1";
  1750. cmd_addr_string[ 9] = "ADDR 2";
  1751. cmd_addr_string[10] = "ADDR 3";
  1752. cmd_addr_string[11] = "ADDR 4";
  1753. cmd_addr_string[12] = "ADDR 5";
  1754. cmd_addr_string[13] = "ADDR 6";
  1755. cmd_addr_string[14] = "ADDR 7";
  1756. cmd_addr_string[15] = "ADDR 8";
  1757. cmd_addr_string[16] = "ADDR 9";
  1758. cmd_addr_string[17] = "ADDR 10";
  1759. cmd_addr_string[18] = "ADDR 11";
  1760. cmd_addr_string[19] = "ADDR 12";
  1761. cmd_addr_string[20] = "ADDR 13";
  1762. cmd_addr_string[21] = "ADDR 14";
  1763. cmd_addr_string[22] = "ADDR 15";
  1764. end
  1765. reg [8*5-1:0] dqs_string [1:0];
  1766. initial begin
  1767. dqs_string[0] = "DQS ";
  1768. dqs_string[1] = "DQS_N";
  1769. end
  1770. // Memory Storage
  1771. `ifdef MAX_MEM
  1772. parameter RFF_BITS = DQ_BITS*BL_MAX;
  1773. // %z format uses 8 bytes for every 32 bits or less.
  1774. parameter RFF_CHUNK = 8 * (RFF_BITS/32 + (RFF_BITS%32 ? 1 : 0));
  1775. reg [1024:1] tmp_model_dir;
  1776. integer memfd[`BANKS-1:0];
  1777. initial
  1778. begin : file_io_open
  1779. integer bank;
  1780. if (!$value$plusargs("model_data+%s", tmp_model_dir))
  1781. begin
  1782. tmp_model_dir = "/tmp";
  1783. $display(
  1784. "%m: at time %t WARNING: no +model_data option specified, using /tmp.",
  1785. $time
  1786. );
  1787. end
  1788. for (bank = 0; bank < `BANKS; bank = bank + 1)
  1789. memfd[bank] = open_bank_file(bank);
  1790. end
  1791. `else
  1792. reg [BL_MAX*DQ_BITS-1:0] memory [0:`MEM_SIZE-1];
  1793. reg [`MAX_BITS-1:0] address [0:`MEM_SIZE-1];
  1794. reg [MEM_BITS:0] memory_index;
  1795. reg [MEM_BITS:0] memory_used = 0;
  1796. `endif
  1797. // receive
  1798. reg rst_n_in;
  1799. reg ck_in;
  1800. reg ck_n_in;
  1801. reg cke_in;
  1802. reg cs_n_in;
  1803. reg ras_n_in;
  1804. reg cas_n_in;
  1805. reg we_n_in;
  1806. reg [15:0] dm_in;
  1807. reg [2:0] ba_in;
  1808. reg [15:0] addr_in;
  1809. reg [63:0] dq_in;
  1810. reg [31:0] dqs_in;
  1811. reg odt_in;
  1812. reg [15:0] dm_in_pos;
  1813. reg [15:0] dm_in_neg;
  1814. reg [63:0] dq_in_pos;
  1815. reg [63:0] dq_in_neg;
  1816. reg dq_in_valid;
  1817. reg dqs_in_valid;
  1818. integer wdqs_cntr;
  1819. integer wdq_cntr;
  1820. integer wdqs_pos_cntr [31:0];
  1821. reg b2b_write;
  1822. reg [BL_BITS:0] wr_burst_length;
  1823. reg [31:0] prev_dqs_in;
  1824. reg diff_ck;
  1825. always @(rst_n ) rst_n_in <= #BUS_DELAY rst_n;
  1826. always @(ck ) ck_in <= #BUS_DELAY ck;
  1827. always @(ck_n ) ck_n_in <= #BUS_DELAY ck_n;
  1828. always @(cke ) cke_in <= #BUS_DELAY cke;
  1829. always @(cs_n ) cs_n_in <= #BUS_DELAY cs_n;
  1830. always @(ras_n ) ras_n_in <= #BUS_DELAY ras_n;
  1831. always @(cas_n ) cas_n_in <= #BUS_DELAY cas_n;
  1832. always @(we_n ) we_n_in <= #BUS_DELAY we_n;
  1833. always @(dm_tdqs) dm_in <= #BUS_DELAY dm_tdqs;
  1834. always @(ba ) ba_in <= #BUS_DELAY ba;
  1835. always @(addr ) addr_in <= #BUS_DELAY addr;
  1836. always @(dq ) dq_in <= #BUS_DELAY dq;
  1837. always @(dqs or dqs_n) dqs_in <= #BUS_DELAY (dqs_n<<16) | dqs;
  1838. always @(odt ) odt_in <= #BUS_DELAY odt;
  1839. // create internal clock
  1840. always @(posedge ck_in) diff_ck <= ck_in;
  1841. always @(posedge ck_n_in) diff_ck <= ~ck_n_in;
  1842. wire [15:0] dqs_even = dqs_in[15:0];
  1843. wire [15:0] dqs_odd = dqs_in[31:16];
  1844. wire [3:0] cmd_n_in = !cs_n_in ? {ras_n_in, cas_n_in, we_n_in} : NOP; //deselect = nop
  1845. // transmit
  1846. reg dqs_out_en;
  1847. reg [DQS_BITS-1:0] dqs_out_en_dly;
  1848. reg dqs_out;
  1849. reg [DQS_BITS-1:0] dqs_out_dly;
  1850. reg dq_out_en;
  1851. reg [DQ_BITS-1:0] dq_out_en_dly;
  1852. reg [DQ_BITS-1:0] dq_out;
  1853. reg [DQ_BITS-1:0] dq_out_dly;
  1854. integer rdqsen_cntr;
  1855. integer rdqs_cntr;
  1856. integer rdqen_cntr;
  1857. integer rdq_cntr;
  1858. bufif1 buf_dqs [DQS_BITS-1:0] (dqs, dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}});
  1859. bufif1 buf_dqs_n [DQS_BITS-1:0] (dqs_n, ~dqs_out_dly, dqs_out_en_dly & {DQS_BITS{out_en}});
  1860. bufif1 buf_dq [DQ_BITS-1:0] (dq, dq_out_dly, dq_out_en_dly & {DQ_BITS {out_en}});
  1861. assign tdqs_n = {DQS_BITS{1'bz}};
  1862. initial begin
  1863. if (BL_MAX < 2)
  1864. $display("%m ERROR: BL_MAX parameter must be >= 2. \nBL_MAX = %d", BL_MAX);
  1865. if ((1<<BO_BITS) > BL_MAX)
  1866. $display("%m ERROR: 2^BO_BITS cannot be greater than BL_MAX parameter.");
  1867. $timeformat (-12, 1, " ps", 1);
  1868. seed = RANDOM_SEED;
  1869. ck_cntr = 0;
  1870. end
  1871. function integer get_rtt_wr;
  1872. input [1:0] rtt;
  1873. begin
  1874. get_rtt_wr = RZQ/{rtt[0], rtt[1], 1'b0};
  1875. end
  1876. endfunction
  1877. function integer get_rtt_nom;
  1878. input [2:0] rtt;
  1879. begin
  1880. case (rtt)
  1881. 1: get_rtt_nom = RZQ/4;
  1882. 2: get_rtt_nom = RZQ/2;
  1883. 3: get_rtt_nom = RZQ/6;
  1884. 4: get_rtt_nom = RZQ/12;
  1885. 5: get_rtt_nom = RZQ/8;
  1886. default : get_rtt_nom = 0;
  1887. endcase
  1888. end
  1889. endfunction
  1890. // calculate the absolute value of a real number
  1891. function real abs_value;
  1892. input arg;
  1893. real arg;
  1894. begin
  1895. if (arg < 0.0)
  1896. abs_value = -1.0 * arg;
  1897. else
  1898. abs_value = arg;
  1899. end
  1900. endfunction
  1901. function integer ceil;
  1902. input number;
  1903. real number;
  1904. // LMR 4.1.7
  1905. // When either operand of a relational expression is a real operand then the other operand shall be converted
  1906. // to an equivalent real value, and the expression shall be interpreted as a comparison between two real values.
  1907. if (number > $rtoi(number))
  1908. ceil = $rtoi(number) + 1;
  1909. else
  1910. ceil = number;
  1911. endfunction
  1912. function integer floor;
  1913. input number;
  1914. real number;
  1915. // LMR 4.1.7
  1916. // When either operand of a relational expression is a real operand then the other operand shall be converted
  1917. // to an equivalent real value, and the expression shall be interpreted as a comparison between two real values.
  1918. if (number < $rtoi(number))
  1919. floor = $rtoi(number) - 1;
  1920. else
  1921. floor = number;
  1922. endfunction
  1923. `ifdef MAX_MEM
  1924. function integer open_bank_file( input integer bank );
  1925. integer fd;
  1926. reg [2048:1] filename;
  1927. begin
  1928. $sformat( filename, "%0s/%m.%0d", tmp_model_dir, bank );
  1929. fd = $fopen(filename, "w+");
  1930. if (fd == 0)
  1931. begin
  1932. $display("%m: at time %0t ERROR: failed to open %0s.", $time, filename);
  1933. $finish;
  1934. end
  1935. else
  1936. begin
  1937. if (DEBUG) $display("%m: at time %0t INFO: opening %0s.", $time, filename);
  1938. open_bank_file = fd;
  1939. end
  1940. end
  1941. endfunction
  1942. function [RFF_BITS:1] read_from_file(
  1943. input integer fd,
  1944. input integer index
  1945. );
  1946. integer code;
  1947. integer offset;
  1948. reg [1024:1] msg;
  1949. reg [RFF_BITS:1] read_value;
  1950. begin
  1951. offset = index * RFF_CHUNK;
  1952. code = $fseek( fd, offset, 0 );
  1953. // $fseek returns 0 on success, -1 on failure
  1954. if (code != 0)
  1955. begin
  1956. $display("%m: at time %t ERROR: fseek to %d failed", $time, offset);
  1957. $finish;
  1958. end
  1959. code = $fscanf(fd, "%z", read_value);
  1960. // $fscanf returns number of items read
  1961. if (code != 1)
  1962. begin
  1963. if ($ferror(fd,msg) != 0)
  1964. begin
  1965. $display("%m: at time %t ERROR: fscanf failed at %d", $time, index);
  1966. $display(msg);
  1967. $finish;
  1968. end
  1969. else
  1970. read_value = 'hx;
  1971. end
  1972. /* when reading from unwritten portions of the file, 0 will be returned.
  1973. * Use 0 in bit 1 as indicator that invalid data has been read.
  1974. * A true 0 is encoded as Z.
  1975. */
  1976. if (read_value[1] === 1'bz)
  1977. // true 0 encoded as Z, data is valid
  1978. read_value[1] = 1'b0;
  1979. else if (read_value[1] === 1'b0)
  1980. // read from file section that has not been written
  1981. read_value = 'hx;
  1982. read_from_file = read_value;
  1983. end
  1984. endfunction
  1985. task write_to_file(
  1986. input integer fd,
  1987. input integer index,
  1988. input [RFF_BITS:1] data
  1989. );
  1990. integer code;
  1991. integer offset;
  1992. begin
  1993. offset = index * RFF_CHUNK;
  1994. code = $fseek( fd, offset, 0 );
  1995. if (code != 0)
  1996. begin
  1997. $display("%m: at time %t ERROR: fseek to %d failed", $time, offset);
  1998. $finish;
  1999. end
  2000. // encode a valid data
  2001. if (data[1] === 1'bz)
  2002. data[1] = 1'bx;
  2003. else if (data[1] === 1'b0)
  2004. data[1] = 1'bz;
  2005. $fwrite( fd, "%z", data );
  2006. end
  2007. endtask
  2008. `else
  2009. function get_index;
  2010. input [`MAX_BITS-1:0] addr;
  2011. begin : index
  2012. get_index = 0;
  2013. for (memory_index=0; memory_index<memory_used; memory_index=memory_index+1) begin
  2014. if (address[memory_index] == addr) begin
  2015. get_index = 1;
  2016. disable index;
  2017. end
  2018. end
  2019. end
  2020. endfunction
  2021. `endif
  2022. task memory_write;
  2023. input [BA_BITS-1:0] bank;
  2024. input [ROW_BITS-1:0] row;
  2025. input [COL_BITS-1:0] col;
  2026. input [BL_MAX*DQ_BITS-1:0] data;
  2027. reg [`MAX_BITS-1:0] addr;
  2028. begin
  2029. `ifdef MAX_MEM
  2030. addr = {row, col}/BL_MAX;
  2031. write_to_file( memfd[bank], addr, data );
  2032. `else
  2033. // chop off the lowest address bits
  2034. addr = {bank, row, col}/BL_MAX;
  2035. if (get_index(addr)) begin
  2036. address[memory_index] = addr;
  2037. memory[memory_index] = data;
  2038. end else if (memory_used == `MEM_SIZE) begin
  2039. $display ("%m: at time %t ERROR: Memory overflow. Write to Address %h with Data %h will be lost.\nYou must increase the MEM_BITS parameter or define MAX_MEM.", $time, addr, data);
  2040. if (STOP_ON_ERROR) $stop(0);
  2041. end else begin
  2042. address[memory_used] = addr;
  2043. memory[memory_used] = data;
  2044. memory_used = memory_used + 1;
  2045. end
  2046. `endif
  2047. end
  2048. endtask
  2049. task memory_read;
  2050. input [BA_BITS-1:0] bank;
  2051. input [ROW_BITS-1:0] row;
  2052. input [COL_BITS-1:0] col;
  2053. output [BL_MAX*DQ_BITS-1:0] data;
  2054. reg [`MAX_BITS-1:0] addr;
  2055. begin
  2056. `ifdef MAX_MEM
  2057. addr = {row, col}/BL_MAX;
  2058. data = read_from_file( memfd[bank], addr );
  2059. `else
  2060. // chop off the lowest address bits
  2061. addr = {bank, row, col}/BL_MAX;
  2062. if (get_index(addr)) begin
  2063. data = memory[memory_index];
  2064. end else begin
  2065. data = {BL_MAX*DQ_BITS{1'bx}};
  2066. end
  2067. `endif
  2068. end
  2069. endtask
  2070. task set_latency;
  2071. begin
  2072. if (al == 0) begin
  2073. additive_latency = 0;
  2074. end else begin
  2075. additive_latency = cas_latency - al;
  2076. end
  2077. read_latency = cas_latency + additive_latency;
  2078. write_latency = cas_write_latency + additive_latency;
  2079. end
  2080. endtask
  2081. // this task will erase the contents of 0 or more banks
  2082. task erase_banks;
  2083. input [`BANKS-1:0] banks; //one select bit per bank
  2084. reg [BA_BITS-1:0] ba;
  2085. reg [`MAX_BITS-1:0] i;
  2086. integer bank;
  2087. begin
  2088. `ifdef MAX_MEM
  2089. for (bank = 0; bank < `BANKS; bank = bank + 1)
  2090. if (banks[bank] === 1'b1) begin
  2091. $fclose(memfd[bank]);
  2092. memfd[bank] = open_bank_file(bank);
  2093. end
  2094. `else
  2095. memory_index = 0;
  2096. i = 0;
  2097. // remove the selected banks
  2098. for (memory_index=0; memory_index<memory_used; memory_index=memory_index+1) begin
  2099. ba = (address[memory_index]>>(ROW_BITS+COL_BITS-BL_BITS));
  2100. if (!banks[ba]) begin //bank is selected to keep
  2101. address[i] = address[memory_index];
  2102. memory[i] = memory[memory_index];
  2103. i = i + 1;
  2104. end
  2105. end
  2106. // clean up the unused banks
  2107. for (memory_index=i; memory_index<memory_used; memory_index=memory_index+1) begin
  2108. address[memory_index] = 'bx;
  2109. memory[memory_index] = {8*DQ_BITS{1'bx}};
  2110. end
  2111. memory_used = i;
  2112. `endif
  2113. end
  2114. endtask
  2115. // Before this task runs, the model must be in a valid state for precharge power down and out of reset.
  2116. // After this task runs, NOP commands must be issued until TZQINIT has been met
  2117. task initialize;
  2118. input [ADDR_BITS-1:0] mode_reg0;
  2119. input [ADDR_BITS-1:0] mode_reg1;
  2120. input [ADDR_BITS-1:0] mode_reg2;
  2121. input [ADDR_BITS-1:0] mode_reg3;
  2122. begin
  2123. if (DEBUG) $display ("%m: at time %t INFO: Performing Initialization Sequence", $time);
  2124. cmd_task(1, NOP, 'bx, 'bx);
  2125. cmd_task(1, ZQ, 'bx, 'h400); //ZQCL
  2126. cmd_task(1, LOAD_MODE, 3, mode_reg3);
  2127. cmd_task(1, LOAD_MODE, 2, mode_reg2);
  2128. cmd_task(1, LOAD_MODE, 1, mode_reg1);
  2129. cmd_task(1, LOAD_MODE, 0, mode_reg0 | 'h100); // DLL Reset
  2130. cmd_task(0, NOP, 'bx, 'bx);
  2131. end
  2132. endtask
  2133. task reset_task;
  2134. integer i;
  2135. begin
  2136. // disable inputs
  2137. dq_in_valid = 0;
  2138. dqs_in_valid <= 0;
  2139. wdqs_cntr = 0;
  2140. wdq_cntr = 0;
  2141. for (i=0; i<31; i=i+1) begin
  2142. wdqs_pos_cntr[i] <= 0;
  2143. end
  2144. b2b_write <= 0;
  2145. // disable outputs
  2146. out_en = 0;
  2147. dq_out_en = 0;
  2148. rdq_cntr = 0;
  2149. dqs_out_en = 0;
  2150. rdqs_cntr = 0;
  2151. // disable ODT
  2152. odt_en = 0;
  2153. dyn_odt_en = 0;
  2154. odt_state = 0;
  2155. dyn_odt_state = 0;
  2156. // reset bank state
  2157. active_bank = 0;
  2158. auto_precharge_bank = 0;
  2159. read_precharge_bank = 0;
  2160. write_precharge_bank = 0;
  2161. // require initialization sequence
  2162. init_done = 0;
  2163. mpr_en = 0;
  2164. init_step = 0;
  2165. init_mode_reg = 0;
  2166. init_dll_reset = 0;
  2167. zq_set = 0;
  2168. // reset DLL
  2169. dll_en = 0;
  2170. dll_reset = 0;
  2171. dll_locked = 0;
  2172. // exit power down and self refresh
  2173. prev_cke = 1'bx;
  2174. in_power_down = 0;
  2175. in_self_refresh = 0;
  2176. // clear pipelines
  2177. al_pipeline = 0;
  2178. wr_pipeline = 0;
  2179. rd_pipeline = 0;
  2180. odt_pipeline = 0;
  2181. dyn_odt_pipeline = 0;
  2182. end
  2183. endtask
  2184. parameter SAME_BANK = 2'd0; // same bank, same group
  2185. parameter DIFF_BANK = 2'd1; // different bank, same group
  2186. parameter DIFF_GROUP = 2'd2; // different bank, different group
  2187. task chk_err;
  2188. input [1:0] relationship;
  2189. input [BA_BITS-1:0] bank;
  2190. input [3:0] fromcmd;
  2191. input [3:0] cmd;
  2192. reg err;
  2193. begin
  2194. // $display ("truebl4 = %d, relationship = %d, fromcmd = %h, cmd = %h", truebl4, relationship, fromcmd, cmd);
  2195. casex ({truebl4, relationship, fromcmd, cmd})
  2196. // load mode
  2197. {1'bx, DIFF_BANK , LOAD_MODE, LOAD_MODE} : begin if (ck_cntr - ck_load_mode < TMRD) $display ("%m: at time %t ERROR: tMRD violation during %s", $time, cmd_string[cmd]); end
  2198. {1'bx, DIFF_BANK , LOAD_MODE, READ } : begin if (($time - tm_load_mode < TMOD) || (ck_cntr - ck_load_mode < TMOD_TCK)) $display ("%m: at time %t ERROR: tMOD violation during %s", $time, cmd_string[cmd]); end
  2199. {1'bx, DIFF_BANK , LOAD_MODE, REFRESH } ,
  2200. {1'bx, DIFF_BANK , LOAD_MODE, PRECHARGE} ,
  2201. {1'bx, DIFF_BANK , LOAD_MODE, ACTIVATE } ,
  2202. {1'bx, DIFF_BANK , LOAD_MODE, ZQ } ,
  2203. {1'bx, DIFF_BANK , LOAD_MODE, PWR_DOWN } ,
  2204. {1'bx, DIFF_BANK , LOAD_MODE, SELF_REF } : begin if (($time - tm_load_mode < TMOD) || (ck_cntr - ck_load_mode < TMOD_TCK)) $display ("%m: at time %t ERROR: tMOD violation during %s", $time, cmd_string[cmd]); end
  2205. // refresh
  2206. {1'bx, DIFF_BANK , REFRESH , LOAD_MODE} ,
  2207. {1'bx, DIFF_BANK , REFRESH , REFRESH } ,
  2208. {1'bx, DIFF_BANK , REFRESH , PRECHARGE} ,
  2209. {1'bx, DIFF_BANK , REFRESH , ACTIVATE } ,
  2210. {1'bx, DIFF_BANK , REFRESH , ZQ } ,
  2211. {1'bx, DIFF_BANK , REFRESH , SELF_REF } : begin if ($time - tm_refresh < TRFC_MIN) $display ("%m: at time %t ERROR: tRFC violation during %s", $time, cmd_string[cmd]); end
  2212. {1'bx, DIFF_BANK , REFRESH , PWR_DOWN } : begin if (ck_cntr - ck_refresh < TREFPDEN) $display ("%m: at time %t ERROR: tREFPDEN violation during %s", $time, cmd_string[cmd]); end
  2213. // precharge
  2214. {1'bx, SAME_BANK , PRECHARGE, ACTIVATE } : begin if ($time - tm_bank_precharge[bank] < TRP) $display ("%m: at time %t ERROR: tRP violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2215. {1'bx, DIFF_BANK , PRECHARGE, LOAD_MODE} ,
  2216. {1'bx, DIFF_BANK , PRECHARGE, REFRESH } ,
  2217. {1'bx, DIFF_BANK , PRECHARGE, ZQ } ,
  2218. {1'bx, DIFF_BANK , PRECHARGE, SELF_REF } : begin if ($time - tm_precharge < TRP) $display ("%m: at time %t ERROR: tRP violation during %s", $time, cmd_string[cmd]); end
  2219. {1'bx, DIFF_BANK , PRECHARGE, PWR_DOWN } : ; //tPREPDEN = 1 tCK, can be concurrent with auto precharge
  2220. // activate
  2221. {1'bx, SAME_BANK , ACTIVATE , PRECHARGE} : begin if ($time - tm_bank_activate[bank] > TRAS_MAX) $display ("%m: at time %t ERROR: tRAS maximum violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2222. if ($time - tm_bank_activate[bank] < TRAS_MIN) $display ("%m: at time %t ERROR: tRAS minimum violation during %s to bank %d", $time, cmd_string[cmd], bank);end
  2223. {1'bx, SAME_BANK , ACTIVATE , ACTIVATE } : begin if ($time - tm_bank_activate[bank] < TRC) $display ("%m: at time %t ERROR: tRC violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2224. {1'bx, SAME_BANK , ACTIVATE , WRITE } ,
  2225. {1'bx, SAME_BANK , ACTIVATE , READ } : ; // tRCD is checked outside this task
  2226. {1'b0, DIFF_BANK , ACTIVATE , ACTIVATE } : begin if (($time - tm_activate < TRRD) || (ck_cntr - ck_activate < TRRD_TCK)) $display ("%m: at time %t ERROR: tRRD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2227. {1'b1, DIFF_BANK , ACTIVATE , ACTIVATE } : begin if (($time - tm_group_activate[bank[1]] < TRRD) || (ck_cntr - ck_group_activate[bank[1]] < TRRD_TCK)) $display ("%m: at time %t ERROR: tRRD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2228. {1'b1, DIFF_GROUP, ACTIVATE , ACTIVATE } : begin if (($time - tm_activate < TRRD_DG) || (ck_cntr - ck_activate < TRRD_DG_TCK)) $display ("%m: at time %t ERROR: tRRD_DG violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2229. {1'bx, DIFF_BANK , ACTIVATE , REFRESH } : begin if ($time - tm_activate < TRC) $display ("%m: at time %t ERROR: tRC violation during %s", $time, cmd_string[cmd]); end
  2230. {1'bx, DIFF_BANK , ACTIVATE , PWR_DOWN } : begin if (ck_cntr - ck_activate < TACTPDEN) $display ("%m: at time %t ERROR: tACTPDEN violation during %s", $time, cmd_string[cmd]); end
  2231. // write
  2232. {1'bx, SAME_BANK , WRITE , PRECHARGE} : begin if (($time - tm_bank_write_end[bank] < TWR) || (ck_cntr - ck_bank_write[bank] <= write_latency + burst_length/2)) $display ("%m: at time %t ERROR: tWR violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2233. {1'b0, DIFF_BANK , WRITE , WRITE } : begin if (ck_cntr - ck_write < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2234. {1'b1, DIFF_BANK , WRITE , WRITE } : begin if (ck_cntr - ck_group_write[bank[1]] < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2235. {1'b0, DIFF_BANK , WRITE , READ } : begin if (ck_cntr - ck_write < write_latency + burst_length/2 + TWTR_TCK - additive_latency) $display ("%m: at time %t ERROR: tWTR violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2236. {1'b1, DIFF_BANK , WRITE , READ } : begin if (ck_cntr - ck_group_write[bank[1]] < write_latency + burst_length/2 + TWTR_TCK - additive_latency) $display ("%m: at time %t ERROR: tWTR violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2237. {1'b1, DIFF_GROUP, WRITE , WRITE } : begin if (ck_cntr - ck_write < TCCD_DG) $display ("%m: at time %t ERROR: tCCD_DG violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2238. {1'b1, DIFF_GROUP, WRITE , READ } : begin if (ck_cntr - ck_write < write_latency + burst_length/2 + TWTR_DG_TCK - additive_latency) $display ("%m: at time %t ERROR: tWTR_DG violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2239. {1'bx, DIFF_BANK , WRITE , PWR_DOWN } : begin if (($time - tm_write_end < TWR) || (ck_cntr - ck_write < write_latency + burst_length/2)) $display ("%m: at time %t ERROR: tWRPDEN violation during %s", $time, cmd_string[cmd]); end
  2240. // read
  2241. {1'bx, SAME_BANK , READ , PRECHARGE} : begin if (($time - tm_bank_read_end[bank] < TRTP) || (ck_cntr - ck_bank_read[bank] < additive_latency + TRTP_TCK)) $display ("%m: at time %t ERROR: tRTP violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2242. {1'b0, DIFF_BANK , READ , WRITE } : ; // tRTW is checked outside this task
  2243. {1'b1, DIFF_BANK , READ , WRITE } : ; // tRTW is checked outside this task
  2244. {1'b0, DIFF_BANK , READ , READ } : begin if (ck_cntr - ck_read < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2245. {1'b1, DIFF_BANK , READ , READ } : begin if (ck_cntr - ck_group_read[bank[1]] < TCCD) $display ("%m: at time %t ERROR: tCCD violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2246. {1'b1, DIFF_GROUP, READ , WRITE } : ; // tRTW is checked outside this task
  2247. {1'b1, DIFF_GROUP, READ , READ } : begin if (ck_cntr - ck_read < TCCD_DG) $display ("%m: at time %t ERROR: tCCD_DG violation during %s to bank %d", $time, cmd_string[cmd], bank); end
  2248. {1'bx, DIFF_BANK , READ , PWR_DOWN } : begin if (ck_cntr - ck_read < read_latency + 5) $display ("%m: at time %t ERROR: tRDPDEN violation during %s", $time, cmd_string[cmd]); end
  2249. // zq
  2250. {1'bx, DIFF_BANK , ZQ , LOAD_MODE} : ; // 1 tCK
  2251. {1'bx, DIFF_BANK , ZQ , REFRESH } ,
  2252. {1'bx, DIFF_BANK , ZQ , PRECHARGE} ,
  2253. {1'bx, DIFF_BANK , ZQ , ACTIVATE } ,
  2254. {1'bx, DIFF_BANK , ZQ , ZQ } ,
  2255. {1'bx, DIFF_BANK , ZQ , PWR_DOWN } ,
  2256. {1'bx, DIFF_BANK , ZQ , SELF_REF } : begin if (ck_cntr - ck_zqinit < TZQINIT) $display ("%m: at time %t ERROR: tZQinit violation during %s", $time, cmd_string[cmd]);
  2257. if (ck_cntr - ck_zqoper < TZQOPER) $display ("%m: at time %t ERROR: tZQoper violation during %s", $time, cmd_string[cmd]);
  2258. if (ck_cntr - ck_zqcs < TZQCS) $display ("%m: at time %t ERROR: tZQCS violation during %s", $time, cmd_string[cmd]); end
  2259. // power down
  2260. {1'bx, DIFF_BANK , PWR_DOWN , LOAD_MODE} ,
  2261. {1'bx, DIFF_BANK , PWR_DOWN , REFRESH } ,
  2262. {1'bx, DIFF_BANK , PWR_DOWN , PRECHARGE} ,
  2263. {1'bx, DIFF_BANK , PWR_DOWN , ACTIVATE } ,
  2264. {1'bx, DIFF_BANK , PWR_DOWN , WRITE } ,
  2265. {1'bx, DIFF_BANK , PWR_DOWN , ZQ } : begin if (($time - tm_power_down < TXP) || (ck_cntr - ck_power_down < TXP_TCK)) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]); end
  2266. {1'bx, DIFF_BANK , PWR_DOWN , READ } : begin if (($time - tm_power_down < TXP) || (ck_cntr - ck_power_down < TXP_TCK)) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]);
  2267. else if (($time - tm_slow_exit_pd < TXPDLL) || (ck_cntr - ck_slow_exit_pd < TXPDLL_TCK)) $display ("%m: at time %t ERROR: tXPDLL violation during %s", $time, cmd_string[cmd]); end
  2268. {1'bx, DIFF_BANK , PWR_DOWN , PWR_DOWN } ,
  2269. {1'bx, DIFF_BANK , PWR_DOWN , SELF_REF } : begin if (($time - tm_power_down < TXP) || (ck_cntr - ck_power_down < TXP_TCK)) $display ("%m: at time %t ERROR: tXP violation during %s", $time, cmd_string[cmd]);
  2270. if ((tm_power_down > tm_refresh) && ($time - tm_refresh < TRFC_MIN)) $display ("%m: at time %t ERROR: tRFC violation during %s", $time, cmd_string[cmd]);
  2271. if ((tm_refresh > tm_power_down) && (($time - tm_power_down < TXPDLL) || (ck_cntr - ck_power_down < TXPDLL_TCK))) $display ("%m: at time %t ERROR: tXPDLL violation during %s", $time, cmd_string[cmd]);
  2272. if (($time - tm_cke_cmd < TCKE) || (ck_cntr - ck_cke_cmd < TCKE_TCK)) $display ("%m: at time %t ERROR: tCKE violation on CKE", $time); end
  2273. // self refresh
  2274. {1'bx, DIFF_BANK , SELF_REF , LOAD_MODE} ,
  2275. {1'bx, DIFF_BANK , SELF_REF , REFRESH } ,
  2276. {1'bx, DIFF_BANK , SELF_REF , PRECHARGE} ,
  2277. {1'bx, DIFF_BANK , SELF_REF , ACTIVATE } ,
  2278. {1'bx, DIFF_BANK , SELF_REF , WRITE } ,
  2279. {1'bx, DIFF_BANK , SELF_REF , ZQ } : begin if (($time - tm_self_refresh < TXS) || (ck_cntr - ck_self_refresh < TXS_TCK)) $display ("%m: at time %t ERROR: tXS violation during %s", $time, cmd_string[cmd]); end
  2280. {1'bx, DIFF_BANK , SELF_REF , READ } : begin if (ck_cntr - ck_self_refresh < TXSDLL) $display ("%m: at time %t ERROR: tXSDLL violation during %s", $time, cmd_string[cmd]); end
  2281. {1'bx, DIFF_BANK , SELF_REF , PWR_DOWN } ,
  2282. {1'bx, DIFF_BANK , SELF_REF , SELF_REF } : begin if (($time - tm_self_refresh < TXS) || (ck_cntr - ck_self_refresh < TXS_TCK)) $display ("%m: at time %t ERROR: tXS violation during %s", $time, cmd_string[cmd]);
  2283. if (($time - tm_cke_cmd < TCKE) || (ck_cntr - ck_cke_cmd < TCKE_TCK)) $display ("%m: at time %t ERROR: tCKE violation on CKE", $time); end
  2284. endcase
  2285. end
  2286. endtask
  2287. task cmd_task;
  2288. input cke;
  2289. input [2:0] cmd;
  2290. input [BA_BITS-1:0] bank;
  2291. input [ADDR_BITS-1:0] addr;
  2292. reg [`BANKS:0] i;
  2293. integer j;
  2294. reg [`BANKS:0] tfaw_cntr;
  2295. reg [COL_BITS-1:0] col;
  2296. reg group;
  2297. begin
  2298. // tRFC max check
  2299. if (!er_trfc_max && !in_self_refresh) begin
  2300. if ($time - tm_refresh > TRFC_MAX && check_strict_timing) begin
  2301. $display ("%m: at time %t ERROR: tRFC maximum violation during %s", $time, cmd_string[cmd]);
  2302. er_trfc_max = 1;
  2303. end
  2304. end
  2305. if (cke) begin
  2306. if ((cmd < NOP) && (cmd != PRECHARGE)) begin
  2307. if (($time - tm_txpr < TXPR) || (ck_cntr - ck_txpr < TXPR_TCK))
  2308. $display ("%m: at time %t ERROR: tXPR violation during %s", $time, cmd_string[cmd]);
  2309. for (j=0; j<=SELF_REF; j=j+1) begin
  2310. chk_err(SAME_BANK , bank, j, cmd);
  2311. chk_err(DIFF_BANK , bank, j, cmd);
  2312. chk_err(DIFF_GROUP, bank, j, cmd);
  2313. end
  2314. end
  2315. case (cmd)
  2316. LOAD_MODE : begin
  2317. if (|odt_pipeline)
  2318. $display ("%m: at time %t ERROR: ODTL violation during %s", $time, cmd_string[cmd]);
  2319. if (odt_state)
  2320. $display ("%m: at time %t ERROR: ODT must be off prior to %s", $time, cmd_string[cmd]);
  2321. if (|active_bank) begin
  2322. $display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]);
  2323. if (STOP_ON_ERROR) $stop(0);
  2324. end else begin
  2325. if (DEBUG) $display ("%m: at time %t INFO: %s %d", $time, cmd_string[cmd], bank);
  2326. if (bank>>2) begin
  2327. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved bank bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2328. end
  2329. case (bank)
  2330. 0 : begin
  2331. // Burst Length
  2332. if (addr[1:0] == 2'b00) begin
  2333. burst_length = 8;
  2334. blotf = 0;
  2335. truebl4 = 0;
  2336. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = %d", $time, cmd_string[cmd], bank, burst_length);
  2337. end else if (addr[1:0] == 2'b01) begin
  2338. burst_length = 8;
  2339. blotf = 1;
  2340. truebl4 = 0;
  2341. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = Select via A12", $time, cmd_string[cmd], bank);
  2342. end else if (addr[1:0] == 2'b10) begin
  2343. burst_length = 4;
  2344. blotf = 0;
  2345. truebl4 = 0;
  2346. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = Fixed %d (chop)", $time, cmd_string[cmd], bank, burst_length);
  2347. end else if (feature_truebl4 && (addr[1:0] == 2'b11)) begin
  2348. burst_length = 4;
  2349. blotf = 0;
  2350. truebl4 = 1;
  2351. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Length = True %d", $time, cmd_string[cmd], bank, burst_length);
  2352. end else begin
  2353. $display ("%m: at time %t ERROR: %s %d Illegal Burst Length = %d", $time, cmd_string[cmd], bank, addr[1:0]);
  2354. end
  2355. // Burst Order
  2356. burst_order = addr[3];
  2357. if (!burst_order) begin
  2358. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Sequential", $time, cmd_string[cmd], bank);
  2359. end else if (burst_order) begin
  2360. if (DEBUG) $display ("%m: at time %t INFO: %s %d Burst Order = Interleaved", $time, cmd_string[cmd], bank);
  2361. end else begin
  2362. $display ("%m: at time %t ERROR: %s %d Illegal Burst Order = %d", $time, cmd_string[cmd], bank, burst_order);
  2363. end
  2364. // CAS Latency
  2365. cas_latency = {addr[2],addr[6:4]} + 4;
  2366. set_latency;
  2367. if ((cas_latency >= CL_MIN) && (cas_latency <= CL_MAX)) begin
  2368. if (DEBUG) $display ("%m: at time %t INFO: %s %d CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency);
  2369. end else begin
  2370. $display ("%m: at time %t ERROR: %s %d Illegal CAS Latency = %d", $time, cmd_string[cmd], bank, cas_latency);
  2371. end
  2372. // Reserved
  2373. if (addr[7] !== 0 && check_strict_mrbits) begin
  2374. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2375. end
  2376. // DLL Reset
  2377. dll_reset = addr[8];
  2378. if (!dll_reset) begin
  2379. if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Normal", $time, cmd_string[cmd], bank);
  2380. end else if (dll_reset) begin
  2381. if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Reset = Reset DLL", $time, cmd_string[cmd], bank);
  2382. dll_locked = 0;
  2383. init_dll_reset = 1;
  2384. ck_dll_reset <= ck_cntr;
  2385. end else begin
  2386. $display ("%m: at time %t ERROR: %s %d Illegal DLL Reset = %d", $time, cmd_string[cmd], bank, dll_reset);
  2387. end
  2388. // Write Recovery
  2389. if (addr[11:9] == 0) begin
  2390. write_recovery = 16;
  2391. end else if (addr[11:9] < 4) begin
  2392. write_recovery = addr[11:9] + 4;
  2393. end else begin
  2394. write_recovery = 2*addr[11:9];
  2395. end
  2396. if ((write_recovery >= WR_MIN) && (write_recovery <= WR_MAX)) begin
  2397. if (DEBUG) $display ("%m: at time %t INFO: %s %d Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery);
  2398. end else begin
  2399. $display ("%m: at time %t ERROR: %s %d Illegal Write Recovery = %d", $time, cmd_string[cmd], bank, write_recovery);
  2400. end
  2401. // Power Down Mode
  2402. low_power = !addr[12];
  2403. if (!low_power) begin
  2404. if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = DLL on", $time, cmd_string[cmd], bank);
  2405. end else if (low_power) begin
  2406. if (DEBUG) $display ("%m: at time %t INFO: %s %d Power Down Mode = DLL off", $time, cmd_string[cmd], bank);
  2407. end else begin
  2408. $display ("%m: at time %t ERROR: %s %d Illegal Power Down Mode = %d", $time, cmd_string[cmd], bank, low_power);
  2409. end
  2410. // Reserved
  2411. if (ADDR_BITS>13 && addr[13] !== 0 && check_strict_mrbits) begin
  2412. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2413. end
  2414. end
  2415. 1 : begin
  2416. // DLL Enable
  2417. dll_en = !addr[0];
  2418. if (!dll_en) begin
  2419. if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Disabled", $time, cmd_string[cmd], bank);
  2420. if (check_strict_mrbits) $display ("%m: at time %t WARNING: %s %d DLL off mode is not modeled", $time, cmd_string[cmd], bank);
  2421. end else if (dll_en) begin
  2422. if (DEBUG) $display ("%m: at time %t INFO: %s %d DLL Enable = Enabled", $time, cmd_string[cmd], bank);
  2423. end else begin
  2424. $display ("%m: at time %t ERROR: %s %d Illegal DLL Enable = %d", $time, cmd_string[cmd], bank, dll_en);
  2425. end
  2426. // Output Drive Strength
  2427. if ({addr[5], addr[1]} == 2'b00) begin
  2428. if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = %d Ohm", $time, cmd_string[cmd], bank, RZQ/6);
  2429. end else if ({addr[5], addr[1]} == 2'b01) begin
  2430. if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = %d Ohm", $time, cmd_string[cmd], bank, RZQ/7);
  2431. end else if ({addr[5], addr[1]} == 2'b11) begin
  2432. if (DEBUG) $display ("%m: at time %t INFO: %s %d Output Drive Strength = %d Ohm", $time, cmd_string[cmd], bank, RZQ/5);
  2433. end else begin
  2434. $display ("%m: at time %t ERROR: %s %d Illegal Output Drive Strength = %d", $time, cmd_string[cmd], bank, {addr[5], addr[1]});
  2435. end
  2436. // ODT Rtt (Rtt_NOM)
  2437. odt_rtt_nom = {addr[9], addr[6], addr[2]};
  2438. if (odt_rtt_nom == 3'b000) begin
  2439. if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = Disabled", $time, cmd_string[cmd], bank);
  2440. odt_en = 0;
  2441. end else if ((odt_rtt_nom < 4) || ((!addr[7] || (addr[7] && addr[12])) && (odt_rtt_nom < 6))) begin
  2442. if (DEBUG) $display ("%m: at time %t INFO: %s %d ODT Rtt = %d Ohm", $time, cmd_string[cmd], bank, get_rtt_nom(odt_rtt_nom));
  2443. odt_en = 1;
  2444. end else begin
  2445. $display ("%m: at time %t ERROR: %s %d Illegal ODT Rtt = %d", $time, cmd_string[cmd], bank, odt_rtt_nom);
  2446. odt_en = 0;
  2447. end
  2448. // Report the additive latency value
  2449. al = addr[4:3];
  2450. set_latency;
  2451. if (al == 0) begin
  2452. if (DEBUG) $display ("%m: at time %t INFO: %s %d Additive Latency = %d", $time, cmd_string[cmd], bank, al);
  2453. end else if ((al >= AL_MIN) && (al <= AL_MAX)) begin
  2454. if (DEBUG) $display ("%m: at time %t INFO: %s %d Additive Latency = CL - %d", $time, cmd_string[cmd], bank, al);
  2455. end else begin
  2456. $display ("%m: at time %t ERROR: %s %d Illegal Additive Latency = %d", $time, cmd_string[cmd], bank, al);
  2457. end
  2458. // Write Levelization
  2459. write_levelization = addr[7];
  2460. if (!write_levelization) begin
  2461. if (DEBUG) $display ("%m: at time %t INFO: %s %d Write Levelization = Disabled", $time, cmd_string[cmd], bank);
  2462. end else if (write_levelization) begin
  2463. if (DEBUG) $display ("%m: at time %t INFO: %s %d Write Levelization = Enabled", $time, cmd_string[cmd], bank);
  2464. end else begin
  2465. $display ("%m: at time %t ERROR: %s %d Illegal Write Levelization = %d", $time, cmd_string[cmd], bank, write_levelization);
  2466. end
  2467. // Reserved
  2468. if (addr[8] !== 0 && check_strict_mrbits) begin
  2469. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2470. end
  2471. // Reserved
  2472. if (addr[10] !== 0 && check_strict_mrbits) begin
  2473. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2474. end
  2475. // TDQS Enable
  2476. tdqs_en = addr[11];
  2477. if (!tdqs_en) begin
  2478. if (DEBUG) $display ("%m: at time %t INFO: %s %d TDQS Enable = Disabled", $time, cmd_string[cmd], bank);
  2479. end else if (tdqs_en) begin
  2480. if (8 == DQ_BITS) begin
  2481. if (DEBUG) $display ("%m: at time %t INFO: %s %d TDQS Enable = Enabled", $time, cmd_string[cmd], bank);
  2482. end
  2483. else begin
  2484. $display ("%m: at time %t WARNING: %s %d Illegal TDQS Enable. TDQS only exists on a x8 part", $time, cmd_string[cmd], bank);
  2485. tdqs_en = 0;
  2486. end
  2487. end else begin
  2488. $display ("%m: at time %t ERROR: %s %d Illegal TDQS Enable = %d", $time, cmd_string[cmd], bank, tdqs_en);
  2489. end
  2490. // Output Enable
  2491. out_en = !addr[12];
  2492. if (!out_en) begin
  2493. if (DEBUG) $display ("%m: at time %t INFO: %s %d Qoff = Disabled", $time, cmd_string[cmd], bank);
  2494. end else if (out_en) begin
  2495. if (DEBUG) $display ("%m: at time %t INFO: %s %d Qoff = Enabled", $time, cmd_string[cmd], bank);
  2496. end else begin
  2497. $display ("%m: at time %t ERROR: %s %d Illegal Qoff = %d", $time, cmd_string[cmd], bank, out_en);
  2498. end
  2499. // Reserved
  2500. if (ADDR_BITS>13 && addr[13] !== 0 && check_strict_mrbits) begin
  2501. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2502. end
  2503. end
  2504. 2 : begin
  2505. if (feature_pasr) begin
  2506. // Partial Array Self Refresh
  2507. pasr = addr[2:0];
  2508. case (pasr)
  2509. 3'b000 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 0-7", $time, cmd_string[cmd], bank);
  2510. 3'b001 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 0-3", $time, cmd_string[cmd], bank);
  2511. 3'b010 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 0-1", $time, cmd_string[cmd], bank);
  2512. 3'b011 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 0", $time, cmd_string[cmd], bank);
  2513. 3'b100 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 2-7", $time, cmd_string[cmd], bank);
  2514. 3'b101 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 4-7", $time, cmd_string[cmd], bank);
  2515. 3'b110 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 6-7", $time, cmd_string[cmd], bank);
  2516. 3'b111 : if (DEBUG) $display ("%m: at time %t INFO: %s %d Partial Array Self Refresh = Bank 7", $time, cmd_string[cmd], bank);
  2517. default : $display ("%m: at time %t ERROR: %s %d Illegal Partial Array Self Refresh = %d", $time, cmd_string[cmd], bank, pasr);
  2518. endcase
  2519. end
  2520. else
  2521. if (addr[2:0] !== 0 && check_strict_mrbits) begin
  2522. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2523. end
  2524. // CAS Write Latency
  2525. cas_write_latency = addr[5:3]+5;
  2526. set_latency;
  2527. if ((cas_write_latency >= CWL_MIN) && (cas_write_latency <= CWL_MAX)) begin
  2528. if (DEBUG) $display ("%m: at time %t INFO: %s %d CAS Write Latency = %d", $time, cmd_string[cmd], bank, cas_write_latency);
  2529. end else begin
  2530. $display ("%m: at time %t ERROR: %s %d Illegal CAS Write Latency = %d", $time, cmd_string[cmd], bank, cas_write_latency);
  2531. end
  2532. // Auto Self Refresh Method
  2533. asr = addr[6];
  2534. if (!asr) begin
  2535. if (DEBUG) $display ("%m: at time %t INFO: %s %d Auto Self Refresh = Disabled", $time, cmd_string[cmd], bank);
  2536. end else if (asr) begin
  2537. if (DEBUG) $display ("%m: at time %t INFO: %s %d Auto Self Refresh = Enabled", $time, cmd_string[cmd], bank);
  2538. if (check_strict_mrbits) $display ("%m: at time %t WARNING: %s %d Auto Self Refresh is not modeled", $time, cmd_string[cmd], bank);
  2539. end else begin
  2540. $display ("%m: at time %t ERROR: %s %d Illegal Auto Self Refresh = %d", $time, cmd_string[cmd], bank, asr);
  2541. end
  2542. // Self Refresh Temperature
  2543. srt = addr[7];
  2544. if (!srt) begin
  2545. if (DEBUG) $display ("%m: at time %t INFO: %s %d Self Refresh Temperature = Normal", $time, cmd_string[cmd], bank);
  2546. end else if (srt) begin
  2547. if (DEBUG) $display ("%m: at time %t INFO: %s %d Self Refresh Temperature = Extended", $time, cmd_string[cmd], bank);
  2548. if (check_strict_mrbits) $display ("%m: at time %t WARNING: %s %d Self Refresh Temperature is not modeled", $time, cmd_string[cmd], bank);
  2549. end else begin
  2550. $display ("%m: at time %t ERROR: %s %d Illegal Self Refresh Temperature = %d", $time, cmd_string[cmd], bank, srt);
  2551. end
  2552. if (asr && srt)
  2553. $display ("%m: at time %t ERROR: %s %d SRT must be set to 0 when ASR is enabled.", $time, cmd_string[cmd], bank);
  2554. // Reserved
  2555. if (addr[8] !== 0 && check_strict_mrbits) begin
  2556. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2557. end
  2558. // Dynamic ODT (Rtt_WR)
  2559. odt_rtt_wr = addr[10:9];
  2560. if (odt_rtt_wr == 2'b00) begin
  2561. if (DEBUG) $display ("%m: at time %t INFO: %s %d Dynamic ODT = Disabled", $time, cmd_string[cmd], bank);
  2562. dyn_odt_en = 0;
  2563. end else if ((odt_rtt_wr > 0) && (odt_rtt_wr < 3)) begin
  2564. if (DEBUG) $display ("%m: at time %t INFO: %s %d Dynamic ODT Rtt = %d Ohm", $time, cmd_string[cmd], bank, get_rtt_wr(odt_rtt_wr));
  2565. dyn_odt_en = 1;
  2566. end else begin
  2567. $display ("%m: at time %t ERROR: %s %d Illegal Dynamic ODT = %d", $time, cmd_string[cmd], bank, odt_rtt_wr);
  2568. dyn_odt_en = 0;
  2569. end
  2570. // Reserved
  2571. if (ADDR_BITS>13 && addr[13:11] !== 0 && check_strict_mrbits) begin
  2572. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2573. end
  2574. end
  2575. 3 : begin
  2576. mpr_select = addr[1:0];
  2577. // MultiPurpose Register Select
  2578. if (mpr_select == 2'b00) begin
  2579. if (DEBUG) $display ("%m: at time %t INFO: %s %d MultiPurpose Register Select = Pre-defined pattern", $time, cmd_string[cmd], bank);
  2580. end else begin
  2581. if (check_strict_mrbits) $display ("%m: at time %t ERROR: %s %d Illegal MultiPurpose Register Select = %d", $time, cmd_string[cmd], bank, mpr_select);
  2582. end
  2583. // MultiPurpose Register Enable
  2584. mpr_en = addr[2];
  2585. if (!mpr_en) begin
  2586. if (DEBUG) $display ("%m: at time %t INFO: %s %d MultiPurpose Register Enable = Disabled", $time, cmd_string[cmd], bank);
  2587. end else if (mpr_en) begin
  2588. if (DEBUG) $display ("%m: at time %t INFO: %s %d MultiPurpose Register Enable = Enabled", $time, cmd_string[cmd], bank);
  2589. end else begin
  2590. $display ("%m: at time %t ERROR: %s %d Illegal MultiPurpose Register Enable = %d", $time, cmd_string[cmd], bank, mpr_en);
  2591. end
  2592. // Reserved
  2593. if (ADDR_BITS>13 && addr[13:3] !== 0 && check_strict_mrbits) begin
  2594. $display ("%m: at time %t ERROR: %s %d Illegal value. Reserved address bits must be programmed to zero", $time, cmd_string[cmd], bank);
  2595. end
  2596. end
  2597. endcase
  2598. if (dyn_odt_en && write_levelization)
  2599. $display ("%m: at time %t ERROR: Dynamic ODT is not available during Write Leveling mode.", $time);
  2600. init_mode_reg[bank] = 1;
  2601. mode_reg[bank] = addr;
  2602. tm_load_mode <= $time;
  2603. ck_load_mode <= ck_cntr;
  2604. end
  2605. end
  2606. REFRESH : begin
  2607. if (mpr_en) begin
  2608. $display ("%m: at time %t ERROR: %s Failure. Multipurpose Register must be disabled.", $time, cmd_string[cmd]);
  2609. if (STOP_ON_ERROR) $stop(0);
  2610. end else if (|active_bank) begin
  2611. $display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]);
  2612. if (STOP_ON_ERROR) $stop(0);
  2613. end else begin
  2614. if (DEBUG) $display ("%m: at time %t INFO: %s", $time, cmd_string[cmd]);
  2615. er_trfc_max = 0;
  2616. ref_cntr = ref_cntr + 1;
  2617. tm_refresh <= $time;
  2618. ck_refresh <= ck_cntr;
  2619. end
  2620. end
  2621. PRECHARGE : begin
  2622. if (addr[AP]) begin
  2623. if (DEBUG) $display ("%m: at time %t INFO: %s All", $time, cmd_string[cmd]);
  2624. end
  2625. // PRECHARGE command will be treated as a NOP if there is no open row in that bank (idle state),
  2626. // or if the previously open row is already in the process of precharging
  2627. if (|active_bank) begin
  2628. if (($time - tm_txpr < TXPR) || (ck_cntr - ck_txpr < TXPR_TCK))
  2629. $display ("%m: at time %t ERROR: tXPR violation during %s", $time, cmd_string[cmd]);
  2630. if (mpr_en) begin
  2631. $display ("%m: at time %t ERROR: %s Failure. Multipurpose Register must be disabled.", $time, cmd_string[cmd]);
  2632. if (STOP_ON_ERROR) $stop(0);
  2633. end else begin
  2634. for (i=0; i<`BANKS; i=i+1) begin
  2635. if (active_bank[i]) begin
  2636. if (addr[AP] || (i == bank)) begin
  2637. for (j=0; j<=SELF_REF; j=j+1) begin
  2638. chk_err(SAME_BANK, i, j, cmd);
  2639. chk_err(DIFF_BANK, i, j, cmd);
  2640. end
  2641. if (auto_precharge_bank[i]) begin
  2642. $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], i);
  2643. if (STOP_ON_ERROR) $stop(0);
  2644. end else begin
  2645. if (DEBUG) $display ("%m: at time %t INFO: %s bank %d", $time, cmd_string[cmd], i);
  2646. active_bank[i] = 1'b0;
  2647. tm_bank_precharge[i] <= $time;
  2648. tm_precharge <= $time;
  2649. ck_precharge <= ck_cntr;
  2650. end
  2651. end
  2652. end
  2653. end
  2654. end
  2655. end
  2656. end
  2657. ACTIVATE : begin
  2658. tfaw_cntr = 0;
  2659. for (i=0; i<`BANKS; i=i+1) begin
  2660. if ($time - tm_bank_activate[i] < TFAW) begin
  2661. tfaw_cntr = tfaw_cntr + 1;
  2662. end
  2663. end
  2664. if (tfaw_cntr > 3) begin
  2665. $display ("%m: at time %t ERROR: tFAW violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2666. end
  2667. if (mpr_en) begin
  2668. $display ("%m: at time %t ERROR: %s Failure. Multipurpose Register must be disabled.", $time, cmd_string[cmd]);
  2669. if (STOP_ON_ERROR) $stop(0);
  2670. end else if (!init_done) begin
  2671. $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
  2672. if (STOP_ON_ERROR) $stop(0);
  2673. end else if (active_bank[bank]) begin
  2674. $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Precharged.", $time, cmd_string[cmd], bank);
  2675. if (STOP_ON_ERROR) $stop(0);
  2676. end else begin
  2677. if (addr >= 1<<ROW_BITS) begin
  2678. $display ("%m: at time %t WARNING: row = %h does not exist. Maximum row = %h", $time, addr, (1<<ROW_BITS)-1);
  2679. end
  2680. if (DEBUG) $display ("%m: at time %t INFO: %s bank %d row %h", $time, cmd_string[cmd], bank, addr);
  2681. active_bank[bank] = 1'b1;
  2682. active_row[bank] = addr;
  2683. tm_group_activate[bank[1]] <= $time;
  2684. tm_activate <= $time;
  2685. tm_bank_activate[bank] <= $time;
  2686. ck_group_activate[bank[1]] <= ck_cntr;
  2687. ck_activate <= ck_cntr;
  2688. end
  2689. end
  2690. WRITE : begin
  2691. if ((!rd_bc && blotf) || (burst_length == 4)) begin // BL=4
  2692. if (truebl4) begin
  2693. if (ck_cntr - ck_group_read[bank[1]] < read_latency + TCCD/2 + 2 - write_latency)
  2694. $display ("%m: at time %t ERROR: tRTW violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2695. if (ck_cntr - ck_read < read_latency + TCCD_DG/2 + 2 - write_latency)
  2696. $display ("%m: at time %t ERROR: tRTW_DG violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2697. end else begin
  2698. if (ck_cntr - ck_read < read_latency + TCCD/2 + 2 - write_latency)
  2699. $display ("%m: at time %t ERROR: tRTW violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2700. end
  2701. end else begin // BL=8
  2702. if (ck_cntr - ck_read < read_latency + TCCD + 2 - write_latency)
  2703. $display ("%m: at time %t ERROR: tRTW violation during %s to bank %d", $time, cmd_string[cmd], bank);
  2704. end
  2705. if (mpr_en) begin
  2706. $display ("%m: at time %t ERROR: %s Failure. Multipurpose Register must be disabled.", $time, cmd_string[cmd]);
  2707. if (STOP_ON_ERROR) $stop(0);
  2708. end else if (!init_done) begin
  2709. $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
  2710. if (STOP_ON_ERROR) $stop(0);
  2711. end else if (!active_bank[bank]) begin
  2712. if (check_strict_timing) $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank);
  2713. if (STOP_ON_ERROR) $stop(0);
  2714. end else if (auto_precharge_bank[bank]) begin
  2715. $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank);
  2716. if (STOP_ON_ERROR) $stop(0);
  2717. end else if (ck_cntr - ck_write < burst_length/2) begin
  2718. $display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]);
  2719. if (STOP_ON_ERROR) $stop(0);
  2720. end else begin
  2721. if (addr[AP]) begin
  2722. auto_precharge_bank[bank] = 1'b1;
  2723. write_precharge_bank[bank] = 1'b1;
  2724. end
  2725. col = {addr[BC-1:AP+1], addr[AP-1:0]}; // assume BC > AP
  2726. if (col >= 1<<COL_BITS) begin
  2727. $display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1);
  2728. end
  2729. if ((!addr[BC] && blotf) || (burst_length == 4)) begin // BL=4
  2730. col = col & -4;
  2731. end else begin // BL=8
  2732. col = col & -8;
  2733. end
  2734. if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]);
  2735. wr_pipeline[2*write_latency + 1] = 1;
  2736. ba_pipeline[2*write_latency + 1] = bank;
  2737. row_pipeline[2*write_latency + 1] = active_row[bank];
  2738. col_pipeline[2*write_latency + 1] = col;
  2739. if ((!addr[BC] && blotf) || (burst_length == 4)) begin // BL=4
  2740. bl_pipeline[2*write_latency + 1] = 4;
  2741. if (mpr_en && col%4) begin
  2742. $display ("%m: at time %t WARNING: col[1:0] must be set to 2'b00 during a BL4 Multipurpose Register read", $time);
  2743. end
  2744. end else begin // BL=8
  2745. bl_pipeline[2*write_latency + 1] = 8;
  2746. if (odt_in) begin
  2747. ck_odth8 <= ck_cntr;
  2748. end
  2749. end
  2750. for (j=0; j<(burst_length + 4); j=j+1) begin
  2751. dyn_odt_pipeline[2*(write_latency - 2) + j] = 1'b1; // ODTLcnw = WL - 2, ODTLcwn = BL/2 + 2
  2752. end
  2753. ck_bank_write[bank] <= ck_cntr;
  2754. ck_group_write[bank[1]] <= ck_cntr;
  2755. ck_write <= ck_cntr;
  2756. end
  2757. end
  2758. READ : begin
  2759. if (!dll_locked)
  2760. $display ("%m: at time %t WARNING: tDLLK violation during %s.", $time, cmd_string[cmd]);
  2761. if (mpr_en && (addr[1:0] != 2'b00)) begin
  2762. $display ("%m: at time %t ERROR: %s Failure. addr[1:0] must be zero during Multipurpose Register Read.", $time, cmd_string[cmd]);
  2763. if (STOP_ON_ERROR) $stop(0);
  2764. end else if (!init_done) begin
  2765. $display ("%m: at time %t ERROR: %s Failure. Initialization sequence is not complete.", $time, cmd_string[cmd]);
  2766. if (STOP_ON_ERROR) $stop(0);
  2767. end else if (!active_bank[bank] && !mpr_en) begin
  2768. if (check_strict_timing) $display ("%m: at time %t ERROR: %s Failure. Bank %d must be Activated.", $time, cmd_string[cmd], bank);
  2769. if (STOP_ON_ERROR) $stop(0);
  2770. end else if (auto_precharge_bank[bank]) begin
  2771. $display ("%m: at time %t ERROR: %s Failure. Auto Precharge is scheduled to bank %d.", $time, cmd_string[cmd], bank);
  2772. if (STOP_ON_ERROR) $stop(0);
  2773. end else if (ck_cntr - ck_read < burst_length/2) begin
  2774. $display ("%m: at time %t ERROR: %s Failure. Illegal burst interruption.", $time, cmd_string[cmd]);
  2775. if (STOP_ON_ERROR) $stop(0);
  2776. end else begin
  2777. if (addr[AP] && !mpr_en) begin
  2778. auto_precharge_bank[bank] = 1'b1;
  2779. read_precharge_bank[bank] = 1'b1;
  2780. end
  2781. col = {addr[BC-1:AP+1], addr[AP-1:0]}; // assume BC > AP
  2782. if (col >= 1<<COL_BITS) begin
  2783. $display ("%m: at time %t WARNING: col = %h does not exist. Maximum col = %h", $time, col, (1<<COL_BITS)-1);
  2784. end
  2785. if (DEBUG) $display ("%m: at time %t INFO: %s bank %d col %h, auto precharge %d", $time, cmd_string[cmd], bank, col, addr[AP]);
  2786. rd_pipeline[2*read_latency - 1] = 1;
  2787. ba_pipeline[2*read_latency - 1] = bank;
  2788. row_pipeline[2*read_latency - 1] = active_row[bank];
  2789. col_pipeline[2*read_latency - 1] = col;
  2790. if ((!addr[BC] && blotf) || (burst_length == 4)) begin // BL=4
  2791. bl_pipeline[2*read_latency - 1] = 4;
  2792. if (mpr_en && col%4) begin
  2793. $display ("%m: at time %t WARNING: col[1:0] must be set to 2'b00 during a BL4 Multipurpose Register read", $time);
  2794. end
  2795. end else begin // BL=8
  2796. bl_pipeline[2*read_latency - 1] = 8;
  2797. if (mpr_en && col%8) begin
  2798. $display ("%m: at time %t WARNING: col[2:0] must be set to 3'b000 during a BL8 Multipurpose Register read", $time);
  2799. end
  2800. end
  2801. rd_bc = addr[BC];
  2802. ck_bank_read[bank] <= ck_cntr;
  2803. ck_group_read[bank[1]] <= ck_cntr;
  2804. ck_read <= ck_cntr;
  2805. end
  2806. end
  2807. ZQ : begin
  2808. if (mpr_en) begin
  2809. $display ("%m: at time %t ERROR: %s Failure. Multipurpose Register must be disabled.", $time, cmd_string[cmd]);
  2810. if (STOP_ON_ERROR) $stop(0);
  2811. end else if (|active_bank) begin
  2812. $display ("%m: at time %t ERROR: %s Failure. All banks must be Precharged.", $time, cmd_string[cmd]);
  2813. if (STOP_ON_ERROR) $stop(0);
  2814. end else begin
  2815. if (DEBUG) $display ("%m: at time %t INFO: %s long = %d", $time, cmd_string[cmd], addr[AP]);
  2816. if (addr[AP]) begin
  2817. zq_set = 1;
  2818. if (init_done) begin
  2819. ck_zqoper <= ck_cntr;
  2820. end else begin
  2821. ck_zqinit <= ck_cntr;
  2822. end
  2823. end else begin
  2824. ck_zqcs <= ck_cntr;
  2825. end
  2826. end
  2827. end
  2828. NOP: begin
  2829. if (in_power_down) begin
  2830. if (($time - tm_freq_change < TCKSRX) || (ck_cntr - ck_freq_change < TCKSRX_TCK))
  2831. $display ("%m: at time %t ERROR: tCKSRX violation during Power Down Exit", $time);
  2832. if ($time - tm_cke_cmd > TPD_MAX)
  2833. $display ("%m: at time %t ERROR: tPD maximum violation during Power Down Exit", $time);
  2834. if (DEBUG) $display ("%m: at time %t INFO: Power Down Exit", $time);
  2835. in_power_down = 0;
  2836. if ((active_bank == 0) && low_power) begin // precharge power down with dll off
  2837. if (ck_cntr - ck_odt < write_latency - 1)
  2838. $display ("%m: at time %t WARNING: tANPD violation during Power Down Exit. Synchronous or asynchronous change in termination resistance is possible.", $time);
  2839. tm_slow_exit_pd <= $time;
  2840. ck_slow_exit_pd <= ck_cntr;
  2841. end
  2842. tm_power_down <= $time;
  2843. ck_power_down <= ck_cntr;
  2844. end
  2845. if (in_self_refresh) begin
  2846. if (($time - tm_freq_change < TCKSRX) || (ck_cntr - ck_freq_change < TCKSRX_TCK))
  2847. $display ("%m: at time %t ERROR: tCKSRX violation during Self Refresh Exit", $time);
  2848. if (ck_cntr - ck_cke_cmd < TCKESR_TCK)
  2849. $display ("%m: at time %t ERROR: tCKESR violation during Self Refresh Exit", $time);
  2850. if ($time - tm_cke < TISXR)
  2851. $display ("%m: at time %t ERROR: tISXR violation during Self Refresh Exit", $time);
  2852. if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Exit", $time);
  2853. in_self_refresh = 0;
  2854. ck_dll_reset <= ck_cntr;
  2855. ck_self_refresh <= ck_cntr;
  2856. tm_self_refresh <= $time;
  2857. tm_refresh <= $time;
  2858. end
  2859. end
  2860. endcase
  2861. if ((prev_cke !== 1) && (cmd !== NOP)) begin
  2862. $display ("%m: at time %t ERROR: NOP or Deselect is required when CKE goes active.", $time);
  2863. end
  2864. if (!init_done) begin
  2865. case (init_step)
  2866. 0 : begin
  2867. if ($time - tm_rst_n < 500000000 && check_strict_timing)
  2868. $display ("%m at time %t WARNING: 500 us is required after RST_N goes inactive before CKE goes active.", $time);
  2869. tm_txpr <= $time;
  2870. ck_txpr <= ck_cntr;
  2871. init_step = init_step + 1;
  2872. end
  2873. 1 : if (dll_en) init_step = init_step + 1;
  2874. 2 : begin
  2875. if (&init_mode_reg && init_dll_reset && zq_set) begin
  2876. if (DEBUG) $display ("%m: at time %t INFO: Initialization Sequence is complete", $time);
  2877. init_done = 1;
  2878. end
  2879. end
  2880. endcase
  2881. end
  2882. end else if (prev_cke) begin
  2883. if ((!init_done) && (init_step > 1)) begin
  2884. $display ("%m: at time %t ERROR: CKE must remain active until the initialization sequence is complete.", $time);
  2885. if (STOP_ON_ERROR) $stop(0);
  2886. end
  2887. case (cmd)
  2888. REFRESH : begin
  2889. if ($time - tm_txpr < TXPR)
  2890. $display ("%m: at time %t ERROR: tXPR violation during %s", $time, cmd_string[SELF_REF]);
  2891. for (j=0; j<=SELF_REF; j=j+1) begin
  2892. chk_err(DIFF_BANK, bank, j, SELF_REF);
  2893. end
  2894. if (mpr_en) begin
  2895. $display ("%m: at time %t ERROR: Self Refresh Failure. Multipurpose Register must be disabled.", $time);
  2896. if (STOP_ON_ERROR) $stop(0);
  2897. end else if (|active_bank) begin
  2898. $display ("%m: at time %t ERROR: Self Refresh Failure. All banks must be Precharged.", $time);
  2899. if (STOP_ON_ERROR) $stop(0);
  2900. end else if (odt_state) begin
  2901. $display ("%m: at time %t ERROR: Self Refresh Failure. ODT must be off prior to entering Self Refresh", $time);
  2902. if (STOP_ON_ERROR) $stop(0);
  2903. end else if (!init_done) begin
  2904. $display ("%m: at time %t ERROR: Self Refresh Failure. Initialization sequence is not complete.", $time);
  2905. if (STOP_ON_ERROR) $stop(0);
  2906. end else begin
  2907. if (DEBUG) $display ("%m: at time %t INFO: Self Refresh Enter", $time);
  2908. if (feature_pasr)
  2909. // Partial Array Self Refresh
  2910. case (pasr)
  2911. 3'b000 : ;//keep Bank 0-7
  2912. 3'b001 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 4-7 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'hF0); end
  2913. 3'b010 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 2-7 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'hFC); end
  2914. 3'b011 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 1-7 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'hFE); end
  2915. 3'b100 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 0-1 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'h03); end
  2916. 3'b101 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 0-3 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'h0F); end
  2917. 3'b110 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 0-5 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'h3F); end
  2918. 3'b111 : begin if (DEBUG) $display("%m: at time %t INFO: Banks 0-6 will be lost due to Partial Array Self Refresh", $time); erase_banks(8'h7F); end
  2919. endcase
  2920. in_self_refresh = 1;
  2921. dll_locked = 0;
  2922. end
  2923. end
  2924. NOP : begin
  2925. // entering precharge power down with dll off and tANPD has not been satisfied
  2926. if (low_power && (active_bank == 0) && |odt_pipeline)
  2927. $display ("%m: at time %t WARNING: tANPD violation during %s. Synchronous or asynchronous change in termination resistance is possible.", $time, cmd_string[PWR_DOWN]);
  2928. if ($time - tm_txpr < TXPR)
  2929. $display ("%m: at time %t ERROR: tXPR violation during %s", $time, cmd_string[PWR_DOWN]);
  2930. for (j=0; j<=SELF_REF; j=j+1) begin
  2931. chk_err(DIFF_BANK, bank, j, PWR_DOWN);
  2932. end
  2933. if (mpr_en) begin
  2934. $display ("%m: at time %t ERROR: Power Down Failure. Multipurpose Register must be disabled.", $time);
  2935. if (STOP_ON_ERROR) $stop(0);
  2936. end else if (!init_done) begin
  2937. $display ("%m: at time %t ERROR: Power Down Failure. Initialization sequence is not complete.", $time);
  2938. if (STOP_ON_ERROR) $stop(0);
  2939. end else begin
  2940. if (DEBUG) begin
  2941. if (|active_bank) begin
  2942. $display ("%m: at time %t INFO: Active Power Down Enter", $time);
  2943. end else begin
  2944. $display ("%m: at time %t INFO: Precharge Power Down Enter", $time);
  2945. end
  2946. end
  2947. in_power_down = 1;
  2948. end
  2949. end
  2950. default : begin
  2951. $display ("%m: at time %t ERROR: NOP, Deselect, or Refresh is required when CKE goes inactive.", $time);
  2952. end
  2953. endcase
  2954. end else if (in_self_refresh || in_power_down) begin
  2955. if ((ck_cntr - ck_cke_cmd <= TCPDED) && (cmd !== NOP))
  2956. $display ("%m: at time %t ERROR: tCPDED violation during Power Down or Self Refresh Entry. NOP or Deselect is required.", $time);
  2957. end
  2958. prev_cke = cke;
  2959. end
  2960. endtask
  2961. task data_task;
  2962. reg [BA_BITS-1:0] bank;
  2963. reg [ROW_BITS-1:0] row;
  2964. reg [COL_BITS-1:0] col;
  2965. integer i;
  2966. integer j;
  2967. begin
  2968. if (diff_ck) begin
  2969. for (i=0; i<32; i=i+1) begin
  2970. if (dq_in_valid && dll_locked && ($time - tm_dqs_neg[i] < $rtoi(TDSS*tck_avg)))
  2971. $display ("%m: at time %t ERROR: tDSS violation on %s bit %d", $time, dqs_string[i/16], i%16);
  2972. if (check_write_dqs_high[i])
  2973. $display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period.", $time, dqs_string[i/16], i%16);
  2974. end
  2975. check_write_dqs_high <= 0;
  2976. end else begin
  2977. for (i=0; i<32; i=i+1) begin
  2978. if (dll_locked && dq_in_valid) begin
  2979. tm_tdqss = abs_value(1.0*tm_ck_pos - tm_dqss_pos[i]);
  2980. if ((tm_tdqss < tck_avg/2.0) && (tm_tdqss > TDQSS*tck_avg))
  2981. $display ("%m: at time %t ERROR: tDQSS violation on %s bit %d", $time, dqs_string[i/16], i%16);
  2982. end
  2983. if (check_write_dqs_low[i])
  2984. $display ("%m: at time %t ERROR: %s bit %d latching edge required during the preceding clock period", $time, dqs_string[i/16], i%16);
  2985. end
  2986. check_write_preamble <= 0;
  2987. check_write_postamble <= 0;
  2988. check_write_dqs_low <= 0;
  2989. end
  2990. if (wr_pipeline[0] || rd_pipeline[0]) begin
  2991. bank = ba_pipeline[0];
  2992. row = row_pipeline[0];
  2993. col = col_pipeline[0];
  2994. burst_cntr = 0;
  2995. memory_read(bank, row, col, memory_data);
  2996. end
  2997. // burst counter
  2998. if (burst_cntr < burst_length) begin
  2999. burst_position = col ^ burst_cntr;
  3000. if (!burst_order) begin
  3001. burst_position[BO_BITS-1:0] = col + burst_cntr;
  3002. end
  3003. burst_cntr = burst_cntr + 1;
  3004. end
  3005. // write dqs counter
  3006. if (wr_pipeline[WDQS_PRE + 1]) begin
  3007. wdqs_cntr = WDQS_PRE + bl_pipeline[WDQS_PRE + 1] + WDQS_PST - 1;
  3008. end
  3009. // write dqs
  3010. if ((wr_pipeline[2]) && (wdq_cntr == 0)) begin //write preamble
  3011. check_write_preamble <= ({DQS_BITS{1'b1}}<<16) | {DQS_BITS{1'b1}};
  3012. end
  3013. if (wdqs_cntr > 1) begin // write data
  3014. if ((wdqs_cntr - WDQS_PST)%2) begin
  3015. check_write_dqs_high <= ({DQS_BITS{1'b1}}<<16) | {DQS_BITS{1'b1}};
  3016. end else begin
  3017. check_write_dqs_low <= ({DQS_BITS{1'b1}}<<16) | {DQS_BITS{1'b1}};
  3018. end
  3019. end
  3020. if (wdqs_cntr == WDQS_PST) begin // write postamble
  3021. check_write_postamble <= ({DQS_BITS{1'b1}}<<16) | {DQS_BITS{1'b1}};
  3022. end
  3023. if (wdqs_cntr > 0) begin
  3024. wdqs_cntr = wdqs_cntr - 1;
  3025. end
  3026. // write dq
  3027. if (dq_in_valid) begin // write data
  3028. bit_mask = 0;
  3029. if (diff_ck) begin
  3030. for (i=0; i<DM_BITS; i=i+1) begin
  3031. bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_neg[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS));
  3032. end
  3033. memory_data = (dq_in_neg<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask);
  3034. end else begin
  3035. for (i=0; i<DM_BITS; i=i+1) begin
  3036. bit_mask = bit_mask | ({`DQ_PER_DQS{~dm_in_pos[i]}}<<(burst_position*DQ_BITS + i*`DQ_PER_DQS));
  3037. end
  3038. memory_data = (dq_in_pos<<(burst_position*DQ_BITS) & bit_mask) | (memory_data & ~bit_mask);
  3039. end
  3040. dq_temp = memory_data>>(burst_position*DQ_BITS);
  3041. if (DEBUG) $display ("%m: at time %t INFO: WRITE @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp);
  3042. if (burst_cntr%BL_MIN == 0) begin
  3043. memory_write(bank, row, col, memory_data);
  3044. end
  3045. end
  3046. if (wr_pipeline[1]) begin
  3047. wdq_cntr = bl_pipeline[1];
  3048. end
  3049. if (wdq_cntr > 0) begin
  3050. wdq_cntr = wdq_cntr - 1;
  3051. dq_in_valid = 1'b1;
  3052. end else begin
  3053. dq_in_valid = 1'b0;
  3054. dqs_in_valid <= 1'b0;
  3055. for (i=0; i<31; i=i+1) begin
  3056. wdqs_pos_cntr[i] <= 0;
  3057. end
  3058. end
  3059. if (wr_pipeline[0]) begin
  3060. b2b_write <= 1'b0;
  3061. end
  3062. if (wr_pipeline[2]) begin
  3063. if (dqs_in_valid) begin
  3064. b2b_write <= 1'b1;
  3065. end
  3066. dqs_in_valid <= 1'b1;
  3067. wr_burst_length = bl_pipeline[2];
  3068. end
  3069. // read dqs enable counter
  3070. if (rd_pipeline[RDQSEN_PRE]) begin
  3071. rdqsen_cntr = RDQSEN_PRE + bl_pipeline[RDQSEN_PRE] + RDQSEN_PST - 1;
  3072. end
  3073. if (rdqsen_cntr > 0) begin
  3074. rdqsen_cntr = rdqsen_cntr - 1;
  3075. dqs_out_en = 1'b1;
  3076. end else begin
  3077. dqs_out_en = 1'b0;
  3078. end
  3079. // read dqs counter
  3080. if (rd_pipeline[RDQS_PRE]) begin
  3081. rdqs_cntr = RDQS_PRE + bl_pipeline[RDQS_PRE] + RDQS_PST - 1;
  3082. end
  3083. // read dqs
  3084. if (((rd_pipeline>>1 & {RDQS_PRE{1'b1}}) > 0) && (rdq_cntr == 0)) begin //read preamble
  3085. dqs_out = 1'b0;
  3086. end else if (rdqs_cntr > RDQS_PST) begin // read data
  3087. dqs_out = rdqs_cntr - RDQS_PST;
  3088. end else if (rdqs_cntr > 0) begin // read postamble
  3089. dqs_out = 1'b0;
  3090. end else begin
  3091. dqs_out = 1'b1;
  3092. end
  3093. if (rdqs_cntr > 0) begin
  3094. rdqs_cntr = rdqs_cntr - 1;
  3095. end
  3096. // read dq enable counter
  3097. if (rd_pipeline[RDQEN_PRE]) begin
  3098. rdqen_cntr = RDQEN_PRE + bl_pipeline[RDQEN_PRE] + RDQEN_PST;
  3099. end
  3100. if (rdqen_cntr > 0) begin
  3101. rdqen_cntr = rdqen_cntr - 1;
  3102. dq_out_en = 1'b1;
  3103. end else begin
  3104. dq_out_en = 1'b0;
  3105. end
  3106. // read dq
  3107. if (rd_pipeline[0]) begin
  3108. rdq_cntr = bl_pipeline[0];
  3109. end
  3110. if (rdq_cntr > 0) begin // read data
  3111. if (mpr_en) begin
  3112. `ifdef MPR_DQ0 // DQ0 output MPR data, other DQ low
  3113. if (mpr_select == 2'b00) begin // Calibration Pattern
  3114. dq_temp = {DQS_BITS{{`DQ_PER_DQS-1{1'b0}}, calibration_pattern[burst_position]}};
  3115. end else if (odts_readout && (mpr_select == 2'b11)) begin // Temp Sensor (ODTS)
  3116. dq_temp = {DQS_BITS{{`DQ_PER_DQS-1{1'b0}}, temp_sensor[burst_position]}};
  3117. end else begin // Reserved
  3118. dq_temp = {DQS_BITS{{`DQ_PER_DQS-1{1'b0}}, 1'bx}};
  3119. end
  3120. `else // all DQ output MPR data
  3121. if (mpr_select == 2'b00) begin // Calibration Pattern
  3122. dq_temp = {DQS_BITS{{`DQ_PER_DQS{calibration_pattern[burst_position]}}}};
  3123. end else if (odts_readout && (mpr_select == 2'b11)) begin // Temp Sensor (ODTS)
  3124. dq_temp = {DQS_BITS{{`DQ_PER_DQS{temp_sensor[burst_position]}}}};
  3125. end else begin // Reserved
  3126. dq_temp = {DQS_BITS{{`DQ_PER_DQS{1'bx}}}};
  3127. end
  3128. `endif
  3129. if (DEBUG) $display ("%m: at time %t READ @ DQS MultiPurpose Register %d, col = %d, data = %b", $time, mpr_select, burst_position, dq_temp[0]);
  3130. end else begin
  3131. dq_temp = memory_data>>(burst_position*DQ_BITS);
  3132. if (DEBUG) $display ("%m: at time %t INFO: READ @ DQS= bank = %h row = %h col = %h data = %h",$time, bank, row, (-1*BL_MAX & col) + burst_position, dq_temp);
  3133. end
  3134. dq_out = dq_temp;
  3135. rdq_cntr = rdq_cntr - 1;
  3136. end else begin
  3137. dq_out = {DQ_BITS{1'b1}};
  3138. end
  3139. // delay signals prior to output
  3140. if (RANDOM_OUT_DELAY && (dqs_out_en || (|dqs_out_en_dly) || dq_out_en || (|dq_out_en_dly))) begin
  3141. for (i=0; i<DQS_BITS; i=i+1) begin
  3142. // DQSCK requirements
  3143. // 1.) less than tDQSCK
  3144. // 2.) greater than -tDQSCK
  3145. // 3.) cannot change more than tQH + tDQSQ from previous DQS edge
  3146. dqsck_max = TDQSCK;
  3147. if (dqsck_max > dqsck[i] + TQH*tck_avg + TDQSQ) begin
  3148. dqsck_max = dqsck[i] + TQH*tck_avg + TDQSQ;
  3149. end
  3150. dqsck_min = -1*TDQSCK;
  3151. if (dqsck_min < dqsck[i] - TQH*tck_avg - TDQSQ) begin
  3152. dqsck_min = dqsck[i] - TQH*tck_avg - TDQSQ;
  3153. end
  3154. // DQSQ requirements
  3155. // 1.) less than tDQSQ
  3156. // 2.) greater than 0
  3157. // 3.) greater than tQH from the previous DQS edge
  3158. dqsq_min = 0;
  3159. if (dqsq_min < dqsck[i] - TQH*tck_avg) begin
  3160. dqsq_min = dqsck[i] - TQH*tck_avg;
  3161. end
  3162. if (dqsck_min == dqsck_max) begin
  3163. dqsck[i] = dqsck_min;
  3164. end else begin
  3165. dqsck[i] = $dist_uniform(seed, dqsck_min, dqsck_max);
  3166. end
  3167. dqsq_max = TDQSQ + dqsck[i];
  3168. dqs_out_en_dly[i] <= #(tck_avg/2) dqs_out_en;
  3169. dqs_out_dly[i] <= #(tck_avg/2 + dqsck[i]) dqs_out;
  3170. if (!write_levelization) begin
  3171. for (j=0; j<`DQ_PER_DQS; j=j+1) begin
  3172. dq_out_en_dly[i*`DQ_PER_DQS + j] <= #(tck_avg/2) dq_out_en;
  3173. if (dqsq_min == dqsq_max) begin
  3174. dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2 + dqsq_min) dq_out[i*`DQ_PER_DQS + j];
  3175. end else begin
  3176. dq_out_dly [i*`DQ_PER_DQS + j] <= #(tck_avg/2 + $dist_uniform(seed, dqsq_min, dqsq_max)) dq_out[i*`DQ_PER_DQS + j];
  3177. end
  3178. end
  3179. end
  3180. end
  3181. end else begin
  3182. out_delay = tck_avg/2;
  3183. dqs_out_en_dly <= #(out_delay) {DQS_BITS{dqs_out_en}};
  3184. dqs_out_dly <= #(out_delay) {DQS_BITS{dqs_out }};
  3185. if (write_levelization !== 1'b1) begin
  3186. dq_out_en_dly <= #(out_delay) {DQ_BITS {dq_out_en }};
  3187. dq_out_dly <= #(out_delay) {DQ_BITS {dq_out }};
  3188. end
  3189. end
  3190. end
  3191. endtask
  3192. always @ (posedge rst_n_in) begin : reset
  3193. integer i;
  3194. if (rst_n_in) begin
  3195. if ($time < 200000000 && check_strict_timing)
  3196. $display ("%m at time %t WARNING: 200 us is required before RST_N goes inactive.", $time);
  3197. if (cke_in !== 1'b0)
  3198. $display ("%m: at time %t ERROR: CKE must be inactive when RST_N goes inactive.", $time);
  3199. if ($time - tm_cke < 10000)
  3200. $display ("%m: at time %t ERROR: CKE must be maintained inactive for 10 ns before RST_N goes inactive.", $time);
  3201. // clear memory
  3202. `ifdef MAX_MEM
  3203. // verification group does not erase memory
  3204. // for (banki = 0; banki < `BANKS; banki = banki + 1) begin
  3205. // $fclose(memfd[banki]);
  3206. // memfd[banki] = open_bank_file(banki);
  3207. // end
  3208. `else
  3209. memory_used <= 0; //erase memory
  3210. `endif
  3211. end
  3212. end
  3213. always @(negedge rst_n_in or posedge diff_ck or negedge diff_ck) begin : main
  3214. integer i;
  3215. if (!rst_n_in) begin
  3216. reset_task;
  3217. end else begin
  3218. if (!in_self_refresh && (diff_ck !== 1'b0) && (diff_ck !== 1'b1))
  3219. $display ("%m: at time %t ERROR: CK and CK_N are not allowed to go to an unknown state.", $time);
  3220. data_task;
  3221. // Clock Frequency Change is legal:
  3222. // 1.) During Self Refresh
  3223. // 2.) During Precharge Power Down (DLL on or off)
  3224. if (in_self_refresh || (in_power_down && (active_bank == 0))) begin
  3225. if (diff_ck) begin
  3226. tjit_per_rtime = $time - tm_ck_pos - tck_avg;
  3227. end else begin
  3228. tjit_per_rtime = $time - tm_ck_neg - tck_avg;
  3229. end
  3230. if (dll_locked && (abs_value(tjit_per_rtime) > TJIT_PER)) begin
  3231. if ((tm_ck_pos - tm_cke_cmd < TCKSRE) || (ck_cntr - ck_cke_cmd < TCKSRE_TCK))
  3232. $display ("%m: at time %t ERROR: tCKSRE violation during Self Refresh or Precharge Power Down Entry", $time);
  3233. if (odt_state) begin
  3234. $display ("%m: at time %t ERROR: Clock Frequency Change Failure. ODT must be off prior to Clock Frequency Change.", $time);
  3235. if (STOP_ON_ERROR) $stop(0);
  3236. end else begin
  3237. if (DEBUG) $display ("%m: at time %t INFO: Clock Frequency Change detected. DLL Reset is Required.", $time);
  3238. tm_freq_change <= $time;
  3239. ck_freq_change <= ck_cntr;
  3240. dll_locked = 0;
  3241. end
  3242. end
  3243. end
  3244. if (diff_ck) begin
  3245. // check setup of command signals
  3246. if ($time > TIS) begin
  3247. if ($time - tm_cke < TIS)
  3248. $display ("%m: at time %t ERROR: tIS violation on CKE by %t", $time, tm_cke + TIS - $time);
  3249. if (cke_in) begin
  3250. for (i=0; i<22; i=i+1) begin
  3251. if ($time - tm_cmd_addr[i] < TIS)
  3252. $display ("%m: at time %t ERROR: tIS violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIS - $time);
  3253. end
  3254. end
  3255. end
  3256. // update current state
  3257. if (dll_locked) begin
  3258. if (mr_chk == 0) begin
  3259. mr_chk = 1;
  3260. end else if (init_mode_reg[0] && (mr_chk == 1)) begin
  3261. // check CL value against the clock frequency
  3262. if (cas_latency*tck_avg < CL_TIME && check_strict_timing)
  3263. $display ("%m: at time %t ERROR: CAS Latency = %d is illegal @tCK(avg) = %f", $time, cas_latency, tck_avg);
  3264. // check WR value against the clock frequency
  3265. if (ceil(write_recovery*tck_avg) < TWR)
  3266. $display ("%m: at time %t ERROR: Write Recovery = %d is illegal @tCK(avg) = %f", $time, write_recovery, tck_avg);
  3267. // check the CWL value against the clock frequency
  3268. if (check_strict_timing) begin
  3269. case (cas_write_latency)
  3270. 5 : if (tck_avg < 2500.0) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3271. 6 : if ((tck_avg < 1875.0) || (tck_avg >= 2500.0)) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3272. 7 : if ((tck_avg < 1500.0) || (tck_avg >= 1875.0)) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3273. 8 : if ((tck_avg < 1250.0) || (tck_avg >= 1500.0)) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3274. 9 : if ((tck_avg < 15e3/14) || (tck_avg >= 1250.0)) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3275. 10: if ((tck_avg < 937.5) || (tck_avg >= 15e3/14)) $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3276. default : $display ("%m: at time %t ERROR: CWL = %d is illegal @tCK(avg) = %f", $time, cas_write_latency, tck_avg);
  3277. endcase
  3278. // check the CL value against the clock frequency
  3279. if (!valid_cl(cas_latency, cas_write_latency))
  3280. $display ("%m: at time %t ERROR: CAS Latency = %d is not valid when CAS Write Latency = %d", $time, cas_latency, cas_write_latency);
  3281. end
  3282. mr_chk = 2;
  3283. end
  3284. end else if (!in_self_refresh) begin
  3285. mr_chk = 0;
  3286. if (ck_cntr - ck_dll_reset == TDLLK) begin
  3287. dll_locked = 1;
  3288. end
  3289. end
  3290. if (|auto_precharge_bank) begin
  3291. for (i=0; i<`BANKS; i=i+1) begin
  3292. // Write with Auto Precharge Calculation
  3293. // 1. Meet minimum tRAS requirement
  3294. // 2. Write Latency PLUS BL/2 cycles PLUS WR after Write command
  3295. if (write_precharge_bank[i]) begin
  3296. if ($time - tm_bank_activate[i] >= TRAS_MIN) begin
  3297. if (ck_cntr - ck_bank_write[i] >= write_latency + burst_length/2 + write_recovery) begin
  3298. if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i);
  3299. write_precharge_bank[i] = 0;
  3300. active_bank[i] = 0;
  3301. auto_precharge_bank[i] = 0;
  3302. tm_bank_precharge[i] = $time;
  3303. tm_precharge = $time;
  3304. ck_precharge = ck_cntr;
  3305. end
  3306. end
  3307. end
  3308. // Read with Auto Precharge Calculation
  3309. // 1. Meet minimum tRAS requirement
  3310. // 2. Additive Latency plus 4 cycles after Read command
  3311. // 3. tRTP after the last 8-bit prefetch
  3312. if (read_precharge_bank[i]) begin
  3313. if (($time - tm_bank_activate[i] >= TRAS_MIN) && (ck_cntr - ck_bank_read[i] >= additive_latency + TRTP_TCK)) begin
  3314. read_precharge_bank[i] = 0;
  3315. // In case the internal precharge is pushed out by tRTP, tRP starts at the point where
  3316. // the internal precharge happens (not at the next rising clock edge after this event).
  3317. if ($time - tm_bank_read_end[i] < TRTP) begin
  3318. if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", tm_bank_read_end[i] + TRTP, i);
  3319. active_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0;
  3320. auto_precharge_bank[i] <= #(tm_bank_read_end[i] + TRTP - $time) 0;
  3321. tm_bank_precharge[i] <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP;
  3322. tm_precharge <= #(tm_bank_read_end[i] + TRTP - $time) tm_bank_read_end[i] + TRTP;
  3323. ck_precharge = ck_cntr;
  3324. end else begin
  3325. if (DEBUG) $display ("%m: at time %t INFO: Auto Precharge bank %d", $time, i);
  3326. active_bank[i] = 0;
  3327. auto_precharge_bank[i] = 0;
  3328. tm_bank_precharge[i] = $time;
  3329. tm_precharge = $time;
  3330. ck_precharge = ck_cntr;
  3331. end
  3332. end
  3333. end
  3334. end
  3335. end
  3336. // respond to incoming command
  3337. if (cke_in ^ prev_cke) begin
  3338. tm_cke_cmd <= $time;
  3339. ck_cke_cmd <= ck_cntr;
  3340. end
  3341. cmd_task(cke_in, cmd_n_in, ba_in, addr_in);
  3342. if ((cmd_n_in == WRITE) || (cmd_n_in == READ)) begin
  3343. al_pipeline[2*additive_latency] = 1'b1;
  3344. end
  3345. if (al_pipeline[0]) begin
  3346. // check tRCD after additive latency
  3347. if ((rd_pipeline[2*cas_latency - 1]) && ($time - tm_bank_activate[ba_pipeline[2*cas_latency - 1]] < TRCD))
  3348. $display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[READ]);
  3349. if ((wr_pipeline[2*cas_write_latency + 1]) && ($time - tm_bank_activate[ba_pipeline[2*cas_write_latency + 1]] < TRCD))
  3350. $display ("%m: at time %t ERROR: tRCD violation during %s", $time, cmd_string[WRITE]);
  3351. // check tWTR after additive latency
  3352. if (rd_pipeline[2*cas_latency - 1]) begin //{
  3353. if (truebl4) begin //{
  3354. i = ba_pipeline[2*cas_latency - 1];
  3355. if ($time - tm_group_write_end[i[1]] < TWTR)
  3356. $display ("%m: at time %t ERROR: tWTR violation during %s", $time, cmd_string[READ]);
  3357. if ($time - tm_write_end < TWTR_DG)
  3358. $display ("%m: at time %t ERROR: tWTR_DG violation during %s", $time, cmd_string[READ]);
  3359. end else begin
  3360. if ($time - tm_write_end < TWTR)
  3361. $display ("%m: at time %t ERROR: tWTR violation during %s", $time, cmd_string[READ]);
  3362. end
  3363. end
  3364. end
  3365. if (rd_pipeline) begin
  3366. if (rd_pipeline[2*cas_latency - 1]) begin
  3367. tm_bank_read_end[ba_pipeline[2*cas_latency - 1]] <= $time;
  3368. end
  3369. end
  3370. for (i=0; i<`BANKS; i=i+1) begin
  3371. if ((ck_cntr - ck_bank_write[i] > write_latency) && (ck_cntr - ck_bank_write[i] <= write_latency + burst_length/2)) begin
  3372. tm_bank_write_end[i] <= $time;
  3373. tm_group_write_end[i[1]] <= $time;
  3374. tm_write_end <= $time;
  3375. end
  3376. end
  3377. // clk pin is disabled during self refresh
  3378. if (!in_self_refresh && tm_ck_pos ) begin
  3379. tjit_cc_time = $time - tm_ck_pos - tck_i;
  3380. tck_i = $time - tm_ck_pos;
  3381. tck_avg = tck_avg - tck_sample[ck_cntr%TDLLK]/$itor(TDLLK);
  3382. tck_avg = tck_avg + tck_i/$itor(TDLLK);
  3383. tck_sample[ck_cntr%TDLLK] = tck_i;
  3384. tjit_per_rtime = tck_i - tck_avg;
  3385. if (dll_locked && check_strict_timing) begin
  3386. // check accumulated error
  3387. terr_nper_rtime = 0;
  3388. for (i=0; i<12; i=i+1) begin
  3389. terr_nper_rtime = terr_nper_rtime + tck_sample[i] - tck_avg;
  3390. terr_nper_rtime = abs_value(terr_nper_rtime);
  3391. case (i)
  3392. 0 :;
  3393. 1 : if (terr_nper_rtime - TERR_2PER >= 1.0) $display ("%m: at time %t ERROR: tERR(2per) violation by %f ps.", $time, terr_nper_rtime - TERR_2PER);
  3394. 2 : if (terr_nper_rtime - TERR_3PER >= 1.0) $display ("%m: at time %t ERROR: tERR(3per) violation by %f ps.", $time, terr_nper_rtime - TERR_3PER);
  3395. 3 : if (terr_nper_rtime - TERR_4PER >= 1.0) $display ("%m: at time %t ERROR: tERR(4per) violation by %f ps.", $time, terr_nper_rtime - TERR_4PER);
  3396. 4 : if (terr_nper_rtime - TERR_5PER >= 1.0) $display ("%m: at time %t ERROR: tERR(5per) violation by %f ps.", $time, terr_nper_rtime - TERR_5PER);
  3397. 5 : if (terr_nper_rtime - TERR_6PER >= 1.0) $display ("%m: at time %t ERROR: tERR(6per) violation by %f ps.", $time, terr_nper_rtime - TERR_6PER);
  3398. 6 : if (terr_nper_rtime - TERR_7PER >= 1.0) $display ("%m: at time %t ERROR: tERR(7per) violation by %f ps.", $time, terr_nper_rtime - TERR_7PER);
  3399. 7 : if (terr_nper_rtime - TERR_8PER >= 1.0) $display ("%m: at time %t ERROR: tERR(8per) violation by %f ps.", $time, terr_nper_rtime - TERR_8PER);
  3400. 8 : if (terr_nper_rtime - TERR_9PER >= 1.0) $display ("%m: at time %t ERROR: tERR(9per) violation by %f ps.", $time, terr_nper_rtime - TERR_9PER);
  3401. 9 : if (terr_nper_rtime - TERR_10PER >= 1.0) $display ("%m: at time %t ERROR: tERR(10per) violation by %f ps.", $time, terr_nper_rtime - TERR_10PER);
  3402. 10 : if (terr_nper_rtime - TERR_11PER >= 1.0) $display ("%m: at time %t ERROR: tERR(11per) violation by %f ps.", $time, terr_nper_rtime - TERR_11PER);
  3403. 11 : if (terr_nper_rtime - TERR_12PER >= 1.0) $display ("%m: at time %t ERROR: tERR(12per) violation by %f ps.", $time, terr_nper_rtime - TERR_12PER);
  3404. endcase
  3405. end
  3406. // check tCK min/max/jitter
  3407. if (abs_value(tjit_per_rtime) - TJIT_PER >= 1.0)
  3408. $display ("%m: at time %t ERROR: tJIT(per) violation by %f ps.", $time, abs_value(tjit_per_rtime) - TJIT_PER);
  3409. if (abs_value(tjit_cc_time) - TJIT_CC >= 1.0)
  3410. $display ("%m: at time %t ERROR: tJIT(cc) violation by %f ps.", $time, abs_value(tjit_cc_time) - TJIT_CC);
  3411. if (TCK_MIN - tck_avg >= 1.0)
  3412. $display ("%m: at time %t ERROR: tCK(avg) minimum violation by %f ps.", $time, TCK_MIN - tck_avg);
  3413. if (tck_avg - TCK_MAX >= 1.0)
  3414. $display ("%m: at time %t ERROR: tCK(avg) maximum violation by %f ps.", $time, tck_avg - TCK_MAX);
  3415. // check tCL
  3416. if (tm_ck_neg - $time < TCL_ABS_MIN*tck_avg)
  3417. $display ("%m: at time %t ERROR: tCL(abs) minimum violation on CLK by %t", $time, TCL_ABS_MIN*tck_avg - tm_ck_neg + $time);
  3418. if (tcl_avg < TCL_AVG_MIN*tck_avg)
  3419. $display ("%m: at time %t ERROR: tCL(avg) minimum violation on CLK by %t", $time, TCL_AVG_MIN*tck_avg - tcl_avg);
  3420. if (tcl_avg > TCL_AVG_MAX*tck_avg)
  3421. $display ("%m: at time %t ERROR: tCL(avg) maximum violation on CLK by %t", $time, tcl_avg - TCL_AVG_MAX*tck_avg);
  3422. end
  3423. // calculate the tch avg jitter
  3424. tch_avg = tch_avg - tch_sample[ck_cntr%TDLLK]/$itor(TDLLK);
  3425. tch_avg = tch_avg + tch_i/$itor(TDLLK);
  3426. tch_sample[ck_cntr%TDLLK] = tch_i;
  3427. tjit_ch_rtime = tch_i - tch_avg;
  3428. duty_cycle = tch_avg/tck_avg;
  3429. // update timers/counters
  3430. tcl_i <= $time - tm_ck_neg;
  3431. end
  3432. prev_odt <= odt_in;
  3433. // update timers/counters
  3434. ck_cntr <= ck_cntr + 1;
  3435. tm_ck_pos = $time;
  3436. end else begin
  3437. // clk pin is disabled during self refresh
  3438. if (!in_self_refresh) begin
  3439. if (dll_locked && check_strict_timing) begin
  3440. if ($time - tm_ck_pos < TCH_ABS_MIN*tck_avg)
  3441. $display ("%m: at time %t ERROR: tCH(abs) minimum violation on CLK by %t", $time, TCH_ABS_MIN*tck_avg - $time + tm_ck_pos);
  3442. if (tch_avg < TCH_AVG_MIN*tck_avg)
  3443. $display ("%m: at time %t ERROR: tCH(avg) minimum violation on CLK by %t", $time, TCH_AVG_MIN*tck_avg - tch_avg);
  3444. if (tch_avg > TCH_AVG_MAX*tck_avg)
  3445. $display ("%m: at time %t ERROR: tCH(avg) maximum violation on CLK by %t", $time, tch_avg - TCH_AVG_MAX*tck_avg);
  3446. end
  3447. // calculate the tcl avg jitter
  3448. tcl_avg = tcl_avg - tcl_sample[ck_cntr%TDLLK]/$itor(TDLLK);
  3449. tcl_avg = tcl_avg + tcl_i/$itor(TDLLK);
  3450. tcl_sample[ck_cntr%TDLLK] = tcl_i;
  3451. // update timers/counters
  3452. tch_i <= $time - tm_ck_pos;
  3453. end
  3454. tm_ck_neg = $time;
  3455. end
  3456. // on die termination
  3457. if (odt_en || dyn_odt_en) begin
  3458. // odt pin is disabled during self refresh
  3459. if (!in_self_refresh && diff_ck) begin
  3460. if ($time - tm_odt < TIS)
  3461. $display ("%m: at time %t ERROR: tIS violation on ODT by %t", $time, tm_odt + TIS - $time);
  3462. if (prev_odt ^ odt_in) begin
  3463. if (!dll_locked)
  3464. $display ("%m: at time %t WARNING: tDLLK violation during ODT transition.", $time);
  3465. if (($time - tm_load_mode < TMOD) || (ck_cntr - ck_load_mode < TMOD_TCK))
  3466. $display ("%m: at time %t ERROR: tMOD violation during ODT transition", $time);
  3467. if (ck_cntr - ck_zqinit < TZQINIT)
  3468. $display ("%m: at time %t ERROR: TZQinit violation during ODT transition", $time);
  3469. if (ck_cntr - ck_zqoper < TZQOPER)
  3470. $display ("%m: at time %t ERROR: TZQoper violation during ODT transition", $time);
  3471. if (ck_cntr - ck_zqcs < TZQCS)
  3472. $display ("%m: at time %t ERROR: tZQcs violation during ODT transition", $time);
  3473. // if (($time - tm_slow_exit_pd < TXPDLL) || (ck_cntr - ck_slow_exit_pd < TXPDLL_TCK))
  3474. // $display ("%m: at time %t ERROR: tXPDLL violation during ODT transition", $time);
  3475. if (ck_cntr - ck_self_refresh < TXSDLL)
  3476. $display ("%m: at time %t ERROR: tXSDLL violation during ODT transition", $time);
  3477. if (in_self_refresh)
  3478. $display ("%m: at time %t ERROR: Illegal ODT transition during Self Refresh.", $time);
  3479. if (!odt_in && (ck_cntr - ck_odt < ODTH4))
  3480. $display ("%m: at time %t ERROR: ODTH4 violation during ODT transition", $time);
  3481. if (!odt_in && (ck_cntr - ck_odth8 < ODTH8))
  3482. $display ("%m: at time %t ERROR: ODTH8 violation during ODT transition", $time);
  3483. if (($time - tm_slow_exit_pd < TXPDLL) || (ck_cntr - ck_slow_exit_pd < TXPDLL_TCK))
  3484. $display ("%m: at time %t WARNING: tXPDLL during ODT transition. Synchronous or asynchronous change in termination resistance is possible.", $time);
  3485. // async ODT mode applies:
  3486. // 1.) during precharge power down with DLL off
  3487. // 2.) if tANPD has not been satisfied
  3488. // 3.) until tXPDLL has been satisfied
  3489. if ((in_power_down && low_power && (active_bank == 0)) || ($time - tm_slow_exit_pd < TXPDLL) || (ck_cntr - ck_slow_exit_pd < TXPDLL_TCK)) begin
  3490. odt_state = odt_in;
  3491. if (DEBUG && odt_en) $display ("%m: at time %t INFO: Async On Die Termination Rtt_NOM = %d Ohm", $time, {32{odt_state}} & get_rtt_nom(odt_rtt_nom));
  3492. if (odt_state) begin
  3493. odt_state_dly <= #(TAONPD) odt_state;
  3494. end else begin
  3495. odt_state_dly <= #(TAOFPD) odt_state;
  3496. end
  3497. // sync ODT mode applies:
  3498. // 1.) during normal operation
  3499. // 2.) during active power down
  3500. // 3.) during precharge power down with DLL on
  3501. end else begin
  3502. odt_pipeline[2*(write_latency - 2)] = 1'b1; // ODTLon, ODTLoff
  3503. end
  3504. ck_odt <= ck_cntr;
  3505. end
  3506. end
  3507. if (odt_pipeline[0]) begin
  3508. odt_state = ~odt_state;
  3509. if (DEBUG && odt_en) $display ("%m: at time %t INFO: Sync On Die Termination Rtt_NOM = %d Ohm", $time, {32{odt_state}} & get_rtt_nom(odt_rtt_nom));
  3510. if (odt_state) begin
  3511. odt_state_dly <= #(TAON) odt_state;
  3512. end else begin
  3513. odt_state_dly <= #(TAOF*tck_avg) odt_state;
  3514. end
  3515. end
  3516. if (rd_pipeline[RDQSEN_PRE]) begin
  3517. odt_cntr = 1 + RDQSEN_PRE + bl_pipeline[RDQSEN_PRE] + RDQSEN_PST - 1;
  3518. end
  3519. if (odt_cntr > 0) begin
  3520. if (odt_state) begin
  3521. $display ("%m: at time %t ERROR: On Die Termination must be OFF during Read data transfer.", $time);
  3522. end
  3523. odt_cntr = odt_cntr - 1;
  3524. end
  3525. if (dyn_odt_en && odt_state) begin
  3526. if (DEBUG && (dyn_odt_state ^ dyn_odt_pipeline[0]))
  3527. $display ("%m: at time %t INFO: Sync On Die Termination Rtt_WR = %d Ohm", $time, {32{dyn_odt_pipeline[0]}} & get_rtt_wr(odt_rtt_wr));
  3528. dyn_odt_state = dyn_odt_pipeline[0];
  3529. end
  3530. dyn_odt_state_dly <= #(TADC*tck_avg) dyn_odt_state;
  3531. end
  3532. /*
  3533. if (cke_in && write_levelization) begin
  3534. for (i=0; i<DQS_BITS; i=i+1) begin
  3535. if ($time - tm_dqs_pos[i] < TWLH)
  3536. $display ("%m: at time %t WARNING: tWLH violation on DQS bit %d positive edge. Indeterminate CK capture is possible.", $time, i);
  3537. end
  3538. end
  3539. */
  3540. // shift pipelines
  3541. if (|wr_pipeline || |rd_pipeline || |al_pipeline) begin
  3542. al_pipeline = al_pipeline>>1;
  3543. wr_pipeline = wr_pipeline>>1;
  3544. rd_pipeline = rd_pipeline>>1;
  3545. for (i=0; i<`MAX_PIPE; i=i+1) begin
  3546. bl_pipeline[i] = bl_pipeline[i+1];
  3547. ba_pipeline[i] = ba_pipeline[i+1];
  3548. row_pipeline[i] = row_pipeline[i+1];
  3549. col_pipeline[i] = col_pipeline[i+1];
  3550. end
  3551. end
  3552. if (|odt_pipeline || |dyn_odt_pipeline) begin
  3553. odt_pipeline = odt_pipeline>>1;
  3554. dyn_odt_pipeline = dyn_odt_pipeline>>1;
  3555. end
  3556. end
  3557. end
  3558. // receiver(s)
  3559. task dqs_even_receiver;
  3560. input [3:0] i;
  3561. reg [63:0] bit_mask;
  3562. begin
  3563. bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS);
  3564. if (dqs_even[i]) begin
  3565. if (tdqs_en) begin // tdqs disables dm
  3566. dm_in_pos[i] = 1'b0;
  3567. end else begin
  3568. dm_in_pos[i] = dm_in[i];
  3569. end
  3570. dq_in_pos = (dq_in & bit_mask) | (dq_in_pos & ~bit_mask);
  3571. end
  3572. end
  3573. endtask
  3574. always @(posedge dqs_even[ 0]) dqs_even_receiver( 0);
  3575. always @(posedge dqs_even[ 1]) dqs_even_receiver( 1);
  3576. always @(posedge dqs_even[ 2]) dqs_even_receiver( 2);
  3577. always @(posedge dqs_even[ 3]) dqs_even_receiver( 3);
  3578. always @(posedge dqs_even[ 4]) dqs_even_receiver( 4);
  3579. always @(posedge dqs_even[ 5]) dqs_even_receiver( 5);
  3580. always @(posedge dqs_even[ 6]) dqs_even_receiver( 6);
  3581. always @(posedge dqs_even[ 7]) dqs_even_receiver( 7);
  3582. always @(posedge dqs_even[ 8]) dqs_even_receiver( 8);
  3583. always @(posedge dqs_even[ 9]) dqs_even_receiver( 9);
  3584. always @(posedge dqs_even[10]) dqs_even_receiver(10);
  3585. always @(posedge dqs_even[11]) dqs_even_receiver(11);
  3586. always @(posedge dqs_even[12]) dqs_even_receiver(12);
  3587. always @(posedge dqs_even[13]) dqs_even_receiver(13);
  3588. always @(posedge dqs_even[14]) dqs_even_receiver(14);
  3589. always @(posedge dqs_even[15]) dqs_even_receiver(15);
  3590. task dqs_odd_receiver;
  3591. input [3:0] i;
  3592. reg [63:0] bit_mask;
  3593. begin
  3594. bit_mask = {`DQ_PER_DQS{1'b1}}<<(i*`DQ_PER_DQS);
  3595. if (dqs_odd[i]) begin
  3596. if (tdqs_en) begin // tdqs disables dm
  3597. dm_in_neg[i] = 1'b0;
  3598. end else begin
  3599. dm_in_neg[i] = dm_in[i];
  3600. end
  3601. dq_in_neg = (dq_in & bit_mask) | (dq_in_neg & ~bit_mask);
  3602. end
  3603. end
  3604. endtask
  3605. always @(posedge dqs_odd[ 0]) dqs_odd_receiver( 0);
  3606. always @(posedge dqs_odd[ 1]) dqs_odd_receiver( 1);
  3607. always @(posedge dqs_odd[ 2]) dqs_odd_receiver( 2);
  3608. always @(posedge dqs_odd[ 3]) dqs_odd_receiver( 3);
  3609. always @(posedge dqs_odd[ 4]) dqs_odd_receiver( 4);
  3610. always @(posedge dqs_odd[ 5]) dqs_odd_receiver( 5);
  3611. always @(posedge dqs_odd[ 6]) dqs_odd_receiver( 6);
  3612. always @(posedge dqs_odd[ 7]) dqs_odd_receiver( 7);
  3613. always @(posedge dqs_odd[ 8]) dqs_odd_receiver( 8);
  3614. always @(posedge dqs_odd[ 9]) dqs_odd_receiver( 9);
  3615. always @(posedge dqs_odd[10]) dqs_odd_receiver(10);
  3616. always @(posedge dqs_odd[11]) dqs_odd_receiver(11);
  3617. always @(posedge dqs_odd[12]) dqs_odd_receiver(12);
  3618. always @(posedge dqs_odd[13]) dqs_odd_receiver(13);
  3619. always @(posedge dqs_odd[14]) dqs_odd_receiver(14);
  3620. always @(posedge dqs_odd[15]) dqs_odd_receiver(15);
  3621. // Processes to check hold and pulse width of control signals
  3622. always @(posedge rst_n_in) begin
  3623. if ($time > 100000) begin
  3624. if (tm_rst_n + 100000 > $time)
  3625. $display ("%m: at time %t ERROR: RST_N pulse width violation by %t", $time, tm_rst_n + 100000 - $time);
  3626. end
  3627. tm_rst_n = $time;
  3628. end
  3629. always @(cke_in) begin
  3630. if (rst_n_in) begin
  3631. if ($time > TIH) begin
  3632. if ($time - tm_ck_pos < TIH)
  3633. $display ("%m: at time %t ERROR: tIH violation on CKE by %t", $time, tm_ck_pos + TIH - $time);
  3634. end
  3635. if ($time - tm_cke < TIPW)
  3636. $display ("%m: at time %t ERROR: tIPW violation on CKE by %t", $time, tm_cke + TIPW - $time);
  3637. end
  3638. tm_cke = $time;
  3639. end
  3640. always @(odt_in) begin
  3641. if (rst_n_in && odt_en && !in_self_refresh) begin
  3642. if ($time - tm_ck_pos < TIH)
  3643. $display ("%m: at time %t ERROR: tIH violation on ODT by %t", $time, tm_ck_pos + TIH - $time);
  3644. if ($time - tm_odt < TIPW)
  3645. $display ("%m: at time %t ERROR: tIPW violation on ODT by %t", $time, tm_odt + TIPW - $time);
  3646. end
  3647. tm_odt = $time;
  3648. end
  3649. task cmd_addr_timing_check;
  3650. input i;
  3651. reg [4:0] i;
  3652. begin
  3653. if (rst_n_in && prev_cke) begin
  3654. if ($time - tm_ck_pos < TIH)
  3655. $display ("%m: at time %t ERROR: tIH violation on %s by %t", $time, cmd_addr_string[i], tm_ck_pos + TIH - $time);
  3656. if ($time - tm_cmd_addr[i] < TIPW)
  3657. $display ("%m: at time %t ERROR: tIPW violation on %s by %t", $time, cmd_addr_string[i], tm_cmd_addr[i] + TIPW - $time);
  3658. end
  3659. tm_cmd_addr[i] = $time;
  3660. end
  3661. endtask
  3662. always @(cs_n_in ) cmd_addr_timing_check( 0);
  3663. always @(ras_n_in ) cmd_addr_timing_check( 1);
  3664. always @(cas_n_in ) cmd_addr_timing_check( 2);
  3665. always @(we_n_in ) cmd_addr_timing_check( 3);
  3666. always @(ba_in [ 0]) cmd_addr_timing_check( 4);
  3667. always @(ba_in [ 1]) cmd_addr_timing_check( 5);
  3668. always @(ba_in [ 2]) cmd_addr_timing_check( 6);
  3669. always @(addr_in[ 0]) cmd_addr_timing_check( 7);
  3670. always @(addr_in[ 1]) cmd_addr_timing_check( 8);
  3671. always @(addr_in[ 2]) cmd_addr_timing_check( 9);
  3672. always @(addr_in[ 3]) cmd_addr_timing_check(10);
  3673. always @(addr_in[ 4]) cmd_addr_timing_check(11);
  3674. always @(addr_in[ 5]) cmd_addr_timing_check(12);
  3675. always @(addr_in[ 6]) cmd_addr_timing_check(13);
  3676. always @(addr_in[ 7]) cmd_addr_timing_check(14);
  3677. always @(addr_in[ 8]) cmd_addr_timing_check(15);
  3678. always @(addr_in[ 9]) cmd_addr_timing_check(16);
  3679. always @(addr_in[10]) cmd_addr_timing_check(17);
  3680. always @(addr_in[11]) cmd_addr_timing_check(18);
  3681. always @(addr_in[12]) cmd_addr_timing_check(19);
  3682. always @(addr_in[13]) cmd_addr_timing_check(20);
  3683. always @(addr_in[14]) cmd_addr_timing_check(21);
  3684. always @(addr_in[15]) cmd_addr_timing_check(22);
  3685. // Processes to check setup and hold of data signals
  3686. task dm_timing_check;
  3687. input i;
  3688. reg [3:0] i;
  3689. begin
  3690. if (dqs_in_valid) begin
  3691. if ($time - tm_dqs[i] < TDH)
  3692. $display ("%m: at time %t ERROR: tDH violation on DM bit %d by %t", $time, i, tm_dqs[i] + TDH - $time);
  3693. if (check_dm_tdipw[i]) begin
  3694. if ($time - tm_dm[i] < TDIPW)
  3695. $display ("%m: at time %t ERROR: tDIPW violation on DM bit %d by %t", $time, i, tm_dm[i] + TDIPW - $time);
  3696. end
  3697. end
  3698. check_dm_tdipw[i] <= 1'b0;
  3699. tm_dm[i] = $time;
  3700. end
  3701. endtask
  3702. always @(dm_in[ 0]) dm_timing_check( 0);
  3703. always @(dm_in[ 1]) dm_timing_check( 1);
  3704. always @(dm_in[ 2]) dm_timing_check( 2);
  3705. always @(dm_in[ 3]) dm_timing_check( 3);
  3706. always @(dm_in[ 4]) dm_timing_check( 4);
  3707. always @(dm_in[ 5]) dm_timing_check( 5);
  3708. always @(dm_in[ 6]) dm_timing_check( 6);
  3709. always @(dm_in[ 7]) dm_timing_check( 7);
  3710. always @(dm_in[ 8]) dm_timing_check( 8);
  3711. always @(dm_in[ 9]) dm_timing_check( 9);
  3712. always @(dm_in[10]) dm_timing_check(10);
  3713. always @(dm_in[11]) dm_timing_check(11);
  3714. always @(dm_in[12]) dm_timing_check(12);
  3715. always @(dm_in[13]) dm_timing_check(13);
  3716. always @(dm_in[14]) dm_timing_check(14);
  3717. always @(dm_in[15]) dm_timing_check(15);
  3718. task dq_timing_check;
  3719. input i;
  3720. reg [5:0] i;
  3721. begin
  3722. if (dqs_in_valid) begin
  3723. if ($time - tm_dqs[i/`DQ_PER_DQS] < TDH)
  3724. $display ("%m: at time %t ERROR: tDH violation on DQ bit %d by %t", $time, i, tm_dqs[i/`DQ_PER_DQS] + TDH - $time);
  3725. if (check_dq_tdipw[i]) begin
  3726. if ($time - tm_dq[i] < TDIPW)
  3727. $display ("%m: at time %t ERROR: tDIPW violation on DQ bit %d by %t", $time, i, tm_dq[i] + TDIPW - $time);
  3728. end
  3729. end
  3730. check_dq_tdipw[i] <= 1'b0;
  3731. tm_dq[i] = $time;
  3732. end
  3733. endtask
  3734. always @(dq_in[ 0]) dq_timing_check( 0);
  3735. always @(dq_in[ 1]) dq_timing_check( 1);
  3736. always @(dq_in[ 2]) dq_timing_check( 2);
  3737. always @(dq_in[ 3]) dq_timing_check( 3);
  3738. always @(dq_in[ 4]) dq_timing_check( 4);
  3739. always @(dq_in[ 5]) dq_timing_check( 5);
  3740. always @(dq_in[ 6]) dq_timing_check( 6);
  3741. always @(dq_in[ 7]) dq_timing_check( 7);
  3742. always @(dq_in[ 8]) dq_timing_check( 8);
  3743. always @(dq_in[ 9]) dq_timing_check( 9);
  3744. always @(dq_in[10]) dq_timing_check(10);
  3745. always @(dq_in[11]) dq_timing_check(11);
  3746. always @(dq_in[12]) dq_timing_check(12);
  3747. always @(dq_in[13]) dq_timing_check(13);
  3748. always @(dq_in[14]) dq_timing_check(14);
  3749. always @(dq_in[15]) dq_timing_check(15);
  3750. always @(dq_in[16]) dq_timing_check(16);
  3751. always @(dq_in[17]) dq_timing_check(17);
  3752. always @(dq_in[18]) dq_timing_check(18);
  3753. always @(dq_in[19]) dq_timing_check(19);
  3754. always @(dq_in[20]) dq_timing_check(20);
  3755. always @(dq_in[21]) dq_timing_check(21);
  3756. always @(dq_in[22]) dq_timing_check(22);
  3757. always @(dq_in[23]) dq_timing_check(23);
  3758. always @(dq_in[24]) dq_timing_check(24);
  3759. always @(dq_in[25]) dq_timing_check(25);
  3760. always @(dq_in[26]) dq_timing_check(26);
  3761. always @(dq_in[27]) dq_timing_check(27);
  3762. always @(dq_in[28]) dq_timing_check(28);
  3763. always @(dq_in[29]) dq_timing_check(29);
  3764. always @(dq_in[30]) dq_timing_check(30);
  3765. always @(dq_in[31]) dq_timing_check(31);
  3766. always @(dq_in[32]) dq_timing_check(32);
  3767. always @(dq_in[33]) dq_timing_check(33);
  3768. always @(dq_in[34]) dq_timing_check(34);
  3769. always @(dq_in[35]) dq_timing_check(35);
  3770. always @(dq_in[36]) dq_timing_check(36);
  3771. always @(dq_in[37]) dq_timing_check(37);
  3772. always @(dq_in[38]) dq_timing_check(38);
  3773. always @(dq_in[39]) dq_timing_check(39);
  3774. always @(dq_in[40]) dq_timing_check(40);
  3775. always @(dq_in[41]) dq_timing_check(41);
  3776. always @(dq_in[42]) dq_timing_check(42);
  3777. always @(dq_in[43]) dq_timing_check(43);
  3778. always @(dq_in[44]) dq_timing_check(44);
  3779. always @(dq_in[45]) dq_timing_check(45);
  3780. always @(dq_in[46]) dq_timing_check(46);
  3781. always @(dq_in[47]) dq_timing_check(47);
  3782. always @(dq_in[48]) dq_timing_check(48);
  3783. always @(dq_in[49]) dq_timing_check(49);
  3784. always @(dq_in[50]) dq_timing_check(50);
  3785. always @(dq_in[51]) dq_timing_check(51);
  3786. always @(dq_in[52]) dq_timing_check(52);
  3787. always @(dq_in[53]) dq_timing_check(53);
  3788. always @(dq_in[54]) dq_timing_check(54);
  3789. always @(dq_in[55]) dq_timing_check(55);
  3790. always @(dq_in[56]) dq_timing_check(56);
  3791. always @(dq_in[57]) dq_timing_check(57);
  3792. always @(dq_in[58]) dq_timing_check(58);
  3793. always @(dq_in[59]) dq_timing_check(59);
  3794. always @(dq_in[60]) dq_timing_check(60);
  3795. always @(dq_in[61]) dq_timing_check(61);
  3796. always @(dq_in[62]) dq_timing_check(62);
  3797. always @(dq_in[63]) dq_timing_check(63);
  3798. task dqs_pos_timing_check;
  3799. input i;
  3800. reg [4:0] i;
  3801. reg [3:0] j;
  3802. begin
  3803. if (write_levelization && i<16) begin
  3804. if (ck_cntr - ck_load_mode < TWLMRD)
  3805. $display ("%m: at time %t ERROR: tWLMRD violation on DQS bit %d positive edge.", $time, i);
  3806. /*
  3807. if (($time - tm_ck_pos < TWLS) || ($time - tm_ck_neg < TWLS))
  3808. $display ("%m: at time %t WARNING: tWLS violation on DQS bit %d positive edge. Indeterminate CK capture is possible.", $time, i);
  3809. */
  3810. if (DEBUG)
  3811. $display ("%m: at time %t Write Leveling @ DQS ck = %b", $time, diff_ck);
  3812. dq_out_en_dly[i*`DQ_PER_DQS] <= #(TWLO) 1'b1;
  3813. dq_out_dly[i*`DQ_PER_DQS] <= #(TWLO) diff_ck;
  3814. for (j=1; j<`DQ_PER_DQS; j=j+1) begin
  3815. dq_out_en_dly[i*`DQ_PER_DQS+j] <= #(TWLO + TWLOE) 1'b1;
  3816. dq_out_dly[i*`DQ_PER_DQS+j] <= #(TWLO + TWLOE) 1'b0;
  3817. end
  3818. end
  3819. if (dqs_in_valid && ((wdqs_pos_cntr[i] < wr_burst_length/2) || b2b_write)) begin
  3820. if (dqs_in[i] ^ prev_dqs_in[i]) begin
  3821. if (dll_locked) begin
  3822. if (check_write_preamble[i]) begin
  3823. if ($time - tm_dqs_pos[i] < $rtoi(TWPRE*tck_avg))
  3824. $display ("%m: at time %t ERROR: tWPRE violation on &s bit %d", $time, dqs_string[i/16], i%16);
  3825. end else if (check_write_postamble[i]) begin
  3826. if ($time - tm_dqs_neg[i] < $rtoi(TWPST*tck_avg))
  3827. $display ("%m: at time %t ERROR: tWPST violation on %s bit %d", $time, dqs_string[i/16], i%16);
  3828. end else begin
  3829. if ($time - tm_dqs_neg[i] < $rtoi(TDQSL*tck_avg))
  3830. $display ("%m: at time %t ERROR: tDQSL violation on %s bit %d", $time, dqs_string[i/16], i%16);
  3831. end
  3832. end
  3833. if ($time - tm_dm[i%16] < TDS)
  3834. $display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%16] + TDS - $time);
  3835. if (!dq_out_en) begin
  3836. for (j=0; j<`DQ_PER_DQS; j=j+1) begin
  3837. if ($time - tm_dq[(i%16)*`DQ_PER_DQS+j] < TDS)
  3838. $display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[(i%16)*`DQ_PER_DQS+j] + TDS - $time);
  3839. check_dq_tdipw[(i%16)*`DQ_PER_DQS+j] <= 1'b1;
  3840. end
  3841. end
  3842. if ((wdqs_pos_cntr[i] < wr_burst_length/2) && !b2b_write) begin
  3843. wdqs_pos_cntr[i] <= wdqs_pos_cntr[i] + 1;
  3844. end else begin
  3845. wdqs_pos_cntr[i] <= 1;
  3846. end
  3847. check_dm_tdipw[i%16] <= 1'b1;
  3848. check_write_preamble[i] <= 1'b0;
  3849. check_write_postamble[i] <= 1'b0;
  3850. check_write_dqs_low[i] <= 1'b0;
  3851. tm_dqs[i%16] <= $time;
  3852. end else begin
  3853. $display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/16], i%16);
  3854. end
  3855. end
  3856. tm_dqss_pos[i] <= $time;
  3857. tm_dqs_pos[i] = $time;
  3858. prev_dqs_in[i] <= dqs_in[i];
  3859. end
  3860. endtask
  3861. always @(posedge dqs_in[ 0]) dqs_pos_timing_check( 0);
  3862. always @(posedge dqs_in[ 1]) dqs_pos_timing_check( 1);
  3863. always @(posedge dqs_in[ 2]) dqs_pos_timing_check( 2);
  3864. always @(posedge dqs_in[ 3]) dqs_pos_timing_check( 3);
  3865. always @(posedge dqs_in[ 4]) dqs_pos_timing_check( 4);
  3866. always @(posedge dqs_in[ 5]) dqs_pos_timing_check( 5);
  3867. always @(posedge dqs_in[ 6]) dqs_pos_timing_check( 6);
  3868. always @(posedge dqs_in[ 7]) dqs_pos_timing_check( 7);
  3869. always @(posedge dqs_in[ 8]) dqs_pos_timing_check( 8);
  3870. always @(posedge dqs_in[ 9]) dqs_pos_timing_check( 9);
  3871. always @(posedge dqs_in[10]) dqs_pos_timing_check(10);
  3872. always @(posedge dqs_in[11]) dqs_pos_timing_check(11);
  3873. always @(posedge dqs_in[12]) dqs_pos_timing_check(12);
  3874. always @(posedge dqs_in[13]) dqs_pos_timing_check(13);
  3875. always @(posedge dqs_in[14]) dqs_pos_timing_check(14);
  3876. always @(posedge dqs_in[15]) dqs_pos_timing_check(15);
  3877. always @(negedge dqs_in[16]) dqs_pos_timing_check(16);
  3878. always @(negedge dqs_in[17]) dqs_pos_timing_check(17);
  3879. always @(negedge dqs_in[18]) dqs_pos_timing_check(18);
  3880. always @(negedge dqs_in[19]) dqs_pos_timing_check(19);
  3881. always @(negedge dqs_in[20]) dqs_pos_timing_check(20);
  3882. always @(negedge dqs_in[21]) dqs_pos_timing_check(21);
  3883. always @(negedge dqs_in[22]) dqs_pos_timing_check(22);
  3884. always @(negedge dqs_in[23]) dqs_pos_timing_check(23);
  3885. always @(negedge dqs_in[24]) dqs_pos_timing_check(24);
  3886. always @(negedge dqs_in[25]) dqs_pos_timing_check(25);
  3887. always @(negedge dqs_in[26]) dqs_pos_timing_check(26);
  3888. always @(negedge dqs_in[27]) dqs_pos_timing_check(27);
  3889. always @(negedge dqs_in[28]) dqs_pos_timing_check(28);
  3890. always @(negedge dqs_in[29]) dqs_pos_timing_check(29);
  3891. always @(negedge dqs_in[30]) dqs_pos_timing_check(30);
  3892. always @(negedge dqs_in[31]) dqs_pos_timing_check(31);
  3893. task dqs_neg_timing_check;
  3894. input i;
  3895. reg [4:0] i;
  3896. reg [3:0] j;
  3897. begin
  3898. if (write_levelization && i<16) begin
  3899. if (ck_cntr - ck_load_mode < TWLDQSEN)
  3900. $display ("%m: at time %t ERROR: tWLDQSEN violation on DQS bit %d.", $time, i);
  3901. if ($time - tm_dqs_pos[i] < $rtoi(TDQSH*tck_avg))
  3902. $display ("%m: at time %t ERROR: tDQSH violation on DQS bit %d by %t", $time, i, tm_dqs_pos[i] + TDQSH*tck_avg - $time);
  3903. end
  3904. if (dqs_in_valid && (wdqs_pos_cntr[i] > 0) && check_write_dqs_high[i]) begin
  3905. if (dqs_in[i] ^ prev_dqs_in[i]) begin
  3906. if (dll_locked) begin
  3907. if ($time - tm_dqs_pos[i] < $rtoi(TDQSH*tck_avg))
  3908. $display ("%m: at time %t ERROR: tDQSH violation on %s bit %d", $time, dqs_string[i/16], i%16);
  3909. if ($time - tm_ck_pos < $rtoi(TDSH*tck_avg))
  3910. $display ("%m: at time %t ERROR: tDSH violation on %s bit %d", $time, dqs_string[i/16], i%16);
  3911. end
  3912. if ($time - tm_dm[i%16] < TDS)
  3913. $display ("%m: at time %t ERROR: tDS violation on DM bit %d by %t", $time, i, tm_dm[i%16] + TDS - $time);
  3914. if (!dq_out_en) begin
  3915. for (j=0; j<`DQ_PER_DQS; j=j+1) begin
  3916. if ($time - tm_dq[(i%16)*`DQ_PER_DQS+j] < TDS)
  3917. $display ("%m: at time %t ERROR: tDS violation on DQ bit %d by %t", $time, i*`DQ_PER_DQS+j, tm_dq[(i%16)*`DQ_PER_DQS+j] + TDS - $time);
  3918. check_dq_tdipw[(i%16)*`DQ_PER_DQS+j] <= 1'b1;
  3919. end
  3920. end
  3921. check_dm_tdipw[i%16] <= 1'b1;
  3922. tm_dqs[i%16] <= $time;
  3923. end else begin
  3924. $display ("%m: at time %t ERROR: Invalid latching edge on %s bit %d", $time, dqs_string[i/16], i%16);
  3925. end
  3926. end
  3927. check_write_dqs_high[i] <= 1'b0;
  3928. tm_dqs_neg[i] = $time;
  3929. prev_dqs_in[i] <= dqs_in[i];
  3930. end
  3931. endtask
  3932. always @(negedge dqs_in[ 0]) dqs_neg_timing_check( 0);
  3933. always @(negedge dqs_in[ 1]) dqs_neg_timing_check( 1);
  3934. always @(negedge dqs_in[ 2]) dqs_neg_timing_check( 2);
  3935. always @(negedge dqs_in[ 3]) dqs_neg_timing_check( 3);
  3936. always @(negedge dqs_in[ 4]) dqs_neg_timing_check( 4);
  3937. always @(negedge dqs_in[ 5]) dqs_neg_timing_check( 5);
  3938. always @(negedge dqs_in[ 6]) dqs_neg_timing_check( 6);
  3939. always @(negedge dqs_in[ 7]) dqs_neg_timing_check( 7);
  3940. always @(negedge dqs_in[ 8]) dqs_neg_timing_check( 8);
  3941. always @(negedge dqs_in[ 9]) dqs_neg_timing_check( 9);
  3942. always @(negedge dqs_in[10]) dqs_neg_timing_check(10);
  3943. always @(negedge dqs_in[11]) dqs_neg_timing_check(11);
  3944. always @(negedge dqs_in[12]) dqs_neg_timing_check(12);
  3945. always @(negedge dqs_in[13]) dqs_neg_timing_check(13);
  3946. always @(negedge dqs_in[14]) dqs_neg_timing_check(14);
  3947. always @(negedge dqs_in[15]) dqs_neg_timing_check(15);
  3948. always @(posedge dqs_in[16]) dqs_neg_timing_check(16);
  3949. always @(posedge dqs_in[17]) dqs_neg_timing_check(17);
  3950. always @(posedge dqs_in[18]) dqs_neg_timing_check(18);
  3951. always @(posedge dqs_in[19]) dqs_neg_timing_check(19);
  3952. always @(posedge dqs_in[20]) dqs_neg_timing_check(20);
  3953. always @(posedge dqs_in[21]) dqs_neg_timing_check(21);
  3954. always @(posedge dqs_in[22]) dqs_neg_timing_check(22);
  3955. always @(posedge dqs_in[23]) dqs_neg_timing_check(23);
  3956. always @(posedge dqs_in[24]) dqs_neg_timing_check(24);
  3957. always @(posedge dqs_in[25]) dqs_neg_timing_check(25);
  3958. always @(posedge dqs_in[26]) dqs_neg_timing_check(26);
  3959. always @(posedge dqs_in[27]) dqs_neg_timing_check(27);
  3960. always @(posedge dqs_in[28]) dqs_neg_timing_check(28);
  3961. always @(posedge dqs_in[29]) dqs_neg_timing_check(29);
  3962. always @(posedge dqs_in[30]) dqs_neg_timing_check(30);
  3963. always @(posedge dqs_in[31]) dqs_neg_timing_check(31);
  3964. endmodule