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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [orp/] [orp_soc/] [bench/] [models/] [28f016s3/] [bwsvff.v] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 lampret
 
2
  /*
3
   3-Jul-97 - the VCS simulator does not allow overwriting parameters. I
4
           changed then to integers and inited them in the initial clause.
5
           This should make the model better suited for all Verilog simulators.
6
   3-Jul-97 - Stretch size of OpBlock, CmdAdd_1 and CmdAdd_2 for 32 block parts.
7
  11-Jul-97 - added variable flash_cycle. Only check TAVAV timing when CEn is
8
           asserted. This avoids errorious ERRORS when the address toggles
9
           to fast when CEn is disabled.
10
  */
11
 
12
  /*
13
   INTEL DEVELOPER'S SOFTWARE LICENSE AGREEMENT
14
 
15
  BY USING THIS SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF
16
  THIS AGREEMENT.  DO NOT USE THE SOFTWARE UNTIL YOU HAVE CAREFULLY READ
17
  AND AGREED TO THE FOLLOWING TERMS AND CONDITIONS.  IF YOU DO NOT AGREE
18
  TO THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN THE SOFTWARE PACKAGE AND
19
  ANY ACCOMPANYING ITEMS.
20
 
21
  IF YOU USE THIS SOFTWARE, YOU WILL BE BOUND BY THE TERMS OF THIS
22
  AGREEMENT
23
 
24
  LICENSE: Intel Corporation ("Intel") grants you the non-exclusive right
25
  to use the enclosed software program ("Software").  You will not use,
26
  copy, modify, rent, sell or transfer the Software or any portion
27
  thereof, except as provided in this Agreement.
28
 
29
  System OEM Developers may:
30
  1.      Copy the Software for support, backup or archival purposes;
31
  2.      Install, use, or distribute Intel owned Software in object code
32
          only;
33
  3.      Modify and/or use Software source code that Intel directly makes
34
          available to you as an OEM Developer;
35
  4.      Install, use, modify, distribute, and/or make or have made
36
          derivatives ("Derivatives") of Intel owned Software under the
37
          terms and conditions in this Agreement, ONLY if you are a System
38
          OEM Developer and NOT an end-user.
39
 
40
  RESTRICTIONS:
41
 
42
  YOU WILL NOT:
43
  1.      Copy the Software, in whole or in part, except as provided for
44
          in this Agreement;
45
  2.      Decompile or reverse engineer any Software provided in object
46
          code format;
47
  3.      Distribute any Software or Derivative code to any end-users,
48
          unless approved by Intel in a prior writing.
49
 
50
  TRANSFER: You may transfer the Software to another OEM Developer if the
51
  receiving party agrees to the terms of this Agreement at the sole risk
52
  of any receiving party.
53
 
54
  OWNERSHIP AND COPYRIGHT OF SOFTWARE: Title to the Software and all
55
  copies thereof remain with Intel or its vendors.  The Software is
56
  copyrighted and is protected by United States and international
57
  copyright laws.  You will not remove the copyright notice from the
58
  Software.  You agree to prevent any unauthorized copying of the
59
  Software.
60
 
61
  DERIVATIVE WORK: OEM Developers that make or have made Derivatives will
62
  not be required to provide Intel with a copy of the source or object
63
  code.  OEM Developers shall be authorized to use, market, sell, and/or
64
  distribute Derivatives to other OEM Developers at their own risk and
65
  expense. Title to Derivatives and all copies thereof shall be in the
66
  particular OEM Developer creating the Derivative.  Such OEMs shall
67
  remove the Intel copyright notice from all Derivatives if such notice is
68
  contained in the Software source code.
69
 
70
  DUAL MEDIA SOFTWARE: If the Software package contains multiple media,
71
  you may only use the medium appropriate for your system.
72
 
73
  WARRANTY: Intel warrants that it has the right to license you to use,
74
  modify, or distribute the Software as provided in this Agreement. The
75
  Software is provided "AS IS".  Intel makes no representations to
76
  upgrade, maintain, or support the Software at any time. Intel warrants
77
  that the media on which the Software is furnished will be free from
78
  defects in material and workmanship for a period of one (1) year from
79
  the date of purchase.  Upon return of such defective media, Intel's
80
  entire liability and your exclusive remedy shall be the replacement of
81
  the Software.
82
 
83
  THE ABOVE WARRANTIES ARE THE ONLY WARRANTIES OF ANY KIND, EITHER EXPRESS
84
  OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
85
  PARTICULAR PURPOSE.
86
 
87
  LIMITATION OF LIABILITY: NEITHER INTEL NOR ITS VENDORS OR AGENTS SHALL
88
  BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
89
  INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
90
  CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
91
  OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
92
 
93
  TERMINATION OF THIS LICENSE: Intel reserves the right to conduct or have
94
  conducted audits to verify your compliance with this Agreement.  Intel
95
  may terminate this Agreement at any time if you are in breach of any of
96
  its terms and conditions.  Upon termination, you will immediately
97
  destroy, and certify in writing the destruction of, the Software or
98
  return all copies of the Software and documentation to Intel.
99
 
100
  U.S. GOVERNMENT RESTRICTED RIGHTS: The Software and documentation were
101
  developed at private expense and are provided with "RESTRICTED RIGHTS".
102
  Use, duplication or disclosure by the Government is subject to
103
  restrictions as set forth in FAR52.227-14 and DFAR252.227-7013 et seq.
104
  or its successor.
105
 
106
  EXPORT LAWS: You agree that the distribution and export/re-export of the
107
  Software is in compliance with the laws, regulations, orders or other
108
  restrictions of the U.S. Export Administration Regulations.
109
 
110
  APPLICABLE LAW: This Agreement is governed by the laws of the State of
111
  California and the United States, including patent and copyright laws.
112
  Any claim arising out of this Agreement will be brought in Santa Clara
113
  County, California.
114
  */
115
 
116
  // This model is representative of the flash device described in the
117
  // Byte-Wide Smart 3 FlashFile(tm) Memory Family datasheet (Order
118
  // Number 290598).
119
 
120
  `timescale      1ns/1ns
121
 
122
  //generic defines for readability (already defined!)
123
  `define FALSE           1'b0
124
  `define TRUE            1'b1
125
 
126
  `define Byte            7:0
127
 
128
  `define VIL             1'b0
129
  `define VIH             1'b1
130
 
131
  `define rpb_vil         2'b00
132
  `define rpb_vih         2'b01
133
  `define rpb_vhh         2'b10
134
 
135
  `define Ready           1'b1
136
  `define Busy            1'b0
137
 
138
  // These constants are the actual command codes
139
  `define ClearCSRCmd     8'h50
140
  `define ProgramCmd      8'h10
141
  `define Program2Cmd     8'h40
142
  `define EraseBlockCmd   8'h20
143
  `define ReadArrayCmd    8'hFF
144
  `define ReadCSRCmd      8'h70
145
  `define ReadIDCmd       8'h90
146
  `define SuspendCmd      8'hB0  //Valid for both erase
147
  `define ResumeCmd       8'hD0  //and write suspend
148
  `define ConfirmCmd      8'hD0
149
  `define LBSetupCmd      8'h60
150
  `define SetBlockLBCmd   8'h01
151
  `define SetMasterLBCmd  8'hF1
152
  `define ClearLBCmd      8'hD0
153
 
154
  `define ReadMode_T      2:0
155
  `define rdARRAY         3'b000
156
  `define rdCSR           3'b011
157
  `define rdID            3'b100
158
 
159
  `define   Program       2'b00
160
  `define   Erase         2'b01
161
  `define   Lock          2'b10
162
 
163
  // Cmd_T record
164
  `define   Cmd_T             157:0
165
  `define   CmdAdd_1          157:137
166
  `define   CmdAdd_2          136:116
167
  `define   Add               115:96
168
  `define   CmdData_1         95:88
169
  `define   CmdData_2         87:78
170
  `define   Cmd               79:72
171
  `define   Count             71:40
172
  `define   Time              39:8
173
  `define   Confirm           7
174
  `define   OpBlock           6:2
175
  `define   OpType            1:0
176
 
177
  `define WritePtr_T          1:0
178
  `define NewCmd              2'b01
