mt48lc16m16a2.v 47 KB

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