OpenCores
URL https://opencores.org/ocsvn/mem_ctrl/mem_ctrl/trunk

Subversion Repositories mem_ctrl

[/] [mem_ctrl/] [trunk/] [bench/] [verilog/] [160b3ver/] [adv_bb.v] - Blame information for rev 28

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 rudi
 
2
 
3
 
4
 
5
//`timescale      1ns/1ns
6
 
7
 
8
//****************************************************************************
9
// This file contains the paramenters which define the part for the
10
// Smart 3 Advanced Boot Block memory model (adv_bb.v).  The '2.7V Vcc Timing'
11
// parameters are representative of the 28F160B3-120 operating at 2.7-3.6V Vcc.
12
// These parameters need to be changed if the 28F160B3-150 operating at
13
// 2.7-3.6V Vcc is to be modeled.  The parameters were taken from the Smart 3 
14
// Advanced Boot Block Flash Memory Family datasheet (Order Number 290580).
15
 
16
// This file must be loaded before the main model, as it contains
17
// definitions required by the model.
18
 
19
//28F160B3-B
20
 
21
`define BlockFileBegin  "f160b3b.bkb"   //starting addresses of each block
22
`define BlockFileEnd    "f160b3b.bke"   //ending addresses of each block
23
`define BlockFileType   "f160b3b.bkt"   //block types
24
 
25
//Available Vcc supported by the device.
26
`define VccLevels       4       //Bit 0 - 5V, Bit 1 = 3.3V, Bit 2 = 2.7V
27
 
28
`define AddrSize        20          //number of address pins
29
`define MaxAddr         `AddrSize'hFFFFF    // device ending address
30
`define MainArraySize   0:`MaxAddr  //array definition in bytes
31
                                    //include A-1 for 8 bit mode
32
`define MaxOutputs      16          //number of output pins
33
`define NumberOfBlocks  39          //number of blocks in the array
34
 
35
`define ID_DeviceCodeB      'h8891  //160B3 Bottom
36
`define ID_ManufacturerB    'h0089
37
 
38
// Timing parameters.  See the data sheet for definition of the parameter.
39
// Only the WE# controlled write timing parameters are used since their
40
// respective CE# controlled write timing parameters have the same value.
41
// The model does not differentiate between the two types of writes.
42
 
43
//2.7V Vcc Timing
44
 
45
// Changed the timings below to represent a "c3" device. --- RU 9/9/99
46
 
47
`define TAVAV_27            110
48
`define TAVQV_27            110
49
`define TELQV_27            110
50
`define TPHQV_27            150
51
`define TGLQV_27              0.1
52
`define TELQX_27              0
53
`define TEHQZ_27             20
54
`define TGLQX_27              0
55
`define TGHQZ_27             20
56
`define TOH_27                0
57
`define TPHWL_27            150
58
`define TWLWH_27             70
59
`define TDVWH_27             60
60
`define TAVWH_27             70
61
`define TWHDX_27              0
62
`define TWHAX_27              0
63
`define TWHWL_27             30
64
`define TVPWH_27            200
65
 
66
 
67
// The following constants control how long it take an algorithm to run
68
// to scale all times together (for making simulation run faster
69
// change the constant later listed as TimerPeriod.  The actual delays
70
// are TimerPeriod*xxx_Time, except for the suspend latency times.
71
 
72
`define TimerPeriod_        1000    //1 usec = 1000ns  requires for
73
                                    //following times to be accurate
74
 
75
// The typical values given in the datasheet are used.
76
 
77
// reducing the following will reduce simulation time
78
 
79
//2.7V Vcc, 12V Vpp
80
`define AC_ProgramTime_Word_27_12      8       //usecs
81
`define AC_EraseTime_Param_27_12       800000  //0.8secs
82
`define AC_EraseTime_Main_27_12        1100000 //1.1secs
83
 //Latency times are NOT multiplied by TimerPeriod_
84
`define AC_Program_Suspend_27_12       5000    //5 usecs
85
`define AC_Erase_Suspend_27_12         10000   //10 usecs
86
 
87
//2.7V Vcc 2.7V Vpp
88
`define AC_ProgramTime_Word_27_27      22       //usecs
89
`define AC_EraseTime_Param_27_27       1000000  //1sec
90
`define AC_EraseTime_Main_27_27        1800000  //1.8secs
91
 //Latency times are NOT multiplied by TimerPeriod_
92
`define AC_Program_Suspend_27_27       6000     //6 usecs
93
`define AC_Erase_Suspend_27_27         13000    //13 usecs
94
 
95
 
96
 
97
//generic defines for readability
98
`define FALSE           1'b0
99
`define TRUE            1'b1
100
 
101
`define Word            15:0
102
`define Byte            7:0
103
 
104
`define VIL             1'b0
105
`define VIH             1'b1
106
 
107
`define Ready           1'b1
108
`define Busy            1'b0
109
 
110
// These constants are the actual command codes
111
`define ClearCSRCmd     8'h50
112
`define ProgramCmd      8'h10
113
`define Program2Cmd     8'h40
114
`define EraseBlockCmd   8'h20
115
`define ReadArrayCmd    8'hFF
116
`define ReadCSRCmd      8'h70
117
`define ReadIDCmd       8'h90
118
`define SuspendCmd      8'hB0  //Valid for both erase
119
`define ResumeCmd       8'hD0  //and program suspend
120
`define ConfirmCmd      8'hD0
121
 
122
`define ReadMode_T      2:0
123
`define rdARRAY         3'b000
124
`define rdCSR           3'b011
125
`define rdID            3'b100
126
 
127
`define   Program           2'b00
128
`define   Erase             2'b01
129
 
130
// Cmd_T record
131
`define   Cmd_T             172:0
132
`define   CmdAdd_1          172:153
133
`define   CmdAdd_2          152:133
134
`define   Add               132:113
135
`define   CmdData_1         112:97
136
`define   CmdData_2         96:81
137
`define   Cmd               80:73
138
`define   Count             72:41
139
`define   Time              40:9
140
`define   Confirm           8
141
`define   OpBlock           7:2
142
`define   OpType            1:0
143
`define   CmdData1Fx8       104:97
144
 
145
`define WritePtr_T          1:0
146
`define NewCmd              2'b01
147
`define CmdField            2'b10
148
 
149
`define BlockType_T         1:0
150
`define MainBlock           2'b00
151
`define LockBlock           2'b01
152
`define ParamBlock          2'b10
153
 