179
  `define CmdField            2'b10
180
 
181
  `define Locked              1'b1
182
  `define Unlocked            1'b0
183
 
184
  `define Vcc2700             3'b100
185
  `define Vcc3300             3'b010
186
  `define Vcc5000             3'b001
187
 
188
  `include "dp016s3.v"
189
 
190
  // device specific
191
 
192
  //module definition for Intel Smartvoltage FlashFile(tm) Flash
193
  //
194
  //vpp and vcc are are 32 bit vectors which are treated as unsigned int
195
  //scale for vpp and vcc is millivolts.  ie. 0 = 0V, 5000 = 5V
196
  //
197
 
198
  module i28f016s3(dq, addr, ceb, oeb, web, rpb, ryby, vpp, vcc, rpblevel);
199
 
200
  inout [`MaxOutputs-1:0] dq;     //8 outputs
201
 
202
  input [`AddrSize-1:0]   addr;   //address pins.
203
 
204
  input          ceb,    //CE# - chip enable bar
205
                 oeb,    //OE# - output enable bar
206
                 web,    //WE# - write enable bar
207
                 rpb;    //RP# - reset bar, powerdown
208
 
209
  output         ryby;   //RY/BY# - Ready/Busy signal
210
 
211
  input [31:0]   vpp,    //vpp in millivolts
212
                 vcc;    //vcc in millivolts
213
 
214
  input [1:0]    rpblevel;   //rpb at vil or vih or vhh
215
 
216
  reg [`Byte]    MainArray[`MainArraySize];  //flash array
217
 
218
  //  Flag to show that a Cmd has been written
219
  //  and needs predecoding
220
  reg        CmdValid ;
221
 
222
  // This points to where data written to the part will
223
  // go. By default it is to NewCmd. CmdField means the
224
  // chip is waiting on more data for the cmd (ie confirm)
225
 
226
  reg [`WritePtr_T]   WriteToPtr ;
227
 
228
  // Contains the current executing command and all its
229
  // support information.
230
  reg [`Cmd_T]   Cmd ;
231
 
232
  reg [`Cmd_T]   Algorithm;
233
 
234
  reg [`Cmd_T]   SuspendedAlg;
235
 
236
  // Output of Data
237
  reg [7:0]  ArrayOut ;
238
 
239
  // Current output of the Compatible status register
240
  reg [7:0]  CSROut ;
241
 
242
  // Current output of the ID register
243
  reg [7:0]  IDOut ;
244
 
245
  //  Startup Flag phase
246
  reg        StartUpFlag ;
247
 
248
  //  Global Reset Flag
249
  reg        Reset ;
250
 
251
  //  Variable to see if chip can only be read -- 2.7V Vcc
252
  reg        ReadOnly;
253
 
254
  //  Vpp Monitoring
255
  reg        VppFlag ;
256
  reg        VppError ;
257
  reg        VppErrFlag ;
258
  reg        ClearVppFlag ;
259
 
260
  //  Internal representation of the CSR SR.1 bit
261
  reg        Protected;
262
  //  Internal representation of the CSR SR.4 bit
263
  reg        Program_SetLBError ;
264
  //  Internal representation of the CSR SR.5 bit
265
  reg        Erase_ClearLBError ;
266
 
267
  //  Internal representation of GSR bit
268
  reg [`ReadMode_T] ReadMode ;
269
 
270
  //  Current value of the CSR
271
  wire [`Byte] CSR ;
272
 
273
  //  Flag that determines if the chip is driving
274
  //  the outputs
275
  reg        DriveOutputs ;
276
 
277
  //  Internal value of the out data.  If DriveOutputs
278
  //  is active this value will be placed on the
279
  //  outputs.  -1 == Unknown or XXXX
280
  reg [`MaxOutputs-1:0]    InternalOutput ;
281
 
282
  //  Number of addition writes necessary to
283
  //  supply the current command information.
284
  //  When it hits zero it goes to Decode
285
  integer       DataPtr ;
286
 
287
  //  Master internal write enable
288
  wire       Internal_WE ;
289
 
290
  //  Master internal output enable
291
  wire       Internal_OE ;
292
  wire       Internal_OE2 ;
293
  wire       Internal_OE3 ;
294
 
295
  //  Master internal read enable
296
  wire       Internal_RE ;
297
 
298
  //  Internal flag to tell if an algorithm is running
299
  reg        ReadyBusy ;
300
 
301
  //  Flag to represent if the chip is write suspended
302
  reg        WriteSuspended ;
303
  //  Flag to represent if the chip is erase suspended
304
  reg        EraseSuspended ;
305
  //  Flag to represent the chip should be suspended
306
  reg        Suspend ;
307
  //  Variable to hold which algorithm (program or erase)
308
  //  is to be suspended
309
  reg [1:0]  ToBeSuspended;
310
 
311
  // Array to hold block lock-bit information
312
  reg        BlockLockBit[`NumberOfBlocks-1:0];
313
  // Variable for block number to be locked
314
  integer    WhichBlock;
315
  // Flag to represent state of master lock-bit
316
  reg        MasterLock;
317
 
318
  //  Algorithm Timer
319
  reg        TimerClk ;
320
 
321
  //  Flag to show the running algorithm is done.
322
  reg        AlgDone ;
323
 
324
  // Number of timer cycles remaining for the
325
  // current algorithm
326
  integer    AlgTime;
327
 
328
  // Number of timer cycles remaining for erase operation
329
  // when erase suspended and program operation in progress
330
  integer    TimeLeft;
331
 
332
  // Generic temporary varible
333
  integer    LoopCntr ;
334
  reg        Other ;
335
 
336
  //Block begin and end address
337
  reg [`AddrSize-1:0] BlocksBegin[0:`NumberOfBlocks-1];
338
  reg [`AddrSize-1:0] BlocksEnd[0:`NumberOfBlocks-1];
339
  reg [31:0]  BlocksEraseCount[0:`NumberOfBlocks-1];
340
 
341
  // states the flash is in a cycle
342
  reg     flash_cycle;
343
 
344
 
345
  //**********************************************************************
346
  //TIMING VALUES
347
  //**********************************************************************
348
 
349
  time    ToOut ;
350
  time    last_addr_time ,curr_addr_time;
351
  time    last_oe_time, curr_oe_time;
352
  time    last_ce_time, curr_ce_time;
353
  time    last_rp_time, curr_rp_time;
354
  time    last_ReadMode_time, curr_ReadMode_time ;
355
  time    last_Internal_RE_time, curr_Internal_RE_time ;
356
  time    last_Internal_WE_time, curr_Internal_WE_time ;
357
  time    last_dq_time ,curr_dq_time;
358
  time    last_rpb_time, curr_rpb_time ;
359
  time    WriteRecovery ;
360
  time    TempTime;
361
 
362
  time    Program_Time_Byte;
363
  time    Block_Erase_Time;
364
  time    Set_LockBit_Time;
365
  time    Clear_LockBit_Time;
366
  time    Program_Suspend_Time;  // latency time
367
  time    Erase_Suspend_Time;    // latency time
368
 
369
  //**********************************************************************
370
  //input configuration
371
 
372
  parameter
373
      LoadOnPowerup   = 1,          //load array from file
374
`ifdef DAMJAN
375
      LoadFileName    = "../src/damjan_flash.in",  //File to load array with
376
`else
377
      LoadFileName    = "../src/flash.in",  //File to load array with
378
`endif
379
      SaveOnPowerdown = `TRUE,         //save array to file
380
      SaveFileName    = "../out/flash.out"; //save file name
381
 
382
  //TIMING PARAMETERS
383
  integer
384
      TAVAV       ,
385
      TPHQV       ,
386
      TELQV       ,
387
      TGLQV       ,
388
      TAVQV       ,
389
      TGLQX       ,
390
      TGHQZ       ,
391
      TEHQZ       ,
392
      TOH         ,
393
      TWPH        ,
394
      TWP         ,
395
      TPHWL       ,
396
      TPHHWH      ,
397
      TAVWH       ,
398
      TDVWH       ,
399
      TWHDX       ,
400
      TWHAX       ,
401
      TimerPeriod ;
402
 
403
 
404
  //**********************************************************************
405
 
406
  initial begin
407
      flash_cycle      =      0     ;
