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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
 
2
--*****************************************************************************
3
--
4
-- Micron Semiconductor Products, Inc.
5
--
6
-- Copyright 1997, Micron Semiconductor Products, Inc.
7
-- All rights reserved.
8
--
9
--*****************************************************************************
10
 
11
-- pragma translate_off
12
 
13
library ieee;
14
use ieee.std_logic_1164.ALL;
15
use std.textio.all;
16
 
17
PACKAGE mti_pkg IS
18
 
19
    FUNCTION  To_StdLogic (s : BIT) RETURN STD_LOGIC;
20
    FUNCTION  TO_INTEGER (input : STD_LOGIC) RETURN INTEGER;
21
    FUNCTION  TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER;
22
    FUNCTION  TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER;
23
    PROCEDURE TO_BITVECTOR  (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR);
24
 
25
 
26
END mti_pkg;
27
 
28
PACKAGE BODY mti_pkg IS
29
 
30
    -- Convert BIT to STD_LOGIC
31
    FUNCTION To_StdLogic (s : BIT) RETURN STD_LOGIC IS
32
    BEGIN
33
            CASE s IS
34
                WHEN '0' => RETURN ('0');
35
                WHEN '1' => RETURN ('1');
36
                WHEN OTHERS => RETURN ('0');
37
            END CASE;
38
    END;
39
 
40
    -- Convert STD_LOGIC to INTEGER
41
    FUNCTION  TO_INTEGER (input : STD_LOGIC) RETURN INTEGER IS
42
    VARIABLE result : INTEGER := 0;
43
    VARIABLE weight : INTEGER := 1;
44
    BEGIN
45
        IF input = '1' THEN
46
            result := weight;
47
        ELSE
48
            result := 0;                                            -- if unknowns, default to logic 0
49
        END IF;
50
        RETURN result;
51
    END TO_INTEGER;
52
 
53
    -- Convert BIT_VECTOR to INTEGER
54
    FUNCTION  TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER IS
55
    VARIABLE result : INTEGER := 0;
56
    VARIABLE weight : INTEGER := 1;
57
    BEGIN
58
        FOR i IN input'LOW TO input'HIGH LOOP
59
            IF input(i) = '1' THEN
60
                result := result + weight;
61
            ELSE
62
                result := result + 0;                               -- if unknowns, default to logic 0
63
            END IF;
64
            weight := weight * 2;
65
        END LOOP;
66
        RETURN result;
67
    END TO_INTEGER;
68
 
69
    -- Convert STD_LOGIC_VECTOR to INTEGER
70
    FUNCTION  TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER IS
71
    VARIABLE result : INTEGER := 0;
72
    VARIABLE weight : INTEGER := 1;
73
    BEGIN
74
        FOR i IN input'LOW TO input'HIGH LOOP
75
            IF input(i) = '1' THEN
76
                result := result + weight;
77
            ELSE
78
                result := result + 0;                               -- if unknowns, default to logic 0
79
            END IF;
80
            weight := weight * 2;
81
        END LOOP;
82
        RETURN result;
83
    END TO_INTEGER;
84
 
85
    -- Conver INTEGER to BIT_VECTOR
86
    PROCEDURE  TO_BITVECTOR (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR) IS
87
    VARIABLE work,offset,outputlen,j : INTEGER := 0;
88
    BEGIN
89
        --length of vector
90
        IF output'LENGTH > 32 THEN              --'
91
            outputlen := 32;
92
            offset := output'LENGTH - 32;               --'
93
            IF input >= 0 THEN
94
                FOR i IN offset-1 DOWNTO 0 LOOP
