Root/sim/verilog/micron_mobile_ddr/mobile_ddr.v

1/****************************************************************************************
2*
3* File Name: mobile_ddr.v
4* Version: 6.03
5* Model: BUS Functional
6*
7* Dependencies: mobile_ddr_parameters.vh
8*
9* Description: Micron MOBILE DDR SDRAM
10*
11* Limitation: - Doesn't check for 8K-cycle refresh
12*
13* Note: - Set simulator resolution to "ps" accuracy
14* - Set Debug = 0 to disable $display messages
15* - Model assume Clk and Clk# crossing at both edge
16*
17* Disclaimer This software code and all associated documentation, comments or other
18* of Warranty: information (collectively "Software") is provided "AS IS" without
19* warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY
20* DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
21* TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES
22* OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT
23* WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE
24* OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
25* FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR
26* THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS,
27* ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE
28* OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI,
29* ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT,
30* INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING,
31* WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION,
32* OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE
33* THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
34* DAMAGES. Because some jurisdictions prohibit the exclusion or
35* limitation of liability for consequential or incidental damages, the
36* above limitation may not apply to you.
37*
38* Copyright 2008 Micron Technology, Inc. All rights reserved.
39*
40* Rev Author Date Changes
41* --- ------ ---------- ---------------------------------------
42* 1.0 NMB 03/19/02 - Initial Release of Mobile DDR model
43* based off of version 5.0 of DDR model
44* 1.1 ritz 12/03/04 - New feature: 1/8th strength driver in Drive Strength (Ext Mode Reg).
45* Bugfix - ba[0] ba[1] were swapped for determening ext_mode_enable
46* thus ext_mode_reg wasnt being programmed.
47* 1.2 ritz 12/07/04 - Logging transactions in transcript for automated testing
48* 1.3 ritz 01/31/05 - updated to SMG DDR model version 5.2 (dqs edge checking errors fix)
49* 1.4 ritz 02/15/05 - Fixed display.*WRITE to use hex for "data".
50* 1.5 ritz 03/22/05 - Fixed read latency (#0.5 and 2*Read_latency-1) for MMG latency
51* 2.0 bas 07/19/06 - Added PASR support and clk_n checking
52* 3.0 bas 08/07/06 - Added tXP check, tCke check, Power-down/Deep power down enter/exit messages
53                            FULL_MEM fix
54* 3.11 bas 10/18/06 - Added clk spd chk, added RP support, added T48M part, added SRR functionality, changed tMRD checker to measure in tck pos edge, DPD optimization for FULL_MEM mode
55* 3.12 bas 10/19/06 - Fixed PASR in FULL_MEM mode
56* 3.20 bas 10/23/06 - changed tXP check to tPDX check for T25L, Initial release to web
57* 3.30 bas 01/15/07 - Updated T48M Parameters (updated as of 12/06)
58* 3.35 bas 02/28/07 - Model uses tAC correctly to calculate strobe/data launch
59* 3.36 bas 03/05/07 - fixed error messages for different banks interrupting
60                            reads/writes w/autoprecharge
61* 3.37 bas 03/21/07 - Added T47M Part to 512Mb parameter file
62* 3.40 bas 06/25/07 - Removed RP options from 1024Mb
63                          - Updated 128Mb, 256Mb, and 512Mb parts to 05/07 datasheet
64                          - Updated 1024Mb part to 02/07
65                          - Added illegal Cas Latency check per speed grade
66* 3.40 jwm 08/02/07 - Support for 512Mb T47M
67* 3.80 clk 10/29/07 - Support for 1024Mb T48M
68* 4.00 clk 12/30/07 - Fixed Read terminated by precharge testcase
69* 4.70 clk 03/30/08 - Fixed typo in SRR code
70* 4.80 clk 04/03/08 - Disable clk checking during initialization
71* 4.90 clk 04/16/08 - Fixed tInit, added mpc support, updated t35m timing
72* 5.00 clk 05/14/08 - Fixed back to back auto precharge commands
73* 5.20 clk 05/21/08 - Fixed read interrupt by pre (BL8), fixed 1024Mb parameter file
74* 5.30 clk 05/22/08 - Fixed DM signal which cause false tWTR errors
75              05/27/08 - Rewrote write and read pipelines, strobes
76* 5.40 clk 05/28/08 - Fixed Addressing problem in Burst Order logic
77* 5.50 clk 07/25/08 - Added T36N part type
78* 5.60 clk 09/05/08 - Fixed tXP in 256Mb part type
79* 5.70 clk 09/17/08 - Fixed burst term check for write w/ all DM active
80* 5.80 clk 11/18/08 - Fixed internally latched dq & mask widths
81* 5.90 clk 12/10/08 - Updated T36N parameters to latest datasheet
82* 6.00 clk 03/05/09 - Fixed DQS problem w/ CL = 2, Fix Wr Pipeline during Rd interrupt
83* 6.01 sph 01/20/10 - Added clock stop detection to fix tCH/tCL timing violation
84* 6.02 sph 01/22/10 - Added check for nop/des is used when enter/exit stop clock mode
85* 6.03 sph 06/07/10 - Include all the mobile_ddr_parameters.vh into a single package
86****************************************************************************************/
87
88// DO NOT CHANGE THE TIMESCALE
89// MAKE SURE YOUR SIMULATOR USES "PS" RESOLUTION
90`timescale 1ns / 1ps
91
92module mobile_ddr (Dq, Dqs, Addr, Ba, Clk, Clk_n, Cke, Cs_n, Ras_n, Cas_n, We_n, Dm);
93
94`ifdef den128Mb
95    `include "128Mb_mobile_ddr_parameters.vh"
96`elsif den256Mb
97    `include "256Mb_mobile_ddr_parameters.vh"
98`elsif den512Mb
99    `include "512Mb_mobile_ddr_parameters.vh"
100`elsif den1024Mb
101    `include "1024Mb_mobile_ddr_parameters.vh"
102`elsif den2048Mb
103    `include "2048Mb_mobile_ddr_parameters.vh"
104`else
105    // NOTE: Intentionally cause a compile fail here to force the users
106    // to select the correct component density before continuing
107    ERROR: You must specify component density with +define+den____Mb.
108`endif
109
110    `define MAX_PIPE 2*(CL_MAX + BL_MAX)
111
112    // Port Declarations
113    input Clk;
114    input Clk_n;
115    input Cke;
116    input Cs_n;
117    input Ras_n;
118    input Cas_n;
119    input We_n;
120    input [ADDR_BITS - 1 : 0] Addr;
121    input [1 : 0] Ba;
122    inout [DQ_BITS - 1 : 0] Dq;
123    inout [DQS_BITS - 1 : 0] Dqs;
124    input [DM_BITS - 1 : 0] Dm;
125
126    //time variables
127    realtime tXP_chk ;
128    reg enter_DPD ;
129    reg enter_PD ;
130    reg enter_APD ;
131
132    //integer clk checks
133
134    // Internal Wires (fixed width)
135    wire [31 : 0] Dq_in;
136    wire [3 : 0] Dqs_in;
137    wire [3 : 0] Dm_in;
138    
139    assign Dq_in [DQ_BITS - 1 : 0] = Dq;
140    assign Dqs_in [DQS_BITS - 1 : 0] = Dqs;
141    assign Dm_in [DM_BITS - 1 : 0] = Dm;
142
143    // Data pair
144    reg [DQ_BITS-1 : 0] dq_rise;
145    reg [DM_BITS-1 : 0] dm_rise;
146    reg [DQ_BITS-1 : 0] dq_fall;
147    reg [DM_BITS-1 : 0] dm_fall;
148    reg [DM_BITS*2-1 : 0] dm_pair;
149    reg [DQ_BITS-1 : 0] Dq_buf;
150
151    // Power-down cycle counter
152    reg [03:00] PD_cntr ;
153
154    // prev cmd value
155
156    reg prev_Cs_n ;
157    reg prev_Ras_n ;
158    reg prev_Cas_n ;
159    reg prev_We_n ;
160    reg [01:00] prev_Ba ;
161    reg prev_cke ;
162
163    wire prev_nop = ~prev_Cs_n & prev_Ras_n & prev_Cas_n & prev_We_n ;
164    wire prev_des = prev_Cs_n ;
165    wire prev_bt = ~prev_Cs_n & prev_Ras_n & prev_Cas_n & ~prev_We_n ;
166    wire prev_rd = ~prev_Cs_n & prev_Ras_n & ~prev_Cas_n & prev_We_n ;
167    reg Clk_Chk_enable = 1'b0 ;
168
169    //differential clk
170    reg diff_ck;
171    always @(posedge Clk) diff_ck <= Clk;
172    always @(posedge Clk_n) diff_ck <= ~Clk_n;
173
174    //measure clock period
175    realtime clk_period ;
176    realtime pos_clk_edge ;
177    integer clk_pos_edge_cnt ;
178    always @(posedge diff_ck) begin
179        clk_period = $realtime - pos_clk_edge ;
180        pos_clk_edge = $realtime ;
181        if ((Cke == 1'b1) && (clk_pos_edge_cnt < 2)) begin
182            clk_pos_edge_cnt = clk_pos_edge_cnt + 1 ;
183        end else if (Cke == 1'b0) begin
184            clk_pos_edge_cnt = 2'b00 ;
185        end
186    end
187
188    //measure duty cycle
189    realtime neg_clk_edge ;
190    always @(negedge diff_ck) begin
191        neg_clk_edge = $realtime ;
192    end
193    realtime pos_clk_time ;
194    realtime neg_clk_time ;
195    reg clock_stop = 0;
196
197    // Mode Register
198    reg [ADDR_BITS - 1 : 0] Mode_reg;
199    reg [ADDR_BITS - 1 : 0] Ext_Mode_reg;
200    reg [2*DQ_BITS - 1 : 0] Srr_reg;
201
202
203    // SRR Registers
204    reg SRR_read;
205
206    // Internal System Clock
207    reg CkeZ, Sys_clk;
208
209    // Internal Dqs initialize
210// reg Dqs_int;
211
212    // Dqs buffer
213    reg Dqs_out;
214// reg [DQS_BITS - 1 : 0] Dqs_gen;
215    reg Dqs_out_en;
216    // Dq buffer
217    reg [DQ_BITS - 1 : 0] Dq_out_temp;
218    reg [DQ_BITS - 1 : 0] Dq_out;
219    reg Dq_out_en;
220
221    // Read pipeline variables
222    reg [`MAX_PIPE : 0] Read_pipeline ;
223    reg [1 : 0] Read_bank [0 : 6];
224    reg [COL_BITS - 1 : 0] Read_cols [0 : 6];
225
226    // Write pipeline variables
227    reg [`MAX_PIPE :-2] Write_pipeline;
228    reg [BA_BITS-1 : 0] Write_bank_pipeline [`MAX_PIPE :-2];
229    reg [COL_BITS - 1 : 0] Write_col_pipeline [`MAX_PIPE :-2];
230
231    // Auto precharge variables
232    reg [3:0] Read_precharge_access ;
233    reg [3:0] Read_precharge_pre ;
234    reg [3:0] Write_precharge_access ;
235    reg [3:0] Write_precharge_pre ;
236    integer Count_precharge [0:3];
237    reg SelfRefresh;
238    reg [3:0] Read_precharge_count [3:0] ;
239    reg [3:0] Write_precharge_count [3:0];
240
241
242    reg wr_ap_display_msg ;
243    reg rd_ap_display_msg ;
244
245    // Manual precharge variables
246// reg [0 : 6] A10_precharge ;
247// reg [1 : 0] Bank_precharge [0 : 6];
248// reg [0 : 6] Cmnd_precharge ;
249
250    // Burst terminate variables
251// reg Cmnd_bst [0 : 6];
252
253    // tMRD counter
254    integer MRD_cntr ;
255    integer SRR_cntr ;
256    integer SRC_cntr ;
257    integer tWTR_cntr ;
258
259    // Memory Banks
260    `ifdef FULL_MEM
261        reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<full_mem_bits)-1];
262    `else
263        reg [DQ_BITS - 1 : 0] mem_array [0 : (1<<part_mem_bits)-1];
264        reg [full_mem_bits - 1 : 0] addr_array [0 : (1<<part_mem_bits)-1];
265        reg [part_mem_bits : 0] mem_used;
266        reg [part_mem_bits : 0] memory_index;
267        initial mem_used = 0;
268    `endif
269
270    // Dqs edge checking
271    integer i;
272    reg [3:0] expect_pos_dqs;
273    reg [3:0] expect_neg_dqs;
274
275    // Burst counter
276    reg [COL_BITS - 1 : 0] Burst_counter;
277
278    // Burst counter delay
279    reg [COL_BITS - 1 : 0] Burst_counter_dly;
280    always @(Mode_reg or Burst_counter) begin
281       if (Mode_reg[6:4] == 3'b010) begin
282// Burst_counter_dly <= #tAC2_max Burst_counter;
283       end else if (Mode_reg[6:4] == 3'b011) begin
284// Burst_counter_dly <= #tAC3_max Burst_counter;
285       end
286    end
287
288    // Precharge variables
289    reg Pc_b0, Pc_b1, Pc_b2, Pc_b3;
290
291    // Activate variables
292    reg Act_b0, Act_b1, Act_b2, Act_b3;
293
294    // Data IO variables
295// reg Data_in_enable;
296    wire Data_in_enable = Write_pipeline[-2];
297// reg Data_out_enable;
298    wire Data_out_enable = Read_pipeline[0];
299    wire tWTR_en = ((|Write_pipeline[`MAX_PIPE : 0]) & ~(&Dm));
300
301    // Data Out Enable delay
302// reg Data_out_enable_dly;
303// always @(Mode_reg or Data_out_enable) begin
304// if (Mode_reg[6:4] == 3'b010) begin
305// Data_out_enable_dly <= #tAC2_max Data_out_enable;
306// end else if (Mode_reg[6:4] == 3'b011) begin
307// Data_out_enable_dly <= #tAC3_max Data_out_enable;
308// end
309// end
310
311    // Internal address mux variables
312    reg [1 : 0] Prev_bank;
313    reg [1 : 0] Bank_addr;
314    reg [COL_BITS - 1 : 0] Cols_addr, Cols_brst, Cols_temp;
315    reg [ADDR_BITS - 1 : 0] Rows_addr;
316    reg [ADDR_BITS - 1 : 0] B0_row_addr;
317    reg [ADDR_BITS - 1 : 0] B1_row_addr;
318    reg [ADDR_BITS - 1 : 0] B2_row_addr;
319    reg [ADDR_BITS - 1 : 0] B3_row_addr;
320
321    integer aref_count;
322    reg ext_mode_load_done;
323    reg mode_load_done;
324    reg power_up_done;
325
326    // Write DQS for tDSS , tDSH, tDQSH, tDQSL checks
327    wire wdqs_valid = Write_pipeline[`MAX_PIPE:0];
328
329    // Commands Decode
330    wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
331    wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n & Cke;
332    wire Sref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n & ~Cke;
333    wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
334    wire Ext_mode_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & Ba[1] & ~Ba[0];
335    wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & ~Ba[1] & ~Ba[0];
336    wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
337    wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
338    wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
339    wire DPD_enable = ~Cs_n & Ras_n & Cas_n & ~We_n & ~Cke;
340    wire PD_enable = ((~Cs_n & Ras_n & Cas_n & We_n) | Cs_n) & ~Cke;
341    wire nop_enable = ~Cs_n & Ras_n & Cas_n & We_n ;
342    wire des_enable = Cs_n ;
343    wire srr_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n & ~Ba[1] & Ba[0] & ((part_size==128)|(part_size==512)|(part_size==1024)) ;
344
345    reg Cke_Chk = 0 ;
346    parameter tInit = 200000 ;
347    reg Cke_Print = 1'b0 ;
348    real Init_Cmd_Chk ;
349    
350
351    // Burst Length Decode
352// reg [4:0] burst_length = 1 << (Mode_reg[2:0]);
353    reg [4:0] burst_length ;
354    reg read_precharge_truncation;
355
356    // CAS Latency Decode
357    wire [2:0] cas_latency = Mode_reg[6:4] ;
358    wire [2:0] cas_latency_x2 = ((2*Mode_reg[6:4])-1);
359
360    real tAC_max ;
361    always @ (Mode_reg)
362    begin
363        if (Mode_reg[6:4] == 3'b011)
364            tAC_max = tAC3_max ;
365        else if (Mode_reg[6:4] == 3'b010)
366            tAC_max = tAC2_max ;
367    end
368
369    // DQS Buffer
370    reg [DQS_BITS - 1 : 0] dqs_delayed ;
371// always@* begin
372// dqs_delayed <= Dqs_out ;
373// end
374
375    assign Dqs = (Dqs_out_en) ? {DQS_BITS{Dqs_out}} : 'bz;
376    assign Dq = (Dq_out_en ) ? Dq_out : 'bz;
377
378    // Debug message
379    wire Debug = 1'b0;
380
381    // Timing Check
382// realtime MRD_chk;
383    realtime RFC_chk;
384    realtime RRD_chk;
385    realtime RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
386    realtime RAP_chk0, RAP_chk1, RAP_chk2, RAP_chk3;
387    realtime RC_chk0, RC_chk1, RC_chk2, RC_chk3;
388    realtime RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
389    realtime RP_chk0, RP_chk1, RP_chk2, RP_chk3;
390    realtime WR_chk0, WR_chk1, WR_chk2, WR_chk3;
391    realtime SRR_chk;
392
393    //
394    reg [2:0] current_init_state ;
395    parameter [2:0] begin_init = 3'b000 ;
396    parameter [2:0] cke_init = 3'b001 ;
397    parameter [2:0] prech_init = 3'b010 ;
398    parameter [2:0] begin_mode_init = 3'b011 ;
399    parameter [2:0] mode_init = 3'b100 ;
400    parameter [2:0] ext_mode_init = 3'b101 ;
401    parameter [2:0] mode_done_init = 3'b110 ;
402
403    initial begin
404        CkeZ = 1'b0;
405        Sys_clk = 1'b0;
406        {Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
407        {Act_b0, Act_b1, Act_b2, Act_b3} = 4'b1111;
408// Dqs_int = 1'b0;
409        Dqs_out_en = {DQS_BITS{1'b0}};
410        Dqs_out = {DQS_BITS{1'bz}};
411// Dqs_gen = {DQS_BITS{1'bz}};
412        Dq_out = {DQ_BITS{1'bz}};
413        Dq_out_en = {DQ_BITS{1'b0}};
414// dq_delayed = {DQ_BITS{1'bz}};
415// Data_in_enable = 1'b0;
416// Data_out_enable = 1'b0;
417        aref_count = 0;
418        SelfRefresh = 1'b0;
419        power_up_done = 0;
420        ext_mode_load_done = 0;
421        mode_load_done = 0;
422// MRD_chk = 0;
423        RFC_chk = 0;
424        RRD_chk = 0;
425        RAS_chk0 = 0;
426        RAS_chk1 = 0;
427        RAS_chk2 = 0;
428        RAS_chk3 = 0;
429        RAP_chk0 = 0;
430        RAP_chk1 = 0;
431        RAP_chk2 = 0;
432        RAP_chk3 = 0;
433        RC_chk0 = 0;
434        RC_chk1 = 0;
435        RC_chk2 = 0;
436        RC_chk3 = 0;
437        RCD_chk0 = 0;
438        RCD_chk1 = 0;
439        RCD_chk2 = 0;
440        RCD_chk3 = 0;
441        RP_chk0 = 0;
442        RP_chk1 = 0;
443        RP_chk2 = 0;
444        RP_chk3 = 0;
445        WR_chk0 = 0;
446        WR_chk1 = 0;
447        WR_chk2 = 0;
448        WR_chk3 = 0;
449        SRR_chk = 0;
450        $timeformat (-9, 3, " ns", 12);
451        pos_clk_time = 0;
452        neg_clk_time = 0;
453        enter_DPD = 0;
454        enter_PD = 0;
455        enter_APD = 0;
456        current_init_state = begin_init ;
457        SRR_read = 1'b0;
458        MRD_cntr = 8;
459        SRR_cntr = 8;
460        SRC_cntr = 8;
461        tWTR_cntr = 8;
462        Read_precharge_access[0] = 1'b0 ;
463        Read_precharge_access[1] = 1'b0 ;
464        Read_precharge_access[2] = 1'b0 ;
465        Read_precharge_access[3] = 1'b0 ;
466        Read_precharge_pre[0] = 1'b0 ;
467        Read_precharge_pre[1] = 1'b0 ;
468        Read_precharge_pre[2] = 1'b0 ;
469        Read_precharge_pre[3] = 1'b0 ;
470        Write_precharge_access[0] = 1'b0 ;
471        Write_precharge_access[1] = 1'b0 ;
472        Write_precharge_access[2] = 1'b0 ;
473        Write_precharge_access[3] = 1'b0 ;
474        Write_precharge_pre[0] = 1'b0 ;
475        Write_precharge_pre[1] = 1'b0 ;
476        Write_precharge_pre[2] = 1'b0 ;
477        Write_precharge_pre[3] = 1'b0 ;
478        wr_ap_display_msg = 1'b0 ;
479        rd_ap_display_msg = 1'b0 ;
480        Read_precharge_count[0] = 4'hf;
481        Read_precharge_count[1] = 4'hf;
482        Read_precharge_count[2] = 4'hf;
483        Read_precharge_count[3] = 4'hf;
484        Write_precharge_count[0] = 4'hf;
485        Write_precharge_count[1] = 4'hf;
486        Write_precharge_count[2] = 4'hf;
487        Write_precharge_count[3] = 4'hf;
488    end
489
490    // make sure 200 us has passed since cke for first command
491    always @ (Clk_Chk_enable or nop_enable or des_enable)
492    begin
493        if (~Clk_Chk_enable) begin
494            if (~nop_enable & ~des_enable) begin
495                Clk_Chk_enable = 1'b1 ;
496                if (~Cke_Chk) begin
497                    if (($realtime - Init_Cmd_Chk < tInit - 0.001) & ~Cke_Print) begin
498                        $display("Warning: You must wait 200 us from CKE assertion before you perform a command. Current wait time: %3.0f ns", $realtime - (Init_Cmd_Chk));
499                        Cke_Print = 1'b1 ;
500                    end
501                end
502            end
503        end
504    end
505
506    // Check for tCH, tCK, and clock stop mode
507    always @(diff_ck) begin
508        if (diff_ck) begin
509            neg_clk_time = $realtime - neg_clk_edge ;
510        end
511        if (~diff_ck) begin
512            pos_clk_time = $realtime - pos_clk_edge ;
513        end
514        if (Cke & Clk_Chk_enable) begin
515            // clock stop mode when either pulse width is 2x bigger than the other (reasonable assumption???)
516            clock_stop = ((pos_clk_time / neg_clk_time > 2) | (neg_clk_time / pos_clk_time > 2));
517            
518            // Check if NOP/DES when enter/exit clock stop mode
519            if ((clock_stop && diff_ck) && (~(prev_nop || prev_des) || ~(nop_enable || des_enable))) begin
520                $display ("%m: at time %t ERROR: Nop or Deselect is required when enter or exit Stop Clock Mode", $time);
521            end
522            
523            if ((pos_clk_time / clk_period < tCH_MIN) && ~clock_stop) begin
524                $display ("%m: at time %t ERROR: tCH minimum violation on CLK by %t", $time, tCH_MIN*clk_period - pos_clk_time);
525            end
526            if ((pos_clk_time / clk_period > tCH_MAX) && ~clock_stop) begin
527                $display ("%m: at time %t ERROR: tCH maximum violation on CLK by %t", $time, pos_clk_time - tCH_MAX*clk_period);
528            end
529            if ((neg_clk_time / clk_period < tCL_MIN) && ~clock_stop) begin
530                $display ("%m: at time %t ERROR: tCL minimum violation on CLK by %t", $time, tCL_MIN*clk_period - pos_clk_time);
531            end
532            if ((neg_clk_time / clk_period > tCL_MAX) && ~clock_stop) begin
533                $display ("%m: at time %t ERROR: tCL maximum violation on CLK by %t", $time, pos_clk_time - tCL_MAX*clk_period);
534            end
535        end
536    end
537
538    //clock Frequency Check
539    always @(posedge diff_ck) begin
540        if (clk_pos_edge_cnt > 1) begin
541            if (Mode_reg[6:4] == 3'b011) begin
542                if (clk_period < (tCK3_min-0.001)) begin
543                    $display ("%m : at time %t ERROR : Illegal clk period for CAS Latency 3", $realtime);
544                    $display ("%m : at time %t CLK PERIOD = %t", $realtime, clk_period);
545                end
546            end
547            if (Mode_reg[6:4] == 3'b010) begin
548                if (clk_period < (tCK2_min-0.001)) begin
549                    $display ("%m : at time %t ERROR : Illegal clk period for CAS Latency 2", $realtime);
550                    $display ("%m : at time %t CLK PERIOD = %t", $realtime, clk_period);
551                end
552            end
553        end
554    end
555
556    //SRR reg settings
557    always @(posedge power_up_done) begin
558        Srr_reg = 'b0 ;
559        Srr_reg[3:0] = 4'b1111 ; //Manufacturer(Micron)
560        Srr_reg[7:4] = 4'b0000 ; //Revision ID(Default to 0 in model)
561        Srr_reg[10:8] = 3'b100 ; //Refresh Rate(based on temp sensor - will default to 1x in model)
562        Srr_reg[11] = (DQ_BITS == 32)? 1'b1 : 1'b0 ; //Part width(x32 or x16)
563        Srr_reg[12] = 1'b0 ; //Device Type (LP DDR)
564        Srr_reg[15:13] = (part_size == 1024)? 3'b011 :
565                         (part_size == 512 )? 3'b010 :
566                         (part_size == 256 )? 3'b001 :
567                                              3'b000 ; //Density(1024Mb, 512Mb, 256Mb, 128Mb)
568    end
569
570    // System Clock
571    always begin
572        @ (posedge diff_ck) begin
573            Sys_clk = CkeZ;
574            CkeZ = Cke;
575        end
576        @ (negedge diff_ck) begin
577            Sys_clk = 1'b0;
578        end
579    end
580
581    task store_prev_cmd;
582    begin
583        prev_Cs_n <= Cs_n ;
584        prev_Ras_n <= Ras_n ;
585        prev_Cas_n <= Cas_n ;
586        prev_We_n <= We_n ;
587        prev_Ba[1] <= Ba[1] ;
588        prev_Ba[0] <= Ba[0] ;
589        prev_cke <= Cke ;
590    end
591    endtask
592
593    task MRD_counter;
594    begin
595        if (Cke) begin
596            if (MRD_cntr < tMRD) begin
597                MRD_cntr = MRD_cntr + 1'b1;
598            end
599        end
600    end
601    endtask
602
603    task SRR_counter;
604    begin
605        if (Cke) begin
606            if (SRR_cntr < tSRR) begin
607                SRR_cntr = SRR_cntr + 1'b1;
608            end
609        end
610    end
611    endtask
612
613    task SRC_counter;
614    begin
615        if (Cke) begin
616            if (SRC_cntr < ((Mode_reg[6:4])+1)) begin
617                SRC_cntr = SRC_cntr + 1'b1;
618            end
619        end
620    end
621    endtask
622
623    task tWTR_counter;
624    begin
625        if (Cke) begin
626            if (tWTR_en) begin
627                tWTR_cntr = 0 ;
628            end else begin
629                tWTR_cntr = tWTR_cntr + 1'b1;
630            end
631        end
632    end
633    endtask
634
635    task command_counter;
636    begin
637        if (Cke) begin
638            for (i=0; i<4;i=i+1) begin
639                if (Read_precharge_count[i] < 4'hf) begin
640                    Read_precharge_count[i] = Read_precharge_count[i] + 1'b1;
641                end
642            end
643            for (i=0; i<4;i=i+1) begin
644                if (Write_precharge_count[i] < 4'hf) begin
645                    Write_precharge_count[i] = Write_precharge_count[i] + 1'b1;
646                end
647            end
648        end
649    end
650    endtask
651
652
653    task PD_counter;
654    begin
655        if (~Cke) begin
656            if (PD_cntr < tCKE) begin
657                PD_cntr = PD_cntr + (enter_DPD | enter_PD | DPD_enable | PD_enable);
658            end
659        end else begin
660            PD_cntr = 4'h0 ;
661        end
662    end
663    endtask
664
665    task tXP_check;
666    begin
667        if (Cke == 1'b1 && prev_cke == 1'b0) begin
668            tXP_chk = $realtime ;
669        end
670        if (Cke) begin
671            if (~nop_enable && ~des_enable) begin
672                if ($realtime-tXP_chk < tXP - 0.001) begin
673`ifdef T25L
674                    $display ("%m: At time %t ERROR: tPDX violation", $realtime);
675`else
676                    $display ("%m: At time %t ERROR: tXP violation", $realtime);
677`endif
678                end
679            end
680        end
681    end
682    endtask
683
684    // DPD pos edge clk cntr
685    always begin
686        @ (posedge diff_ck) begin
687            tXP_check ;
688            Power_down_chk ;
689            PD_counter ;
690            store_prev_cmd ;
691        end
692    end
693
694    // Check to make sure that we have a Deselect or NOP command on the bus when CKE is brought high
695    always @(Cke) begin
696        if (Cke === 1'b1) begin
697            Init_Cmd_Chk = $realtime ;
698            if (SelfRefresh === 1'b1) begin
699                SelfRefresh = 1'b0;
700            end
701            if (!((Cs_n) || (~Cs_n & Ras_n & Cas_n & We_n))) begin
702                $display ("%m: At time %t MEMORY ERROR: You must have a Deselect or NOP command applied", $realtime);
703                $display ("%m: when the Clock Enable is brought High.");
704            end
705        end
706    end
707
708    //BL Mode Reg settings
709    always@(Mode_reg[2:0] or mode_load_done) begin
710        if (mode_load_done) begin
711            case (Mode_reg[2:0])
712                3'b001 : burst_length = 5'b00010;
713                3'b010 : burst_length = 5'b00100;
714                3'b011 : burst_length = 5'b01000;
715                3'b100 : burst_length = 5'b10000;
716                default : burst_length = 5'bxxxxx;
717            endcase
718        end
719    end
720
721// Init sequence
722always @(current_init_state or Cke or Prech_enable or ext_mode_load_done or mode_load_done or aref_count) begin
723    if (current_init_state == begin_init) begin
724        if (Cke) begin
725            current_init_state = cke_init ;
726            power_up_done = 1'b0 ;
727        end
728    end
729    if (current_init_state == cke_init) begin
730        if (Prech_enable) begin
731            current_init_state = prech_init ;
732            aref_count = 0 ;
733        end
734    end
735    if (current_init_state == prech_init) begin
736        if (~Prech_enable) begin
737            current_init_state = begin_mode_init ;
738        end
739    end
740    if (current_init_state == begin_mode_init) begin
741        if (ext_mode_load_done) begin
742            current_init_state = ext_mode_init ;
743        end
744        if (mode_load_done) begin
745            current_init_state = mode_init ;
746        end
747    end
748    if (current_init_state == mode_init) begin
749        if (ext_mode_load_done) begin
750            current_init_state = mode_done_init ;
751        end
752    end
753    if (current_init_state == ext_mode_init) begin
754        if (mode_load_done) begin
755            current_init_state = mode_done_init ;
756        end
757    end
758    if (current_init_state == mode_done_init && aref_count >= 2) begin
759        power_up_done = 1'b1;
760    end
761end
762
763
764    // this task will erase the contents of 0 or more banks
765    task erase_mem;
766        input [BA_BITS+1:0] bank_MSB_row; //bank bits + 2 row MSB
767        input DPD_mode ; //erase all memory locations
768        integer i;
769        begin
770
771            if (DPD_mode) begin
772`ifdef FULL_MEM
773                for (i=0; i<{(BA_BITS+ROW_BITS+COL_BITS){1'b1}}; i=i+1) begin
774                    mem_array[i] = 'bx;
775                end
776`else
777                memory_index = 0;
778                i = 0;
779                // remove the selected banks
780                for (memory_index=0; memory_index<mem_used; memory_index=memory_index+1) begin
781                    addr_array[i] = 'bx;
782                    mem_array[i] = 'bx;
783                    i = i + 1;
784                end
785`endif
786            end else begin
787`ifdef FULL_MEM
788                for (i={bank_MSB_row, {(ROW_BITS+COL_BITS-2){1'b1}}}; i<={1'b0, {(BA_BITS+ROW_BITS+COL_BITS){1'b1}}}; i=i+1) begin
789                    mem_array[i] = 'bx;
790                end
791`else
792                memory_index = 0;
793                i = 0;
794                // remove the selected banks
795                for (memory_index=0; memory_index<mem_used; memory_index=memory_index+1) begin
796                    if (addr_array[memory_index]>({bank_MSB_row, {(ROW_BITS+COL_BITS-2){1'b1}}})) begin
797                        addr_array[i] = 'bx;
798                        mem_array[i] = 'bx;
799                        i = i + 1;
800                    end else begin
801                        i = i + 1;
802                    end
803                end
804`endif
805            end
806        end
807    endtask
808
809    // Write Memory
810    task write_mem;
811        input [full_mem_bits - 1 : 0] addr;
812        input [DQ_BITS - 1 : 0] data;
813        reg [part_mem_bits : 0] i;
814        begin
815`ifdef FULL_MEM
816            mem_array[addr] = data;
817`else
818            begin : loop
819                for (i = 0; i < mem_used; i = i + 1) begin
820                    if (addr_array[i] === addr) begin
821                        disable loop;
822                    end
823                end
824            end
825            if (i === mem_used) begin
826                if (i === (1<<part_mem_bits)) begin
827                    $display ("%m: At time %t ERROR: Memory overflow.\n Write to Address %d with Data %d will be lost.\n You must increase the part_mem_bits parameter or `define FULL_MEM.", $realtime, addr, data);
828                end else begin
829                    mem_used = mem_used + 1;
830                    addr_array[i] = addr;
831                end
832            end
833            mem_array[i] = data;
834`endif
835        end
836    endtask
837
838    // Read Memory
839    task read_mem;
840        input [full_mem_bits - 1 : 0] addr;
841        output [DQ_BITS - 1 : 0] data;
842        reg [part_mem_bits : 0] i;
843        begin
844`ifdef FULL_MEM
845            data = mem_array[addr];
846`else
847            begin : loop
848                for (i = 0; i < mem_used; i = i + 1) begin
849                    if (addr_array[i] === addr) begin
850                        disable loop;
851                    end
852                end
853            end
854            if (i <= mem_used) begin
855                data = mem_array[i];
856            end else begin
857                data = 'bx;
858            end
859`endif
860        end
861    endtask
862
863    // Burst Decode
864    task Burst_Decode;
865    begin
866
867        // Advance Burst Counter
868// if (Burst_counter < burst_length) begin
869        if (Write_pipeline[-2]) begin
870            Burst_counter = Burst_counter + 1;
871        end
872
873        // Burst Type
874        if (Mode_reg[3] === 1'b0) begin // Sequential Burst
875            Cols_temp = Cols_addr + 1;
876        end else if (Mode_reg[3] === 1'b1) begin // Interleaved Burst
877            Cols_temp[2] = Burst_counter[2] ^ Cols_brst[2];
878            Cols_temp[1] = Burst_counter[1] ^ Cols_brst[1];
879            Cols_temp[0] = Burst_counter[0] ^ Cols_brst[0];
880        end
881
882        // Burst Length
883        if (burst_length === 2) begin
884            Cols_addr [0] = Cols_temp [0];
885        end else if (burst_length === 4) begin
886            Cols_addr [1 : 0] = Cols_temp [1 : 0];
887        end else if (burst_length === 8) begin
888            Cols_addr [2 : 0] = Cols_temp [2 : 0];
889        end else if (burst_length === 16) begin
890            Cols_addr [3 : 0] = Cols_temp [3 : 0];
891        end else begin
892            Cols_addr = Cols_temp;
893        end
894
895        // Data Counter
896// if (Burst_counter >= burst_length) begin
897// Data_in_enable = 1'b0;
898// Data_out_enable = 1'b0;
899// read_precharge_truncation = 1'b0;
900// SRR_read = 1'b0;
901// end
902    end
903    endtask
904
905
906    // SRC check
907    task Timing_chk_SRC;
908    begin
909        if (Active_enable || Aref_enable || Sref_enable || Burst_term ||
910            Ext_mode_enable || Mode_reg_enable || Prech_enable || Read_enable ||
911            Write_enable || DPD_enable || PD_enable || srr_enable) begin
912               if (part_size == 1024) begin
913                   if (SRC_cntr < ((Mode_reg[6:4])+tSRC)) begin
914                       $display ("%m: At time %t ERROR: tSRC Violation", $realtime);
915                   end
916               end
917        end
918    end
919    endtask
920
921    task ShiftPipelines;
922    begin
923        // read command pipeline
924        Read_pipeline = Read_pipeline >> 1;
925        Write_pipeline = Write_pipeline >> 1;
926        for (i = -2; i < `MAX_PIPE-1; i = i + 1)
927        begin
928            Write_col_pipeline [i] = Write_col_pipeline[i+1];
929            Write_bank_pipeline [i] = Write_bank_pipeline[i+1];
930        end
931    end
932    endtask
933
934    // Dq and Dqs Drivers
935    task Dq_Dqs_Drivers;
936    begin
937
938        // Initialize Read command
939        if (Read_pipeline [0] === 1'b1) begin
940// Data_out_enable = 1'b1;
941            Bank_addr = Write_bank_pipeline[0];
942            Cols_addr = Write_col_pipeline [0];
943            Cols_brst = Cols_addr [2 : 0];
944// if (SRR_read == 1'b1) begin
945// Burst_counter = burst_length - 2;
946// end else begin
947// Burst_counter = 0;
948// end
949
950            // Row Address Mux
951            case (Bank_addr)
952                2'd0 : Rows_addr = B0_row_addr;
953                2'd1 : Rows_addr = B1_row_addr;
954                2'd2 : Rows_addr = B2_row_addr;
955                2'd3 : Rows_addr = B3_row_addr;
956                default : $display ("%m: At time %t ERROR: Invalid Bank Address", $realtime);
957            endcase
958        end
959
960        // Read latch
961        if (Read_pipeline[0] === 1'b1) begin
962            // output data
963            if (SRR_read == 1'b1) begin
964                if (Cols_addr == 0) begin
965                    Dq_out_temp = Srr_reg[DQ_BITS-1:0];
966                end else begin
967                    Dq_out_temp = Srr_reg[2*DQ_BITS-1:DQ_BITS];
968                    SRR_read = 1'b0 ;
969                end
970            end else begin
971                read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_out_temp);
972            end
973            if (Debug) begin
974                $display ("At time %t %m:READ: Bank = %d, Row = %d, Col = %d, Data = %d", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_out);
975            end
976
977        end
978
979        Dq_out <= #(tAC_max) Dq_out_temp ;
980        Dqs_out <= #(tAC_max) ((|Read_pipeline[0]) & Sys_clk) ;
981
982        if (cas_latency == 3)
983            Dqs_out_en <= #(tAC_max) (|Read_pipeline[2:0]);
984        else
985            Dqs_out_en <= #(tAC_max) (|Read_pipeline[1:0]);
986        if (Sys_clk) begin
987            Dq_out_en <= #(tAC_max) (Read_pipeline[0]);
988        end
989
990    end
991    endtask
992
993    // Write FIFO and DM Mask Logic
994    task Write_FIFO_DM_Mask_Logic;
995    begin
996
997        // Initialize Write command
998        if (Write_pipeline [-2] === 1'b1) begin
999// Data_in_enable = 1'b1;
1000            Bank_addr = Write_bank_pipeline [-2];
1001            Cols_addr = Write_col_pipeline [-2];
1002            Cols_brst = Cols_addr [2 : 0];
1003// Burst_counter = 0;
1004
1005            // Row address mux
1006            case (Bank_addr)
1007                2'd0 : Rows_addr = B0_row_addr;
1008                2'd1 : Rows_addr = B1_row_addr;
1009                2'd2 : Rows_addr = B2_row_addr;
1010                2'd3 : Rows_addr = B3_row_addr;
1011                default : $display ("%m: At time %t ERROR: Invalid Row Address", $realtime);
1012            endcase
1013        end
1014
1015        // Write data
1016// if (Data_in_enable === 1'b1) begin
1017        if (Write_pipeline[-2] === 1'b1) begin
1018
1019            // Data Buffer
1020            read_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
1021
1022            // write negedge Dqs on posedge Sys_clk
1023            if (Sys_clk) begin
1024                if (!dm_fall[0]) begin
1025                    Dq_buf [ 7 : 0] = dq_fall [ 7 : 0];
1026                end
1027                if (!dm_fall[1]) begin
1028                    Dq_buf [15 : 8] = dq_fall [15 : 8];
1029                end
1030`ifdef x32
1031                if (!dm_fall[2]) begin
1032                    Dq_buf [23 : 16] = dq_fall [23 : 16];
1033                end
1034                if (!dm_fall[3]) begin
1035                    Dq_buf [31 : 24] = dq_fall [31 : 24];
1036                end
1037`endif
1038                if (~&dm_fall) begin
1039                    if (Debug) begin
1040                        $display ("At time %t %m:WRITE: Bank = %d, Row = %d, Col = %d, Data = %h", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
1041                    end
1042                end
1043            // write posedge Dqs on negedge Sys_clk
1044            end else begin
1045                if (!dm_rise[0]) begin
1046                    Dq_buf [ 7 : 0] = dq_rise [ 7 : 0];
1047                end
1048                if (!dm_rise[1]) begin
1049                    Dq_buf [15 : 8] = dq_rise [15 : 8];
1050                end
1051`ifdef x32
1052                if (!dm_rise[2]) begin
1053                    Dq_buf [23 : 16] = dq_rise [23 : 16];
1054                end
1055                if (!dm_rise[3]) begin
1056                    Dq_buf [31 : 24] = dq_rise [31 : 24];
1057                end
1058`endif
1059                if (~&dm_rise) begin
1060                    if (Debug) begin
1061                        $display ("At time %t %m:WRITE: Bank = %d, Row = %d, Col = %d, Data = %h", $realtime, Bank_addr, Rows_addr, Cols_addr, Dq_buf[DQ_BITS-1:0]);
1062                    end
1063                end
1064            end
1065
1066            // Write Data
1067            write_mem({Bank_addr, Rows_addr, Cols_addr}, Dq_buf);
1068            // tWR start and tWTR check
1069            if (Sys_clk && &dm_pair === 1'b0) begin
1070                case (Bank_addr)
1071                    2'd0 : WR_chk0 = $realtime;
1072                    2'd1 : WR_chk1 = $realtime;
1073                    2'd2 : WR_chk2 = $realtime;
1074                    2'd3 : WR_chk3 = $realtime;
1075                    default : $display ("%m: At time %t ERROR: Invalid Bank Address (tWR)", $realtime);
1076                endcase
1077
1078// // tWTR check
1079// if (Read_enable === 1'b1) begin
1080// $display ("%m: At time %t ERROR: tWTR violation during Read", $realtime);
1081// end
1082            end
1083        end
1084    end
1085    endtask
1086
1087    // Auto Precharge Calculation
1088    task Auto_Precharge_Calculation;
1089    begin
1090        // Precharge counter
1091        if (Read_precharge_access [0] === 1'b1 || Write_precharge_access [0] === 1'b1) begin
1092            Count_precharge [0] = Count_precharge [0] + 1;
1093        end
1094        if (Read_precharge_access [1] === 1'b1 || Write_precharge_access [1] === 1'b1) begin
1095            Count_precharge [1] = Count_precharge [1] + 1;
1096        end
1097        if (Read_precharge_access [2] === 1'b1 || Write_precharge_access [2] === 1'b1) begin
1098            Count_precharge [2] = Count_precharge [2] + 1;
1099        end
1100        if (Read_precharge_access [3] === 1'b1 || Write_precharge_access [3] === 1'b1) begin
1101            Count_precharge [3] = Count_precharge [3] + 1;
1102        end
1103
1104        // Read with AutoPrecharge Calculation
1105        // The device start internal precharge when:
1106        // 1. BL/2 cycles after command
1107        // 2. Meet tRAS requirement
1108        if (Read_precharge_access[0] & (Count_precharge[0] >= burst_length/2)) begin
1109            Read_precharge_access[0] = 1'b0 ;
1110            Read_precharge_pre[0] = 1'b1 ;
1111        end
1112        if ((Read_precharge_pre[0] === 1'b1) && ($realtime - RAS_chk0 >= tRAS - 0.001)) begin
1113            Pc_b0 = 1'b1;
1114            Act_b0 = 1'b0;
1115            RP_chk0 = $realtime;
1116            Read_precharge_pre[0] = 1'b0;
1117        end
1118
1119        if (Read_precharge_access[1] & (Count_precharge[1] >= burst_length/2)) begin
1120            Read_precharge_access[1] = 1'b0 ;
1121            Read_precharge_pre[1] = 1'b1 ;
1122        end
1123        if ((Read_precharge_pre[1] === 1'b1) && ($realtime - RAS_chk1 >= tRAS - 0.001)) begin
1124            Pc_b1 = 1'b1;
1125            Act_b1 = 1'b0;
1126            RP_chk1 = $realtime;
1127            Read_precharge_pre[1] = 1'b0;
1128        end
1129
1130        if (Read_precharge_access[2] & (Count_precharge[2] >= burst_length/2)) begin
1131            Read_precharge_access[2] = 1'b0 ;
1132            Read_precharge_pre[2] = 1'b1 ;
1133        end
1134        if ((Read_precharge_pre[2] === 1'b1) && ($realtime - RAS_chk2 >= tRAS - 0.001)) begin
1135            Pc_b2 = 1'b1;
1136            Act_b2 = 1'b0;
1137            RP_chk2 = $realtime;
1138            Read_precharge_pre[2] = 1'b0;
1139        end
1140
1141        if (Read_precharge_access[3] & (Count_precharge[3] >= burst_length/2)) begin
1142            Read_precharge_access[3] = 1'b0 ;
1143            Read_precharge_pre[3] = 1'b1 ;
1144        end
1145        if ((Read_precharge_pre[3] === 1'b1) && ($realtime - RAS_chk3 >= tRAS - 0.001)) begin
1146            Pc_b3 = 1'b1;
1147            Act_b3 = 1'b0;
1148            RP_chk3 = $realtime;
1149            Read_precharge_pre[3] = 1'b0;
1150        end
1151
1152        // Write with AutoPrecharge Calculation
1153        // The device start internal precharge when:
1154        // 1. Meet tRAS requirement
1155        // 2. Two clock after last burst
1156        // Since tWR is time base, the model will compensate tRP
1157        if (Write_precharge_access[0] & (Count_precharge[0] >= burst_length/2+3)) begin
1158            Write_precharge_access[0] = 1'b0 ;
1159            Write_precharge_pre[0] = 1'b1 ;
1160        end
1161        if (Write_precharge_pre[0] & ($realtime - RAS_chk0 >= tRAS - 0.001)) begin
1162                Write_precharge_pre[0] = 1'b0;
1163                Pc_b0 = 1'b1;
1164                Act_b0 = 1'b0;
1165                RP_chk0 = $realtime - ((2 * clk_period) - tWR);
1166        end
1167
1168        if (Write_precharge_access[1] & (Count_precharge[1] >= burst_length/2+3)) begin
1169            Write_precharge_access[1] = 1'b0 ;
1170            Write_precharge_pre[1] = 1'b1 ;
1171        end
1172        if (Write_precharge_pre[1] & ($realtime - RAS_chk1 >= tRAS - 0.001)) begin
1173                Write_precharge_pre[1] = 1'b0;
1174                Pc_b1 = 1'b1;
1175                Act_b1 = 1'b0;
1176                RP_chk1 = $realtime - ((2 * clk_period) - tWR);
1177        end
1178
1179        if (Write_precharge_access[2] & (Count_precharge[2] >= burst_length/2+3)) begin
1180            Write_precharge_access[2] = 1'b0 ;
1181            Write_precharge_pre[2] = 1'b1 ;
1182        end
1183        if (Write_precharge_pre[2] & ($realtime - RAS_chk2 >= tRAS - 0.001)) begin
1184                Write_precharge_pre[2] = 1'b0;
1185                Pc_b2 = 1'b1;
1186                Act_b2 = 1'b0;
1187                RP_chk2 = $realtime - ((2 * clk_period) - tWR);
1188        end
1189
1190        if (Write_precharge_access[3] & (Count_precharge[3] >= burst_length/2+3)) begin
1191            Write_precharge_access[3] = 1'b0 ;
1192            Write_precharge_pre[3] = 1'b1 ;
1193        end
1194        if (Write_precharge_pre[3] & ($realtime - RAS_chk3 >= tRAS - 0.001)) begin
1195                Write_precharge_pre[3] = 1'b0;
1196                Pc_b3 = 1'b1;
1197                Act_b3 = 1'b0;
1198                RP_chk3 = $realtime - ((2 * clk_period) - tWR);
1199        end
1200    end
1201    endtask
1202
1203    task Power_down_chk;
1204    begin
1205        if (DPD_enable == 1'b1 && enter_DPD == 1'b0) begin
1206            if (prev_cke & Pc_b0 & Pc_b1 & Pc_b2 & Pc_b3) begin
1207                erase_mem(4'b0000, 1'b1);
1208                current_init_state = begin_init ;
1209                ext_mode_load_done = 1'b0 ;
1210                mode_load_done = 1'b0 ;
1211                enter_DPD = 1'b1;
1212                $display ("%m: at time %t Entering Deep Power-Down Mode", $realtime);
1213            end
1214        end
1215        if (enter_DPD == 1'b1) begin
1216            if (Cke == 1'b1 && prev_cke == 1'b0) begin
1217                if (PD_cntr < tCKE) begin
1218                    $display ("%m: At time %t ERROR: tCKE violation during exiting of Deep Power-Down Mode", $realtime);
1219                end
1220                $display ("%m: at time %t Exiting Deep Power-Down Mode - A 200 us delay is required with either DESELECT or NOP commands present before the initialization sequence may begin", $realtime);
1221                enter_DPD = 1'b0;
1222            end
1223        end
1224        if (PD_enable == 1'b1 && enter_PD == 1'b0) begin
1225            if (prev_cke) begin
1226                if (Pc_b0 & Pc_b1 & Pc_b2 & Pc_b3) begin
1227                    $display ("%m: at time %t Entering Power-Down Mode", $realtime);
1228                    enter_PD = 1'b1;
1229                end else if (~Pc_b0 | ~Pc_b1 | ~Pc_b2 | ~Pc_b3) begin
1230                    $display ("%m: at time %t Entering Active Power-Down Mode", $realtime);
1231                    enter_APD = 1'b1;
1232                end
1233            end
1234        end
1235        if (enter_PD == 1'b1 || enter_APD == 1'b1) begin
1236            if (Cke == 1'b1 && prev_cke == 1'b0) begin
1237                if (PD_cntr < tCKE) begin
1238                    if (enter_PD == 1'b1) begin
1239                        $display ("%m: At time %t ERROR: tCKE violation during exiting of Power-Down Mode", $realtime);
1240                    end else if (enter_APD == 1'b1) begin
1241                        $display ("%m: At time %t ERROR: tCKE violation during exiting of Active Power-Down Mode", $realtime);
1242                    end
1243                end
1244                if (enter_PD == 1'b1) begin
1245                    $display ("%m: at time %t Exiting Power-Down Mode", $realtime);
1246                    enter_PD = 1'b0 ;
1247                end else if (enter_APD == 1'b1) begin
1248                    $display ("%m: at time %t Exiting Active Power-Down Mode", $realtime);
1249                    enter_APD = 1'b0 ;
1250                end
1251            end
1252        end
1253
1254    end
1255    endtask
1256
1257    reg [31:0] xx ;
1258    function [COL_BITS-1:0] Burst_Order;
1259        input [COL_BITS-1:0] Col;
1260        input [31:0] i;
1261    begin
1262        if (Mode_reg[3] == 1'b1) //interleaved
1263            Burst_Order = (Col & -1*burst_length) + (Col%burst_length ^ i);
1264        else // sequential
1265        begin
1266            xx = -1*burst_length;
1267            Burst_Order = (Col & xx) + (Col%burst_length + i) % (burst_length);
1268        end
1269    end
1270    endfunction
1271
1272    // Control Logic
1273    task Control_Logic;
1274    begin
1275
1276      // Self Refresh
1277        if (Sref_enable === 1'b1) begin
1278            // Partial Array Self Refresh
1279            if (part_size == 128) begin
1280                case (Ext_Mode_reg[2:0])
1281                    3'b000 : ;//keep Bank 0-7
1282                    3'b001 : begin $display("%m: at time %t INFO: Banks 2-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0111, 1'b0); end
1283                    3'b010 : begin $display("%m: at time %t INFO: Banks 1-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0011, 1'b0); end
1284                    3'b011 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1285                    3'b100 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1286                    3'b101 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1287                    3'b110 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1288                endcase
1289            end else begin
1290                case (Ext_Mode_reg[2:0])
1291                    3'b000 : ;//keep Bank 0-7
1292                    3'b001 : begin $display("%m: at time %t INFO: Banks 2-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0111, 1'b0); end
1293                    3'b010 : begin $display("%m: at time %t INFO: Banks 1-3 will be lost due to Partial Array Self Refresh", $realtime) ; erase_mem(4'b0011, 1'b0); end
1294                    3'b011 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1295                    3'b100 : begin $display("%m: at time %t INFO: Reserved", $realtime) ; end
1296                    3'b101 : begin $display("%m: at time %t INFO: Banks 1-3 and 1/2 of bank 0 will be lost due to Partial Array Self Refresh", $realtime); erase_mem(4'b0001, 1'b0); end
1297                    3'b110 : begin $display("%m: at time %t INFO: Banks 1-3 and 3/4 of bank 0 will be lost due to Partial Array Self Refresh", $realtime); erase_mem(4'b0000, 1'b0); end
1298                endcase
1299            end
1300            SelfRefresh = 1'b1;
1301        end
1302        if (Aref_enable === 1'b1) begin
1303            if (Debug) begin
1304                $display ("Debug: At time %t %m:AUTOREFRESH: Auto Refresh", $realtime);
1305            end
1306            // aref_count is to make sure we have met part of the initialization sequence
1307            if (~power_up_done) begin
1308                aref_count = aref_count + 1;
1309            end
1310
1311            // Auto Refresh to Auto Refresh
1312            if ($realtime - RFC_chk < tRFC - 0.001) begin
1313                $display ("%m: At time %t ERROR: tRFC violation during Auto Refresh", $realtime);
1314            end
1315            
1316            // Precharge to Auto Refresh
1317            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1318                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1319                $display ("%m: At time %t ERROR: tRP violation during Auto Refresh", $realtime);
1320            end
1321            
1322            // Precharge to Auto Refresh
1323            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
1324                $display ("%m: At time %t ERROR: All banks must be Precharged before Auto Refresh", $realtime);
1325            end
1326            
1327            // Record Current tRFC time
1328            RFC_chk = $realtime;
1329        end
1330
1331        // SRR Register
1332        if (srr_enable == 1'b1) begin
1333            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1 &&
1334                Data_out_enable === 1'b0 && Data_in_enable === 1'b0) begin
1335                SRR_read = 1'b1;
1336                SRR_chk = $realtime;
1337                SRR_cntr = 0;
1338            end
1339        end
1340
1341
1342        // Extended Mode Register
1343        if (Ext_mode_enable == 1'b1) begin
1344            if (Debug) begin
1345                $display ("Debug: At time %t %m:EMR : Extended Mode Register", $realtime);
1346            end
1347
1348            // Register Mode
1349            Ext_Mode_reg = Addr;
1350
1351            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1) begin
1352                // ensure that power sequence is met properly
1353                if (~power_up_done) begin
1354                    ext_mode_load_done = 1'b1;
1355                end
1356                $display ("At time %t %m:ELMR : Extended Load Mode Register", $realtime);
1357                if (part_size == 128) begin
1358                    // Self Refresh Coverage
1359                    case (Addr[2 : 0])
1360                        3'b000 : $display ("%m : Self Refresh Cov = 4 banks");
1361                        3'b001 : $display ("%m : Self Refresh Cov = 2 banks");
1362                        3'b010 : $display ("%m : Self Refresh Cov = 1 bank");
1363                        3'b101 : $display ("%m : PASR = Reserved");
1364                        3'b110 : $display ("%m : PASR = Reserved");
1365                        default : $display ("%m : PASR = Reserved");
1366                    endcase
1367                end else begin
1368                    // Self Refresh Coverage
1369                    case (Addr[2 : 0])
1370                        3'b000 : $display ("%m : Self Refresh Cov = 4 banks");
1371                        3'b001 : $display ("%m : Self Refresh Cov = 2 banks");
1372                        3'b010 : $display ("%m : Self Refresh Cov = 1 bank");
1373                        3'b101 : $display ("%m : Self Refresh Cov = 1/2 bank");
1374                        3'b110 : $display ("%m : Self Refresh Cov = 1/4 bank");
1375                        default : $display ("%m : PASR = Reserved");
1376                    endcase
1377                end
1378                // Maximum Case Temp
1379// case (Addr[4 : 3])
1380// 2'b11 : $display ("%m : Maximum Case Temp = 85C");
1381// 2'b00 : $display ("%m : Maximum Case Temp = 70C");
1382// 2'b01 : $display ("%m : Maximum Case Temp = 45C");
1383// 2'b10 : $display ("%m : Maximum Case Temp = 15C");
1384// endcase
1385
1386                // Drive Strength
1387                case (Addr[7 : 5])
1388                    3'b000 : $display ("%m : Drive Strength = Full Strength");
1389                    3'b001 : $display ("%m : Drive Strength = Half Strength");
1390                    3'b010 : $display ("%m : Drive Strength = Quarter Strength");
1391                    3'b011 : $display ("%m : Drive Strength = Three Quarter Strength");
1392                    3'b100 : $display ("%m : Drive Strength = Three Quarter Strength");
1393                endcase
1394
1395            end else begin
1396                $display ("%m: At time %t ERROR: all banks must be Precharged before Extended Mode Register", $realtime);
1397            end
1398
1399            // Precharge to EMR
1400            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1401                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1402                $display ("%m: At time %t ERROR: tRP violation during Extended Mode Register", $realtime);
1403            end
1404
1405            // LMR/EMR to LMR/EMR
1406// if ($realtime - MRD_chk < tMRD) begin
1407// $display ("%m: At time %t ERROR: tMRD violation during Extended Mode Register", $realtime);
1408// end
1409
1410            if (MRD_cntr < tMRD) begin
1411                $display ("%m: At time %t ERROR: tMRD violation during Extended Mode Register", $realtime);
1412            end
1413
1414            // Record current tMRD time
1415// MRD_chk = $realtime;
1416            MRD_cntr = 0;
1417        end
1418    
1419        // Load Mode Register
1420        if (Mode_reg_enable === 1'b1) begin
1421            if (Debug) begin
1422                $display ("Debug: At time %t %m:LMR : Load Mode Register", $realtime);
1423            end
1424
1425            // Register Mode
1426            Mode_reg = Addr;
1427
1428            if (Mode_reg[6:4] == 3'b010) begin
1429                if (tCK2_min == 0) begin
1430                    $display ("%m : at time %t ERROR : Illegal CAS Latency of 2 set for current speed grade", $realtime);
1431                end
1432            end
1433
1434            // Precharge to LMR
1435            if (Pc_b0 === 1'b0 || Pc_b1 === 1'b0 || Pc_b2 === 1'b0 || Pc_b3 === 1'b0) begin
1436                $display ("%m: At time %t ERROR: all banks must be Precharged before Load Mode Register", $realtime);
1437            end
1438
1439            // Precharge to LMR
1440            if (($realtime - RP_chk0 < tRP - 0.001) || ($realtime - RP_chk1 < tRP - 0.001) ||
1441                ($realtime - RP_chk2 < tRP - 0.001) || ($realtime - RP_chk3 < tRP - 0.001)) begin
1442                $display ("%m: At time %t ERROR: tRP violation during Load Mode Register", $realtime);
1443            end
1444
1445            // LMR/EMR to LMR/EMR
1446// if ($realtime - MRD_chk < tMRD) begin
1447// $display ("%m: At time %t ERROR: tMRD violation during Load Mode Register", $realtime);
1448// end
1449            if (MRD_cntr < tMRD) begin
1450                $display ("%m: At time %t ERROR: tMRD violation during Load Mode Register", $realtime);
1451            end
1452
1453            if (Pc_b0 === 1'b1 && Pc_b1 === 1'b1 && Pc_b2 === 1'b1 && Pc_b3 === 1'b1) begin
1454                // ensure that power sequence is met properly
1455                if (~power_up_done) begin
1456                    mode_load_done = 1'b1;
1457                end
1458               // Burst Length
1459               case (Addr [2 : 0])
1460                   3'b001 : $display ("At time %t %m:LMR : Burst Length = 2", $realtime);
1461                   3'b010 : $display ("At time %t %m:LMR : Burst Length = 4", $realtime);
1462                   3'b011 : $display ("At time %t %m:LMR : Burst Length = 8", $realtime);
1463                   3'b100 : $display ("At time %t %m:LMR : Burst Length = 16",$realtime);
1464                   default :
1465                     begin
1466                       $display ("%m: At time %t ERROR: Undefined burst length selection", $realtime);
1467                       $stop;
1468                     end
1469               endcase
1470   
1471               // CAS Latency
1472               case (Addr [6 : 4])
1473                   3'b010 : $display ("At time %t %m:LMR : CAS Latency = 2", $realtime);
1474                   3'b011 : $display ("At time %t %m:LMR : CAS Latency = 3", $realtime);
1475                   default : begin
1476                       $display ("%m: At time %t ERROR: CAS Latency not supported", $realtime);
1477                       $stop;
1478                   end
1479               endcase
1480   
1481            end
1482            // Record current tMRD time
1483// MRD_chk = $realtime;
1484            MRD_cntr = 0;
1485        end
1486
1487        // Activate Block
1488        if (Active_enable === 1'b1) begin
1489            if (!(power_up_done)) begin
1490                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Activate command", $realtime);
1491            end
1492            // Display Debug Message
1493            if (Debug) begin
1494                $display ("Debug: At time %t %m:ACTIVATE: Bank = %d, Row = %d", $realtime, Ba, Addr);
1495            end
1496
1497            // Activating an open bank can cause corruption.
1498            if ((Ba === 2'b00 && Pc_b0 === 1'b0) || (Ba === 2'b01 && Pc_b1 === 1'b0) ||
1499                (Ba === 2'b10 && Pc_b2 === 1'b0) || (Ba === 2'b11 && Pc_b3 === 1'b0)) begin
1500                $display ("%m: At time %t ERROR: Bank = %d is already activated - data can be corrupted", $realtime, Ba);
1501            end
1502            
1503            // Activate Bank 0
1504            if (Ba === 2'b00 && Pc_b0 === 1'b1) begin
1505                // Activate to Activate (same bank)
1506                if ($realtime - RC_chk0 < tRC - 0.001) begin
1507                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1508                end
1509
1510                // Precharge to Activate
1511                if ($realtime - RP_chk0 < tRP - 0.001) begin
1512                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1513                end
1514
1515                // Record variables for checking violation
1516                Act_b0 = 1'b1;
1517                Pc_b0 = 1'b0;
1518                B0_row_addr = Addr;
1519                RC_chk0 = $realtime;
1520                RCD_chk0 = $realtime;
1521                RAS_chk0 = $realtime;
1522                RAP_chk0 = $realtime;
1523            end
1524
1525            // Activate Bank 1
1526            if (Ba === 2'b01 && Pc_b1 === 1'b1) begin
1527                // Activate to Activate (same bank)
1528                if ($realtime - RC_chk1 < tRC - 0.001) begin
1529                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1530                end
1531
1532                // Precharge to Activate
1533                if ($realtime - RP_chk1 < tRP - 0.001) begin
1534                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1535                end
1536
1537                // Record variables for checking violation
1538                Act_b1 = 1'b1;
1539                Pc_b1 = 1'b0;
1540                B1_row_addr = Addr;
1541                RC_chk1 = $realtime;
1542                RCD_chk1 = $realtime;
1543                RAS_chk1 = $realtime;
1544                RAP_chk1 = $realtime;
1545            end
1546
1547            // Activate Bank 2
1548            if (Ba === 2'b10 && Pc_b2 === 1'b1) begin
1549                // Activate to Activate (same bank)
1550                if ($realtime - RC_chk2 < tRC - 0.001) begin
1551                    $display ("%m: At time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1552                end
1553
1554                // Precharge to Activate
1555                if ($realtime - RP_chk2 < tRP - 0.001) begin
1556                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1557                end
1558
1559                // Record variables for checking violation
1560                Act_b2 = 1'b1;
1561                Pc_b2 = 1'b0;
1562                B2_row_addr = Addr;
1563                RC_chk2 = $realtime;
1564                RCD_chk2 = $realtime;
1565                RAS_chk2 = $realtime;
1566                RAP_chk2 = $realtime;
1567            end
1568
1569            // Activate Bank 3
1570            if (Ba === 2'b11 && Pc_b3 === 1'b1) begin
1571                // Activate to Activate (same bank)
1572                if ($realtime - RC_chk3 < tRC - 0.001) begin
1573                    $display ("%m: t time %t ERROR: tRC violation during Activate bank %d", $realtime, Ba);
1574                end
1575
1576                // Precharge to Activate
1577                if ($realtime - RP_chk3 < tRP - 0.001) begin
1578                    $display ("%m: At time %t ERROR: tRP violation during Activate bank %d", $realtime, Ba);
1579                end
1580
1581                // Record variables for checking violation
1582                Act_b3 = 1'b1;
1583                Pc_b3 = 1'b0;
1584                B3_row_addr = Addr;
1585                RC_chk3 = $realtime;
1586                RCD_chk3 = $realtime;
1587                RAS_chk3 = $realtime;
1588                RAP_chk3 = $realtime;
1589            end
1590
1591            // Activate to Activate (different bank)
1592            if ((Prev_bank != Ba) && ($realtime - RRD_chk < tRRD - 0.001)) begin
1593                $display ("%m: At time %t ERROR: tRRD violation during Activate bank = %d", $realtime, Ba);
1594            end
1595            
1596            // AutoRefresh to Activate
1597            if ($realtime - RFC_chk < tRFC - 0.001) begin
1598                $display ("%m: At time %t ERROR: tRFC violation during Activate bank %d", $realtime, Ba);
1599            end
1600
1601            // Record variable for checking violation
1602            RRD_chk = $realtime;
1603            Prev_bank = Ba;
1604        end
1605    
1606        // Precharge Block - consider NOP if bank already precharged or in process of precharging
1607        if (Prech_enable === 1'b1) begin
1608            // Display Debug Message
1609            if (Debug) begin
1610                $display ("Debug: At time %t %m:PRE: Addr[10] = %b, Bank = %b", $realtime, Addr[10], Ba);
1611            end
1612
1613            // EMR or LMR to Precharge
1614// if ($realtime - MRD_chk < tMRD) begin
1615// $display ("%m: At time %t ERROR: tMRD violation during Precharge", $realtime);
1616// end
1617            if (MRD_cntr < tMRD) begin
1618                $display ("%m: At time %t ERROR: tMRD violation during Precharge", $realtime);
1619            end
1620
1621            // Precharge bank 0
1622            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b00)) && Act_b0 === 1'b1) begin
1623                Act_b0 = 1'b0;
1624                Pc_b0 = 1'b1;
1625                RP_chk0 = $realtime;
1626                
1627                // Activate to Precharge Bank
1628                if ($realtime - RAS_chk0 < tRAS - 0.001) begin
1629                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1630                end
1631                
1632                // tWR violation check for Write
1633                if ($realtime - WR_chk0 < tWR - 0.001) begin
1634                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1635                end
1636            end
1637
1638            // Precharge bank 1
1639            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b01)) && Act_b1 === 1'b1) begin
1640                Act_b1 = 1'b0;
1641                Pc_b1 = 1'b1;
1642                RP_chk1 = $realtime;
1643
1644                // Activate to Precharge Bank 1
1645                if ($realtime - RAS_chk1 < tRAS - 0.001) begin
1646                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1647                end
1648                
1649                // tWR violation check for Write
1650                if ($realtime - WR_chk1 < tWR - 0.001) begin
1651                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1652                end
1653            end
1654
1655            // Precharge bank 2
1656            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b10)) && Act_b2 === 1'b1) begin
1657                Act_b2 = 1'b0;
1658                Pc_b2 = 1'b1;
1659                RP_chk2 = $realtime;
1660                
1661                // Activate to Precharge Bank 2
1662                if ($realtime - RAS_chk2 < tRAS - 0.001) begin
1663                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1664                end
1665                
1666                // tWR violation check for Write
1667                if ($realtime - WR_chk2 < tWR - 0.001) begin
1668                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1669                end
1670            end
1671
1672            // Precharge bank 3
1673            if ((Addr[10] === 1'b1 || (Addr[10] === 1'b0 && Ba === 2'b11)) && Act_b3 === 1'b1) begin
1674                Act_b3 = 1'b0;
1675                Pc_b3 = 1'b1;
1676                RP_chk3 = $realtime;
1677                
1678                // Activate to Precharge Bank 3
1679                if ($realtime - RAS_chk3 < tRAS - 0.001) begin
1680                    $display ("%m: At time %t ERROR: tRAS violation during Precharge", $realtime);
1681                end
1682                
1683                // tWR violation check for Write
1684                if ($realtime - WR_chk3 < tWR - 0.001) begin
1685                    $display ("%m: At time %t ERROR: tWR violation during Precharge", $realtime);
1686                end
1687            end
1688
1689            // Pipeline for READ
1690            if ((Addr[10] === 1'b1) | (Ba == Write_bank_pipeline[4]))
1691                for (i = 4; i < `MAX_PIPE; i = i + 1)
1692                    Read_pipeline[i] = 1'b0 ;
1693    
1694        end
1695    
1696        // Burst terminate
1697        if (Burst_term === 1'b1) begin
1698            // Display Debug Message
1699            if (Debug) begin
1700                $display ("Debug: %m: At time %t BURST_TERMINATE): Burst Terminate",$realtime);
1701            end
1702
1703            // Burst Terminate Command Pipeline for Read
1704            for (i = cas_latency_x2-1; i < `MAX_PIPE; i = i + 1)
1705                Read_pipeline[i] = 1'b0 ;
1706            // Illegal to burst terminate a Write
1707            if ((Data_in_enable === 1'b1) & ~((&dm_rise) & (&dm_fall))) begin
1708                $display ("%m: At time %t ERROR: It's illegal to burst terminate a Write", $realtime);
1709            end
1710            
1711            // Illegal to burst terminate a Read with Auto Precharge
1712            if (|Read_precharge_access) begin
1713                $display ("%m: At time %t ERROR: It's illegal to burst terminate a Read with Auto Precharge", $realtime);
1714            end
1715        end
1716        
1717        // Read Command
1718        if (Read_enable === 1'b1) begin
1719            if (!(power_up_done)) begin
1720                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Read Command", $realtime);
1721            end
1722            // Display Debug Message
1723            if (Debug) begin
1724                $display ("Debug: At time %t %m:READ: Bank = %d, Col = %d", $realtime, Ba, {Addr [11], Addr [9 : 0]});
1725            end
1726            if (part_size == 1024) begin
1727                if (SRR_read == 1'b1) begin
1728                    if (SRR_cntr < tSRR) begin
1729                        $display ("%m: At time %t ERROR: tSRR Violation", $realtime);
1730                    end
1731                    SRC_cntr = 0 ;
1732                end
1733            end else begin
1734                if (SRR_read == 1'b1) begin
1735                    if ($realtime - SRR_chk < tSRR-0.01) begin
1736                        $display ("%m: At time %t ERROR: tSRR Violation", $realtime);
1737                    end
1738                    SRC_cntr = 0;
1739                end
1740            end
1741            // CAS Latency pipeline
1742            if (SRR_read) begin
1743                if ({Ba, Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]} > 0) begin
1744                   $display ("%m: At time %t ERROR: Address must be all 0 during SRR Read", $realtime);
1745                end
1746                for (i=0; i<2; i=i+1)
1747                begin
1748                    Read_pipeline[cas_latency_x2 - 2 + i + 1] = 1'b1;
1749                    Write_col_pipeline [cas_latency_x2 - 2 + i + 1] = i;
1750                    Write_bank_pipeline [cas_latency_x2 - 2 + i + 1] = 0;
1751                end
1752            end else begin
1753                for (i=0; i<burst_length; i=i+1)
1754                begin
1755                    Read_pipeline[cas_latency_x2 - 2 + i + 1] = 1'b1;
1756                    Write_bank_pipeline [cas_latency_x2 - 2 + i + 1] = Ba;
1757                    Write_col_pipeline [cas_latency_x2 - 2 + i + 1] = Burst_Order({Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}, i);
1758                end
1759            end
1760
1761            // Clear out Write Pipeline
1762            Write_pipeline = 64'b0;
1763
1764            // Interrupt a Read with Auto Precharge
1765            if (Read_precharge_access [Ba] === 1'b1) begin
1766                $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (same bank)", $realtime);
1767            end else if ((Read_precharge_access [0] === 1'b1) |
1768                         (Read_precharge_access [1] === 1'b1) |
1769                         (Read_precharge_access [2] === 1'b1) |
1770                         (Read_precharge_access [3] === 1'b1) ) begin
1771                $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (different banks)", $realtime);
1772            end
1773
1774            // Interrupt a Write with Auto Precharge
1775            if (Write_precharge_access [Ba] === 1'b1) begin
1776// $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (same banks)", $realtime);
1777            end else if ((Write_precharge_count [0] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1778                         (Write_precharge_count [1] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1779                         (Write_precharge_count [2] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1780                         (Write_precharge_count [3] < (burst_length/2 )) & (Mode_reg[6:4] == 3'b010) |
1781                         (Write_precharge_count [0] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1782                         (Write_precharge_count [1] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1783                         (Write_precharge_count [2] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) |
1784                         (Write_precharge_count [3] < (burst_length/2-1)) & (Mode_reg[6:4] == 3'b011) ) begin
1785                $display ("%m: At time %t ERROR: It's illegal to interrupt a data transfer on a Write with Auto Precharge (different banks)", $realtime);
1786            end
1787
1788            // Activate to Read
1789            if (((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1790                 (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) &&
1791                (SRR_read == 1'b0)) begin
1792                $display("%m: At time %t ERROR: Bank is not Activated for Read", $realtime);
1793            end
1794
1795            // Activate to Read without Auto Precharge
1796            if ((Addr [10] === 1'b0 && Ba === 2'b00 && $realtime - RCD_chk0 < tRCD - 0.001) ||
1797                (Addr [10] === 1'b0 && Ba === 2'b01 && $realtime - RCD_chk1 < tRCD - 0.001) ||
1798                (Addr [10] === 1'b0 && Ba === 2'b10 && $realtime - RCD_chk2 < tRCD - 0.001) ||
1799                (Addr [10] === 1'b0 && Ba === 2'b11 && $realtime - RCD_chk3 < tRCD - 0.001)) begin
1800                $display("%m: At time %t ERROR: tRCD violation during Read", $realtime);
1801            end
1802
1803            // Auto Precharge
1804            if (Addr[10] === 1'b1) begin
1805                Read_precharge_access [Ba]= 1'b1;
1806                Count_precharge [Ba]= 0;
1807                Read_precharge_count[Ba] = 4'h0;
1808            end
1809            
1810            // tWTR
1811            if (tWTR_cntr < tWTR - 0.001) begin
1812                $display("%m: At time %t ERROR: tWTR violation during Read", $realtime);
1813            end
1814        end
1815
1816        // Write Command
1817        if (Write_enable === 1'b1) begin
1818            if (!(power_up_done)) begin
1819                $display ("%m: At time %t ERROR: Power Up and Initialization Sequence not completed before executing Write Command", $realtime);
1820            end
1821            // display debug message
1822            if (Debug) begin
1823                $display ("Debug: At time %t %m:WRITE: Bank = %d, Col = %d", $realtime, Ba, {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]});
1824            end
1825
1826            // Pipeline for Write
1827// Write_pipeline [3] = 1'b1;
1828            for (i=0; i<burst_length; i=i+1)
1829            begin
1830                Write_pipeline[1 + i] = 1'b1;
1831// Write_col_pipeline [1 + i] = {Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]} + i;
1832                Write_col_pipeline [1 + i] = Burst_Order({Addr [ADDR_BITS - 1 : 11], Addr [9 : 0]}, i);
1833                Write_bank_pipeline [1 + i] = Ba;
1834
1835            end
1836
1837            // Interrupt a Write with Auto Precharge (same bank only)
1838            if (Write_precharge_access [Ba] === 1'b1) begin
1839                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge", $realtime);
1840            end
1841
1842            // Activate to Write
1843            if ((Ba === 2'b00 && Pc_b0 === 1'b1) || (Ba === 2'b01 && Pc_b1 === 1'b1) ||
1844                (Ba === 2'b10 && Pc_b2 === 1'b1) || (Ba === 2'b11 && Pc_b3 === 1'b1)) begin
1845                $display("%m: At time %t ERROR: Bank is not Activated for Write", $realtime);
1846            end
1847
1848            // Activate to Write
1849            if ((Ba === 2'b00 && $realtime - RCD_chk0 < tRCD - 0.001) ||
1850                (Ba === 2'b01 && $realtime - RCD_chk1 < tRCD - 0.001) ||
1851                (Ba === 2'b10 && $realtime - RCD_chk2 < tRCD - 0.001) ||
1852                (Ba === 2'b11 && $realtime - RCD_chk3 < tRCD - 0.001)) begin
1853                $display("%m: At time %t ERROR: tRCD violation during Write to Bank %d", $realtime, Ba);
1854            end
1855
1856            if (Read_pipeline[0]) begin
1857                $display("%m: At time %t ERROR: Read to Write violation", $realtime);
1858            end
1859
1860            // Interrupt a Write with Auto Precharge
1861            if (Write_precharge_access [Ba] === 1'b1) begin
1862                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (same bank)", $realtime);
1863            end else if (((Write_precharge_access [0] === 1'b1) & (Count_precharge[0] < (burst_length/2))) |
1864                         ((Write_precharge_access [1] === 1'b1) & (Count_precharge[1] < (burst_length/2))) |
1865                         ((Write_precharge_access [2] === 1'b1) & (Count_precharge[2] < (burst_length/2))) |
1866                         ((Write_precharge_access [3] === 1'b1) & (Count_precharge[3] < (burst_length/2))) ) begin
1867                $display ("%m: At time %t ERROR: It's illegal to interrupt a Write with Auto Precharge (different bank)", $realtime);
1868            end
1869
1870            // Interrupt a Read with Auto Precharge
1871            if (((Read_precharge_count [Ba] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1872                ((Read_precharge_count [Ba] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) ) begin
1873// $display ("%m: At time %t ERROR: It's illegal to interrupt a Read with Auto Precharge (same bank)", $realtime);
1874            end else if (((Read_precharge_count [0] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1875                         ((Read_precharge_count [1] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1876                         ((Read_precharge_count [2] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1877                         ((Read_precharge_count [3] < (4'h2 + (burst_length/2))) & (Mode_reg[6:4] == 3'b010)) |
1878                         ((Read_precharge_count [0] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1879                         ((Read_precharge_count [1] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1880                         ((Read_precharge_count [2] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) |
1881                         ((Read_precharge_count [3] < (4'h3 + (burst_length/2))) & (Mode_reg[6:4] == 3'b011)) ) begin
1882                $display ("%m: At time %t ERROR: It's illegal to interrupt a data transfer on a Read with Auto Precharge (different bank)", $realtime);
1883            end
1884            
1885            // Auto Precharge
1886            if (Addr[10] === 1'b1) begin
1887                Write_precharge_access [Ba]= 1'b1;
1888                Count_precharge [Ba]= 0;
1889                Write_precharge_count[Ba] = 4'h0;
1890            end
1891        end
1892
1893    end
1894    endtask
1895
1896    // Main Logic
1897    always @ (posedge Sys_clk) begin
1898        ShiftPipelines;
1899// Manual_Precharge_Pipeline;
1900// Burst_Terminate_Pipeline;
1901        Dq_Dqs_Drivers;
1902        Write_FIFO_DM_Mask_Logic;
1903        Burst_Decode;
1904        Auto_Precharge_Calculation;
1905        Timing_chk_SRC;
1906        Control_Logic;
1907        MRD_counter;
1908        SRR_counter;
1909        SRC_counter;
1910        tWTR_counter;
1911        command_counter;
1912    end
1913
1914    always @ (negedge Sys_clk) begin
1915        ShiftPipelines;
1916// Manual_Precharge_Pipeline;
1917// Burst_Terminate_Pipeline;
1918        Dq_Dqs_Drivers;
1919        Write_FIFO_DM_Mask_Logic;
1920        Burst_Decode;
1921    end
1922
1923    // Dqs Receiver
1924    always @ (posedge Dqs_in[0]) begin
1925        // Latch data at posedge Dqs
1926        dq_rise[7 : 0] = Dq_in[7 : 0];
1927        dm_rise[0] = Dm_in[0];
1928        expect_pos_dqs[0] = 0;
1929    end
1930
1931    always @ (posedge Dqs_in[1]) begin
1932        // Latch data at posedge Dqs
1933        dq_rise[15 : 8] = Dq_in[15 : 8];
1934        dm_rise[1] = Dm_in[1];
1935        expect_pos_dqs[1] = 0;
1936    end
1937
1938`ifdef x32
1939    always @ (posedge Dqs_in[2]) begin
1940        // Latch data at posedge Dqs
1941        dq_rise[23 : 16] = Dq_in[23 : 16];
1942        dm_rise[2] = Dm_in[2];
1943        expect_pos_dqs[2] = 0;
1944    end
1945
1946    always @ (posedge Dqs_in[3]) begin
1947        // Latch data at posedge Dqs
1948        dq_rise[31 : 24] = Dq_in[31 : 24];
1949        dm_rise[3] = Dm_in[3];
1950        expect_pos_dqs[3] = 0;
1951    end
1952`endif
1953
1954    always @ (negedge Dqs_in[0]) begin
1955        // Latch data at negedge Dqs
1956        dq_fall[7 : 0] = Dq_in[7 : 0];
1957        dm_fall[0] = Dm_in[0];
1958        dm_pair[1:0] = {dm_rise[0], dm_fall[0]};
1959        expect_neg_dqs[0] = 0;
1960    end
1961
1962    always @ (negedge Dqs_in[1]) begin
1963        // Latch data at negedge Dqs
1964        dq_fall[15: 8] = Dq_in[15 : 8];
1965        dm_fall[1] = Dm_in[1];
1966        dm_pair[3:2] = {dm_rise[1], dm_fall[1]};
1967        expect_neg_dqs[1] = 0;
1968    end
1969
1970`ifdef x32
1971    always @ (negedge Dqs_in[2]) begin
1972        // Latch data at negedge Dqs
1973        dq_fall[23: 16] = Dq_in[23 : 16];
1974        dm_fall[2] = Dm_in[2];
1975        dm_pair[5:4] = {dm_rise[2], dm_fall[2]};
1976        expect_neg_dqs[2] = 0;
1977    end
1978
1979    always @ (negedge Dqs_in[3]) begin
1980        // Latch data at negedge Dqs
1981        dq_fall[31: 24] = Dq_in[31 : 24];
1982        dm_fall[3] = Dm_in[3];
1983        dm_pair[7:6] = {dm_rise[3], dm_fall[3]};
1984        expect_neg_dqs[3] = 0;
1985    end
1986`endif
1987
1988    // Dqs edge checking
1989    always @ (posedge Sys_clk) begin
1990// if (Write_pipeline[2] || Write_pipeline[1] || Data_in_enable) begin
1991        if (Write_pipeline[-1]) begin
1992            for (i=0; i<DQS_BITS; i=i+1) begin
1993                if (expect_neg_dqs[i]) begin
1994                    $display ("%m: At time %t ERROR: Negative DQS[%1d] transition required.", $realtime, i);
1995                end
1996                expect_neg_dqs[i] = 1'b1;
1997            end
1998        end else begin
1999           expect_neg_dqs = 0;
2000           expect_pos_dqs = 0;
2001        end
2002    end
2003
2004    always @ (negedge Sys_clk) begin
2005// if (Write_pipeline[2] || Write_pipeline[1] || Data_in_enable) begin
2006        if (Write_pipeline[-1]) begin
2007            for (i=0; i<DQS_BITS; i=i+1) begin
2008                if (expect_pos_dqs[i]) begin
2009                    $display ("%m: At time %t ERROR: Positive DQS[%1d] transition required.", $realtime, i);
2010                end
2011                expect_pos_dqs[i] = 1'b1;
2012            end
2013        end else begin
2014           expect_neg_dqs = 0;
2015           expect_pos_dqs = 0;
2016        end
2017    end
2018
2019    specify
2020                                                   // SYMBOL UNITS DESCRIPTION
2021                                                   // ------ ----- -----------
2022`ifdef sg5 // specparams for -6 (CL = 3)
2023        specparam tCLK_MIN = 5.0 ; // tCLK ns minimum clk cycle time
2024        specparam tDSS = 1.0 ; // tDSS ns DQS falling edge to CLK rising (setup time)
2025        specparam tDSH = 1.0 ; // tDSH ns DQS falling edge from CLK rising (hold time)
2026        specparam tIH = 1.0 ; // tIH ns Input Hold Time (fast)
2027        specparam tIS = 1.0 ; // tIS ns Input Setup Time (fast)
2028        specparam tDQSH = 1.75; // tDQSH ns DQS input High Pulse Width
2029        specparam tDQSL = 1.75; // tDQSL ns DQS input Low Pulse Width
2030`elsif sg54 // specparams for -6 (CL = 3)
2031        specparam tCLK_MIN = 5.4; // tCLK ns minimum clk cycle time
2032        specparam tDSS = 1.08; // tDSS ns DQS falling edge to CLK rising (setup time)
2033        specparam tDSH = 1.08; // tDSH ns DQS falling edge from CLK rising (hold time)
2034        specparam tIH = 1.0; // tIH ns Input Hold Time (fast)
2035        specparam tIS = 1.0; // tIS ns Input Setup Time (fast)
2036        specparam tDQSH = 2.16; // tDQSH ns DQS input High Pulse Width
2037        specparam tDQSL = 2.16; // tDQSL ns DQS input Low Pulse Width
2038`elsif sg6 // specparams for -6 (CL = 3)
2039        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2040        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2041        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2042        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2043        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2044        specparam tDQSH = 2.1; // tDQSH ns DQS input High Pulse Width
2045        specparam tDQSL = 2.1; // tDQSL ns DQS input Low Pulse Width
2046`elsif sg75 // specparams for -75 (CL = 3)
2047        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2048        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2049        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2050        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2051        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2052        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2053        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2054`elsif sg5v18 // specparams for -6 (CL = 3)
2055        specparam tCLK_MIN = 5.0 ; // tCLK ns minimum clk cycle time
2056        specparam tDSS = 1.0 ; // tDSS ns DQS falling edge to CLK rising (setup time)
2057        specparam tDSH = 1.0 ; // tDSH ns DQS falling edge from CLK rising (hold time)
2058        specparam tIH = 0.9 ; // tIH ns Input Hold Time (fast)
2059        specparam tIS = 0.9 ; // tIS ns Input Setup Time (fast)
2060        specparam tDQSH = 2.0 ; // tDQSH ns DQS input High Pulse Width
2061        specparam tDQSL = 2.0 ; // tDQSL ns DQS input Low Pulse Width
2062`elsif sg6v18 // specparams for -6 (CL = 3)
2063        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2064        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2065        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2066        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2067        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2068        specparam tDQSH = 2.4; // tDQSH ns DQS input High Pulse Width
2069        specparam tDQSL = 2.4; // tDQSL ns DQS input Low Pulse Width
2070`elsif sg75v18 // specparams for -75 (CL = 3)
2071        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2072        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2073        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2074        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2075        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2076        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2077        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2078`elsif sg6v12 // specparams for -6 (CL = 3)
2079        specparam tCLK_MIN = 6.0; // tCLK ns minimum clk cycle time
2080        specparam tDSS = 1.2; // tDSS ns DQS falling edge to CLK rising (setup time)
2081        specparam tDSH = 1.2; // tDSH ns DQS falling edge from CLK rising (hold time)
2082        specparam tIH = 1.1; // tIH ns Input Hold Time (fast)
2083        specparam tIS = 1.1; // tIS ns Input Setup Time (fast)
2084        specparam tDQSH = 2.1; // tDQSH ns DQS input High Pulse Width
2085        specparam tDQSL = 2.1; // tDQSL ns DQS input Low Pulse Width
2086`elsif sg75v12 // specparams for -75 (CL = 3)
2087        specparam tCLK_MIN = 7.5; // tCLK ns minimum clk cycle time
2088        specparam tDSS = 1.5; // tDSS ns DQS falling edge to CLK rising (setup time)
2089        specparam tDSH = 1.5; // tDSH ns DQS falling edge from CLK rising (hold time)
2090        specparam tIH = 1.3; // tIH ns Input Hold Time (fast)
2091        specparam tIS = 1.3; // tIS ns Input Setup Time (fast)
2092        specparam tDQSH = 3.0; // tDQSH ns DQS input High Pulse Width
2093        specparam tDQSL = 3.0; // tDQSL ns DQS input Low Pulse Width
2094`elsif sg10v12 // specparams for -10 (CL = 3)
2095        specparam tCLK_MIN = 9.6; // tCLK ns minimum clk cycle time
2096        specparam tDSS = 1.92; // tDSS ns DQS falling edge to CLK rising (setup time)
2097        specparam tDSH = 1.92; // tDSH ns DQS falling edge from CLK rising (hold time)
2098        specparam tIH = 1.7; // tIH ns Input Hold Time (fast)
2099        specparam tIS = 1.7; // tIS ns Input Setup Time (fast)
2100        specparam tDQSH = 3.84; // tDQSH ns DQS input High Pulse Width
2101        specparam tDQSL = 3.84; // tDQSL ns DQS input Low Pulse Width
2102`else `define sg10 // specparams for -10 (CL = 3)
2103        specparam tCLK_MIN = 9.6; // tCLK ns minimum clk cycle time
2104        specparam tDSS = 1.92; // tDSS ns DQS falling edge to CLK rising (setup time)
2105        specparam tDSH = 1.92; // tDSH ns DQS falling edge from CLK rising (hold time)
2106        specparam tIH = 1.5; // tIH ns Input Hold Time (fast)
2107        specparam tIS = 1.5; // tIS ns Input Setup Time (fast)
2108        specparam tDQSH = 3.84; // tDQSH ns DQS input High Pulse Width
2109        specparam tDQSL = 3.84; // tDQSL ns DQS input Low Pulse Width
2110`endif
2111        $period (posedge Clk, tCLK_MIN);
2112        $width (posedge Dqs_in[0] &&& wdqs_valid, tDQSH);
2113        $width (posedge Dqs_in[1] &&& wdqs_valid, tDQSH);
2114        $width (negedge Dqs_in[0] &&& wdqs_valid, tDQSL);
2115        $width (negedge Dqs_in[1] &&& wdqs_valid, tDQSL);
2116        $setuphold(posedge Clk, Cke, tIS, tIH);
2117        $setuphold(posedge Clk, Cs_n, tIS, tIH);
2118        $setuphold(posedge Clk, Cas_n, tIS, tIH);
2119        $setuphold(posedge Clk, Ras_n, tIS, tIH);
2120        $setuphold(posedge Clk, We_n, tIS, tIH);
2121        $setuphold(posedge Clk, Addr, tIS, tIH);
2122        $setuphold(posedge Clk, Ba, tIS, tIH);
2123        $setuphold(posedge Clk, negedge Dqs &&& wdqs_valid, tDSS , tDSH);
2124    endspecify
2125
2126endmodule
2127

Archive Download this file

Branches:
master



interactive