154
`define Vcc2700             3'b100
155
`define Vcc3300             3'b010
156
`define Vcc5000             3'b001
157
 
158
 
159
// device specific
160
 
161
//module definition for Intel Advanced Boot Block Flash Memory Family
162
//
163
//vpp and vcc are are 32 bit vectors which are treated as unsigned int
164
//scale for vpp and vcc is millivolts.  ie. 0 = 0V, 5000 = 5V
165
//
166
 
167
module IntelAdvBoot(dq, addr, ceb, oeb, web, rpb, wpb, vpp, vcc);
168
 
169
inout [`MaxOutputs-1:0] dq;     //16 outputs
170
 
171
input [`AddrSize-1:0]   addr;   //address pins.
172
 
173
input                   ceb,    //CE# - chip enable bar
174
                        oeb,    //OE# - output enable bar
175
                        web,    //WE# - write enable bar
176
                        rpb,    //RP# - reset bar, powerdown
177
                        wpb;    //WP# = write protect bar
178
 
179
input [31:0]            vpp,    //vpp in millivolts
180
                        vcc;    //vcc in millivolts
181
 
182
reg [`Word]             MainArray[`MainArraySize];  //flash array
183
 
184
//  Flag to show that a Cmd has been written
185
//  and needs predecoding
186
reg       CmdValid ;
187
 
188
// This points to where data written to the part will
189
// go. By default it is to NewCmd. CmdField means the 
190
// chip is waiting on more data for the cmd (ie confirm)
191
 
192
reg [`WritePtr_T]   WriteToPtr ;
193
 
194
// Contains the current executing command and all its 
195
// support information.
196
reg  [`Cmd_T] Cmd;
197
reg  [`Cmd_T] Algorithm;
198
reg  [`Cmd_T] SuspendedAlg;
199
 
200
// Output of Data
201
reg [`Word]  ArrayOut ;
202
 
203
// Current output of the Compatible status register
204
reg [`Word]  CSROut ;
205
 
206
// Current output of the ID register
207
reg [`Word]  IDOut ;
208
 
209
//  Startup Flag phase
210
reg        StartUpFlag ;
211
 
212
//  Global Reset Flag
213
reg         Reset ;
214
 
215
//Vpp Monitoring
216
reg         VppFlag ;
217
reg         VppError ;
218
reg         VppErrFlag ;
219
reg         ClearVppFlag ;
220
 
221
// Internal representation of the CSR SR.1 bit
222
reg         BlockLockStatus;
223
// Internal representation of the CSR SR.4 bit
224
reg         ProgramError;
225
// Internal representation of the CSR SR.5 bit
226
reg         EraseError;
227
 
228
//  Internal representation of CUI modes
229
reg [`ReadMode_T] ReadMode ;
230
 
231
//  Current value of the CSR
232
wire [`Byte] CSR ;
233
 
234
//  Flag that determines if the chip is driving
235
//  the outputs
236
reg        DriveOutputs ;
237
 
238
//  Internal value of the out data.  If DriveOutputs
239
//  is active this value will be placed on the
240
//  outputs.  -1 == Unknown or XXXX
241
reg [`MaxOutputs-1:0]    InternalOutput ;
242
 
243
//  Number of addition writes necessary to 
244
//  supply the current command information.
245
//  When it hits zero it goes to Decode
246
integer       DataPtr ;
247
 
248
//  Master internal write enable
249
wire       Internal_WE ;
250
 
251
//  Master internal output enable
252
wire       Internal_OE ;
253
wire       Internal_OE2 ;
254
wire       Internal_OE3 ;
255
 
256
//  Master internal read enable
257
wire       Internal_RE ;
258
 
259
//  Master internal boot block write enable
260
reg         InternalBoot_WE ;
261
wire        InternalBoot;
262
 
263
//  Internal flag to tell if an algorithm is running
264
reg         ReadyBusy ;
265
//reg        RunningAlgorithm ;  *******************************
266
 
267
//  Flag to represent if the chip is write suspended
268
reg        WriteSuspended ;
269
//  Flag to represent if the chip is erase suspended
270
reg        EraseSuspended ;
271
// Flag for if the chip should be suspended
272
reg        Suspend ;
273
//  Variable to hold which algorithm (program or erase)
274
//  is to be suspended
275
reg [1:0]  ToBeSuspended;
276
 
277
//  Algorithm Timer
278
reg        TimerClk ;
279
 
280
//  Flag to show the running algorithm is done.
281
reg        AlgDone ;
282
 
283
// Number of timer cycles remaining for the 
284
// current algorithm
285
integer    AlgTime;
286
 
287
// Number of timer cycles remaining for erase operation
288
// when erase suspended and program operation in progress
289
integer    TimeLeft;
290
 
291
// Generic temporary varible
292
integer    LoopCntr ;
293
reg        Other ;
294
 
295
//Block begin and end address
296
reg [`AddrSize-1:0] BlocksBegin[0:`NumberOfBlocks-1];
297
reg [`AddrSize-1:0] BlocksEnd[0:`NumberOfBlocks-1];
298
reg [`BlockType_T] BlocksType[0:`NumberOfBlocks-1];
299
reg [31:0]  BlocksEraseCount[0:`NumberOfBlocks-1];
300
 
301
//************************************************************************
302
//TIMING VALUES
303
 
304
//************************************************************************
305
time    ToOut ;
306
time    last_addr_time ,curr_addr_time;
307
time    last_oe_time, curr_oe_time;
308
time    last_ce_time, curr_ce_time;
309
time    last_rp_time, curr_rp_time;
310
time    last_ReadMode_time, curr_ReadMode_time ;
311
time    last_Internal_RE_time, curr_Internal_RE_time ;
312
time    last_Internal_WE_time, curr_Internal_WE_time ;
313
time    last_dq_time ,curr_dq_time;
314
time    last_rpb_time, curr_rpb_time ;
315
time    WriteRecovery ;
316
time    TempTime;
317
 
318
time    Program_Time_Word;
319
time    Param_Erase_Time;
320
time    Main_Erase_Time;
321
time    Program_Suspend_Time;  // latency time
322
time    Erase_Suspend_Time;    // latency time
323
 
324
//************************************************************************
325
//input configuration
326
 
327
 
328
parameter
329
    LoadOnPowerup = `FALSE,        //load array from file
330
    LoadFileName = "f160b3.dat",   //File to load array with
331
    SaveOnPowerdown = `FALSE,      //save array to file
332
    SaveFileName = "f160b3.dat";   //save file name
333
 
