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

Subversion Repositories core_arm

[/] [core_arm/] [trunk/] [vhdl/] [tbench/] [mem/] [mt48lc16m16a2.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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