-------------------------------------------------------------------------------- -- File Name: mt46v16m16.vhd -------------------------------------------------------------------------------- -- Copyright (C) 2002-2004 Free Model Foundry; http://eda.org/fmf/ -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License version 2 as -- published by the Free Software Foundation. -- -- MODIFICATION HISTORY: -- -- version: | author: | mod date: | changes made: -- V1.0 M.Marinkovic 02 Dec 16 Initial release -- V1.1 R. Munden 03 MAR 15 Changed type of some _nwv signals to -- satisfy ncvhdl -- V1.2 R. Munden 03 MAR 22 Removed DM initialization requirement -- Added CLK skew check -- V1.3 R. Munden 03 MAR 25 Removed DM valid check added CSNeg nop -- V1.4 R. Munden 03 JUN 13 Changed initialize values of some sigs -- remove DM for reads, changed AR generic -- V1.5 R. Munden 03 JUN 16 Changed DQS to not drive 'X' -- adjusted CL=2 timing -- V1.6 R. Munden 03 JUL 03 Fixed address problem in burst reads -- V1.7 R. Munden 03 AUG 05 Fixed timing problem with tRCD -- V1.8 R. Munden 03 OCT 10 Enhaced memory preload capability -- V1.9 R. Munden 03 DEC 15 Fixed enhaced memory preload capability -- Fixed write burst problem -- V1.10 M.Marinkovic 03 Dec 29 Fixed DQS Latch (prior/at/after CLK -- edge -- v1.11 M.Marinkovic 04 Jan 15 Fixed row/column address width problem -- v1.12 M.Marinkovic 04 Jan 26 Added memory access procedures -- v1.13 A.Savic 04 Mar 19 DQS preamble burst interrupt bug fix -- Precharge after WRITE - tRW violation -- detect added -- V1.14 R. Munden 04 Jul 21 Made error message for tWR more detailed -- V1.15 R. Munden 04 Aug 23 Correct Detect_tWR_Violation -- Added wrt_bank variable -- V1.16 R. Munden 06 Jan 06 Correct Burst_Cnt on writes -- -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: RAM -- Technology: CMOS -- Part: mt46v16m16 -- -- Description: 4M x 16 x 4Banks Double Data Rate SDRAM -------------------------------------------------------------------------------- -- Note: -- Required simulator resolution 10ps or less -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE STD.textio.ALL; USE IEEE.VITAL_timing.all; USE IEEE.VITAL_primitives.all; LIBRARY FMF; USE FMF.gen_utils.ALL; USE FMF.conversions.ALL; -------------------------------------------------------------------------------- -- ENTITY DECLARATION -------------------------------------------------------------------------------- ENTITY mt46v16m16 IS GENERIC ( -- tipd delays: interconnect path delays tipd_BA0 : VitalDelayType01 := VitalZeroDelay01; tipd_BA1 : VitalDelayType01 := VitalZeroDelay01; tipd_LDQS : VitalDelayType01 := VitalZeroDelay01; tipd_UDQS : VitalDelayType01 := VitalZeroDelay01; tipd_LDM : VitalDelayType01 := VitalZeroDelay01; tipd_UDM : VitalDelayType01 := VitalZeroDelay01; tipd_DQ0 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ1 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ2 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ3 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ4 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ5 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ6 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ7 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ8 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ9 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ10 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ11 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ12 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ13 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ14 : VitalDelayType01 := VitalZeroDelay01; tipd_DQ15 : VitalDelayType01 := VitalZeroDelay01; tipd_CLKNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CLK : VitalDelayType01 := VitalZeroDelay01; tipd_CKE : VitalDelayType01 := VitalZeroDelay01; tipd_A0 : VitalDelayType01 := VitalZeroDelay01; tipd_A1 : VitalDelayType01 := VitalZeroDelay01; tipd_A2 : VitalDelayType01 := VitalZeroDelay01; tipd_A3 : VitalDelayType01 := VitalZeroDelay01; tipd_A4 : VitalDelayType01 := VitalZeroDelay01; tipd_A5 : VitalDelayType01 := VitalZeroDelay01; tipd_A6 : VitalDelayType01 := VitalZeroDelay01; tipd_A7 : VitalDelayType01 := VitalZeroDelay01; tipd_A8 : VitalDelayType01 := VitalZeroDelay01; tipd_A9 : VitalDelayType01 := VitalZeroDelay01; tipd_A10 : VitalDelayType01 := VitalZeroDelay01; tipd_A11 : VitalDelayType01 := VitalZeroDelay01; tipd_A12 : VitalDelayType01 := VitalZeroDelay01; tipd_WENeg : VitalDelayType01 := VitalZeroDelay01; tipd_RASNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CSNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CASNeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_CLK_DQ0 : VitalDelayType01Z := UnitDelay01Z; -- Access window / 2 tpd_CLK_DQ1 : VitalDelayType := UnitDelay; -- tpw values: pulse widths tpw_CLK_posedge : VitalDelayType := UnitDelay; tpw_CLK_negedge : VitalDelayType := UnitDelay; tpw_LDQS_posedge : VitalDelayType := UnitDelay; -- tsetup values: setup times tsetup_A0_CLK : VitalDelayType := UnitDelay; tsetup_DQ0_CLK : VitalDelayType := UnitDelay; tsetup_LDQS_CLK : VitalDelayType := UnitDelay; tsetup_DQ0_LDQS : VitalDelayType := UnitDelay; tsetup_LDM_LDQS : VitalDelayType := UnitDelay; -- thold values: hold times thold_A0_CLK : VitalDelayType := UnitDelay; thold_DQ0_CLK : VitalDelayType := UnitDelay; thold_LDQS_CLK : VitalDelayType := UnitDelay; thold_DQ0_LDQS : VitalDelayType := UnitDelay; thold_LDM_LDQS : VitalDelayType := UnitDelay; -- tperiod_min: minimum clock period = 1/max freq tperiod_CLK_posedge : VitalDelayType := UnitDelay; -- tskew values: skew times tskew_CLK_CLKNeg : VitalDelayType := UnitDelay; -- tdevice values: values for internal delays (for the -6) tdevice_REF : VitalDelayType := 15_625 ns; tdevice_TRC : VitalDelayType := 60 ns; tdevice_TRCD : VitalDelayType := 18 ns; tdevice_TRP : VitalDelayType := 18 ns; tdevice_TRFC : VitalDelayType := 72 ns; tdevice_TWR : VitalDelayType := 15 ns; tdevice_TRAS : VitalDelayType01 := (42 ns, 70_000 ns); -- tpowerup: Power up initialization time. Data sheets say 200 us. -- May be shortened during simulation debug. tpowerup : TIME := 2 us; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; SeverityMode : SEVERITY_LEVEL := WARNING; -- memory file to be loaded mem_file_name : STRING :="none"; --"mt46v16m16.mem"; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( BA0 : IN std_logic := 'U'; BA1 : IN std_logic := 'U'; LDM : IN std_logic := 'U'; UDM : IN std_logic := 'U'; LDQS : INOUT std_logic := 'U'; UDQS : INOUT std_logic := 'U'; DQ0 : INOUT std_logic := 'U'; DQ1 : INOUT std_logic := 'U'; DQ2 : INOUT std_logic := 'U'; DQ3 : INOUT std_logic := 'U'; DQ4 : INOUT std_logic := 'U'; DQ5 : INOUT std_logic := 'U'; DQ6 : INOUT std_logic := 'U'; DQ7 : INOUT std_logic := 'U'; DQ8 : INOUT std_logic := 'U'; DQ9 : INOUT std_logic := 'U'; DQ10 : INOUT std_logic := 'U'; DQ11 : INOUT std_logic := 'U'; DQ12 : INOUT std_logic := 'U'; DQ13 : INOUT std_logic := 'U'; DQ14 : INOUT std_logic := 'U'; DQ15 : INOUT std_logic := 'U'; CLK : IN std_logic := 'U'; CLKNeg : IN std_logic := 'U'; CKE : IN std_logic := 'U'; A0 : IN std_logic := 'U'; A1 : IN std_logic := 'U'; A2 : IN std_logic := 'U'; A3 : IN std_logic := 'U'; A4 : IN std_logic := 'U'; A5 : IN std_logic := 'U'; A6 : IN std_logic := 'U'; A7 : IN std_logic := 'U'; A8 : IN std_logic := 'U'; A9 : IN std_logic := 'U'; A10 : IN std_logic := 'U'; A11 : IN std_logic := 'U'; A12 : IN std_logic := 'U'; WENeg : IN std_logic := 'U'; RASNeg : IN std_logic := 'U'; CSNeg : IN std_logic := 'U'; CASNeg : IN std_logic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of mt46v16m16 : ENTITY IS TRUE; END mt46v16m16; -------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION -------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of mt46v16m16 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "mt46v16m16"; CONSTANT hi_bank : NATURAL := 3; CONSTANT HiAddrBit : NATURAL := 12; CONSTANT HiColBit : NATURAL := 8; CONSTANT HiDataBit : NATURAL := 15; CONSTANT depth : NATURAL := 16#3FFFFF#; --<< for simulation purpose -- real value is 16#3FFFFF#; SIGNAL CKEreg : X01 := 'X'; SIGNAL PoweredUp : boolean := false; SIGNAL BA0_ipd : std_ulogic := 'U'; SIGNAL BA1_ipd : std_ulogic := 'U'; SIGNAL LDQS_ipd : std_ulogic := 'U'; SIGNAL UDQS_ipd : std_ulogic := 'U'; SIGNAL LDM_ipd : std_ulogic := 'U'; SIGNAL UDM_ipd : std_ulogic := 'U'; SIGNAL DQ0_ipd : std_ulogic := 'U'; SIGNAL DQ1_ipd : std_ulogic := 'U'; SIGNAL DQ2_ipd : std_ulogic := 'U'; SIGNAL DQ3_ipd : std_ulogic := 'U'; SIGNAL DQ4_ipd : std_ulogic := 'U'; SIGNAL DQ5_ipd : std_ulogic := 'U'; SIGNAL DQ6_ipd : std_ulogic := 'U'; SIGNAL DQ7_ipd : std_ulogic := 'U'; SIGNAL DQ8_ipd : std_ulogic := 'U'; SIGNAL DQ9_ipd : std_ulogic := 'U'; SIGNAL DQ10_ipd : std_ulogic := 'U'; SIGNAL DQ11_ipd : std_ulogic := 'U'; SIGNAL DQ12_ipd : std_ulogic := 'U'; SIGNAL DQ13_ipd : std_ulogic := 'U'; SIGNAL DQ14_ipd : std_ulogic := 'U'; SIGNAL DQ15_ipd : std_ulogic := 'U'; SIGNAL CLK_ipd : std_ulogic := 'U'; SIGNAL CLKNeg_ipd : std_ulogic := 'U'; SIGNAL CKE_ipd : std_ulogic := 'U'; SIGNAL A0_ipd : std_ulogic := 'U'; SIGNAL A1_ipd : std_ulogic := 'U'; SIGNAL A2_ipd : std_ulogic := 'U'; SIGNAL A3_ipd : std_ulogic := 'U'; SIGNAL A4_ipd : std_ulogic := 'U'; SIGNAL A5_ipd : std_ulogic := 'U'; SIGNAL A6_ipd : std_ulogic := 'U'; SIGNAL A7_ipd : std_ulogic := 'U'; SIGNAL A8_ipd : std_ulogic := 'U'; SIGNAL A9_ipd : std_ulogic := 'U'; SIGNAL A10_ipd : std_ulogic := 'U'; SIGNAL A11_ipd : std_ulogic := 'U'; SIGNAL A12_ipd : std_ulogic := 'U'; SIGNAL WENeg_ipd : std_ulogic := 'U'; SIGNAL RASNeg_ipd : std_ulogic := 'U'; SIGNAL CSNeg_ipd : std_ulogic := 'U'; SIGNAL CASNeg_ipd : std_ulogic := 'U'; SIGNAL BA0_nwv : std_ulogic := 'U'; SIGNAL BA1_nwv : std_ulogic := 'U'; SIGNAL LDQS_nwv : std_ulogic := 'U'; SIGNAL UDQS_nwv : std_ulogic := 'U'; SIGNAL LDM_nwv : std_ulogic := 'U'; SIGNAL UDM_nwv : std_ulogic := 'U'; SIGNAL DQ0_nwv : UX01 := 'U'; SIGNAL DQ1_nwv : UX01 := 'U'; SIGNAL DQ2_nwv : UX01 := 'U'; SIGNAL DQ3_nwv : UX01 := 'U'; SIGNAL DQ4_nwv : UX01 := 'U'; SIGNAL DQ5_nwv : UX01 := 'U'; SIGNAL DQ6_nwv : UX01 := 'U'; SIGNAL DQ7_nwv : UX01 := 'U'; SIGNAL DQ8_nwv : UX01 := 'U'; SIGNAL DQ9_nwv : UX01 := 'U'; SIGNAL DQ10_nwv : UX01 := 'U'; SIGNAL DQ11_nwv : UX01 := 'U'; SIGNAL DQ12_nwv : UX01 := 'U'; SIGNAL DQ13_nwv : UX01 := 'U'; SIGNAL DQ14_nwv : UX01 := 'U'; SIGNAL DQ15_nwv : UX01 := 'U'; SIGNAL A0_nwv : UX01 := 'U'; SIGNAL A1_nwv : UX01 := 'U'; SIGNAL A2_nwv : UX01 := 'U'; SIGNAL A3_nwv : UX01 := 'U'; SIGNAL A4_nwv : UX01 := 'U'; SIGNAL A5_nwv : UX01 := 'U'; SIGNAL A6_nwv : UX01 := 'U'; SIGNAL A7_nwv : UX01 := 'U'; SIGNAL A8_nwv : UX01 := 'U'; SIGNAL A9_nwv : UX01 := 'U'; SIGNAL A10_nwv : UX01 := 'U'; SIGNAL A11_nwv : UX01 := 'U'; SIGNAL A12_nwv : UX01 := 'U'; SIGNAL CLK_nwv : std_ulogic := 'U'; SIGNAL CLKNeg_nwv : std_ulogic := 'U'; SIGNAL CKE_nwv : std_ulogic := 'U'; SIGNAL WENeg_nwv : std_ulogic := 'U'; SIGNAL RASNeg_nwv : std_ulogic := 'U'; SIGNAL CSNeg_nwv : std_ulogic := 'U'; SIGNAL CASNeg_nwv : std_ulogic := 'U'; SIGNAL CKSKWtrg : std_ulogic := '0'; SIGNAL rct_in : std_ulogic := '0'; SIGNAL rct_out : std_ulogic := '0'; SIGNAL rcdt_in : std_ulogic_vector(3 downto 0) := (others => '0'); SIGNAL rcdt_out : std_ulogic_vector(3 downto 0) := (others => '0'); SIGNAL pre_in : std_ulogic := '0'; SIGNAL pre_out : std_ulogic := '0'; SIGNAL refreshed_in : std_ulogic := '0'; SIGNAL refreshed_out : std_ulogic := '0'; SIGNAL rfc_out : std_ulogic := '0'; SIGNAL rfc_in : std_ulogic := '0'; SIGNAL wrt_in : std_ulogic := '0'; SIGNAL wrt_out : std_ulogic := '0'; SIGNAL ras_in : std_ulogic_vector(3 downto 0) := (others => '0'); SIGNAL ras_out : std_ulogic_vector(3 downto 0) := (others => '0'); SIGNAL wrt_glitch : std_ulogic := '0'; SIGNAL Viol_tWR_in : std_ulogic_vector(3 downto 0) := (others => '0'); SIGNAL Viol_tWR_out : std_ulogic_vector(3 downto 0) := (others => '1'); SHARED VARIABLE cur_bank : natural range 0 to hi_bank; SHARED VARIABLE wrt_bank : natural range 0 to hi_bank; BEGIN ---------------------------------------------------------------------------- -- Internal Delays ---------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays REF : VitalBuf (refreshed_out, refreshed_in, (UnitDelay, tdevice_REF)); TRC : VitalBuf (rct_out, rct_in, (tdevice_TRC, VitalZeroDelay)); TRCD : VitalBuf (rcdt_out(0), rcdt_in(0), (VitalZeroDelay, tdevice_TRCD)); TRCD1 : VitalBuf (rcdt_out(1), rcdt_in(1), (VitalZeroDelay, tdevice_TRCD)); TRCD2 : VitalBuf (rcdt_out(2), rcdt_in(2), (VitalZeroDelay, tdevice_TRCD)); TRCD3 : VitalBuf (rcdt_out(3), rcdt_in(3), (VitalZeroDelay, tdevice_TRCD)); TRP : VitalBuf (pre_out, pre_in, (tdevice_TRP, UnitDelay)); TRFC : VitalBuf (rfc_out, rfc_in, (tdevice_TRFC, UnitDelay)); TWR : VitalBuf (wrt_out, wrt_in, (UnitDelay, tdevice_TWR)); TRAS : VitalBuf (ras_out(0), ras_in(0), tdevice_TRAS); TRAS1 : VitalBuf (ras_out(1), ras_in(1), tdevice_TRAS); TRAS2 : VitalBuf (ras_out(2), ras_in(2), tdevice_TRAS); TRAS3 : VitalBuf (ras_out(3), ras_in(3), tdevice_TRAS); ---------------------------------------------------------------------------- -- Wire Delays ---------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (BA0_ipd, BA0, tipd_BA0); w_2 : VitalWireDelay (BA1_ipd, BA1, tipd_BA1); w_3 : VitalWireDelay (LDQS_ipd, LDQS, tipd_LDQS); w_51: VitalWireDelay (UDQS_ipd, UDQS, tipd_UDQS); w_4 : VitalWireDelay (LDM_ipd, LDM, tipd_LDM); w_52: VitalWireDelay (UDM_ipd, UDM, tipd_UDM); w_5 : VitalWireDelay (DQ0_ipd, DQ0, tipd_DQ0); w_6 : VitalWireDelay (DQ1_ipd, DQ1, tipd_DQ1); w_7 : VitalWireDelay (DQ2_ipd, DQ2, tipd_DQ2); w_8 : VitalWireDelay (DQ3_ipd, DQ3, tipd_DQ3); w_9 : VitalWireDelay (DQ4_ipd, DQ4, tipd_DQ4); w_10 : VitalWireDelay (DQ5_ipd, DQ5, tipd_DQ5); w_11 : VitalWireDelay (DQ6_ipd, DQ6, tipd_DQ6); w_12 : VitalWireDelay (DQ7_ipd, DQ7, tipd_DQ7); w_55 : VitalWireDelay (DQ8_ipd, DQ8, tipd_DQ8); w_56 : VitalWireDelay (DQ9_ipd, DQ9, tipd_DQ9); w_57 : VitalWireDelay (DQ10_ipd, DQ10, tipd_DQ10); w_58 : VitalWireDelay (DQ11_ipd, DQ11, tipd_DQ11); w_59 : VitalWireDelay (DQ12_ipd, DQ12, tipd_DQ12); w_60 : VitalWireDelay (DQ13_ipd, DQ13, tipd_DQ13); w_61 : VitalWireDelay (DQ14_ipd, DQ14, tipd_DQ14); w_62 : VitalWireDelay (DQ15_ipd, DQ15, tipd_DQ15); w_21 : VitalWireDelay (CLKNeg_ipd, CLKNeg, tipd_CLKNeg); w_22 : VitalWireDelay (CLK_ipd, CLK, tipd_CLK); w_23 : VitalWireDelay (CKE_ipd, CKE, tipd_CKE); w_24 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_25 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_26 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_27 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_28 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_29 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_30 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_31 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_32 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_33 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_34 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_35 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_36 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_47 : VitalWireDelay (WENeg_ipd, WENeg, tipd_WENeg); w_48 : VitalWireDelay (RASNeg_ipd, RASNeg, tipd_RASNeg); w_49 : VitalWireDelay (CSNeg_ipd, CSNeg, tipd_CSNeg); w_50 : VitalWireDelay (CASNeg_ipd, CASNeg, tipd_CASNeg); END BLOCK; WENeg_nwv <= To_UX01(WENeg_ipd); RASNeg_nwv <= To_UX01(RASNeg_ipd); CSNeg_nwv <= To_UX01(CSNeg_ipd); CASNeg_nwv <= To_UX01(CASNeg_ipd); CLKNeg_nwv <= To_UX01(CLKNeg_ipd); CLK_nwv <= To_UX01(CLK_ipd); CKE_nwv <= To_UX01(CKE_ipd); BA0_nwv <= To_UX01(BA0_ipd); BA1_nwv <= To_UX01(BA1_ipd); LDM_nwv <= To_UX01(LDM_ipd); UDM_nwv <= To_UX01(UDM_ipd); LDQS_nwv <= To_UX01(LDQS_ipd); UDQS_nwv <= To_UX01(UDQS_ipd); DQ0_nwv <= To_UX01(DQ0_ipd); DQ1_nwv <= To_UX01(DQ1_ipd); DQ2_nwv <= To_UX01(DQ2_ipd); DQ3_nwv <= To_UX01(DQ3_ipd); DQ4_nwv <= To_UX01(DQ4_ipd); DQ5_nwv <= To_UX01(DQ5_ipd); DQ6_nwv <= To_UX01(DQ6_ipd); DQ7_nwv <= To_UX01(DQ7_ipd); DQ8_nwv <= To_UX01(DQ8_ipd); DQ9_nwv <= To_UX01(DQ9_ipd); DQ10_nwv <= To_UX01(DQ10_ipd); DQ11_nwv <= To_UX01(DQ11_ipd); DQ12_nwv <= To_UX01(DQ12_ipd); DQ13_nwv <= To_UX01(DQ13_ipd); DQ14_nwv <= To_UX01(DQ14_ipd); DQ15_nwv <= To_UX01(DQ15_ipd); A0_nwv <= To_UX01(A0_ipd); A1_nwv <= To_UX01(A1_ipd); A2_nwv <= To_UX01(A2_ipd); A3_nwv <= To_UX01(A3_ipd); A4_nwv <= To_UX01(A4_ipd); A5_nwv <= To_UX01(A5_ipd); A6_nwv <= To_UX01(A6_ipd); A7_nwv <= To_UX01(A7_ipd); A8_nwv <= To_UX01(A8_ipd); A9_nwv <= To_UX01(A9_ipd); A10_nwv <= To_UX01(A10_ipd); A11_nwv <= To_UX01(A11_ipd); A12_nwv <= To_UX01(A12_ipd); ---------------------------------------------------------------------------- -- Main Behavior Block ---------------------------------------------------------------------------- Main : BLOCK PORT ( BAIn : IN std_logic_vector(1 downto 0); LDMIn : IN std_ulogic := 'U'; UDMIn : IN std_ulogic := 'U'; LDQSIn : IN std_ulogic := 'U'; UDQSIn : IN std_ulogic := 'U'; DataIn : IN std_logic_vector(HiDataBit downto 0); DataOut : OUT std_logic_vector(HiDataBit downto 0) := (others => 'Z'); LDQSOut : OUT std_ulogic := 'Z'; UDQSOut : OUT std_ulogic := 'Z'; CLK_In : IN std_ulogic := 'U'; CLKNeg_In : IN std_ulogic := 'U'; CKEIn : IN std_ulogic := 'U'; AddressIn : IN std_logic_vector(HiAddrBit downto 0); WENegIn : IN std_ulogic := 'U'; RASNegIn : IN std_ulogic := 'U'; CSNegIn : IN std_ulogic := 'U'; CASNegIn : IN std_ulogic := 'U' ); PORT MAP ( BAIn(0) => BA0_nwv, BAIn(1) => BA1_nwv, LDMIn => LDM_nwv, UDMIn => UDM_nwv, LDQSIn => LDQS_nwv, LDQSOut => LDQS, UDQSIn => UDQS_nwv, UDQSOut => UDQS, DataOut(0) => DQ0, DataOut(1) => DQ1, DataOut(2) => DQ2, DataOut(3) => DQ3, DataOut(4) => DQ4, DataOut(5) => DQ5, DataOut(6) => DQ6, DataOut(7) => DQ7, DataOut(8) => DQ8, DataOut(9) => DQ9, DataOut(10) => DQ10, DataOut(11) => DQ11, DataOut(12) => DQ12, DataOut(13) => DQ13, DataOut(14) => DQ14, DataOut(15) => DQ15, DataIn(0) => DQ0_nwv, DataIn(1) => DQ1_nwv, DataIn(2) => DQ2_nwv, DataIn(3) => DQ3_nwv, DataIn(4) => DQ4_nwv, DataIn(5) => DQ5_nwv, DataIn(6) => DQ6_nwv, DataIn(7) => DQ7_nwv, DataIn(8) => DQ8_nwv, DataIn(9) => DQ9_nwv, DataIn(10) => DQ10_nwv, DataIn(11) => DQ11_nwv, DataIn(12) => DQ12_nwv, DataIn(13) => DQ13_nwv, DataIn(14) => DQ14_nwv, DataIn(15) => DQ15_nwv, CLK_In => CLK_nwv, CLKNEG_In => CLKNeg_nwv, CKEIn => CKE_nwv, AddressIn(0) => A0_nwv, AddressIn(1) => A1_nwv, AddressIn(2) => A2_nwv, AddressIn(3) => A3_nwv, AddressIn(4) => A4_nwv, AddressIn(5) => A5_nwv, AddressIn(6) => A6_nwv, AddressIn(7) => A7_nwv, AddressIn(8) => A8_nwv, AddressIn(9) => A9_nwv, AddressIn(10) => A10_nwv, AddressIn(11) => A11_nwv, AddressIn(12) => A12_nwv, WENegIn => WENeg_nwv, RASNegIn => RASNeg_nwv, CSNegIn => CSNeg_nwv, CASNegIn => CASNeg_nwv ); -- Type definition for state machine TYPE mem_state IS (pwron, precharge, idle, mode_set, self_refresh, self_refresh_rec, auto_refresh, pwrdwn, bank_act, bank_act_pwrdwn, write, write_suspend, read, read_suspend, write_auto_pre, read_auto_pre, write_sec, read_sec ); TYPE statebanktype IS array (hi_bank downto 0) of mem_state; SIGNAL statebank : statebanktype; SIGNAL next_statebank : statebanktype; SIGNAL CAS_Lat : NATURAL RANGE 2 to 3 := 2; SIGNAL D_zd : std_logic_vector(HiDataBit DOWNTO 0); SIGNAL LDQS_zd : std_logic; SIGNAL UDQS_zd : std_logic; SIGNAL DLL_EN : boolean := false; SIGNAL DLL_reset : boolean := false; SIGNAL PERIOD : time := 50 ns; -- CLK period SIGNAL CLKint : std_ulogic := '0'; SIGNAL CLKtemp : std_ulogic := '0'; SIGNAL CLKcomb : std_ulogic := '0'; SIGNAL HalfPer : Time := 0 ns; SIGNAL dlldelay : Time := 0 ns; ----------------------------------------------------------------------- SIGNAL clk_tmp1 : std_logic; SIGNAL clkneg_tmp1 : std_logic; SIGNAL clk_tmp2 : std_logic; SIGNAL clkneg_tmp2 : std_logic; SIGNAL CLKIn : std_logic; SIGNAL CLKNegIn : std_logic; BEGIN --------------------------------------------------------------------------- --delta cycle fix --------------------------------------------------------------------------- clk_tmp1 <= CLK_In ; clkneg_tmp1 <= CLKNeg_In; clk_tmp2 <= clk_tmp1; clkneg_tmp2 <= clkneg_tmp1; CLKIn <= clk_tmp2; --fixed CLKNegIn <= clkneg_tmp2; --fixed --------------------------------------------------------------------------- PoweredUp <= true after tpowerup; CLKcomb <= CLKIn AND not(CLKNegIn); ---------------------------------------------- -- DLL model functional section --- ---------------------------------------------- DLL: PROCESS(CLKcomb, CLKIn, CLKNegIn, CKSKWtrg) -- Timing Check Variables VARIABLE Sviol_CLK_CLKNeg : X01 := '0'; VARIABLE SD_CLK_CLKNeg : VitalSkewDataType := VitalSkewDataInit; -- Functionality Results Variables VARIABLE Violation : X01 := '0'; VARIABLE Previous : Time := 0 ns; VARIABLE TmpPer : Time := 0 ns; BEGIN -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalOutPhaseSkewCheck ( Signal1 => CLKIn, Signal1Name => "CLK", Signal2 => CLKNegIn, Signal2Name => "CLKNeg", SkewS1S2RiseFall => tskew_CLK_CLKNeg, SkewS2S1RiseFall => tskew_CLK_CLKNeg, SkewS1S2FallRise => tskew_CLK_CLKNeg, SkewS2S1FallRise => tskew_CLK_CLKNeg, CheckEnabled => TRUE, HeaderMsg => InstancePath & PartID, SkewData => SD_CLK_CLKNeg, Trigger => CKSKWtrg, XOn => XOn, MsgOn => MsgOn, Violation => Sviol_CLK_CLKNeg ); Violation := Sviol_CLK_CLKNeg; END IF; -- Timing Check Section -------------------------------------------------------------------- -- Functional Section -------------------------------------------------------------------- IF rising_edge(CLKcomb) AND DLL_reset = TRUE THEN TmpPer := NOW - Previous; IF TmpPer > 0 ns THEN PERIOD <= TmpPer; END IF; Previous := NOW; HalfPer <= PERIOD/2; dlldelay <= PERIOD - tpd_CLK_DQ1; END IF; END PROCESS DLL; CLK_temp : PROCESS (CLKcomb)-- generating internal clock from DLL BEGIN IF DLL_reset = FALSE THEN CLKtemp <= TRANSPORT not(CLKtemp) AFTER HalfPer; END IF; END PROCESS; CLK_int : PROCESS (CLKcomb, CLKtemp)-- Passing clock based on DLL_EN BEGIN IF DLL_EN AND NOT DLL_RESET then CLKint <= TRANSPORT CLKtemp AFTER dlldelay; CLKint <= CLKcomb; END IF; END PROCESS; Detect_tWR_Violation : PROCESS( wrt_glitch, Viol_tWR_out ) BEGIN IF rising_edge(wrt_glitch) THEN Viol_tWR_in(wrt_bank) <= '0', '1' AFTER 1 ns; END IF; IF rising_edge(Viol_tWR_out(0)) THEN Viol_tWR_in(0) <= '0'; END IF; IF rising_edge(Viol_tWR_out(1)) THEN Viol_tWR_in(1) <= '0'; END IF; IF rising_edge(Viol_tWR_out(2)) THEN Viol_tWR_in(2) <= '0'; END IF; IF rising_edge(Viol_tWR_out(3)) THEN Viol_tWR_in(3) <= '0'; END IF; END PROCESS Detect_tWR_Violation; tWR_Timing_Control : PROCESS( Viol_tWR_in ) BEGIN IF rising_edge(Viol_tWR_in(0)) THEN Viol_tWR_out(0) <= '0', '1' AFTER (tdevice_TWR - 1 ns); END IF; IF rising_edge(Viol_tWR_in(1)) THEN Viol_tWR_out(1) <= '0', '1' AFTER (tdevice_TWR - 1 ns); END IF; IF rising_edge(Viol_tWR_in(2)) THEN Viol_tWR_out(2) <= '0', '1' AFTER (tdevice_TWR - 1 ns); END IF; IF rising_edge(Viol_tWR_in(3)) THEN Viol_tWR_out(3) <= '0', '1' AFTER (tdevice_TWR - 1 ns); END IF; END PROCESS tWR_Timing_Control; ---------------------------------------------------------------------------- -- Main Behavior Process ---------------------------------------------------------------------------- Behavior : PROCESS (BAIn, LDMIn, UDMIn, LDQSIn, UDQSIn, DataIn, CLKIn, CLKNegIn, CLKint, CKEIn, AddressIn, WENegIn, RASNegIn, CSNegIn, CASNegIn, PoweredUp) -- Type definition for commands TYPE command_type is (desl, nop, bst, read, writ, act, pre, mrs, ref ); -- Timing Check Variables VARIABLE Tviol_BA_CLK : X01 := '0'; VARIABLE TD_BA_CLK : VitalTimingDataType; VARIABLE Tviol_LDM_LDQS : X01 := '0'; VARIABLE TD_LDM_LDQS : VitalTimingDataType; VARIABLE Tviol_UDM_UDQS : X01 := '0'; VARIABLE TD_UDM_UDQS : VitalTimingDataType; VARIABLE Tviol_D0_CLK : X01 := '0'; VARIABLE TD_D0_CLK : VitalTimingDataType; VARIABLE Tviol_LDQS_CLK : X01 := '0'; VARIABLE TD_LDQS_CLK : VitalTimingDataType; VARIABLE Tviol_UDQS_CLK : X01 := '0'; VARIABLE TD_UDQS_CLK : VitalTimingDataType; VARIABLE Tviol_CKE_CLK : X01 := '0'; VARIABLE TD_CKE_CLK : VitalTimingDataType; VARIABLE Tviol_Address_CLK : X01 := '0'; VARIABLE TD_Address_CLK : VitalTimingDataType; VARIABLE Tviol_WENeg_CLK : X01 := '0'; VARIABLE TD_WENeg_CLK : VitalTimingDataType; VARIABLE Tviol_RASNeg_CLK : X01 := '0'; VARIABLE TD_RASNeg_CLK : VitalTimingDataType; VARIABLE Tviol_CSNeg_CLK : X01 := '0'; VARIABLE TD_CSNeg_CLK : VitalTimingDataType; VARIABLE Tviol_CASNeg_CLK : X01 := '0'; VARIABLE TD_CASNeg_CLK : VitalTimingDataType; VARIABLE Tviol_D8_UDQS : X01 := '0'; VARIABLE TD_D8_UDQS : VitalTimingDataType; VARIABLE Tviol_D0_LDQS : X01 := '0'; VARIABLE TD_D0_LDQS : VitalTimingDataType; VARIABLE Pviol_CLK : X01 := '0'; VARIABLE PD_CLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_UDQS : X01 := '0'; VARIABLE PD_UDQS : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_LDQS : X01 := '0'; VARIABLE PD_LDQS : VitalPeriodDataType := VitalPeriodDataInit; -- Memory array declaration TYPE MemStore IS ARRAY (0 to depth) OF INTEGER RANGE -2 TO 255; TYPE MemBlock IS ARRAY (0 to 3) OF MemStore; TYPE mode_set_type IS (standard, extended); TYPE Burst_type IS (sequential, interleave); TYPE Write_Burst_type IS (programmed, single); TYPE sequence IS ARRAY (0 to 7) OF NATURAL RANGE 0 to 7; TYPE seqtab IS ARRAY (0 to 7) OF sequence; TYPE MemLoc IS ARRAY (0 to 3) OF std_logic_vector(HiAddrBit+HiColBit+1 DOWNTO 0); TYPE burst_counter IS ARRAY (0 to 3) OF NATURAL RANGE 0 to 257; TYPE StartAddr_type IS ARRAY (0 to 3) OF NATURAL RANGE 0 TO 7; TYPE Burst_Inc_type IS ARRAY (0 to 3) OF NATURAL RANGE 0 TO 8; TYPE BaseLoc_type IS ARRAY (0 to 3) OF NATURAL RANGE 0 TO depth; SUBTYPE OutWord IS std_logic_vector(15 DOWNTO 0); CONSTANT seq0 : sequence := (0 & 1 & 2 & 3 & 4 & 5 & 6 & 7); CONSTANT seq1 : sequence := (1 & 0 & 3 & 2 & 5 & 4 & 7 & 6); CONSTANT seq2 : sequence := (2 & 3 & 0 & 1 & 6 & 7 & 4 & 5); CONSTANT seq3 : sequence := (3 & 2 & 1 & 0 & 7 & 6 & 5 & 4); CONSTANT seq4 : sequence := (4 & 5 & 6 & 7 & 0 & 1 & 2 & 3); CONSTANT seq5 : sequence := (5 & 4 & 7 & 6 & 1 & 0 & 3 & 2); CONSTANT seq6 : sequence := (6 & 7 & 4 & 5 & 2 & 3 & 0 & 1); CONSTANT seq7 : sequence := (7 & 6 & 5 & 4 & 3 & 2 & 1 & 0); CONSTANT intab : seqtab := (seq0, seq1, seq2, seq3, seq4, seq5, seq6, seq7); FILE mem_file : text IS mem_file_name; VARIABLE UMemData : MemBlock; VARIABLE LMemData : MemBlock; VARIABLE file_bank : NATURAL := 0; VARIABLE ind : NATURAL := 0; VARIABLE buf : line; VARIABLE mode_set_ind : mode_set_type ; VARIABLE MemAddr : MemLoc; VARIABLE Location : NATURAL RANGE 0 TO depth := 0; VARIABLE Location2 : NATURAL RANGE 0 TO depth := 0; VARIABLE BaseLoc : BaseLoc_type; VARIABLE Burst_Inc : Burst_Inc_type; VARIABLE StartAddr : StartAddr_type; VARIABLE Burst_Length : NATURAL RANGE 2 TO 8 := 2; VARIABLE Burst_Bits : NATURAL RANGE 1 TO 3 := 1; VARIABLE Burst : Burst_Type; VARIABLE Burst_Cnt : burst_counter; VARIABLE command : command_type; VARIABLE written : boolean := false; VARIABLE chip_en : boolean := false; VARIABLE write_to_write : boolean := false; VARIABLE LDQS_event_reg : boolean := false; VARIABLE UDQS_event_reg : boolean := false; VARIABLE ModeReg : std_logic_vector(12 DOWNTO 0) := (OTHERS => 'X'); VARIABLE ExtModeReg : std_logic_vector(12 DOWNTO 0) := (OTHERS => 'X'); VARIABLE Ref_Cnt : NATURAL RANGE 0 TO 8192 := 0; VARIABLE next_ref : TIME; VARIABLE BankString : STRING(8 DOWNTO 1) := " Bank-X "; -- Functionality Results Variables VARIABLE Violation : X01 := '0'; VARIABLE DataDriveOut : std_logic_vector(HiDataBit DOWNTO 0) := (OTHERS => 'Z'); VARIABLE DataDrive : OutWord; VARIABLE DataDrive1 : OutWord; VARIABLE DataDrive2 : OutWord; VARIABLE DataDrive3 : OutWord; VARIABLE DataDrive4 : OutWord; VARIABLE DataDrive5 : OutWord; VARIABLE DataDrive6 : OutWord; VARIABLE LDM_reg0 : UX01; VARIABLE LDM_reg1 : UX01; VARIABLE LDM_reg2 : UX01; VARIABLE UDM_reg0 : UX01; VARIABLE UDM_reg1 : UX01; VARIABLE UDM_reg2 : UX01; VARIABLE LDQSDriveOut : std_logic; VARIABLE LDQSDrive : std_logic; VARIABLE LDQSDrive1 : std_logic; VARIABLE LDQSDrive2 : std_logic; VARIABLE LDQSDrive3 : std_logic; VARIABLE LDQSDrive4 : std_logic; VARIABLE LDQSDrive5 : std_logic; VARIABLE LDQSDrive6 : std_logic; VARIABLE LDQSDrive7 : std_logic; VARIABLE LDQS_zd : std_logic; VARIABLE LDQS_GlitchData : VitalGlitchDataType; VARIABLE UDQSDriveOut : std_logic; VARIABLE UDQSDrive : std_logic; VARIABLE UDQSDrive1 : std_logic; VARIABLE UDQSDrive2 : std_logic; VARIABLE UDQSDrive3 : std_logic; VARIABLE UDQSDrive4 : std_logic; VARIABLE UDQSDrive5 : std_logic; VARIABLE UDQSDrive6 : std_logic; VARIABLE UDQSDrive7 : std_logic; VARIABLE UDQS_zd : std_logic; VARIABLE UDQS_GlitchData : VitalGlitchDataType; VARIABLE UInputReg : INTEGER RANGE -2 TO 255; VARIABLE LInputReg : INTEGER RANGE -2 TO 255; PROCEDURE FixColumnAddress( bank : IN NATURAL RANGE 0 TO 3) IS BEGIN MemAddr(bank)(HiColBit downto 0) := (others => '0'); MemAddr(bank)(HiColBit downto Burst_Bits) := AddressIn(HiColBit downto Burst_Bits); -- Burst_Inc(bank) := to_nat(AddressIn(Burst_Bits-1 downto 0)); StartAddr(bank) := Burst_Inc(bank) mod 8; BaseLoc(bank) := to_nat(MemAddr(bank)); Location := BaseLoc(bank) + Burst_Inc(bank); END PROCEDURE ; PROCEDURE ReadFromMem( bank : IN NATURAL RANGE 0 TO 3) IS BEGIN LDQSDrive:='0'; UDQSDrive:='0'; IF LMemData(Bank)(Location) = -2 THEN DataDrive(7 downto 0) := (others => 'U'); ELSIF LMemData(Bank)(Location) = -1 THEN DataDrive(7 downto 0) := (others => 'X'); ELSE DataDrive(7 downto 0):= to_slv(LMemData(Bank)(Location),8); END IF; IF UMemData(Bank)(Location) = -2 THEN DataDrive(15 downto 8) := (others => 'U'); ELSIF UMemData(Bank)(Location) = -1 THEN DataDrive(15 downto 8) := (others => 'X'); ELSE DataDrive(15 downto 8) := to_slv(UMemData(Bank)(Location),8); END IF; END; PROCEDURE WriteToMem( bank : IN NATURAL RANGE 0 TO 3) IS BEGIN IF LDQS_event_reg THEN IF Violation = '0' THEN LMemData(Bank)(Location) := LInputReg; ELSE LMemData(Bank)(Location) := -1; END IF; END IF; IF UDQS_event_reg THEN IF Violation = '0' THEN UMemData(Bank)(Location) := UInputReg; ELSE UMemData(Bank)(Location) := -1; END IF; END IF; END; PROCEDURE BurstCtrl( bank : IN NATURAL RANGE 0 TO 3) IS BEGIN IF (Burst = sequential) THEN Burst_Inc(bank) := (Burst_Inc(bank) + 1) MOD Burst_Length; ELSE Burst_Inc(bank) := intab(StartAddr(bank)) (Burst_Cnt(bank)); END IF; END; BEGIN -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => BAIn, TestSignalName => "BA", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_DQ0_CLK, SetupLow => tsetup_DQ0_CLK, HoldHigh => thold_DQ0_CLK, HoldLow => thold_DQ0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_BA_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_BA_CLK ); VitalSetupHoldCheck ( TestSignal => LDMIn, TestSignalName => "LDM", RefSignal => LDQSIn, RefSignalName => "LDQS", SetupHigh => tsetup_LDM_LDQS, SetupLow => tsetup_LDM_LDQS, HoldHigh => thold_LDM_LDQS, HoldLow => thold_LDM_LDQS, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_LDM_LDQS, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LDM_LDQS ); VitalSetupHoldCheck ( TestSignal => UDMIn, TestSignalName => "UDM", RefSignal => UDQSIn, RefSignalName => "UDQS", SetupHigh => tsetup_LDM_LDQS, SetupLow => tsetup_LDM_LDQS, HoldHigh => thold_LDM_LDQS, HoldLow => thold_LDM_LDQS, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_UDM_UDQS, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_UDM_UDQS ); VitalSetupHoldCheck ( TestSignal => DataIn, TestSignalName => "Data", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_DQ0_CLK, SetupLow => tsetup_DQ0_CLK, HoldHigh => thold_DQ0_CLK, HoldLow => thold_DQ0_CLK, CheckEnabled => chip_en AND NOT(DataIn(0)='X' AND D_zd(0)='Z'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D0_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D0_CLK ); VitalSetupHoldCheck ( TestSignal => DataIn(15 downto 8), TestSignalName => "Data", RefSignal => UDQSIn, RefSignalName => "UDQS", SetupHigh => tsetup_DQ0_LDQS, SetupLow => tsetup_DQ0_LDQS, HoldHigh => thold_DQ0_LDQS, HoldLow => thold_DQ0_LDQS, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D8_UDQS, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D8_UDQS ); VitalSetupHoldCheck ( TestSignal => DataIn(7 downto 0), TestSignalName => "Data", RefSignal => LDQSIn, RefSignalName => "LDQS", SetupHigh => tsetup_DQ0_LDQS, SetupLow => tsetup_DQ0_LDQS, HoldHigh => thold_DQ0_LDQS, HoldLow => thold_DQ0_LDQS, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D0_LDQS, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D0_LDQS ); VitalSetupHoldCheck ( TestSignal => LDQSIn, TestSignalName => "LDQS", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_LDQS_CLK, HoldHigh => thold_LDQS_CLK, CheckEnabled => chip_en AND (NOT LDQSIn=LDQS_zd), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_LDQS_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LDQS_CLK ); VitalSetupHoldCheck ( TestSignal => UDQSIn, TestSignalName => "UDQS", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_LDQS_CLK, HoldHigh => thold_LDQS_CLK, CheckEnabled => chip_en AND (NOT UDQSIn=UDQS_zd), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_UDQS_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_UDQS_CLK ); VitalSetupHoldCheck ( TestSignal => CKEIn, TestSignalName => "CKE", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_DQ0_CLK, SetupLow => tsetup_DQ0_CLK, HoldHigh => thold_DQ0_CLK, HoldLow => thold_DQ0_CLK, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CKE_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CKE_CLK ); VitalSetupHoldCheck ( TestSignal => AddressIn, TestSignalName => "Address", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_A0_CLK, SetupLow => tsetup_A0_CLK, HoldHigh => thold_A0_CLK, HoldLow => thold_A0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_Address_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_Address_CLK ); VitalSetupHoldCheck ( TestSignal => WENegIn, TestSignalName => "WENeg", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_A0_CLK, SetupLow => tsetup_A0_CLK, HoldHigh => thold_A0_CLK, HoldLow => thold_A0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WENeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WENeg_CLK ); VitalSetupHoldCheck ( TestSignal => RASNegIn, TestSignalName => "RASNeg", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_A0_CLK, SetupLow => tsetup_A0_CLK, HoldHigh => thold_A0_CLK, HoldLow => thold_A0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_RASNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RASNeg_CLK ); VitalSetupHoldCheck ( TestSignal => CSNegIn, TestSignalName => "CSNeg", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_A0_CLK, SetupLow => tsetup_A0_CLK, HoldHigh => thold_A0_CLK, HoldLow => thold_A0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CSNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CSNeg_CLK ); VitalSetupHoldCheck ( TestSignal => CASNegIn, TestSignalName => "CASNeg", RefSignal => CLKIn, RefSignalName => "CLK", SetupHigh => tsetup_A0_CLK, SetupLow => tsetup_A0_CLK, HoldHigh => thold_A0_CLK, HoldLow => thold_A0_CLK, CheckEnabled => chip_en, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_CASNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CASNeg_CLK ); VitalPeriodPulseCheck ( TestSignal => CLKIn, TestSignalName => "CLK", Period => tperiod_CLK_posedge, PulseWidthLow => tpw_CLK_negedge, PulseWidthHigh => tpw_CLK_posedge, PeriodData => PD_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CLK, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE ); VitalPeriodPulseCheck ( TestSignal => LDQSIn, TestSignalName => "LDQSIn", PulseWidthLow => tpw_LDQS_posedge, PulseWidthHigh => tpw_LDQS_posedge, PeriodData => PD_LDQS, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_LDQS, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE ); VitalPeriodPulseCheck ( TestSignal => UDQSIn, TestSignalName => "CLK", PulseWidthLow => tpw_LDQS_posedge, PulseWidthHigh => tpw_LDQS_posedge, PeriodData => PD_UDQS, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_UDQS, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE ); Violation := Pviol_LDQS OR Pviol_UDQS OR Pviol_CLK OR Tviol_BA_CLK OR Tviol_LDM_LDQS OR Tviol_UDM_UDQS OR Tviol_LDQS_CLK OR Tviol_UDQS_CLK OR Tviol_D8_UDQS OR Tviol_D0_LDQS OR Tviol_CKE_CLK OR Tviol_Address_CLK OR Tviol_WENeg_CLK OR Tviol_RASNeg_CLK OR Tviol_CSNeg_CLK OR Tviol_CASNeg_CLK; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY SeverityMode; END IF; -- Timing Check Section -------------------------------------------------------------------- -- Functional Section -------------------------------------------------------------------- IF (rising_edge(CLKIn)) THEN CKEreg <= CKE_nwv; IF (NOW > Next_Ref AND PoweredUp AND Ref_Cnt > 0) THEN Ref_Cnt := Ref_Cnt - 1; Next_Ref := NOW + tdevice_REF; END IF; IF CKEreg = '1' THEN IF CSNegIn = '0' THEN chip_en := true; ELSE chip_en := false; END IF; END IF; END IF; IF (rising_edge(LDQSin) OR falling_edge(LDQSIn)) AND (LDM_nwv = '0') AND NOT(LDQSin=LDQS_zd) THEN LInputReg := to_nat(DataIn(7 downto 0)); LDQS_event_reg := TRUE; END IF; IF (rising_edge(UDQSin) OR falling_edge(UDQSIn)) AND (UDM_nwv = '0') AND NOT(UDQSin=UDQS_zd) THEN UInputReg := to_nat(DataIn(15 downto 8)); UDQS_event_reg := TRUE; END IF; IF (rising_edge(CLKIn) AND CKEreg = '1' AND to_X01(CSNegIn) = '1') THEN command := nop; ELSIF (rising_edge(CLKIn) AND CKEreg = '1' AND to_X01(CSNegIn) = '0') THEN ASSERT (not(Is_X(WENegIn))) REPORT InstancePath & partID & ": Unusable value for WENeg" SEVERITY SeverityMode; ASSERT (not(Is_X(RASNegIn))) REPORT InstancePath & partID & ": Unusable value for RASNeg" SEVERITY SeverityMode; ASSERT (not(Is_X(CASNegIn))) REPORT InstancePath & partID & ": Unusable value for CASNeg" SEVERITY SeverityMode; -- Command Decode IF ((RASNegIn = '1') AND (CASNegIn = '1') AND (WENegIn = '1')) THEN command := nop; ELSIF ((RASNegIn = '0') AND (CASNegIn = '1') AND (WENegIn = '1')) THEN command := act; ELSIF ((RASNegIn = '1') AND (CASNegIn = '0') AND (WENegIn = '1')) THEN command := read; ELSIF ((RASNegIn = '1') AND (CASNegIn = '0') AND (WENegIn = '0')) THEN command := writ; ELSIF ((RASNegIn = '1') AND (CASNegIn = '1') AND (WENegIn = '0')) THEN command := bst; ELSIF ((RASNegIn = '0') AND (CASNegIn = '1') AND (WENegIn = '0')) THEN command := pre; ELSIF ((RASNegIn = '0') AND (CASNegIn = '0') AND (WENegIn = '1')) THEN command := ref; ELSIF ((RASNegIn = '0') AND (CASNegIn = '0') AND (WENegIn = '0')) THEN command := mrs; END IF; -- PowerUp Check IF (NOT(PoweredUp) AND command /= nop) THEN ASSERT false REPORT InstancePath & partID & ": Incorrect power up. Command" & " issued before power up complete." SEVERITY SeverityMode; END IF; -- Bank Decode CASE BAIn IS WHEN "00" => cur_bank := 0; BankString := " Bank-0 "; WHEN "01" => cur_bank := 1; BankString := " Bank-1 "; WHEN "10" => cur_bank := 2; BankString := " Bank-2 "; WHEN "11" => cur_bank := 3; BankString := " Bank-3 "; WHEN others => ASSERT false REPORT InstancePath & partID & ": Could not decode bank" & " selection - results may be incorrect." SEVERITY SeverityMode; END CASE; IF command = pre THEN IF ( AddressIn(10) = '1' AND ( (NOT Viol_tWR_out) /= "0000" ) ) OR ( AddressIn(10) = '0' AND Viol_tWR_out(wrt_bank) = '0' AND wrt_bank = cur_bank ) THEN REPORT InstancePath & partID & ": Precharge command violates" & " tWR for bank " & to_bin_str(wrt_bank) & " - results may be incorrect." SEVERITY SeverityMode; END IF; END IF; END IF; IF (rising_edge(CLKIn) AND CKEreg = '1') THEN ASSERT (not(Is_X(CSNegIn))) REPORT InstancePath & partID & ": Unusable value for CSNeg" SEVERITY SeverityMode; IF (CSNegIn = '1') THEN command := nop; END IF; -- DM pipeline LDM_reg2 := LDM_reg1; LDM_reg1 := LDM_reg0; LDM_reg0 := LDMIn; UDM_reg2 := UDM_reg1; UDM_reg1 := UDM_reg0; UDM_reg0 := UDMIn; -- by default data drive is Z, might get over written in one -- of the passes below DataDrive := (OTHERS => 'Z'); LDQSDrive:='Z'; UDQSDrive:='Z'; END IF; -- The Big State Machine IF (rising_edge(CLKIn) AND CKEreg = '1') THEN banks : FOR bank IN 0 TO hi_bank LOOP CASE statebank(bank) IS WHEN pwron => IF (PoweredUp = false) THEN ASSERT (command = nop) REPORT InstancePath & partID & BankString &": Only NOPs allowed" & " during power up." SEVERITY SeverityMode; DataDrive := (OTHERS => 'Z'); ELSIF (command = pre) AND ((cur_bank = bank) OR (AddressIn(10) = '1')) THEN statebank(bank) <= precharge, idle AFTER tdevice_TRP; END IF; WHEN precharge => IF cur_bank = bank THEN -- It is only an error if this bank is selected ASSERT (command = nop OR command = pre) REPORT InstancePath & partID & BankString &": Illegal command received" & " during precharge." SEVERITY SeverityMode; END IF; WHEN idle => IF (command = nop OR command = bst OR command = pre) OR (cur_bank /= bank) THEN null; ELSIF (command = mrs) THEN IF (statebank = idle & idle & idle & idle) THEN IF BAIn = "01" THEN mode_set_ind:= extended; ExtModeReg := AddressIn; ELSE mode_set_ind:= standard; ModeReg := AddressIn; END IF; statebank <= mode_set & mode_set & mode_set & mode_set; END IF; ELSIF (command = ref) THEN IF (statebank = idle & idle & idle & idle) THEN IF (CKEIn = '1') THEN statebank(bank) <= auto_refresh, idle AFTER tdevice_TRFC; ELSE statebank(bank) <= self_refresh; END IF; END IF; ELSIF (command = act) THEN statebank(bank) <= bank_act; ras_in(bank) <= '1', '0' AFTER 70 ns; rct_in <= '1', '0' AFTER 10 ps; rcdt_in(bank) <= '1', '0' AFTER 10 ps; MemAddr(bank)(HiAddrBit+HiColBit+1 downto HiColBit +1) := AddressIn; -- latch row addr ELSE ASSERT false REPORT InstancePath & partID & ": Illegal command" & " received in idle state." SEVERITY SeverityMode; END IF; WHEN mode_set => statebank <= idle & idle & idle & idle; IF mode_set_ind=standard THEN ASSERT (ModeReg(7) = '0') REPORT InstancePath & partID & BankString &": Illegal operating mode set." SEVERITY SeverityMode; ASSERT command = nop REPORT InstancePath & partID & BankString & ": Illegal command received during mode_set." SEVERITY SeverityMode; -- read burst length IF (ModeReg(2 downto 0) = "001") THEN Burst_Length := 2; Burst_Bits := 1; ELSIF (ModeReg(2 downto 0) = "010") THEN Burst_Length := 4; Burst_Bits := 2; ELSIF (ModeReg(2 downto 0) = "011") THEN Burst_Length := 8; Burst_Bits := 3; ELSE ASSERT false REPORT InstancePath & partID & BankString &": Invalid burst length specified." SEVERITY SeverityMode; END IF; -- read burst type IF (ModeReg(3) = '0') THEN Burst := sequential; ELSIF (ModeReg(3) = '1') THEN Burst := interleave; ELSE ASSERT false REPORT InstancePath & partID & BankString &": Invalid burst type specified." SEVERITY SeverityMode; END IF; -- read CAS latency IF (ModeReg(6 downto 4) = "010") THEN CAS_Lat <= 2; ELSIF (ModeReg(6 downto 4) = "110") THEN CAS_Lat <= 3; ELSE ASSERT false REPORT InstancePath & partID & BankString & ": CAS Latency set incorrecty " SEVERITY SeverityMode; END IF; IF (ModeReg(8) = '1') THEN DLL_reset <= TRUE; ELSE DLL_reset <= FALSE; END IF; ELSIF mode_set_ind=extended THEN IF (ExtModeReg( 0) = '0') THEN DLL_EN <= TRUE; ELSE DLL_EN <= FALSE; END IF; END IF; WHEN auto_refresh => IF (Ref_Cnt < 8192) THEN Ref_Cnt := Ref_Cnt + 1; END IF; ASSERT command = nop REPORT InstancePath & partID & BankString & ": Illegal command received during auto_refresh." SEVERITY SeverityMode; WHEN bank_act => IF (command = pre) AND ((cur_bank = bank) OR (AddressIn(10) = '1')) THEN ASSERT ras_out(bank) = '1' REPORT InstancePath & partID & BankString & ": precharge command" & " does not meet tRAS time." SEVERITY SeverityMode; statebank(bank) <= precharge, idle AFTER tdevice_TRP; ELSIF (command = nop OR command = bst) OR (cur_bank /= bank) THEN null; ELSIF (command = read) THEN ASSERT rcdt_out(bank) = '0' REPORT InstancePath & partID & BankString & ": read command received too soon after active." SEVERITY SeverityMode; ASSERT ((AddressIn(10) = '0') OR (AddressIn(10) = '1')) REPORT InstancePath & partID & BankString & ": AddressIn(10) = X" & " during read command. Next state unknown." SEVERITY SeverityMode; FixColumnAddress(bank); -- IF NOT(UDQSDrive2='0' AND UDQSDrive3='0') THEN -- UDQSDrive1:='0'; -- END IF; IF (UDQSDrive1='Z') THEN UDQSDrive1:='0'; END IF; -- IF NOT(LDQSDrive2='0' AND LDQSDrive3='0') THEN -- LDQSDrive1:='0'; -- END IF; IF (LDQSDrive1='Z') THEN LDQSDrive1:='0'; END IF; ReadFromMem(bank); Burst_Cnt(bank) := 0; statebank(bank)<=read_sec; IF (AddressIn(10) = '0') THEN next_statebank(bank) <= read; ELSIF (AddressIn(10) = '1') THEN next_statebank(bank) <= read_auto_pre; END IF; ELSIF (command = writ) THEN ASSERT rcdt_out(bank) = '0' REPORT InstancePath & partID & BankString & ": write command" & " received too soon after active." SEVERITY SeverityMode; FixColumnAddress(bank); Burst_Cnt(bank) := 0; ASSERT ((AddressIn(10) = '0') OR (AddressIn(10) = '1')) REPORT InstancePath & partID & BankString & ": AddressIn(10) = X" & " during write command. Next state unknown." SEVERITY SeverityMode; IF (AddressIn(10) = '0') THEN statebank(bank) <= write; wrt_bank := cur_bank; ELSIF (AddressIn(10) = '1') THEN statebank(bank) <= write_auto_pre; END IF; written := true; ELSIF (cur_bank = bank) OR (command = mrs) THEN ASSERT false REPORT InstancePath & partID & BankString & ": Illegal command " & "received in active state." SEVERITY SeverityMode; END IF; WHEN write => IF (command = bst) THEN IF rising_edge(CLKIn) THEN ASSERT false REPORT InstancePath & partID & BankString & ": Illegal command " & "received in write state." SEVERITY SeverityMode; END IF; ELSIF (command = read) THEN IF cur_bank = bank THEN FixColumnAddress(bank); Burst_Cnt(bank) := 0; ReadFromMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; statebank(bank) <= read_sec; IF (AddressIn(10) = '0') THEN next_statebank(bank) <= read; ELSIF (AddressIn(10) = '1') THEN next_statebank(bank) <= read_auto_pre; END IF; ELSE statebank(bank) <= bank_act; END IF; ELSIF (command = writ) THEN IF (Burst_Cnt(bank) = Burst_Length) THEN statebank(bank) <= bank_act; Burst_Cnt(bank) := 0; ras_in(bank) <= '1'; Burst_Inc(bank) := 0; wrt_bank := cur_bank; ELSE statebank(bank) <= write_sec; WriteToMem(bank); Location2 := Location; write_to_write := TRUE; Burst_Inc(bank) := 0; FixColumnAddress(bank); ASSERT ((AddressIn(10) = '0') OR (AddressIn(10) = '1')) REPORT InstancePath & partID & BankString & ": AddressIn(10) = X" & " during write command. Next state unknown." SEVERITY SeverityMode; IF (AddressIn(10) = '0') THEN next_statebank(bank) <= write; ELSIF (AddressIn(10) = '1') THEN next_statebank(bank) <= write_auto_pre; END IF; Burst_Cnt(bank) := 0; wrt_in <= '1'; wrt_glitch <= '1', '0' AFTER 1 ns; written := true; END IF; IF cur_bank /= bank THEN next_statebank(bank) <= bank_act; ELSE next_statebank(bank)<=write; END IF; ELSIF (command = pre) AND ((cur_bank = bank) OR (AddressIn(10) = '1')) THEN ASSERT ras_out(bank) = '1' REPORT InstancePath & partID & BankString & ": precharge command" & " does not meet tRAS time." SEVERITY SeverityMode; ASSERT (LDM_nwv = '1') REPORT InstancePath & partID & BankString & ": LDM should be" & " held high, data is lost." SEVERITY SeverityMode; statebank(bank) <= precharge, idle AFTER tdevice_TRP; ASSERT (UDM_nwv = '1') REPORT InstancePath & partID & BankString & ": UDM should be" & " held high, data is lost." SEVERITY SeverityMode; statebank(bank) <= precharge, idle AFTER tdevice_TRP; ELSIF (command = nop) OR (cur_bank /= bank) THEN IF (Burst_Cnt(bank) = Burst_Length) THEN statebank(bank) <= bank_act; Burst_Cnt(bank) := 0; ras_in(bank) <= '1'; Burst_Inc(bank) := 0; ELSE statebank(bank) <= write_sec; next_statebank(bank)<=write; Location := BaseLoc(bank) + Burst_Inc(bank); BurstCtrl(bank); WriteToMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; wrt_in <= '1'; wrt_glitch <= '1', '0' AFTER 1 ns; END IF; ELSIF cur_bank = bank THEN ASSERT false REPORT InstancePath & partID & ": Illegal command" & " received in write state." SEVERITY SeverityMode; END IF; WHEN read => IF (command = bst) THEN statebank(bank) <= bank_act; Burst_Cnt(bank) := 0; Burst_Inc(bank) := 0; LDQSDrive:='0'; UDQSDrive:='0'; ELSIF (command = read) THEN IF cur_bank = bank THEN FixColumnAddress(bank); Burst_Cnt(bank) := 0; ReadFromMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; statebank(bank) <= read_sec; IF (AddressIn(10) = '0') THEN next_statebank(bank) <= read; ELSIF (AddressIn(10) = '1') THEN next_statebank(bank) <= read_auto_pre; END IF; ELSE statebank(bank) <= bank_act; END IF; ELSIF (command = writ) THEN IF cur_bank = bank THEN IF (Burst_Cnt(bank) = Burst_Length) THEN statebank(bank) <= bank_act; Burst_Cnt(bank) := 0; ras_in(bank) <= '1'; Burst_Inc(bank) := 0; wrt_bank := cur_bank; ELSE statebank(bank) <= write_sec; next_statebank(bank)<=write; WriteToMem(bank); Location2 := Location; write_to_write := TRUE; FixColumnAddress(bank); ASSERT ((AddressIn(10) = '0') OR (AddressIn(10) = '1')) REPORT InstancePath & partID & BankString & ": AddressIn(10) = X" & " during write command. Next state unknown." SEVERITY SeverityMode; IF (AddressIn(10) = '0') THEN next_statebank(bank) <= write; ELSIF (AddressIn(10) = '1') THEN next_statebank(bank) <= write_auto_pre; END IF; Burst_Cnt(bank) := 0; wrt_in <= '1'; wrt_glitch <= '1', '0' AFTER 1 ns; written := true; END IF; ELSE statebank(bank)<=bank_act; END IF; ELSIF (command = pre) AND ((cur_bank = bank) OR (AddressIn(10) = '1')) THEN statebank(bank) <= precharge, idle AFTER tdevice_TRP; ASSERT ras_out(bank) = '1' REPORT InstancePath & partID & BankString & ": precharge command" & " does not meet tRAS time." SEVERITY SeverityMode; ELSIF (command = nop) OR (cur_bank /= bank) THEN IF (Burst_Cnt(bank) >= Burst_Length -1) THEN statebank(bank) <= bank_act; Burst_Cnt(bank) := 0; LDQSDrive:='0'; UDQSDrive:='0'; ras_in(bank) <= '1'; Burst_Inc(bank) := 0; ELSE statebank(bank) <= read_sec; next_statebank(bank)<=read; BurstCtrl(bank); Location := BaseLoc(bank) + Burst_Inc(bank); ReadFromMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; END IF; ELSIF cur_bank = bank THEN ASSERT false REPORT InstancePath & partID & BankString & ": Illegal command" & " received in read state." SEVERITY SeverityMode; END IF; WHEN write_auto_pre => IF (command = nop) OR (cur_bank /= bank) THEN IF (Burst_Cnt(bank) = Burst_Length ) THEN statebank(bank) <= precharge, idle AFTER tdevice_TRP; Burst_Cnt(bank) := 0; ras_in(bank) <= '1'; Burst_Inc(bank) := 0; ELSE statebank(bank) <= write_sec; next_statebank(bank)<=write_auto_pre; Location := BaseLoc(bank) + Burst_Inc(bank); BurstCtrl(bank); WriteToMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; wrt_in <= '1'; wrt_glitch <= '1', '0' AFTER 1 ns; END IF; ELSE ASSERT false REPORT InstancePath & partID & BankString & ": Illegal command" & " received in write state." SEVERITY SeverityMode; END IF; WHEN read_auto_pre => IF (command = nop) OR (cur_bank /= bank) THEN IF (Burst_Cnt(bank) >= Burst_Length-1) THEN statebank(bank) <= precharge, idle AFTER tdevice_TRP; Burst_Cnt(bank) := 0; ras_in(bank) <= '1'; LDQSDrive:='0'; UDQSDrive:='0'; Burst_Inc(bank) := 0; ELSE statebank(bank) <= read_sec; next_statebank(bank)<=read_auto_pre; BurstCtrl(bank); Location := BaseLoc(bank) + Burst_Inc(bank); ReadFromMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; END IF; ELSIF (command = read) AND (cur_bank /= bank) THEN statebank(bank) <= precharge, idle AFTER tdevice_TRP; ELSE ASSERT false REPORT InstancePath & partID & BankString & ": Illegal command" & " received in read state." SEVERITY SeverityMode; END IF; WHEN others => null; END CASE; END LOOP banks; -- Check Refresh Status IF (written = true) THEN ASSERT Ref_Cnt > 0 REPORT InstancePath & partID & ": memory not refreshed (by ref_cnt)" SEVERITY SeverityMode; END IF; END IF; -- Second DATA READ WRITE (DDR) -- IF (rising_edge(CLKNegIn) AND CKEreg = '1') THEN banks2 : FOR bank IN 0 TO hi_bank LOOP CASE statebank(bank) IS WHEN write_sec => statebank(bank) <= next_statebank(bank); IF write_to_write THEN Location := Location2 + 1; ELSE Location := BaseLoc(bank) + Burst_Inc(bank); END IF; BurstCtrl(bank); WriteToMem(bank); Burst_Cnt(bank) := Burst_Cnt(bank) + 1; wrt_in <= '1'; wrt_glitch <= '1', '0' AFTER 1 ns; IF write_to_write --AND Burst_Cnt(bank) = Burst_Length THEN Burst_Inc(bank) := 0; Burst_Cnt(bank) := 0; Write_to_write := false; ELSE Location := BaseLoc(bank) + Burst_Inc(bank); END IF; WHEN read_sec => statebank(bank) <= next_statebank(bank); BurstCtrl(bank); Location := BaseLoc(bank) + Burst_Inc(bank); ReadFromMem(bank); LDQSDrive := '1'; UDQSDrive := '1'; Burst_Cnt(bank) := Burst_Cnt(bank) + 1; WHEN bank_act => IF (command=nop OR command=bst) AND (cur_bank = bank) THEN LDQSDrive:='Z'; UDQSDrive:='Z'; END IF; WHEN others => null; END CASE; END LOOP banks2; END IF; -- Latency adjustments and DM read masking IF rising_edge(CLKIn) OR rising_edge(CLKNegIn) THEN LDQS_event_reg := FALSE; UDQS_event_reg := FALSE; END IF; IF rising_edge(CLKInt) OR falling_edge(CLKInt) THEN IF CKEreg = '1' THEN DataDrive6 := DataDrive5; DataDrive5 := DataDrive4; DataDrive4 := DataDrive3; DataDrive3 := DataDrive2; DataDrive2 := DataDrive1; DataDrive1 := DataDrive; LDQSDrive6 := LDQSDrive5; LDQSDrive5 := LDQSDrive4; LDQSDrive4 := LDQSDrive3; LDQSDrive3 := LDQSDrive2; LDQSDrive2 := LDQSDrive1; LDQSDrive1 := LDQSDrive; UDQSDrive6 := UDQSDrive5; UDQSDrive5 := UDQSDrive4; UDQSDrive4 := UDQSDrive3; UDQSDrive3 := UDQSDrive2; UDQSDrive2 := UDQSDrive1; UDQSDrive1 := UDQSDrive; END IF; IF (CAS_Lat = 3) THEN DataDriveOut(15 downto 8) := DataDrive6(15 downto 8); UDQSDriveOut := UDQSDrive5; DataDriveOut(7 downto 0) := DataDrive6(7 downto 0); LDQSDriveOut := LDQSDrive5; ELSE DataDriveOut(15 downto 8) := DataDrive5(15 downto 8); UDQSDriveOut := UDQSDrive4; DataDriveOut(7 downto 0) := DataDrive5(7 downto 0); LDQSDriveOut := LDQSDrive4; END IF; END IF; -- The Powering-down State Machine IF (rising_edge(CLKIn) AND CKEreg = '1' AND CKEIn = '0') THEN ASSERT (not(Is_X(CSNegIn))) REPORT InstancePath & partID & ": Unusable value for CSNeg" SEVERITY SeverityMode; IF (CSNegIn = '1') THEN command := nop; END IF; CASE statebank(cur_bank) IS WHEN idle => IF (command = nop) THEN statebank <= pwrdwn & pwrdwn & pwrdwn & pwrdwn; ELSIF (command = ref) THEN statebank <= self_refresh & self_refresh & self_refresh & self_refresh; END IF; WHEN write => statebank(cur_bank) <= write_suspend; WHEN read => statebank(cur_bank) <= read_suspend; WHEN bank_act => IF (command = writ) THEN statebank(cur_bank) <= write_suspend; ELSIF (command = read) THEN statebank(cur_bank) <= read_suspend; ELSE statebank(cur_bank) <= bank_act_pwrdwn; END IF; WHEN others => null; END CASE; END IF; -- The Powering-up State Machine IF (rising_edge(CLKIn) AND CKEreg = '0' AND CKEIn = '1') THEN ASSERT (not(Is_X(CSNegIn))) REPORT InstancePath & partID & ": Unusable value for CSNeg" SEVERITY SeverityMode; IF (CSNegIn = '1') THEN command := nop; END IF; CASE statebank(cur_bank) IS WHEN write_suspend => statebank(cur_bank) <= write; WHEN read_suspend => statebank(cur_bank) <= read; WHEN self_refresh => statebank <= idle & idle & idle & idle after tdevice_TRP; Ref_Cnt := 8192; ASSERT command = nop REPORT InstancePath & partID & ": Illegal command received" & " during self_refresh." SEVERITY SeverityMode; WHEN pwrdwn => statebank <= idle & idle & idle & idle; WHEN bank_act_pwrdwn => statebank(cur_bank) <= bank_act; WHEN others => null; END CASE; END IF; -------------------------------------------------------------------- -- File Read Section -------------------------------------------------------------------- -- mt46v16m16 memory preload file format -------------------------------------------------------------------- -- / - comment -- @baaaaaa - stands for bank, i -- stands for address within bank -- dd dd -
are bytes to be written at Mem(*)(aaaaaa++) -- (aaaaaa is incremented at every load) -- only first 1-8 columns are loaded. NO empty lines ! -------------------------------------------------------------------- IF PoweredUp'EVENT and PoweredUp and (mem_file_name /= "none") THEN ind := 0; file_bank:=0; WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN file_bank := h(buf(2 to 2)); ind := h(buf(3 to 8)); ELSE UMemData(file_bank)(ind) := h(buf(1 to 2)); LMemData(file_bank)(ind) := h(buf(4 to 5)); IF ind < depth THEN ind := ind + 1; ELSE REPORT "Out of range memory load attempted" SEVERITY ERROR; END IF; END IF; END LOOP; END IF; -------------------------------------------------------------------- -- Output Section -------------------------------------------------------------------- LDQS_zd := LDQSDriveOut; UDQS_zd := UDQSDriveOut; if rising_edge(CLKint) OR falling_edge(CLKint) THEN D_zd <= DataDriveOut; elsif rising_edge(CLKIn) OR falling_edge(CLKIn) THEN if DataDriveOut /= "ZZZZZZZZZZZZZZZZ" THEN D_zd <= (others => 'X'); END IF; END IF; ------------------------------------------------------------------------ -- Path Delay Process ------------------------------------------------------------------------ VitalPathDelay01Z ( OutSignal => LDQSOut, OutSignalName => "LDQS", OutTemp => LDQS_zd, Mode => OnEvent, GlitchData => LDQS_GlitchData, Paths => ( 1 => (InputChangeTime => CLKInt'LAST_EVENT, PathDelay => tpd_CLK_DQ0, PathCondition => TRUE) ) ); VitalPathDelay01Z ( OutSignal => UDQSOut, OutSignalName => "UDQS", OutTemp => UDQS_zd, Mode => OnEvent, GlitchData => UDQS_GlitchData, Paths => ( 1 => (InputChangeTime => CLKInt'LAST_EVENT, PathDelay => tpd_CLK_DQ0, PathCondition => TRUE) ) ); END PROCESS; ------------------------------------------------------------------------ -- Path Delay Process ------------------------------------------------------------------------ DataOutBlk : FOR i IN HiDataBit DOWNTO 0 GENERATE DataOut_Delay : PROCESS (D_zd(i)) VARIABLE D_GlitchData:VitalGlitchDataArrayType(HiDataBit Downto 0); BEGIN VitalPathDelay01Z ( OutSignal => DataOut(i), OutSignalName => "Data", OutTemp => D_zd(i), Mode => OnEvent, GlitchData => D_GlitchData(i), Paths => ( 0 => (InputChangeTime => CLKint'LAST_EVENT, PathDelay => tpd_CLK_DQ0, PathCondition => TRUE), 1 => (InputChangeTime => CLKIn'LAST_EVENT, PathDelay => VitalExtendtoFillDelay(tpd_CLK_DQ1), PathCondition => TRUE) ) ); END PROCESS; END GENERATE; END BLOCK; END vhdl_behavioral;