408
      Other               =       `FALSE  ;
409
      AlgDone             =       `FALSE  ;
410
      Reset               =        1'bx   ;
411
      Reset               <=      `TRUE   ;
412
      StartUpFlag         =       `TRUE   ;
413
      StartUpFlag         <=  #2  `FALSE  ;
414
      DriveOutputs        =       `FALSE  ;
415
      ToOut               =        0      ;
416
      VppError            =       `FALSE  ;
417
      VppErrFlag          =       `FALSE  ;
418
      ClearVppFlag        =       `FALSE  ;
419
      VppFlag             =       `FALSE  ;
420
      WriteSuspended      =       `FALSE  ;
421
      EraseSuspended      =       `FALSE  ;
422
      Suspend             =       `FALSE  ;
423
      ToBeSuspended       =       `Program;
424
      MasterLock          =       `Unlocked;
425
      Erase_ClearLBError  =       `FALSE  ;
426
      Protected           =       `FALSE  ;
427
      TimerClk            =        1'b0   ;
428
      ArrayOut            =       `MaxOutputs'hxx ;
429
      CSROut              =        0      ;
430
      IDOut               =        0      ;
431
      CmdValid            =       `FALSE  ;
432
      WriteToPtr          =       `NewCmd ;
433
      last_addr_time      =        0      ;
434
      curr_addr_time      =        0      ;
435
      last_ce_time        =        0      ;
436
      curr_ce_time        =        0      ;
437
      last_oe_time        =        0      ;
438
      curr_oe_time        =        0      ;
439
      last_rp_time        =        0      ;
440
      curr_rp_time        =        0      ;
441
      last_ReadMode_time  =        0      ;
442
      curr_ReadMode_time  =        0      ;
443
      last_dq_time        =        0      ;
444
      curr_dq_time        =        0      ;
445
      last_rpb_time       =        0      ;
446
      curr_rpb_time       =        0      ;
447
      WriteRecovery       =        0      ;
448
      last_Internal_RE_time =      0      ;
449
      curr_Internal_RE_time =      0      ;
450
      InternalOutput        =     `MaxOutputs'hxx ;
451
      last_Internal_WE_time =      0      ;
452
      curr_Internal_WE_time =      0      ;
453
      Program_Time_Byte    = `AC_ProgramTime_Byte_50_12 ;
454
      Block_Erase_Time     = `AC_EraseTime_Block_50_12;
455
      Set_LockBit_Time     = `AC_Set_LockBit_50_12;
456
      Clear_LockBit_Time   = `AC_Clear_LockBit_50_12;
457
      Program_Suspend_Time = `AC_Program_Suspend_50_12;
458
      Erase_Suspend_Time   = `AC_Erase_Suspend_50_12;
459
 
460
      $readmemh(`BlockFileBegin,BlocksBegin);
461
      $readmemh(`BlockFileEnd,BlocksEnd);
462
 
463
      for (LoopCntr = 0; LoopCntr <= `NumberOfBlocks; LoopCntr = LoopCntr
464
  + 1) begin
465
        BlocksEraseCount [LoopCntr] = 0 ;
466
      end
467
 
468
      for (LoopCntr = 0; LoopCntr < `NumberOfBlocks; LoopCntr = LoopCntr
469
  + 1) begin
470
        BlockLockBit[LoopCntr] = `Unlocked;
471
      end
472
  //--------------------------------------------------------------------
473
  // Array Init
474
  //--------------------------------------------------------------------
475
 
476
  //Constant condition expression: LoadOnPowerup == 1'b1
477
    if (LoadOnPowerup)
478
      LoadFromFile;
479
    else begin
480
      $display("Initializing Memory to 'hFF");
481
      for (LoopCntr = 0; LoopCntr <= `MaxAddr; LoopCntr = LoopCntr + 1) begin
482
        MainArray [LoopCntr] = 8'hFF ;
483
      end
484
    end
485
  end  //initial
486
 
487
  //--------------------------------------------------------------------
488
  // LoadFromFile
489
  //  This is used when the LoadOnPowerup parameter is set so that the
490
  //  Main array contains code at startup.  Basically it loads the array
491
  //  from data in a file (LoadFileName).
492
  //--------------------------------------------------------------------
493
 
494
  task LoadFromFile ;
495
    begin
496
      $display("Loading from file %s",LoadFileName);
497
      $readmemh(LoadFileName,MainArray, 1048576);
498
    end
499
  endtask
500
 
501
  //--------------------------------------------------------------------
502
  // StoreToFile
503
  //  This is used when the SaveOnPowerDown flag is set so that the Main
504
  //  Array stores code at powerdown.  Basically it stores the array into
505
  //  a file (SaveFileName).
506
  //--------------------------------------------------------------------
507
 
508
  task  StoreToFile;
509
    reg [31:0]  ArrayAddr ;
510
    reg [31:0]  outfile ;
511
    begin
512
      outfile = $fopen(SaveFileName) ;
513
      if (outfile == 0)
514
        $display("Error, cannot open output file %s",SaveFileName) ;
515
      else
516
        $display("Saving data to file %s",SaveFileName);
517
      for (ArrayAddr = 0 ; ArrayAddr <= `MaxAddr; ArrayAddr = ArrayAddr
518
  + 1) begin
519
        $fdisplay(outfile,"%h",MainArray[ArrayAddr]);
520
      end
521
    end
522
  endtask
523
 
524
  //--------------------------------------------------------------------
525
  // Program
526
  //  Description: Programs new values in to the array
527
  //--------------------------------------------------------------------
528
 
529
  task  Program ;
530
    inout  [`Byte] TheArrayValue ;
531
    input  [`Byte] DataIn  ;
532
 
533
    reg    [`Byte] OldData;
534
    begin
535
      OldData = TheArrayValue;
536
      TheArrayValue = DataIn & OldData;
537
    end
538
  endtask
539
 
540
  assign  Internal_OE  = !(ceb | oeb | !rpb) ;
541
  assign  Internal_OE2 = Internal_OE ;
542
  assign  Internal_OE3 = Internal_OE2 ;
543
  assign  Internal_RE  = (((ReadyBusy == `Ready) || (ReadMode != `rdARRAY))
544
  && !ceb && !Reset) ;
545
  assign  Internal_WE  = !(ceb | web | !rpb) ;
546
 
547
  // register definitions //
548
 
549
  // Compatible Status Register
550
  assign  CSR [7] = ReadyBusy;
551
  assign  CSR [6] = EraseSuspended ;
552
  assign  CSR [5] = Erase_ClearLBError ;
553
  assign  CSR [4] = Program_SetLBError ;
554
  assign  CSR [3] = VppError ;
555
  assign  CSR [2] = WriteSuspended ;
556
  assign  CSR [1] = Protected ;
557
  assign  CSR [0] = 1'b0 ;
558
 
559
  // Output Drivers //