95
                    output(output'HIGH - i) := '0';              --'
96
                END LOOP;
97
            ELSE
98
                FOR i IN offset-1 DOWNTO 0 LOOP
99
                    output(output'HIGH - i) := '1';             --'             
100
                END LOOP;
101
            END IF;
102
        ELSE
103
            outputlen := output'LENGTH;                 --'
104
        END IF;
105
        --positive value
106
        IF (input >= 0) THEN
107
            work := input;
108
            j := outputlen - 1;
109
            FOR i IN 1 to 32 LOOP
110
                IF j >= 0 then
111
                    IF (work MOD 2) = 0 THEN
112
                        output(output'HIGH-j-offset) := '0';             --'
113
                    ELSE
114
                        output(output'HIGH-j-offset) := '1';            --'
115
                    END IF;
116
                END IF;
117
                work := work / 2;
118
                j := j - 1;
119
            END LOOP;
120
            IF outputlen = 32 THEN
121
                output(output'HIGH) := '0';              --'
122
            END IF;
123
        --negative value
124
        ELSE
125
            work := (-input) - 1;
126
            j := outputlen - 1;
127
            FOR i IN 1 TO 32 LOOP
128
                IF j>= 0 THEN
129
                    IF (work MOD 2) = 0 THEN
130
                        output(output'HIGH-j-offset) := '1';            --'
131
                    ELSE
132
                        output(output'HIGH-j-offset) := '0';             --'
133
                    END IF;
134
                END IF;
135
                work := work / 2;
136
                j := j - 1;
137
            END LOOP;
138
            IF outputlen = 32 THEN
139
                output(output'HIGH) := '1';             --'
140
            END IF;
141
        END IF;
142
    END TO_BITVECTOR;
143
 
144
END mti_pkg;
145
 
146
-----------------------------------------------------------------------------------------
147
--
148
--     File Name: MT48LC16M16A2.VHD
149
--       Version: 0.0g
150
--          Date: June 29th, 2000
151
--         Model: Behavioral
152
--     Simulator: Model Technology (PC version 5.3 PE)
153
--
154
--  Dependencies: None
155
--
156
--        Author: Son P. Huynh
157
--         Email: sphuynh@micron.com
158
--         Phone: (208) 368-3825
159
--       Company: Micron Technology, Inc.
160
--   Part Number: MT48LC16M16A2 (4Mb x 16 x 4 Banks)
161
--
162
--   Description: Micron 256Mb SDRAM
163
--
164
--    Limitation: - Doesn't check for 4096-cycle refresh                --'
165
--
166
--          Note: - Set simulator resolution to "ps" accuracy
167
--
168
--    Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY 
169
--                WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY 
170
--                IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
171
--                A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
172
--
173
--                Copyright (c) 1998 Micron Semiconductor Products, Inc.
174
--                All rights researved
175
--
176
--  Rev   Author          Phone         Date        Changes
177
--  ----  ----------------------------  ----------  -------------------------------------
178
--  0.0g  Son Huynh       208-368-3825  06/29/2000  Add Load/Dump memory array
179
--        Micron Technology Inc.                    Modify tWR + tRAS timing check
180
--
181
--  0.0f  Son Huynh       208-368-3825  07/08/1999  Fix tWR = 1 Clk + 7.5 ns (Auto)
182
--        Micron Technology Inc.                    Fix tWR = 15 ns (Manual)
183
--                                                  Fix tRP (Autoprecharge to AutoRefresh)
184
--
185
--  0.0c  Son P. Huynh    208-368-3825  04/08/1999  Fix tWR + tRP in Write with AP
186
--        Micron Technology Inc.                    Fix tRC check in Load Mode Register
187
--
188
--  0.0b  Son P. Huynh    208-368-3825  01/06/1998  Derive from 64Mb SDRAM model
189
--        Micron Technology Inc.
190
--
191
-----------------------------------------------------------------------------------------
192
 
193
LIBRARY STD;
194
    USE STD.TEXTIO.ALL;
195
LIBRARY IEEE;
196
    USE IEEE.STD_LOGIC_1164.ALL;
197
LIBRARY WORK;
198
    USE WORK.MTI_PKG.ALL;
199
    use std.textio.all;
200
 
201
library grlib;
202
use grlib.stdlib.all;
203
library gaisler;
204
use gaisler.sim.all;
205
 
206
ENTITY mt48lc16m16a2 IS
207
    GENERIC (
208
        -- Timing Parameters for -75 (PC133) and CAS Latency = 2
209
        tAC       : TIME    :=  6.0 ns;
210
        tHZ       : TIME    :=  7.0 ns;
211
        tOH       : TIME    :=  2.7 ns;
212
        tMRD      : INTEGER :=  2;          -- 2 Clk Cycles
213
        tRAS      : TIME    := 44.0 ns;
214
        tRC       : TIME    := 66.0 ns;
215
        tRCD      : TIME    := 20.0 ns;
216
        tRP       : TIME    := 20.0 ns;
217
        tRRD      : TIME    := 15.0 ns;
218
        tWRa      : TIME    :=  7.5 ns;     -- A2 Version - Auto precharge mode only (1 Clk + 7.5 ns)
219
        tWRp      : TIME    := 15.0 ns;     -- A2 Version - Precharge mode only (15 ns)
220
 
221
        tAH       : TIME    :=  0.8 ns;
222
        tAS       : TIME    :=  1.5 ns;
223
        tCH       : TIME    :=  2.5 ns;
224
        tCL       : TIME    :=  2.5 ns;
225
        tCK       : TIME    := 10.0 ns;
226
        tDH       : TIME    :=  0.8 ns;
227
        tDS       : TIME    :=  1.5 ns;
228
        tCKH      : TIME    :=  0.8 ns;
229
        tCKS      : TIME    :=  1.5 ns;
230
        tCMH      : TIME    :=  0.8 ns;
231
        tCMS      : TIME    :=  1.5 ns;
232
 
233
        addr_bits : INTEGER := 13;
234
        data_bits : INTEGER := 16;
235
        col_bits  : INTEGER :=  9;
236
        index     : INTEGER :=  0;
237
        fname     : string := "sdram.srec"      -- File to read from
238
    );
239
    PORT (
240
        Dq    : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
241
        Addr  : IN    STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
242
        Ba    : IN    STD_LOGIC_VECTOR := "00";
243
        Clk   : IN    STD_LOGIC := '0';
244
        Cke   : IN    STD_LOGIC := '1';
245
        Cs_n  : IN    STD_LOGIC := '1';
246
        Ras_n : IN    STD_LOGIC := '1';
247
        Cas_n : IN    STD_LOGIC := '1';
248
        We_n  : IN    STD_LOGIC := '1';
249
        Dqm   : IN    STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"
250
    );
251
END mt48lc16m16a2;
252
 
253
ARCHITECTURE behave OF mt48lc16m16a2 IS
254
    TYPE   State       IS (ACT, A_REF, BST, LMR, NOP, PRECH, READ, READ_A, WRITE, WRITE_A, LOAD_FILE, DUMP_FILE);
255
    TYPE   Array4xI    IS ARRAY (3 DOWNTO 0) OF INTEGER;
256
    TYPE   Array4xT    IS ARRAY (3 DOWNTO 0) OF TIME;
257
    TYPE   Array4xB    IS ARRAY (3 DOWNTO 0) OF BIT;
258
    TYPE   Array4x2BV  IS ARRAY (3 DOWNTO 0) OF BIT_VECTOR (1 DOWNTO 0);
259
    TYPE   Array4xCBV  IS ARRAY (4 DOWNTO 0) OF BIT_VECTOR (Col_bits - 1 DOWNTO 0);
260
    TYPE   Array_state IS ARRAY (4 DOWNTO 0) OF State;
261
    SIGNAL Operation : State := NOP;
262
    SIGNAL Mode_reg : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
263
    SIGNAL Active_enable, Aref_enable, Burst_term : BIT := '0';
264
    SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : BIT := '0';
265
    SIGNAL Burst_length_1, Burst_length_2, Burst_length_4, Burst_length_8 : BIT := '0';
266
    SIGNAL Cas_latency_2, Cas_latency_3 : BIT := '0';
267
    SIGNAL Ras_in, Cas_in, We_in : BIT := '0';
268
    SIGNAL Write_burst_mode : BIT := '0';
269
    SIGNAL RAS_clk, Sys_clk, CkeZ : BIT := '0';
270
 
271
    -- Checking internal wires
272
    SIGNAL Pre_chk : BIT_VECTOR (3 DOWNTO 0) := "0000";
273
    SIGNAL Act_chk : BIT_VECTOR (3 DOWNTO 0) := "0000";
274
    SIGNAL Dq_in_chk, Dq_out_chk : BIT := '0';
275
    SIGNAL Bank_chk : BIT_VECTOR (1 DOWNTO 0) := "00";
276
    SIGNAL Row_chk : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
277
    SIGNAL Col_chk : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
278
 
279
BEGIN
280
    -- CS# Decode
281
    WITH Cs_n SELECT
282
        Cas_in <= TO_BIT (Cas_n, '1') WHEN '0',
283
                  '1' WHEN '1',
284
                  '1' WHEN OTHERS;
285
    WITH Cs_n SELECT
286
        Ras_in <= TO_BIT (Ras_n, '1') WHEN '0',
287
                  '1' WHEN '1',
288
                  '1' WHEN OTHERS;
289
    WITH Cs_n SELECT
290
        We_in  <= TO_BIT (We_n,  '1') WHEN '0',
291
                  '1' WHEN '1',
292
                  '1' WHEN OTHERS;
293
 
294
    -- Commands Decode
295
    Active_enable   <= NOT(Ras_in) AND     Cas_in  AND     We_in;
296
    Aref_enable     <= NOT(Ras_in) AND NOT(Cas_in) AND     We_in;
297
    Burst_term      <=     Ras_in  AND     Cas_in  AND NOT(We_in);
298
    Mode_reg_enable <= NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in);
299
    Prech_enable    <= NOT(Ras_in) AND     Cas_in  AND NOT(We_in);
300
    Read_enable     <=     Ras_in  AND NOT(Cas_in) AND     We_in;
301
    Write_enable    <=     Ras_in  AND NOT(Cas_in) AND NOT(We_in);
302
 
303
    -- Burst Length Decode
304
    Burst_length_1  <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND NOT(Mode_reg(0));
305
    Burst_length_2  <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND     Mode_reg(0);
306
    Burst_length_4  <= NOT(Mode_reg(2)) AND     Mode_reg(1)  AND NOT(Mode_reg(0));
307
    Burst_length_8  <= NOT(Mode_reg(2)) AND     Mode_reg(1)  AND     Mode_reg(0);
308
 
309
    -- CAS Latency Decode
310
    Cas_latency_2   <= NOT(Mode_reg(6)) AND     Mode_reg(5)  AND NOT(Mode_reg(4));
311
    Cas_latency_3   <= NOT(Mode_reg(6)) AND     Mode_reg(5)  AND     Mode_reg(4);
312
 
313
    -- Write Burst Mode
314
    Write_burst_mode <= Mode_reg(9);
315
 
316
    -- RAS Clock for checking tWR and tRP
317
    PROCESS
318
        variable Clk0, Clk1 : integer := 0;
319
    begin
320
        RAS_clk <= '1';
321
        wait for 0.5 ns;
322
        RAS_clk <= '0';
323
        wait for 0.5 ns;
324
        if Clk0 > 100 or Clk1 > 100 then
325
            wait;
326
        else
327
            if Clk = '1' and Cke = '1' then
328
                Clk0 := 0;
329
                Clk1 := Clk1 + 1;
330
            elsif Clk = '0' and Cke = '1' then
331
                Clk0 := Clk0 + 1;
332
                Clk1 := 0;
333
            end if;
334
        end if;
335
    END PROCESS;
336
 
337
    -- System Clock
338
    int_clk : PROCESS (Clk)
339
        begin
340
            IF Clk'LAST_VALUE = '0' AND Clk = '1' THEN           --'
341
                CkeZ <= TO_BIT(Cke, '1');
342
            END IF;
343
            Sys_clk <= CkeZ AND TO_BIT(Clk, '0');
344
    END PROCESS;
345
 
346
    state_register : PROCESS
347
        -- NOTE: The extra bits in RAM_TYPE is for checking memory access.  A logic 1 means
348
        --       the location is in use.  This will be checked when doing memory DUMP.
349
        TYPE ram_type IS ARRAY (2**col_bits - 1 DOWNTO 0) OF BIT_VECTOR (data_bits DOWNTO 0);
350
        TYPE ram_pntr IS ACCESS ram_type;
351
        TYPE ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF ram_pntr;
352
        VARIABLE Bank0 : ram_stor;
353
        VARIABLE Bank1 : ram_stor;
354
        VARIABLE Bank2 : ram_stor;
355
        VARIABLE Bank3 : ram_stor;
356
        VARIABLE Row_index, Col_index : INTEGER := 0;
357
        VARIABLE Dq_temp : BIT_VECTOR (data_bits DOWNTO 0) := (OTHERS => '0');
358
 
359
        VARIABLE Col_addr : Array4xCBV;
360
        VARIABLE Bank_addr : Array4x2BV;
361
        VARIABLE Dqm_reg0, Dqm_reg1 : BIT_VECTOR (1 DOWNTO 0) := "00";
362
 
363
        VARIABLE Bank, Previous_bank : BIT_VECTOR (1 DOWNTO 0) := "00";
364
        VARIABLE B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
365
        VARIABLE Col_brst : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
366
        VARIABLE Row : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
367
        VARIABLE Col : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
368
        VARIABLE Burst_counter : INTEGER := 0;
369
 
370
        VARIABLE Command : Array_state;
371
        VARIABLE Bank_precharge : Array4x2BV;
372
        VARIABLE A10_precharge : Array4xB := ('0' & '0' & '0' & '0');
373
        VARIABLE Auto_precharge : Array4xB := ('0' & '0' & '0' & '0');
374
        VARIABLE Read_precharge : Array4xB := ('0' & '0' & '0' & '0');
375
        VARIABLE Write_precharge : Array4xB := ('0' & '0' & '0' & '0');
376
        VARIABLE RW_interrupt_read : Array4xB := ('0' & '0' & '0' & '0');
377
        VARIABLE RW_interrupt_write : Array4xB := ('0' & '0' & '0' & '0');
378
        VARIABLE RW_interrupt_bank : BIT_VECTOR (1 DOWNTO 0) := "00";
379
        VARIABLE Count_time : Array4xT := (0 ns & 0 ns & 0 ns & 0 ns);
380
        VARIABLE Count_precharge : Array4xI := (0 & 0 & 0 & 0);
381
 
382
        VARIABLE Data_in_enable, Data_out_enable : BIT := '0';
383
        VARIABLE Pc_b0, Pc_b1, Pc_b2, Pc_b3 : BIT := '0';
384
        VARIABLE Act_b0, Act_b1, Act_b2, Act_b3 : BIT := '0';
385
 
386
        -- Timing Check
387
        VARIABLE MRD_chk : INTEGER := 0;
388
        VARIABLE WR_counter : Array4xI := (0 & 0 & 0 & 0);
389
        VARIABLE WR_time : Array4xT := (0 ns & 0 ns & 0 ns & 0 ns);
390
        VARIABLE WR_chkp : Array4xT := (0 ns & 0 ns & 0 ns & 0 ns);
391
        VARIABLE RC_chk, RRD_chk : TIME := 0 ns;
392
        VARIABLE RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3 : TIME := 0 ns;
393
        VARIABLE RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3 : TIME := 0 ns;
394
        VARIABLE RP_chk0, RP_chk1, RP_chk2, RP_chk3 : TIME := 0 ns;
395
 
396
        -- Load and Dumb variables
397
        FILE     file_load : TEXT open read_mode is fname;   -- Data load
398
        FILE     file_dump : TEXT open write_mode is "dumpdata.txt";   -- Data dump
399
        VARIABLE bank_load : bit_vector ( 1 DOWNTO 0);
400
        VARIABLE rows_load : BIT_VECTOR (12 DOWNTO 0);
401
        VARIABLE cols_load : BIT_VECTOR ( 8 DOWNTO 0);
402
        VARIABLE data_load : BIT_VECTOR (15 DOWNTO 0);
403
        VARIABLE i, j      : INTEGER;
404
        VARIABLE good_load : BOOLEAN;
405
        VARIABLE l         : LINE;
406
        variable load : std_logic := '1';
407
        variable dump : std_logic := '0';
408
        variable ch   : character;
409
        variable rectype : bit_vector(3 downto 0);
410
        variable recaddr : bit_vector(31 downto 0);
411
        variable reclen : bit_vector(7 downto 0);
412
        variable recdata : bit_vector(0 to 16*8-1);
413
 
414
        -- Initialize empty rows
415
        PROCEDURE Init_mem (Bank : bit_vector (1 DOWNTO 0); Row_index : INTEGER) IS
416
            VARIABLE i, j : INTEGER := 0;
417
        BEGIN
418
            IF Bank = "00" THEN
419
                IF Bank0 (Row_index) = NULL THEN                        -- Check to see if row empty
420
                    Bank0 (Row_index) := NEW ram_type;                  -- Open new row for access
421
                    FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP            -- Filled row with zeros
422
                        FOR j IN (data_bits) DOWNTO 0 LOOP
423
                            Bank0 (Row_index) (i) (j) := '0';
424
                        END LOOP;
425
                    END LOOP;
426
                END IF;
427
            ELSIF Bank = "01" THEN
428
                IF Bank1 (Row_index) = NULL THEN
429
                    Bank1 (Row_index) := NEW ram_type;
430
                    FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
431
                        FOR j IN (data_bits) DOWNTO 0 LOOP
432
                            Bank1 (Row_index) (i) (j) := '0';
433
                        END LOOP;
434
                    END LOOP;
435
                END IF;
436
            ELSIF Bank = "10" THEN
437
                IF Bank2 (Row_index) = NULL THEN
438
                    Bank2 (Row_index) := NEW ram_type;
439
                    FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
440
                        FOR j IN (data_bits) DOWNTO 0 LOOP
441
                            Bank2 (Row_index) (i) (j) := '0';
442
                        END LOOP;
443
                    END LOOP;
444
                END IF;
445
            ELSIF Bank = "11" THEN
446
                IF Bank3 (Row_index) = NULL THEN
447
                    Bank3 (Row_index) := NEW ram_type;
448
                    FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
449
                        FOR j IN (data_bits) DOWNTO 0 LOOP
450
                            Bank3 (Row_index) (i) (j) := '0';
451
                        END LOOP;
452
                    END LOOP;
453
                END IF;
454
            END IF;
455
        END;
456
 
457
        -- Burst Counter
458
        PROCEDURE Burst_decode IS
459
            VARIABLE Col_int : INTEGER := 0;
460
            VARIABLE Col_vec, Col_temp : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
461
        BEGIN
462
            -- Advance Burst Counter
463
            Burst_counter := Burst_counter + 1;
464
 
465
            -- Burst Type
466
            IF Mode_reg (3) = '0' THEN
467
                Col_int := TO_INTEGER(Col);
468
                Col_int := Col_int + 1;
469
                TO_BITVECTOR (Col_int, Col_temp);
470
            ELSIF Mode_reg (3) = '1' THEN
471
                TO_BITVECTOR (Burst_counter, Col_vec);
472
                Col_temp (2) :=  Col_vec (2) XOR Col_brst (2);
473
                Col_temp (1) :=  Col_vec (1) XOR Col_brst (1);
474
                Col_temp (0) :=  Col_vec (0) XOR Col_brst (0);
475
            END IF;
476
 
477
            -- Burst Length
478
            IF Burst_length_2 = '1' THEN
479
                Col (0) := Col_temp (0);
480
            ELSIF Burst_length_4 = '1' THEN
481
                Col (1 DOWNTO 0) := Col_temp (1 DOWNTO 0);
482
            ELSIF Burst_length_8 = '1' THEN
483
                Col (2 DOWNTO 0) := Col_temp (2 DOWNTO 0);
484
            ELSE
485
                Col := Col_temp;
486
            END IF;
487
 
488
            -- Burst Read Single Write
489
            IF Write_burst_mode = '1' AND Data_in_enable = '1' THEN
490
                Data_in_enable := '0';
491
            END IF;
492
 
493
            -- Data counter
494
            IF Burst_length_1 = '1' THEN
495
                IF Burst_counter >= 1 THEN
496
                    IF Data_in_enable = '1' THEN
497
                        Data_in_enable := '0';
498
                    ELSIF Data_out_enable = '1' THEN
499
                        Data_out_enable := '0';
500
                    END IF;
501
                END IF;
502
            ELSIF Burst_length_2 = '1' THEN
503
                IF Burst_counter >= 2 THEN
504
                    IF Data_in_enable = '1' THEN
505
                        Data_in_enable := '0';
506
                    ELSIF Data_out_enable = '1' THEN
507
                        Data_out_enable := '0';
508
                    END IF;
509
                END IF;
510
            ELSIF Burst_length_4 = '1' THEN
511
                IF Burst_counter >= 4 THEN
512
                    IF Data_in_enable = '1' THEN
513
                        Data_in_enable := '0';
514
                    ELSIF Data_out_enable = '1' THEN
515
                        Data_out_enable := '0';
516
                    END IF;
517
                END IF;
518
            ELSIF Burst_length_8 = '1' THEN
519
                IF Burst_counter >= 8 THEN
520
                    IF Data_in_enable = '1' THEN
521
                        Data_in_enable := '0';
522
                    ELSIF Data_out_enable = '1' THEN
523
                        Data_out_enable := '0';
524
                    END IF;
525
                END IF;
526
            END IF;
527
        END;
528
 
529
    BEGIN
530
        WAIT ON Sys_clk, RAS_clk;
531
        IF Sys_clk'event AND Sys_clk = '1' AND Load = '0' AND Dump = '0' THEN             --'
532
            -- Internal Command Pipeline
533
            Command(0) := Command(1);
534
            Command(1) := Command(2);
535
            Command(2) := Command(3);
536
            Command(3) := NOP;
537
 
538
            Col_addr(0) := Col_addr(1);
539
            Col_addr(1) := Col_addr(2);
540
            Col_addr(2) := Col_addr(3);
541
            Col_addr(3) := (OTHERS => '0');
542
 
543
            Bank_addr(0) := Bank_addr(1);
544
            Bank_addr(1) := Bank_addr(2);
545
            Bank_addr(2) := Bank_addr(3);
546
            Bank_addr(3) := "00";
547
 
548
            Bank_precharge(0) := Bank_precharge(1);
549
            Bank_precharge(1) := Bank_precharge(2);
550
            Bank_precharge(2) := Bank_precharge(3);
551
            Bank_precharge(3) := "00";
552
 
553
            A10_precharge(0) := A10_precharge(1);
554
            A10_precharge(1) := A10_precharge(2);
555
            A10_precharge(2) := A10_precharge(3);
556
            A10_precharge(3) := '0';
557
 
558
            -- Operation Decode (Optional for showing current command on posedge clock / debug feature)
559
            IF Active_enable = '1' THEN
560
                Operation <= ACT;
561
            ELSIF Aref_enable = '1' THEN
562
                Operation <= A_REF;
563
            ELSIF Burst_term = '1' THEN
564
                Operation <= BST;
565
            ELSIF Mode_reg_enable = '1' THEN
566
                Operation <= LMR;
567
            ELSIF Prech_enable = '1' THEN
568
                Operation <= PRECH;
569
            ELSIF Read_enable = '1' THEN
570
                IF Addr(10) = '0' THEN
571
                    Operation <= READ;
572
                ELSE
573
                    Operation <= READ_A;
574
                END IF;
575
            ELSIF Write_enable = '1' THEN
576
                IF Addr(10) = '0' THEN
577
                    Operation <= WRITE;
578
                ELSE
579
                    Operation <= WRITE_A;
580
                END IF;
581
            ELSE
582
                Operation <= NOP;
583
            END IF;
584
 
585
            -- Dqm pipeline for Read
586
            Dqm_reg0 := Dqm_reg1;
587
            Dqm_reg1 := TO_BITVECTOR(Dqm);
588
 
589
            -- Read or Write with Auto Precharge Counter
590
            IF Auto_precharge (0) = '1' THEN
591
                Count_precharge (0) := Count_precharge (0) + 1;
592
            END IF;
593
            IF Auto_precharge (1) = '1' THEN
594
                Count_precharge (1) := Count_precharge (1) + 1;
595
            END IF;
596
            IF Auto_precharge (2) = '1' THEN
597
                Count_precharge (2) := Count_precharge (2) + 1;
598
            END IF;
599
            IF Auto_precharge (3) = '1' THEN
600
                Count_precharge (3) := Count_precharge (3) + 1;
601
            END IF;
602
 
603
            -- Auto Precharge Timer for tWR
604
            if (Burst_length_1 = '1' OR Write_burst_mode = '1') then
605
                if (Count_precharge(0) = 1) then
606
                    Count_time(0) := NOW;
607
                end if;
608
                if (Count_precharge(1) = 1) then
609
                    Count_time(1) := NOW;
610
                end if;
611
                if (Count_precharge(2) = 1) then
612
                    Count_time(2) := NOW;
613
                end if;
614
                if (Count_precharge(3) = 1) then
615
                    Count_time(3) := NOW;
616
                end if;
617
            elsif (Burst_length_2 = '1') then
618
                if (Count_precharge(0) = 2) then
619
                    Count_time(0) := NOW;
620
                end if;
621
                if (Count_precharge(1) = 2) then
622
                    Count_time(1) := NOW;
623
                end if;
624
                if (Count_precharge(2) = 2) then
625
                    Count_time(2) := NOW;
626
                end if;
627
                if (Count_precharge(3) = 2) then
628
                    Count_time(3) := NOW;
629
                end if;
630
            elsif (Burst_length_4 = '1') then
631
                if (Count_precharge(0) = 4) then
632
                    Count_time(0) := NOW;
633
                end if;
634
                if (Count_precharge(1) = 4) then
635
                    Count_time(1) := NOW;
636
                end if;
637
                if (Count_precharge(2) = 4) then
638
                    Count_time(2) := NOW;
639
                end if;
640
                if (Count_precharge(3) = 4) then
641
                    Count_time(3) := NOW;
642
                end if;
643
            elsif (Burst_length_8 = '1') then
644
                if (Count_precharge(0) = 8) then
645
                    Count_time(0) := NOW;
646
                end if;
647
                if (Count_precharge(1) = 8) then
648
                    Count_time(1) := NOW;
649
                end if;
650
                if (Count_precharge(2) = 8) then
651
                    Count_time(2) := NOW;
652
                end if;
653
                if (Count_precharge(3) = 8) then
654
                    Count_time(3) := NOW;
655
                end if;
656
            end if;
657
 
658
            -- tMRD Counter
659
            MRD_chk := MRD_chk + 1;
660
 
661
            -- tWR Counter
662
            WR_counter(0) := WR_counter(0) + 1;
663
            WR_counter(1) := WR_counter(1) + 1;
664
            WR_counter(2) := WR_counter(2) + 1;
665
            WR_counter(3) := WR_counter(3) + 1;
666
 
667
 
668
            -- Auto Refresh
669
            IF Aref_enable = '1' THEN
670
                -- Auto Refresh to Auto Refresh
671
                ASSERT (NOW - RC_chk >= tRC)
672
                    REPORT "tRC violation during Auto Refresh"
673
                    SEVERITY WARNING;
674
                -- Precharge to Auto Refresh
675
                ASSERT (NOW - RP_chk0 >= tRP OR NOW - RP_chk1 >= tRP OR NOW - RP_chk2 >= tRP OR NOW - RP_chk3 >= tRP)
676
                    REPORT "tRP violation during Auto Refresh"
677
                    SEVERITY WARNING;
678
                -- All banks must be idle before refresh
679
                IF (Pc_b3 ='0' OR Pc_b2 = '0' OR Pc_b1 ='0' OR Pc_b0 = '0') THEN
680
                    ASSERT (FALSE)
681
                        REPORT "All banks must be Precharge before Auto Refresh"
682
                        SEVERITY WARNING;
683
                END IF;
684
                -- Record current tRC time
685
                RC_chk := NOW;
686
            END IF;
687
 
688
            -- Load Mode Register
689
            IF Mode_reg_enable = '1' THEN
690
                Mode_reg <= TO_BITVECTOR (Addr);
691
                IF (Pc_b3 ='0' OR Pc_b2 = '0' OR Pc_b1 ='0' OR Pc_b0 = '0') THEN
692
                    ASSERT (FALSE)
693
                        REPORT "All bank must be Precharge before Load Mode Register"
694
                        SEVERITY WARNING;
695
                END IF;
696
                -- REF to LMR
697
                ASSERT (NOW - RC_chk >= tRC)
698
                    REPORT "tRC violation during Load Mode Register"
699
                    SEVERITY WARNING;
700
                -- LMR to LMR
701
                ASSERT (MRD_chk >= tMRD)
702
                    REPORT "tMRD violation during Load Mode Register"
703
                    SEVERITY WARNING;
704
                -- Record current tMRD time
705
                MRD_chk := 0;
706
            END IF;
707
 
708
            -- Active Block (latch Bank and Row Address)
709
            IF Active_enable = '1' THEN
710
                IF Ba = "00" AND Pc_b0 = '1' THEN
711
                    Act_b0 := '1';
712
                    Pc_b0 := '0';
713
                    B0_row_addr := TO_BITVECTOR (Addr);
714
                    RCD_chk0 := NOW;
715
                    RAS_chk0 := NOW;
716
                    -- Precharge to Active Bank 0
717
                    ASSERT (NOW - RP_chk0 >= tRP)
718
                        REPORT "tRP violation during Activate Bank 0"
719
                        SEVERITY WARNING;
720
                ELSIF Ba = "01" AND Pc_b1 = '1' THEN
721
                    Act_b1 := '1';
722
                    Pc_b1 := '0';
723
                    B1_row_addr := TO_BITVECTOR (Addr);
724
                    RCD_chk1 := NOW;
725
                    RAS_chk1 := NOW;
726
                    -- Precharge to Active Bank 1
727
                    ASSERT (NOW - RP_chk1 >= tRP)
728
                        REPORT "tRP violation during Activate Bank 1"
729
                        SEVERITY WARNING;
730
                ELSIF Ba = "10" AND Pc_b2 = '1' THEN
731
                    Act_b2 := '1';
732
                    Pc_b2 := '0';
733
                    B2_row_addr := TO_BITVECTOR (Addr);
734
                    RCD_chk2 := NOW;
735
                    RAS_chk2 := NOW;
736
                    -- Precharge to Active Bank 2
737
                    ASSERT (NOW - RP_chk2 >= tRP)
738
                        REPORT "tRP violation during Activate Bank 2"
739
                        SEVERITY WARNING;
740
                ELSIF Ba = "11" AND Pc_b3 = '1' THEN
741
                    Act_b3 := '1';
742
                    Pc_b3 := '0';
743
                    B3_row_addr := TO_BITVECTOR (Addr);
744
                    RCD_chk3 := NOW;
745
                    RAS_chk3 := NOW;
746
                    -- Precharge to Active Bank 3
747
                    ASSERT (NOW - RP_chk3 >= tRP)
748
                        REPORT "tRP violation during Activate Bank 3"
749
                        SEVERITY WARNING;
750
                ELSIF Ba = "00" AND Pc_b0 = '0' THEN
751
                    ASSERT (FALSE)
752
                        REPORT "Bank 0 is not Precharged"
753
                        SEVERITY WARNING;
754
                ELSIF Ba = "01" AND Pc_b1 = '0' THEN
755
                    ASSERT (FALSE)
756
                        REPORT "Bank 1 is not Precharged"
757
                        SEVERITY WARNING;
758
                ELSIF Ba = "10" AND Pc_b2 = '0' THEN
759
                    ASSERT (FALSE)
760
                        REPORT "Bank 2 is not Precharged"
761
                        SEVERITY WARNING;
762
                ELSIF Ba = "11" AND Pc_b3 = '0' THEN
763
                    ASSERT (FALSE)
764
                        REPORT "Bank 3 is not Precharged"
765
                        SEVERITY WARNING;
766
                END IF;
767
                -- Active Bank A to Active Bank B
768
                IF ((Previous_bank /= TO_BITVECTOR (Ba)) AND (NOW - RRD_chk < tRRD)) THEN
769
                    ASSERT (FALSE)
770
                        REPORT "tRRD violation during Activate"
771
                        SEVERITY WARNING;
772
                END IF;
773
                -- LMR to ACT
774
                ASSERT (MRD_chk >= tMRD)
775
                    REPORT "tMRD violation during Activate"
776
                    SEVERITY WARNING;
777
                -- AutoRefresh to Activate
778
                ASSERT (NOW - RC_chk >= tRC)
779
                    REPORT "tRC violation during Activate"
780
                    SEVERITY WARNING;
781
                -- Record variable for checking violation
782
                RRD_chk := NOW;
783
                Previous_bank := TO_BITVECTOR (Ba);
784
            END IF;
785
 
786
            -- Precharge Block
787
            IF Prech_enable = '1' THEN
788
                IF Addr(10) = '1' THEN
789
                    Pc_b0 := '1';
790
                    Pc_b1 := '1';
791
                    Pc_b2 := '1';
792
                    Pc_b3 := '1';
793
                    Act_b0 := '0';
794
                    Act_b1 := '0';
795
                    Act_b2 := '0';
796
                    Act_b3 := '0';
797
                    RP_chk0 := NOW;
798
                    RP_chk1 := NOW;
799
                    RP_chk2 := NOW;
800
                    RP_chk3 := NOW;
801
                    -- Activate to Precharge all banks
802
                    ASSERT ((NOW - RAS_chk0 >= tRAS) OR (NOW - RAS_chk1 >= tRAS))
803
                        REPORT "tRAS violation during Precharge all banks"
804
                        SEVERITY WARNING;
805
                    -- tWR violation check for Write
806
                    IF ((NOW - WR_chkp(0) < tWRp) OR (NOW - WR_chkp(1) < tWRp) OR
807
                        (NOW - WR_chkp(2) < tWRp) OR (NOW - WR_chkp(3) < tWRp)) THEN
808
                        ASSERT (FALSE)
809
                            REPORT "tWR violation during Precharge ALL banks"
810
                            SEVERITY WARNING;
811
                    END IF;
812
                ELSIF Addr(10) = '0' THEN
813
                    IF Ba = "00" THEN
814
                        Pc_b0 := '1';
815
                        Act_b0 := '0';
816
                        RP_chk0 := NOW;
817
                        -- Activate to Precharge bank 0
818
                        ASSERT (NOW - RAS_chk0 >= tRAS)
819
                            REPORT "tRAS violation during Precharge bank 0"
820
                            SEVERITY WARNING;
821
                    ELSIF Ba = "01" THEN
822
                        Pc_b1 := '1';
823
                        Act_b1 := '0';
824
                        RP_chk1 := NOW;
825
                        -- Activate to Precharge bank 1
826
                        ASSERT (NOW - RAS_chk1 >= tRAS)
827
                            REPORT "tRAS violation during Precharge bank 1"
828
                            SEVERITY WARNING;
829
                    ELSIF Ba = "10" THEN
830
                        Pc_b2 := '1';
831
                        Act_b2 := '0';
832
                        RP_chk2 := NOW;
833
                        -- Activate to Precharge bank 2
834
                        ASSERT (NOW - RAS_chk2 >= tRAS)
835
                            REPORT "tRAS violation during Precharge bank 2"
836
                            SEVERITY WARNING;
837
                    ELSIF Ba = "11" THEN
838
                        Pc_b3 := '1';
839
                        Act_b3 := '0';
840
                        RP_chk3 := NOW;
841
                        -- Activate to Precharge bank 3
842
                        ASSERT (NOW - RAS_chk3 >= tRAS)
843
                            REPORT "tRAS violation during Precharge bank 3"
844
                            SEVERITY WARNING;
845
                    END IF;
846
                    -- tWR violation check for Write
847
                    ASSERT (NOW - WR_chkp(TO_INTEGER(Ba)) >= tWRp)
848
                        REPORT "tWR violation during Precharge"
849
                        SEVERITY WARNING;
850
                END IF;
851
                -- Terminate a Write Immediately (if same bank or all banks)
852
                IF (Data_in_enable = '1' AND (Bank = TO_BITVECTOR(Ba) OR Addr(10) = '1')) THEN
853
                    Data_in_enable := '0';
854
                END IF;
855
                -- Precharge Command Pipeline for READ
856
                IF CAS_latency_3 = '1' THEN
857
                    Command(2) := PRECH;
858
                    Bank_precharge(2) := TO_BITVECTOR (Ba);
859
                    A10_precharge(2) := TO_BIT(Addr(10));
860
                ELSIF CAS_latency_2 = '1' THEN
861
                    Command(1) := PRECH;
862
                    Bank_precharge(1) := TO_BITVECTOR (Ba);
863
                    A10_precharge(1) := TO_BIT(Addr(10));
864
                END IF;
865
            END IF;
866
 
867
            -- Burst Terminate
868
            IF Burst_term = '1' THEN
869
                -- Terminate a Write immediately
870
                IF Data_in_enable = '1' THEN
871
                    Data_in_enable := '0';
872
                END IF;
873
                -- Terminate a Read depend on CAS Latency
874
                IF CAS_latency_3 = '1' THEN
875
                    Command(2) := BST;
876
                ELSIF CAS_latency_2 = '1' THEN
877
                    Command(1) := BST;
878
                END IF;
879
            END IF;
880
 
881
            -- Read, Write, Column Latch
882
            IF Read_enable = '1' OR Write_enable = '1' THEN
883
                -- Check to see if bank is open (ACT) for Read or Write
884
                IF ((Ba="00" AND Pc_b0='1') OR (Ba="01" AND Pc_b1='1') OR (Ba="10" AND Pc_b2='1') OR (Ba="11" AND Pc_b3='1')) THEN
885
                    ASSERT (FALSE)
886
                        REPORT "Cannot Read or Write - Bank is not Activated"
887
                        SEVERITY WARNING;
888
                END IF;
889
                -- Activate to Read or Write
890
                IF Ba = "00" THEN
891
                    ASSERT (NOW - RCD_chk0 >= tRCD)
892
                        REPORT "tRCD violation during Read or Write to Bank 0"
893
                        SEVERITY WARNING;
894
                ELSIF Ba = "01" THEN
895
                    ASSERT (NOW - RCD_chk1 >= tRCD)
896
                        REPORT "tRCD violation during Read or Write to Bank 1"
897
                        SEVERITY WARNING;
898
                ELSIF Ba = "10" THEN
899
                    ASSERT (NOW - RCD_chk2 >= tRCD)
900
                        REPORT "tRCD violation during Read or Write to Bank 2"
901
                        SEVERITY WARNING;
902
                ELSIF Ba = "11" THEN
903
                    ASSERT (NOW - RCD_chk3 >= tRCD)
904
                        REPORT "tRCD violation during Read or Write to Bank 3"
905
                        SEVERITY WARNING;
906
                END IF;
907
 
908
                -- Read Command
909
                IF Read_enable = '1' THEN
910
                    -- CAS Latency Pipeline
911
                    IF Cas_latency_3 = '1' THEN
912
                        IF Addr(10) = '1' THEN
913
                            Command(2) := READ_A;
914
                        ELSE
915
                            Command(2) := READ;
916
                        END IF;
917
                        Col_addr (2) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
918
                        Bank_addr (2) := TO_BITVECTOR (Ba);
919
                    ELSIF Cas_latency_2 = '1' THEN
920
                        IF Addr(10) = '1' THEN
921
                            Command(1) := READ_A;
922
                        ELSE
923
                            Command(1) := READ;
924
                        END IF;
925
                        Col_addr (1) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
926
                        Bank_addr (1) := TO_BITVECTOR (Ba);
927
                    END IF;
928
 
929
                    -- Read intterupt a Write (terminate Write immediately)
930
                    IF Data_in_enable = '1' THEN
931
                        Data_in_enable := '0';
932
                    END IF;
933
 
934
                -- Write Command
935
                ELSIF Write_enable = '1' THEN
936
                    IF Addr(10) = '1' THEN
937
                        Command(0) := WRITE_A;
938
                    ELSE
939
                        Command(0) := WRITE;
940
                    END IF;
941
                    Col_addr (0) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
942
                    Bank_addr (0) := TO_BITVECTOR (Ba);
943
 
944
                    -- Write intterupt a Write (terminate Write immediately)
945
                    IF Data_in_enable = '1' THEN
946
                        Data_in_enable := '0';
947
                    END IF;
948
 
949
                    -- Write interrupt a Read (terminate Read immediately)
950
                    IF Data_out_enable = '1' THEN
951
                        Data_out_enable := '0';
952
                    END IF;
953
                END IF;
954
 
955
                -- Interrupt a Write with Auto Precharge
956
                IF Auto_precharge(TO_INTEGER(RW_Interrupt_Bank)) = '1' AND Write_precharge(TO_INTEGER(RW_Interrupt_Bank)) = '1' THEN
957
                    RW_interrupt_write(TO_INTEGER(RW_Interrupt_Bank)) := '1';
958
                END IF;
959
 
960
                -- Interrupt a Read with Auto Precharge
961
                IF Auto_precharge(TO_INTEGER(RW_Interrupt_Bank)) = '1' AND Read_precharge(TO_INTEGER(RW_Interrupt_Bank)) = '1' THEN
962
                    RW_interrupt_read(TO_INTEGER(RW_Interrupt_Bank)) := '1';
963
                END IF;
964
 
965
                -- Read or Write with Auto Precharge
966
                IF Addr(10) = '1' THEN
967
                    Auto_precharge (TO_INTEGER(Ba)) := '1';
968
                    Count_precharge (TO_INTEGER(Ba)) := 0;
969
                    RW_Interrupt_Bank := TO_BitVector(Ba);
970
                    IF Read_enable = '1' THEN
971
                        Read_precharge (TO_INTEGER(Ba)) := '1';
972
                    ELSIF Write_enable = '1' THEN
973
                        Write_precharge (TO_INTEGER(Ba)) := '1';
974
                    END IF;
975
                END IF;
976
            END IF;
977
 
978
            -- Read with AutoPrecharge Calculation
979
            --      The device start internal precharge when:
980
            --          1.  BL/2 cycles after command
981
            --      and 2.  Meet tRAS requirement
982
            --       or 3.  Interrupt by a Read or Write (with or without Auto Precharge)
983
            IF ((Auto_precharge(0) = '1') AND (Read_precharge(0) = '1')) THEN
984
                IF (((NOW - RAS_chk0 >= tRAS) AND
985
                    ((Burst_length_1 = '1' AND Count_precharge(0) >= 1)  OR
986
                     (Burst_length_2 = '1' AND Count_precharge(0) >= 2)  OR
987
                     (Burst_length_4 = '1' AND Count_precharge(0) >= 4)  OR
988
                     (Burst_length_8 = '1' AND Count_precharge(0) >= 8))) OR
989
                     (RW_interrupt_read(0) = '1')) THEN
990
                    Pc_b0 := '1';
991
                    Act_b0 := '0';
992
                    RP_chk0 := NOW;
993
                    Auto_precharge(0) := '0';
994
                    Read_precharge(0) := '0';
995
                    RW_interrupt_read(0) := '0';
996
                END IF;
997
            END IF;
998
            IF ((Auto_precharge(1) = '1') AND (Read_precharge(1) = '1')) THEN
999
                IF (((NOW - RAS_chk1 >= tRAS) AND
1000
                    ((Burst_length_1 = '1' AND Count_precharge(1) >= 1)  OR
1001
                     (Burst_length_2 = '1' AND Count_precharge(1) >= 2)  OR
1002
                     (Burst_length_4 = '1' AND Count_precharge(1) >= 4)  OR
1003
                     (Burst_length_8 = '1' AND Count_precharge(1) >= 8))) OR
1004
                     (RW_interrupt_read(1) = '1')) THEN
1005
                    Pc_b1 := '1';
1006
                    Act_b1 := '0';
1007
                    RP_chk1 := NOW;
1008
                    Auto_precharge(1) := '0';
1009
                    Read_precharge(1) := '0';
1010
                    RW_interrupt_read(1) := '0';
1011
                END IF;
1012
            END IF;
1013
            IF ((Auto_precharge(2) = '1') AND (Read_precharge(2) = '1')) THEN
1014
                IF (((NOW - RAS_chk2 >= tRAS) AND
1015
                    ((Burst_length_1 = '1' AND Count_precharge(2) >= 1)  OR
1016
                     (Burst_length_2 = '1' AND Count_precharge(2) >= 2)  OR
1017
                     (Burst_length_4 = '1' AND Count_precharge(2) >= 4)  OR
1018
                     (Burst_length_8 = '1' AND Count_precharge(2) >= 8))) OR
1019
                     (RW_interrupt_read(2) = '1')) THEN
1020
                    Pc_b2 := '1';
1021
                    Act_b2 := '0';
1022
                    RP_chk2 := NOW;
1023
                    Auto_precharge(2) := '0';
1024
                    Read_precharge(2) := '0';
1025
                    RW_interrupt_read(2) := '0';
1026
                END IF;
1027
            END IF;
1028
            IF ((Auto_precharge(3) = '1') AND (Read_precharge(3) = '1')) THEN
1029
                IF (((NOW - RAS_chk3 >= tRAS) AND
1030
                    ((Burst_length_1 = '1' AND Count_precharge(3) >= 1)  OR
1031
                     (Burst_length_2 = '1' AND Count_precharge(3) >= 2)  OR
1032
                     (Burst_length_4 = '1' AND Count_precharge(3) >= 4)  OR
1033
                     (Burst_length_8 = '1' AND Count_precharge(3) >= 8))) OR
1034
                     (RW_interrupt_read(3) = '1')) THEN
1035
                    Pc_b3 := '1';
1036
                    Act_b3 := '0';
1037
                    RP_chk3 := NOW;
1038
                    Auto_precharge(3) := '0';
1039
                    Read_precharge(3) := '0';
1040
                    RW_interrupt_read(3) := '0';
1041
                END IF;
1042
            END IF;
1043
 
1044
            -- Internal Precharge or Bst
1045
            IF Command(0) = PRECH THEN                          -- PRECH terminate a read if same bank or all banks
1046
                IF Bank_precharge(0) = Bank OR A10_precharge(0) = '1' THEN
1047
                    IF Data_out_enable = '1' THEN
1048
                        Data_out_enable := '0';
1049
                    END IF;
1050
                END IF;
1051
            ELSIF Command(0) = BST THEN                         -- BST terminate a read regardless of bank
1052
                IF Data_out_enable = '1' THEN
1053
                    Data_out_enable := '0';
1054
                END IF;
1055
            END IF;
1056
 
1057
            IF Data_out_enable = '0' THEN
1058
                Dq <= TRANSPORT (OTHERS => 'Z') AFTER tOH;
1059
            END IF;
1060
 
1061
            -- Detect Read or Write Command
1062
            IF Command(0) = READ OR Command(0) = READ_A THEN
1063
                Bank := Bank_addr (0);
1064
                Col := Col_addr (0);
1065
                Col_brst := Col_addr (0);
1066
                IF Bank_addr (0) = "00" THEN
1067
                    Row := B0_row_addr;
1068
                ELSIF Bank_addr (0) = "01" THEN
1069
                    Row := B1_row_addr;
1070
                ELSIF Bank_addr (0) = "10" THEN
1071
                    Row := B2_row_addr;
1072
                ELSE
1073
                    Row := B3_row_addr;
1074
                END IF;
1075
                Burst_counter := 0;
1076
                Data_in_enable := '0';
1077
                Data_out_enable := '1';
1078
            ELSIF Command(0) = WRITE OR Command(0) = WRITE_A THEN
1079
                Bank := Bank_addr(0);
1080
                Col := Col_addr(0);
1081
                Col_brst := Col_addr(0);
1082
                IF Bank_addr (0) = "00" THEN
1083
                    Row := B0_row_addr;
1084
                ELSIF Bank_addr (0) = "01" THEN
1085
                    Row := B1_row_addr;
1086
                ELSIF Bank_addr (0) = "10" THEN
1087
                    Row := B2_row_addr;
1088
                ELSE
1089
                    Row := B3_row_addr;
1090
                END IF;
1091
                Burst_counter := 0;
1092
                Data_in_enable := '1';
1093
                Data_out_enable := '0';
1094
            END IF;
1095
 
1096
            -- DQ (Driver / Receiver)
1097
            Row_index := TO_INTEGER (Row);
1098
            Col_index := TO_INTEGER (Col);
1099
            IF Data_in_enable = '1' THEN
1100
                IF Dqm /= "11" THEN
1101
                    Init_mem (Bank, Row_index);
1102
                    IF Bank = "00" THEN
1103
                        Dq_temp := Bank0 (Row_index) (Col_index);
1104
                        IF Dqm = "01" THEN
1105
                            Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
1106
                        ELSIF Dqm = "10" THEN
1107
                            Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
1108
                        ELSE
1109
                            Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
1110
                        END IF;
1111
                        Bank0 (Row_index) (Col_index) := ('1' & Dq_temp(data_bits - 1 DOWNTO 0));
1112
                    ELSIF Bank = "01" THEN
1113
                        Dq_temp := Bank1 (Row_index) (Col_index);
1114
                        IF Dqm = "01" THEN
1115
                            Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
1116
                        ELSIF Dqm = "10" THEN
1117
                            Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
1118
                        ELSE
1119
                            Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
1120
                        END IF;
1121
                        Bank1 (Row_index) (Col_index) := ('1' & Dq_temp(data_bits - 1 DOWNTO 0));
1122
                    ELSIF Bank = "10" THEN
1123
                        Dq_temp := Bank2 (Row_index) (Col_index);
1124
                        IF Dqm = "01" THEN
1125
                            Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
1126
                        ELSIF Dqm = "10" THEN
1127
                            Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
1128
                        ELSE
1129
                            Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
1130
                        END IF;
1131
                        Bank2 (Row_index) (Col_index) := ('1' & Dq_temp(data_bits - 1 DOWNTO 0));
1132
                    ELSIF Bank = "11" THEN
1133
                        Dq_temp := Bank3 (Row_index) (Col_index);
1134
                        IF Dqm = "01" THEN
1135
                            Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
1136
                        ELSIF Dqm = "10" THEN
1137
                            Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
1138
                        ELSE
1139
                            Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
1140
                        END IF;
1141
                        Bank3 (Row_index) (Col_index) := ('1' & Dq_temp(data_bits - 1 DOWNTO 0));
1142
                    END IF;
1143
                    WR_chkp(TO_INTEGER(Bank)) := NOW;
1144
                    WR_counter(TO_INTEGER(Bank)) := 0;
1145
                END IF;
1146
                Burst_decode;
1147
            ELSIF Data_out_enable = '1' THEN
1148
                IF Dqm_reg0 /= "11" THEN
1149
                    Init_mem (Bank, Row_index);
1150
                    IF Bank = "00" THEN
1151
                        Dq_temp := Bank0 (Row_index) (Col_index);
1152
                        IF Dqm_reg0 = "00" THEN
1153
                            Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
1154
                        ELSIF Dqm_reg0 = "01" THEN
1155
                            Dq (15 DOWNTO 8)  <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
1156
                            Dq (7 DOWNTO 0)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1157
                        ELSIF Dqm_reg0 = "10" THEN
1158
                            Dq (15 DOWNTO 8)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1159
                            Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
1160
                        END IF;
1161
                    ELSIF Bank = "01" THEN
1162
                        Dq_temp := Bank1 (Row_index) (Col_index);
1163
                        IF Dqm_reg0 = "00" THEN
1164
                            Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
1165
                        ELSIF Dqm_reg0 = "01" THEN
1166
                            Dq (15 DOWNTO 8)  <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
1167
                            Dq (7 DOWNTO 0)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1168
                        ELSIF Dqm_reg0 = "10" THEN
1169
                            Dq (15 DOWNTO 8)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1170
                            Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
1171
                        END IF;
1172
                    ELSIF Bank = "10" THEN
1173
                        Dq_temp := Bank2 (Row_index) (Col_index);
1174
                        IF Dqm_reg0 = "00" THEN
1175
                            Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
1176
                        ELSIF Dqm_reg0 = "01" THEN
1177
                            Dq (15 DOWNTO 8)  <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
1178
                            Dq (7 DOWNTO 0)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1179
                        ELSIF Dqm_reg0 = "10" THEN
1180
                            Dq (15 DOWNTO 8)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1181
                            Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
1182
                        END IF;
1183
                    ELSIF Bank = "11" THEN
1184
                        Dq_temp := Bank3 (Row_index) (Col_index);
1185
                        IF Dqm_reg0 = "00" THEN
1186
                            Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
1187
                        ELSIF Dqm_reg0 = "01" THEN
1188
                            Dq (15 DOWNTO 8)  <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
1189
                            Dq (7 DOWNTO 0)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1190
                        ELSIF Dqm_reg0 = "10" THEN
1191
                            Dq (15 DOWNTO 8)  <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
1192
                            Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
1193
                        END IF;
1194
                    END IF;
1195
                ELSE
1196
                      Dq <= TRANSPORT (OTHERS => 'Z') AFTER tHZ;
1197
                END IF;
1198
                Burst_decode;
1199
            END IF;
1200
        ELSIF Sys_clk'event AND Sys_clk = '1' AND Load = '1' AND Dump = '0' THEN                 --'
1201
            Operation <= LOAD_FILE;
1202
            load := '0';
1203
--            ASSERT (FALSE) REPORT "Reading memory array from file.  This operation may take several minutes.  Please wait..."
1204
--                SEVERITY NOTE;
1205
            WHILE NOT endfile(file_load) LOOP
1206
                readline(file_load, l);
1207
                read(l, ch);
1208
                if (ch /= 'S') or (ch /= 's') then
1209
                  hexread(l, rectype);
1210
                  hexread(l, reclen);
1211
                  recaddr := (others => '0');
1212
                  case rectype is
1213
                  when "0001" =>
1214
                    hexread(l, recaddr(15 downto 0));
1215
                  when "0010" =>
1216
                    hexread(l, recaddr(23 downto 0));
1217
                  when "0011" =>
1218
                    hexread(l, recaddr);
1219
                    recaddr(31 downto 24) := (others => '0');
1220
                  when others => next;
1221
                  end case;
1222
                  if true then
1223
                    hexread(l, recdata);
1224
                    Bank_Load := recaddr(25 downto 24);
1225
                    Rows_Load := recaddr(23 downto 11);
1226
                    Cols_Load := recaddr(10 downto 2);
1227
                    Init_Mem (Bank_Load, To_Integer(Rows_Load));
1228
 
1229
                    IF Bank_Load = "00" THEN
1230
                      for i in 0 to 3 loop
1231
                        Bank0 (To_Integer(Rows_Load)) (To_Integer(Cols_Load)+i) := ('1' & recdata(i*32+index to i*32+index+15));
1232
                      end loop;
1233
                    ELSIF Bank_Load = "01" THEN
1234
                      for i in 0 to 3 loop
1235
                        Bank1 (To_Integer(Rows_Load)) (To_Integer(Cols_Load)+i) := ('1' & recdata(i*32+index to i*32+index+15));
1236
                      end loop;
1237
                    ELSIF Bank_Load = "10" THEN
1238
                      for i in 0 to 3 loop
1239
                        Bank2 (To_Integer(Rows_Load)) (To_Integer(Cols_Load)+i) := ('1' & recdata(i*32+index to i*32+index+15));
1240
                      end loop;
1241
                    ELSIF Bank_Load = "11" THEN
1242
                      for i in 0 to 3 loop
1243
                        Bank3 (To_Integer(Rows_Load)) (To_Integer(Cols_Load)+i) := ('1' & recdata(i*32+index to i*32+index+15));
1244
                      end loop;
1245
                    END IF;
1246
 
1247
                  END IF;
1248
                END IF;
1249
            END LOOP;
1250
        ELSIF Sys_clk'event AND Sys_clk = '1' AND Load = '0' AND Dump = '1' THEN                 --'
1251
            Operation <= DUMP_FILE;
1252
            ASSERT (FALSE) REPORT "Writing memory array to file.  This operation may take several minutes.  Please wait..."
1253
                SEVERITY NOTE;
1254
            WRITE (l, string'("# Micron Technology, Inc. (FILE DUMP / MEMORY DUMP)"));          --'
1255
            WRITELINE (file_dump, l);
1256
            WRITE (l, string'("# BA ROWS          COLS      DQ"));              --'
1257
            WRITELINE (file_dump, l);
1258
            WRITE (l, string'("# -- ------------- --------- ----------------"));                --'
1259
            WRITELINE (file_dump, l);
1260
            -- Dumping Bank 0
1261
            FOR i IN 0 TO 2**addr_bits -1 LOOP
1262
                -- Check if ROW is NULL
1263
                IF Bank0 (i) /= NULL THEN
1264
                    For j IN 0 TO 2**col_bits - 1 LOOP
1265
                        -- Check if COL is NULL
1266
                        NEXT WHEN Bank0 (i) (j) (data_bits) = '0';
1267
                        WRITE (l, string'("00"), right, 4);             --'
1268
                        WRITE (l, To_BitVector(Conv_Std_Logic_Vector(i, addr_bits)), right, addr_bits+1);
1269
                        WRITE (l, To_BitVector(Conv_std_Logic_Vector(j, col_bits)), right, col_bits+1);
1270
                        WRITE (l, Bank0 (i) (j) (data_bits -1 DOWNTO 0), right, data_bits+1);
1271
                        WRITELINE (file_dump, l);
1272
                    END LOOP;
1273
                END IF;
1274
            END LOOP;
1275
            -- Dumping Bank 1
1276
            FOR i IN 0 TO 2**addr_bits -1 LOOP
1277
                -- Check if ROW is NULL
1278
                IF Bank1 (i) /= NULL THEN
1279
                    For j IN 0 TO 2**col_bits - 1 LOOP
1280
                        -- Check if COL is NULL
1281
                        NEXT WHEN Bank1 (i) (j) (data_bits) = '0';
1282
                        WRITE (l, string'("01"), right, 4);             --'
1283
                        WRITE (l, To_BitVector(Conv_Std_Logic_Vector(i, addr_bits)), right, addr_bits+1);
1284
                        WRITE (l, To_BitVector(Conv_std_Logic_Vector(j, col_bits)), right, col_bits+1);
1285
                        WRITE (l, Bank1 (i) (j) (data_bits -1 DOWNTO 0), right, data_bits+1);
1286
                        WRITELINE (file_dump, l);
1287
                    END LOOP;
1288
                END IF;
1289
            END LOOP;
1290
            -- Dumping Bank 2
1291
            FOR i IN 0 TO 2**addr_bits -1 LOOP
1292
                -- Check if ROW is NULL
1293
                IF Bank2 (i) /= NULL THEN
1294
                    For j IN 0 TO 2**col_bits - 1 LOOP
1295
                        -- Check if COL is NULL
1296
                        NEXT WHEN Bank2 (i) (j) (data_bits) = '0';
1297
                        WRITE (l, string'("10"), right, 4);             --'
1298
                        WRITE (l, To_BitVector(Conv_Std_Logic_Vector(i, addr_bits)), right, addr_bits+1);
1299
                        WRITE (l, To_BitVector(Conv_std_Logic_Vector(j, col_bits)), right, col_bits+1);
1300
                        WRITE (l, Bank2 (i) (j) (data_bits -1 DOWNTO 0), right, data_bits+1);
1301
                        WRITELINE (file_dump, l);
1302
                    END LOOP;
1303
                END IF;
1304
            END LOOP;
1305
            -- Dumping Bank 3
1306
            FOR i IN 0 TO 2**addr_bits -1 LOOP
1307
                -- Check if ROW is NULL
1308
                IF Bank3 (i) /= NULL THEN
1309
                    For j IN 0 TO 2**col_bits - 1 LOOP
1310
                        -- Check if COL is NULL
1311
                        NEXT WHEN Bank3 (i) (j) (data_bits) = '0';
1312
                        WRITE (l, string'("11"), right, 4);             --'
1313
                        WRITE (l, To_BitVector(Conv_Std_Logic_Vector(i, addr_bits)), right, addr_bits+1);
1314
                        WRITE (l, To_BitVector(Conv_std_Logic_Vector(j, col_bits)), right, col_bits+1);
1315
                        WRITE (l, Bank3 (i) (j) (data_bits -1 DOWNTO 0), right, data_bits+1);
1316
                        WRITELINE (file_dump, l);
1317
                    END LOOP;
1318
                END IF;
1319
            END LOOP;
1320
        END IF;
1321
 
1322
        -- Write with AutoPrecharge Calculation
1323
        --      The device start internal precharge when:
1324
        --          1.  tWR cycles after command
1325
        --      and 2.  Meet tRAS requirement
1326
        --       or 3.  Interrupt by a Read or Write (with or without Auto Precharge)
1327
        IF ((Auto_precharge(0) = '1') AND (Write_precharge(0) = '1')) THEN
1328
            IF (((NOW - RAS_chk0 >= tRAS) AND
1329
               (((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(0) >= 1 AND NOW - Count_time(0) >= tWRa)  OR
1330
                 (Burst_length_2 = '1'                             AND Count_precharge(0) >= 2 AND NOW - Count_time(0) >= tWRa)  OR
1331
                 (Burst_length_4 = '1'                             AND Count_precharge(0) >= 4 AND NOW - Count_time(0) >= tWRa)  OR
1332
                 (Burst_length_8 = '1'                             AND Count_precharge(0) >= 8 AND NOW - Count_time(0) >= tWRa))) OR
1333
                 (RW_interrupt_write(0) = '1' AND WR_counter(0) >= 1 AND NOW - WR_time(0) >= tWRa)) THEN
1334
                Auto_precharge(0) := '0';
1335
                Write_precharge(0) := '0';
1336
                RW_interrupt_write(0) := '0';
1337
                Pc_b0 := '1';
1338
                Act_b0 := '0';
1339
                RP_chk0 := NOW;
1340
                ASSERT FALSE REPORT "Start Internal Precharge Bank 0" SEVERITY NOTE;
1341
            END IF;
1342
        END IF;
1343
        IF ((Auto_precharge(1) = '1') AND (Write_precharge(1) = '1')) THEN
1344
            IF (((NOW - RAS_chk1 >= tRAS) AND
1345
               (((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(1) >= 1 AND NOW - Count_time(1) >= tWRa)  OR
1346
                 (Burst_length_2 = '1'                             AND Count_precharge(1) >= 2 AND NOW - Count_time(1) >= tWRa)  OR
1347
                 (Burst_length_4 = '1'                             AND Count_precharge(1) >= 4 AND NOW - Count_time(1) >= tWRa)  OR
1348
                 (Burst_length_8 = '1'                             AND Count_precharge(1) >= 8 AND NOW - Count_time(1) >= tWRa))) OR
1349
                 (RW_interrupt_write(1) = '1' AND WR_counter(1) >= 1 AND NOW - WR_time(1) >= tWRa)) THEN
1350
                Auto_precharge(1) := '0';
1351
                Write_precharge(1) := '0';
1352
                RW_interrupt_write(1) := '0';
1353
                Pc_b1 := '1';
1354
                Act_b1 := '0';
1355
                RP_chk1 := NOW;
1356
            END IF;
1357
        END IF;
1358
        IF ((Auto_precharge(2) = '1') AND (Write_precharge(2) = '1')) THEN
1359
            IF (((NOW - RAS_chk2 >= tRAS) AND
1360
               (((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(2) >= 1 AND NOW - Count_time(2) >= tWRa)  OR
1361
                 (Burst_length_2 = '1'                             AND Count_precharge(2) >= 2 AND NOW - Count_time(2) >= tWRa)  OR
1362
                 (Burst_length_4 = '1'                             AND Count_precharge(2) >= 4 AND NOW - Count_time(2) >= tWRa)  OR
1363
                 (Burst_length_8 = '1'                             AND Count_precharge(2) >= 8 AND NOW - Count_time(2) >= tWRa))) OR
1364
                 (RW_interrupt_write(2) = '1' AND WR_counter(2) >= 1 AND NOW - WR_time(2) >= tWRa)) THEN
1365
                Auto_precharge(2) := '0';
1366
                Write_precharge(2) := '0';
1367
                RW_interrupt_write(2) := '0';
1368
                Pc_b2 := '1';
1369
                Act_b2 := '0';
1370
                RP_chk2 := NOW;
1371
            END IF;
1372
        END IF;
1373
        IF ((Auto_precharge(3) = '1') AND (Write_precharge(3) = '1')) THEN
1374
            IF (((NOW - RAS_chk3 >= tRAS) AND
1375
               (((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(3) >= 1 AND NOW - Count_time(3) >= tWRa)  OR
1376
                 (Burst_length_2 = '1'                             AND Count_precharge(3) >= 2 AND NOW - Count_time(3) >= tWRa)  OR
1377
                 (Burst_length_4 = '1'                             AND Count_precharge(3) >= 4 AND NOW - Count_time(3) >= tWRa)  OR
1378
                 (Burst_length_8 = '1'                             AND Count_precharge(3) >= 8 AND NOW - Count_time(3) >= tWRa))) OR
1379
                 (RW_interrupt_write(0) = '1' AND WR_counter(0) >= 1 AND NOW - WR_time(3) >= tWRa)) THEN
1380
                Auto_precharge(3) := '0';
1381
                Write_precharge(3) := '0';
1382
                RW_interrupt_write(3) := '0';
1383
                Pc_b3 := '1';
1384
                Act_b3 := '0';
1385
                RP_chk3 := NOW;
1386
            END IF;
1387
        END IF;
1388
 
1389
        -- Checking internal wires (Optional for debug purpose)
1390
        Pre_chk (0) <= Pc_b0;
1391
        Pre_chk (1) <= Pc_b1;
1392
        Pre_chk (2) <= Pc_b2;
1393
        Pre_chk (3) <= Pc_b3;
1394
        Act_chk (0) <= Act_b0;
1395
        Act_chk (1) <= Act_b1;
1396
        Act_chk (2) <= Act_b2;
1397
        Act_chk (3) <= Act_b3;
1398
        Dq_in_chk   <= Data_in_enable;
1399
        Dq_out_chk  <= Data_out_enable;
1400
        Bank_chk    <= Bank;
1401
        Row_chk     <= Row;
1402
        Col_chk     <= Col;
1403
    END PROCESS;
1404
 
1405
 
1406
    -- Clock timing checks
1407
--    Clock_check : PROCESS
1408
--        VARIABLE Clk_low, Clk_high : TIME := 0 ns;
1409
--    BEGIN       
1410
--        WAIT ON Clk;
1411
--        IF (Clk = '1' AND NOW >= 10 ns) THEN
1412
--            ASSERT (NOW - Clk_low >= tCL)
1413
--                REPORT "tCL violation"
1414
--                SEVERITY WARNING;
1415
--            ASSERT (NOW - Clk_high >= tCK)
1416
--                REPORT "tCK violation"
1417
--                SEVERITY WARNING;
1418
--            Clk_high := NOW;
1419
--        ELSIF (Clk = '0' AND NOW /= 0 ns) THEN
1420
--            ASSERT (NOW - Clk_high >= tCH)
1421
--                REPORT "tCH violation"
1422
--                SEVERITY WARNING;
1423
--            Clk_low := NOW;
1424
--        END IF;
1425
--    END PROCESS;    
1426
 
1427
    -- Setup timing checks
1428
    Setup_check : PROCESS
1429
    BEGIN
1430
        wait;
1431
        WAIT ON Clk;
1432
        IF Clk = '1' THEN
1433
            ASSERT(Cke'LAST_EVENT >= tCKS)              --'
1434
                REPORT "CKE Setup time violation -- tCKS"
1435
                SEVERITY WARNING;
1436
            ASSERT(Cs_n'LAST_EVENT >= tCMS)             --'
1437
                REPORT "CS# Setup time violation -- tCMS"
1438
                SEVERITY WARNING;
1439
            ASSERT(Cas_n'LAST_EVENT >= tCMS)            --'
1440
                REPORT "CAS# Setup time violation -- tCMS"
1441
                SEVERITY WARNING;
1442
            ASSERT(Ras_n'LAST_EVENT >= tCMS)            --'
1443
                REPORT "RAS# Setup time violation -- tCMS"
1444
                SEVERITY WARNING;
1445
            ASSERT(We_n'LAST_EVENT >= tCMS)             --'
1446
                REPORT "WE# Setup time violation -- tCMS"
1447
                SEVERITY WARNING;
1448
            ASSERT(Dqm'LAST_EVENT >= tCMS)              --'
1449
                REPORT "Dqm Setup time violation -- tCMS"
1450
                SEVERITY WARNING;
1451
            ASSERT(Addr'LAST_EVENT >= tAS)              --'
1452
                REPORT "ADDR Setup time violation -- tAS"
1453
                SEVERITY WARNING;
1454
            ASSERT(Ba'LAST_EVENT >= tAS)                --'
1455
                REPORT "BA Setup time violation -- tAS"
1456
                SEVERITY WARNING;
1457
            ASSERT(Dq'LAST_EVENT >= tDS)                --'
1458
                REPORT "Dq Setup time violation -- tDS"
1459
                SEVERITY WARNING;
1460
        END IF;
1461
    END PROCESS;
1462
 
1463
    -- Hold timing checks
1464
    Hold_check : PROCESS
1465
    BEGIN
1466
        wait;
1467
        WAIT ON Clk'DELAYED (tCKH), Clk'DELAYED (tCMH), Clk'DELAYED (tAH), Clk'DELAYED (tDH);
1468
        IF Clk'DELAYED (tCKH) = '1' THEN                --'
1469
            ASSERT(Cke'LAST_EVENT > tCKH)               --'
1470
                REPORT "CKE Hold time violation -- tCKH"
1471
                SEVERITY WARNING;
1472
        END IF;
1473
        IF Clk'DELAYED (tCMH) = '1' THEN                --'
1474
            ASSERT(Cs_n'LAST_EVENT > tCMH)              --'
1475
                REPORT "CS# Hold time violation -- tCMH"
1476
                SEVERITY WARNING;
1477
            ASSERT(Cas_n'LAST_EVENT > tCMH)             --'
1478
                REPORT "CAS# Hold time violation -- tCMH"
1479
                SEVERITY WARNING;
1480
            ASSERT(Ras_n'LAST_EVENT > tCMH)             --'
1481
                REPORT "RAS# Hold time violation -- tCMH"
1482
                SEVERITY WARNING;
1483
            ASSERT(We_n'LAST_EVENT > tCMH)              --'
1484
                REPORT "WE# Hold time violation -- tCMH"
1485
                SEVERITY WARNING;
1486
            ASSERT(Dqm'LAST_EVENT > tCMH)               --'
1487
                REPORT "Dqm Hold time violation -- tCMH"
1488
                SEVERITY WARNING;
1489
        END IF;
1490
        IF Clk'DELAYED (tAH) = '1' THEN                 --'
1491
            ASSERT(Addr'LAST_EVENT > tAH)               --'
1492
                REPORT "ADDR Hold time violation -- tAH"
1493
                SEVERITY WARNING;
1494
            ASSERT(Ba'LAST_EVENT > tAH)                 --'
1495
                REPORT "BA Hold time violation -- tAH"
1496
                SEVERITY WARNING;
1497
        END IF;
1498
        IF Clk'DELAYED (tDH) = '1' THEN                 --'
1499
            ASSERT(Dq'LAST_EVENT > tDH)                 --'
1500
                REPORT "Dq Hold time violation -- tDH"
1501
                SEVERITY WARNING;
1502
        END IF;
1503
    END PROCESS;
1504
 
1505
END behave;
1506
 
1507
-- pragma translate_on

powered by: WebSVN 2.1.0

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