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/] [m25p80.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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