- added models

git-svn-id: http://moon:8086/svn/vhdl/trunk@1290 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2015-06-10 19:27:35 +00:00
parent 8eb6b3ff9e
commit 2edaa4d7cb
217 changed files with 152127 additions and 0 deletions
@@ -0,0 +1,242 @@
---------------------------------------------------------------------------------
--COMMAND FORMAT --
-- --
-- write(column address(integer), bank(bit), first data(integer), dqm(bit), cke(bit));--
-- read(column address(integer), bank(bit), dqm(bit), cke(bit)); --
-- active(row address(integer), bank(bit), data bus (integer), dqm(bit), cke(bit));--
-- precharge(bank(bit), data bus(integer), dqm(bit), cke(bit)); --
-- nop(data bus(integer), dqm(bit), cke(bit), cs(bit)); --
-- burst_term(data bus(integer), dqm(bit_vector), cke(bit)); --
-- load_array('1'); --
-- load_mode_reg(register(integer), cke(bit)); --
-- next_cycle(clk); This is used after every command(incl. nop) to clock --
-- at the correct clock frequency entered in the clock --
-- period constant below --
-- unload_array(row_start(integer), row_end(integer), bank(bit)) --
-- load_mode_reg(op_code(integer)) --
-- --
---------------------------------------------------------------------------------
LIBRARY work;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE std.textio.all;
USE work.generate_vectors.all;
ENTITY vector_generate IS
END vector_generate;
ARCHITECTURE vector_generate OF vector_generate IS
SIGNAL stim_done : BOOLEAN := FALSE;
SIGNAL clk : BIT := '0';
CONSTANT clk_start : time := 15 ns;
CONSTANT clk_period : time := 10 ns;
CONSTANT Z : INTEGER := -100;
BEGIN
PROCESS
BEGIN
WAIT UNTIL clk = '1' AND clk'EVENT;
--------------------ENTER COMMANDS BELOW THIS LINE-----------------------------
--******************DO NOT USE -100 FOR A DQ VALUE*************************----
--*******************Z WILL PLACE HI-Z ON THE BUS**************************----
--*******USE next_cycle(clk) FOR ADVANCING TO NEXT CLOCK CYCLE*************----
nop(Z, "00", '1', '1'); -- Always begin with one nop when using Micron's testbench
FOR i IN 1 to 5 LOOP -- You will need 100 us for powerup.
next_cycle(clk); -- I used 5 here just for an example.
nop(Z, "00", '1', '1');
END LOOP;
next_cycle(clk);
precharge('0', 1024, Z, "00", '1'); -- Precharge all banks
FOR i IN 1 to 2 LOOP
next_cycle(clk);
nop(Z, "00", '1', '1');
END LOOP;
next_cycle(clk);
auto_refresh; -- First auto refresh
FOR i IN 1 TO 8 LOOP
next_cycle(clk);
nop(Z, "00", '1', '1');
END LOOP;
next_cycle(clk);
auto_refresh; -- Second auto refresh
FOR i IN 1 TO 8 LOOP
next_cycle(clk);
nop(Z, "00", '1', '1');
END LOOP;
next_cycle(clk);
load_mode_reg(51, '1'); -- Load mode register (lat=3, bl=8, mode=seq)
FOR i IN 1 TO 2 LOOP
next_cycle(clk);
nop(Z, "00", '1', '1');
END LOOP;
-- Alternate bank write access
next_cycle(clk);
active(0, '0', Z, "00", '1'); -- Activate Bank 0, Row 0
next_cycle(clk);
nop(Z, "00", '1', '1');
next_cycle(clk);
nop(Z, "00", '1', '1');
next_cycle(clk);
write(1024, '0', 100, "00", '1'); -- Write Bank 0, Col 0, Data 100 (auto precharge)
next_cycle(clk);
nop (101, "00", '1', '1');
next_cycle(clk);
nop (102, "00", '1', '1');
next_cycle(clk);
nop (103, "00", '1', '1');
next_cycle(clk);
nop (104, "00", '1', '1');
next_cycle(clk);
active(0, '1', 105, "00", '1'); -- Activate Bank 1, Row 0
next_cycle(clk);
nop (106, "00", '1', '1');
next_cycle(clk);
nop (107, "00", '1', '1');
next_cycle(clk);
write(1024, '1', 200, "00", '1'); -- Write Bank 1, Col 0, Data 200 (auto precharge)
next_cycle(clk);
nop (201, "00", '1', '1');
next_cycle(clk);
nop (202, "00", '1', '1');
next_cycle(clk);
nop (203, "00", '1', '1');
next_cycle(clk);
nop (204, "00", '1', '1');
next_cycle(clk);
active(0, '0', 205, "00", '1'); -- Activate Bank 0, Row 0
next_cycle(clk);
nop (206, "00", '1', '1');
next_cycle(clk);
nop (207, "00", '1', '1');
-- Alternate bank read access
next_cycle(clk);
read(1024, '0', "00", '1'); -- Read Bank 0, Col 0 (auto precharge)
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
active(0, '1', Z, "00", '1'); -- Activate Bank 1, Row 0
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
read(1024, '1', "00", '1'); -- Read Bank 1, Col 0 (auto precharge)
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop (Z, "00", '1', '1');
next_cycle(clk);
nop(Z, "00", '1', '1');
next_cycle(clk);
nop(Z, "00", '1', '1');
next_cycle(clk);
nop(Z, "00", '1', '1');
next_cycle(clk);
nop(Z, "00", '1', '1');
stim_done <= TRUE; --always include this line at the end of your stimulus
-------------------------------------------------------------------------------
--*************************************************************************----
END PROCESS;
clock:
PROCESS
VARIABLE done_time : time;
VARIABLE cycle_var : integer := 0;
BEGIN
cycle <= 0;
clk <= '0';
WAIT for clk_start;
WHILE not stim_done loop
clk <= '1';
cycle <= cycle_var;
WAIT for clk_period/2;
cycle_var := cycle_var + 1;
clk <= '0';
WAIT for clk_period/2;
END LOOP;
ASSERT (FALSE)
REPORT "Test Vectors Generated"
SEVERITY note;
WAIT;
END PROCESS;
END;
@@ -0,0 +1,266 @@
LIBRARY ieee;
USE std.textio.ALL;
USE ieee.std_logic_1164.ALL;
PACKAGE io_utils IS
PROCEDURE write_string(l : INOUT line;
value : IN string;
justified : IN side := right;
field : IN width := 0);
TYPE radix IS (binary, octal, decimal, hex);
-- read a number from the line
-- use this if you have hex numbers that are not in VHDL pound-sign format
PROCEDURE read(l : INOUT line; value : OUT integer; radix : IN positive);
-- read a number that might be in VHDL pound-sign format
PROCEDURE read_based(l : INOUT line; value : OUT integer);
PROCEDURE write(l : INOUT line;
value : IN std_logic_vector;
justified : IN side := right;
field : IN width := 0;
base : IN radix;
use_pound : boolean := false);
PROCEDURE write(l : INOUT line;
value : IN integer;
justified : IN side := right;
field : IN width := 0;
base : IN radix;
use_pound : boolean := false);
END io_utils;
PACKAGE BODY io_utils IS
PROCEDURE write_string(l : INOUT line;
value : IN string;
justified : IN side := right;
field : IN width := 0)
IS
BEGIN
write(l, value, justified, field);
END;
PROCEDURE shrink_line(l : INOUT line; pos : integer) IS
VARIABLE tmpl : line;
BEGIN
tmpl := l;
l := NEW string'(tmpl(pos TO tmpl'high));
deallocate(tmpl);
END;
PROCEDURE read(l : INOUT line;
value : OUT integer;
radix : IN positive)
IS
CONSTANT not_digit : integer := -999;
-- convert a character to a value from 0 to 15
FUNCTION digit_value(c : character) RETURN integer IS
BEGIN
IF (c >= '0') AND (c <= '9') THEN
RETURN (character'pos(c) - character'pos('0'));
ELSIF (c >= 'a') AND (c <= 'f') THEN
RETURN (character'pos(c) - character'pos('a') + 10);
ELSIF (c >= 'A') AND (c <= 'F') THEN
RETURN (character'pos(c) - character'pos('A') + 10);
ELSE
RETURN not_digit;
END IF;
END;
-- skip leading white space in the line
PROCEDURE skip_white(VARIABLE l : IN line; pos : OUT integer) IS
BEGIN
pos := l'low;
FOR i IN l'low TO l'high LOOP
CASE l(i) IS
WHEN ' ' | ht =>
pos := i + 1;
WHEN OTHERS =>
EXIT;
END CASE;
END LOOP;
END;
VARIABLE digit : integer;
VARIABLE result : integer := 0;
VARIABLE pos : integer;
BEGIN
-- skip white space
skip_white(l, pos);
-- calculate the value
FOR i IN pos TO l'right LOOP
digit := digit_value(l(i));
EXIT WHEN (digit = not_digit) OR (digit >= radix);
result := result * radix + digit;
pos := i + 1;
END LOOP;
value := result;
-- remove the "used" characters from the line
shrink_line(l, pos);
END;
PROCEDURE read_based(l : INOUT line; value : OUT integer) IS
VARIABLE digit : integer;
VARIABLE num : integer;
VARIABLE base : integer;
BEGIN
read(l, num, 10);
IF (l'length > 1) AND (l(l'left) = '#') THEN
shrink_line(l, l'left+1);
base := num;
read(l, num, base);
IF (l'length >= 1) AND (l(l'left) = '#') THEN
shrink_line(l, l'left+1);
END IF;
END IF;
value := num;
END;
PROCEDURE write(l : INOUT line;
value : IN std_logic_vector;
justified : IN side := right;
field : IN width := 0;
base : IN radix;
use_pound : boolean := false)
IS
FUNCTION to_int(bv : std_logic_vector) RETURN integer
IS
VARIABLE result : integer := 0;
BEGIN
FOR i IN bv'RANGE LOOP
result := result * 2;
IF (bv(i) = '1') THEN
result := result + 1;
END IF;
END LOOP;
RETURN result;
END;
TYPE array_of_widths IS ARRAY(radix) OF natural;
CONSTANT nibble_widths : array_of_widths := (
binary => 1,
octal => 3,
hex => 4,
decimal=> 32);
CONSTANT hex_digit : string(1 TO 16) := "0123456789ABCDEF";
ALIAS input_val : std_logic_vector(value'length DOWNTO 1) IS value;
CONSTANT nibble_width : natural := nibble_widths(base);
CONSTANT result_width : natural := (value'length + nibble_width - 1)/nibble_width;
VARIABLE result : string(1 TO result_width); -- longest possible value
VARIABLE result_pos : positive := 1;
VARIABLE nibble_val : integer;
VARIABLE bitcnt : integer;
BEGIN
IF base = decimal THEN
write(l, to_int(value), justified, field, base, use_pound);
RETURN;
END IF;
bitcnt := value'length MOD nibble_width;
IF (bitcnt = 0) THEN
bitcnt := nibble_width;
END IF;
FOR i IN input_val'RANGE LOOP
nibble_val := nibble_val * 2;
IF (input_val(i) = '1') THEN
nibble_val := nibble_val + 1;
END IF;
bitcnt := bitcnt - 1;
IF (bitcnt = 0) THEN
result(result_pos) := hex_digit(nibble_val + 1);
result_pos := result_pos + 1;
nibble_val := 0;
bitcnt := nibble_width;
END IF;
END LOOP;
write(l, result, justified, field);
END;
PROCEDURE write(l : INOUT line;
value : IN integer;
justified : IN side := right;
field : IN width := 0;
base : IN radix;
use_pound : boolean := false)
IS
FUNCTION to_bv(int : integer) RETURN std_logic_vector
IS
VARIABLE bv : std_logic_vector(32 DOWNTO 1) := (OTHERS => '0');
VARIABLE pos : integer := 0;
VARIABLE tmpval : integer := int;
BEGIN
FOR i IN 1 TO 32 LOOP
pos := pos + 1;
IF (tmpval MOD 2) = 1 THEN
bv(i) := '1';
END IF;
tmpval := tmpval / 2;
EXIT WHEN tmpval = 0;
END LOOP;
RETURN bv(pos DOWNTO 1);
END;
VARIABLE tmp : line;
BEGIN
IF (base = decimal) THEN
IF (use_pound) THEN
write_string(tmp, "10#");
END IF;
write(tmp, value);
IF (use_pound) THEN
write_string(tmp, "#");
END IF;
write(l, tmp.ALL, justified, field);
deallocate(tmp);
ELSE
write(l, to_bv(value), justified, field, base, use_pound);
END IF;
END;
END io_utils;
-- test the hex number reader
--ENTITY test IS END;
--USE std.textio.ALL;
--USE work.io_utils.ALL;
--ARCHITECTURE hex_test OF test IS
--BEGIN
-- PROCESS
-- VARIABLE val : integer;
-- FILE myfile : text IS IN "values";
-- VARIABLE inline : line;
-- VARIABLE outline : line;
-- BEGIN
-- WHILE NOT endfile(myfile) LOOP
-- readline(myfile, inline);
-- write(outline, inline.ALL);
--
-- read_based(inline, val);
-- write_string(outline, " binary: ");
-- write(outline, val, base => binary);
-- write_string(outline, " octal: ");
-- write(outline, val, base => octal);
-- write_string(outline, " decimal: ");
-- write(outline, val, base => decimal);
-- write_string(outline, " hex: ");
-- write(outline, val, base => hex);
-- writeline(output, outline);
-- END LOOP;
-- WAIT;
-- END PROCESS;
--END;
@@ -0,0 +1,907 @@
-----------------------------------------------------------------------------------------
--
-- File Name: MT48LC1M18A1.VHD
-- Version: 0.0c
-- Date: April 20th, 1999
-- Model: Behavioral
-- Simulator: Model Technology VLOG (PC version 5.2e PE)
--
-- Dependencies: None
--
-- Author: Son P. Huynh
-- Email: sphuynh@micron.com
-- Phone: (208) 368-3825
-- Company: Micron Technology, Inc.
-- Part Number: MT48LC1M16A1 (512k x 16 x 2 Banks)
--
-- Description: Micron 16Mb SDRAM
--
-- Limitation: - Doesn't check for 4096-cycle refresh
--
-- Note: - Set simulator resolution to "ps" accuracy
--
-- Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
-- WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
-- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
-- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
--
-- Copyright (c) 1998 Micron Semiconductor Products, Inc.
-- All rights researved
--
-- Rev Author Phone Date Changes
-- ---- ---------------------------- ---------- -------------------------------------
-- 0.0c Son P. Huynh 208-368-3825 04/20/1999 Fix precharge to different bank
-- Micron Technology Inc. terminate current bank
--
-- 0.0b Son P. Huynh 208-368-3825 12/09/1998 Fix some timing check problem
-- Micron Technology Inc. - Improve model functionality
--
-- 0.0a Son P. Huynh 208-368-3825 08/10/1998 First Release
-- Micron Technology Inc. - Simple testbench included
-----------------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE WORK.mti_pkg.ALL;
ENTITY mt48lc1m16a1 IS
GENERIC (
tAC : TIME := 6.0 ns; -- Timing parameter for -10 device
tAH : TIME := 1.0 ns;
tAS : TIME := 3.0 ns;
tCH : TIME := 3.5 ns;
tCL : TIME := 3.5 ns;
tCK : TIME := 10.0 ns;
tDH : TIME := 1.0 ns;
tDS : TIME := 3.0 ns;
tCKH : TIME := 1.0 ns;
tCKS : TIME := 3.0 ns;
tCMH : TIME := 1.0 ns;
tCMS : TIME := 3.0 ns;
tOH : TIME := 2.5 ns;
tHZ : TIME := 6.0 ns;
tMRD : INTEGER := 2;
tRAS : TIME := 60.0 ns;
tRC : TIME := 90.0 ns;
tRCD : TIME := 30.0 ns;
tRP : TIME := 30.0 ns;
tRRD : TIME := 20.0 ns;
tWR : INTEGER := 1;
addr_bits : INTEGER := 11;
data_bits : INTEGER := 16;
col_bits : INTEGER := 8
);
PORT (
Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
Ba : IN STD_LOGIC := '0';
Clk : IN STD_LOGIC := '0';
Cke : IN STD_LOGIC := '0';
Cs_n : IN STD_LOGIC := '1';
Ras_n : IN STD_LOGIC := '0';
Cas_n : IN STD_LOGIC := '0';
We_n : IN STD_LOGIC := '0';
Dqm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"
);
END mt48lc1m16a1;
ARCHITECTURE behave OF mt48lc1m16a1 IS
TYPE State IS (ACT, A_REF, BST, LMR, NOP, PRECH, READ, READ_A, WRITE, WRITE_A);
TYPE Array2xI IS ARRAY (1 DOWNTO 0) OF INTEGER;
TYPE Array2xB IS ARRAY (1 DOWNTO 0) OF BIT;
TYPE Array4xB IS ARRAY (3 DOWNTO 0) OF BIT;
TYPE Array2x2BV IS ARRAY (1 DOWNTO 0) OF BIT_VECTOR (1 DOWNTO 0);
TYPE Array4xCBV IS ARRAY (3 DOWNTO 0) OF BIT_VECTOR (Col_bits - 1 DOWNTO 0);
TYPE Array_state IS ARRAY (3 DOWNTO 0) OF State;
SIGNAL Operation : State := NOP;
SIGNAL Mode_reg : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL Active_enable, Aref_enable, Burst_term : BIT := '0';
SIGNAL Mode_reg_enable, Prech_enable, Read_enable, Write_enable : BIT := '0';
SIGNAL Burst_length_1, Burst_length_2, Burst_length_4, Burst_length_8 : BIT := '0';
SIGNAL Cas_latency_1, Cas_latency_2, Cas_latency_3 : BIT := '0';
SIGNAL Ras_in, Cas_in, We_in : BIT := '0';
SIGNAL Write_burst_mode : BIT := '0';
SIGNAL Sys_clk, CkeZ : BIT := '0';
-- Checking internal wires
SIGNAL Pre_chk : BIT_VECTOR (1 DOWNTO 0) := "00";
SIGNAL Act_chk : BIT_VECTOR (1 DOWNTO 0) := "00";
SIGNAL Dq_in_chk, Dq_out_chk : BIT := '0';
SIGNAL Bank_chk : BIT := '0';
SIGNAL Row_chk : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
SIGNAL Col_chk : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- CS# Decode
WITH Cs_n SELECT
Cas_in <= TO_BIT (Cas_n, '1') WHEN '0',
'1' WHEN '1',
'1' WHEN OTHERS;
WITH Cs_n SELECT
Ras_in <= TO_BIT (Ras_n, '1') WHEN '0',
'1' WHEN '1',
'1' WHEN OTHERS;
WITH Cs_n SELECT
We_in <= TO_BIT (We_n, '1') WHEN '0',
'1' WHEN '1',
'1' WHEN OTHERS;
-- Commands Decode
Active_enable <= NOT(Ras_in) AND Cas_in AND We_in;
Aref_enable <= NOT(Ras_in) AND NOT(Cas_in) AND We_in;
Burst_term <= Ras_in AND Cas_in AND NOT(We_in);
Mode_reg_enable <= NOT(Ras_in) AND NOT(Cas_in) AND NOT(We_in);
Prech_enable <= NOT(Ras_in) AND Cas_in AND NOT(We_in);
Read_enable <= Ras_in AND NOT(Cas_in) AND We_in;
Write_enable <= Ras_in AND NOT(Cas_in) AND NOT(We_in);
-- Burst Length Decode
Burst_length_1 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND NOT(Mode_reg(0));
Burst_length_2 <= NOT(Mode_reg(2)) AND NOT(Mode_reg(1)) AND Mode_reg(0);
Burst_length_4 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND NOT(Mode_reg(0));
Burst_length_8 <= NOT(Mode_reg(2)) AND Mode_reg(1) AND Mode_reg(0);
-- CAS Latency Decode
Cas_latency_1 <= NOT(Mode_reg(6)) AND NOT(Mode_reg(5)) AND Mode_reg(4);
Cas_latency_2 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND NOT(Mode_reg(4));
Cas_latency_3 <= NOT(Mode_reg(6)) AND Mode_reg(5) AND Mode_reg(4);
-- Write Burst Mode
Write_burst_mode <= Mode_reg(9);
-- System Clock
int_clk : PROCESS (Clk)
begin
IF Clk'LAST_VALUE = '0' AND Clk = '1' THEN
CkeZ <= TO_BIT(Cke, '1');
END IF;
Sys_clk <= CkeZ AND TO_BIT(Clk, '0');
END PROCESS;
state_register : PROCESS
TYPE ram_type IS ARRAY (2**col_bits - 1 DOWNTO 0) OF BIT_VECTOR (data_bits - 1 DOWNTO 0);
TYPE ram_pntr IS ACCESS ram_type;
TYPE ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF ram_pntr;
VARIABLE Bank0 : ram_stor;
VARIABLE Bank1 : ram_stor;
VARIABLE Row_index, Col_index : INTEGER := 0;
VARIABLE Dq_temp : BIT_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => '0');
VARIABLE Col_addr : Array4xCBV;
VARIABLE Bank_addr : Array4xB;
VARIABLE Dqm_reg : Array2x2BV;
VARIABLE Bank, Previous_bank : BIT := '0';
VARIABLE B0_row_addr, B1_row_addr : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
VARIABLE Col_brst : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
VARIABLE Row : BIT_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
VARIABLE Col : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
VARIABLE Burst_counter : INTEGER := 0;
VARIABLE Command : Array_state;
VARIABLE A10_precharge, Bank_precharge : Array4xB;
VARIABLE Auto_precharge, Read_precharge, Write_precharge : Array2xB;
VARIABLE Count_precharge : Array2xI;
VARIABLE RW_interrupt_write : BIT := '0';
VARIABLE Data_in_enable, Data_out_enable : BIT := '0';
VARIABLE Pc_b0, Pc_b1 : BIT := '0';
VARIABLE Act_b0, Act_b1 : BIT := '0';
-- Timing Check
VARIABLE MRD_chk : INTEGER := 0;
VARIABLE RC_chk, RRD_chk : TIME := 0 ns;
VARIABLE RAS_chk0, RAS_chk1 : TIME := 0 ns;
VARIABLE RCD_chk0, RCD_chk1 : TIME := 0 ns;
VARIABLE RP_chk, RP_chk0, RP_chk1 : TIME := 0 ns;
VARIABLE WR_chk : Array2xI := (0 & 0);
-- Initialize empty rows
PROCEDURE Init_mem (Bank : BIT; Row_index : INTEGER) IS
VARIABLE i, j : INTEGER := 0;
BEGIN
IF Bank = '0' THEN
IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty
Bank0 (Row_index) := NEW ram_type; -- Open new row for access
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank0 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
ELSIF Bank = '1' THEN
IF Bank1 (Row_index) = NULL THEN
Bank1 (Row_index) := NEW ram_type;
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank1 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
END IF;
END;
-- Burst Counter
PROCEDURE Burst_decode IS
VARIABLE Col_int : INTEGER := 0;
VARIABLE Col_vec, Col_temp : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- Advance Burst Counter
Burst_counter := Burst_counter + 1;
-- Burst Type
IF Mode_reg (3) = '0' THEN
Col_int := TO_INTEGER(Col);
Col_int := Col_int + 1;
TO_BITVECTOR (Col_int, Col_temp);
ELSIF Mode_reg (3) = '1' THEN
TO_BITVECTOR (Burst_counter, Col_vec);
Col_temp (2) := Col_vec (2) XOR Col_brst (2);
Col_temp (1) := Col_vec (1) XOR Col_brst (1);
Col_temp (0) := Col_vec (0) XOR Col_brst (0);
END IF;
-- Burst Length
IF Burst_length_2 = '1' THEN
Col (0) := Col_temp (0);
ELSIF Burst_length_4 = '1' THEN
Col (1 DOWNTO 0) := Col_temp (1 DOWNTO 0);
ELSIF Burst_length_8 = '1' THEN
Col (2 DOWNTO 0) := Col_temp (2 DOWNTO 0);
ELSE
Col := Col_temp;
END IF;
-- Burst Read Single Write
IF Write_burst_mode = '1' AND Data_in_enable = '1' THEN
Data_in_enable := '0';
END IF;
-- Data counter
IF Burst_length_1 = '1' THEN
IF Burst_counter >= 1 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Burst_length_2 = '1' THEN
IF Burst_counter >= 2 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Burst_length_4 = '1' THEN
IF Burst_counter >= 4 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Burst_length_8 = '1' THEN
IF Burst_counter >= 8 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
END IF;
END;
BEGIN
WAIT ON Sys_clk;
IF Sys_clk = '1' THEN
-- Internal Command Pipeline
Command(0) := Command(1);
Command(1) := Command(2);
Command(2) := Command(3);
Command(3) := NOP;
Col_addr(0) := Col_addr(1);
Col_addr(1) := Col_addr(2);
Col_addr(2) := Col_addr(3);
Col_addr(3) := (OTHERS => '0');
Bank_addr(0) := Bank_addr(1);
Bank_addr(1) := Bank_addr(2);
Bank_addr(2) := Bank_addr(3);
Bank_addr(3) := '0';
Bank_precharge(0) := Bank_precharge(1);
Bank_precharge(1) := Bank_precharge(2);
Bank_precharge(2) := Bank_precharge(3);
Bank_precharge(3) := '0';
A10_precharge(0) := A10_precharge(1);
A10_precharge(1) := A10_precharge(2);
A10_precharge(2) := A10_precharge(3);
A10_precharge(3) := '0';
-- Operation Decode
IF Active_enable = '1' THEN
Operation <= ACT;
ELSIF Aref_enable = '1' THEN
Operation <= A_REF;
ELSIF Burst_term = '1' THEN
Operation <= BST;
ELSIF Mode_reg_enable = '1' THEN
Operation <= LMR;
ELSIF Prech_enable = '1' THEN
Operation <= PRECH;
ELSIF Read_enable = '1' THEN
IF Addr(10) = '0' THEN
Operation <= READ;
ELSE
Operation <= READ_A;
END IF;
ELSIF Write_enable = '1' THEN
IF Addr(10) = '0' THEN
Operation <= WRITE;
ELSE
Operation <= WRITE_A;
END IF;
ELSE
Operation <= NOP;
END IF;
-- Dqm pipeline for Read
Dqm_reg(0) := Dqm_reg(1);
Dqm_reg(1) := TO_BITVECTOR(Dqm);
-- Read or Write with Auto Precharge Counter
IF Auto_precharge (0) = '1' THEN
Count_precharge (0) := Count_precharge (0) + 1;
END IF;
IF Auto_precharge (1) = '1' THEN
Count_precharge (1) := Count_precharge (1) + 1;
END IF;
-- tMRD Counter
MRD_chk := MRD_chk + 1;
-- tWR Counter
WR_chk(0) := WR_chk(0) + 1;
WR_chk(1) := WR_chk(1) + 1;
-- Auto Refresh
IF Aref_enable = '1' THEN
-- Auto Refresh to Auto Refresh
ASSERT (NOW - RC_chk >= tRC)
REPORT "tRC violation during Auto Refresh"
SEVERITY WARNING;
-- Precharge to Auto Refresh
ASSERT (NOW - RP_chk >= tRP)
REPORT "tRP violation during Auto Refresh"
SEVERITY WARNING;
-- Banks must be idle before Refresh
IF Pc_b1 = '0' OR Pc_b0 = '0' THEN
ASSERT (FALSE)
REPORT "All banks must be Precharge before Auto Refresh"
SEVERITY WARNING;
END IF;
-- Record current tRC time
RC_chk := NOW;
END IF;
-- Load Mode Register
IF Mode_reg_enable = '1' THEN
Mode_reg <= TO_BITVECTOR (Addr);
IF (Pc_b0 /= '1' OR Pc_b1 /= '1') THEN
ASSERT (FALSE)
REPORT "All bank must be Precharge before Load Mode Register"
SEVERITY WARNING;
END IF;
-- REF to LMR
ASSERT (RC_chk >= tRC)
REPORT "tRC violation during Load Mode Register"
SEVERITY WARNING;
-- LMR to LMR
ASSERT (MRD_chk >= tMRD)
REPORT "tMRD violation during Load Mode Register"
SEVERITY WARNING;
-- Record current tMRD time
MRD_chk := 0;
END IF;
-- Active Block (latch Bank and Row Address)
IF Active_enable = '1' THEN
IF Ba = '0' AND Pc_b0 = '1' THEN
Act_b0 := '1';
Pc_b0 := '0';
B0_row_addr := TO_BITVECTOR (Addr);
RCD_chk0 := NOW;
RAS_chk0 := NOW;
-- Precharge to Active Bank 0
ASSERT (NOW - RP_chk0 >= tRP)
REPORT "tRP violation during Activate Bank 0"
SEVERITY WARNING;
ELSIF Ba = '1' AND Pc_b1 = '1' THEN
Act_b1 := '1';
Pc_b1 := '0';
B1_row_addr := TO_BITVECTOR (Addr);
RCD_chk1 := NOW;
RAS_chk1 := NOW;
-- Precharge to Active Bank 1
ASSERT (NOW - RP_chk1 >= tRP)
REPORT "tRP violation during Activate Bank 1"
SEVERITY WARNING;
ELSIF Ba = '0' AND Pc_b0 = '0' THEN
ASSERT (FALSE)
REPORT "Bank 0 is not Precharged"
SEVERITY WARNING;
ELSIF Ba = '1' AND Pc_b1 = '0' THEN
ASSERT (FALSE)
REPORT "Bank 1 is not Precharged"
SEVERITY WARNING;
END IF;
-- Active Bank A to Active Bank B
IF (Previous_bank /= TO_BIT(Ba)) AND (NOW - RRD_chk < tRRD) THEN
ASSERT (FALSE)
REPORT "tRRD violation during activate"
SEVERITY WARNING;
END IF;
-- LMR to ACT
ASSERT (MRD_chk >= tMRD)
REPORT "tMRD violation during Activate"
SEVERITY WARNING;
-- AutoRefresh to Activate
ASSERT (NOW - RC_chk >= tRC)
REPORT "tRC violation during Activate"
SEVERITY WARNING;
-- Record current Bank and RRD_chk
Previous_bank := TO_BIT(Ba);
RRD_chk := NOW;
END IF;
-- Precharge Block
IF Prech_enable = '1' THEN
IF Addr(10) = '1' THEN
Pc_b0 := '1';
Pc_b1 := '1';
Act_b0 := '0';
Act_b1 := '0';
RP_chk0 := NOW;
RP_chk1 := NOW;
-- Activate to Precharge all banks
ASSERT ((NOW - RAS_chk0 >= tRAS) OR (NOW - RAS_chk1 >= tRAS))
REPORT "tRAS violation during Precharge all banks"
SEVERITY WARNING;
-- tWR violation check for Write
IF ((WR_chk(0) < tWR) AND (WR_chk(1) < tWR)) THEN
ASSERT (FALSE)
REPORT "tWR violation during Precharge all banks"
SEVERITY WARNING;
END IF;
ELSIF Addr(10) = '0' THEN
IF Ba = '0' THEN
Pc_b0 := '1';
Act_b0 := '0';
RP_chk0 := NOW;
-- Activate to Precharge bank 0
ASSERT (NOW - RAS_chk0 >= tRAS)
REPORT "tRAS violation during Precharge bank 0"
SEVERITY WARNING;
ELSIF Ba = '1' THEN
Pc_b1 := '1';
Act_b1 := '0';
RP_chk1 := NOW;
-- Activate to Precharge bank 1
ASSERT (NOW - RAS_chk1 >= tRAS)
REPORT "tRAS violation during Precharge bank 1"
SEVERITY WARNING;
END IF;
-- tWR violation check for Write
IF (WR_chk(TO_INTEGER(Ba)) < tWR) THEN
ASSERT (FALSE)
REPORT "tWR violation during Precharge"
SEVERITY WARNING;
END IF;
END IF;
-- Terminate a Write Immediately (if same bank or all banks)
IF (Data_in_enable = '1' AND (Bank = TO_BIT(Ba) OR Addr(10) = '1')) THEN
Data_in_enable := '0';
END IF;
-- Precharge Command Pipeline for READ
IF CAS_latency_3 = '1' THEN
Command(2) := PRECH;
Bank_precharge(2) := TO_BIT (Ba);
A10_precharge(2) := TO_BIT (Addr(10));
ELSIF CAS_latency_2 = '1' THEN
Command(1) := PRECH;
Bank_precharge(1) := TO_BIT (Ba);
A10_precharge(1) := TO_BIT (Addr(10));
ELSIF CAS_latency_1 = '1' THEN
Command(0) := PRECH;
Bank_precharge(0) := TO_BIT (Ba);
A10_precharge(0) := TO_BIT (Addr(10));
END IF;
-- Record Precharge Bank and Current tRP time
RP_chk := NOW;
END IF;
-- Burst Terminate
IF Burst_term = '1' THEN
IF CAS_latency_3 = '1' THEN
Command(2) := BST;
ELSIF CAS_latency_2 = '1' THEN
Command(1) := BST;
ELSIF CAS_latency_1 = '1' THEN
Command(0) := BST;
END IF;
END IF;
-- Read, Write, Column Latch
IF Read_enable = '1' OR Write_enable = '1' THEN
-- Check to see if bank is open (ACT) for Read or Write
IF ((Ba = '0' AND Pc_b0 = '1') OR (Ba = '1' AND Pc_b1 = '1')) THEN
ASSERT (FALSE)
REPORT "Cannot Read or Write - Bank is not Activated"
SEVERITY WARNING;
END IF;
-- Activate to Read or Write
IF Ba = '0' THEN
ASSERT (NOW - RCD_chk0 >= tRCD)
REPORT "tRCD violation during Read or Write to Bank 0"
SEVERITY WARNING;
ELSIF Ba = '1' THEN
ASSERT (NOW - RCD_chk1 >= tRCD)
REPORT "tRCD violation during Read or Write to Bank 1"
SEVERITY WARNING;
END IF;
-- Read Command
IF Read_enable = '1' THEN
-- Read Terminate a Write Immediately
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
RW_interrupt_write := '1';
END IF;
-- CAS Latency Pipeline
IF Cas_latency_3 = '1' THEN
IF Addr(10) = '1' THEN
Command(2) := READ_A;
ELSE
Command(2) := READ;
END IF;
Col_addr (2) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
Bank_addr (2) := TO_BIT (Ba);
ELSIF Cas_latency_2 = '1' THEN
IF Addr(10) = '1' THEN
Command(1) := READ_A;
ELSE
Command(1) := READ;
END IF;
Col_addr (1) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
Bank_addr (1) := TO_BIT (Ba);
ELSIF Cas_latency_1 = '1' THEN
IF Addr(10) = '1' THEN
Command(0) := READ_A;
ELSE
Command(0) := READ;
END IF;
Col_addr (0) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
Bank_addr (0) := TO_BIT (Ba);
END IF;
-- Write Command
ELSIF Write_enable = '1' THEN
IF Addr(10) = '1' THEN
Command(0) := WRITE_A;
ELSE
Command(0) := WRITE;
END IF;
Col_addr (0) := TO_BITVECTOR (Addr(col_bits - 1 DOWNTO 0));
Bank_addr (0) := TO_BIT (Ba);
IF Data_in_enable = '1' THEN
RW_interrupt_write := '1';
END IF;
END IF;
-- Read or Write with Auto Precharge
IF Addr(10) = '1' THEN
Auto_precharge (TO_INTEGER(Ba)) := '1';
Count_precharge (TO_INTEGER(Ba)) := 0;
IF Read_enable = '1' THEN
Read_precharge (TO_INTEGER(Ba)) := '1';
ELSIF Write_enable = '1' THEN
Write_precharge (TO_INTEGER(Ba)) := '1';
END IF;
END IF;
END IF;
-- Read with AutoPrecharge Calculation
-- The device start internal precharge when:
-- 1. BL/2 cycles after command
-- and 2. Meet tRAS requirement
-- or 3. Interrupt by a Read or Write (with or without Auto Precharge)
IF ((Auto_precharge(0) = '1') AND (Read_precharge(0) = '1')) THEN
IF (((NOW - RAS_chk0 >= tRAS) AND
((Burst_length_1 = '1' AND Count_precharge(0) >= 1) OR
(Burst_length_2 = '1' AND Count_precharge(0) >= 2) OR
(Burst_length_4 = '1' AND Count_precharge(0) >= 4) OR
(Burst_length_8 = '1' AND Count_precharge(0) >= 8))) OR
((Read_enable = '1' OR Write_enable = '1') AND Count_precharge(0) >= 1)) THEN
Pc_b0 := '1';
Act_b0 := '0';
RP_chk0 := NOW;
Auto_precharge(0) := '0';
Read_precharge(0) := '0';
Write_precharge(0) := '0';
END IF;
END IF;
IF ((Auto_precharge(1) = '1') AND (Read_precharge(1) = '1')) THEN
IF (((NOW - RAS_chk1 >= tRAS) AND
((Burst_length_1 = '1' AND Count_precharge(1) >= 1) OR
(Burst_length_2 = '1' AND Count_precharge(1) >= 2) OR
(Burst_length_4 = '1' AND Count_precharge(1) >= 4) OR
(Burst_length_8 = '1' AND Count_precharge(1) >= 8))) OR
((Read_enable = '1' OR Write_enable = '1') AND Count_precharge(1) >= 1)) THEN
Pc_b1 := '1';
Act_b1 := '0';
RP_chk1 := NOW;
Auto_precharge(1) := '0';
Read_precharge(1) := '0';
Write_precharge(1) := '0';
END IF;
END IF;
-- Write with AutoPrecharge Calculation
-- The device start internal precharge when:
-- 1. tWR cycles after command
-- and 2. Meet tRAS requirement
-- or 3. Interrupt by a Read or Write (with or without Auto Precharge)
IF ((Auto_precharge(0) = '1') AND (Write_precharge(0) = '1')) THEN
IF (((NOW - RAS_chk0 >= tRAS) AND
(((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(0) >= 1) OR
(Burst_length_2 = '1' AND Count_precharge(0) >= 2) OR
(Burst_length_4 = '1' AND Count_precharge(0) >= 4) OR
(Burst_length_8 = '1' AND Count_precharge(0) >= 8))) OR
(RW_interrupt_write = '1' AND WR_chk(0) >= 1)) THEN
Pc_b0 := '1';
Act_b0 := '0';
RP_chk0 := NOW;
Auto_precharge(0) := '0';
Read_precharge(0) := '0';
Write_precharge(0) := '0';
RW_interrupt_write := '0';
END IF;
END IF;
IF ((Auto_precharge(1) = '1') AND (Write_precharge(1) = '1')) THEN
IF (((NOW - RAS_chk1 >= tRAS) AND
(((Burst_length_1 = '1' OR Write_burst_mode = '1' ) AND Count_precharge(1) >= 1) OR
(Burst_length_2 = '1' AND Count_precharge(1) >= 2) OR
(Burst_length_4 = '1' AND Count_precharge(1) >= 4) OR
(Burst_length_8 = '1' AND Count_precharge(1) >= 8))) OR
(RW_interrupt_write = '1' AND WR_chk(1) >= 1)) THEN
Pc_b1 := '1';
Act_b1 := '0';
RP_chk1 := NOW;
Auto_precharge(1) := '0';
Read_precharge(1) := '0';
Write_precharge(1) := '0';
RW_interrupt_write := '0';
END IF;
END IF;
-- Internal Precharge or Bst
IF Command(0) = PRECH THEN
IF Bank_precharge(0) = Bank OR A10_precharge(0) = '1' THEN
IF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Command(0) = BST THEN
IF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
IF Data_out_enable = '0' THEN
Dq <= TRANSPORT (OTHERS => 'Z') AFTER tOH;
END IF;
-- Detect Read or Write Command
IF Command(0) = READ OR Command(0) = READ_A THEN
Bank := Bank_addr (0);
Col := Col_addr (0);
Col_brst := Col_addr (0);
IF Bank_addr (0) = '0' THEN
Row := B0_row_addr;
ELSE
Row := B1_row_addr;
END IF;
Burst_counter := 0;
Data_in_enable := '0';
Data_out_enable := '1';
ELSIF Command(0) = WRITE OR Command(0) = WRITE_A THEN
Bank := Bank_addr(0);
Col := Col_addr(0);
Col_brst := Col_addr(0);
IF Bank_addr (0) = '0' THEN
Row := B0_row_addr;
ELSE
Row := B1_row_addr;
END IF;
Burst_counter := 0;
Data_in_enable := '1';
Data_out_enable := '0';
END IF;
-- DQ (Driver / Receiver)
Row_index := TO_INTEGER (Row);
Col_index := TO_INTEGER (Col);
IF Data_in_enable = '1' THEN
IF Dqm /= "11" THEN
Init_mem (Bank, Row_index);
IF Bank = '0' THEN
Dq_temp := Bank0 (Row_index) (Col_index);
IF Dqm = "01" THEN
Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
ELSIF Dqm = "10" THEN
Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
ELSE
Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
END IF;
Bank0 (Row_index) (Col_index) := Dq_temp;
ELSIF Bank = '1' THEN
Dq_temp := Bank1 (Row_index) (Col_index);
IF Dqm = "01" THEN
Dq_temp (15 DOWNTO 8) := TO_BITVECTOR (Dq (15 DOWNTO 8));
ELSIF Dqm = "10" THEN
Dq_temp (7 DOWNTO 0) := TO_BITVECTOR (Dq (7 DOWNTO 0));
ELSE
Dq_temp (15 DOWNTO 0) := TO_BITVECTOR (Dq (15 DOWNTO 0));
END IF;
Bank1 (Row_index) (Col_index) := Dq_temp;
END IF;
WR_chk(TO_INTEGER(Bank)) := 0;
END IF;
Burst_decode;
ELSIF Data_out_enable = '1' THEN
Init_mem (Bank, Row_index);
IF Bank = '0' THEN
Dq_temp (15 DOWNTO 0) := Bank0 (Row_index) (Col_index);
IF Dqm_reg(0) = "00" THEN
Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
ELSIF Dqm_reg(0) = "01" THEN
Dq (15 DOWNTO 8) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
Dq (7 DOWNTO 0) <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
ELSIF Dqm_reg(0) = "10" THEN
Dq (15 DOWNTO 8) <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
ELSE
Dq <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
END IF;
ELSIF Bank = '1' THEN
Dq_temp (15 DOWNTO 0) := Bank1 (Row_index) (Col_index);
IF Dqm_reg(0) = "00" THEN
Dq (15 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 0)) AFTER tAC;
ELSIF Dqm_reg(0) = "01" THEN
Dq (15 DOWNTO 8) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (15 DOWNTO 8)) AFTER tAC;
Dq (7 DOWNTO 0) <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
ELSIF Dqm_reg(0) = "10" THEN
Dq (15 DOWNTO 8) <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
Dq (7 DOWNTO 0) <= TRANSPORT TO_STDLOGICVECTOR (Dq_temp (7 DOWNTO 0)) AFTER tAC;
ELSE
Dq <= TRANSPORT (OTHERS => 'Z') AFTER tAC;
END IF;
END IF;
Burst_decode;
END IF;
-- Checking internal wires
Pre_chk (0) <= Pc_b0;
Pre_chk (1) <= Pc_b1;
Act_chk (0) <= Act_b0;
Act_chk (1) <= Act_b1;
Dq_in_chk <= Data_in_enable;
Dq_out_chk <= Data_out_enable;
Bank_chk <= Bank;
Row_chk <= Row;
Col_chk <= Col;
END IF;
END PROCESS;
-- Clock timing checks
Clock_check : PROCESS
VARIABLE Clk_low, Clk_high : TIME := 0 ns;
BEGIN
WAIT ON Clk;
IF (Clk = '1' AND NOW >= 10 ns) THEN
ASSERT (NOW - Clk_low >= tCL)
REPORT "tCL violation"
SEVERITY WARNING;
ASSERT (NOW - Clk_high >= tCK)
REPORT "tCK violation"
SEVERITY WARNING;
Clk_high := NOW;
ELSIF (Clk = '0' AND NOW /= 0 ns) THEN
ASSERT (NOW - Clk_high >= tCH)
REPORT "tCH violation"
SEVERITY WARNING;
Clk_low := NOW;
END IF;
END PROCESS;
-- Setup timing checks
Setup_check : PROCESS
BEGIN
WAIT ON Clk;
IF Clk = '1' THEN
ASSERT(Cke'LAST_EVENT >= tCKS)
REPORT "CKE Setup time violation -- tCKS"
SEVERITY WARNING;
ASSERT(Cs_n'LAST_EVENT >= tCMS)
REPORT "CS# Setup time violation -- tCMS"
SEVERITY WARNING;
ASSERT(Cas_n'LAST_EVENT >= tCMS)
REPORT "CAS# Setup time violation -- tCMS"
SEVERITY WARNING;
ASSERT(Ras_n'LAST_EVENT >= tCMS)
REPORT "RAS# Setup time violation -- tCMS"
SEVERITY WARNING;
ASSERT(We_n'LAST_EVENT >= tCMS)
REPORT "WE# Setup time violation -- tCMS"
SEVERITY WARNING;
ASSERT(Dqm'LAST_EVENT >= tCMS)
REPORT "Dqm Setup time violation -- tCMS"
SEVERITY WARNING;
ASSERT(Addr'LAST_EVENT >= tAS)
REPORT "ADDR Setup time violation -- tAS"
SEVERITY WARNING;
ASSERT(Ba'LAST_EVENT >= tAS)
REPORT "BA Setup time violation -- tAS"
SEVERITY WARNING;
ASSERT(Dq'LAST_EVENT >= tDS)
REPORT "Dq Setup time violation -- tDS"
SEVERITY WARNING;
END IF;
END PROCESS;
-- Hold timing checks
Hold_check : PROCESS
BEGIN
WAIT ON Clk'DELAYED (tCKH), Clk'DELAYED (tCMH), Clk'DELAYED (tAH), Clk'DELAYED (tDH);
IF Clk'DELAYED (tCKH) = '1' THEN
ASSERT(Cke'LAST_EVENT > tCKH)
REPORT "CKE Hold time violation -- tCKH"
SEVERITY WARNING;
END IF;
IF Clk'DELAYED (tCMH) = '1' THEN
ASSERT(Cs_n'LAST_EVENT > tCMH)
REPORT "CS# Hold time violation -- tCMH"
SEVERITY WARNING;
ASSERT(Cas_n'LAST_EVENT > tCMH)
REPORT "CAS# Hold time violation -- tCMH"
SEVERITY WARNING;
ASSERT(Ras_n'LAST_EVENT > tCMH)
REPORT "RAS# Hold time violation -- tCMH"
SEVERITY WARNING;
ASSERT(We_n'LAST_EVENT > tCMH)
REPORT "WE# Hold time violation -- tCMH"
SEVERITY WARNING;
ASSERT(Dqm'LAST_EVENT > tCMH)
REPORT "Dqm Hold time violation -- tCMH"
SEVERITY WARNING;
END IF;
IF Clk'DELAYED (tAH) = '1' THEN
ASSERT(Addr'LAST_EVENT > tAH)
REPORT "ADDR Hold time violation -- tAH"
SEVERITY WARNING;
ASSERT(Ba'LAST_EVENT > tAH)
REPORT "BA Hold time violation -- tAH"
SEVERITY WARNING;
END IF;
IF Clk'DELAYED (tDH) = '1' THEN
ASSERT(Dq'LAST_EVENT > tDH)
REPORT "DQ Hold time violation -- tDH"
SEVERITY WARNING;
END IF;
END PROCESS;
END behave;
@@ -0,0 +1,143 @@
--*****************************************************************************
--
-- Micron Semiconductor Products, Inc.
--
-- Copyright 1997, Micron Semiconductor Products, Inc.
-- All rights reserved.
--
--*****************************************************************************
LIBRARY work;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
PACKAGE mti_pkg IS
FUNCTION TO_INTEGER (input : BIT) RETURN INTEGER;
FUNCTION TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER;
FUNCTION TO_INTEGER (input : STD_LOGIC) RETURN INTEGER;
FUNCTION TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER;
PROCEDURE TO_BITVECTOR (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR);
END mti_pkg;
PACKAGE BODY mti_pkg IS
-- Convert BIT to INTEGER
FUNCTION TO_INTEGER (input : BIT) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
IF input = '1' THEN
result := weight;
ELSE
result := 0; -- if unknowns, default to logic 0
END IF;
RETURN result;
END TO_INTEGER;
-- Convert BIT_VECTOR to INTEGER
FUNCTION TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
FOR i IN input'LOW TO input'HIGH LOOP
IF input(i) = '1' THEN
result := result + weight;
ELSE
result := result + 0; -- if unknowns, default to logic 0
END IF;
weight := weight * 2;
END LOOP;
RETURN result;
END TO_INTEGER;
-- Convert STD_LOGIC to INTEGER
FUNCTION TO_INTEGER (input : STD_LOGIC) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
IF input = '1' THEN
result := weight;
ELSE
result := 0; -- if unknowns, default to logic 0
END IF;
RETURN result;
END TO_INTEGER;
-- Convert STD_LOGIC_VECTOR to INTEGER
FUNCTION TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
FOR i IN input'LOW TO input'HIGH LOOP
IF input(i) = '1' THEN
result := result + weight;
ELSE
result := result + 0; -- if unknowns, default to logic 0
END IF;
weight := weight * 2;
END LOOP;
RETURN result;
END TO_INTEGER;
-- Conver integer to bit_vector
PROCEDURE TO_BITVECTOR (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR) IS
VARIABLE work,offset,outputlen,j : INTEGER := 0;
BEGIN
--length of vector
IF output'LENGTH > 32 THEN
outputlen := 32;
offset := output'LENGTH - 32;
IF input >= 0 THEN
FOR i IN offset-1 DOWNTO 0 LOOP
output(output'HIGH - i) := '0';
END LOOP;
ELSE
FOR i IN offset-1 DOWNTO 0 LOOP
output(output'HIGH - i) := '1';
END LOOP;
END IF;
ELSE
outputlen := output'LENGTH;
END IF;
--positive value
IF (input >= 0) THEN
work := input;
j := outputlen - 1;
FOR i IN 1 to 32 LOOP
IF j >= 0 then
IF (work MOD 2) = 0 THEN
output(output'HIGH-j-offset) := '0';
ELSE
output(output'HIGH-j-offset) := '1';
END IF;
END IF;
work := work / 2;
j := j - 1;
END LOOP;
IF outputlen = 32 THEN
output(output'HIGH) := '0';
END IF;
--negative value
ELSE
work := (-input) - 1;
j := outputlen - 1;
FOR i IN 1 TO 32 LOOP
IF j>= 0 THEN
IF (work MOD 2) = 0 THEN
output(output'HIGH-j-offset) := '1';
ELSE
output(output'HIGH-j-offset) := '0';
END IF;
END IF;
work := work / 2;
j := j - 1;
END LOOP;
IF outputlen = 32 THEN
output(output'HIGH) := '1';
END IF;
END IF;
END TO_BITVECTOR;
END mti_pkg;
@@ -0,0 +1,14 @@
To operate the test bench for the Micron SDRAM VHDL model, follow the directions
given below:
1. Be sure all supporting files for the SDRAM are compiled into your library:
util1164.vhd
stdlogar.vhd
io_utils.vhd
mti_pkg.vhd
2. Next, compile the mt48lc1m16a1.vhd file and the test.vhd file.
3. Simulate the "tb" architecture. This is the testbench for the SDRAM.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
0 ns 1 1 1 1 1 00 0 0 -100
22 ns 1 1 1 1 1 00 0 0 -100
32 ns 1 1 1 1 1 00 0 0 -100
42 ns 1 1 1 1 1 00 0 0 -100
52 ns 1 1 1 1 1 00 0 0 -100
62 ns 1 1 1 1 1 00 0 0 -100
72 ns 1 0 0 1 0 00 0 1024 -100
82 ns 1 1 1 1 1 00 0 0 -100
92 ns 1 1 1 1 1 00 0 0 -100
102 ns 1 0 0 0 1 00 0 0 -100
112 ns 1 1 1 1 1 00 0 0 -100
122 ns 1 1 1 1 1 00 0 0 -100
132 ns 1 1 1 1 1 00 0 0 -100
142 ns 1 1 1 1 1 00 0 0 -100
152 ns 1 1 1 1 1 00 0 0 -100
162 ns 1 1 1 1 1 00 0 0 -100
172 ns 1 1 1 1 1 00 0 0 -100
182 ns 1 1 1 1 1 00 0 0 -100
192 ns 1 0 0 0 1 00 0 0 -100
202 ns 1 1 1 1 1 00 0 0 -100
212 ns 1 1 1 1 1 00 0 0 -100
222 ns 1 1 1 1 1 00 0 0 -100
232 ns 1 1 1 1 1 00 0 0 -100
242 ns 1 1 1 1 1 00 0 0 -100
252 ns 1 1 1 1 1 00 0 0 -100
262 ns 1 1 1 1 1 00 0 0 -100
272 ns 1 1 1 1 1 00 0 0 -100
282 ns 1 0 0 0 0 00 0 51 -100
292 ns 1 1 1 1 1 00 0 0 -100
302 ns 1 1 1 1 1 00 0 0 -100
312 ns 1 0 0 1 1 00 0 0 -100
322 ns 1 1 1 1 1 00 0 0 -100
332 ns 1 1 1 1 1 00 0 0 -100
342 ns 1 0 1 0 0 00 0 1024 100
352 ns 1 1 1 1 1 00 0 0 101
362 ns 1 1 1 1 1 00 0 0 102
372 ns 1 1 1 1 1 00 0 0 103
382 ns 1 1 1 1 1 00 0 0 104
392 ns 1 0 0 1 1 00 1 0 105
402 ns 1 1 1 1 1 00 0 0 106
412 ns 1 1 1 1 1 00 0 0 107
422 ns 1 0 1 0 0 00 1 1024 200
432 ns 1 1 1 1 1 00 0 0 201
442 ns 1 1 1 1 1 00 0 0 202
452 ns 1 1 1 1 1 00 0 0 203
462 ns 1 1 1 1 1 00 0 0 204
472 ns 1 0 0 1 1 00 0 0 205
482 ns 1 1 1 1 1 00 0 0 206
492 ns 1 1 1 1 1 00 0 0 207
502 ns 1 0 1 0 1 00 0 1024 -100
512 ns 1 1 1 1 1 00 0 0 -100
522 ns 1 1 1 1 1 00 0 0 -100
532 ns 1 1 1 1 1 00 0 0 -100
542 ns 1 1 1 1 1 00 0 0 -100
552 ns 1 0 0 1 1 00 1 0 -100
562 ns 1 1 1 1 1 00 0 0 -100
572 ns 1 1 1 1 1 00 0 0 -100
582 ns 1 0 1 0 1 00 1 1024 -100
592 ns 1 1 1 1 1 00 0 0 -100
602 ns 1 1 1 1 1 00 0 0 -100
612 ns 1 1 1 1 1 00 0 0 -100
622 ns 1 1 1 1 1 00 0 0 -100
632 ns 1 1 1 1 1 00 0 0 -100
642 ns 1 1 1 1 1 00 0 0 -100
652 ns 1 1 1 1 1 00 0 0 -100
662 ns 1 1 1 1 1 00 0 0 -100
672 ns 1 1 1 1 1 00 0 0 -100
682 ns 1 1 1 1 1 00 0 0 -100
692 ns 1 1 1 1 1 00 0 0 -100
@@ -0,0 +1,168 @@
LIBRARY ieee;
LIBRARY work;
USE ieee.std_logic_1164.ALL;
USE work.std_logic_arith.ALL;
USE work.util_1164.ALL;
USE std.textio.ALL;
USE work.mti_pkg.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE test OF tb IS
CONSTANT addr_bits : INTEGER := 11;
CONSTANT clk_start : time := 5 ns;
CONSTANT clk_period : time := 10 ns;
CONSTANT continue_time : time := 10 ns;
CONSTANT data_bits : INTEGER := 16;
COMPONENT mt48lc1m16a1
PORT (
Dq : INOUT STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
Addr : IN STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0) := (OTHERS => '0');
Ba : IN STD_LOGIC := '0';
Clk : IN STD_LOGIC := '0';
Cke : IN STD_LOGIC := '0';
Cs_n : IN STD_LOGIC := '1';
Cas_n : IN STD_LOGIC := '0';
Ras_n : IN STD_LOGIC := '0';
We_n : IN STD_LOGIC := '0';
Dqm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) := "00"
);
END COMPONENT;
FOR ALL : mt48lc1m16a1 USE ENTITY work.mt48lc1m16a1 (behave);
SIGNAL pDq : STD_LOGIC_VECTOR (data_bits - 1 DOWNTO 0);
SIGNAL pAddr : STD_LOGIC_VECTOR (addr_bits - 1 DOWNTO 0);
SIGNAL pBa : STD_LOGIC;
SIGNAL pClk : STD_LOGIC;
SIGNAL pCke : STD_LOGIC;
SIGNAL pCs : STD_LOGIC;
SIGNAL pCas : STD_LOGIC;
SIGNAL pRas : STD_LOGIC;
SIGNAL pWe : STD_LOGIC;
SIGNAL pDqm : STD_LOGIC_VECTOR (1 DOWNTO 0);
SIGNAL stim_done : boolean := false;
SIGNAL clk_done : boolean := false;
BEGIN
u1: mt48lc1m16a1
PORT MAP(
Dq => pDq,
Addr => pAddr,
Ba => pBa,
Clk => pClk,
Cke => pCke,
Cs_n => pCs,
Ras_n => pRas,
Cas_n => pCas,
We_n => pWe,
Dqm => pDqm
);
stimulator : PROCESS
FILE stim_file:text IS IN "test.txt";
VARIABLE l : line;
VARIABLE time_var : TIME;
VARIABLE pCke_var : STD_LOGIC;
VARIABLE pCs_var : STD_LOGIC;
VARIABLE pRas_var : STD_LOGIC;
VARIABLE PCas_var : STD_LOGIC;
VARIABLE pWe_var : STD_LOGIC;
VARIABLE pDqm_var : STD_LOGIC_VECTOR (1 DOWNTO 0);
VARIABLE pBa_var : STD_LOGIC;
VARIABLE pAddr_var : INTEGER;
VARIABLE pDq_var : INTEGER; -- -100 is converted to hi-Z state
VARIABLE pMa_var_vect : STD_LOGIC_VECTOR(addr_bits - 1 DOWNTO 0);
CONSTANT HiZ : STD_LOGIC_VECTOR(data_bits - 1 DOWNTO 0) := (OTHERS => 'Z');
BEGIN
WHILE not ENDFILE(stim_file) LOOP
readline(stim_file,l);
IF l'length > 0 THEN
read(l, time_var);
read(l, pCke_var);
read(l, pCs_var);
read(l, pRas_var);
read(l, pCas_var);
read(l, pWe_var);
read(l, pDqm_var);
read(l, pBa_var);
read(l, pAddr_var);
read(l, pDq_var);
IF now > time_var THEN
ASSERT false
REPORT "Detected a time in the stim file that is in the past"
SEVERITY error;
ELSE
WAIT FOR time_var-now;
IF pWe_var='1' THEN
pCke <= pCke_var;
pCs <= pCs_var;
pRas <= pRas_var;
pCas <= pCas_var;
pWe <= pWe_var;
pDqm <= pDqm_var;
pBa <= pBa_var;
pMa_var_vect := CONV_STD_LOGIC_VECTOR(pAddr_var, addr_bits);
pAddr <= pMa_var_vect;
IF pDq_var = -100 THEN
pDq <= HiZ;
ELSE
pDq <= CONV_STD_LOGIC_VECTOR(pDq_var, data_bits);
END IF;
ELSE
pCke <= pCke_var;
pCs <= pCs_var;
pRas <= pRas_var;
pCas <= pCas_var;
pWe <= pWe_var;
pDqm <= pDqm_var;
pBa <= pBa_var;
pMa_var_vect := CONV_STD_LOGIC_VECTOR(pAddr_var, addr_bits);
pAddr <= pMa_var_vect;
IF pDq_var = -100 THEN
pDq <= HiZ;
ELSE
pDq <= CONV_STD_LOGIC_VECTOR(pDq_var, data_bits);
END IF;
END IF;
END IF;
END IF;
END LOOP;
ASSERT false
REPORT "End of Stimulation File Detected!"
SEVERITY note;
stim_done <= true;
WAIT;
END PROCESS;
clock : PROCESS
VARIABLE done_time : time;
BEGIN
pclk <= '0';
WAIT for clk_start;
WHILE not stim_done loop
pclk <= '1';
WAIT for clk_period/2;
pclk <= '0';
WAIT for clk_period/2;
END LOOP;
done_time := now+continue_time;
WHILE now < done_time LOOP --one last clock to finish last command
pclk <= '1';
WAIT for clk_period/2;
pclk <= '0';
WAIT for clk_period/2;
END LOOP;
ASSERT false
REPORT "Suspending clock activity"
SEVERITY note;
clk_done <= true;
WAIT;
END PROCESS;
END test;
@@ -0,0 +1,124 @@
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE STD.textio.ALL;
PACKAGE util_1164 IS
PROCEDURE read(l: INOUT line; value: OUT std_logic);
PROCEDURE read(l: INOUT line; value: OUT std_logic_vector);
PROCEDURE write(l: INOUT line; value: IN std_logic_vector;
JUSTIFIED: IN SIDE := right;
FIELD: IN WIDTH := 0);
PROCEDURE Grow_line(L : inout LINE; incr : in integer);
END util_1164;
PACKAGE BODY util_1164 IS
FUNCTION white_space(value:character) RETURN boolean IS
VARIABLE result:boolean;
BEGIN
IF (value = ' ') OR (value = HT) THEN
RETURN true;
ELSE
RETURN false;
END IF;
END white_space;
PROCEDURE read(l: INOUT line; value: OUT std_logic) IS
VARIABLE char_var: character:= ' ';
BEGIN
WHILE l'LENGTH > 0 LOOP
read(l,char_var);
IF NOT white_space(char_var) THEN
EXIT;
END IF;
END LOOP;
IF white_space(char_var) THEN
ASSERT false REPORT "No std_logic value found in file"
SEVERITY error;
value := 'X';
RETURN;
END IF;
CASE char_var IS
WHEN 'U'|'u' => value := 'U';
WHEN '0' => value := '0';
WHEN '1' => value := '1';
WHEN 'X'|'x' => value := 'X';
WHEN 'L'|'l' => value := 'L';
WHEN 'H'|'h' => value := 'H';
WHEN 'W'|'w' => value := 'W';
WHEN 'Z'|'z' => value := 'Z';
WHEN '-' => value := '-';
WHEN OTHERS =>
ASSERT false REPORT "Unrecognized value read for std_logic"
SEVERITY error;
value := 'X';
END CASE;
END read;
PROCEDURE read(l: INOUT line; value: OUT std_logic_vector) IS
BEGIN
FOR i IN value'HIGH DOWNTO value'LOW LOOP
IF l'LENGTH > 0 THEN
read(l,value(i));
ELSE
ASSERT false REPORT "Not enough values for std_logic_vector in file"
SEVERITY error;
RETURN;
END IF;
END LOOP;
END read;
procedure Grow_line(L : inout LINE; incr : in integer)
is
variable old_L : LINE := L;
variable bfp: integer; -- Blank fill pointer.
begin
assert incr > 0
report "Textio: Grow_line called with zero increment."
severity error;
if L = null then
bfp := 0;
L := new string(1 to incr);
else
bfp := old_L'high;
L := new string(old_L'low to old_L'high + incr);
L(old_L'low to old_L'high) := old_L.all;
Deallocate(old_L);
end if;
for i in 1 to incr loop
L(bfp + i) := ' ';
end loop;
end;
PROCEDURE write(l: INOUT line; value: IN std_logic_vector;
JUSTIFIED: IN SIDE := right;
FIELD: IN WIDTH := 0) IS
variable fw: integer := VALUE'length;
variable bp: integer;
variable offset: integer := 0;
alias normal : std_logic_vector(0 to value'length - 1) is value;
begin
if L /= null then
bp := L'high + 1;
else bp := 1;
end if;
if FIELD > VALUE'length then
fw := FIELD;
if JUSTIFIED = right then
offset := fw - VALUE'length;
end if;
end if;
Grow_line(L, fw);
for i in normal'range loop
L(bp + i + offset) := character'val(
std_logic'pos(normal(i)) + character'pos('0'));
end loop;
end;
END util_1164;
@@ -0,0 +1,369 @@
-------------------------------------------------------------------------------
-- --
-- This is a data generator for the testbench for Micron's Synchronous --
-- DRAM. This generator reads a text file line-by-line and generates --
-- a file of test vectors that is then read by the testbench and --
-- applied to the part. --
-- --
-- This VHDL program creates a text file of test vectors that is used by the --
-- test bench. Place your commands in a file (a copy of VEC_GEN.VHD) and run --
-- VEC_GEN.VHD in your VHDL simulator (make sure you have compiled this --
-- package prior to running the program VEC_GEN.VHD). This will produce the --
-- vectors that are required to run the included testbench. Change the name --
-- of the vector file to save your vectors in separate files. The default --
-- file name for the output vectors generated from this pacakage is --
-- "test.txt." --
-- --
-- Now compile and run the testbench program embedtb.vhd. The testbench uses --
-- the default test.txt as input vectors. --
-- --
-- --
-- Copyright 1997 Micron Technology, Inc. --
-- --
-------------------------------------------------------------------------------
LIBRARY work;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE std.textio.all;
USE work.io_utils.all;
PACKAGE generate_vectors IS
CONSTANT set_up : TIME;
CONSTANT hold : TIME;
CONSTANT cycle_start : TIME;
SIGNAL cycle : INTEGER := 0;
SIGNAL sim_time : TIME := 0 ns;
FILE output_file:TEXT IS OUT "test.txt";
PROCEDURE write(col_address : IN INTEGER; bank : IN BIT;
first_data : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT);
PROCEDURE read(col_address : IN INTEGER; bank : IN BIT; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT);
PROCEDURE active(row_address : IN INTEGER; bank : IN BIT; data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT);
PROCEDURE precharge(bank : IN BIT; address : IN INTEGER; data_bus: IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT);
PROCEDURE nop(data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT; cs : IN BIT);
PROCEDURE burst_term(data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT);
PROCEDURE auto_refresh;
PROCEDURE next_cycle(SIGNAL clk : IN BIT);
PROCEDURE load_array(load : IN BIT);
PROCEDURE load_mode_reg(op_code : IN INTEGER; cke : IN BIT);
PROCEDURE unload_array(row_start : IN INTEGER; row_end : IN INTEGER; bank : IN BIT);
END generate_vectors;
PACKAGE BODY generate_vectors IS
CONSTANT set_up : TIME := 3 ns;
CONSTANT hold : TIME := 1 ns;
CONSTANT cycle_start : TIME := 0 ns;
PROCEDURE write(col_address : IN INTEGER; bank : IN BIT; first_data : IN INTEGER;
dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT) IS
VARIABLE l : LINE;
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, Cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 0, right, 4); --Cas
write(l, 0, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, col_address, right, 6); --address
write(l, first_data, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE read(col_address : IN INTEGER; bank : IN BIT; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT) IS
VARIABLE l : LINE;
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, Cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 0, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, col_address, right, 6); --address
write(l, -100, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE active(row_address : IN INTEGER; bank : IN BIT; data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT) IS
VARIABLE l : LINE;
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, Cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 0, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, row_address, right, 6); --address
write(l, data_bus, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE precharge(bank : IN BIT; address : IN INTEGER; data_bus: IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT) IS
VARIABLE l : LINE;
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, Cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 0, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 0, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, address, right, 6); --address
write(l, data_bus, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE nop(data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT; cs : IN BIT) IS
VARIABLE l : LINE;
VARIABLE col_address : INTEGER := 0;
VARIABLE bank : BIT := '0';
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, cke, right, 4); --Cke
write(l, cs, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, col_address, right, 6); --address
write(l, data_bus, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE burst_term(data_bus : IN INTEGER; dqm : IN BIT_VECTOR(1 DOWNTO 0); cke : IN BIT) IS
VARIABLE l : LINE;
VARIABLE col_address : INTEGER := 0;
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 0, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, 0, right, 4); --Ba
write(l, col_address, right, 6); --address
write(l, data_bus, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE auto_refresh IS
VARIABLE l : LINE;
VARIABLE dqm : BIT_VECTOR(1 DOWNTO 0) := "00";
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, 1, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 0, right, 4); --Ras
write(l, 0, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, 0, right, 4); --Ba
write(l, 0, right, 6); --address
write(l, -100, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE next_cycle(SIGNAL clk : IN BIT) IS
BEGIN
WAIT UNTIL clk = '1';
END;
PROCEDURE load_array(load : IN BIT) IS
VARIABLE l : LINE;
VARIABLE dqm : BIT_VECTOR(1 DOWNTO 0) := "00";
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, 1, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, 0, right, 4); --Ba
write(l, 0, right, 6); --address
write(l, -100, right, 6); --first data location
--write(l, 1, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE unload_array(row_start : IN INTEGER; row_end : IN INTEGER; bank : IN BIT) IS
VARIABLE l : LINE;
VARIABLE dqm : BIT_VECTOR(1 DOWNTO 0) := "00";
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, 1, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 1, right, 4); --Ras
write(l, 1, right, 4); --Cas
write(l, 1, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, bank, right, 4); --Ba
write(l, 0, right, 6); --address
write(l, -100, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 1, right, 4); --unload
--write(l, row_start, right, 6); --row_address_start
--write(l, row_end, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
PROCEDURE load_mode_reg(op_code : IN INTEGER; cke : IN BIT) IS
VARIABLE l : LINE;
VARIABLE dqm : BIT_VECTOR(1 DOWNTO 0) := "00";
BEGIN
IF cycle = 0 THEN
write(l, cycle_start, left, 4, ns);
ELSE
write(l, now-set_up, left, 4, ns);
END IF;
write(l, cke, right, 4); --Cke
write(l, 0, right, 4); --Cs
write(l, 0, right, 4); --Ras
write(l, 0, right, 4); --Cas
write(l, 0, right, 4); --We
write(l, dqm, right, 4); --Dqm
write(l, 0, right, 4); --Ba
write(l, op_code, right, 6); --address
write(l, -100, right, 6); --first data location
--write(l, 0, right, 4); --load
--write(l, 0, right, 4); --unload
--write(l, 0, right, 6); --row_address_start
--write(l, 0, right, 6); --row_address_end
writeline(output_file,l); --write vector to file
END;
END generate_vectors;