-------------------------------------------------------------------------------- -- File Name: mt54w1mh18.vhd -------------------------------------------------------------------------------- -- Copyright (C) 2002, 2003 Free Model Foundry; http://www.FreeModelFoundry.com -- -- 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 Oct 16 Initial release -- V1.1 M.Marinkovic 02 Nov 25 Added DLL, memory file read -- V1.2 R. Munden 03 May 27 Fixed output timing in K mode -- V1.3 R. Munden 03 Jun 28 Rewrote DLL phase lock in C mode -- V1.4 R. Munden 03 Aug 03 Rewrote DLL phase lock in K mode -- V1.5 R. Munden 03 Oct 10 Enhaced memory preload capability -- V1.6 R. Munden 03 Nov 06 Fixed memory preload capability -- enhanced DLLs -- V1.7 R. Munden 04 MAR 26 Fixed DLLs to work with stopped clocks -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: RAM -- Technology: CMOS -- Part: MT54W1MH18 -- -- Description: QDR II SRAM 1M x 18 -- This model requires VITAL2000 -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.VITAL_timing.ALL; USE IEEE.VITAL_primitives.ALL; USE STD.textio.ALL; LIBRARY FMF; USE FMF.gen_utils.ALL; USE FMF.conversions.ALL; -------------------------------------------------------------------------------- -- ENTITY DECLARATION -------------------------------------------------------------------------------- ENTITY mt54w1mh18 IS GENERIC ( -- tipd delays: interconnect path delays tipd_DLLNeg : VitalDelayType01 := VitalZeroDelay01; tipd_ZQ : 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_A13 : VitalDelayType01 := VitalZeroDelay01; tipd_A14 : VitalDelayType01 := VitalZeroDelay01; tipd_A15 : VitalDelayType01 := VitalZeroDelay01; tipd_A16 : VitalDelayType01 := VitalZeroDelay01; tipd_A17 : VitalDelayType01 := VitalZeroDelay01; tipd_A18 : VitalDelayType01 := VitalZeroDelay01; tipd_D0 : VitalDelayType01 := VitalZeroDelay01; tipd_D1 : VitalDelayType01 := VitalZeroDelay01; tipd_D2 : VitalDelayType01 := VitalZeroDelay01; tipd_D3 : VitalDelayType01 := VitalZeroDelay01; tipd_D4 : VitalDelayType01 := VitalZeroDelay01; tipd_D5 : VitalDelayType01 := VitalZeroDelay01; tipd_D6 : VitalDelayType01 := VitalZeroDelay01; tipd_D7 : VitalDelayType01 := VitalZeroDelay01; tipd_D8 : VitalDelayType01 := VitalZeroDelay01; tipd_D9 : VitalDelayType01 := VitalZeroDelay01; tipd_D10 : VitalDelayType01 := VitalZeroDelay01; tipd_D11 : VitalDelayType01 := VitalZeroDelay01; tipd_D12 : VitalDelayType01 := VitalZeroDelay01; tipd_D13 : VitalDelayType01 := VitalZeroDelay01; tipd_D14 : VitalDelayType01 := VitalZeroDelay01; tipd_D15 : VitalDelayType01 := VitalZeroDelay01; tipd_D16 : VitalDelayType01 := VitalZeroDelay01; tipd_D17 : VitalDelayType01 := VitalZeroDelay01; tipd_RNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WNeg : VitalDelayType01 := VitalZeroDelay01; tipd_BW0Neg : VitalDelayType01 := VitalZeroDelay01; tipd_BW1Neg : VitalDelayType01 := VitalZeroDelay01; tipd_K : VitalDelayType01 := VitalZeroDelay01; tipd_KNeg : VitalDelayType01 := VitalZeroDelay01; tipd_C : VitalDelayType01 := VitalZeroDelay01; tipd_CNeg : VitalDelayType01 := VitalZeroDelay01; tipd_TMS : VitalDelayType01 := VitalZeroDelay01; tipd_TDI : VitalDelayType01 := VitalZeroDelay01; tipd_TCK : VitalDelayType01 := VitalZeroDelay01; -- tpd delays -- tCLZ tpd_C_Q0 : VitalDelayType01Z := VitalZeroDelay01Z; -- tKC Var tpd_C_CQ : VitalDelayType01Z := VitalZeroDelay01Z; -- tCCQ0 tpd_C_Q1 : VitalDelayType := 200 ps; -- tpw values: pulse widths -- tKH tpw_K_posedge : VitalDelayType := UnitDelay; -- tKL tpw_K_negedge : VitalDelayType := UnitDelay; -- tperiod min (calculated as 1/max freq) -- tCYC tperiod_K : VitalDelayType := UnitDelay; -- tsetup values: setup times -- tSA tsetup_A0_K : VitalDelayType := UnitDelay; -- tSD tsetup_D0_K : VitalDelayType := UnitDelay; -- tSC, tSCDDR tsetup_RNeg_K : VitalDelayType := UnitDelay; -- thold values: hold times -- tHA thold_A0_K : VitalDelayType := UnitDelay; -- tHD thold_D0_K : VitalDelayType := UnitDelay; -- tHC, tHCDDR thold_RNeg_K : VitalDelayType := UnitDelay; --VITAL2000 -- tskew values: skew times -- tKHCH tskew_K_C : VitalDelayType := UnitDelay; -- tKHKH tskew_K_KNeg : VitalDelayType := UnitDelay; -- tKHKH tskew_KNeg_K : VitalDelayType := UnitDelay; -- 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"; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( DLLNeg : IN std_ulogic := 'U'; ZQ : IN std_ulogic := 'U'; A0 : IN std_ulogic := 'U'; A1 : IN std_ulogic := 'U'; A2 : IN std_ulogic := 'U'; A3 : IN std_ulogic := 'U'; A4 : IN std_ulogic := 'U'; A5 : IN std_ulogic := 'U'; A6 : IN std_ulogic := 'U'; A7 : IN std_ulogic := 'U'; A8 : IN std_ulogic := 'U'; A9 : IN std_ulogic := 'U'; A10 : IN std_ulogic := 'U'; A11 : IN std_ulogic := 'U'; A12 : IN std_ulogic := 'U'; A13 : IN std_ulogic := 'U'; A14 : IN std_ulogic := 'U'; A15 : IN std_ulogic := 'U'; A16 : IN std_ulogic := 'U'; A17 : IN std_ulogic := 'U'; A18 : IN std_ulogic := 'U'; D0 : IN std_ulogic := 'U'; D1 : IN std_ulogic := 'U'; D2 : IN std_ulogic := 'U'; D3 : IN std_ulogic := 'U'; D4 : IN std_ulogic := 'U'; D5 : IN std_ulogic := 'U'; D6 : IN std_ulogic := 'U'; D7 : IN std_ulogic := 'U'; D8 : IN std_ulogic := 'U'; D9 : IN std_ulogic := 'U'; D10 : IN std_ulogic := 'U'; D11 : IN std_ulogic := 'U'; D12 : IN std_ulogic := 'U'; D13 : IN std_ulogic := 'U'; D14 : IN std_ulogic := 'U'; D15 : IN std_ulogic := 'U'; D16 : IN std_ulogic := 'U'; D17 : IN std_ulogic := 'U'; RNeg : IN std_ulogic := 'U'; WNeg : IN std_ulogic := 'U'; BW0Neg : IN std_ulogic := 'U'; BW1Neg : IN std_ulogic := 'U'; K : IN std_ulogic := 'U'; KNeg : IN std_ulogic := 'U'; C : IN std_ulogic := 'U'; CNeg : IN std_ulogic := 'U'; TMS : IN std_ulogic := 'U'; TDI : IN std_ulogic := 'U'; TCK : IN std_ulogic := 'U'; Q0 : OUT std_ulogic := 'U'; Q1 : OUT std_ulogic := 'U'; Q2 : OUT std_ulogic := 'U'; Q3 : OUT std_ulogic := 'U'; Q4 : OUT std_ulogic := 'U'; Q5 : OUT std_ulogic := 'U'; Q6 : OUT std_ulogic := 'U'; Q7 : OUT std_ulogic := 'U'; Q8 : OUT std_ulogic := 'U'; Q9 : OUT std_ulogic := 'U'; Q10 : OUT std_ulogic := 'U'; Q11 : OUT std_ulogic := 'U'; Q12 : OUT std_ulogic := 'U'; Q13 : OUT std_ulogic := 'U'; Q14 : OUT std_ulogic := 'U'; Q15 : OUT std_ulogic := 'U'; Q16 : OUT std_ulogic := 'U'; Q17 : OUT std_ulogic := 'U'; CQ : OUT std_ulogic := 'U'; CQNeg : OUT std_ulogic := 'U'; TDO : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of mt54w1mh18 : ENTITY IS TRUE; END mt54w1mh18; -------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION -------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of mt54w1mh18 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "mt54w1mh18"; CONSTANT TotalLOC : NATURAL := 524287; CONSTANT MaxData : NATURAL := 511; CONSTANT HiAbit : NATURAL := 18; CONSTANT HiDbit : NATURAL := 8; SIGNAL DLLNeg_ipd : std_ulogic := 'U'; SIGNAL ZQ_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 A13_ipd : std_ulogic := 'U'; SIGNAL A14_ipd : std_ulogic := 'U'; SIGNAL A15_ipd : std_ulogic := 'U'; SIGNAL A16_ipd : std_ulogic := 'U'; SIGNAL A17_ipd : std_ulogic := 'U'; SIGNAL A18_ipd : std_ulogic := 'U'; SIGNAL D0_ipd : std_ulogic := 'U'; SIGNAL D1_ipd : std_ulogic := 'U'; SIGNAL D2_ipd : std_ulogic := 'U'; SIGNAL D3_ipd : std_ulogic := 'U'; SIGNAL D4_ipd : std_ulogic := 'U'; SIGNAL D5_ipd : std_ulogic := 'U'; SIGNAL D6_ipd : std_ulogic := 'U'; SIGNAL D7_ipd : std_ulogic := 'U'; SIGNAL D8_ipd : std_ulogic := 'U'; SIGNAL D9_ipd : std_ulogic := 'U'; SIGNAL D10_ipd : std_ulogic := 'U'; SIGNAL D11_ipd : std_ulogic := 'U'; SIGNAL D12_ipd : std_ulogic := 'U'; SIGNAL D13_ipd : std_ulogic := 'U'; SIGNAL D14_ipd : std_ulogic := 'U'; SIGNAL D15_ipd : std_ulogic := 'U'; SIGNAL D16_ipd : std_ulogic := 'U'; SIGNAL D17_ipd : std_ulogic := 'U'; SIGNAL RNeg_ipd : std_ulogic := 'U'; SIGNAL WNeg_ipd : std_ulogic := 'U'; SIGNAL BW0Neg_ipd : std_ulogic := 'U'; SIGNAL BW1Neg_ipd : std_ulogic := 'U'; SIGNAL K_ipd : std_ulogic := 'U'; SIGNAL KNeg_ipd : std_ulogic := 'U'; SIGNAL C_ipd : std_ulogic := 'U'; SIGNAL CNeg_ipd : std_ulogic := 'U'; SIGNAL TMS_ipd : std_ulogic := 'U'; SIGNAL TDI_ipd : std_ulogic := 'U'; SIGNAL TCK_ipd : std_ulogic := 'U'; BEGIN ---------------------------------------------------------------------------- -- Wire Delays ---------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (DLLNeg_ipd, DLLNeg, tipd_DLLNeg); w_2 : VitalWireDelay (ZQ_ipd, ZQ, tipd_ZQ); w_3 : VitalWireDelay (A0_ipd, A0, tipd_A0); w_4 : VitalWireDelay (A1_ipd, A1, tipd_A1); w_5 : VitalWireDelay (A2_ipd, A2, tipd_A2); w_6 : VitalWireDelay (A3_ipd, A3, tipd_A3); w_7 : VitalWireDelay (A4_ipd, A4, tipd_A4); w_8 : VitalWireDelay (A5_ipd, A5, tipd_A5); w_9 : VitalWireDelay (A6_ipd, A6, tipd_A6); w_10 : VitalWireDelay (A7_ipd, A7, tipd_A7); w_11 : VitalWireDelay (A8_ipd, A8, tipd_A8); w_12 : VitalWireDelay (A9_ipd, A9, tipd_A9); w_13 : VitalWireDelay (A10_ipd, A10, tipd_A10); w_14 : VitalWireDelay (A11_ipd, A11, tipd_A11); w_15 : VitalWireDelay (A12_ipd, A12, tipd_A12); w_16 : VitalWireDelay (A13_ipd, A13, tipd_A13); w_17 : VitalWireDelay (A14_ipd, A14, tipd_A14); w_18 : VitalWireDelay (A15_ipd, A15, tipd_A15); w_19 : VitalWireDelay (A16_ipd, A16, tipd_A16); w_20 : VitalWireDelay (A17_ipd, A17, tipd_A17); w_64 : VitalWireDelay (A18_ipd, A18, tipd_A18); w_25 : VitalWireDelay (D0_ipd, D0, tipd_D0); w_26 : VitalWireDelay (D1_ipd, D1, tipd_D1); w_27 : VitalWireDelay (D2_ipd, D2, tipd_D2); w_28 : VitalWireDelay (D3_ipd, D3, tipd_D3); w_29 : VitalWireDelay (D4_ipd, D4, tipd_D4); w_30 : VitalWireDelay (D5_ipd, D5, tipd_D5); w_31 : VitalWireDelay (D6_ipd, D6, tipd_D6); w_32 : VitalWireDelay (D7_ipd, D7, tipd_D7); w_33 : VitalWireDelay (D8_ipd, D8, tipd_D8); w_34 : VitalWireDelay (D9_ipd, D9, tipd_D9); w_35 : VitalWireDelay (D10_ipd, D10, tipd_D10); w_36 : VitalWireDelay (D11_ipd, D11, tipd_D11); w_37 : VitalWireDelay (D12_ipd, D12, tipd_D12); w_38 : VitalWireDelay (D13_ipd, D13, tipd_D13); w_39 : VitalWireDelay (D14_ipd, D14, tipd_D14); w_40 : VitalWireDelay (D15_ipd, D15, tipd_D15); w_41 : VitalWireDelay (D16_ipd, D16, tipd_D16); w_42 : VitalWireDelay (D17_ipd, D17, tipd_D17); w_53 : VitalWireDelay (RNeg_ipd, RNeg, tipd_RNeg); w_54 : VitalWireDelay (WNeg_ipd, WNeg, tipd_WNeg); w_55 : VitalWireDelay (BW0Neg_ipd, BW0Neg, tipd_BW0Neg); w_56 : VitalWireDelay (BW1Neg_ipd, BW1Neg, tipd_BW1Neg); w_57 : VitalWireDelay (K_ipd, K, tipd_K); w_58 : VitalWireDelay (KNeg_ipd, KNeg, tipd_KNeg); w_59 : VitalWireDelay (C_ipd, C, tipd_C); w_60 : VitalWireDelay (CNeg_ipd, CNeg, tipd_CNeg); w_61 : VitalWireDelay (TMS_ipd, TMS, tipd_TMS); w_62 : VitalWireDelay (TDI_ipd, TDI, tipd_TDI); w_63 : VitalWireDelay (TCK_ipd, TCK, tipd_TCK); END BLOCK; ---------------------------------------------------------------------------- -- Main Behavior Block ---------------------------------------------------------------------------- Behavior: BLOCK PORT ( DLLNegIn : IN std_logic := 'U'; BW0NIn : IN std_ulogic := 'U'; BW1NIn : IN std_ulogic := 'U'; Dat0In : IN std_logic_vector(HiDbit downto 0); Dat1In : IN std_logic_vector(HiDbit downto 0); DataOut : OUT std_logic_vector(17 downto 0) := (others => 'Z'); CIn : IN std_ulogic := 'U'; CNegIn : IN std_ulogic := 'U'; KIn : IN std_ulogic := 'U'; KNegIn : IN std_ulogic := 'U'; AddressIn : IN std_logic_vector(HiAbit downto 0); RIn : IN std_ulogic := 'U'; WIn : IN std_ulogic := 'U'; CQOut : OUT std_ulogic := 'U'; CQNegOut : OUT std_ulogic := 'U' ); PORT MAP ( Dat0In(0) => D0_ipd, Dat0In(1) => D1_ipd, Dat0In(2) => D2_ipd, Dat0In(3) => D3_ipd, Dat0In(4) => D4_ipd, Dat0In(5) => D5_ipd, Dat0In(6) => D6_ipd, Dat0In(7) => D7_ipd, Dat0In(8) => D8_ipd, Dat1In(0) => D9_ipd, Dat1In(1) => D10_ipd, Dat1In(2) => D11_ipd, Dat1In(3) => D12_ipd, Dat1In(4) => D13_ipd, Dat1In(5) => D14_ipd, Dat1In(6) => D15_ipd, Dat1In(7) => D16_ipd, Dat1In(8) => D17_ipd, DataOut(0) => Q0, DataOut(1) => Q1, DataOut(2) => Q2, DataOut(3) => Q3, DataOut(4) => Q4, DataOut(5) => Q5, DataOut(6) => Q6, DataOut(7) => Q7, DataOut(8) => Q8, DataOut(9) => Q9, DataOut(10) => Q10, DataOut(11) => Q11, DataOut(12) => Q12, DataOut(13) => Q13, DataOut(14) => Q14, DataOut(15) => Q15, DataOut(16) => Q16, DataOut(17) => Q17, AddressIn(0) => A0_ipd, AddressIn(1) => A1_ipd, AddressIn(2) => A2_ipd, AddressIn(3) => A3_ipd, AddressIn(4) => A4_ipd, AddressIn(5) => A5_ipd, AddressIn(6) => A6_ipd, AddressIn(7) => A7_ipd, AddressIn(8) => A8_ipd, AddressIn(9) => A9_ipd, AddressIn(10) => A10_ipd, AddressIn(11) => A11_ipd, AddressIn(12) => A12_ipd, AddressIn(13) => A13_ipd, AddressIn(14) => A14_ipd, AddressIn(15) => A15_ipd, AddressIn(16) => A16_ipd, AddressIn(17) => A17_ipd, AddressIn(18) => A18_ipd, BW0NIn => BW0Neg_ipd, BW1NIn => BW1Neg_ipd, CIn => C_ipd, CNegIn => CNeg_ipd, KIn => K_ipd, KNegIn => KNeg_ipd, RIn => RNeg_ipd, WIn => WNeg_ipd, CQOut => CQ, CQNegOut => CQNeg, DLLNegIn => DLLNeg_ipd ); SIGNAL Q_zd : std_logic_vector(17 DOWNTO 0); SIGNAL KTRIG : std_ulogic; SIGNAL CTRIG : std_ulogic; SIGNAL KCTRIG : std_ulogic; SIGNAL KCTRIGN : std_ulogic; SIGNAL CPERIOD : time := 6 ns; -- C period SIGNAL KPERIOD : time := 6 ns; -- K period SIGNAL CInt : std_ulogic := '0'; SIGNAL CNegInt : std_ulogic := '0'; SIGNAL Ctemp : std_ulogic := '0'; SIGNAL Ktemp : std_ulogic := '0'; SIGNAL CHalfPer : time := 5 ns; SIGNAL Cdlldelay: time := 0 ns; SIGNAL KHalfPer : time := 5 ns; SIGNAL Kdlldelay: time := 0 ns; TYPE cmode IS (c, k); SIGNAL mode : cmode := c; BEGIN ---------------------------------------------- -- DLL model functional section --- ---------------------------------------------- C_DLL: PROCESS(CIn, Ctemp) VARIABLE CIn_period : Time := 1 ms; VARIABLE prev_CIn : Time := 0 ns; VARIABLE Ctemp_period : Time := 0 ns; VARIABLE Ctemp_period1 : Time := 0 ns; VARIABLE Ctemp_period2 : Time := 0 ns; VARIABLE prev_Ctemp : Time := 0 ns; VARIABLE dll_lock : BOOLEAN := false; VARIABLE toggle1 : boolean; VARIABLE toggle2 : boolean; BEGIN IF mode = c THEN IF rising_edge(CIn) THEN CIn_period := NOW - prev_CIn; prev_CIn := NOW; IF CIn_period > 30 ns THEN dll_lock := false; ASSERT false REPORT "C mode DLL reseting" SEVERITY note; END IF; END IF; IF rising_edge(Ctemp) THEN Ctemp_period := NOW - prev_Ctemp; prev_Ctemp := NOW; IF toggle1 AND toggle2 AND not(dll_lock) THEN IF Ctemp_period > CIn_period THEN Chalfper <= Chalfper - 51 ps; dll_lock := false; ELSIF Ctemp_period < CIn_period THEN Chalfper <= Chalfper + 7 ps; dll_lock := false; ELSIF Ctemp_period = Ctemp_period2 THEN -- stable? dll_lock := true; ASSERT false REPORT "C mode DLL lock achieved" SEVERITY note; ELSE Ctemp_period2 := Ctemp_period1; Ctemp_period1 := Ctemp_period; END IF; END IF; toggle1 := not toggle1; IF toggle1 THEN toggle2 := not toggle2; ELSE Cdlldelay <= 0 ps; END IF; END IF; IF rising_edge(Ctemp) AND dll_lock AND toggle1 AND toggle2 THEN IF (prev_CIn + tpd_C_Q1) < NOW THEN IF Cdlldelay < CIn_period THEN Cdlldelay <= Cdlldelay - 60 ps; END IF; END IF; END IF; END IF; END PROCESS C_DLL; C_temp : PROCESS(Ctemp) -- generating internal clock from DLL BEGIN Ctemp <= not(Ctemp) AFTER CHalfPer + Cdlldelay; END PROCESS C_temp; K_DLL: PROCESS(KIn, Ktemp) VARIABLE KIn_period : Time := 1 ms; VARIABLE prev_KIn : Time := 0 ns; VARIABLE Ktemp_period : Time := 0 ns; VARIABLE Ktemp_period1 : Time := 0 ns; VARIABLE Ktemp_period2 : Time := 0 ns; VARIABLE prev_Ktemp : Time := 0 ns; VARIABLE dll_lock : BOOLEAN := false; VARIABLE toggle1 : boolean; VARIABLE toggle2 : boolean; BEGIN IF mode = k THEN IF rising_edge(KIn) THEN KIn_period := NOW - prev_KIn; prev_KIn := NOW; IF KIn_period > 30 ns THEN dll_lock := false; ASSERT false REPORT "K mode DLL reseting" SEVERITY note; END IF; END IF; IF rising_edge(Ktemp) THEN Ktemp_period := NOW - prev_Ktemp; prev_Ktemp := NOW; IF toggle1 AND toggle2 AND not(dll_lock) THEN IF Ktemp_period > KIn_period THEN Khalfper <= Khalfper - 51 ps; dll_lock := false; ELSIF Ktemp_period < KIn_period THEN Khalfper <= Khalfper + 7 ps; dll_lock := false; ELSIF Ktemp_period = Ktemp_period2 THEN -- stable? dll_lock := true; ASSERT false REPORT "K mode DLL lock achieved" SEVERITY note; ELSE Ktemp_period2 := Ktemp_period1; Ktemp_period1 := Ktemp_period; END IF; END IF; toggle1 := not toggle1; IF toggle1 THEN toggle2 := not toggle2; ELSE Kdlldelay <= 0 ps; END IF; END IF; IF rising_edge(Ktemp) AND dll_lock AND toggle1 AND toggle2 THEN IF (prev_KIn + tpd_C_Q1) < NOW THEN IF Kdlldelay < KIn_period THEN Kdlldelay <= Kdlldelay - 60 ps; END IF; END IF; END IF; END IF; END PROCESS K_DLL; K_temp : PROCESS(Ktemp) -- generating internal clock from DLL BEGIN Ktemp <= not(Ktemp) AFTER KHalfPer + Kdlldelay; END PROCESS K_temp; C_int : PROCESS (CIn, Ctemp, KIn, Ktemp)-- Passing clock based on DLL_EN BEGIN IF (not DLLNegIn='0') THEN IF mode = c THEN CInt <= TRANSPORT Ctemp; CNegInt <= TRANSPORT not Ctemp; ELSIF mode = k THEN CInt <= TRANSPORT Ktemp; CNegInt <= TRANSPORT not Ktemp; END IF; ELSE IF mode = c THEN CInt <= CIn ; CNegInt <= CNegIn ; ELSE CInt <= KIn; CNegInt <= KNegIn; END IF; END IF; END PROCESS C_int; ------------------------------------------------------------------------ -- Behavior Process ------------------------------------------------------------------------ Behavior : PROCESS (BW0NIn, BW1NIn, CInt, CNegInt, KIn, KNegIn, RIn, WIn, AddressIn, Dat0In, Dat1In, KTRIG, CTRIG, KCTRIG, KCTRIGN) -- Timing Check Variables VARIABLE Tviol_A0_K : X01 := '0'; VARIABLE TD_A0_K : VitalTimingDataType; VARIABLE Tviol_A0_KNeg : X01 := '0'; VARIABLE TD_A0_KNeg : VitalTimingDataType; VARIABLE Tviol_D0_K : X01 := '0'; VARIABLE TD_D0_K : VitalTimingDataType; VARIABLE Tviol_D1_K : X01 := '0'; VARIABLE TD_D1_K : VitalTimingDataType; VARIABLE Tviol_D2_K : X01 := '0'; VARIABLE TD_D2_K : VitalTimingDataType; VARIABLE Tviol_D3_K : X01 := '0'; VARIABLE TD_D3_K : VitalTimingDataType; VARIABLE Tviol_D0_KNeg : X01 := '0'; VARIABLE TD_D0_KNeg : VitalTimingDataType; VARIABLE Tviol_D1_KNeg : X01 := '0'; VARIABLE TD_D1_KNeg : VitalTimingDataType; VARIABLE Tviol_D2_KNeg : X01 := '0'; VARIABLE TD_D2_KNeg : VitalTimingDataType; VARIABLE Tviol_D3_KNeg : X01 := '0'; VARIABLE TD_D3_KNeg : VitalTimingDataType; VARIABLE Tviol_RNeg_K : X01 := '0'; VARIABLE TD_RNeg_K : VitalTimingDataType; VARIABLE Tviol_WNeg_K : X01 := '0'; VARIABLE TD_WNeg_K : VitalTimingDataType; VARIABLE Tviol_BW0Neg_K : X01 := '0'; VARIABLE TD_BW0Neg_K : VitalTimingDataType; VARIABLE Tviol_BW1Neg_K : X01 := '0'; VARIABLE TD_BW1Neg_K : VitalTimingDataType; VARIABLE Tviol_BW0Neg_KNeg : X01 := '0'; VARIABLE TD_BW0Neg_KNeg : VitalTimingDataType; VARIABLE Tviol_BW1Neg_KNeg : X01 := '0'; VARIABLE TD_BW1Neg_KNeg : VitalTimingDataType; VARIABLE Pviol_C : X01 := '0'; VARIABLE TD_C : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CNeg : X01 := '0'; VARIABLE TD_CNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_K : X01 := '0'; VARIABLE TD_K : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_KNeg : X01 := '0'; VARIABLE TD_KNeg : VitalPeriodDataType := VitalPeriodDataInit; --VITAL2000 VARIABLE Sviol_KNeg_CNeg : X01 := '0'; VARIABLE SD_KNeg_CNeg : VitalSkewDataType := VitalSkewDataInit; VARIABLE Sviol_K_C : X01 := '0'; VARIABLE SD_K_C : VitalSkewDataType := VitalSkewDataInit; VARIABLE Sviol_K_KNeg : X01 := '0'; VARIABLE SD_K_KNeg : VitalSkewDataType := VitalSkewDataInit; VARIABLE Sviol_C_CNeg : X01 := '0'; VARIABLE SD_C_CNeg : VitalSkewDataType := VitalSkewDataInit; -- Functionality Results Variables VARIABLE Violation : X01 := '0'; VARIABLE CQ_zd : std_ulogic := 'U'; VARIABLE CQNeg_zd : std_ulogic := 'U'; VARIABLE CQ_GlitchData : VitalGlitchDataType; VARIABLE CQNeg_GlitchData : VitalGlitchDataType; -- Memory array declaration -- TYPE MemStore IS ARRAY (0 to TotalLOC) OF INTEGER RANGE -2 TO MaxData; VARIABLE MemData0A : MemStore; VARIABLE MemData1A : MemStore; VARIABLE MemData0B : MemStore; VARIABLE MemData1B : MemStore; VARIABLE wrop : boolean := false; VARIABLE rdop : boolean := false; VARIABLE waddr : NATURAL; VARIABLE raddr : NATURAL; VARIABLE datatmp : INTEGER; -- No Weak Values Variables VARIABLE BW0Neg_nwv : UX01 := 'U'; VARIABLE BW1Neg_nwv : UX01 := 'U'; VARIABLE BW0Neg_reg : UX01 := 'U'; VARIABLE BW1Neg_reg : UX01 := 'U'; VARIABLE RNeg_nwv : UX01 := 'U'; VARIABLE WNeg_nwv : UX01 := 'U'; VARIABLE dat0_reg : std_logic_vector(HiDbit downto 0); VARIABLE dat1_reg : std_logic_vector(HiDbit downto 0); VARIABLE dout_tmpA : std_logic_vector(17 downto 0):= (OTHERS=>'Z'); VARIABLE dout_tmpB : std_logic_vector(17 downto 0):= (OTHERS=>'Z'); VARIABLE dout_regA : std_logic_vector(17 downto 0); VARIABLE dout_regB : std_logic_vector(17 downto 0); -- mem file FILE mem_file : text IS mem_file_name; VARIABLE ind : NATURAL := 0; VARIABLE buf : line; BEGIN BW0Neg_nwv := To_UX01 (s => BW0NIn); BW1Neg_nwv := To_UX01 (s => BW1NIn); RNeg_nwv := To_UX01 (s => RIn); WNeg_nwv := To_UX01 (s => WIn); -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => RIn, TestSignalName => "RNeg", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_RNeg_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RNeg_K ); VitalSetupHoldCheck ( TestSignal => WIn, TestSignalName => "WNeg", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_WNeg_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WNeg_K ); VitalSetupHoldCheck ( TestSignal => BW0NIn, TestSignalName => "BW0Neg", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => ( WNeg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_BW0Neg_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_BW0Neg_K ); VitalSetupHoldCheck ( TestSignal => BW1NIn, TestSignalName => "BW1Neg", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => ( WNeg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_BW1Neg_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_BW1Neg_K ); VitalSetupHoldCheck ( TestSignal => BW0NIn, TestSignalName => "BW0Neg", RefSignal => KNegIn, RefSignalName => "KNeg", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => ( WNeg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_BW0Neg_KNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_BW0Neg_KNeg ); VitalSetupHoldCheck ( TestSignal => BW1NIn, TestSignalName => "BW1Neg", RefSignal => KNegIn, RefSignalName => "KNeg", SetupLow => tsetup_RNeg_K, HoldLow => thold_RNeg_K, CheckEnabled => ( WNeg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_BW1Neg_KNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_BW1Neg_KNeg ); VitalSetupHoldCheck ( TestSignal => Dat0In, TestSignalName => "Dat0In", RefSignal => KNegIn, RefSignalName => "KNeg", SetupLow => tsetup_D0_K, HoldLow => thold_D0_K, CheckEnabled => ( WNeg_nwv = '0' AND BW0Neg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D0_KNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D0_KNeg ); VitalSetupHoldCheck ( TestSignal => Dat1In, TestSignalName => "Dat1In", RefSignal => KNegIn, RefSignalName => "KNeg", SetupLow => tsetup_D0_K, HoldLow => thold_D0_K, CheckEnabled => ( WNeg_nwv = '0' AND BW1Neg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D1_KNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D1_KNeg ); VitalSetupHoldCheck ( TestSignal => Dat0In, TestSignalName => "Dat0In", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_D0_K, HoldLow => thold_D0_K, CheckEnabled => ( WNeg_nwv = '0' AND BW0Neg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D0_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D0_K ); VitalSetupHoldCheck ( TestSignal => Dat1In, TestSignalName => "Dat1In", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_D0_K, HoldLow => thold_D0_K, CheckEnabled => ( WNeg_nwv = '0' AND BW1Neg_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_D1_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D1_K ); VitalSetupHoldCheck ( TestSignal => AddressIn, TestSignalName => "Address", RefSignal => KNegIn, RefSignalName => "KNeg", SetupLow => tsetup_A0_K, HoldLow => thold_A0_K, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_KNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_KNeg ); VitalSetupHoldCheck ( TestSignal => AddressIn, TestSignalName => "Address", RefSignal => KIn, RefSignalName => "K", SetupLow => tsetup_A0_K, HoldLow => thold_A0_K, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & PartID, TimingData => TD_A0_K, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_A0_K ); VitalPeriodPulseCheck ( TestSignal => CIn, TestSignalName => "C", Period => tperiod_K, PulseWidthLow => tpw_K_negedge, PulseWidthHigh => tpw_K_posedge, PeriodData => TD_C, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => (mode = c), Violation => Pviol_C ); VitalPeriodPulseCheck ( TestSignal => CNegIn, TestSignalName => "CNeg", Period => tperiod_K, PulseWidthLow => tpw_K_negedge, PulseWidthHigh => tpw_K_posedge, PeriodData => TD_CNeg, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => (mode = c), Violation => Pviol_CNeg ); VitalPeriodPulseCheck ( TestSignal => KIn, TestSignalName => "K", Period => tperiod_K, PulseWidthLow => tpw_K_negedge, PulseWidthHigh => tpw_K_posedge, PeriodData => TD_K, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_K ); VitalPeriodPulseCheck ( TestSignal => KNegIn, TestSignalName => "KNeg", Period => tperiod_K, PulseWidthLow => tpw_K_negedge, PulseWidthHigh => tpw_K_posedge, PeriodData => TD_KNeg, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_KNeg ); --VITAL2000 VitalInPhaseSkewCheck ( Signal1 => KIn, Signal2 => CIn, SkewS1S2RiseRise => tskew_K_C, SkewData => SD_K_C, CheckEnabled => (mode = c), Trigger => KCTRIG, Violation => Sviol_K_C ); VitalInPhaseSkewCheck ( Signal1 => KNegIn, Signal2 => CNegIn, SkewS1S2RiseRise => tskew_K_C, SkewData => SD_KNeg_CNeg, CheckEnabled => (mode = c), Trigger => KCTRIGN, Violation => Sviol_KNeg_CNeg ); VitalOutPhaseSkewCheck ( Signal1 => KIn, Signal2 => KNegIn, SkewS1S2RiseFall => tskew_K_KNeg, SkewS2S1RiseFall => tskew_KNeg_K, SkewData => SD_K_KNeg, CheckEnabled => TRUE, Trigger => KTRIG, Violation => Sviol_K_KNeg ); VitalOutPhaseSkewCheck ( Signal1 => CIn, Signal2 => CNegIn, SkewS1S2RiseFall => tskew_K_KNeg, SkewS2S1RiseFall => tskew_KNeg_K, SkewData => SD_C_CNeg, CheckEnabled => (mode = c), Trigger => CTRIG, Violation => Sviol_C_CNeg ); Violation := Tviol_A0_K OR Tviol_A0_KNeg OR Tviol_D0_K OR Tviol_D1_K OR Tviol_D0_KNeg OR Tviol_D1_KNeg OR Tviol_RNeg_K OR Tviol_WNeg_K OR Tviol_BW0Neg_K OR Tviol_BW1Neg_K OR Tviol_BW0Neg_KNeg OR Tviol_BW1Neg_KNeg OR Pviol_C OR Pviol_CNeg OR Pviol_K OR Pviol_KNeg OR --VITAL2000 Sviol_KNeg_CNeg OR Sviol_K_C OR Sviol_K_KNeg OR Sviol_C_CNeg; END IF; -- Timing Check Section -------------------------------------------------------------------- -- Functional Section -------------------------------------------------------------------- IF NOW < 1 ns THEN IF To_UX01(CIn) = '1' AND To_UX01(CNegIn) = '1' THEN mode <= k; ELSE mode <= c; END IF; rdop:= false; wrop:= false; END IF; IF rising_edge(KIn) THEN IF WNeg_nwv = '0' THEN wrop := true; ASSERT (not(Is_X(BW0Neg_nwv))) REPORT InstancePath & partID & ": Unusable value for BW0Neg" SEVERITY SeverityMode; ASSERT (not(Is_X(BW1Neg_nwv))) REPORT InstancePath & partID & ": Unusable value for BW1Neg" SEVERITY SeverityMode; BW0Neg_reg := BW0Neg_nwv; BW1Neg_reg := BW1Neg_nwv; dat0_reg := Dat0In; dat1_reg := Dat1In; END IF; IF RNeg_nwv = '0' THEN rdop := true; raddr := To_Nat(AddressIn); END IF; END IF; IF rising_edge(KNegIn) THEN IF wrop = true THEN waddr := To_Nat(AddressIn); wrop := false; IF BW0Neg_reg = '0' THEN IF Violation = '0' THEN MemData0A(waddr) := To_Nat(dat0_reg); MemData0B(waddr) := To_Nat(Dat0In); ELSE MemData0A(waddr) := -1; MemData0B(waddr) := -1; END IF; END IF; IF BW1Neg_reg = '0' THEN IF Violation = '0' THEN MemData1A(waddr) := To_Nat(dat1_reg); MemData1B(waddr) := To_Nat(Dat1In); ELSE MemData1A(waddr) := -1; MemData1B(waddr) := -1; END IF; END IF; END IF; END IF; IF rising_edge(CNegInt) THEN dout_regA:=dout_tmpA; dout_regB:=dout_tmpB; IF rdop = true THEN rdop := false; datatmp := MemData0A(raddr); IF datatmp = -2 THEN dout_tmpA(8 downto 0) := (others => 'U'); ELSIF datatmp = -1 THEN dout_tmpA(8 downto 0) := (others => 'X'); ELSE dout_tmpA(8 downto 0) := To_slv(datatmp, 9); END IF; datatmp := MemData1A(raddr); IF datatmp = -2 THEN dout_tmpA(17 downto 9) := (others => 'U'); ELSIF datatmp = -1 THEN dout_tmpA(17 downto 9) := (others => 'X'); ELSE dout_tmpA(17 downto 9) := To_slv(datatmp, 9); END IF; datatmp := MemData0B(raddr); IF datatmp = -2 THEN dout_tmpB(8 downto 0) := (others => 'U'); ELSIF datatmp = -1 THEN dout_tmpB(8 downto 0) := (others => 'X'); ELSE dout_tmpB(8 downto 0) := To_slv(datatmp, 9); END IF; datatmp := MemData1B(raddr); IF datatmp = -2 THEN dout_tmpB(17 downto 9) := (others => 'U'); ELSIF datatmp = -1 THEN dout_tmpB(17 downto 9) := (others => 'X'); ELSE dout_tmpB(17 downto 9) := To_slv(datatmp, 9); END IF; ELSE dout_tmpA := (others => 'Z'); dout_tmpB := (others => 'Z'); END IF; END IF; IF rising_edge(CInt) THEN Q_zd <= dout_regB; CQ_zd := '1'; END IF; IF rising_edge(CNegInt) THEN Q_zd <= dout_regA; CQNeg_zd := '1'; END IF; IF falling_edge(CInt) THEN CQ_zd := '0'; END IF; IF falling_edge(CNegInt) THEN CQNeg_zd := '0'; END IF; -------------------------------------------------------------------- -- File Read Section -------------------------------------------------------------------- -- mt54w1mh18 memory preload file format -------------------------------------------------------------------- -- / - comment -- @aaaaa - stands for address of a 36-bit word -- ddd ddd - are bytes to be written -- data lines must be in pairs -- (aaaaa is incremented at every load) -- only first 1-15 columns are loaded. NO empty lines ! -------------------------------------------------------------------- IF NOW< 1 ns and (mem_file_name /= "none") THEN ind := 0; WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 to 6)); ELSE -- all bytes have the same value MemData1A(ind) := h(buf(1 to 3)); MemData0A(ind) := h(buf(5 to 7)); READLINE (mem_file, buf); MemData1B(ind) := h(buf(1 to 3)); MemData0B(ind) := h(buf(5 to 7)); ind := ind + 1; END IF; END LOOP; END IF; ------------------------------------------------------------------------ -- Path Delay Section ------------------------------------------------------------------------ VitalPathDelay01Z ( OutSignal => CQOut, OutSignalName => "CQ", OutTemp => CQ_zd, XOn => XOn, MsgOn => MsgOn, Paths => ( 0 => (InputChangeTime => CInt'LAST_EVENT, PathDelay => tpd_C_CQ, PathCondition => TRUE ) ), GlitchData => CQ_GlitchData ); VitalPathDelay01Z ( OutSignal => CQNegOut, OutSignalName => "CQNeg", OutTemp => CQNeg_zd, XOn => XOn, MsgOn => MsgOn, Paths => ( 0 => (InputChangeTime => CNegInt'LAST_EVENT, PathDelay => tpd_C_CQ, PathCondition => TRUE ) ), GlitchData => CQNeg_GlitchData ); END PROCESS; ------------------------------------------------------------------------ -- Path Delay Processes generated as a function of data width ------------------------------------------------------------------------ DataOut_Width : FOR i IN 17 DOWNTO 0 GENERATE DataOut_Delay : PROCESS (Q_zd(i)) VARIABLE Q_GlitchData:VitalGlitchDataArrayType(17 Downto 0); BEGIN VitalPathDelay01Z ( OutSignal => DataOut(i), OutSignalName => "Q", OutTemp => Q_zd(i), Mode => OnEvent, GlitchData => Q_GlitchData(i), Paths => ( 0 => (InputChangeTime => CInt'LAST_EVENT, PathDelay => tpd_C_Q0, PathCondition => TRUE), 1 => (InputChangeTime => CNegInt'LAST_EVENT, PathDelay => tpd_C_Q0, PathCondition => TRUE) ) ); END PROCESS; END GENERATE; END BLOCK; END vhdl_behavioral;