334
//TIMING PARAMETERS
335
parameter
336
    TAVAV       =   `TAVAV_27,
337
    TAVQV       =   `TAVQV_27,
338
    TELQV       =   `TELQV_27,
339
    TPHQV       =   `TPHQV_27,
340
    TGLQV       =   `TGLQV_27,
341
    TELQX       =   `TELQX_27,
342
    TEHQZ       =   `TEHQZ_27,
343
    TGLQX       =   `TGLQX_27,
344
    TGHQZ       =   `TGHQZ_27,
345
    TOH         =   `TOH_27  ,
346
    TPHWL       =   `TPHWL_27,
347
    TWLWH       =   `TWLWH_27,
348
    TDVWH       =   `TDVWH_27,
349
    TAVWH       =   `TAVWH_27,
350
    TWHDX       =   `TWHDX_27,
351
    TWHAX       =   `TWHAX_27,
352
    TWHWL       =   `TWHWL_27,
353
    TVPWH       =   `TVPWH_27,
354
    TimerPeriod =   `TimerPeriod_;
355
 
356
 
357
//************************************************************************
358
 
359
 
360
initial begin
361
    Other               =       `FALSE  ;
362
    AlgDone             =       `FALSE  ;
363
    Reset               =       1'hx    ;
364
    Reset               <=      `TRUE   ;
365
    StartUpFlag         =       `TRUE   ;
366
    StartUpFlag         <=  #2  `FALSE  ;
367
    DriveOutputs        =       `FALSE  ;
368
    ToOut               =       0       ;
369
    VppError            =       `FALSE  ;
370
    VppErrFlag          =       `FALSE  ;
371
    ClearVppFlag        =       `FALSE  ;
372
    VppFlag             =       `FALSE  ;
373
    WriteSuspended      =       `FALSE  ;
374
    EraseSuspended      =       `FALSE  ;
375
    Suspend             =       `FALSE  ;
376
    ToBeSuspended       =       `Program;
377
    EraseError          =       `FALSE  ;
378
    TimerClk            =       1'b0    ;
379
    ArrayOut            =       `MaxOutputs'hxxxx ;
380
    CSROut              =       0       ;
381
    IDOut               =       0       ;
382
    CmdValid            =       `FALSE  ;
383
    WriteToPtr          =       `NewCmd ;
384
    last_addr_time      =       0       ;
385
    curr_addr_time      =       0       ;
386
    last_ce_time      =         0       ;
387
    curr_ce_time      =         0       ;
388
    last_oe_time      =         0       ;
389
    curr_oe_time      =         0       ;
390
    last_rp_time      =         0       ;
391
    curr_rp_time      =         0       ;
392
    last_ReadMode_time  =       0       ;
393
    curr_ReadMode_time  =       0       ;
394
    last_dq_time        =       0       ;
395
    curr_dq_time        =       0       ;
396
    last_rpb_time       =       0       ;
397
    curr_rpb_time       =       0       ;
398
    WriteRecovery       =       0       ;
399
    last_Internal_RE_time =     0       ;
400
    curr_Internal_RE_time =     0       ;
401
    InternalOutput        =     `MaxOutputs'hx     ;
402
    last_Internal_WE_time = 0           ;
403
    curr_Internal_WE_time = 0           ;
404
    Program_Time_Word    = `AC_ProgramTime_Word_27_12;
405
    Param_Erase_Time     = `AC_EraseTime_Param_27_12;
406
    Main_Erase_Time      = `AC_EraseTime_Main_27_12;
407
    Program_Suspend_Time = `AC_Program_Suspend_27_12;
408
    Erase_Suspend_Time   = `AC_Erase_Suspend_27_12;
409
 
410
    $readmemh(`BlockFileBegin,BlocksBegin);
411
    $readmemh(`BlockFileEnd,BlocksEnd);
412
    $readmemh(`BlockFileType,BlocksType,0,`NumberOfBlocks-1);
413
    for (LoopCntr = 0; LoopCntr <= `NumberOfBlocks; LoopCntr = LoopCntr + 1) begin
414
        BlocksEraseCount [LoopCntr] = 0 ;
415
    end
416
 
417
//------------------------------------------------------------------------
418
// Array Init
419
//------------------------------------------------------------------------
420
 
421
//Constant condition expression: LoadOnPowerup == 1'b1
422
    if (LoadOnPowerup)
423
        LoadFromFile;
424
    else begin
425
      //$display("Initializing Memory to 'hFFFF");
426
      //for (LoopCntr = 0; LoopCntr <= `MaxAddr; LoopCntr = LoopCntr + 1) begin
427
      //  MainArray [LoopCntr] = 16'hFFFF ;
428 10 rudi
      $display("FLASH: Initializing Memory data to address value (0, 1, 2 ...)");
429 4 rudi
      for (LoopCntr = 0; LoopCntr <= 1024; LoopCntr = LoopCntr + 1) begin
430
        MainArray [LoopCntr] = LoopCntr ;
431
 
432
      end
433
    end
434
end
435
 
436
 
437
//------------------------------------------------------------------------
438
// LoadFromFile
439
//  This is used when the LoadOnPowerup parameter is set so that the Main 
440
//  array contains code at startup.  Basically it loads the array from 
441
//  data in a file (LoadFileName).
442
//------------------------------------------------------------------------
443
 
444
task LoadFromFile ;
445
begin
446 10 rudi
    $display("FLASH: Loading from file %s",LoadFileName);
447 4 rudi
    $readmemh(LoadFileName,MainArray);
448
end
449
endtask
450
 
451
//------------------------------------------------------------------------
452
// StoreToFile
453
//  This is used when the SaveOnPowerDown flag is set so that the Main 
454
//  Array stores code at powerdown.  Basically it stores the array into
455
//  a file (SaveFileName).
456
//-----------------------------------------------------------------
457
 
458
task  StoreToFile;
459
    reg [31:0]  ArrayAddr ;
460
    reg [31:0]  outfile ;
461
begin
462
    outfile = $fopen(SaveFileName) ;
463
    if (outfile == 0)
464 10 rudi
        $display("FLASH: Error, cannot open output file %s",SaveFileName) ;
465 4 rudi
    else
466 10 rudi
        $display("FLASH: Saving data to file %s",SaveFileName);
467 4 rudi
    for (ArrayAddr = 0 ; ArrayAddr <= `MaxAddr; ArrayAddr = ArrayAddr + 1) begin
468
        $fdisplay(outfile,"%h",MainArray[ArrayAddr]);
469
    end
470
end
471
endtask
472
 
473
//------------------------------------------------------------------------
474
// Program  
475
// -- Description: Programs new values in to the array --
476
//------------------------------------------------------------------------
477
 
478
task  Program ;
479
  inout  [`Word] TheArrayValue ;