560
  assign dq[7:0] = (DriveOutputs == `TRUE) ? InternalOutput : 8'hz ;
561
 
562
  always @(Reset) begin : Reset_process
563
    if (Reset) begin
564
      ClearVppFlag    <=  #1  `TRUE   ;
565
      ClearVppFlag    <=  #9  `FALSE  ;
566
      AlgDone          =      `FALSE  ;
567
      VppError         =      `FALSE  ;
568
      ReadMode         =      `rdARRAY;
569
      ReadyBusy        =      `Ready  ;
570
      WriteSuspended   =      `FALSE  ;
571
      EraseSuspended   =      `FALSE  ;
572
      Suspend          =      `FALSE  ;
573
      Erase_ClearLBError  =   `FALSE  ;
574
      Program_SetLBError  =   `FALSE  ;
575
      Protected        =      `FALSE  ;
576
      AlgTime          =       0      ;
577
      CmdValid         =      `FALSE  ;
578
      WriteToPtr       =      `NewCmd ;
579
      CSROut           =       0      ;
580
      IDOut            =       0      ;
581
    end
582
  end
583
 
584
 
585
  always @(Internal_RE or ReadMode or addr) begin : array_read
586
    if (Internal_RE && ReadMode == `rdARRAY)
587
      ArrayOut  = MainArray[addr] ;      // x8 outputs
588
  end
589
 
590
  always @(Internal_RE or ReadMode or addr or Internal_OE2) begin
591
    // output mux
592
    // Determine and generate the access time .
593
    ToOut = 0;
594
    if ($time > TAVQV) begin
595
      last_addr_time = $time - curr_addr_time;
596
      if ((last_addr_time < TAVQV) && ((TAVQV - last_addr_time) > ToOut))
597
        ToOut = TAVQV - last_addr_time ;
598
      last_oe_time = $time - curr_oe_time;
599
      if ((last_oe_time < TGLQV) && ((TGLQV - last_oe_time) > ToOut))
600
        ToOut = TGLQV - last_oe_time ;
601
      last_ce_time = $time - curr_ce_time;
602
      if ((last_ce_time < TELQV) && ((TELQV - last_ce_time) > ToOut))
603
        ToOut = TELQV - last_ce_time ;
604
      last_rp_time = $time - curr_rp_time;
605
      if ((last_rp_time < TPHQV) && ((TPHQV - last_rp_time) > ToOut))
606
        ToOut = TPHQV - last_rp_time ;
607
      last_ReadMode_time = $time - curr_ReadMode_time;
608
      if ((last_ReadMode_time < TAVQV) && ((TAVQV - last_ReadMode_time) >
609
  ToOut))
610
        ToOut = TAVQV - last_ReadMode_time ;
611
      last_Internal_RE_time = $time - curr_Internal_RE_time ;
612
      if ((last_Internal_RE_time < TAVQV) && ((TAVQV - last_Internal_RE_time)
613
  > ToOut))
614
        ToOut = TAVQV - last_Internal_RE_time ;
615
    end  // if
616
 
617
    //  Output Mux with timing
618
    if (!StartUpFlag) begin
619
      case (ReadMode)
620
       `rdARRAY : begin
621
          if ( (EraseSuspended == `TRUE) && (WriteSuspended == `FALSE)
622
               && (addr >= BlocksBegin[Algorithm[`OpBlock]])
623
               && (addr <= BlocksEnd[Algorithm[`OpBlock]]) && (oeb ==
624
  `VIL) ) begin
625
            $display("Error:  Attempting to read from erase suspended block");
626
            InternalOutput <= `MaxOutputs'hxx;
627
          end
628
          else if ( (EraseSuspended == `TRUE) && (WriteSuspended == `TRUE)
629
                    && (oeb == `VIL) && (addr >=
630
  BlocksBegin[SuspendedAlg[`OpBlock]])
631
                    && (addr <= BlocksEnd[SuspendedAlg[`OpBlock]]) ) begin
632
            $display("Error:  Attempting to read from erase suspended block.");
633
            InternalOutput <= `MaxOutputs'hxx;
634
          end
635
          else if ( (WriteSuspended == `TRUE) && (addr == Algorithm[`CmdAdd_1])
636
                    && (oeb == `VIL) ) begin
637
            $display("Error:  Attempting to read from write suspended address");
638
            InternalOutput <= `MaxOutputs'hxx;
639
          end
640
          else
641
            InternalOutput <= #ToOut ArrayOut ;
642
        end
643
       `rdCSR   : begin
644
          InternalOutput <= #ToOut CSROut ;
645
        end
646
       `rdID    :  begin
647
          InternalOutput <= #ToOut IDOut ;
648
        end
649
        default  :  begin
650
          $display("%t Error: illegal readmode", $time);
651
        end
652
      endcase
653
    end  // if
654
  end  // always
655
 
656
  //
657
  // other reads
658
  //
659
  always @(Internal_OE or addr) begin : other_read
660
    if (!Reset) begin
661
      if (ReadMode != `rdARRAY) begin
662
        CSROut = CSR ;
663
        if (addr[1:0] == 2'b00)
664
          IDOut = `ID_ManufacturerB ;
665
        else if (addr[1:0] == 2'b01)
666
          IDOut = `ID_DeviceCodeB ;
667
        else if (addr[1:0] == 2'b10) begin
668
          for (LoopCntr = `NumberOfBlocks-1; LoopCntr >= 0; LoopCntr = LoopCntr
669
  -
670
  1)
671
            if (addr <= BlocksEnd[LoopCntr])
672
             WhichBlock = LoopCntr;
673
          IDOut = BlockLockBit[WhichBlock];
674
        end
675
        else
676
          IDOut = MasterLock;
677
      end
678
    end
679
  end
680
 
681
  // Handle Write to Part
682
 
683
  always @(negedge Internal_WE) begin : handle_write
684
 
685
    reg [`Byte]   temp ;  // temporary variable needed for double
686
                          // indexing CmdData.
687
    if (!Reset) begin
688
      case (WriteToPtr)             // Where are we writting to ?
689
       `NewCmd : begin              // This is a new command.
690
         Cmd[`Cmd] = dq[7:0] ;
691
         Cmd[`Add] = addr[`AddrSize-1:0] ;
692
         CmdValid <= `TRUE ; // CmdValid sends it to the Predecode section
693
         DataPtr <= -1 ;
694
       end
695
       `CmdField : begin   // This is data used by another command
696
         if (DataPtr == 1) begin
697
           Cmd[`CmdData_1] = dq[`Byte];
698
           Cmd[`CmdAdd_1] = addr [`AddrSize-1:0] ;
699
         end
700
         else if (DataPtr == 2) begin
701
           Cmd[`CmdData_2] = dq[`Byte];
702
           Cmd[`CmdAdd_2] = addr[`AddrSize-1:0] ;
703
         end
704
         else
705
           $display("DataPtr out of range") ;
706
         DataPtr <= #1 DataPtr - 1 ;  // When DataPtr hits zero the command
707
       end
708
       default    :   begin
709
         $display("Error: Write To ? Cmd");
710
       end
711
      endcase
712
    end  //if
713
  end  //always
714
 
715
  //
716
  // Predecode Command
717
  //
718
  always @(posedge CmdValid) begin : predecode
719
    reg [`Byte] temp;       // temporary variable needed for double
720
                            // indexing BSR.
721
    if (!Reset) begin
722
      // Set Defaults
723
      Cmd [`OpType] = `Program ;
724
      WriteToPtr = `NewCmd ;
725
      DataPtr <= 0 ;
726
      case (Cmd [`Cmd])          // Handle the basic read mode commands
727
 
728
       // READ ARRAY COMMAND --
729
 
730
       `ReadArrayCmd  : begin    // Read Flash Array
731
         CmdValid <= `FALSE ;
732
         if (ReadyBusy == `Busy) // Can not read array when running an algorithm
733
           ReadMode <= `rdCSR ;
734
         else
735
           ReadMode <= `rdARRAY ;
736
       end
737
 
738
       // READ INTELLIGENT IDENTIFIER COMMAND --
739
 
740
       `ReadIDCmd     :  begin   // Read Intelligent ID
741
         if ( (WriteSuspended == `TRUE) || (EraseSuspended == `TRUE) )
742
           $display("Invalid read ID command during suspend");
743
         else
744
           ReadMode <= `rdID ;
745
         CmdValid <= `FALSE ;
746
       end
747
 
748
        // READ COMPATIBLE STATUS REGISTER COMMAND --
749
 
750
        `ReadCSRCmd  : begin    // Read CSR
751
          ReadMode <= `rdCSR ;
752
          CmdValid <= `FALSE ;
753
        end
754
       default  : begin
755
          Other = `TRUE ;            // Other flag marks commands that are algorithms
756
          Cmd [`Confirm] = `FALSE  ; // Defaults
757
         case (Cmd [`Cmd])
758
 
759
          // PROGRAM BYTE COMMAND --
760
 
761
          `ProgramCmd : begin                              // Program Byte
762
            if (WriteSuspended == `TRUE) begin
763
              $display("Error:  Program Command during Write Suspend");
764
              CmdValid <= `FALSE;
765
            end
766
            else begin
767
              WriteToPtr = `CmdField  ;
768
              DataPtr <= 1  ;
769
              if (EraseSuspended == `TRUE) begin
770
                TimeLeft = AlgTime;
771
                SuspendedAlg = Algorithm;
772
              end
773
              ToBeSuspended = `Program;
774
            end
775
          end
776
 
777
            // PROGRAM BYTE COMMAND --
778
 
779
          `Program2Cmd  : begin       // Program Byte
780
            if (WriteSuspended == `TRUE) begin
781
              $display("Error:  Program Command during Write Suspend");
782
              CmdValid <= `FALSE;
783
            end
784
            else begin
785
              Cmd [`Cmd] = `ProgramCmd ;
786
              WriteToPtr = `CmdField ;
787
              DataPtr <= 1 ;
788
              if (EraseSuspended == `TRUE) begin
789
                TimeLeft = AlgTime;
790
                SuspendedAlg = Algorithm;
791
              end
792
              ToBeSuspended = `Program;
793
            end
794
          end
795
 
796
            // ERASE BLOCK COMMAND --
797
 
798
          `EraseBlockCmd : begin    // Single Block Erase
799
            if ( (WriteSuspended == `TRUE) || (EraseSuspended == `TRUE) ) begin
800
              $display("Attempted to erase block while suspended");
801
              CmdValid <= `FALSE;
802
            end
803
            else begin
804
              WriteToPtr = `CmdField ;
805
              DataPtr <= 1 ;
806
              Cmd [`OpType] = `Erase ;
807
              Cmd [`Confirm] = `TRUE ;
808
              ToBeSuspended = `Erase;
809
            end
810
          end
811
 
812
            // LOCK BIT COMMAND
813
 
814
          `LBSetupCmd : begin
815
            if ( (WriteSuspended == `TRUE) || (EraseSuspended == `TRUE) ) begin
816
              $display("Attempted to set lock-bit while suspended");
817
              CmdValid <= `FALSE;
818
            end
819
            else begin
820
              WriteToPtr = `CmdField ;
821
              DataPtr <= 1 ;
822
              Cmd [`OpType] = `Lock ;
823
            end
824
          end
825
 
826
          default : begin  // The remaining commands are complex
827
                           // non-algorithm commands
828
              Other = `FALSE ;
829
              CmdValid = `FALSE ;
830
 
831
              // CLEAR STATUS REGISTER COMMAND
832
 
833
              if (Cmd [`Cmd] == `ClearCSRCmd) begin
834
                if (EraseSuspended | WriteSuspended)
835
                  ReadMode <= `rdARRAY ;
836
                else if (ReadyBusy == `Busy)
837
                  ReadMode <= `rdCSR ;
838
                else begin
839
                  Erase_ClearLBError <= `FALSE ;
840
                  Program_SetLBError <= `FALSE ;
841
                  VppError <= `FALSE ;
842
                  Protected <= `FALSE;
843
                  ReadMode <= `rdCSR ;
844
                end
845
              end
846
 
847
              // RESUME COMMAND --
848
 
849
            else if (Cmd [`Cmd] == `ResumeCmd) begin
850
              if (WriteSuspended | EraseSuspended)
851
                ReadMode <= `rdCSR ;
852
              Suspend = `FALSE ;
853
              if (ToBeSuspended == `Program)
854
                WriteSuspended <= `FALSE ;
855
              else
856
                EraseSuspended <= `FALSE ;
857
              ReadyBusy = `Busy;
858
            end
859
 
860
            // SUSPEND COMMAND --
861
 
862
            else if (Cmd [`Cmd] == `SuspendCmd) begin
863
              if (ReadyBusy == `Ready) begin
864
                ReadMode <= `rdARRAY ;
865
                $display("Algorithm finished; nothing to suspend");
866
              end
867
              else begin
868
                ReadMode <= `rdCSR ;
869
                Suspend = `TRUE ;
870
              end
871
              CmdValid <= `FALSE ;
872
            end
873
            else begin
874
              CmdValid <= `FALSE ;
875
              $display("Warning:Illegal Command");
876
            end
877
          end  //default
878
         endcase
879
       end  //default
880
      endcase
881
    end  //if
882
  end  //always (predecode)
883
 
884
  //
885
  // Command Decode
886
  //
887
 
888
  always @(DataPtr) begin : command
889
 
890
    integer BlockUsed;
891
 
892
    if (!Reset && (DataPtr == 0) && (WriteToPtr != `NewCmd)) begin
893
     // When DataPtr hits zero it means that all the
894
     // additional data has been given to the current command
895
      if (CmdValid && (WriteToPtr == `CmdField)) begin
896
        WriteToPtr = `NewCmd;
897
        // Just finish a multi-cycle command.  Determine which block the command uses
898
        BlockUsed = -1;
899
        for (LoopCntr = `NumberOfBlocks-1; LoopCntr >= 0; LoopCntr =
900
  LoopCntr - 1) begin
901
          if (Cmd[`CmdAdd_1] <= BlocksEnd[LoopCntr])
902
            BlockUsed = LoopCntr;
903
        end
904
        if (BlockUsed == -1)
905
          $display("Error:  Invalid Command Address");
906
        else
907
          Cmd [`OpBlock] = BlockUsed;
908
        if (Cmd [`OpType] ==  `Erase )
909
          Cmd [`Time] = Block_Erase_Time ;
910
        else if (Cmd [`OpType] == `Program )
911
          Cmd [`Time] = Program_Time_Byte;
912
        else
913
          Cmd [`Time] = 0;
914
 
915
        // If this command needs a confirm
916
        // (flaged at predecode) then check if confirm was received
917
        if (Cmd [`Confirm]) begin
918
          if (Cmd[`CmdData_1] == `ConfirmCmd) begin
919
          // If the command is still valid put it in the queue and deactivate the array
920
            Algorithm = Cmd;
921
            AlgTime = Cmd [`Time] ;
922
            CmdValid <= `FALSE;
923
            if (!VppError)
924
              ReadyBusy <= #1 `Busy ;
925
            ReadMode <= `rdCSR;
926
          end
927
          else begin
928
            ReadMode <= `rdCSR ;
929
            Program_SetLBError <= `TRUE;
930
            Erase_ClearLBError <= `TRUE;
931
            CmdValid <= `FALSE;
932
          end
933
        end
934
        else begin
935
          Algorithm = Cmd;
936
          AlgTime = Cmd [`Time] ;
937
          CmdValid <= `FALSE;
938
          if (!VppError)
939
            ReadyBusy <= #1 `Busy ;
940
          ReadMode <= `rdCSR;
941
        end
942
      end
943
    end
944
  end  //always (command)
945
 
946
  ///////////////
947
  // Execution //
948
  ///////////////
949
  always @(posedge AlgDone)  begin : execution
950
    reg   [`Byte]   temp ;  // temporary variable needed for double indexing BSR.
951
    if (!Reset) begin
952
      if (AlgDone) begin  // When the algorithm finishes
953
                          // if chips is executing during an erase interrupt
954
                          // then execute out of queue slot 2
955
        if (Algorithm [`OpType] == `Erase) begin
956
 
957
         // ERASE COMMAND //
958
          if (VppFlag) begin
959
         $display("Vpp Error occured");
960
            VppError <= `TRUE ;
961
            Erase_ClearLBError <= `TRUE;
962
          end
963
          else begin
964
            // Do ERASE to OpBlock
965
            if ((BlockLockBit[Algorithm[`OpBlock]] == `Locked)
966
                && (rpblevel != `rpb_vhh)) begin
967
              $display("Error: Attempted to erase locked block");
968
              Erase_ClearLBError <= `TRUE;
969
              Protected <= `TRUE;
970
            end
971
            else begin
972
              for (LoopCntr = BlocksBegin[Algorithm[`OpBlock]];
973
                   LoopCntr <= BlocksEnd[Algorithm[`OpBlock]]; LoopCntr
974
  = LoopCntr + 1)
975
                MainArray [LoopCntr] = 'hFF ;
976
              BlocksEraseCount[Algorithm[`OpBlock]] =
977
  BlocksEraseCount[Algorithm[
978
  `OpBlock]] + 1;
979
              $display("Block %d Erase Count: %d", Algorithm[`OpBlock],
980
  BlocksEraseCount[Algorithm[`OpBlock]]);
981
            end
982
          end
983
        end  //ERASE COMMAND
984
        else if (Algorithm [`OpType] == `Program) begin
985
 
986
          // PROGRAM COMMAND //
987
       $display("PROGRAM COMMAND:");
988
       $display("     VppFlag=", VppFlag);
989
       $display("     BlockLockBit=", BlockLockBit [Algorithm[`OpBlock]]);
990
       $display("     rpblevel=",rpblevel);
991
 
992
          if (VppFlag) begin
993
         $display("VppFlag set, do program of byte aborted!");
994
            Program_SetLBError <= `TRUE;
995
            VppError <= `TRUE ;
996
          end
997
          else begin
998
            if ((BlockLockBit [Algorithm[`OpBlock]] == `Locked)
999
                && (rpblevel != `rpb_vhh)) begin
1000
              $display("Error: Attempted to program locked block.");
1001
              Program_SetLBError <= `TRUE;
1002
              Protected <= `TRUE;
1003
            end
1004
            else begin
1005
           $display("calling program task");
1006
              Program (MainArray[Algorithm [`CmdAdd_1]], Algorithm [`CmdData_1])
1007
  ;
1008
              if (EraseSuspended == `TRUE) begin
1009
                AlgTime = TimeLeft;
1010
                ToBeSuspended = `Erase;
1011
                Algorithm = SuspendedAlg;
1012
              end
1013
            end
1014
          end
1015
        end  // PROGRAM COMMAND
1016
        else if (Algorithm [`OpType] == `Lock) begin
1017
 
1018
          // LOCK BIT COMMANDS
1019
 
1020
          if (Algorithm [`CmdData_1] == `SetBlockLBCmd) begin
1021
            if ( ((MasterLock == `Locked) && (rpblevel  != `rpb_vhh)) ||
1022
                 ((rpblevel != `rpb_vih) && (rpblevel != `rpb_vhh)) ) begin
1023
              Program_SetLBError = `TRUE;
1024
              Protected = `TRUE;
1025
              $display("Attempted to set locked block lock-bit");
1026
            end
1027
            else begin
1028
              #Set_LockBit_Time
1029
              BlockLockBit [Algorithm[`OpBlock]] = `Locked;
1030
            end
1031
          end
1032
          else if (Algorithm [`CmdData_1] == `SetMasterLBCmd) begin
1033
            if (rpblevel == `rpb_vhh)
1034
              MasterLock = `Locked;
1035
            else begin
1036
              Program_SetLBError = `TRUE;
1037
              Protected = `TRUE;
1038
              $display("Attempted to set master lock-bit with invalid RP# level");
1039
            end
1040
          end //SetMasterLBCmd
1041
          else if (Algorithm [`CmdData_1] == `ClearLBCmd) begin
1042
            if ( ((MasterLock == `Locked) && (rpblevel  != `rpb_vhh)) ||
1043
                 ((rpblevel != `rpb_vih) && (rpblevel != `rpb_vhh)) ) begin
1044
              Erase_ClearLBError = `TRUE;
1045
              Protected = `TRUE;
1046
              $display("Attempted to clear lock-bits while master lock-bit set");
1047
            end
1048
            else begin
1049
              #Clear_LockBit_Time
1050
              for (LoopCntr = 0; LoopCntr < `NumberOfBlocks; LoopCntr = LoopCntr + 1) begin
1051
                BlockLockBit[LoopCntr] = `Unlocked;
1052
              end
1053
            end
1054
          end  //ClearLBCmd
1055
          else begin
1056
            $display("Invalid lock-bit configuration command sequence");
1057
            Erase_ClearLBError = `TRUE;
1058
            Program_SetLBError = `TRUE;
1059
          end
1060
        end  //LOCK BIT COMMANDS
1061
        else
1062
          $display("Invalid algorithm operation type");
1063
      end  //if (AlgDone)
1064
      ReadyBusy <= `Ready ;
1065
    end  //if (!Reset)
1066
  end  //always (execution)
1067
 
1068
  always @(ReadyBusy) begin
1069
    if ((!Reset) && (ReadyBusy  == `Busy)) begin  // If the algorithm engine
1070
                                                  // just started, start the clock
1071
 
1072
      ClearVppFlag <= #1 `TRUE ;
1073
      ClearVppFlag <= #3 `FALSE ;
1074
      TimerClk <= #1 1'b1 ;
1075
      TimerClk <= #TimerPeriod 1'b0 ;
1076
    end
1077
  end
1078
 
1079
  // record the time for addr changes from ADDR change to posedge CEB.
1080
  always @(addr or posedge ceb) begin
1081
       if ($time != 0 & flash_cycle & ceb) begin
1082
          if ((curr_addr_time + TAVAV) > $time)    //Read/Write Cycle Time
1083
          $display("[",$time,"] Timing Violation: Read/Write Cycle Time (TAVAV), Last addr change: %d",curr_addr_time) ;
1084
       end
1085
       curr_addr_time = $time ;
1086
       flash_cycle = ~ceb;
1087
  end
1088
 
1089
  // start of flash cycle
1090
  always @(negedge ceb) begin
1091
       flash_cycle = 1;
1092
  end
1093
 
1094
  // record the time for oe changes .
1095
  always @(oeb) begin
1096
    if ($time != 0) begin
1097
      curr_oe_time = $time ;
1098
    end
1099
  end
1100
 
1101
  // record the time for ce changes .
1102
  always @(ceb) begin
1103
    if ($time != 0) begin
1104
      curr_ce_time = $time ;
1105
    end
1106
  end
1107
 
1108
  // record the time for rp changes .
1109
  always @(rpb) begin
1110
    if ($time != 0) begin
1111
      curr_rp_time = $time ;
1112
    end
1113
  end
1114
 
1115
  // record the time for ReadMode changes .
1116
  always @(ReadMode) begin
1117
    if ($time != 0) begin
1118
      curr_ReadMode_time = $time ;
1119
    end
1120
  end
1121
 
1122
  // record the time for Internal_RE changes .
1123
  always @(Internal_RE) begin
1124
    if ($time != 0) begin
1125
      curr_Internal_RE_time = $time ;
1126
    end
1127
  end
1128
 
1129
  //always @(InternalBoot) begin
1130
  //  InternalBoot_WE <= #TPHHWH InternalBoot;
1131
  //end
1132
 
1133
  always @(TimerClk) begin
1134
    if ((!Reset) && (ReadyBusy == `Busy) && (TimerClk == 1'b0)) begin
1135
      // Reschedule clock and decrement algorithm count
1136
      TimerClk <= #1 1'b1 ;
1137
      TimerClk <= #TimerPeriod 1'b0 ;
1138
      if (Suspend) begin   // Is the chip pending suspend? If so do it
1139
        Suspend = `FALSE;
1140
        if (ToBeSuspended == `Program) begin
1141
          WriteSuspended <= #Program_Suspend_Time `TRUE;
1142
          ReadyBusy <= #Program_Suspend_Time `Ready;
1143
        end
1144
        else begin
1145
          EraseSuspended <= #Erase_Suspend_Time `TRUE;
1146
          ReadyBusy <= #Erase_Suspend_Time `Ready;
1147
        end
1148
      end
1149
      if (ReadyBusy == `Busy) begin
1150
        AlgTime = AlgTime - 1;
1151
        if (AlgTime <= 0) begin // Check if the algorithm is done
1152
          AlgDone <= #1 `TRUE ;
1153
          AlgDone <= #10 `FALSE ;
1154
        end
1155
      end
1156
    end
1157
  end
1158
 
1159
  //------------------------------------------------------------------------
1160
  //  Reset Controller
1161
  //------------------------------------------------------------------------
1162
 
1163
  always @(rpb or vcc) begin : ResetPowerdownMonitor
1164
    // Go into reset if reset powerdown pin is active or
1165
    // the vcc is too low
1166
    if ((rpb != `VIH) || (vcc < 2500)) begin // Low Vcc protection
1167
      Reset <= `TRUE ;
1168
      if (!((vcc >= 2500) || StartUpFlag))
1169
        $display ("Low Vcc: Chip Resetting") ;
1170
    end
1171
    else
1172
      // Coming out of reset takes time
1173
      Reset <= #TPHWL  `FALSE ;
1174
  end
1175
 
1176
  //------------------------------------------------------------------------
1177
  // VccMonitor
1178
  //------------------------------------------------------------------------
1179
 
1180
  always @(Reset or vcc) begin : VccMonitor
1181
    // Save the array when chip is powered off
1182
    if ($time > 0) begin
1183
      if (vcc == 0 && SaveOnPowerdown)
1184
        StoreToFile;
1185
      if (vcc < 2700)
1186
        $display("Vcc is below minimum operating specs");
1187
      else if ((vcc >= 2700) && (vcc <= 3600)) begin
1188
        if ((vcc >= 3000) && (vcc <= 3600) && (`VccLevels & `Vcc3300)) begin
1189
          $display ("Vcc is in operating range for 3.3 volt mode") ;
1190
          ReadOnly    =   `FALSE    ;
1191
          TAVAV       =   121 ;
1192
          TAVAV       =   `TAVAV_33 ;
1193
          TPHQV       =   `TPHQV_33 ;
1194
          TELQV       =   `TELQV_33 ;
1195
          TGLQV       =   `TGLQV_33 ;
1196
          TAVQV       =   `TAVQV_33 ;
1197
          TGLQX       =   `TGLQX_33 ;
1198
          TGHQZ       =   `TGHQZ_33 ;
1199
          TEHQZ       =   `TEHQZ_33 ;
1200
          TOH         =   `TOH_33   ;
1201
          TWPH        =   `TWPH_33  ;
1202
          TWP         =   `TWP_33   ;
1203
          TPHWL       =   `TPHWL_33 ;
1204
          TPHHWH      =   `TPHHWH_33;
1205
          TAVWH       =   `TAVWH_33 ;
1206
          TDVWH       =   `TDVWH_33 ;
1207
          TWHDX       =   `TWHDX_33 ;
1208
          TWHAX       =   `TWHAX_33 ;
1209
       TimerPeriod =   `TimerPeriod_ ;
1210
          if ((vpp <= 3600) && (vpp >= 3000)) begin
1211
            $display ("Vpp is in operating range for 3.3 volt mode") ;
1212
            Block_Erase_Time     = `AC_EraseTime_Block_33_33;
1213
            Clear_LockBit_Time   = `AC_Clear_LockBit_33_33;
1214
            Program_Time_Byte    = `AC_ProgramTime_Byte_33_33;
1215
            Set_LockBit_Time     = `AC_Set_LockBit_33_33;
1216
            Program_Suspend_Time = `AC_Program_Suspend_33_33;
1217
            Erase_Suspend_Time   = `AC_Erase_Suspend_33_33;
1218
          end
1219
          else if ((vpp <= 5500) && (vpp >= 4500)) begin
1220
            $display ("Vpp is in operating range for 5.0 volt mode") ;
1221
            Block_Erase_Time     = `AC_EraseTime_Block_33_5;
1222
            Program_Time_Byte    = `AC_ProgramTime_Byte_33_5;
1223
            Set_LockBit_Time     = `AC_Set_LockBit_33_5;
1224
            Clear_LockBit_Time   = `AC_Clear_LockBit_33_5;
1225
            Program_Suspend_Time = `AC_Program_Suspend_33_5;
1226
            Erase_Suspend_Time   = `AC_Erase_Suspend_33_5;
1227
          end
1228
          else begin
1229
            $display ("Vpp is in operating range for 12.0 volt mode") ;
1230
            Block_Erase_Time     = `AC_EraseTime_Block_33_12;
1231
            Program_Time_Byte    = `AC_ProgramTime_Byte_33_12;
1232
            Set_LockBit_Time     = `AC_Set_LockBit_33_12;
1233
            Clear_LockBit_Time   = `AC_Clear_LockBit_33_12;
1234
            Program_Suspend_Time = `AC_Program_Suspend_33_12;
1235
            Erase_Suspend_Time   = `AC_Erase_Suspend_33_12;
1236
          end
1237
        end
1238
        else if (`VccLevels & `Vcc2700) begin
1239
          $display ("Vcc is in operating range for 2.7 volt mode -- read only")
1240
  ;
1241
          ReadOnly    =   `TRUE     ;
1242
          TAVAV       =   `TAVAV_27 ;
1243
          TPHQV       =   `TPHQV_27 ;
1244
          TELQV       =   `TELQV_27 ;
1245
          TGLQV       =   `TGLQV_27 ;
1246
          TAVQV       =   `TAVQV_27 ;
1247
          TGLQX       =   `TGLQX_27 ;
1248
          TGHQZ       =   `TGHQZ_27 ;
1249
          TEHQZ       =   `TEHQZ_27 ;
1250
          TOH         =   `TOH_27   ;
1251
          TWPH        =   `TWPH_27  ;
1252
          TWP         =   `TWP_27   ;
1253
          TPHWL       =   `TPHWL_27 ;
1254
          TPHHWH      =   `TPHHWH_27;
1255
          TAVWH       =   `TAVWH_27 ;
1256
          TDVWH       =   `TDVWH_27 ;
1257
          TWHDX       =   `TWHDX_27 ;
1258
          TWHAX       =   `TWHAX_27 ;
1259
       TimerPeriod =   `TimerPeriod_ ;
1260
        end
1261
        else
1262
          $display("Invalid Vcc Level");
1263
      end
1264
      else if ((vcc >= 4500) && (vcc <= 5500) && (`VccLevels & `Vcc5000)) begin
1265
        $display ("Vcc is in operating range for 5 volt mode") ;
1266
        ReadOnly    =   `FALSE    ;
1267
        TAVAV       =   `TAVAV_50 ;
1268
        TPHQV       =   `TPHQV_50 ;
1269
        TELQV       =   `TELQV_50 ;
1270
        TGLQV       =   `TGLQV_50 ;
1271
        TAVQV       =   `TAVQV_50 ;
1272
        TGLQX       =   `TGLQX_50 ;
1273
        TGHQZ       =   `TGHQZ_50 ;
1274
        TEHQZ       =   `TEHQZ_50 ;
1275
        TOH         =   `TOH_50   ;
1276
        TWPH        =   `TWPH_50  ;
1277
        TWP         =   `TWP_50   ;
1278
        TPHWL       =   `TPHWL_50 ;
1279
        TPHHWH      =   `TPHHWH_50;
1280
        TAVWH       =   `TAVWH_50 ;
1281
        TDVWH       =   `TDVWH_50 ;
1282
        TWHDX       =   `TWHDX_50 ;
1283
        TWHAX       =   `TWHAX_50 ;
1284
        TimerPeriod =   `TimerPeriod_ ;
1285
        if ((vpp <= 5500) && (vpp >= 4500)) begin
1286
          Block_Erase_Time     = `AC_EraseTime_Block_50_5;
1287
          Program_Time_Byte    = `AC_ProgramTime_Byte_50_5;
1288
          Set_LockBit_Time     = `AC_Set_LockBit_50_5;
1289
          Clear_LockBit_Time   = `AC_Clear_LockBit_50_5;
1290
          Program_Suspend_Time = `AC_Program_Suspend_50_5;
1291
          Erase_Suspend_Time   = `AC_Erase_Suspend_50_5;
1292
        end
1293
        else begin
1294
          Block_Erase_Time     = `AC_EraseTime_Block_50_12;
1295
          Program_Time_Byte    = `AC_ProgramTime_Byte_50_12;
1296
          Set_LockBit_Time     = `AC_Set_LockBit_50_12;
1297
          Clear_LockBit_Time   = `AC_Clear_LockBit_50_12;
1298
          Program_Suspend_Time = `AC_Program_Suspend_50_12;
1299
          Erase_Suspend_Time   = `AC_Erase_Suspend_50_12;
1300
        end
1301
      end
1302
      else
1303
        $display ("Vcc is out of operating range") ;
1304
    end //$time
1305
  end  //always (VccMonitor)
1306
 
1307
  //------------------------------------------------------------------------
1308
  // VppMonitor
1309
  //------------------------------------------------------------------------
1310
  always @(VppFlag or ClearVppFlag or vpp) begin : VppMonitor
1311
    if (ClearVppFlag) begin
1312
      VppErrFlag = `FALSE ;
1313
    end
1314
    else
1315
      if (!( ((vpp <= 12600) && (vpp >= 11400)) || ((vpp <= 5500) &&
1316
  (vpp >= 4500))
1317
             || ((vpp <= 3600) && (vpp >= 3000)))) begin
1318
        VppErrFlag = `TRUE ;
1319
      end
1320
    if ((vpp <= 3600) && (vpp >= 3000)) begin
1321
      if ((vcc <= 3600) && (vcc >= 3000)) begin
1322
        Block_Erase_Time      = `AC_EraseTime_Block_33_33;
1323
        Clear_LockBit_Time    = `AC_Clear_LockBit_33_33;
1324
        Program_Time_Byte     = `AC_ProgramTime_Byte_33_33;
1325
        Set_LockBit_Time      = `AC_Set_LockBit_33_33;
1326
        Program_Suspend_Time  = `AC_Program_Suspend_33_33;
1327
        Erase_Suspend_Time    = `AC_Erase_Suspend_33_33;
1328
      end
1329
      else
1330
        VppErrFlag = `TRUE;
1331
    end
1332
    else if ((vpp <= 5500) && (vpp >= 4500)) begin
1333
      if ((vcc <= 3600) && (vcc >= 3000)) begin
1334
        Block_Erase_Time     = `AC_EraseTime_Block_33_5;
1335
        Program_Time_Byte    = `AC_ProgramTime_Byte_33_5;
1336
        Set_LockBit_Time     = `AC_Set_LockBit_33_5;
1337
        Clear_LockBit_Time   = `AC_Clear_LockBit_33_5;
1338
        Program_Suspend_Time = `AC_Program_Suspend_33_5;
1339
        Erase_Suspend_Time   = `AC_Erase_Suspend_33_5;
1340
      end
1341
      else if ((vcc <= 5500) && (vcc >= 4500)) begin
1342
        Block_Erase_Time     = `AC_EraseTime_Block_50_5;
1343
        Program_Time_Byte    = `AC_ProgramTime_Byte_50_5;
1344
        Set_LockBit_Time     = `AC_Set_LockBit_50_5;
1345
        Clear_LockBit_Time   = `AC_Clear_LockBit_50_5;
1346
        Program_Suspend_Time = `AC_Program_Suspend_50_5;
1347
        Erase_Suspend_Time   = `AC_Erase_Suspend_50_5;
1348
      end
1349
      else
1350
        VppErrFlag = `TRUE;
1351
    end
1352
    else begin
1353
      if ((vcc <= 3600) && (vcc >= 3000)) begin
1354
        Block_Erase_Time     = `AC_EraseTime_Block_33_12;
1355
        Program_Time_Byte    = `AC_ProgramTime_Byte_33_12;
1356
        Set_LockBit_Time     = `AC_Set_LockBit_33_12;
1357
        Clear_LockBit_Time   = `AC_Clear_LockBit_33_12;
1358
        Program_Suspend_Time = `AC_Program_Suspend_33_12;
1359
        Erase_Suspend_Time   = `AC_Erase_Suspend_33_12;
1360
      end
1361
      else if ((vcc <= 5500) && (vcc >= 4500)) begin
1362
        Block_Erase_Time     = `AC_EraseTime_Block_50_12;
1363
        Program_Time_Byte    = `AC_ProgramTime_Byte_50_12;
1364
        Set_LockBit_Time     = `AC_Set_LockBit_50_12;
1365
        Clear_LockBit_Time   = `AC_Clear_LockBit_50_12;
1366
        Program_Suspend_Time = `AC_Program_Suspend_50_12;
1367
        Erase_Suspend_Time   = `AC_Erase_Suspend_50_12;
1368
      end
1369
      else
1370
        VppErrFlag = `TRUE;
1371
    end
1372
 
1373
    VppFlag <= VppErrFlag;
1374
  end  //always (VppMonitor)
1375
 
1376
 
1377
  always @(StartUpFlag or Internal_OE3) begin : OEMonitor
1378
    // This section generated DriveOutputs which is the main signal that
1379
    // controls the state of the output drivers
1380
 
1381
    if (!StartUpFlag)  begin
1382
      WriteRecovery = 0 ;
1383
      last_Internal_WE_time = $time - curr_Internal_WE_time;
1384
      if (Internal_OE) begin
1385
        TempTime = WriteRecovery + TGLQX ;
1386
        DriveOutputs = `FALSE ;
1387
        WriteRecovery = WriteRecovery + TGLQV -TempTime;
1388
        DriveOutputs <= #WriteRecovery `TRUE ;
1389
      end
1390
      else begin
1391
       InternalOutput <= #TOH `MaxOutputs'hx;
1392
       if (oeb == `VIH)
1393
         WriteRecovery = WriteRecovery + TGHQZ;
1394
       else
1395
         WriteRecovery = WriteRecovery + TEHQZ;
1396
        DriveOutputs <= #WriteRecovery `FALSE ;
1397
      end
1398
    end
1399
    else
1400
      DriveOutputs <= `FALSE ;
1401
  end
1402
 
1403
  /////// Timing Checks /////////////
1404
 
1405
  always @(Internal_WE) begin : Timing_chk
1406
 
1407
    if ($time > 0) begin
1408
 
1409
      // pulse chk
1410
      if (Internal_WE) begin
1411
        if ((($time - curr_Internal_WE_time) < TWPH) && (TWPH > 0 )) begin
1412
          $display("[",$time,"] Timing Violation: Internal Write Enable Insufficient High Time") ;
1413
        end
1414
      end
1415
      else begin
1416
        // WEb controlled write
1417
        if ((curr_Internal_WE_time - curr_ce_time) >= 10) begin
1418
          if ((vcc <= 5500) && (vcc >= 4500)) begin
1419
            if (($time - curr_Internal_WE_time) < (TWP - 10)) begin
1420
              $display("[",$time,"] Timing Violation: Internal Write Enable Insufficient Low Time");
1421
            end
1422
          end
1423
          else begin
1424
            if (($time - curr_Internal_WE_time) < (TWP - 20))begin
1425
              $display("[",$time,"] Timing Violation: Interanal Write Enable Insufficient Low Time");
1426
            end
1427
          end
1428
        end
1429
        // CEb controlled write
1430
        else begin
1431
          if ((($time - curr_Internal_WE_time) < TWP) && (TWP > 0 )) begin
1432
            $display("[",$time,"] Timing Violation: Internal Write Enable Insufficient Low Time") ;
1433
          end
1434
        end
1435
      end
1436
      curr_Internal_WE_time = $time ;
1437
 
1438
      // timing_chk - addr
1439
      last_dq_time = $time - curr_dq_time;
1440
      last_rpb_time = $time - curr_rpb_time;
1441
      last_addr_time = $time - curr_addr_time;
1442
 
1443
      if (Internal_WE == 0)  begin
1444
        if ((last_addr_time < TAVWH) && (last_addr_time > 0))
1445
          $display("[",$time,"] Timing Violation: Address setup time during write, Last Event %d",last_addr_time) ;
1446
        if ((last_rpb_time < TPHWL) && (last_rpb_time > 0))
1447
          $display("[",$time,"] Timing Violation: Writing while coming out of powerdown,  Last Event %d",last_rpb_time) ;
1448
        if ((last_dq_time < TDVWH) && (last_dq_time > 0))
1449
          $display("[",$time,"] Timing Violation: Data setup time during write, Last Event %d",last_dq_time) ;
1450
      end
1451
    end
1452
  end
1453
 
1454
  always @(addr) begin
1455
    last_Internal_WE_time = $time - curr_Internal_WE_time;
1456
    if (($time > 0) && !Internal_WE) begin   //timing chk
1457
      if ((last_Internal_WE_time < TWHAX) && (last_Internal_WE_time > 0))
1458
        $display("[",$time,"] Timing Violation:Address hold time after write, Last Event %d",last_Internal_WE_time) ;
1459
    end
1460
  end
1461
 
1462
  always @(rpb) begin
1463
    if ($time > 0) begin
1464
      curr_rpb_time = $time ;
1465
    end
1466
  end
1467
 
1468
  always @(dq) begin
1469
    curr_dq_time = $time ;
1470
    last_Internal_WE_time = $time - curr_Internal_WE_time;
1471
    if (($time > 0) && !Internal_WE) begin
1472
      if ((last_Internal_WE_time < TWHDX) && (last_Internal_WE_time > 0))
1473
        $display("[",$time,"] Timing Violation:Data hold time after write, Last Event %d",last_Internal_WE_time) ;
1474
    end
1475
  end
1476
 
1477
  endmodule

powered by: WebSVN 2.1.0

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