started implementing SAMSUNG's Verilog DDR model in VHDL
This commit is contained in:
@@ -4,22 +4,7 @@ LIBRARY IEEE;
|
||||
|
||||
LIBRARY work;
|
||||
|
||||
PACKAGE ddr_ram_model_pkg IS
|
||||
-- DDR RAM timing constants
|
||||
|
||||
CONSTANT TRFC_MIN : TIME := 105000 ps; -- refresh to refresh command minimum value
|
||||
CONSTANT TRFC_MAX : TIME := 70000000 ps; -- refresh to refresh command maximum value
|
||||
CONSTANT TRP : TIME := 13125 ps; -- precharge period
|
||||
CONSTANT TRPA : TIME := 13125 ps; -- precharge all period
|
||||
CONSTANT TRC : TIME := 54000 ps; -- activate to activate/auto refresh command time
|
||||
CONSTANT TRAS_MIN : TIME := 40000 ps; -- minimum active to precharge command time
|
||||
CONSTANT TRAS_MAX : TIME := 70000000 ps; -- maximum active to precharge command time
|
||||
CONSTANT TRRD : TIME := 10000 ps; -- tRRD: active bank to active bank command time
|
||||
CONSTANT TFAW : TIME := 45000 ps; -- four bank activate window
|
||||
CONSTANT TWR : TIME := 15000 ps; -- write recovery time
|
||||
|
||||
CONSTANT RANDOM_SEED : INTEGER := 711689044; -- seed value for random generator
|
||||
|
||||
PACKAGE ddr_ram_model_pkg IS
|
||||
COMPONENT ddr_ram_model IS
|
||||
GENERIC
|
||||
(
|
||||
@@ -27,31 +12,33 @@ PACKAGE ddr_ram_model_pkg IS
|
||||
|
||||
CLOCK_TICK : TIME := (1000000 / 132000) * 1 ps; -- time for one clock tick
|
||||
|
||||
BA_BITS : INTEGER := 2; -- number of banks
|
||||
ADDR_BITS : INTEGER := 13; -- number of address bits
|
||||
DM_BITS : INTEGER := 2; -- number of data mask bits
|
||||
DQ_BITS : INTEGER := 16; -- number of data bits
|
||||
DQS_BITS : INTEGER := 2 -- number of data strobes
|
||||
NBANK : INTEGER := 4;
|
||||
ADDRTOP : INTEGER := 12;
|
||||
A10_LESS : BOOLEAN := TRUE; -- top column address is less than A10
|
||||
B : INTEGER := 16; -- number of bit (x16)
|
||||
NCOL : INTEGER := 10; -- top column address is CA9 (NCOL- 1)
|
||||
PAGEDEPTH : INTEGER := 1024;
|
||||
NDM : INTEGER := 2;
|
||||
NDQS : INTEGER := 2
|
||||
);
|
||||
PORT
|
||||
(
|
||||
ck : IN STD_LOGIC;
|
||||
ck_n : IN STD_LOGIC;
|
||||
dqi : INOUT STD_LOGIC_VECTOR (B - 1 DOWNTO 0);
|
||||
ba : IN UNSIGNED (NBANK / 2 - 1 DOWNTO 0);
|
||||
ad : IN STD_LOGIC_VECTOR (ADDRTOP DOWNTO 0);
|
||||
rasb : IN STD_LOGIC;
|
||||
casb : IN STD_LOGIC;
|
||||
web : IN STD_LOGIC;
|
||||
clk : IN STD_LOGIC;
|
||||
clkb : IN STD_LOGIC;
|
||||
cke : IN STD_LOGIC;
|
||||
cs_n : IN STD_LOGIC;
|
||||
ras_n : IN STD_LOGIC;
|
||||
cas_n : IN STD_LOGIC;
|
||||
we_n : IN STD_LOGIC;
|
||||
dm_rdqs : INOUT UNSIGNED (DM_BITS - 1 DOWNTO 0);
|
||||
ba : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
addr : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0);
|
||||
dq : INOUT UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
dqs : INOUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
dqs_n : INOUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
rdqs_n : OUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
odt : IN STD_LOGIC
|
||||
csb : IN STD_LOGIC;
|
||||
dm : IN UNSIGNED (NDM - 1 DOWNTO 0);
|
||||
dqs : INOUT STD_LOGIC_VECTOR (NDQS - 1 DOWNTO 0);
|
||||
qfc : OUT STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
END PACKAGE;
|
||||
|
||||
PACKAGE BODY ddr_ram_model_pkg IS
|
||||
@@ -69,716 +56,90 @@ LIBRARY work;
|
||||
ENTITY ddr_ram_model IS
|
||||
GENERIC
|
||||
(
|
||||
VERBOSE : BOOLEAN := TRUE; -- define if you want additional debug output
|
||||
VERBOSE : BOOLEAN := TRUE; -- define if you want additional debug output
|
||||
|
||||
CLOCK_TICK : TIME := (1000000 / 132000) * 1 ps; -- time for one clock tick
|
||||
|
||||
BA_BITS : INTEGER := 2; -- number of banks
|
||||
ADDR_BITS : INTEGER := 13; -- number of address bits
|
||||
DM_BITS : INTEGER := 2; -- number of data mask bits
|
||||
DQ_BITS : INTEGER := 8; -- number of data bits
|
||||
DQS_BITS : INTEGER := 2 -- number of data strobes
|
||||
|
||||
NBANK : INTEGER := 4;
|
||||
ADDRTOP : INTEGER := 12;
|
||||
A10_LESS : BOOLEAN := TRUE; -- top column address is less than A10
|
||||
B : INTEGER := 16; -- number of bit (x16)
|
||||
NCOL : INTEGER := 10; -- top column address is CA9 (NCOL- 1)
|
||||
PAGEDEPTH : INTEGER := 1024;
|
||||
NDM : INTEGER := 2;
|
||||
NDQS : INTEGER := 2
|
||||
);
|
||||
PORT
|
||||
(
|
||||
ck : IN STD_LOGIC;
|
||||
ck_n : IN STD_LOGIC;
|
||||
cke : IN STD_LOGIC;
|
||||
cs_n : IN STD_LOGIC;
|
||||
ras_n : IN STD_LOGIC;
|
||||
cas_n : IN STD_LOGIC;
|
||||
we_n : IN STD_LOGIC;
|
||||
dm_rdqs : INOUT UNSIGNED (DM_BITS - 1 DOWNTO 0);
|
||||
ba : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
addr : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0);
|
||||
dq : INOUT UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
dqs : INOUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
dqs_n : INOUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
rdqs_n : OUT UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
odt : IN STD_LOGIC
|
||||
);
|
||||
dqi : INOUT STD_LOGIC_VECTOR (B - 1 DOWNTO 0);
|
||||
ba : IN UNSIGNED (NBANK / 2 - 1 DOWNTO 0);
|
||||
ad : IN STD_LOGIC_VECTOR (ADDRTOP DOWNTO 0);
|
||||
rasb : IN STD_LOGIC;
|
||||
casb : IN STD_LOGIC;
|
||||
web : IN STD_LOGIC;
|
||||
clk : IN STD_LOGIC;
|
||||
clkb : IN STD_LOGIC;
|
||||
cke : IN STD_LOGIC;
|
||||
csb : IN STD_LOGIC;
|
||||
dm : IN UNSIGNED (NDM - 1 DOWNTO 0);
|
||||
dqs : INOUT STD_LOGIC_VECTOR (NDQS - 1 DOWNTO 0);
|
||||
qfc : OUT STD_LOGIC
|
||||
);
|
||||
END ENTITY ddr_ram_model;
|
||||
|
||||
ARCHITECTURE rtl OF ddr_ram_model IS
|
||||
-- DDR RAM size constants
|
||||
CONSTANT MEM_BITS : INTEGER := 10; -- number of write data bursts can be stored in memory. The default is 2 ** 10 = 1024
|
||||
CONSTANT AP : INTEGER := 10; -- the address bit that controls auto-precharge and precharge-all
|
||||
CONSTANT TDLLK : INTEGER := 200;
|
||||
CONSTANT BANKS : INTEGER := TO_INTEGER(SHIFT_LEFT(TO_UNSIGNED(1, 32), BA_BITS));
|
||||
CONSTANT ROW_BITS : INTEGER := 13;
|
||||
CONSTANT COL_BITS : INTEGER := 10;
|
||||
CONSTANT BL_BITS : INTEGER := 3; -- the number of bits required to count to MAX_BL
|
||||
CONSTANT BL_MAX : INTEGER := 8;
|
||||
CONSTANT BO_BITS : INTEGER := 2; -- the number of burst order bits
|
||||
CONSTANT MAX_BITS : INTEGER := BA_BITS + ROW_BITS + COL_BITS - BL_BITS;
|
||||
-- DDR RAM timing constants
|
||||
|
||||
CONSTANT TRC : TIME := 65 ps; -- row cycle time (min)
|
||||
CONSTANT TRFC : TIME := 115 ps; -- Refresh Row cycle time (min)
|
||||
CONSTANT TRASMIN : TIME := 45 ps; -- Row active minimum time
|
||||
CONSTANT TRASMAX : TIME := 120000 ps; -- Row active maximum time
|
||||
CONSTANT TRCD : TIME := 20 ps; -- Ras to cas delay (min)
|
||||
CONSTANT TRP : TIME := 20 ps; -- Row precharge time (min)
|
||||
CONSTANT TRRD : TIME := 15 ps; -- Row to row delay (min)
|
||||
|
||||
CONSTANT TCCD : TIME := CLOCK_TICK; -- Col. address to col. address delay: 1 clk
|
||||
|
||||
CONSTANT TCKMIN : TIME := 7.5 ps; -- Clock minimum cycle time
|
||||
CONSTANT TCKMAX : TIME := 12 ps; -- Clock maximum cycle time
|
||||
CONSTANT TCK15 : TIME := 10 ps; -- Clock minimum cycle time at cas latency=1.5
|
||||
CONSTANT TCK2 : TIME := 10 ps; -- Clock minimum cycle time at cas latency=2
|
||||
CONSTANT TCK25 : TIME := 7.5 ps; -- Clock minimum cycle time at cas latency=2.5
|
||||
CONSTANT TCK3 : TIME := 7.5 ps; -- Clock minimum cycle time at cas latency=3
|
||||
CONSTANT TCHMIN : TIME := 0.45 ps; -- Clock high pulse width (min. 0.45 tCK, max: 0.55 tCK)
|
||||
CONSTANT TCHMAX : TIME := 0.55 ps;
|
||||
CONSTANT TCLMIN : TIME := 0.45 ps; -- Clock low pulse width (min. 0.45 tCK, max: 0.55 tCK)
|
||||
CONSTANT TCLMAX : TIME := 0.55 ps;
|
||||
CONSTANT TIS : TIME := 0.9 ps; -- input setup time (old Tss)
|
||||
CONSTANT TIH : TIME := 0.9 ps; -- input hold time (old Tsh)
|
||||
CONSTANT TWR : TIME := 15 ps; -- write recovery time
|
||||
CONSTANT TDS : TIME := 0.5 ps; -- Data in & DQM setup time
|
||||
CONSTANT TDH : TIME := 0.5 ps; -- Data in & DQM hold time
|
||||
CONSTANT TDQSH : TIME := 0.6 ps; -- DQS-in high level width (min. 0.4 tCK, max. 0.6 tCK)
|
||||
CONSTANT TDQSL : TIME := 0.6 ps; --
|
||||
CONSTANT TDSC : TIME := 1 ps; -- DQS-in cycle time tCIC changed following tDSC
|
||||
CONSTANT TPDEX : TIME := 7.5 ps; -- Power down exit time
|
||||
CONSTANT TSREX : TIME := 200 ps; -- Self refresh exit time : 200 clk
|
||||
CONSTANT THZQ : TIME := 0.75 ps; -- Data out active to High-Z (min:-0.75, max: +0.75)
|
||||
CONSTANT TDQSCK : TIME := 0.75 ps; -- DQS out edge to clock edge
|
||||
CONSTANT TAC : TIME := 0.75 ps; -- Output data access time from CK/CKB (min: -0.75, max: +0.75)
|
||||
CONSTANT TQCSW : TIME := 3.5 ps; -- Delay from the clock edge of write command to QFC out on writes (max: 4ns)
|
||||
CONSTANT TQCHW : TIME := 0.5 ps; -- QFC hold time on writes (min 1.25 ns, max: 0.5 tCK)
|
||||
CONSTANT TQCH : TIME := 0.4 ps; -- QFC hold time on reads (min 0.4 tCK, max 0.6 tCK)
|
||||
CONSTANT TQCS : TIME := 0.9 ps; -- QFC setup time on reads (min: 0.9 tCK, max 1.1 tCK)
|
||||
|
||||
-- time constants
|
||||
CONSTANT BUS_DELAY : TIME := 0 ps;
|
||||
CONSTANT K1 : INTEGER := 1024;
|
||||
CONSTANT M1 : INTEGER := 1048576;
|
||||
CONSTANT BYTE : INTEGER := 8;
|
||||
|
||||
-- time constants (in tCK's)
|
||||
CONSTANT TMRD : INTEGER := 2; -- load mode register command cycle time
|
||||
CONSTANT TCCD : INTEGER := 2; -- CAS to CAS command delay
|
||||
CONSTANT TBITS : INTEGER := 512 * M1;
|
||||
|
||||
CONSTANT DQ_PER_DQS : INTEGER := DQ_BITS / DQS_BITS;
|
||||
CONSTANT MAX_SIZE : INTEGER := TO_INTEGER(SHIFT_LEFT(TO_UNSIGNED(1, 32), BA_BITS + ROW_BITS + COL_BITS - BL_BITS));
|
||||
CONSTANT MEM_SIZE : INTEGER := TO_INTEGER(SHIFT_LEFT(TO_UNSIGNED(1, 32), MEM_BITS));
|
||||
CONSTANT AL_MAX : INTEGER := 6;
|
||||
CONSTANT CL_MAX : INTEGER := 7;
|
||||
CONSTANT MAX_PIPE : INTEGER := 2 * (AL_MAX + CL_MAX);
|
||||
|
||||
TYPE time_array_t IS ARRAY (NATURAL RANGE <>) OF TIME;
|
||||
|
||||
-- clock jitter
|
||||
SIGNAL tck_avg : REAL;
|
||||
SIGNAL tck_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
||||
SIGNAL tch_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
||||
SIGNAL tcl_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
||||
SIGNAL tck_i : TIME;
|
||||
SIGNAL tch_i : TIME;
|
||||
SIGNAL tcl_i : TIME;
|
||||
SIGNAL tch_avg : REAL;
|
||||
SIGNAL tcl_avg : REAL;
|
||||
SIGNAL tm_ck_pos : TIME;
|
||||
SIGNAL tm_ck_neg : TIME;
|
||||
SIGNAL tjit_per_rtime : REAL;
|
||||
SIGNAL tjit_cc_time : INTEGER;
|
||||
SIGNAL terr_nper_rtime : REAL;
|
||||
|
||||
-- clock skew
|
||||
SIGNAL out_delay : REAL;
|
||||
SIGNAL dqsck : UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
SIGNAL dqsck_min : INTEGER;
|
||||
SIGNAL dqsck_max : INTEGER;
|
||||
SIGNAL dqsq_min : INTEGER;
|
||||
SIGNAL dqsq_max : INTEGER;
|
||||
SIGNAL seed : INTEGER;
|
||||
|
||||
-- mode registers
|
||||
SIGNAL burst_order : STD_LOGIC;
|
||||
SIGNAL burst_length : UNSIGNED (BL_BITS DOWNTO 0);
|
||||
SIGNAL cas_latency : INTEGER;
|
||||
SIGNAL additive_latency : INTEGER;
|
||||
SIGNAL dll_reset : STD_LOGIC;
|
||||
SIGNAL dll_locked : STD_LOGIC;
|
||||
SIGNAL dll_en : STD_LOGIC;
|
||||
SIGNAL write_recovery : INTEGER;
|
||||
SIGNAL low_power : STD_LOGIC;
|
||||
SIGNAL odt_rtt : UNSIGNED (1 DOWNTO 0);
|
||||
SIGNAL odt_en : STD_LOGIC;
|
||||
SIGNAL ocd : UNSIGNED (2 DOWNTO 0);
|
||||
SIGNAL dqs_n_en : STD_LOGIC;
|
||||
SIGNAL rdqs_en : STD_LOGIC;
|
||||
SIGNAL out_en : STD_LOGIC;
|
||||
SIGNAL read_latency : INTEGER;
|
||||
SIGNAL write_latency : INTEGER;
|
||||
|
||||
TYPE cmd_type_t IS (LOAD_MODE, REFRESH, PRECHARGE, ACTIVATE, WRITE_CMD, READ_CMD, NOP, PWR_DOWN, SELF_REF);
|
||||
TYPE cmd_type_encoding_array_t IS ARRAY(cmd_type_t) OF UNSIGNED(3 DOWNTO 0);
|
||||
CONSTANT cmd_type_encoding : cmd_type_encoding_array_t :=
|
||||
(
|
||||
"0000", "0001", "0010", "0011",
|
||||
"0100", "0101", "0111", "1000",
|
||||
"1001"
|
||||
);
|
||||
|
||||
TYPE cmd_string_array_t IS ARRAY (INTEGER RANGE <>) OF STRING(1 TO 9);
|
||||
CONSTANT cmd_string : cmd_string_array_t(1 TO 9) :=
|
||||
( "Load Mode",
|
||||
"Refresh ",
|
||||
"Precharge",
|
||||
"Activate ",
|
||||
"Write ",
|
||||
"Read ",
|
||||
"No OP ",
|
||||
"Pwr Down ",
|
||||
"Self Ref "
|
||||
);
|
||||
|
||||
-- command state
|
||||
SIGNAL active_bank : UNSIGNED (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL auto_precharge_bank : UNSIGNED (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL write_precharge_bank : UNSIGNED (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL read_precharge_bank : UNSIGNED (BANKS - 1 DOWNTO 0);
|
||||
|
||||
TYPE row_array_t IS ARRAY (INTEGER RANGE <>) OF UNSIGNED (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL active_row : row_array_t (ROW_BITS - 1 DOWNTO 0);
|
||||
SIGNAL in_power_down : STD_LOGIC;
|
||||
SIGNAL in_self_refresh : STD_LOGIC;
|
||||
SIGNAL init_mode_reg : UNSIGNED (3 DOWNTO 0);
|
||||
SIGNAL init_done : STD_LOGIC;
|
||||
SIGNAL init_step : INTEGER;
|
||||
SIGNAL er_trfc_max : STD_LOGIC;
|
||||
SIGNAL odt_state : STD_LOGIC;
|
||||
SIGNAL pref_odt : STD_LOGIC;
|
||||
|
||||
-- cmd timers/counters
|
||||
SIGNAL ref_cntr : INTEGER;
|
||||
SIGNAL ck_cntr : INTEGER;
|
||||
SIGNAL ck_load_mode : INTEGER;
|
||||
SIGNAL ck_write : INTEGER;
|
||||
SIGNAL ck_read : INTEGER;
|
||||
SIGNAL ck_write_ap : INTEGER;
|
||||
SIGNAL ck_power_down : INTEGER;
|
||||
SIGNAL ck_slow_exit_pd : INTEGER;
|
||||
SIGNAL ck_self_refresh : INTEGER;
|
||||
SIGNAL ck_cke : INTEGER;
|
||||
SIGNAL ck_odt : INTEGER;
|
||||
SIGNAL ck_dll_reset : INTEGER;
|
||||
|
||||
TYPE ck_bank_array_t IS ARRAY (NATURAL RANGE <>) OF INTEGER;
|
||||
SIGNAL ck_bank_write : ck_bank_array_t (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL ck_bank_read : ck_bank_array_t (BANKS - 1 DOWNTO 0);
|
||||
|
||||
SIGNAL tm_refresh : TIME;
|
||||
SIGNAL tm_precharge : TIME;
|
||||
SIGNAL tm_precharge_all : TIME;
|
||||
SIGNAL tm_activate : TIME;
|
||||
SIGNAL tm_write_end : TIME;
|
||||
SIGNAL tm_self_refresh : TIME;
|
||||
SIGNAL tm_odt_en : TIME;
|
||||
SIGNAL tm_bank_precharge : time_array_t (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL tm_bank_activate : time_array_t (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL tm_bank_write_end : time_array_t (BANKS - 1 DOWNTO 0);
|
||||
SIGNAL tm_bank_read_end : time_array_t (BANKS - 1 DOWNTO 0);
|
||||
|
||||
-- pipelines
|
||||
SIGNAL al_pipeline : UNSIGNED (MAX_PIPE DOWNTO 0);
|
||||
SIGNAL wr_pipeline : UNSIGNED (MAX_PIPE DOWNTO 0);
|
||||
SIGNAL rd_pipeline : UNSIGNED (MAX_PIPE DOWNTO 0);
|
||||
SIGNAL odt_pipeline : UNSIGNED (MAX_PIPE DOWNTO 0);
|
||||
|
||||
TYPE ba_pipeline_t IS ARRAY (NATURAL RANGE <>) OF UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
SIGNAL ba_pipeline : ba_pipeline_t (MAX_PIPE DOWNTO 0);
|
||||
|
||||
TYPE row_pipeline_t IS ARRAY (NATURAL RANGE <>) OF UNSIGNED (ROW_BITS - 1 DOWNTO 0);
|
||||
SIGNAL row_pipeline : row_pipeline_t (MAX_PIPE DOWNTO 0);
|
||||
|
||||
TYPE col_pipeline_t IS ARRAY (NATURAL RANGE <>) OF UNSIGNED (COL_BITS - 1 DOWNTO 0);
|
||||
SIGNAL col_pipeline : col_pipeline_t (MAX_PIPE DOWNTO 0);
|
||||
|
||||
SIGNAL prev_cke : STD_LOGIC;
|
||||
|
||||
-- data state
|
||||
SIGNAL memory_data : UNSIGNED (BL_MAX * DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL bit_mask : UNSIGNED (BL_MAX * DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL burst_position : UNSIGNED (BL_BITS - 1 DOWNTO 0);
|
||||
SIGNAL burst_cntr : UNSIGNED (BL_BITS DOWNTO 0);
|
||||
SIGNAL dq_temp : UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL check_write_postamble: UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL check_write_preamble : UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL check_write_dqs_high : UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL check_write_dqs_low : UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL check_dm_tdipw : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL check_dq_tdipw : UNSIGNED (17 DOWNTO 0);
|
||||
|
||||
-- data timers/counters
|
||||
SIGNAL tm_cke : TIME;
|
||||
SIGNAL tm_odt : TIME;
|
||||
SIGNAL tm_tdqss : TIME;
|
||||
SIGNAL tm_dm : time_array_t (17 DOWNTO 0);
|
||||
SIGNAL tm_dqs : time_array_t (17 DOWNTO 0);
|
||||
SIGNAL tm_dqs_pos : time_array_t (35 DOWNTO 0);
|
||||
SIGNAL tm_dqss_pos : time_array_t (35 DOWNTO 0);
|
||||
SIGNAL tm_dqss_neg : time_array_t (35 DOWNTO 0);
|
||||
SIGNAL tm_dq : time_array_t (71 DOWNTO 0);
|
||||
SIGNAL tm_cmd_addr : time_array_t (22 DOWNTO 0);
|
||||
|
||||
TYPE cmd_addr_array_t IS ARRAY (INTEGER RANGE <>) OF STRING(1 TO 8);
|
||||
CONSTANT cmd_addr_string : cmd_addr_array_t(22 DOWNTO 0) :=
|
||||
(
|
||||
"CS_N ",
|
||||
"RAS_N ",
|
||||
"CAS_N ",
|
||||
"WE_N ",
|
||||
"BA 0 ",
|
||||
"BA 1 ",
|
||||
"BA 2 ",
|
||||
"ADDR 0",
|
||||
"ADDR 1",
|
||||
"ADDR 2",
|
||||
"ADDR 3",
|
||||
"ADDR 4",
|
||||
"ADDR 5",
|
||||
"ADDR 6",
|
||||
"ADDR 7",
|
||||
"ADDR 8",
|
||||
"ADDR 9",
|
||||
"ADDR 10",
|
||||
"ADDR 11",
|
||||
"ADDR 12",
|
||||
"ADDR 13",
|
||||
"ADDR 14",
|
||||
"ADDR 15"
|
||||
);
|
||||
|
||||
TYPE dqs_string_t IS ARRAY (INTEGER RANGE <>) OF STRING (1 TO 5);
|
||||
CONSTANT dqs_string : dqs_string_t (1 DOWNTO 0) :=
|
||||
(
|
||||
"DQS ",
|
||||
"DQS_N"
|
||||
);
|
||||
--SIGNAL BITs : UNSIGNED (B - 1 DOWNTO 0);
|
||||
SIGNAL BIT_C : UNSIGNED (NCOL - 1 DOWNTO 0);
|
||||
CONSTANT NWORD : INTEGER := TBITS / B / NBANK;
|
||||
SIGNAL BIT_T : UNSIGNED (NCOL + ADDRTOP DOWNTO 0);
|
||||
SIGNAL WORD : UNSIGNED (NWORD - 1 DOWNTO 0);
|
||||
|
||||
-- memory storage
|
||||
TYPE mem_t IS ARRAY (INTEGER RANGE <>) OF UNSIGNED (BL_MAX * DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL memory : mem_t(0 TO MEM_SIZE - 1);
|
||||
TYPE adr_t IS ARRAY (INTEGER RANGE <>) OF UNSIGNED (MAX_BITS - 1 DOWNTO 0);
|
||||
SIGNAL address : adr_t(0 TO MEM_SIZE - 1);
|
||||
SIGNAL memory_index : UNSIGNED(MEM_BITS DOWNTO 0);
|
||||
SIGNAL memory_used : UNSIGNED(MEM_BITS DOWNTO 0);
|
||||
|
||||
SIGNAL ck_in : STD_LOGIC;
|
||||
SIGNAL ck_n_in : STD_LOGIC;
|
||||
SIGNAL cke_in : STD_LOGIC;
|
||||
SIGNAL cs_n_in : STD_LOGIC;
|
||||
SIGNAL ras_n_in : STD_LOGIC;
|
||||
SIGNAL cas_n_in : STD_LOGIC;
|
||||
SIGNAL we_n_in : STD_LOGIC;
|
||||
SIGNAL dm_in : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL ba_in : UNSIGNED (2 DOWNTO 0);
|
||||
SIGNAL addr_in : UNSIGNED (15 DOWNTO 0);
|
||||
SIGNAL dq_in : UNSIGNED (71 DOWNTO 0);
|
||||
SIGNAL dqs_in : UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL odt_in : STD_LOGIC;
|
||||
|
||||
SIGNAL dm_in_pos : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL dm_in_neg : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL dq_in_pos : UNSIGNED (71 DOWNTO 0);
|
||||
SIGNAL dq_in_neg : UNSIGNED (71 DOWNTO 0);
|
||||
SIGNAL dq_in_valid : STD_LOGIC;
|
||||
SIGNAL dqs_in_valid : STD_LOGIC;
|
||||
SIGNAL wdqs_cntr : INTEGER;
|
||||
SIGNAL wdq_cntr : INTEGER;
|
||||
|
||||
TYPE integer_array_t IS ARRAY (NATURAL RANGE <>) OF INTEGER;
|
||||
SIGNAL wdqs_pos_cntr : integer_array_t(35 DOWNTO 0);
|
||||
|
||||
SIGNAL b2b_write : STD_LOGIC;
|
||||
SIGNAL prev_dqs_in : UNSIGNED (35 DOWNTO 0);
|
||||
SIGNAL diff_ck : STD_LOGIC;
|
||||
|
||||
SIGNAL dqs_even : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL dqs_odd : UNSIGNED (17 DOWNTO 0);
|
||||
SIGNAL cmd_n_in : UNSIGNED (3 DOWNTO 0);
|
||||
|
||||
-- transmit
|
||||
SIGNAL dqs_out_en : STD_LOGIC;
|
||||
SIGNAL dqs_out_en_dly : UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
SIGNAL dqs_out : STD_LOGIC;
|
||||
SIGNAL dqs_out_dly : UNSIGNED (DQS_BITS - 1 DOWNTO 0);
|
||||
SIGNAL dq_out_en : STD_LOGIC;
|
||||
SIGNAL dq_out_en_dly : UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL dq_out : UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL dq_out_dly : UNSIGNED (DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL rdqsen_cntr : INTEGER;
|
||||
SIGNAL rdqs_cntr : INTEGER;
|
||||
SIGNAL rdqen_cntr : INTEGER;
|
||||
SIGNAL rdq_cntr : INTEGER;
|
||||
|
||||
SIGNAL r : STD_LOGIC := '0';
|
||||
|
||||
PROCEDURE memory_write(
|
||||
SIGNAL bank : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
SIGNAL row : IN UNSIGNED (ROW_BITS - 1 DOWNTO 0);
|
||||
SIGNAL col : IN UNSIGNED (COL_BITS - 1 DOWNTO 0);
|
||||
SIGNAL data : IN UNSIGNED (BL_MAX * DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL addr : INOUT UNSIGNED (MAX_BITS - 1 DOWNTO 0)) IS
|
||||
BEGIN
|
||||
addr <= (bank & row & col) / BL_MAX;
|
||||
-- TODO: only the MAX_MEM defined functionality available here
|
||||
-- memory(addr) <= data;
|
||||
END memory_write;
|
||||
|
||||
PROCEDURE memory_read(
|
||||
SIGNAL bank : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
SIGNAL row : IN UNSIGNED (ROW_BITS - 1 DOWNTO 0);
|
||||
SIGNAL col : IN UNSIGNED (COL_BITS - 1 DOWNTO 0);
|
||||
SIGNAL data : OUT UNSIGNED (BL_MAX * DQ_BITS - 1 DOWNTO 0);
|
||||
SIGNAL addr : INOUT UNSIGNED (MAX_BITS - 1 DOWNTO 0)) IS
|
||||
BEGIN
|
||||
-- chop off the lowest address bits
|
||||
addr <= (bank & row & col) / BL_MAX;
|
||||
-- TODO: only the MAX_MEM defined functionality defined yet
|
||||
-- data <= memory(addr);
|
||||
END memory_read;
|
||||
|
||||
PROCEDURE cmd_task(
|
||||
cke : IN STD_LOGIC;
|
||||
cmd : IN UNSIGNED (3 DOWNTO 0);
|
||||
bank : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
addr : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0)) IS
|
||||
|
||||
VARIABLE i : UNSIGNED (BANKS DOWNTO 0);
|
||||
VARIABLE j : INTEGER;
|
||||
VARIABLE tfaw_cntr : UNSIGNED (BANKS DOWNTO 0);
|
||||
VARIABLE col : UNSIGNED (COL_BITS - 1 DOWNTO 0);
|
||||
BEGIN
|
||||
END cmd_task;
|
||||
|
||||
|
||||
PROCEDURE initialize(
|
||||
SIGNAL mode_reg0 : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0);
|
||||
SIGNAL mode_reg1 : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0);
|
||||
SIGNAL mode_reg2 : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0);
|
||||
SIGNAL mode_reg3 : IN UNSIGNED (ADDR_BITS - 1 DOWNTO 0)) IS
|
||||
|
||||
CONSTANT AP_BIT : UNSIGNED (ADDR_BITS - 1 DOWNTO 0) := TO_UNSIGNED(2 ** AP, ADDR_BITS);
|
||||
BEGIN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & "INFO: performing initialization sequence");
|
||||
|
||||
cmd_task('1', cmd_type_encoding(NOP), (OTHERS => 'X'), (OTHERS => 'X'));
|
||||
cmd_task('1', cmd_type_encoding(PRECHARGE), (OTHERS => 'X'), AP_BIT);
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), RESIZE(2D"3", BA_BITS), mode_reg3);
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), RESIZE(2D"2", BA_BITS), mode_reg2);
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), RESIZE(2D"1", BA_BITS), mode_reg1);
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), (OTHERS => '0'), mode_reg0 OR "100"); -- DLL reset
|
||||
cmd_task('1', cmd_type_encoding(PRECHARGE), (OTHERS => 'X'), AP_BIT); -- Precharge all
|
||||
cmd_task('1', cmd_type_encoding(REFRESH), (OTHERS => 'X'), (OTHERS => 'X'));
|
||||
cmd_task('1', cmd_type_encoding(REFRESH), (OTHERS => 'X'), (OTHERS => 'X'));
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), (OTHERS => '0'), mode_reg0);
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), RESIZE(2D"1", BA_BITS), mode_reg1 OR x"380"); -- OCD default
|
||||
cmd_task('1', cmd_type_encoding(LOAD_MODE), RESIZE(2D"1", BA_BITS), mode_reg1);
|
||||
cmd_task('1', cmd_type_encoding(NOP), (OTHERS => 'X'), (OTHERS => 'X'));
|
||||
END initialize;
|
||||
|
||||
FUNCTION abs_value(SIGNAL arg : IN REAL) RETURN REAL IS
|
||||
BEGIN
|
||||
IF arg < 0.0 THEN
|
||||
RETURN -1.0 * arg;
|
||||
END IF;
|
||||
|
||||
RETURN arg;
|
||||
END abs_value;
|
||||
|
||||
BEGIN
|
||||
PROCESS (ck)
|
||||
BEGIN
|
||||
ck_in <= ck AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (ck_n)
|
||||
BEGIN
|
||||
ck_n_in <= ck_n AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (cke)
|
||||
BEGIN
|
||||
cke_in <= cke AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (cs_n)
|
||||
BEGIN
|
||||
cs_n_in <= cs_n AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (ras_n)
|
||||
BEGIN
|
||||
ras_n_in <= ras_n AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (cas_n)
|
||||
BEGIN
|
||||
cas_n_in <= cas_n AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (we_n)
|
||||
BEGIN
|
||||
we_n_in <= we_n AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (dm_rdqs)
|
||||
BEGIN
|
||||
dm_in <= RESIZE(dm_rdqs, dm_in'LENGTH) AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (ba)
|
||||
BEGIN
|
||||
ba_in <= RESIZE(ba, ba_in'LENGTH) AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (addr)
|
||||
BEGIN
|
||||
addr_in <= RESIZE(addr, addr_in'LENGTH) AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (dq)
|
||||
BEGIN
|
||||
dq_in <= RESIZE(dq, dq_in'LENGTH) AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (dqs, dqs_n)
|
||||
BEGIN
|
||||
dqs_in <= SHIFT_LEFT(RESIZE(dqs_n, dqs_in'LENGTH), 18) OR RESIZE(dqs, dqs_in'LENGTH);
|
||||
END PROCESS;
|
||||
|
||||
PROCESS (odt)
|
||||
BEGIN
|
||||
odt_in <= odt AFTER BUS_DELAY;
|
||||
END PROCESS;
|
||||
|
||||
-- create internal clock
|
||||
PROCESS
|
||||
BEGIN
|
||||
WAIT UNTIL RISING_EDGE(ck_in);
|
||||
diff_ck <= ck_in;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS
|
||||
BEGIN
|
||||
WAIT UNTIL RISING_EDGE(ck_n_in);
|
||||
diff_ck <= NOT ck_n_in;
|
||||
END PROCESS;
|
||||
|
||||
dqs_even <= dqs_in (17 DOWNTO 0);
|
||||
dqs_odd <= dqs_in (35 DOWNTO 18) WHEN dqs_n_en = '1' ELSE NOT(dqs_in (17 DOWNTO 0));
|
||||
cmd_n_in <= '0' & ras_n_in & cas_n_in & we_n_in WHEN NOT(cs_n_in) ELSE cmd_type_encoding(NOP);
|
||||
|
||||
-- bufif1 buf_dqs
|
||||
dqs <= dqs_out_dly WHEN (dqs_out_en_dly AND UNSIGNED'(0 TO DQS_BITS - 1 => out_en)) /= x"0" ELSE (OTHERS => 'Z');
|
||||
|
||||
-- bufif1 buf_dm
|
||||
dm_rdqs <= dqs_out_dly WHEN (dqs_out_en_dly AND
|
||||
UNSIGNED'(0 TO DM_BITS - 1 => out_en) AND
|
||||
UNSIGNED'(0 TO DM_BITS - 1 => rdqs_en)) /= x"0" ELSE (OTHERS => 'Z');
|
||||
-- bufif1 buf_dqs_n
|
||||
dqs_n <= NOT dqs_out_dly WHEN (dqs_out_en_dly AND
|
||||
UNSIGNED'(0 TO DQS_BITS - 1 => out_en) AND
|
||||
UNSIGNED'(0 TO DQS_BITS - 1 => dqs_n_en)) /= x"0" ELSE (OTHERS => 'Z');
|
||||
-- bufif1 buf_rdqs_n
|
||||
rdqs_n <= NOT dqs_out_dly WHEN (dqs_out_en_dly AND
|
||||
UNSIGNED'(0 TO DQS_BITS - 1 => out_en) AND
|
||||
UNSIGNED'(0 to DQS_BITS - 1 => dqs_n_en) AND
|
||||
UNSIGNED'(0 TO DQS_BITS - 1 => rdqs_en)) /= x"0" ELSE (OTHERS => 'Z');
|
||||
|
||||
-- bufif1 buf_dq
|
||||
dq <= dq_out_dly WHEN (dq_out_en_dly AND
|
||||
UNSIGNED'(0 TO DQ_BITS - 1 => out_en)) /= x"0" ELSE (OTHERS => 'Z');
|
||||
|
||||
-- initial block
|
||||
init : PROCESS
|
||||
BEGIN
|
||||
IF BL_MAX < 2 THEN
|
||||
REPORT("ERROR: BL_MAX parameter must be >= 2. BL_MAX=" & INTEGER'IMAGE(BL_MAX));
|
||||
END IF;
|
||||
|
||||
IF 2 ** BO_BITS > BL_MAX THEN
|
||||
REPORT("ERROR: 2**BO_BITS cannot be greater than BL_MAX parameter");
|
||||
END IF;
|
||||
seed <= RANDOM_SEED;
|
||||
ck_cntr <= 0;
|
||||
|
||||
WAIT;
|
||||
END PROCESS;
|
||||
|
||||
-- ugly kludge: encapsulate reset_task PROCEDURE into a process to make ModelSim happy
|
||||
reset : PROCESS
|
||||
PROCEDURE reset_task IS
|
||||
-- VARIABLE i : INTEGER;
|
||||
BEGIN
|
||||
-- disable inputs
|
||||
dq_in_valid <= '0';
|
||||
dqs_in_valid <= '0';
|
||||
wdqs_cntr <= 0;
|
||||
wdq_cntr <= 0;
|
||||
|
||||
FOR i IN 0 TO 35 LOOP
|
||||
wdqs_pos_cntr(i) <= 0;
|
||||
END LOOP;
|
||||
|
||||
b2b_write <= '0';
|
||||
|
||||
-- disable outputs
|
||||
out_en <= '0';
|
||||
dqs_n_en <= '0';
|
||||
rdqs_en <= '0';
|
||||
dq_out_en <= '0';
|
||||
rdq_cntr <= 0;
|
||||
dqs_out_en <= '0';
|
||||
rdqs_cntr <= 0;
|
||||
|
||||
-- disable ODT
|
||||
odt_en <= '0';
|
||||
odt_state <= '0';
|
||||
|
||||
-- reset bank state
|
||||
active_bank <= (OTHERS => '1');
|
||||
auto_precharge_bank <= (OTHERS =>'0');
|
||||
read_precharge_bank <= (OTHERS => '0');
|
||||
write_precharge_bank <= (OTHERS =>'0');
|
||||
|
||||
-- require initialization sequence
|
||||
init_done <= '0';
|
||||
init_step <= 0;
|
||||
init_mode_reg <= (OTHERS => '0');
|
||||
|
||||
-- reset DLL
|
||||
dll_en <= '0';
|
||||
dll_reset <= '0';
|
||||
dll_locked <= '0';
|
||||
ocd <= (OTHERS => '0');
|
||||
|
||||
-- exit power down and self refresh
|
||||
in_power_down <= '0';
|
||||
in_self_refresh <= '0';
|
||||
|
||||
-- clear pipelines
|
||||
al_pipeline <= (OTHERS => '0');
|
||||
wr_pipeline <= (OTHERS => '0');
|
||||
rd_pipeline <= (OTHERS => '0');
|
||||
odt_pipeline <= (OTHERS => '0');
|
||||
|
||||
-- clear memory
|
||||
FOR i IN 0 TO MAX_SIZE LOOP
|
||||
memory(i) <= (OTHERS => 'X');
|
||||
END LOOP;
|
||||
|
||||
-- clear maximum timing checks
|
||||
tm_refresh <= 0 ns;
|
||||
FOR i IN 0 TO BANKS - 1 LOOP
|
||||
tm_bank_activate(i) <= 0 ns;
|
||||
END LOOP;
|
||||
END reset_task;
|
||||
BEGIN
|
||||
WAIT UNTIL rising_edge(ck);
|
||||
IF r /= '0' THEN
|
||||
reset_task;
|
||||
r <= '0';
|
||||
END IF;
|
||||
END PROCESS; -- reset
|
||||
|
||||
err : PROCESS
|
||||
PROCEDURE chk_err(
|
||||
samebank : IN UNSIGNED (0 DOWNTO 0);
|
||||
bank : IN UNSIGNED (BA_BITS - 1 DOWNTO 0);
|
||||
fromcmd : IN UNSIGNED (3 DOWNTO 0);
|
||||
cmd : IN UNSIGNED (3 DOWNTO 0)
|
||||
) IS
|
||||
|
||||
VARIABLE err : STD_LOGIC;
|
||||
BEGIN
|
||||
-- all matching case expression will be evaluated
|
||||
|
||||
CASE? (samebank & fromcmd & cmd) IS
|
||||
WHEN "0" & cmd_type_encoding(LOAD_MODE) & "0---" =>
|
||||
IF ck_cntr - ck_load_mode < TMRD THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tMRD violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(LOAD_MODE) & "100-" =>
|
||||
IF ck_cntr - ck_load_mode < TMRD THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " INFO: Load Mode to Reset Condition");
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(REFRESH) & "0---" =>
|
||||
IF NOW - tm_refresh < TRFC_MIN THEN
|
||||
REPORT("tRFC violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(REFRESH) & cmd_type_encoding(PWR_DOWN) =>
|
||||
NULL; -- 1 tCK_avg
|
||||
|
||||
WHEN "0" & cmd_type_encoding(REFRESH) & cmd_type_encoding(SELF_REF) =>
|
||||
IF NOW - tm_refresh < TRFC_MIN THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & "INFO: Refresh to Reset condition");
|
||||
END IF;
|
||||
init_done <= '0';
|
||||
|
||||
WHEN "0" & cmd_type_encoding(PRECHARGE) & "000-" =>
|
||||
IF NOW - tm_precharge_all < TRPA THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRPA violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
IF NOW - tm_precharge < TRP THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRP violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
|
||||
WHEN "1" & cmd_type_encoding(PRECHARGE) & cmd_type_encoding(PRECHARGE) =>
|
||||
IF VERBOSE = TRUE AND NOW - tm_precharge_all < TRPA THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " INFO: Precharge All interruption during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
IF VERBOSE = TRUE AND NOW - tm_bank_precharge(TO_INTEGER(bank)) < TRP THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " INFO: Precharge Bank " & INTEGER'IMAGE(TO_INTEGER(bank)) & " interruption during "
|
||||
& cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
|
||||
WHEN "1" & cmd_type_encoding(PRECHARGE) & cmd_type_encoding(ACTIVATE) =>
|
||||
IF NOW - tm_precharge_all < TRPA THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRPA violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
IF NOW - tm_bank_precharge(TO_INTEGER(bank)) < TRP THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " tRP violation during " & cmd_string(TO_INTEGER(cmd)) & " to bank "
|
||||
& INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(PRECHARGE) & cmd_type_encoding(PWR_DOWN) =>
|
||||
-- 1 tCK, can be concurrent with auto precharge
|
||||
|
||||
WHEN "0" & cmd_type_encoding(PRECHARGE) & cmd_type_encoding(SELF_REF) =>
|
||||
IF NOW - tm_precharge_all < TRPA OR NOW - tm_precharge < TRP THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " INFO: Precharge to reset condition");
|
||||
init_done <= '0';
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(ACTIVATE) & cmd_type_encoding(REFRESH) =>
|
||||
IF NOW - tm_activate < TRC THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRC violation during " & cmd_string(TO_INTEGER(cmd)));
|
||||
END IF;
|
||||
|
||||
WHEN "1" & cmd_type_encoding(ACTIVATE) & cmd_type_encoding(PRECHARGE) =>
|
||||
IF NOW - tm_bank_activate(TO_INTEGER(bank)) > TRAS_MAX AND active_bank(TO_INTEGER(bank)) = '1' THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRAS maximum violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
IF NOW - tm_bank_activate(TO_INTEGER(bank)) < TRAS_MIN THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRAS minimum violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(ACTIVATE) & cmd_type_encoding(ACTIVATE) =>
|
||||
IF NOW - tm_activate < TRRD THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRRD violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "1" & cmd_type_encoding(ACTIVATE) & cmd_type_encoding(ACTIVATE) =>
|
||||
IF NOW - tm_bank_activate(TO_INTEGER(bank)) < TRC THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tRC violation during " & cmd_string(TO_INTEGER(cmd)) & " to bank " &
|
||||
INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "1" & cmd_type_encoding(ACTIVATE) & "010-" =>
|
||||
NULL; -- tRCD is checked outside this task
|
||||
|
||||
WHEN "1" & cmd_type_encoding(ACTIVATE) & cmd_type_encoding(PWR_DOWN) =>
|
||||
NULL; -- 1 tCK
|
||||
|
||||
WHEN "1" & cmd_type_encoding(WRITE_CMD) & cmd_type_encoding(PRECHARGE) =>
|
||||
IF ck_cntr - ck_bank_write(TO_INTEGER(bank))
|
||||
<= write_latency + TO_INTEGER(burst_length) + 2 OR
|
||||
NOW - tm_bank_write_end(TO_INTEGER(bank)) < TWR THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tWR violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(WRITE_CMD) & cmd_type_encoding(WRITE_CMD) =>
|
||||
IF ck_cntr - ck_write < TCCD THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tCCD violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(WRITE_CMD) & cmd_type_encoding(READ_CMD) =>
|
||||
IF ck_load_mode < ck_write AND ck_cntr - ck_write < write_latency + TO_INTEGER(burst_length) / 2 + 2 - additive_latency THEN
|
||||
REPORT("at time " & TIME'IMAGE(NOW) & " ERROR: tWTR violation during " & cmd_string(TO_INTEGER(cmd)) &
|
||||
" to bank " & INTEGER'IMAGE(TO_INTEGER(bank)));
|
||||
END IF;
|
||||
|
||||
WHEN "0" & cmd_type_encoding(WRITE_CMD) & cmd_type_encoding(PWR_DOWN) =>
|
||||
|
||||
|
||||
WHEN OTHERS =>
|
||||
NULL; -- do nothing
|
||||
|
||||
END CASE?;
|
||||
END;
|
||||
BEGIN
|
||||
WAIT UNTIL RISING_EDGE(ck);
|
||||
END PROCESS; -- err
|
||||
CONSTANT HB : INTEGER := B / 2;
|
||||
BEGIN
|
||||
END rtl;
|
||||
|
||||
@@ -469,15 +469,17 @@ BEGIN
|
||||
I_DDR_1 : ddr_ram_model
|
||||
PORT MAP
|
||||
(
|
||||
ck => clk_ddr_out,
|
||||
ck_n => clk_ddr_out_n,
|
||||
clk => clk_ddr_out,
|
||||
clkb => clk_ddr_out_n,
|
||||
cke => vcke,
|
||||
cs_n => vcs_n,
|
||||
ras_n => vras_n,
|
||||
cas_n => vcas_n,
|
||||
we_n => vwe_n,
|
||||
csb => vcs_n,
|
||||
rasb => vras_n,
|
||||
casb => vcas_n,
|
||||
web => vwe_n,
|
||||
ba => UNSIGNED(ba),
|
||||
addr => UNSIGNED(va),
|
||||
odt => '1'
|
||||
ad => va (12 DOWNTO 0),
|
||||
dqi => vd (30 DOWNTO 15),
|
||||
dm => UNSIGNED(vdm (3 DOWNTO 2)),
|
||||
dqs => vd_qs (3 DOWNTO 2)
|
||||
);
|
||||
END beh;
|
||||
Reference in New Issue
Block a user