480
  input  [`Word] DataIn;
481
 
482
  reg    [`Word] OldData;
483
  begin
484
    OldData = TheArrayValue;
485
    TheArrayValue = DataIn & OldData;
486
  end
487
endtask
488
 
489
 
490
assign  Internal_OE = !(ceb | oeb | !rpb) ;
491
assign  Internal_OE2 = Internal_OE ;
492
assign  Internal_OE3 = Internal_OE2 ;
493
assign  Internal_RE = (((ReadyBusy == `Ready) || (ReadMode != `rdARRAY)) && !ceb && !Reset) ;
494
assign  Internal_WE = !(ceb | web | !rpb) ;
495
assign  InternalBoot = wpb ;
496
 
497
//******************************************************************
498
// Determine if the algorithm engine is operating
499
//assign  ReadyBusy = (RunningAlgorithm & !Suspended) ? `Busy : `Ready;
500
//******************************************************************
501
 
502
// register definitions //
503
 
504
// Compatible Status Register
505
assign  CSR [7] = ReadyBusy;
506
assign  CSR [6] = EraseSuspended ;
507
assign  CSR [5] = EraseError ;
508
assign  CSR [4] = ProgramError ;
509
assign  CSR [3] = VppError ;
510
assign  CSR [2] = WriteSuspended;
511
assign  CSR [1] = BlockLockStatus;
512
assign  CSR [0] = 1'b0;
513
 
514
 
