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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [fmf/] [flash/] [s25fl064a.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
-------------------------------------------------------------------------------
2
--  File Name: s25fl064a.vhd
3
-------------------------------------------------------------------------------
4
--  Copyright (C) 2005-2007 Free Model Foundry; http://www.FreeModelFoundry.com
5
--
6
--  This program is free software; you can redistribute it and/or modify
7
--  it under the terms of the GNU General Public License version 2 as
8
--  published by the Free Software Foundation.
9
--
10
--  MODIFICATION HISTORY:
11
--
12
--  version: |  author:      | mod date: |  changes made:
13
--    V1.0     G.Gojanovic    05 May 11   Inital Release
14
--    V1.1     D.Randjelovic  06 Apr 11   MSB of latched address is ignored
15
--    V1.2     D.Randjelovic  06 May 04   Page Program Command used with the
16
--                                        single byte data corrected.
17
--                                        Release from Deep Power Down when
18
--                                        Electronic Signature is not read
19
--                                        fixed
20
--    V1.3     D.Stanojkovic  07 Jul 02   Correction to enable testing in NCSim
21
--
22
-------------------------------------------------------------------------------
23
--  PART DESCRIPTION:
24
--
25
--  Library:    FLASH
26
--  Technology: Flash Memory
27
--  Part:       S25FL064A
28
--
29
--   Description: 64 Megabit Serial Flash Memory with 50MHz SPI Bus Interface
30
--
31
-------------------------------------------------------------------------------
32
--  Comments :
33
--      When testing with NCSim default value for TimingModel in
34
--      generic list should be removed, otherwise backannotation of this value
35
--      will not be done properly
36
-------------------------------------------------------------------------------
37
-------------------------------------------------------------------------------
38
--  Known Bugs:
39
--
40
-------------------------------------------------------------------------------
41
LIBRARY IEEE;   USE IEEE.std_logic_1164.ALL;
42
                USE STD.textio.ALL;
43
                USE IEEE.VITAL_timing.ALL;
44
                USE IEEE.VITAL_primitives.ALL;
45
 
46
LIBRARY FMF;    USE FMF.gen_utils.ALL;
47
                USE FMF.conversions.ALL;
48
-------------------------------------------------------------------------------
49
-- ENTITY DECLARATION
50
-------------------------------------------------------------------------------
51
ENTITY s25fl064a IS
52
    GENERIC (
53
        -- tipd delays: interconnect path delays
54
        tipd_SCK            : VitalDelayType01 := VitalZeroDelay01;
55
        tipd_SI             : VitalDelayType01 := VitalZeroDelay01;
56
        tipd_CSNeg          : VitalDelayType01 := VitalZeroDelay01;
57
        tipd_HOLDNeg        : VitalDelayType01 := VitalZeroDelay01;
58
        tipd_WNeg           : VitalDelayType01 := VitalZeroDelay01;
59
 
60
        -- tpd delays
61
        tpd_SCK_SO          : VitalDelayType01Z := UnitDelay01Z;--tV
62
        tpd_CSNeg_SO        : VitalDelayType01Z := UnitDelay01Z;--tDIS
63
        tpd_HOLDNeg_SO      : VitalDelayType01Z := UnitDelay01Z;--tLZ,tHZ
64
 
65
        --tsetup values
66
        tsetup_SI_SCK       : VitalDelayType := UnitDelay;  --tsuDAT /
67
        tsetup_CSNeg_SCK    : VitalDelayType := UnitDelay;  --tCSS /
68
        tsetup_HOLDNeg_SCK  : VitalDelayType := UnitDelay;  --tHD /
69
        tsetup_WNeg_CSNeg   : VitalDelayType := UnitDelay;  --tWPS \
70
 
71
        --thold values
72
        thold_SI_SCK        : VitalDelayType := UnitDelay;  --thdDAT /
73
        thold_CSNeg_SCK     : VitalDelayType := UnitDelay;  --tCSH /
74
        thold_HOLDNeg_SCK   : VitalDelayType := UnitDelay;  --tCD /
75
        thold_WNeg_CSNeg    : VitalDelayType := UnitDelay;  --tWPH \
76
 
77
        --tpw values: pulse width
78
        tpw_SCK_posedge     : VitalDelayType := UnitDelay; --tWH
79
        tpw_SCK_negedge     : VitalDelayType := UnitDelay; --tWL
80
        tpw_CSNeg_posedge   : VitalDelayType := UnitDelay; --tCS
81
 
82
        -- tperiod min (calculated as 1/max freq)
83
        tperiod_SCK_rd      : VitalDelayType := UnitDelay; -- fSCK=33MHz
84
        tperiod_SCK_fast_rd : VitalDelayType := UnitDelay; -- fSCK=50MHz
85
 
86
        -- tdevice values: values for internal delays
87
            -- Page Program Operation
88
        tdevice_PP          : VitalDelayType    := 3 ms;   --tPP
89
            --Sector Erase Operation
90
        tdevice_SE          : VitalDelayType    := 3 sec;  --tSE
91
            --Bulk Erase Operation
92
        tdevice_BE          : VitalDelayType    := 384 sec; --tBE
93
            --Write Status Register Operation
94
        tdevice_WR          : VitalDelayType    := 60 ms;  --tW
95
            --Deep Power Down
96
        tdevice_DP          : VitalDelayType    := 3 us;   --tDP
97
            --Release from Software Protect Mode
98
        tdevice_RES         : VitalDelayType    := 30 us;  --tRES
99
            --VCC (min) to CS# Low
100
        tdevice_PU          : VitalDelayType    := 10 ms;
101
        -- generic control parameters
102
        InstancePath        : STRING    := DefaultInstancePath;
103
        TimingChecksOn      : BOOLEAN   := DefaultTimingChecks;
104
        MsgOn               : BOOLEAN   := DefaultMsgOn;
105
        XOn                 : BOOLEAN   := DefaultXon;
106
        -- memory file to be loaded
107
        mem_file_name       : STRING    := "s25fl064a.mem";
108
 
109
        UserPreload         : BOOLEAN   := FALSE; --TRUE;
110
        LongTimming         : BOOLEAN   := TRUE;
111
 
112
        -- For FMF SDF technology file usage
113
        TimingModel         : STRING    := DefaultTimingModel
114
    );
115
    PORT (
116
        SCK             : IN    std_ulogic := 'U'; --serial clock input
117
        SI              : IN    std_ulogic := 'U'; --serial data input
118
        CSNeg           : IN    std_ulogic := 'U'; -- chip select input
119
        HOLDNeg         : IN    std_ulogic := 'U'; -- hold input
120
        WNeg            : IN    std_ulogic := 'U'; -- write protect input
121
        SO              : OUT   std_ulogic := 'U'  --serial data output
122
    );
123
    ATTRIBUTE VITAL_LEVEL0 of s25fl064a : ENTITY IS TRUE;
124
END s25fl064a;
125
 
126
-------------------------------------------------------------------------------
127
-- ARCHITECTURE DECLARATION
128
-------------------------------------------------------------------------------
129
ARCHITECTURE vhdl_behavioral of s25fl064a IS
130
    ATTRIBUTE VITAL_LEVEL0 OF vhdl_behavioral : ARCHITECTURE IS TRUE;
131
 
132
    CONSTANT PartID        : STRING  := "s25fl064a";
133
    CONSTANT MaxData       : NATURAL := 16#FF#; --255;
134
    CONSTANT SecSize       : NATURAL := 16#FFFF#; --65535
135
    CONSTANT SecNum        : NATURAL := 127;
136
    CONSTANT HiAddrBit     : NATURAL := 22;
137
    CONSTANT AddrRANGE     : NATURAL := 16#7FFFFF#;
138
    CONSTANT BYTE          : NATURAL := 8;
139
    --Electronic Signature
140
    CONSTANT ES            : NATURAL := 16#16#;
141
    --Device ID
142
    --Manufacturer Identification && Memory Type && Memory Capacity
143
    CONSTANT DeviceID      : NATURAL := 16#010216#;
144
 
145
-- interconnect path delay signals
146
    SIGNAL SCK_ipd         : std_ulogic := 'U';
147
    SIGNAL SI_ipd          : std_ulogic := 'U';
148
    SIGNAL CSNeg_ipd       : std_ulogic := 'U';
149
    SIGNAL HOLDNeg_ipd     : std_ulogic := 'U';
150
    SIGNAL WNeg_ipd        : std_ulogic := 'U';
151
 
152
    ---  internal delays
153
    SIGNAL PP_in           : std_ulogic := '0';
154
    SIGNAL PP_out          : std_ulogic := '0';
155
    SIGNAL PU_in           : std_ulogic := '0';
156
    SIGNAL PU_out          : std_ulogic := '0';
157
    SIGNAL SE_in           : std_ulogic := '0';
158
    SIGNAL SE_out          : std_ulogic := '0';
159
    SIGNAL BE_in           : std_ulogic := '0';
160
    SIGNAL BE_out          : std_ulogic := '0';
161
    SIGNAL WR_in           : std_ulogic := '0';
162
    SIGNAL WR_out          : std_ulogic := '0';
163
    SIGNAL DP_in           : std_ulogic := '0';
164
    SIGNAL DP_out          : std_ulogic := '0';
165
    SIGNAL RES_in          : std_ulogic := '0';
166
    SIGNAL RES_out         : std_ulogic := '0';
167
 
168
BEGIN
169
    ---------------------------------------------------------------------------
170
    -- Internal Delays
171
    ---------------------------------------------------------------------------
172
    -- Artificial VITAL primitives to incorporate internal delays
173
    PP     :VitalBuf(PP_out,  PP_in,      (tdevice_PP     ,UnitDelay));
174
    PU     :VitalBuf(PU_out,  PU_in,      (tdevice_PU     ,UnitDelay));
175
    SE     :VitalBuf(SE_out,  SE_in,      (tdevice_SE     ,UnitDelay));
176
    BE     :VitalBuf(BE_out,  BE_in,      (tdevice_BE     ,UnitDelay));
177
    WR     :VitalBuf(WR_out,  WR_in,      (tdevice_WR     ,UnitDelay));
178
    DP     :VitalBuf(DP_out,  DP_in,      (tdevice_DP     ,UnitDelay));
179
    RES    :VitalBuf(RES_out, RES_in,     (tdevice_RES    ,UnitDelay));
180
 
181
    ---------------------------------------------------------------------------
182
    -- Wire Delays
183
    ---------------------------------------------------------------------------
184
    WireDelay : BLOCK
185
    BEGIN
186
 
187
        w_1 : VitalWireDelay (SCK_ipd,     SCK, tipd_SCK);
188
        w_2 : VitalWireDelay (SI_ipd,      SI, tipd_SI);
189
        w_3 : VitalWireDelay (CSNeg_ipd,   CSNeg, tipd_CSNeg);
190
        w_4 : VitalWireDelay (HOLDNeg_ipd, HOLDNeg, tipd_HOLDNeg);
191
        w_5 : VitalWireDelay (WNeg_ipd,    WNeg, tipd_WNeg);
192
 
193
    END BLOCK;
194
 
195
    ---------------------------------------------------------------------------
196
    -- Main Behavior Block
197
    ---------------------------------------------------------------------------
198
    Behavior: BLOCK
199
 
200
        -- State Machine : State_Type
201
        TYPE state_type IS (IDLE,
202
                            DP_DOWN,
203
                            WRITE_SR,
204
                            SECTOR_ER,
205
                            BULK_ER,
206
                            PAGE_PG
207
                            );
208
 
209
        -- Instruction Type
210
        TYPE instruction_type IS (NONE,
211
                                  WREN,
212
                                  WRDI,
213
                                  WRSR,
214
                                  RDSR,
215
                                  READ,
216
                                  RDID,
217
                                  FAST_READ,
218
                                  SE,
219
                                  BE,
220
                                  PP,
221
                                  DP,
222
                                  RES_READ_ES
223
                                  );
224
 
225
        TYPE WByteType IS ARRAY (0 TO 255) OF INTEGER RANGE -1 TO MaxData;
226
        --Flash Memory Array
227
        TYPE MemArray IS ARRAY (0 TO AddrRANGE) OF INTEGER RANGE -1 TO MaxData;
228
 
229
    ---------------------------------------------------------------------------
230
    --  memory declaration
231
    ---------------------------------------------------------------------------
232
        SHARED VARIABLE Mem         : MemArray := (OTHERS => MaxData);
233
 
234
        -- states
235
        SIGNAL current_state    : state_type;
236
        SIGNAL next_state       : state_type;
237
 
238
        SIGNAL WByte            : WByteType := (others => 0);
239
        SIGNAL Instruct         : instruction_type;
240
        --zero delay signal
241
        SIGNAL SO_zd            : std_logic :='Z';
242
        --HOLD delay on output data
243
        SIGNAL SO_z             : std_logic :='Z';
244
        -- powerup
245
        SIGNAL PoweredUp        : std_logic := '0';
246
 
247
        SHARED VARIABLE Status_reg   : std_logic_vector(7 downto 0)
248
                                                := (others => '0');
249
 
250
        SIGNAL Status_reg_in         : std_logic_vector(7 downto 0)
251
                                              := (others => '0');
252
 
253
        ALIAS WEL    :std_logic IS Status_reg(1);
254
        ALIAS WIP    :std_logic IS Status_reg(0);
255
        ALIAS BP0    :std_logic IS Status_reg(2);
256
        ALIAS BP1    :std_logic IS Status_reg(3);
257
        ALIAS BP2    :std_logic IS Status_reg(4);
258
        ALIAS SRWD   :std_logic IS Status_reg(7);
259
        --Command Register
260
        SIGNAL write            : std_logic := '0';
261
        SIGNAL read_out         : std_logic := '0';
262
 
263
        SIGNAL fast_rd          : boolean   := true;
264
        SIGNAL rd               : boolean   := false;
265
 
266
        SIGNAL change_addr      : std_logic := '0';
267
 
268
        --FSM control signals
269
        SIGNAL PDONE            : std_logic := '1'; -- Page Prog. Done
270
        SIGNAL PSTART           : std_logic := '0'; --Start Page Programming
271
 
272
        SIGNAL WDONE            : std_logic := '1'; -- Write. Done
273
        SIGNAL WSTART           : std_logic := '0'; --Start Write
274
 
275
        SIGNAL ESTART           : std_logic := '0'; --Start Erase
276
        SIGNAL EDONE            : std_logic := '1'; --Erase Done
277
 
278
        SIGNAL SA               : NATURAL RANGE 0 TO SecNum := 0;
279
        SIGNAL Byte_number      : NATURAL RANGE 0 TO 255    := 0;
280
 
281
        SHARED VARIABLE Sec_Prot    : std_logic_vector(SecNum downto 0) :=
282
                                                   (OTHERS => '0');
283
 
284
        SIGNAL Address          : NATURAL RANGE 0 TO AddrRANGE := 0;
285
 
286
        -- timing check violation
287
        SIGNAL Viol                : X01 := '0';
288
 
289
        PROCEDURE ADDRHILO_SEC(
290
            VARIABLE   AddrLOW  : INOUT NATURAL RANGE 0 to ADDRRange;
291
            VARIABLE   AddrHIGH : INOUT NATURAL RANGE 0 to ADDRRange;
292
            VARIABLE   Addr     : NATURAL) IS
293
            VARIABLE   sector   : NATURAL RANGE 0 TO SecNum;
294
        BEGIN
295
            sector   := Addr/16#10000#;
296
            AddrLOW  := sector*16#10000#;
297
            AddrHIGH := sector*16#10000# + 16#0FFFF#;
298
        END AddrHILO_SEC;
299
 
300
        PROCEDURE ADDRHILO_PG(
301
            VARIABLE   AddrLOW  : INOUT NATURAL RANGE 0 to ADDRRange;
302
            VARIABLE   AddrHIGH : INOUT NATURAL RANGE 0 to ADDRRange;
303
            VARIABLE   Addr     : NATURAL) IS
304
            VARIABLE   page     : NATURAL RANGE 0 TO 65535;
305
        BEGIN
306
            page     := Addr/16#100#;
307
            AddrLOW  := Page*16#100#;
308
            AddrHIGH := Page*16#100# + 16#FF#;
309
        END AddrHILO_PG;
310
 
311
    BEGIN
312
   ----------------------------------------------------------------------------
313
    --Power Up time;
314
    ---------------------------------------------------------------------------
315
 
316
    PoweredUp <= '1' AFTER tdevice_PU;
317
 
318
    ---------------------------------------------------------------------------
319
    -- VITAL Timing Checks Procedures
320
    ---------------------------------------------------------------------------
321
    VITALTimingCheck: PROCESS(SI_ipd, SCK_ipd, CSNeg_ipd, HOLDNeg_ipd,
322
                              WNeg_ipd)
323
         -- Timing Check Variables
324
        VARIABLE Tviol_SI_SCK     : X01 := '0';
325
        VARIABLE TD_SI_SCK        : VitalTimingDataType;
326
 
327
        VARIABLE Tviol_HOLD_SCK   : X01 := '0';
328
        VARIABLE TD_HOLD_SCK      : VitalTimingDataType;
329
 
330
        VARIABLE Tviol_CS_SCK     : X01 := '0';
331
        VARIABLE TD_CS_SCK        : VitalTimingDataType;
332
 
333
        VARIABLE Tviol_WS_CS      : X01 := '0';
334
        VARIABLE TD_WS_CS         : VitalTimingDataType;
335
 
336
        VARIABLE Tviol_WH_CS      : X01 := '0';
337
        VARIABLE TD_WH_CS         : VitalTimingDataType;
338
 
339
        VARIABLE Pviol_CS         : X01 := '0';
340
        VARIABLE PD_CS            : VitalPeriodDataType := VitalPeriodDataInit;
341
 
342
        VARIABLE Pviol_SCK        : X01 := '0';
343
        VARIABLE PD_SCK           : VitalPeriodDataType := VitalPeriodDataInit;
344
 
345
        VARIABLE Pviol_SCK_rd     : X01 := '0';
346
        VARIABLE PD_SCK_rd        : VitalPeriodDataType := VitalPeriodDataInit;
347
 
348
        VARIABLE Pviol_SCK_fast_rd: X01 := '0';
349
        VARIABLE PD_SCK_fast_rd   : VitalPeriodDataType := VitalPeriodDataInit;
350
 
351
        VARIABLE Violation        : X01 := '0';
352
 
353
    BEGIN
354
    ---------------------------------------------------------------------------
355
    -- Timing Check Section
356
    ---------------------------------------------------------------------------
357
    IF (TimingChecksOn) THEN
358
 
359
        -- Setup/Hold Check between SI and SCK
360
        VitalSetupHoldCheck (
361
            TestSignal      => SI_ipd,
362
            TestSignalName  => "SI",
363
            RefSignal       => SCK_ipd,
364
            RefSignalName   => "SCK",
365
            SetupHigh       => tsetup_SI_SCK,
366
            SetupLow        => tsetup_SI_SCK,
367
            HoldHigh        => thold_SI_SCK,
368
            HoldLow         => thold_SI_SCK,
369
            CheckEnabled    => true,
370
            RefTransition   => '/',
371
            HeaderMsg       => InstancePath & PartID,
372
            TimingData      => TD_SI_SCK,
373
            Violation       => Tviol_SI_SCK
374
        );
375
 
376
        -- Setup/Hold Check between HOLD# and SCK /
377
        VitalSetupHoldCheck (
378
            TestSignal      => HOLDNeg_ipd,
379
            TestSignalName  => "HOLD#",
380
            RefSignal       => SCK_ipd,
381
            RefSignalName   => "SCK",
382
            SetupLow        => tsetup_HOLDNeg_SCK,
383
            HoldLow         => thold_HOLDNeg_SCK,
384
            CheckEnabled    => true,
385
            RefTransition   => '/',
386
            HeaderMsg       => InstancePath & PartID,
387
            TimingData      => TD_HOLD_SCK,
388
            Violation       => Tviol_HOLD_SCK
389
        );
390
 
391
        -- Setup/Hold Check between CS# and SCK
392
        VitalSetupHoldCheck (
393
            TestSignal      => CSNeg_ipd,
394
            TestSignalName  => "CS#",
395
            RefSignal       => SCK_ipd,
396
            RefSignalName   => "SCK",
397
            SetupHigh       => tsetup_CSNeg_SCK,
398
            SetupLow        => tsetup_CSNeg_SCK,
399
            HoldHigh        => thold_CSNeg_SCK,
400
            HoldLow         => thold_CSNeg_SCK,
401
            CheckEnabled    => true,
402
            RefTransition   => '/',
403
            HeaderMsg       => InstancePath & PartID,
404
            TimingData      => TD_CS_SCK,
405
            Violation       => Tviol_CS_SCK
406
        );
407
 
408
        -- Setup Check between W# and CS# \
409
        VitalSetupHoldCheck (
410
            TestSignal      => WNeg_ipd,
411
            TestSignalName  => "W#",
412
            RefSignal       => CSNeg_ipd,
413
            RefSignalName   => "CS#",
414
            SetupHigh       => tsetup_WNeg_CSNeg,
415
            CheckEnabled    => true,
416
            RefTransition   => '\',
417
            HeaderMsg       => InstancePath & PartID,
418
            TimingData      => TD_WS_CS,
419
            Violation       => Tviol_WS_CS
420
        );
421
 
422
        -- Hold Check between W# and CS# /
423
        VitalSetupHoldCheck (
424
            TestSignal      => WNeg_ipd,
425
            TestSignalName  => "W#",
426
            RefSignal       => CSNeg_ipd,
427
            RefSignalName   => "CS#",
428
            HoldHigh        => thold_WNeg_CSNeg,
429
            CheckEnabled    => true,
430
            RefTransition   => '/',
431
            HeaderMsg       => InstancePath & PartID,
432
            TimingData      => TD_WH_CS,
433
            Violation       => Tviol_WH_CS
434
        );
435
 
436
        -- Period Check CS# m
437
        VitalPeriodPulseCheck (
438
            TestSignal      =>  CSNeg_ipd,
439
            TestSignalName  =>  "CS#",
440
            PulseWidthHigh  =>  tpw_CSNeg_posedge,
441
            PeriodData      =>  PD_CS,
442
            XOn             =>  XOn,
443
            MsgOn           =>  MsgOn,
444
            Violation       =>  Pviol_CS,
445
            HeaderMsg       =>  InstancePath & PartID,
446
            CheckEnabled    =>  true );
447
 
448
        -- Period Check SCK for everything but READ
449
        VitalPeriodPulseCheck (
450
            TestSignal      =>  SCK_ipd,
451
            TestSignalName  =>  "SCK",
452
            PulseWidthLow   =>  tpw_SCK_negedge,
453
            PulseWidthHigh  =>  tpw_SCK_posedge,
454
            PeriodData      =>  PD_SCK,
455
            XOn             =>  XOn,
456
            MsgOn           =>  MsgOn,
457
            Violation       =>  Pviol_SCK,
458
            HeaderMsg       =>  InstancePath & PartID,
459
            CheckEnabled    =>  true );
460
 
461
        -- Period Check SCK for READ
462
        VitalPeriodPulseCheck (
463
            TestSignal      =>  SCK_ipd,
464
            TestSignalName  =>  "SCK",
465
            Period          =>  tperiod_SCK_rd,
466
            PeriodData      =>  PD_SCK_rd,
467
            XOn             =>  XOn,
468
            MsgOn           =>  MsgOn,
469
            Violation       =>  Pviol_SCK_rd,
470
            HeaderMsg       =>  InstancePath & PartID,
471
            CheckEnabled    =>  rd );
472
 
473
        -- Period Check SCK for other than READ
474
        VitalPeriodPulseCheck (
475
            TestSignal      =>  SCK_ipd,
476
            TestSignalName  =>  "SCK",
477
            Period          =>  tperiod_SCK_fast_rd,
478
            PeriodData      =>  PD_SCK_fast_rd,
479
            XOn             =>  XOn,
480
            MsgOn           =>  MsgOn,
481
            Violation       =>  Pviol_SCK_fast_rd,
482
            HeaderMsg       =>  InstancePath & PartID,
483
            CheckEnabled    =>  fast_rd );
484
 
485
        Violation := Tviol_SI_SCK            OR
486
                     Tviol_HOLD_SCK          OR
487
                     Tviol_CS_SCK            OR
488
                     Tviol_WS_CS             OR
489
                     Tviol_WH_CS             OR
490
                     Pviol_SCK               OR
491
                     Pviol_SCK_rd            OR
492
                     Pviol_SCK_fast_rd       OR
493
                     Pviol_CS;
494
 
495
        Viol <= Violation;
496
 
497
        ASSERT Violation = '0'
498
            REPORT InstancePath & partID & ": simulation may be" &
499
                    " inaccurate due to timing violations"
500
            SEVERITY WARNING;
501
 
502
    END IF;
503
END PROCESS VITALTimingCheck;
504
 
505
    ----------------------------------------------------------------------------
506
    -- sequential process for FSM state transition
507
    ----------------------------------------------------------------------------
508
    StateTransition : PROCESS(next_state, PoweredUp)
509
 
510
    BEGIN
511
        IF PoweredUp = '1' THEN
512
                current_state <= next_state;
513
        END IF;
514
END PROCESS StateTransition;
515
 
516
    ---------------------------------------------------------------------------
517
    --  Write cycle decode
518
    ---------------------------------------------------------------------------
519
    BusCycleDecode : PROCESS(SCK_ipd, CSNeg_ipd, HOLDNeg_ipd, SI_ipd, RES_in)
520
 
521
        TYPE bus_cycle_type IS (STAND_BY,
522
                                CODE_BYTE,
523
                                ADDRESS_BYTES,
524
                                DUMMY_BYTES,
525
                                DATA_BYTES
526
                                );
527
 
528
        VARIABLE bus_cycle_state    : bus_cycle_type;
529
 
530
        VARIABLE data_cnt        : NATURAL := 0;
531
        VARIABLE addr_cnt        : NATURAL := 0;
532
        VARIABLE code_cnt        : NATURAL := 0;
533
        VARIABLE dummy_cnt       : NATURAL := 0;
534
        VARIABLE bit_cnt         : NATURAL := 0;
535
        VARIABLE Data_in         : std_logic_vector(2047 downto 0)
536
                                                    := (others => '0');
537
        VARIABLE code            : std_logic_vector(7 downto 0);
538
        VARIABLE code_in         : std_logic_vector(7 downto 0);
539
        VARIABLE Byte_slv        : std_logic_vector(7 downto 0);
540
        VARIABLE addr_bytes      : std_logic_vector(HiAddrBit downto 0);
541
        VARIABLE Address_in      : std_logic_vector(23 downto 0);
542
    BEGIN
543
 
544
        CASE bus_cycle_state IS
545
            WHEN STAND_BY =>
546
                IF falling_edge(CSNeg_ipd) THEN
547
                    Instruct <= NONE;
548
                    write <= '1';
549
                    code_cnt := 0;
550
                    addr_cnt := 0;
551
                    data_cnt := 0;
552
                    dummy_cnt := 0;
553
                    bus_cycle_state := CODE_BYTE;
554
                END IF;
555
 
556
            WHEN CODE_BYTE =>
557
                IF rising_edge(SCK_ipd) AND HOLDNeg_ipd = '1' THEN
558
                    Code_in(code_cnt) := SI_ipd;
559
                    code_cnt := code_cnt + 1;
560
                    IF code_cnt = BYTE THEN
561
                        --MSB first
562
                        FOR I IN 7 DOWNTO 0 LOOP
563
                            code(i) := code_in(7-i);
564
                        END LOOP;
565
                        CASE code IS
566
                            WHEN "00000110" =>
567
                                Instruct <= WREN;
568
                                bus_cycle_state := DATA_BYTES;
569
                            WHEN "00000100" =>
570
                                Instruct <= WRDI;
571
                                bus_cycle_state := DATA_BYTES;
572
                            WHEN "00000001" =>
573
                                Instruct <= WRSR;
574
                                bus_cycle_state := DATA_BYTES;
575
                            WHEN "00000101" =>
576
                                Instruct <= RDSR;
577
                                bus_cycle_state := DATA_BYTES;
578
                            WHEN "00000011" =>
579
                                Instruct <= READ;
580
                                bus_cycle_state := ADDRESS_BYTES;
581
                            WHEN "00001011" =>
582
                                Instruct <= FAST_READ;
583
                                bus_cycle_state := ADDRESS_BYTES;
584
                            WHEN "10011111" =>
585
                                Instruct <= RDID;
586
                                bus_cycle_state := DATA_BYTES;
587
                            WHEN "10101011" =>
588
                                Instruct <= RES_READ_ES;
589
                                bus_cycle_state := DUMMY_BYTES;
590
                            WHEN "11011000" =>
591
                                Instruct <= SE;
592
                                bus_cycle_state := ADDRESS_BYTES;
593
                            WHEN "11000111" =>
594
                                Instruct <= BE;
595
                                bus_cycle_state := DATA_BYTES;
596
                            WHEN "00000010" =>
597
                                Instruct <= PP;
598
                                bus_cycle_state := ADDRESS_BYTES;
599
                            WHEN "10111001" =>
600
                                Instruct <= DP;
601
                                bus_cycle_state := DATA_BYTES;
602
                            WHEN others =>
603
                                null;
604
                        END CASE;
605
                    END IF;
606
                END IF;
607
 
608
                WHEN ADDRESS_BYTES =>
609
                    IF rising_edge(SCK_ipd) AND HOLDNeg_ipd = '1' THEN
610
                        Address_in(addr_cnt) := SI_ipd;
611
                        addr_cnt := addr_cnt + 1;
612
                        IF addr_cnt = 3*BYTE THEN
613
                            FOR I IN 23 DOWNTO 23-HiAddrBit LOOP
614
                                addr_bytes(23-i) := Address_in(i);
615
                            END LOOP;
616
                            Address <= to_nat(addr_bytes);
617
                            change_addr <= '1','0' AFTER 1 ns;
618
                            IF Instruct = FAST_READ THEN
619
                                bus_cycle_state := DUMMY_BYTES;
620
                            ELSE
621
                                bus_cycle_state := DATA_BYTES;
622
                            END IF;
623
                        END IF;
624
                    END IF;
625
 
626
                WHEN DUMMY_BYTES =>
627
                    IF rising_edge(SCK_ipd) AND HOLDNeg_ipd = '1' THEN
628
                        dummy_cnt := dummy_cnt + 1;
629
                        IF dummy_cnt = BYTE THEN
630
                            IF Instruct = FAST_READ THEN
631
                                bus_cycle_state := DATA_BYTES;
632
                            END IF;
633
                        ELSIF dummy_cnt = 3*BYTE THEN
634
                            bus_cycle_state := DATA_BYTES;
635
                        END IF;
636
                    END IF;
637
 
638
                    IF rising_edge(CSNeg_ipd) THEN
639
                        bus_cycle_state := STAND_BY;
640
                        IF HOLDNeg_ipd = '1' AND Instruct = RES_READ_ES THEN
641
                            write <= '0';
642
                        END IF;
643
                    END IF;
644
 
645
                WHEN DATA_BYTES =>
646
                    IF falling_edge(SCK_ipd) AND CSNeg_ipd = '0'
647
                    AND HOLDNeg_ipd = '1' THEN
648
                        IF Instruct = READ OR Instruct = RES_READ_ES
649
                           OR Instruct = FAST_READ OR Instruct = RDSR
650
                           OR Instruct = RDID THEN
651
                            read_out <= '1', '0' AFTER 1 ns;
652
                        END IF;
653
                    END IF;
654
 
655
                    IF rising_edge(SCK_ipd) AND HOLDNeg_ipd = '1' THEN
656
                        IF data_cnt > 2047 THEN
657
                        --In case of PP, if more than 256 bytes are
658
                        --sent to the device
659
                            IF bit_cnt = 0 THEN
660
                                FOR I IN 0 TO (255*BYTE - 1) LOOP
661
                                    Data_in(i) := Data_in(i+8);
662
                                END LOOP;
663
                            END IF;
664
                            Data_in(2040 + bit_cnt) := SI_ipd;
665
                            bit_cnt := bit_cnt + 1;
666
                            IF bit_cnt = 8 THEN
667
                                bit_cnt := 0;
668
                            END IF;
669
                            data_cnt := data_cnt + 1;
670
                        ELSE
671
                            Data_in(data_cnt) := SI_ipd;
672
                            data_cnt := data_cnt + 1;
673
                            bit_cnt := 0;
674
                        END IF;
675
                    END IF;
676
 
677
                    IF rising_edge(CSNeg_ipd) THEN
678
                        bus_cycle_state := STAND_BY;
679
                        IF  HOLDNeg_ipd = '1' THEN
680
                            CASE Instruct IS
681
                                WHEN WREN | WRDI | DP | BE | SE =>
682
                                    IF data_cnt = 0 THEN
683
                                        write <= '0';
684
                                    END IF;
685
                                WHEN RDID | RES_READ_ES =>
686
                                    write <= '0';
687
                                WHEN WRSR =>
688
                                    IF data_cnt = 8 THEN
689
                                        write <= '0';
690
                                        Status_reg_in <= Data_in(7 downto 0);
691
                                        --MSB first
692
                                    END IF;
693
                                WHEN PP =>
694
                                    IF ((data_cnt mod 8) = 0 AND
695
                                        data_cnt > 0) THEN
696
                                        write <= '0';
697
                                        FOR I IN 0 TO 255 LOOP
698
                                            FOR J IN 7 DOWNTO 0 LOOP
699
                                                Byte_slv(j) :=
700
                                                Data_in((i*8) + (7-j));
701
                                            END LOOP;
702
                                            WByte(i) <= to_nat(Byte_slv);
703
                                        END LOOP;
704
                                        IF data_cnt > 256*BYTE THEN
705
                                            Byte_number <= 255;
706
                                        ELSE
707
                                            Byte_number <= data_cnt/8-1;
708
                                        END IF;
709
                                    END IF;
710
                                WHEN others =>
711
                                    null;
712
                            END CASE;
713
                        END IF;
714
                    END IF;
715
 
716
            END CASE;
717
 
718
END PROCESS BusCycleDecode;
719
    ---------------------------------------------------------------------------
720
    -- Timing control for the Page Program
721
    ---------------------------------------------------------------------------
722
    ProgTime : PROCESS(PSTART)
723
        VARIABLE pob      : time;
724
    BEGIN
725
        IF LongTimming THEN
726
            pob  := tdevice_PP;
727
        ELSE
728
            pob  := tdevice_PP / 100;
729
        END IF;
730
        IF rising_edge(PSTART) AND PDONE = '1' THEN
731
            IF NOT Sec_Prot(SA) = '1' THEN
732
                PDONE <= '0', '1' AFTER pob;
733
            END IF;
734
        END IF;
735
END PROCESS ProgTime;
736
    ---------------------------------------------------------------------------
737
    -- Timing control for the Write Status Register
738
    ---------------------------------------------------------------------------
739
    WriteTime : PROCESS(WSTART)
740
        VARIABLE wob      : time;
741
    BEGIN
742
        IF LongTimming THEN
743
            wob  := tdevice_WR;
744
        ELSE
745
            wob  := tdevice_WR / 100;
746
        END IF;
747
        IF rising_edge(WSTART) AND WDONE = '1' THEN
748
            WDONE <= '0', '1' AFTER wob;
749
        END IF;
750
END PROCESS WriteTime;
751
    ---------------------------------------------------------------------------
752
    -- Timing control for the Bulk Erase
753
    ---------------------------------------------------------------------------
754
    ErsTime : PROCESS(ESTART)
755
        VARIABLE seo      : time;
756
        VARIABLE beo      : time;
757
        VARIABLE duration : time;
758
    BEGIN
759
        IF LongTimming THEN
760
            seo := tdevice_SE;
761
            beo := tdevice_BE;
762
        ELSE
763
            seo := tdevice_SE / 100;
764
            beo := tdevice_BE / 100;
765
        END IF;
766
        IF rising_edge(ESTART) AND EDONE = '1' THEN
767
            IF Instruct = BE THEN
768
                duration := beo;
769
            ELSE --Instruct = SE
770
                duration := seo;
771
            END IF;
772
            EDONE <= '0', '1' AFTER duration;
773
        END IF;
774
END PROCESS ErsTime;
775
 
776
    CheckCEOnPowerUP :PROCESS
777
    BEGIN
778
        IF CSNeg /= '1' THEN
779
            REPORT InstancePath & partID &
780
            ": Device is selected during Power Up"
781
            SEVERITY WARNING;
782
        END IF;
783
        WAIT;
784
    END PROCESS;
785
 
786
    ---------------------------------------------------------------------------
787
    -- Main Behavior Process
788
    -- combinational process for next state generation
789
    ---------------------------------------------------------------------------
790
    StateGen :PROCESS(write, CSNeg, WDONE, PDONE, EDONE)
791
 
792
        VARIABLE sect   : NATURAL RANGE 0 TO SecNum;
793
 
794
    BEGIN
795
        -----------------------------------------------------------------------
796
        -- Functionality Section
797
        -----------------------------------------------------------------------
798
 
799
        CASE current_state IS
800
            WHEN IDLE          =>
801
                IF falling_edge(write) THEN
802
                    IF Instruct = WRSR AND WEL = '1'
803
                       AND not(SRWD = '1' AND WNeg = '0') THEN
804
                       -- can not execute if HPM is entered
805
                       -- or if WEL bit is zero
806
                        next_state <= WRITE_SR;
807
                    ELSIF Instruct = PP AND WEL = '1' THEN
808
                        sect := Address / 16#10000#;
809
                        IF Sec_Prot(sect) = '0' THEN
810
                            next_state <=  PAGE_PG;
811
                        END IF;
812
                    ELSIF Instruct = SE AND WEL = '1' THEN
813
                        sect := Address / 16#10000#;
814
                        IF Sec_Prot(sect) = '0' THEN
815
                            next_state <=  SECTOR_ER;
816
                        END IF;
817
                    ELSIF Instruct = BE AND WEL = '1' AND
818
                          (BP0 = '0' AND BP1 = '0' AND BP2 = '0') THEN
819
                        next_state <= BULK_ER;
820
                    ELSIF Instruct = DP THEN
821
                        next_state <= DP_DOWN;
822
                    ELSE
823
                        next_state <= IDLE;
824
                    END IF;
825
                END IF;
826
 
827
            WHEN WRITE_SR      =>
828
                IF rising_edge(WDONE) THEN
829
                    next_state <= IDLE;
830
                END IF;
831
 
832
            WHEN PAGE_PG       =>
833
                IF rising_edge(PDONE) THEN
834
                    next_state <= IDLE;
835
                END IF;
836
 
837
            WHEN BULK_ER | SECTOR_ER  =>
838
                IF rising_edge(EDONE) THEN
839
                    next_state <= IDLE;
840
                END IF;
841
 
842
            WHEN DP_DOWN     =>
843
                IF falling_edge(write) AND Instruct = RES_READ_ES THEN
844
                    next_state <= IDLE;
845
                END IF;
846
 
847
        END CASE;
848
 
849
END PROCESS StateGen;
850
 
851
    ---------------------------------------------------------------------------
852
    --FSM Output generation and general funcionality
853
    ---------------------------------------------------------------------------
854
    Functional : PROCESS(write,read_out, WDONE, PDONE, EDONE, current_state,
855
                         CSNeg_ipd, HOLDNeg_ipd, Instruct, Address, WByte,
856
                         RES_out, change_addr, PoweredUp, WNeg_ipd)
857
 
858
        TYPE WDataType IS ARRAY (0 TO 255) OF INTEGER RANGE -1 TO MaxData;
859
 
860
        VARIABLE WData       : WDataType:= (OTHERS => 0);
861
 
862
        VARIABLE oe          : boolean := FALSE;
863
 
864
        VARIABLE AddrLo      : NATURAL;
865
        VARIABLE AddrHi      : NATURAL;
866
        VARIABLE Addr        : NATURAL;
867
 
868
        VARIABLE read_cnt    : NATURAL;
869
        VARIABLE read_addr   : NATURAL RANGE 0 TO AddrRANGE;
870
        VARIABLE data_out    : std_logic_vector(7 downto 0);
871
        VARIABLE ident_out   : std_logic_vector(23 downto 0);
872
 
873
        VARIABLE old_bit     : std_logic_vector(7 downto 0);
874
        VARIABLE new_bit     : std_logic_vector(7 downto 0);
875
        VARIABLE old_int     : INTEGER RANGE -1 to MaxData;
876
        VARIABLE new_int     : INTEGER RANGE -1 to MaxData;
877
        VARIABLE wr_cnt      : NATURAL RANGE 0 TO 255;
878
 
879
        VARIABLE sect        : NATURAL RANGE 0 TO SecNum;
880
        VARIABLE BP          : std_logic_vector(2 downto 0) := "000";
881
 
882
    BEGIN
883
        -----------------------------------------------------------------------
884
        -- Functionality Section
885
        -----------------------------------------------------------------------
886
 
887
        oe := rising_edge(read_out) AND PoweredUp = '1';
888
 
889
        IF Instruct'EVENT THEN
890
            read_cnt := 0;
891
            fast_rd  <= true;
892
            rd       <= false;
893
        END IF;
894
 
895
        IF rising_edge(change_addr) THEN
896
            read_addr := Address;
897
        END IF;
898
 
899
        IF RES_out'EVENT AND RES_out = '1' THEN
900
            RES_in <= '0';
901
        END IF;
902
 
903
        CASE current_state IS
904
            WHEN IDLE          =>
905
                IF falling_edge(write) THEN
906
                    read_cnt := 0;
907
                    IF RES_in = '1' THEN
908
                        ASSERT false
909
                            REPORT InstancePath & partID & "Command results" &
910
                                  " can be corrupted, a delay of tRES" &
911
                                  " currently in progress."
912
                            SEVERITY WARNING;
913
                    END IF;
914
                    IF Instruct = WREN THEN
915
                        WEL := '1';
916
                    ELSIF Instruct = WRDI THEN
917
                        WEL := '0';
918
                    ELSIF Instruct = WRSR AND WEL = '1'
919
                          AND not(SRWD = '1' AND WNeg_ipd = '0') THEN
920
                       -- can not execute if HPM is entered
921
                       -- or if WEL bit is zero
922
                        WSTART <= '1', '0' AFTER 1 ns;
923
                        WIP := '1';
924
                    ELSIF Instruct = PP AND WEL = '1' THEN
925
                        sect := Address / 16#10000#;
926
                        IF Sec_Prot(sect) = '0' THEN
927
                            PSTART <= '1', '0' AFTER 1 ns;
928
                            WIP := '1';
929
                            SA <= sect;
930
                            Addr := Address;
931
                            wr_cnt := Byte_number;
932
                            FOR I IN wr_cnt DOWNTO 0 LOOP
933
                                IF Viol /= '0' AND Sec_Prot(SA) /= '0' THEN
934
                                    WData(i) := -1;
935
                                ELSE
936
                                    WData(i) := WByte(i);
937
                                END IF;
938
                            END LOOP;
939
                        END IF;
940
                    ELSIF Instruct = SE AND WEL = '1' THEN
941
                        sect := Address / 16#10000#;
942
                        IF Sec_Prot(sect) = '0' THEN
943
                            ESTART <= '1', '0' AFTER 1 ns;
944
                            WIP := '1';
945
                            Addr := Address;
946
                        END IF;
947
                    ELSIF Instruct = BE AND WEL = '1' AND
948
                          (BP0 = '0' AND BP1 = '0' AND BP2 = '0') THEN
949
                        ESTART <= '1', '0' AFTER 1 ns;
950
                        WIP := '1';
951
                    END IF;
952
 
953
                ELSIF oe AND RES_in = '0' THEN
954
                    IF Instruct = RDSR THEN
955
                        --Read Status Register
956
                        SO_zd <= Status_reg(7-read_cnt);
957
                        read_cnt := read_cnt + 1;
958
                        IF read_cnt = 8 THEN
959
                            read_cnt := 0;
960
                        END IF;
961
                    ELSIF Instruct = READ OR Instruct = FAST_READ THEN
962
                        --Read Memory array
963
                        IF Instruct = READ THEN
964
                            fast_rd <= false;
965
                            rd      <= true;
966
                        END IF;
967
                        data_out := to_slv(Mem(read_addr),8);
968
                        SO_zd <= data_out(7-read_cnt);
969
                        read_cnt := read_cnt + 1;
970
                        IF read_cnt = 8 THEN
971
                            read_cnt := 0;
972
                            IF read_addr = AddrRANGE THEN
973
                                read_addr := 0;
974
                            ELSE
975
                                read_addr := read_addr + 1;
976
                            END IF;
977
                        END IF;
978
                    ELSIF Instruct = RDID THEN
979
                        --Read Device ID
980
                        --can be terminated by driving CSNeg high
981
                        --at any time
982
                        ident_out := to_slv(DeviceID,24);
983
                        SO_zd     <= ident_out(23-read_cnt);
984
                        read_cnt  := read_cnt + 1;
985
                        IF read_cnt = 24 THEN
986
                            read_cnt := 0;
987
                        END IF;
988
                    ELSIF Instruct = RES_READ_ES THEN
989
                    --Read Electronic Signature
990
                        data_out := to_slv(ES,8);
991
                        SO_zd <= data_out(7 - read_cnt);
992
                        read_cnt := read_cnt + 1;
993
                        IF read_cnt = 8 THEN
994
                            read_cnt := 0;
995
                        END IF;
996
                    END IF;
997
                ELSIF oe AND RES_in = '1' THEN
998
                    SO_zd <= 'X';
999
                    read_cnt := read_cnt + 1;
1000
                    IF read_cnt = 8 THEN
1001
                        read_cnt := 0;
1002
                    END IF;
1003
                    ASSERT false
1004
                        REPORT InstancePath & partID & "Command results" &
1005
                              " can be corrupted, a delay of tRES" &
1006
                              " currently in progress."
1007
                        SEVERITY WARNING;
1008
 
1009
                END IF;
1010
 
1011
            WHEN WRITE_SR      =>
1012
 
1013
                IF oe AND Instruct = RDSR THEN
1014
                    SO_zd <= Status_reg(7-read_cnt);
1015
                    read_cnt := read_cnt + 1;
1016
                    IF read_cnt = 8 THEN
1017
                        read_cnt := 0;
1018
                    END IF;
1019
                END IF;
1020
 
1021
                IF WDONE = '1' THEN
1022
                    WIP  := '0';
1023
                    WEL  := '0';
1024
                    SRWD := Status_reg_in(0);--MSB first
1025
                    BP2  := Status_reg_in(3);
1026
                    BP1  := Status_reg_in(4);
1027
                    BP0  := Status_reg_in(5);
1028
                    BP   := BP2 & BP1 & BP0;
1029
                    CASE BP IS
1030
                        WHEN "000" =>
1031
                            Sec_Prot := (others => '0');
1032
                        WHEN "001" =>
1033
                            Sec_Prot(127)          := '1';
1034
                            Sec_Prot(126)          := '1';
1035
                            Sec_Prot(125 downto 0) := (others => '0');
1036
                        WHEN "010" =>
1037
                            Sec_Prot(127 downto 124):= (others => '1');
1038
                            Sec_Prot(123 downto 0) := (others => '0');
1039
                        WHEN "011" =>
1040
                            Sec_Prot(127 downto 120):= to_slv(16#FF#,8);
1041
                            Sec_Prot(119 downto 0) := (others => '0');
1042
                        WHEN "100" =>
1043
                            Sec_Prot(127 downto 112):= to_slv(16#FFFF#,16);
1044
                            Sec_Prot(111 downto 0) := (others => '0');
1045
                        WHEN "101" =>
1046
                            Sec_Prot(127 downto 112):= to_slv(16#FFFF#,16);
1047
                            Sec_Prot(111 downto 96):= to_slv(16#FFFF#,16);
1048
                            Sec_Prot(95 downto 0) := (others => '0');
1049
                        WHEN "110" =>
1050
                            Sec_Prot(127 downto 112):= to_slv(16#FFFF#,16);
1051
                            Sec_Prot(111 downto 96):= to_slv(16#FFFF#,16);
1052
                            Sec_Prot(95 downto 80):= to_slv(16#FFFF#,16);
1053
                            Sec_Prot(79 downto 64):= to_slv(16#FFFF#,16);
1054
                            Sec_Prot(63 downto 0) := (others => '0');
1055
                        WHEN others =>
1056
                            Sec_Prot := (others => '1');
1057
                    END CASE;
1058
                END IF;
1059
 
1060
            WHEN PAGE_PG       =>
1061
 
1062
                IF oe AND Instruct = RDSR THEN
1063
                    SO_zd <= Status_reg(7-read_cnt);
1064
                    read_cnt := read_cnt + 1;
1065
                    IF read_cnt = 8 THEN
1066
                        read_cnt := 0;
1067
                    END IF;
1068
                END IF;
1069
 
1070
                ADDRHILO_PG(AddrLo, AddrHi, Addr);
1071
                IF (Addr + wr_cnt) > AddrHi THEN
1072
                    wr_cnt := AddrHi - Addr;
1073
                END IF;
1074
 
1075
                FOR I IN Addr TO Addr + wr_cnt LOOP
1076
                    new_int := WData(i-Addr);
1077
                    old_int := Mem(i);
1078
                    IF new_int > -1 THEN
1079
                        new_bit := to_slv(new_int,8);
1080
                        IF old_int > -1 THEN
1081
                            old_bit := to_slv(old_int,8);
1082
                            FOR j IN 0 TO 7 LOOP
1083
                                IF old_bit(j) = '0' THEN
1084
                                    new_bit(j) := '0';
1085
                                END IF;
1086
                            END LOOP;
1087
                            new_int := to_nat(new_bit);
1088
                        END IF;
1089
                        WData(i-Addr) := new_int;
1090
                    ELSE
1091
                        WData(i-Addr) := -1;
1092
                    END IF;
1093
                END LOOP;
1094
 
1095
                FOR I IN Addr TO Addr + wr_cnt LOOP
1096
                     Mem (i) :=  -1;
1097
                END LOOP;
1098
 
1099
                IF PDONE = '1' THEN
1100
                    WIP := '0';
1101
                    WEL := '0';
1102
                    FOR i IN Addr TO Addr + wr_cnt LOOP
1103
                        Mem(i) := WData(i-Addr);
1104
                    END LOOP;
1105
                END IF;
1106
 
1107
            WHEN SECTOR_ER     =>
1108
 
1109
                IF oe AND Instruct = RDSR THEN
1110
                    SO_zd <= Status_reg(7-read_cnt);
1111
                    read_cnt := read_cnt + 1;
1112
                    IF read_cnt = 8 THEN
1113
                        read_cnt := 0;
1114
                    END IF;
1115
                END IF;
1116
 
1117
                ADDRHILO_SEC(AddrLo, AddrHi, Addr);
1118
                FOR i IN AddrLo TO AddrHi LOOP
1119
                    Mem(i) := -1;
1120
                END LOOP;
1121
                IF EDONE = '1' THEN
1122
                    WIP := '0';
1123
                    WEL := '0';
1124
                    FOR i IN AddrLo TO AddrHi LOOP
1125
                        Mem(i) :=  MaxData;
1126
                    END LOOP;
1127
                END IF;
1128
 
1129
            WHEN BULK_ER       =>
1130
 
1131
                IF oe AND Instruct = RDSR THEN
1132
                    SO_zd <= Status_reg(7-read_cnt);
1133
                    read_cnt := read_cnt + 1;
1134
                    IF read_cnt = 8 THEN
1135
                        read_cnt := 0;
1136
                    END IF;
1137
                END IF;
1138
 
1139
                FOR i IN 0 TO AddrRANGE LOOP
1140
                    Mem(i) := -1;
1141
                END LOOP;
1142
                IF EDONE = '1' THEN
1143
                    WIP := '0';
1144
                    WEL := '0';
1145
                    FOR i IN 0 TO AddrRANGE LOOP
1146
                        Mem(i) :=  MaxData;
1147
                    END LOOP;
1148
                END IF;
1149
 
1150
            WHEN DP_DOWN     =>
1151
                IF falling_edge(write) THEN
1152
                    IF Instruct = RES_READ_ES THEN
1153
                        RES_in <= '1';
1154
                    END IF;
1155
                ELSIF oe AND Instruct = RES_READ_ES THEN
1156
                    --Read Electronic Signature
1157
                    data_out := to_slv(ES,8);
1158
                    SO_zd <= data_out(7 - read_cnt);
1159
                    read_cnt := read_cnt + 1;
1160
                    IF read_cnt = 8 THEN
1161
                        read_cnt := 0;
1162
                    END IF;
1163
                END IF;
1164
 
1165
        END CASE;
1166
 
1167
        --Output Disable Control
1168
        IF (CSNeg_ipd = '1') THEN
1169
            SO_zd <= 'Z';
1170
        END IF;
1171
 
1172
END PROCESS Functional;
1173
 
1174
    HOLD_FRAME_ON_SO_ZD : PROCESS( SO_zd, HOLDNeg_ipd)
1175
    BEGIN
1176
        IF (HOLDNeg_ipd = '0') THEN
1177
            SO_z <= 'Z';
1178
        ELSE
1179
            SO_z <= SO_zd;
1180
        END IF;
1181
    END PROCESS HOLD_FRAME_ON_SO_ZD;
1182
 
1183
    ---------------------------------------------------------------------------
1184
    ---- File Read Section - Preload Control
1185
    ---------------------------------------------------------------------------
1186
    MemPreload : PROCESS
1187
 
1188
        -- text file input variables
1189
        FILE mem_file        : text  is  mem_file_name;
1190
        VARIABLE ind         : NATURAL := 0;
1191
        VARIABLE buf         : line;
1192
 
1193
    BEGIN
1194
    ---------------------------------------------------------------------------
1195
    --s25fl016a memory preload file format  -----------------------------------
1196
    ---------------------------------------------------------------------------
1197
    --   /       - comment
1198
    --   @aaaaaa - <aaaaaa> stands for address
1199
    --   dd      - <dd> is byte to be written at Mem(aaaaaa++)
1200
    --             (aaaaaa is incremented at every load)
1201
    --   only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!!
1202
    ---------------------------------------------------------------------------
1203
 
1204
         -- memory preload
1205
        IF (mem_file_name /= "none" AND UserPreload) THEN
1206
            ind := 0;
1207
            Mem := (OTHERS => MaxData);
1208
            WHILE (not ENDFILE (mem_file)) LOOP
1209
                READLINE (mem_file, buf);
1210
                IF buf(1) = '/' THEN
1211
                    NEXT;
1212
                ELSIF buf(1) = '@' THEN
1213
                    ind := h(buf(2 to 7)); --address
1214
                    IF ind > AddrRANGE THEN
1215
                        ASSERT false
1216
                            REPORT "Given preload address is out of" &
1217
                                   "memory address range"
1218
                            SEVERITY warning;
1219
                    END IF;
1220
                ELSE
1221
                    IF ind <= AddrRANGE THEN
1222
                        Mem(ind) := h(buf(1 to 2));
1223
                    END IF;
1224
                    IF ind < AddrRANGE THEN
1225
                        ind := ind + 1;
1226
                    END IF;
1227
                END IF;
1228
            END LOOP;
1229
        END IF;
1230
 
1231
        WAIT;
1232
    END PROCESS MemPreload;
1233
 
1234
    SO_OUT: PROCESS(SO_z)
1235
 
1236
        VARIABLE SO_GlitchData : VitalGlitchDataType;
1237
    BEGIN
1238
        VitalPathDelay01Z (
1239
            OutSignal       => SO,
1240
            OutSignalName   => "SO",
1241
            OutTemp         => SO_z,
1242
            GlitchData      => SO_GlitchData,
1243
            XOn             => XOn,
1244
            MsgOn           => MsgOn,
1245
            Paths           => (
1246
 
1247
                      PathDelay       => VitalExtendtofillDelay(tpd_SCK_SO),
1248
                      PathCondition   => SO_z /= 'Z'),
1249
                1 => (InputChangeTime => CSNeg_ipd'LAST_EVENT,
1250
                      PathDelay       => tpd_CSNeg_SO,
1251
                      PathCondition   => CSNeg_ipd = '1'),
1252
                2 => (InputChangeTime => HOLDNeg_ipd'LAST_EVENT,
1253
                      PathDelay       => tpd_HOLDNeg_SO,
1254
                      PathCondition   => TRUE)
1255
            )
1256
        );
1257
    END PROCESS SO_OUT;
1258
 
1259
    END BLOCK behavior;
1260
END vhdl_behavioral;

powered by: WebSVN 2.1.0

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