mt48lc16m16a2.v 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. /**************************************************************************
  2. *
  3. * File Name: MT48LC16M16A2.V
  4. * Version: 2.1
  5. * Date: June 6th, 2002
  6. * Model: BUS Functional
  7. * Simulator: Model Technology
  8. *
  9. * Dependencies: None
  10. *
  11. * Email: modelsupport@micron.com
  12. * Company: Micron Technology, Inc.
  13. * Model: MT48LC16M16A2 (4Meg x 16 x 4 Banks)
  14. *
  15. * Description: Micron 256Mb SDRAM Verilog model
  16. *
  17. * Limitation: - Doesn't check for 8192 cycle refresh
  18. *
  19. * Note: - Set simulator resolution to "ps" accuracy
  20. * - Set Debug = 0 to disable $display messages
  21. *
  22. * Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
  23. * WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
  25. * A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
  26. *
  27. * Copyright © 2001 Micron Semiconductor Products, Inc.
  28. * All rights researved
  29. *
  30. * Rev Author Date Changes
  31. * --- -------------------------- ---------------------------------------
  32. * 2.1 SH 06/06/2002 - Typo in bank multiplex
  33. * Micron Technology Inc.
  34. *
  35. * 2.0 SH 04/30/2002 - Second release
  36. * Micron Technology Inc.
  37. *
  38. **************************************************************************/
  39. `timescale 1ns / 1ps
  40. module mt48lc16m16a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
  41. parameter addr_bits = 13;
  42. parameter data_bits = 16;
  43. parameter col_bits = 9;
  44. parameter mem_sizes = 4194303;
  45. inout [data_bits - 1 : 0] Dq;
  46. input [addr_bits - 1 : 0] Addr;
  47. input [1 : 0] Ba;
  48. input Clk;
  49. input Cke;
  50. input Cs_n;
  51. input Ras_n;
  52. input Cas_n;
  53. input We_n;
  54. input [1 : 0] Dqm;
  55. reg [data_bits - 1 : 0] Bank0 [0 : mem_sizes];
  56. reg [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
  57. reg [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
  58. reg [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
  59. reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline
  60. reg [col_bits - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline
  61. reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline
  62. reg [1 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline
  63. reg [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
  64. reg [addr_bits - 1 : 0] Mode_reg;
  65. reg [data_bits - 1 : 0] Dq_reg, Dq_dqm;
  66. reg [col_bits - 1 : 0] Col_temp, Burst_counter;
  67. reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate
  68. reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge
  69. reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command
  70. reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks)
  71. reg Auto_precharge [0 : 3]; // RW Auto Precharge (Bank)
  72. reg Read_precharge [0 : 3]; // R Auto Precharge
  73. reg Write_precharge [0 : 3]; // W Auto Precharge
  74. reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge
  75. reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge
  76. reg [1 : 0] RW_interrupt_bank; // RW Interrupt Bank
  77. integer RW_interrupt_counter [0 : 3]; // RW Interrupt Counter
  78. integer Count_precharge [0 : 3]; // RW Auto Precharge Counter
  79. reg Data_in_enable;
  80. reg Data_out_enable;
  81. reg [1 : 0] Bank, Prev_bank;
  82. reg [addr_bits - 1 : 0] Row;
  83. reg [col_bits - 1 : 0] Col, Col_brst;
  84. // Internal system clock
  85. reg CkeZ, Sys_clk;
  86. // Commands Decode
  87. wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
  88. wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n;
  89. wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
  90. wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n;
  91. wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
  92. wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
  93. wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
  94. // Burst Length Decode
  95. wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
  96. wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0];
  97. wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0];
  98. wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
  99. wire Burst_length_f = Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
  100. // CAS Latency Decode
  101. wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4];
  102. wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4];
  103. // Write Burst Mode
  104. wire Write_burst_mode = Mode_reg[9];
  105. wire Debug = 1'b0; // Debug messages : 1 = On
  106. wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ
  107. assign Dq = Dq_reg; // DQ buffer
  108. // Commands Operation
  109. `define ACT 0
  110. `define NOP 1
  111. `define READ 2
  112. `define WRITE 3
  113. `define PRECH 4
  114. `define A_REF 5
  115. `define BST 6
  116. `define LMR 7
  117. // Timing Parameters for -7E PC133 CL2
  118. parameter tAC = 6.0;
  119. parameter tHZ = 6.0;
  120. parameter tOH = 5.0;
  121. parameter tMRD = 2.0; // 2 Clk Cycles
  122. parameter tRAS = 42.0;
  123. parameter tRC = 60.0;
  124. parameter tRCD = 15.0;
  125. parameter tRFC = 64.0;
  126. parameter tRP = 15.0;
  127. parameter tRRD = 14.0;
  128. parameter tWRa = 7.0; // A2 Version - Auto precharge mode (1 Clk + 7 ns)
  129. parameter tWRm = 14.0; // A2 Version - Manual precharge mode (14 ns)
  130. // Timing Check variable
  131. time MRD_chk;
  132. time WR_chkm [0 : 3];
  133. time RFC_chk, RRD_chk;
  134. time RC_chk0, RC_chk1, RC_chk2, RC_chk3;
  135. time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
  136. time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
  137. time RP_chk0, RP_chk1, RP_chk2, RP_chk3;
  138. initial begin
  139. Dq_reg = {data_bits{1'bz}};
  140. Data_in_enable = 0; Data_out_enable = 0;
  141. Act_b0 = 1; Act_b1 = 1; Act_b2 = 1; Act_b3 = 1;
  142. Pc_b0 = 0; Pc_b1 = 0; Pc_b2 = 0; Pc_b3 = 0;
  143. WR_chkm[0] = 0; WR_chkm[1] = 0; WR_chkm[2] = 0; WR_chkm[3] = 0;
  144. RW_interrupt_read[0] = 0; RW_interrupt_read[1] = 0; RW_interrupt_read[2] = 0; RW_interrupt_read[3] = 0;
  145. RW_interrupt_write[0] = 0; RW_interrupt_write[1] = 0; RW_interrupt_write[2] = 0; RW_interrupt_write[3] = 0;
  146. MRD_chk = 0; RFC_chk = 0; RRD_chk = 0;
  147. RAS_chk0 = 0; RAS_chk1 = 0; RAS_chk2 = 0; RAS_chk3 = 0;
  148. RCD_chk0 = 0; RCD_chk1 = 0; RCD_chk2 = 0; RCD_chk3 = 0;
  149. RC_chk0 = 0; RC_chk1 = 0; RC_chk2 = 0; RC_chk3 = 0;
  150. RP_chk0 = 0; RP_chk1 = 0; RP_chk2 = 0; RP_chk3 = 0;
  151. $timeformat (-9, 1, " ns", 12);
  152. end
  153. // System clock generator
  154. always begin
  155. @ (posedge Clk) begin
  156. Sys_clk = CkeZ;
  157. CkeZ = Cke;
  158. end
  159. @ (negedge Clk) begin
  160. Sys_clk = 1'b0;
  161. end
  162. end
  163. always @ (posedge Sys_clk) begin
  164. // Internal Commamd Pipelined
  165. Command[0] = Command[1];
  166. Command[1] = Command[2];
  167. Command[2] = Command[3];
  168. Command[3] = `NOP;
  169. Col_addr[0] = Col_addr[1];
  170. Col_addr[1] = Col_addr[2];
  171. Col_addr[2] = Col_addr[3];
  172. Col_addr[3] = {col_bits{1'b0}};
  173. Bank_addr[0] = Bank_addr[1];
  174. Bank_addr[1] = Bank_addr[2];
  175. Bank_addr[2] = Bank_addr[3];
  176. Bank_addr[3] = 2'b0;
  177. Bank_precharge[0] = Bank_precharge[1];
  178. Bank_precharge[1] = Bank_precharge[2];
  179. Bank_precharge[2] = Bank_precharge[3];
  180. Bank_precharge[3] = 2'b0;
  181. A10_precharge[0] = A10_precharge[1];
  182. A10_precharge[1] = A10_precharge[2];
  183. A10_precharge[2] = A10_precharge[3];
  184. A10_precharge[3] = 1'b0;
  185. // Dqm pipeline for Read
  186. Dqm_reg0 = Dqm_reg1;
  187. Dqm_reg1 = Dqm;
  188. // Read or Write with Auto Precharge Counter
  189. if (Auto_precharge[0] === 1'b1) begin
  190. Count_precharge[0] = Count_precharge[0] + 1;
  191. end
  192. if (Auto_precharge[1] === 1'b1) begin
  193. Count_precharge[1] = Count_precharge[1] + 1;
  194. end
  195. if (Auto_precharge[2] === 1'b1) begin
  196. Count_precharge[2] = Count_precharge[2] + 1;
  197. end
  198. if (Auto_precharge[3] === 1'b1) begin
  199. Count_precharge[3] = Count_precharge[3] + 1;
  200. end
  201. // Read or Write Interrupt Counter
  202. if (RW_interrupt_write[0] === 1'b1) begin
  203. RW_interrupt_counter[0] = RW_interrupt_counter[0] + 1;
  204. end
  205. if (RW_interrupt_write[1] === 1'b1) begin
  206. RW_interrupt_counter[1] = RW_interrupt_counter[1] + 1;
  207. end
  208. if (RW_interrupt_write[2] === 1'b1) begin
  209. RW_interrupt_counter[2] = RW_interrupt_counter[2] + 1;
  210. end
  211. if (RW_interrupt_write[3] === 1'b1) begin
  212. RW_interrupt_counter[3] = RW_interrupt_counter[3] + 1;
  213. end
  214. // tMRD Counter
  215. MRD_chk = MRD_chk + 1;
  216. // Auto Refresh
  217. if (Aref_enable === 1'b1) begin
  218. if (Debug) begin
  219. $display ("%m : at time %t AREF : Auto Refresh", $time);
  220. end
  221. // Auto Refresh to Auto Refresh
  222. if ($time - RFC_chk < tRFC) begin
  223. $display ("%m : at time %t ERROR: tRFC violation during Auto Refresh", $time);
  224. end
  225. // Precharge to Auto Refresh
  226. if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
  227. ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
  228. $display ("%m : at time %t ERROR: tRP violation during Auto Refresh", $time);
  229. end
  230. // Precharge to Refresh
  231. if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
  232. $display ("%m : at time %t ERROR: All banks must be Precharge before Auto Refresh", $time);
  233. end
  234. // Load Mode Register to Auto Refresh
  235. if (MRD_chk < tMRD) begin
  236. $display ("%m : at time %t ERROR: tMRD violation during Auto Refresh", $time);
  237. end
  238. // Record Current tRFC time
  239. RFC_chk = $time;
  240. end
  241. // Load Mode Register
  242. if (Mode_reg_enable === 1'b1) begin
  243. // Register Mode
  244. Mode_reg = Addr;
  245. // Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
  246. if (Debug) begin
  247. $display ("%m : at time %t LMR : Load Mode Register", $time);
  248. // CAS Latency
  249. case (Addr[6 : 4])
  250. 3'b010 : $display ("%m : CAS Latency = 2");
  251. 3'b011 : $display ("%m : CAS Latency = 3");
  252. default : $display ("%m : CAS Latency = Reserved");
  253. endcase
  254. // Burst Length
  255. case (Addr[2 : 0])
  256. 3'b000 : $display ("%m : Burst Length = 1");
  257. 3'b001 : $display ("%m : Burst Length = 2");
  258. 3'b010 : $display ("%m : Burst Length = 4");
  259. 3'b011 : $display ("%m : Burst Length = 8");
  260. 3'b111 : $display ("%m : Burst Length = Full");
  261. default : $display ("%m : Burst Length = Reserved");
  262. endcase
  263. // Burst Type
  264. if (Addr[3] === 1'b0) begin
  265. $display ("%m : Burst Type = Sequential");
  266. end else if (Addr[3] === 1'b1) begin
  267. $display ("%m : Burst Type = Interleaved");
  268. end else begin
  269. $display ("%m : Burst Type = Reserved");
  270. end
  271. // Write Burst Mode
  272. if (Addr[9] === 1'b0) begin
  273. $display ("%m : Write Burst Mode = Programmed Burst Length");
  274. end else if (Addr[9] === 1'b1) begin
  275. $display ("%m : Write Burst Mode = Single Location Access");
  276. end else begin
  277. $display ("%m : Write Burst Mode = Reserved");
  278. end
  279. end
  280. // Precharge to Load Mode Register
  281. if (Pc_b0 === 1'b0 && Pc_b1 === 1'b0 && Pc_b2 === 1'b0 && Pc_b3 === 1'b0) begin
  282. $display ("%m : at time %t ERROR: all banks must be Precharge before Load Mode Register", $time);
  283. end
  284. // Precharge to Load Mode Register
  285. if (($time - RP_chk0 < tRP) || ($time - RP_chk1 < tRP) ||
  286. ($time - RP_chk2 < tRP) || ($time - RP_chk3 < tRP)) begin
  287. $display ("%m : at time %t ERROR: tRP violation during Load Mode Register", $time);
  288. end
  289. // Auto Refresh to Load Mode Register
  290. if ($time - RFC_chk < tRFC) begin
  291. $display ("%m : at time %t ERROR: tRFC violation during Load Mode Register", $time);
  292. end
  293. // Load Mode Register to Load Mode Register
  294. if (MRD_chk < tMRD) begin
  295. $display ("%m : at time %t ERROR: tMRD violation during Load Mode Register", $time);
  296. end
  297. // Reset MRD Counter
  298. MRD_chk = 0;
  299. end
  300. // Active Block (Latch Bank Address and Row Address)
  301. if (Active_enable === 1'b1) begin
  302. // Activate an open bank can corrupt data
  303. if ((Ba === 2'b00 && Act_b0 === 1'b1) || (Ba === 2'b01 && Act_b1 === 1'b1) ||
  304. (Ba === 2'b10 && Act_b2 === 1'b1) || (Ba === 2'b11 && Act_b3 === 1'b1)) begin
  305. $display ("%m : at time %t ERROR: Bank already activated -- data can be corrupted", $time);
  306. end
  307. // Activate Bank 0
  308. if (Ba === 2'b00 && Pc_b0 === 1'b1) begin
  309. // Debug Message
  310. if (Debug) begin
  311. $display ("%m : at time %t ACT : Bank = 0 Row = %d", $time, Addr);
  312. end
  313. // ACTIVE to ACTIVE command period
  314. if ($time - RC_chk0 < tRC) begin
  315. $display ("%m : at time %t ERROR: tRC violation during Activate bank 0", $time);
  316. end
  317. // Precharge to Activate Bank 0
  318. if ($time - RP_chk0 < tRP) begin
  319. $display ("%m : at time %t ERROR: tRP violation during Activate bank 0", $time);
  320. end
  321. // Record variables
  322. Act_b0 = 1'b1;
  323. Pc_b0 = 1'b0;
  324. B0_row_addr = Addr [addr_bits - 1 : 0];
  325. RAS_chk0 = $time;
  326. RC_chk0 = $time;
  327. RCD_chk0 = $time;
  328. end
  329. if (Ba == 2'b01 && Pc_b1 == 1'b1) begin
  330. // Debug Message
  331. if (Debug) begin
  332. $display ("%m : at time %t ACT : Bank = 1 Row = %d", $time, Addr);
  333. end
  334. // ACTIVE to ACTIVE command period
  335. if ($time - RC_chk1 < tRC) begin
  336. $display ("%m : at time %t ERROR: tRC violation during Activate bank 1", $time);
  337. end
  338. // Precharge to Activate Bank 1
  339. if ($time - RP_chk1 < tRP) begin
  340. $display ("%m : at time %t ERROR: tRP violation during Activate bank 1", $time);
  341. end
  342. // Record variables
  343. Act_b1 = 1'b1;
  344. Pc_b1 = 1'b0;
  345. B1_row_addr = Addr [addr_bits - 1 : 0];
  346. RAS_chk1 = $time;
  347. RC_chk1 = $time;
  348. RCD_chk1 = $time;
  349. end
  350. if (Ba == 2'b10 && Pc_b2 == 1'b1) begin
  351. // Debug Message
  352. if (Debug) begin
  353. $display ("%m : at time %t ACT : Bank = 2 Row = %d", $time, Addr);
  354. end
  355. // ACTIVE to ACTIVE command period
  356. if ($time - RC_chk2 < tRC) begin
  357. $display ("%m : at time %t ERROR: tRC violation during Activate bank 2", $time);
  358. end
  359. // Precharge to Activate Bank 2
  360. if ($time - RP_chk2 < tRP) begin
  361. $display ("%m : at time %t ERROR: tRP violation during Activate bank 2", $time);
  362. end
  363. // Record variables
  364. Act_b2 = 1'b1;
  365. Pc_b2 = 1'b0;
  366. B2_row_addr = Addr [addr_bits - 1 : 0];
  367. RAS_chk2 = $time;
  368. RC_chk2 = $time;
  369. RCD_chk2 = $time;
  370. end
  371. if (Ba == 2'b11 && Pc_b3 == 1'b1) begin
  372. // Debug Message
  373. if (Debug) begin
  374. $display ("%m : at time %t ACT : Bank = 3 Row = %d", $time, Addr);
  375. end
  376. // ACTIVE to ACTIVE command period
  377. if ($time - RC_chk3 < tRC) begin
  378. $display ("%m : at time %t ERROR: tRC violation during Activate bank 3", $time);
  379. end
  380. // Precharge to Activate Bank 3
  381. if ($time - RP_chk3 < tRP) begin
  382. $display ("%m : at time %t ERROR: tRP violation during Activate bank 3", $time);
  383. end
  384. // Record variables
  385. Act_b3 = 1'b1;
  386. Pc_b3 = 1'b0;
  387. B3_row_addr = Addr [addr_bits - 1 : 0];
  388. RAS_chk3 = $time;
  389. RC_chk3 = $time;
  390. RCD_chk3 = $time;
  391. end
  392. // Active Bank A to Active Bank B
  393. if ((Prev_bank != Ba) && ($time - RRD_chk < tRRD)) begin
  394. $display ("%m : at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba);
  395. end
  396. // Auto Refresh to Activate
  397. if ($time - RFC_chk < tRFC) begin
  398. $display ("%m : at time %t ERROR: tRFC violation during Activate bank = %d", $time, Ba);
  399. end
  400. // Load Mode Register to Active
  401. if (MRD_chk < tMRD ) begin
  402. $display ("%m : at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba);
  403. end
  404. // Record variables for checking violation
  405. RRD_chk = $time;
  406. Prev_bank = Ba;
  407. end
  408. // Precharge Block
  409. if (Prech_enable == 1'b1) begin
  410. // Load Mode Register to Precharge
  411. if ($time - MRD_chk < tMRD) begin
  412. $display ("%m : at time %t ERROR: tMRD violaiton during Precharge", $time);
  413. end
  414. // Precharge Bank 0
  415. if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin
  416. Act_b0 = 1'b0;
  417. Pc_b0 = 1'b1;
  418. RP_chk0 = $time;
  419. // Activate to Precharge
  420. if ($time - RAS_chk0 < tRAS) begin
  421. $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
  422. end
  423. // tWR violation check for write
  424. if ($time - WR_chkm[0] < tWRm) begin
  425. $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
  426. end
  427. end
  428. // Precharge Bank 1
  429. if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin
  430. Act_b1 = 1'b0;
  431. Pc_b1 = 1'b1;
  432. RP_chk1 = $time;
  433. // Activate to Precharge
  434. if ($time - RAS_chk1 < tRAS) begin
  435. $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
  436. end
  437. // tWR violation check for write
  438. if ($time - WR_chkm[1] < tWRm) begin
  439. $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
  440. end
  441. end
  442. // Precharge Bank 2
  443. if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin
  444. Act_b2 = 1'b0;
  445. Pc_b2 = 1'b1;
  446. RP_chk2 = $time;
  447. // Activate to Precharge
  448. if ($time - RAS_chk2 < tRAS) begin
  449. $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
  450. end
  451. // tWR violation check for write
  452. if ($time - WR_chkm[2] < tWRm) begin
  453. $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
  454. end
  455. end
  456. // Precharge Bank 3
  457. if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin
  458. Act_b3 = 1'b0;
  459. Pc_b3 = 1'b1;
  460. RP_chk3 = $time;
  461. // Activate to Precharge
  462. if ($time - RAS_chk3 < tRAS) begin
  463. $display ("%m : at time %t ERROR: tRAS violation during Precharge", $time);
  464. end
  465. // tWR violation check for write
  466. if ($time - WR_chkm[3] < tWRm) begin
  467. $display ("%m : at time %t ERROR: tWR violation during Precharge", $time);
  468. end
  469. end
  470. // Terminate a Write Immediately (if same bank or all banks)
  471. if (Data_in_enable === 1'b1 && (Bank === Ba || Addr[10] === 1'b1)) begin
  472. Data_in_enable = 1'b0;
  473. end
  474. // Precharge Command Pipeline for Read
  475. if (Cas_latency_3 === 1'b1) begin
  476. Command[2] = `PRECH;
  477. Bank_precharge[2] = Ba;
  478. A10_precharge[2] = Addr[10];
  479. end else if (Cas_latency_2 === 1'b1) begin
  480. Command[1] = `PRECH;
  481. Bank_precharge[1] = Ba;
  482. A10_precharge[1] = Addr[10];
  483. end
  484. end
  485. // Burst terminate
  486. if (Burst_term === 1'b1) begin
  487. // Terminate a Write Immediately
  488. if (Data_in_enable == 1'b1) begin
  489. Data_in_enable = 1'b0;
  490. end
  491. // Terminate a Read Depend on CAS Latency
  492. if (Cas_latency_3 === 1'b1) begin
  493. Command[2] = `BST;
  494. end else if (Cas_latency_2 == 1'b1) begin
  495. Command[1] = `BST;
  496. end
  497. // Display debug message
  498. if (Debug) begin
  499. $display ("%m : at time %t BST : Burst Terminate",$time);
  500. end
  501. end
  502. // Read, Write, Column Latch
  503. if (Read_enable === 1'b1) begin
  504. // Check to see if bank is open (ACT)
  505. if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
  506. (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
  507. $display("%m : at time %t ERROR: Bank is not Activated for Read", $time);
  508. end
  509. // Activate to Read or Write
  510. if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) ||
  511. (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) ||
  512. (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) ||
  513. (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin
  514. $display("%m : at time %t ERROR: tRCD violation during Read", $time);
  515. end
  516. // CAS Latency pipeline
  517. if (Cas_latency_3 == 1'b1) begin
  518. Command[2] = `READ;
  519. Col_addr[2] = Addr;
  520. Bank_addr[2] = Ba;
  521. end else if (Cas_latency_2 == 1'b1) begin
  522. Command[1] = `READ;
  523. Col_addr[1] = Addr;
  524. Bank_addr[1] = Ba;
  525. end
  526. // Read interrupt Write (terminate Write immediately)
  527. if (Data_in_enable == 1'b1) begin
  528. Data_in_enable = 1'b0;
  529. // Interrupting a Write with Autoprecharge
  530. if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
  531. RW_interrupt_write[RW_interrupt_bank] = 1'b1;
  532. RW_interrupt_counter[RW_interrupt_bank] = 0;
  533. // Display debug message
  534. if (Debug) begin
  535. $display ("%m : at time %t NOTE : Read interrupt Write with Autoprecharge", $time);
  536. end
  537. end
  538. end
  539. // Write with Auto Precharge
  540. if (Addr[10] == 1'b1) begin
  541. Auto_precharge[Ba] = 1'b1;
  542. Count_precharge[Ba] = 0;
  543. RW_interrupt_bank = Ba;
  544. Read_precharge[Ba] = 1'b1;
  545. end
  546. end
  547. // Write Command
  548. if (Write_enable == 1'b1) begin
  549. // Activate to Write
  550. if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
  551. (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
  552. $display("%m : at time %t ERROR: Bank is not Activated for Write", $time);
  553. end
  554. // Activate to Read or Write
  555. if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD) ||
  556. (Ba == 2'b01) && ($time - RCD_chk1 < tRCD) ||
  557. (Ba == 2'b10) && ($time - RCD_chk2 < tRCD) ||
  558. (Ba == 2'b11) && ($time - RCD_chk3 < tRCD)) begin
  559. $display("%m : at time %t ERROR: tRCD violation during Read", $time);
  560. end
  561. // Latch Write command, Bank, and Column
  562. Command[0] = `WRITE;
  563. Col_addr[0] = Addr;
  564. Bank_addr[0] = Ba;
  565. // Write interrupt Write (terminate Write immediately)
  566. if (Data_in_enable == 1'b1) begin
  567. Data_in_enable = 1'b0;
  568. // Interrupting a Write with Autoprecharge
  569. if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Write_precharge[RW_interrupt_bank] == 1'b1) begin
  570. RW_interrupt_write[RW_interrupt_bank] = 1'b1;
  571. // Display debug message
  572. if (Debug) begin
  573. $display ("%m : at time %t NOTE : Read Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank);
  574. end
  575. end
  576. end
  577. // Write interrupt Read (terminate Read immediately)
  578. if (Data_out_enable == 1'b1) begin
  579. Data_out_enable = 1'b0;
  580. // Interrupting a Read with Autoprecharge
  581. if (Auto_precharge[RW_interrupt_bank] == 1'b1 && Read_precharge[RW_interrupt_bank] == 1'b1) begin
  582. RW_interrupt_read[RW_interrupt_bank] = 1'b1;
  583. // Display debug message
  584. if (Debug) begin
  585. $display ("%m : at time %t NOTE : Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, RW_interrupt_bank);
  586. end
  587. end
  588. end
  589. // Write with Auto Precharge
  590. if (Addr[10] == 1'b1) begin
  591. Auto_precharge[Ba] = 1'b1;
  592. Count_precharge[Ba] = 0;
  593. RW_interrupt_bank = Ba;
  594. Write_precharge[Ba] = 1'b1;
  595. end
  596. end
  597. /*
  598. Write with Auto Precharge Calculation
  599. The device start internal precharge when:
  600. 1. Meet minimum tRAS requirement
  601. and 2. tWR cycle(s) after last valid data
  602. or 3. Interrupt by a Read or Write (with or without Auto Precharge)
  603. Note: Model is starting the internal precharge 1 cycle after they meet all the
  604. requirement but tRP will be compensate for the time after the 1 cycle.
  605. */
  606. if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
  607. if ((($time - RAS_chk0 >= tRAS) && // Case 1
  608. (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 2
  609. (Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) ||
  610. (Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) ||
  611. (Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) ||
  612. (RW_interrupt_write[0] == 1'b1 && RW_interrupt_counter[0] >= 1)) begin // Case 3
  613. Auto_precharge[0] = 1'b0;
  614. Write_precharge[0] = 1'b0;
  615. RW_interrupt_write[0] = 1'b0;
  616. Pc_b0 = 1'b1;
  617. Act_b0 = 1'b0;
  618. RP_chk0 = $time + tWRa;
  619. if (Debug) begin
  620. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
  621. end
  622. end
  623. end
  624. if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
  625. if ((($time - RAS_chk1 >= tRAS) && // Case 1
  626. (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) || // Case 2
  627. (Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) ||
  628. (Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) ||
  629. (Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) ||
  630. (RW_interrupt_write[1] == 1'b1 && RW_interrupt_counter[1] >= 1)) begin // Case 3
  631. Auto_precharge[1] = 1'b0;
  632. Write_precharge[1] = 1'b0;
  633. RW_interrupt_write[1] = 1'b0;
  634. Pc_b1 = 1'b1;
  635. Act_b1 = 1'b0;
  636. RP_chk1 = $time + tWRa;
  637. if (Debug) begin
  638. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
  639. end
  640. end
  641. end
  642. if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
  643. if ((($time - RAS_chk2 >= tRAS) && // Case 1
  644. (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) || // Case 2
  645. (Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) ||
  646. (Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) ||
  647. (Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) ||
  648. (RW_interrupt_write[2] == 1'b1 && RW_interrupt_counter[2] >= 1)) begin // Case 3
  649. Auto_precharge[2] = 1'b0;
  650. Write_precharge[2] = 1'b0;
  651. RW_interrupt_write[2] = 1'b0;
  652. Pc_b2 = 1'b1;
  653. Act_b2 = 1'b0;
  654. RP_chk2 = $time + tWRa;
  655. if (Debug) begin
  656. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
  657. end
  658. end
  659. end
  660. if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
  661. if ((($time - RAS_chk3 >= tRAS) && // Case 1
  662. (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) || // Case 2
  663. (Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) ||
  664. (Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) ||
  665. (Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) ||
  666. (RW_interrupt_write[3] == 1'b1 && RW_interrupt_counter[3] >= 1)) begin // Case 3
  667. Auto_precharge[3] = 1'b0;
  668. Write_precharge[3] = 1'b0;
  669. RW_interrupt_write[3] = 1'b0;
  670. Pc_b3 = 1'b1;
  671. Act_b3 = 1'b0;
  672. RP_chk3 = $time + tWRa;
  673. if (Debug) begin
  674. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
  675. end
  676. end
  677. end
  678. // Read with Auto Precharge Calculation
  679. // The device start internal precharge:
  680. // 1. Meet minimum tRAS requirement
  681. // and 2. CAS Latency - 1 cycles before last burst
  682. // or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
  683. if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
  684. if ((($time - RAS_chk0 >= tRAS) && // Case 1
  685. ((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 2
  686. (Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
  687. (Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
  688. (Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
  689. (RW_interrupt_read[0] == 1'b1)) begin // Case 3
  690. Pc_b0 = 1'b1;
  691. Act_b0 = 1'b0;
  692. RP_chk0 = $time;
  693. Auto_precharge[0] = 1'b0;
  694. Read_precharge[0] = 1'b0;
  695. RW_interrupt_read[0] = 1'b0;
  696. if (Debug) begin
  697. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
  698. end
  699. end
  700. end
  701. if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
  702. if ((($time - RAS_chk1 >= tRAS) &&
  703. ((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
  704. (Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
  705. (Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
  706. (Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
  707. (RW_interrupt_read[1] == 1'b1)) begin
  708. Pc_b1 = 1'b1;
  709. Act_b1 = 1'b0;
  710. RP_chk1 = $time;
  711. Auto_precharge[1] = 1'b0;
  712. Read_precharge[1] = 1'b0;
  713. RW_interrupt_read[1] = 1'b0;
  714. if (Debug) begin
  715. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
  716. end
  717. end
  718. end
  719. if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
  720. if ((($time - RAS_chk2 >= tRAS) &&
  721. ((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
  722. (Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
  723. (Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
  724. (Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
  725. (RW_interrupt_read[2] == 1'b1)) begin
  726. Pc_b2 = 1'b1;
  727. Act_b2 = 1'b0;
  728. RP_chk2 = $time;
  729. Auto_precharge[2] = 1'b0;
  730. Read_precharge[2] = 1'b0;
  731. RW_interrupt_read[2] = 1'b0;
  732. if (Debug) begin
  733. $display ("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
  734. end
  735. end
  736. end
  737. if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
  738. if ((($time - RAS_chk3 >= tRAS) &&
  739. ((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
  740. (Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
  741. (Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
  742. (Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
  743. (RW_interrupt_read[3] == 1'b1)) begin
  744. Pc_b3 = 1'b1;
  745. Act_b3 = 1'b0;
  746. RP_chk3 = $time;
  747. Auto_precharge[3] = 1'b0;
  748. Read_precharge[3] = 1'b0;
  749. RW_interrupt_read[3] = 1'b0;
  750. if (Debug) begin
  751. $display("%m : at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
  752. end
  753. end
  754. end
  755. // Internal Precharge or Bst
  756. if (Command[0] == `PRECH) begin // Precharge terminate a read with same bank or all banks
  757. if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin
  758. if (Data_out_enable == 1'b1) begin
  759. Data_out_enable = 1'b0;
  760. end
  761. end
  762. end else if (Command[0] == `BST) begin // BST terminate a read to current bank
  763. if (Data_out_enable == 1'b1) begin
  764. Data_out_enable = 1'b0;
  765. end
  766. end
  767. if (Data_out_enable == 1'b0) begin
  768. Dq_reg <= #tOH {data_bits{1'bz}};
  769. end
  770. // Detect Read or Write command
  771. if (Command[0] == `READ) begin
  772. Bank = Bank_addr[0];
  773. Col = Col_addr[0];
  774. Col_brst = Col_addr[0];
  775. case (Bank_addr[0])
  776. 2'b00 : Row = B0_row_addr;
  777. 2'b01 : Row = B1_row_addr;
  778. 2'b10 : Row = B2_row_addr;
  779. 2'b11 : Row = B3_row_addr;
  780. endcase
  781. Burst_counter = 0;
  782. Data_in_enable = 1'b0;
  783. Data_out_enable = 1'b1;
  784. end else if (Command[0] == `WRITE) begin
  785. Bank = Bank_addr[0];
  786. Col = Col_addr[0];
  787. Col_brst = Col_addr[0];
  788. case (Bank_addr[0])
  789. 2'b00 : Row = B0_row_addr;
  790. 2'b01 : Row = B1_row_addr;
  791. 2'b10 : Row = B2_row_addr;
  792. 2'b11 : Row = B3_row_addr;
  793. endcase
  794. Burst_counter = 0;
  795. Data_in_enable = 1'b1;
  796. Data_out_enable = 1'b0;
  797. end
  798. // DQ buffer (Driver/Receiver)
  799. if (Data_in_enable == 1'b1) begin // Writing Data to Memory
  800. // Array buffer
  801. case (Bank)
  802. 2'b00 : Dq_dqm = Bank0 [{Row, Col}];
  803. 2'b01 : Dq_dqm = Bank1 [{Row, Col}];
  804. 2'b10 : Dq_dqm = Bank2 [{Row, Col}];
  805. 2'b11 : Dq_dqm = Bank3 [{Row, Col}];
  806. endcase
  807. // Dqm operation
  808. if (Dqm[0] == 1'b0) begin
  809. Dq_dqm [ 7 : 0] = Dq [ 7 : 0];
  810. end
  811. if (Dqm[1] == 1'b0) begin
  812. Dq_dqm [15 : 8] = Dq [15 : 8];
  813. end
  814. // Write to memory
  815. case (Bank)
  816. 2'b00 : Bank0 [{Row, Col}] = Dq_dqm;
  817. 2'b01 : Bank1 [{Row, Col}] = Dq_dqm;
  818. 2'b10 : Bank2 [{Row, Col}] = Dq_dqm;
  819. 2'b11 : Bank3 [{Row, Col}] = Dq_dqm;
  820. endcase
  821. // Display debug message
  822. if (Dqm !== 2'b11) begin
  823. // Record tWR for manual precharge
  824. WR_chkm [Bank] = $time;
  825. if (Debug) begin
  826. $display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %d", $time, Bank, Row, Col, Dq_dqm);
  827. end
  828. end else begin
  829. if (Debug) begin
  830. $display("%m : at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
  831. end
  832. end
  833. // Advance burst counter subroutine
  834. #tHZ Burst_decode;
  835. end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory
  836. // Array buffer
  837. case (Bank)
  838. 2'b00 : Dq_dqm = Bank0[{Row, Col}];
  839. 2'b01 : Dq_dqm = Bank1[{Row, Col}];
  840. 2'b10 : Dq_dqm = Bank2[{Row, Col}];
  841. 2'b11 : Dq_dqm = Bank3[{Row, Col}];
  842. endcase
  843. // Dqm operation
  844. if (Dqm_reg0 [0] == 1'b1) begin
  845. Dq_dqm [ 7 : 0] = 8'bz;
  846. end
  847. if (Dqm_reg0 [1] == 1'b1) begin
  848. Dq_dqm [15 : 8] = 8'bz;
  849. end
  850. // Display debug message
  851. if (Dqm_reg0 !== 2'b11) begin
  852. Dq_reg = #tAC Dq_dqm;
  853. if (Debug) begin
  854. $display("%m : at time %t READ : Bank = %d Row = %d, Col = %d, Data = %d", $time, Bank, Row, Col, Dq_reg);
  855. end
  856. end else begin
  857. Dq_reg = #tHZ {data_bits{1'bz}};
  858. if (Debug) begin
  859. $display("%m : at time %t READ : Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
  860. end
  861. end
  862. // Advance burst counter subroutine
  863. Burst_decode;
  864. end
  865. end
  866. // Burst counter decode
  867. task Burst_decode;
  868. begin
  869. // Advance Burst Counter
  870. Burst_counter = Burst_counter + 1;
  871. // Burst Type
  872. if (Mode_reg[3] == 1'b0) begin // Sequential Burst
  873. Col_temp = Col + 1;
  874. end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst
  875. Col_temp[2] = Burst_counter[2] ^ Col_brst[2];
  876. Col_temp[1] = Burst_counter[1] ^ Col_brst[1];
  877. Col_temp[0] = Burst_counter[0] ^ Col_brst[0];
  878. end
  879. // Burst Length
  880. if (Burst_length_2) begin // Burst Length = 2
  881. Col [0] = Col_temp [0];
  882. end else if (Burst_length_4) begin // Burst Length = 4
  883. Col [1 : 0] = Col_temp [1 : 0];
  884. end else if (Burst_length_8) begin // Burst Length = 8
  885. Col [2 : 0] = Col_temp [2 : 0];
  886. end else begin // Burst Length = FULL
  887. Col = Col_temp;
  888. end
  889. // Burst Read Single Write
  890. if (Write_burst_mode == 1'b1) begin
  891. Data_in_enable = 1'b0;
  892. end
  893. // Data Counter
  894. if (Burst_length_1 == 1'b1) begin
  895. if (Burst_counter >= 1) begin
  896. Data_in_enable = 1'b0;
  897. Data_out_enable = 1'b0;
  898. end
  899. end else if (Burst_length_2 == 1'b1) begin
  900. if (Burst_counter >= 2) begin
  901. Data_in_enable = 1'b0;
  902. Data_out_enable = 1'b0;
  903. end
  904. end else if (Burst_length_4 == 1'b1) begin
  905. if (Burst_counter >= 4) begin
  906. Data_in_enable = 1'b0;
  907. Data_out_enable = 1'b0;
  908. end
  909. end else if (Burst_length_8 == 1'b1) begin
  910. if (Burst_counter >= 8) begin
  911. Data_in_enable = 1'b0;
  912. Data_out_enable = 1'b0;
  913. end
  914. end
  915. end
  916. endtask
  917. // Timing Parameters for -7E (133 MHz @ CL2)
  918. specify
  919. specparam
  920. tAH = 0.8, // Addr, Ba Hold Time
  921. tAS = 1.5, // Addr, Ba Setup Time
  922. tCH = 2.5, // Clock High-Level Width
  923. tCL = 2.5, // Clock Low-Level Width
  924. tCK = 7.0, // Clock Cycle Time
  925. tDH = 0.8, // Data-in Hold Time
  926. tDS = 1.5, // Data-in Setup Time
  927. tCKH = 0.8, // CKE Hold Time
  928. tCKS = 1.5, // CKE Setup Time
  929. tCMH = 0.8, // CS#, RAS#, CAS#, WE#, DQM# Hold Time
  930. tCMS = 1.5; // CS#, RAS#, CAS#, WE#, DQM# Setup Time
  931. $width (posedge Clk, tCH);
  932. $width (negedge Clk, tCL);
  933. $period (negedge Clk, tCK);
  934. $period (posedge Clk, tCK);
  935. $setuphold(posedge Clk, Cke, tCKS, tCKH);
  936. $setuphold(posedge Clk, Cs_n, tCMS, tCMH);
  937. $setuphold(posedge Clk, Cas_n, tCMS, tCMH);
  938. $setuphold(posedge Clk, Ras_n, tCMS, tCMH);
  939. $setuphold(posedge Clk, We_n, tCMS, tCMH);
  940. $setuphold(posedge Clk, Addr, tAS, tAH);
  941. $setuphold(posedge Clk, Ba, tAS, tAH);
  942. $setuphold(posedge Clk, Dqm, tCMS, tCMH);
  943. $setuphold(posedge Dq_chk, Dq, tDS, tDH);
  944. endspecify
  945. endmodule