515
// Output Drivers //
516
assign dq = (DriveOutputs == `TRUE) ? InternalOutput : 16'hz;
517
 
518
always @(Reset) begin : Reset_process
519
    if (Reset) begin
520
        ClearVppFlag    <=  #1  `TRUE   ;
521
        ClearVppFlag    <=  #9  `FALSE  ;
522
        AlgDone         =       `FALSE  ;
523
        VppError        =       `FALSE  ;
524
        ReadMode        =       `rdARRAY;
525
        ReadyBusy       =       `Ready  ;
526
        WriteSuspended  =       `FALSE  ;
527
        EraseSuspended  =       `FALSE  ;
528
        Suspend         =       `FALSE  ;
529
        EraseError      =       `FALSE  ;
530
        ProgramError    =       `FALSE  ;
531
        BlockLockStatus =       `FALSE  ;
532
        AlgTime         =       0       ;
533
        CmdValid        =       `FALSE  ;
534
        WriteToPtr      =       `NewCmd ;
535
        CSROut          =       0       ;
536
        IDOut           =       0       ;
537
    end
538
end
539
 
540
 
541
always @(Internal_RE or ReadMode or addr) begin : array_read
542
  if (Internal_RE && ReadMode == `rdARRAY) begin
543
    ArrayOut = MainArray[addr] ;      // x16 outputs
544
  end
545
end
546
 
547
 
548
always @(Internal_RE or ReadMode or addr or Internal_OE2 or ArrayOut) begin
549
    // output mux
550
    // Determine and generate the access time .
551
    ToOut = 0;
552
 
553
    if ($time > TAVQV) begin
554
        last_addr_time = $time - curr_addr_time;
555
 
556
        if ((last_addr_time < TAVQV) && ((TAVQV - last_addr_time) > ToOut))
557
            ToOut = TAVQV - last_addr_time ;
558
        last_oe_time = $time - curr_oe_time;
559
        if ((last_oe_time < TGLQV) && ((TGLQV - last_oe_time) > ToOut))
560
            ToOut = TGLQV - last_oe_time ;
561
        last_ce_time = $time - curr_ce_time;
562
 
563
        if ((last_ce_time < TELQV) && ((TELQV - last_ce_time) > ToOut))
564
            ToOut = TELQV - last_ce_time ;
565
        last_rp_time = $time - curr_rp_time;
566
        if ((last_rp_time < TPHQV) && ((TPHQV - last_rp_time) > ToOut))
567
            ToOut = TPHQV - last_rp_time ;
568
        last_ReadMode_time = $time - curr_ReadMode_time;
569
        if ((last_ReadMode_time < TAVQV) && ((TAVQV - last_ReadMode_time) > ToOut))
570
            ToOut = TAVQV - last_ReadMode_time ;
571
        last_Internal_RE_time = $time - curr_Internal_RE_time ;
572
        if ((last_Internal_RE_time < TAVQV) && ((TAVQV - last_Internal_RE_time) > ToOut)) begin
573
           ToOut = TAVQV - last_Internal_RE_time ;
574
            end
575
 
576
        end
577
 
578
//  Output Mux with timing
579
    if (!StartUpFlag) begin
580
         case (ReadMode)
581
            `rdARRAY : begin
582
              if ( (EraseSuspended == `TRUE) && (WriteSuspended == `FALSE)
583
                   && (addr >= BlocksBegin[Algorithm[`OpBlock]])
584
                   && (addr <= BlocksEnd[Algorithm[`OpBlock]]) && (oeb == `VIL) ) begin
585 10 rudi
                $display("FLASH: Error:  Attempting to read from erase suspended block");
586 4 rudi
                InternalOutput <= `MaxOutputs'hxxxx;
587
              end
588
              else if ( (WriteSuspended == `TRUE) && (EraseSuspended == `TRUE)
589
                       && (addr >= BlocksBegin[SuspendedAlg[`OpBlock]])
590
                       && (addr <= BlocksEnd[SuspendedAlg[`OpBlock]]) && (oeb == `VIL)) begin
591 10 rudi
                $display("FLASH: Error:  Attempting to read from erase suspended block");
592 4 rudi
                InternalOutput <= `MaxOutputs'hxxxx;
593
              end
594
              else if ( (WriteSuspended == `TRUE) && (addr == Algorithm[`CmdAdd_1])
595
                       && (oeb == `VIL) ) begin
596 10 rudi
                $display("FLASH: Error:  Attempting to read from write suspended address");
597 4 rudi
                InternalOutput = `MaxOutputs'hxxxx;
598
              end
599
              else
600
                InternalOutput <= #ToOut ArrayOut ;
601
            end
602
            `rdCSR   : begin
603
                InternalOutput <= #ToOut CSROut ;
604
            end
605
            `rdID    :  begin
606
                InternalOutput <= #ToOut IDOut ;
607
            end
608
            default  :  begin
609 10 rudi
                $display("FLASH: Error: illegal readmode");
610 4 rudi
            end
611
        endcase
612
    end
613
end
614
 
615
 
616
 
617
//
618
// other reads 
619
//
620
always @(Internal_OE or addr) begin : other_read
621
    if (!Reset) begin
622
        if (ReadMode != `rdARRAY) begin
623
            CSROut = {8'h00,CSR} ;
624
            if (addr[0] == 1'b0)
625
                IDOut = `ID_ManufacturerB ;
626
            else
627
                IDOut = `ID_DeviceCodeB ;
628
        end
629
    end
630
end
631
 
632
// Handle Write to Part
633
 
634
always @(negedge Internal_WE) begin : handle_write
635
  reg [`Word]   temp ;       // temporary variable needed for double
636
                             // indexing CmdData.
637
  if (!Reset) begin
638
    case (WriteToPtr)                        // Where are we writting to ?
639
      `NewCmd : begin                       // This is a new command.
640
         Cmd[`Cmd] = dq[7:0];
641
         Cmd[`Add] = addr[`AddrSize-1:0];   //by 16 word index
642
         CmdValid <= `TRUE ;                // CmdValid sends it to the Predecode section
643
         DataPtr <= -1;
644
       end
645
      `CmdField : begin   // This is data used by another command
646
         if (DataPtr == 1) begin
647
           Cmd[`CmdData_1] = dq[`Word];
648
           Cmd[`CmdAdd_1] = addr[`AddrSize-1:0];
649
         end
650
         else if (DataPtr == 2) begin
651
           Cmd[`CmdData_2] = dq[`Word];
652
           Cmd[`CmdAdd_2] = addr[`AddrSize-1:0];
653
         end
654
         else
655 10 rudi
           $display("FLASH: DataPtr out of range");
656 4 rudi
         DataPtr <= #1 DataPtr - 1 ; // When DataPtr = 0 the command goes to Decode section
657
       end
658
       default : begin
659 10 rudi
         $display("FLASH: Error: Write To ? Cmd");
660 4 rudi
       end
661
    endcase
662
  end
663
end
664
 
665
//
666
// Predecode Command
667
//
668
always @(posedge CmdValid) begin : predecode
669
  reg [`Byte] temp;       // temporary variable needed for double 
670
                          // indexing BSR.
671
  if (!Reset) begin
672
    // Set Defaults
673
    Cmd [`OpType] = `Program ;
674
    WriteToPtr = `NewCmd ;
675
    DataPtr <= 0 ;
676
    case (Cmd [`Cmd])            // Handle the basic read mode commands
677
    // READ ARRAY COMMAND --
678
      `ReadArrayCmd  : begin     // Read Flash Array
679
         CmdValid <= `FALSE ;
680
         if (ReadyBusy == `Busy) // Can not read array when running an algorithm
681
           ReadMode <= `rdCSR ;
682
         else
683
           ReadMode <= `rdARRAY ;
684
       end
685
    // READ INTELLIGENT IDENTIFIER COMMAND --
686
      `ReadIDCmd     :  begin    // Read Intelligent ID
687
         if ((WriteSuspended == `TRUE) || (EraseSuspended == `TRUE))
688 10 rudi
           $display("FLASH: Invalid read ID command during suspend");
689 4 rudi
         else
690
           ReadMode <= `rdID ;
691
         CmdValid <= `FALSE ;
692
       end
693
    // READ COMPATIBLE STATUS REGISTER COMMAND --
694
      `ReadCSRCmd  : begin       // Read CSR 
695
         ReadMode <= `rdCSR ;
696
         CmdValid <= `FALSE ;
697
       end
698
       default  : begin
699
         Other = `TRUE ;            // Other flag marks commands that are algorithms
700
         Cmd [`Confirm] = `FALSE  ; // Defaults
701
         case (Cmd [`Cmd])
702
    // PROGRAM WORD COMMAND --
703
           `ProgramCmd : begin                              // Program Word
704
              if (WriteSuspended == `TRUE) begin
705 10 rudi
                $display("FLASH: Error:  Program Command during Write Suspend");
706 4 rudi
                CmdValid <= `FALSE;
707
              end
708
              else begin
709
                WriteToPtr = `CmdField;
710
                DataPtr <= 1;
711
                if (EraseSuspended == `TRUE) begin
712
                  TimeLeft = AlgTime;
713
                  SuspendedAlg = Algorithm;
714
                end
715
                ToBeSuspended = `Program;
716
                Cmd [`Time] = Program_Time_Word;
717
              end
718
            end
719
    // PROGRAM WORD COMMAND --
720
           `Program2Cmd  : begin       // Program Word
721
              if (WriteSuspended == `TRUE) begin
722 10 rudi
                $display("FLASH: Error:  Program Command during Write Suspend");
723 4 rudi
                CmdValid <= `FALSE;
724
              end
725
              else begin
726
                Cmd [`Cmd] = `ProgramCmd;
727
                WriteToPtr = `CmdField;
728
                DataPtr <= 1;
729
                if (EraseSuspended == `TRUE) begin
730
                  TimeLeft = AlgTime;
731
                  SuspendedAlg = Algorithm;
732
                end
733
                ToBeSuspended = `Program;
734
                Cmd [`Time] = Program_Time_Word ;
735
              end
736
            end
737
    // ERASE BLOCK COMMAND --
738
           `EraseBlockCmd : begin    // Single Block Erase
739
              if ((WriteSuspended == `TRUE) || (EraseSuspended == `TRUE)) begin
740 10 rudi
                $display("FLASH: Attempted to erase block while suspended");
741 4 rudi
                CmdValid <= `FALSE;
742
              end
743
              else begin
744
                WriteToPtr = `CmdField;
745
                DataPtr <= 1;
746
//              Cmd [`Time] = `AC_EraseTime ;
747
                Cmd [`OpType] = `Erase;
748
                Cmd [`Confirm] = `TRUE;
749
                ToBeSuspended = `Erase;
750
              end
751
            end
752
            default : begin // The remaining commands are complex non-algorithm commands
753
              Other = `FALSE ;
754
              CmdValid = `FALSE ;
755
    // CLEAR STATUS REGISTER COMMAND
756
              if (Cmd [`Cmd] == `ClearCSRCmd) begin
757
                if (WriteSuspended | EraseSuspended)
758
                  ReadMode <= `rdARRAY;
759
                else if (ReadyBusy == `Busy)
760
                  ReadMode <= `rdCSR;
761
                else begin
762
                  EraseError <= `FALSE;
763
                  ProgramError <= `FALSE;
764
                  VppError <= `FALSE;
765
                  BlockLockStatus <= `FALSE;
766
                  ReadMode <= `rdCSR;
767
                end
768
              end
769
    // RESUME COMMAND --
770
              else if (Cmd [`Cmd] == `ResumeCmd) begin
771
                if (WriteSuspended | EraseSuspended)
772
                  ReadMode <= `rdCSR;
773
                Suspend = `FALSE;
774
                if (ToBeSuspended == `Program)
775
                  WriteSuspended <= `FALSE;
776
                else
777
                  EraseSuspended <= `FALSE;
778
                ReadyBusy = `Busy;
779
              end
780
    // SUSPEND COMMAND --
781
              else if (Cmd [`Cmd] == `SuspendCmd) begin
782
                if (ReadyBusy == `Ready) begin
783
                  ReadMode <= `rdARRAY;
784 10 rudi
                  $display("FLASH: Algorithm finished; nothing to suspend");
785 4 rudi
                end
786
                else begin
787
                  ReadMode <= `rdCSR;
788
                  Suspend = `TRUE;
789
                end
790
                CmdValid <= `FALSE;
791
              end
792
              else begin
793
                CmdValid <= `FALSE;
794 10 rudi
                $display("FLASH: Warning:Illegal Command (%h)", Cmd [`Cmd]);    // Added displaying command code,--- RU 9/10/99
795 4 rudi
              end
796
            end  //default
797
         endcase
798
       end  //default
799
    endcase
800
  end  //if
801
end  //always (predecode)
802
 
803
 
804
//
805
// Command Decode
806
//
807
always @(DataPtr) begin : command
808
  integer BlockUsed;
809
  // When DataPtr hits zero it means that all the
810
  // additional data has been given to the current command
811
  if (!Reset && (DataPtr == 0) && (WriteToPtr != `NewCmd)) begin
812
    if (CmdValid && (WriteToPtr == `CmdField)) begin
813
      WriteToPtr = `NewCmd;
814
      // Just finish a multi-cycle command.  Determine which block the command uses
815
      BlockUsed = -1;
816
      for (LoopCntr = `NumberOfBlocks-1; LoopCntr >= 0; LoopCntr = LoopCntr - 1) begin
817
        if (Cmd[`CmdAdd_1] <= BlocksEnd[LoopCntr])
818
          BlockUsed = LoopCntr;
819
      end
820
      if (BlockUsed == -1)
821 10 rudi
        $display("FLASH: Error:  Invalid Command Address");
822 4 rudi
      else
823
        Cmd [`OpBlock] = BlockUsed;
824
      if (Cmd [`OpType] ==  `Erase ) begin
825
        if (BlocksType[BlockUsed] == `MainBlock)
826
          Cmd[`Time] = Main_Erase_Time;
827
        else
828
          Cmd[`Time] = Param_Erase_Time;
829
      end
830
      else if (Cmd [`OpType] == `Program)
831
        Cmd[`Time] = Program_Time_Word;
832
      else
833
        Cmd[`Time] = 0;
834
      // If this command needs a confirm 
835
      // (flaged at predecode) then check if confirm was received
836
      if (Cmd [`Confirm]) begin
837
        if (Cmd[`CmdData1Fx8] == `ConfirmCmd) begin
838
       // If the command is still valid put it in the queue and deactivate the array
839
          Algorithm = Cmd;
840
          AlgTime = Cmd [`Time] ;
841
          CmdValid <= `FALSE;
842
          if (!VppError)
843
            ReadyBusy <= #1 `Busy;
844
          ReadMode <= `rdCSR;
845
        end
846
        else begin
847
          ReadMode <= `rdCSR ;
848
          ProgramError <= `TRUE;
849
          EraseError <= `TRUE;
850
          CmdValid <= `FALSE;
851
        end
852
      end
853
      else begin
854
        Algorithm = Cmd;
855
        AlgTime = Cmd [`Time] ;
856
        CmdValid <= `FALSE;
857
        if (!VppError)
858
          ReadyBusy <= #1 `Busy ;
859
        ReadMode <= `rdCSR;
860
      end
861
    end
862
  end
863
end  //always (command)
864
 
865
//////////////
866
// Execution //
867
//////////////
868
always @(posedge AlgDone)  begin  : execution
869
  if (!Reset) begin
870
    if (AlgDone) begin   // When the algorithm finishes
871
                         // if chips is executing during an erase interrupt
872
                         // then execute out of queue slot 2
873
      if (Algorithm [`OpType] == `Erase) begin
874
    // ERASE COMMAND //
875
        if (VppFlag) begin
876
          VppError <= `TRUE ;
877
          EraseError <= `TRUE;
878
        end
879
        else begin
880
    // Do ERASE to OpBlock
881
          if ((BlocksType[Algorithm[`OpBlock]] == `LockBlock) && !InternalBoot_WE) begin
882 10 rudi
            $display("FLASH: Error: Attempted to erase locked block.");
883 4 rudi
            EraseError <= `TRUE;
884
            BlockLockStatus <= `TRUE;
885
          end
886
          else begin
887
            for (LoopCntr = BlocksBegin[Algorithm[`OpBlock]];
888
                 LoopCntr <= BlocksEnd[Algorithm[`OpBlock]]; LoopCntr = LoopCntr + 1)
889
              MainArray [LoopCntr] = 'hFFFF;
890
            BlocksEraseCount[Algorithm[`OpBlock]] = BlocksEraseCount[Algorithm[`OpBlock]] + 1;
891 10 rudi
            $display("FLASH: Block %d Erase Count: %d",Algorithm[`OpBlock],BlocksEraseCount[Algorithm[`OpBlock]]);
892 4 rudi
          end
893
        end
894
      end
895
      else begin
896
    // PROGRAM COMMAND //
897
        if (VppFlag) begin
898
          ProgramError <= `TRUE;
899
          VppError <= `TRUE ;
900
        end
901
        else begin
902
          if ((BlocksType[Algorithm[`OpBlock]] == `LockBlock) && !InternalBoot_WE) begin
903 10 rudi
            $display("FLASH: Error: Attempted to program locked boot block.");
904 4 rudi
            ProgramError <= `TRUE;
905
            BlockLockStatus <= `TRUE;
906
          end
907
          else begin
908
            Program (MainArray[Algorithm [`CmdAdd_1]], Algorithm [`CmdData_1]);
909
            if (EraseSuspended == `TRUE) begin
