started implementing SAMSUNG's Verilog DDR model in VHDL
This commit is contained in:
@@ -5,21 +5,6 @@ LIBRARY IEEE;
|
|||||||
LIBRARY work;
|
LIBRARY work;
|
||||||
|
|
||||||
PACKAGE ddr_ram_model_pkg IS
|
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
|
|
||||||
|
|
||||||
COMPONENT ddr_ram_model IS
|
COMPONENT ddr_ram_model IS
|
||||||
GENERIC
|
GENERIC
|
||||||
(
|
(
|
||||||
@@ -27,31 +12,33 @@ PACKAGE ddr_ram_model_pkg IS
|
|||||||
|
|
||||||
CLOCK_TICK : TIME := (1000000 / 132000) * 1 ps; -- time for one clock tick
|
CLOCK_TICK : TIME := (1000000 / 132000) * 1 ps; -- time for one clock tick
|
||||||
|
|
||||||
BA_BITS : INTEGER := 2; -- number of banks
|
NBANK : INTEGER := 4;
|
||||||
ADDR_BITS : INTEGER := 13; -- number of address bits
|
ADDRTOP : INTEGER := 12;
|
||||||
DM_BITS : INTEGER := 2; -- number of data mask bits
|
A10_LESS : BOOLEAN := TRUE; -- top column address is less than A10
|
||||||
DQ_BITS : INTEGER := 16; -- number of data bits
|
B : INTEGER := 16; -- number of bit (x16)
|
||||||
DQS_BITS : INTEGER := 2 -- number of data strobes
|
NCOL : INTEGER := 10; -- top column address is CA9 (NCOL- 1)
|
||||||
|
PAGEDEPTH : INTEGER := 1024;
|
||||||
|
NDM : INTEGER := 2;
|
||||||
|
NDQS : INTEGER := 2
|
||||||
);
|
);
|
||||||
PORT
|
PORT
|
||||||
(
|
(
|
||||||
ck : IN STD_LOGIC;
|
dqi : INOUT STD_LOGIC_VECTOR (B - 1 DOWNTO 0);
|
||||||
ck_n : IN STD_LOGIC;
|
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;
|
cke : IN STD_LOGIC;
|
||||||
cs_n : IN STD_LOGIC;
|
csb : IN STD_LOGIC;
|
||||||
ras_n : IN STD_LOGIC;
|
dm : IN UNSIGNED (NDM - 1 DOWNTO 0);
|
||||||
cas_n : IN STD_LOGIC;
|
dqs : INOUT STD_LOGIC_VECTOR (NDQS - 1 DOWNTO 0);
|
||||||
we_n : IN STD_LOGIC;
|
qfc : OUT 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
|
|
||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
END PACKAGE;
|
END PACKAGE;
|
||||||
|
|
||||||
PACKAGE BODY ddr_ram_model_pkg IS
|
PACKAGE BODY ddr_ram_model_pkg IS
|
||||||
@@ -70,715 +57,89 @@ ENTITY ddr_ram_model IS
|
|||||||
GENERIC
|
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
|
CLOCK_TICK : TIME := (1000000 / 132000) * 1 ps; -- time for one clock tick
|
||||||
|
|
||||||
BA_BITS : INTEGER := 2; -- number of banks
|
NBANK : INTEGER := 4;
|
||||||
ADDR_BITS : INTEGER := 13; -- number of address bits
|
ADDRTOP : INTEGER := 12;
|
||||||
DM_BITS : INTEGER := 2; -- number of data mask bits
|
A10_LESS : BOOLEAN := TRUE; -- top column address is less than A10
|
||||||
DQ_BITS : INTEGER := 8; -- number of data bits
|
B : INTEGER := 16; -- number of bit (x16)
|
||||||
DQS_BITS : INTEGER := 2 -- number of data strobes
|
NCOL : INTEGER := 10; -- top column address is CA9 (NCOL- 1)
|
||||||
|
PAGEDEPTH : INTEGER := 1024;
|
||||||
|
NDM : INTEGER := 2;
|
||||||
|
NDQS : INTEGER := 2
|
||||||
);
|
);
|
||||||
PORT
|
PORT
|
||||||
(
|
(
|
||||||
ck : IN STD_LOGIC;
|
dqi : INOUT STD_LOGIC_VECTOR (B - 1 DOWNTO 0);
|
||||||
ck_n : IN STD_LOGIC;
|
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;
|
cke : IN STD_LOGIC;
|
||||||
cs_n : IN STD_LOGIC;
|
csb : IN STD_LOGIC;
|
||||||
ras_n : IN STD_LOGIC;
|
dm : IN UNSIGNED (NDM - 1 DOWNTO 0);
|
||||||
cas_n : IN STD_LOGIC;
|
dqs : INOUT STD_LOGIC_VECTOR (NDQS - 1 DOWNTO 0);
|
||||||
we_n : IN STD_LOGIC;
|
qfc : OUT 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
|
|
||||||
);
|
);
|
||||||
END ENTITY ddr_ram_model;
|
END ENTITY ddr_ram_model;
|
||||||
|
|
||||||
ARCHITECTURE rtl OF ddr_ram_model IS
|
ARCHITECTURE rtl OF ddr_ram_model IS
|
||||||
-- DDR RAM size constants
|
-- DDR RAM timing 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;
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
-- time constants
|
CONSTANT TCCD : TIME := CLOCK_TICK; -- Col. address to col. address delay: 1 clk
|
||||||
CONSTANT BUS_DELAY : TIME := 0 ps;
|
|
||||||
|
|
||||||
-- time constants (in tCK's)
|
CONSTANT TCKMIN : TIME := 7.5 ps; -- Clock minimum cycle time
|
||||||
CONSTANT TMRD : INTEGER := 2; -- load mode register command cycle time
|
CONSTANT TCKMAX : TIME := 12 ps; -- Clock maximum cycle time
|
||||||
CONSTANT TCCD : INTEGER := 2; -- CAS to CAS command delay
|
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)
|
||||||
|
|
||||||
CONSTANT DQ_PER_DQS : INTEGER := DQ_BITS / DQS_BITS;
|
CONSTANT K1 : INTEGER := 1024;
|
||||||
CONSTANT MAX_SIZE : INTEGER := TO_INTEGER(SHIFT_LEFT(TO_UNSIGNED(1, 32), BA_BITS + ROW_BITS + COL_BITS - BL_BITS));
|
CONSTANT M1 : INTEGER := 1048576;
|
||||||
CONSTANT MEM_SIZE : INTEGER := TO_INTEGER(SHIFT_LEFT(TO_UNSIGNED(1, 32), MEM_BITS));
|
CONSTANT BYTE : INTEGER := 8;
|
||||||
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;
|
CONSTANT TBITS : INTEGER := 512 * M1;
|
||||||
|
|
||||||
-- clock jitter
|
--SIGNAL BITs : UNSIGNED (B - 1 DOWNTO 0);
|
||||||
SIGNAL tck_avg : REAL;
|
SIGNAL BIT_C : UNSIGNED (NCOL - 1 DOWNTO 0);
|
||||||
SIGNAL tck_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
CONSTANT NWORD : INTEGER := TBITS / B / NBANK;
|
||||||
SIGNAL tch_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
SIGNAL BIT_T : UNSIGNED (NCOL + ADDRTOP DOWNTO 0);
|
||||||
SIGNAL tcl_sample : time_array_t (TDLLK - 1 DOWNTO 0);
|
SIGNAL WORD : UNSIGNED (NWORD - 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"
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
|
CONSTANT HB : INTEGER := B / 2;
|
||||||
BEGIN
|
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
|
|
||||||
END rtl;
|
END rtl;
|
||||||
|
|||||||
@@ -469,15 +469,17 @@ BEGIN
|
|||||||
I_DDR_1 : ddr_ram_model
|
I_DDR_1 : ddr_ram_model
|
||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
ck => clk_ddr_out,
|
clk => clk_ddr_out,
|
||||||
ck_n => clk_ddr_out_n,
|
clkb => clk_ddr_out_n,
|
||||||
cke => vcke,
|
cke => vcke,
|
||||||
cs_n => vcs_n,
|
csb => vcs_n,
|
||||||
ras_n => vras_n,
|
rasb => vras_n,
|
||||||
cas_n => vcas_n,
|
casb => vcas_n,
|
||||||
we_n => vwe_n,
|
web => vwe_n,
|
||||||
ba => UNSIGNED(ba),
|
ba => UNSIGNED(ba),
|
||||||
addr => UNSIGNED(va),
|
ad => va (12 DOWNTO 0),
|
||||||
odt => '1'
|
dqi => vd (30 DOWNTO 15),
|
||||||
|
dm => UNSIGNED(vdm (3 DOWNTO 2)),
|
||||||
|
dqs => vd_qs (3 DOWNTO 2)
|
||||||
);
|
);
|
||||||
END beh;
|
END beh;
|
||||||
Reference in New Issue
Block a user