910
              AlgTime = TimeLeft;
911
              ToBeSuspended = `Erase;
912
              Algorithm = SuspendedAlg;
913
            end
914
          end
915
        end
916
      end
917
    end  //if (AlgDone)
918
    ReadyBusy <= `Ready;
919
  end  //if (!Reset)
920
end  //always (execution)
921
 
922
always @(ReadyBusy) begin
923
  if ((!Reset) && (ReadyBusy  == `Busy)) begin  // If the algorithm engine
924
                                                // just started, start the clock
925
    ClearVppFlag <= #1 `TRUE ;
926
    ClearVppFlag <= #3 `FALSE ;
927
    TimerClk <= #1 1'b1 ;
928
    TimerClk <= #TimerPeriod 1'b0 ;
929
  end
930
end
931
 
932
// record the time for addr changes .
933
always @(addr) begin
934 16 rudi
  if ($time != 0 & !ceb) begin
935
    if (((curr_addr_time + TAVAV) > $time) & !ceb)    //Read/Write Cycle Time           --- Added "& !ceb" RU 9/9/99 9pm
936 10 rudi
      $display("FLASH: [",$time,"] Timing Violation: Read/Write Cycle Time (TAVAV), Last addr change: %d",curr_addr_time) ;
937 4 rudi
    curr_addr_time = $time ;
938
  end
939
end
940
 
941
// record the time for oe changes .
942
always @(oeb) begin
943
  if ($time != 0) begin
944
    curr_oe_time = $time ;
945
  end
946
end
947
 
948
// record the time for ce changes .
949
always @(ceb) begin
950
  if ($time != 0) begin
951
    curr_ce_time = $time ;
952
  end
953
end
954
 
955
reg rpb_r;
956
initial rpb_r = rpb;
957
 
958
// record the time for rp changes .
959
always @(rpb) begin
960
  if ((rpb_r != rpb) & ($time != 0) ) begin
961
    curr_rp_time = $time ;
962
    rpb_r = rpb;
963
  end
964
end
965
 
966
// record the time for ReadMode changes .
967
always @(ReadMode) begin
968
  if ($time != 0) begin
969
    curr_ReadMode_time = $time ;
970
  end
971
end
972
 
973
// record the time for Internal_RE changes .
974
always @(Internal_RE) begin
975
  if ($time != 0) begin
976
    curr_Internal_RE_time = $time ;
977
  end
978
end
979
 
980
always @(InternalBoot) begin
981
  InternalBoot_WE <= #TVPWH InternalBoot;
982
end
983
 
984
always @(TimerClk) begin
985
  if ((!Reset) && (ReadyBusy == `Busy) && (TimerClk == 1'b0)) begin  // Reschedule clock and
986
                                                                     // decrement algorithm count
987
    TimerClk <= #1 1'b1 ;
988
    TimerClk <= #TimerPeriod 1'b0 ;
989
    if (Suspend) begin   // Is the chip pending suspend? If so do it
990
      Suspend = `FALSE;
991
      if (ToBeSuspended == `Program) begin
992
        WriteSuspended <= #Program_Suspend_Time `TRUE;
993
        ReadyBusy <= #Program_Suspend_Time `Ready;
994
      end
995
      else begin
996
        EraseSuspended <= #Erase_Suspend_Time `TRUE;
997
        ReadyBusy <= #Erase_Suspend_Time `Ready;
998
      end
999
    end
1000
    if (ReadyBusy == `Busy) begin
1001
      AlgTime = AlgTime - 1;
1002
      if (AlgTime <= 0) begin // Check if the algorithm is done
1003
        AlgDone <= #1 `TRUE ;
1004
        AlgDone <= #10 `FALSE ;
1005
      end
1006
    end
1007
  end
1008
end
1009
 
1010
//------------------------------------------------------------------------
1011
//  Reset Controller
1012
//------------------------------------------------------------------------
1013
 
1014
always @(rpb or vcc) begin : ResetPowerdownMonitor
1015
    // Go into reset if reset powerdown pin is active or
1016
    // the vcc is too low
1017
    if ((rpb != `VIH) || (vcc < 2500)) begin // Low Vcc protection
1018
        Reset <= `TRUE ;
1019
    if (!((vcc >= 2500) || StartUpFlag))
1020 10 rudi
        $display ("FLASH: Low Vcc: Chip Resetting") ;
1021 4 rudi
    end
1022
    else
1023
    // Coming out of reset takes time
1024
        Reset <= #TPHWL  `FALSE ;
1025
end
1026
 
1027
 
1028
//------------------------------------------------------------------------
1029
// VccMonitor
1030
//------------------------------------------------------------------------
1031
 
1032
always @(Reset or vcc) begin : VccMonitor
1033
// Save the array when chip is powered off
1034
  if ($time > 0) begin
1035
    if (vcc == 0 && SaveOnPowerdown)
1036
      StoreToFile;
1037
    if (vcc < 2700)
1038 10 rudi
      $display("FLASH: Vcc is below minimum operating specs");
1039 4 rudi
    else if ((vcc >= 2700) && (vcc <= 3600) && (`VccLevels & `Vcc2700)) begin
1040
      //$display ("Vcc is in operating range for 2.7 volt mode") ;                      // Commented out RU 9/11/99
1041
/*
1042
      TAVAV       =   `TAVAV_27;
1043
      TAVQV       =   `TAVQV_27;
1044
      TELQV       =   `TELQV_27;
1045
      TPHQV       =   `TPHQV_27;
1046
      TGLQV       =   `TGLQV_27;
1047
      TELQX       =   `TELQX_27;
1048
      TEHQZ       =   `TEHQZ_27;
1049
      TGLQX       =   `TGLQX_27;
1050
      TGHQZ       =   `TGHQZ_27;
1051
      TOH         =   `TOH_27  ;
1052
      TPHWL       =   `TPHWL_27;
1053
      TWLWH       =   `TWLWH_27;
1054
      TDVWH       =   `TDVWH_27;
1055
      TAVWH       =   `TAVWH_27;
1056
      TWHDX       =   `TWHDX_27;
1057
      TWHAX       =   `TWHAX_27;
1058
      TWHWL       =   `TWHWL_27;
1059
      TVPWH       =   `TVPWH_27;
1060
*/
1061
      if ((vpp <= 3600) && (vpp >= 2700)) begin
1062
        Param_Erase_Time  = `AC_EraseTime_Param_27_27;
1063
        Main_Erase_Time   = `AC_EraseTime_Main_27_27;
1064
        Program_Time_Word = `AC_ProgramTime_Word_27_27;
1065
      end
1066
      else begin
1067
        Param_Erase_Time  = `AC_EraseTime_Param_27_12;
1068
        Main_Erase_Time   = `AC_EraseTime_Main_27_12;
1069
        Program_Time_Word = `AC_ProgramTime_Word_27_12;
1070
      end
1071
    end
1072
    else
1073 10 rudi
      $display ("FLASH: Vcc is out of operating range") ;
1074 4 rudi
  end //$time
1075
end
1076
 
1077
//------------------------------------------------------------------------
1078
// VppMonitor
1079
//------------------------------------------------------------------------
1080
always @(VppFlag or ClearVppFlag or vpp) begin : VppMonitor
1081
  if (ClearVppFlag) begin
1082
    VppErrFlag = `FALSE ;
1083
  end
1084
  else
1085
    if (!(((vpp <= 12600) && (vpp >= 11400)) || ((vpp <= 3600) && (vpp >= 2700)))) begin
1086
      VppErrFlag = `TRUE ;
1087
    end
1088
  if ((vpp <= 3600) && (vpp >= 2700)) begin
1089
    if ((vcc >= 2700) && (vcc <= 3600)) begin
1090
      Param_Erase_Time  = `AC_EraseTime_Param_27_27;
1091
      Main_Erase_Time   = `AC_EraseTime_Main_27_27;
1092
      Program_Time_Word = `AC_ProgramTime_Word_27_27;
1093
    end
1094
    else begin
1095 10 rudi
      $display("FLASH: Invalid Vcc level at Vpp change");
1096 4 rudi
      VppErrFlag = `TRUE;
1097
    end
1098
  end
1099
  else begin
1100
    if ((vcc >= 2700) && (vcc <= 3600)) begin
1101
      Param_Erase_Time  = `AC_EraseTime_Param_27_12;
1102
      Main_Erase_Time   = `AC_EraseTime_Main_27_12;
1103
      Program_Time_Word = `AC_ProgramTime_Word_27_12;
1104
    end
1105
    else begin
1106 10 rudi
      $display("FLASH: Invalid Vcc level at Vpp change");
1107 4 rudi
      VppErrFlag = `TRUE;
1108
    end
1109
  end
1110
  VppFlag <= VppErrFlag;
1111
end
1112
 
1113
 
1114
always @(StartUpFlag or Internal_OE3) begin : OEMonitor
1115
   // This section generated DriveOutputs which is the main signal that
1116
   // controls the state of the output drivers
1117
 
1118
   if (!StartUpFlag)  begin
1119
      WriteRecovery = 0 ;
1120
      last_Internal_WE_time = $time - curr_Internal_WE_time;
1121
      if (Internal_OE) begin
1122
         TempTime = WriteRecovery + TGLQX ;
1123
         DriveOutputs = `FALSE ;
1124
         WriteRecovery = WriteRecovery + TGLQV - TempTime;
1125
         DriveOutputs <= #WriteRecovery `TRUE ;
1126
      end
1127
      else begin
1128
         InternalOutput <= #TOH `MaxOutputs'hx;
1129
         if (oeb == `VIH)
1130
           WriteRecovery = WriteRecovery + TGHQZ;
1131
         else
1132
           WriteRecovery = WriteRecovery + TEHQZ;
1133
         DriveOutputs <= #WriteRecovery `FALSE ;
1134
      end
1135
   end
1136
   else
1137
      DriveOutputs <= `FALSE ;
1138
end
1139
 
1140
/////// Timing Checks /////////////
1141
 
1142
always @(Internal_WE) begin : Timing_chk
1143
  if ($time > 0) begin
1144
  // pulse chk
1145
    if (Internal_WE) begin
1146
      if ((($time - curr_Internal_WE_time) < TWHWL) && (TWHWL > 0 )) begin
1147 10 rudi
        $display("FLASH: [",$time,"] Timing Violation: Internal Write Enable Insufficient High Time") ;
1148 4 rudi
      end
1149
    end
1150
    else if ((($time - curr_Internal_WE_time) < TWLWH) && (TWLWH > 0 ))
1151 10 rudi
      $display("FLASH: [",$time,"] Timing Violation: Internal Write Enable Insufficient Low Time") ;
1152 4 rudi
    curr_Internal_WE_time = $time ;
1153
    // timing_chk - addr
1154
    last_dq_time = $time - curr_dq_time;
1155
    last_rpb_time = $time - curr_rpb_time;
1156
    last_addr_time = $time - curr_addr_time;
1157
    if (Internal_WE == 0)  begin
1158
      if ((last_addr_time < TAVWH) && (last_addr_time > 0))
1159 10 rudi
        $display("FLASH: [",$time,"] Timing Violation: Address setup time during write, Last Event %d",last_addr_time) ;
1160 4 rudi
      if ((last_rpb_time < TPHWL) && (last_rpb_time > 0))
1161 10 rudi
        $display("FLASH: [",$time,"] Timing Violation: Writing while coming out of powerdown,  Last Event %d",last_rpb_time) ;
1162 4 rudi
      if ((last_dq_time < TDVWH) && (last_dq_time > 0))
1163 10 rudi
        $display("FLASH: [",$time,"] Timing Violation: Data setup time during write, Last Event %d",last_dq_time) ;
1164 4 rudi
    end
1165
  end
1166
end
1167
 
1168
always @(addr) begin
1169
  last_Internal_WE_time = $time - curr_Internal_WE_time;
1170
  if (($time > 0) && !Internal_WE) begin   //timing chk
1171
    if ((last_Internal_WE_time < TWHAX) && (last_Internal_WE_time > 0))
1172 10 rudi
      $display("FLASH: [",$time,"] Timing Violation:Address hold time after write, Last Event %d",last_Internal_WE_time) ;
1173 4 rudi
  end
1174
end
1175
 
1176
always @(rpb) begin
1177
  if ((rpb_r != rpb) & ($time > 0)) begin
1178
    curr_rpb_time = $time ;
1179
  end
1180
end
1181
 
1182
always @(dq) begin
1183
  curr_dq_time = $time ;
1184
  last_Internal_WE_time = $time - curr_Internal_WE_time;
1185
  if (($time > 0) && !Internal_WE) begin
1186
    if ((last_Internal_WE_time < TWHDX) && (last_Internal_WE_time > 0))
1187 10 rudi
      $display("FLASH: [",$time,"] Timing Violation:Data hold time after write, Last Event %d",last_Internal_WE_time) ;
1188 4 rudi
  end
1189
end
1190
 
1191
endmodule
1192
 
1193
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.