-------------------------------------------------------------------------------- -- File Name: cy22395.vhd -------------------------------------------------------------------------------- -- Copyright (C) 2005 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 V.Ljubisavljevic 05 Jan 14 Initial release -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: CLOCK -- Technology: CMOS -- Part: CY22395 -- -- Description: Three-PLL Serial-Programmable Flash-Programmable Clock -- Generator -- -------------------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.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 cy22395 IS GENERIC ( -- tipd delays: interconnect path delays tipd_XTALIN : VitalDelayType01 := VitalZeroDelay01; tipd_SDAT : VitalDelayType01Z := VitalZeroDelay01Z; tipd_SCLK : VitalDelayType01 := VitalZeroDelay01; tipd_S2SUSPENDNeg : VitalDelayType01 := VitalZeroDelay01; tipd_SHUTDOWNNegOE : VitalDelayType01 := VitalZeroDelay01; --tsetup values tsetup_SDAT_SCLK : VitalDelayType:= UnitDelay; --tpw values: pulse width tpw_SCLK_posedge : VitalDelayType := UnitDelay; tpw_SCLK_negedge : VitalDelayType := UnitDelay; -- tperiod_min: minimum clock period = 1/max freq tperiod_XTALIN : VitalDelayType := UnitDelay; tperiod_SCLK : VitalDelayType := UnitDelay; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXon; -- For FMF SDF technology file usage TimingModel : STRING := DefaultTimingModel ); PORT ( XTALIN : IN std_logic := 'U'; SCLK : IN std_logic := 'U'; S2SUSPENDNeg : IN std_logic := 'U'; SHUTDOWNNegOE : IN std_logic := 'U'; SDAT : INOUT std_logic := 'Z'; CLKA : OUT std_logic := 'U'; CLKB : OUT std_logic := 'U'; CLKC : OUT std_logic := 'U'; CLKD : OUT std_logic := 'U'; CLKE : OUT std_logic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of cy22395 : ENTITY IS TRUE; END cy22395; -------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION -------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of cy22395 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "cy22395"; CONSTANT DeviceAddress : std_logic_vector(7 downto 0) := X"69"; CONSTANT MaxAddr : NATURAL := 16#FF#; SIGNAL XTALIN_ipd : std_logic := 'U'; SIGNAL SDAT_ipd : std_logic := 'U'; SIGNAL SCLK_ipd : std_logic := 'U'; SIGNAL S2SUSPENDNeg_ipd : std_logic := 'U'; SIGNAL SHUTDOWNNegOE_ipd : std_logic := 'U'; SIGNAL PLL1_LOCK : boolean; SIGNAL PLL2_LOCK : boolean; SIGNAL PLL3_LOCK : boolean; SIGNAL MULT1_OUT : std_logic := '0'; SIGNAL MULT2_OUT : std_logic := '0'; SIGNAL MULT3_OUT : std_logic := '0'; SIGNAL PLL1_OUT : std_logic := '1'; SIGNAL PLL2_OUT : std_logic := '1'; SIGNAL PLL3_OUT : std_logic := '1'; SIGNAL DIV1_OUT : std_logic := '1'; SIGNAL DIV2_OUT : std_logic := '1'; SIGNAL DIV3_OUT : std_logic := '1'; SIGNAL PostDivA_in : std_logic; SIGNAL PostDivB_in : std_logic; SIGNAL PostDivC_in : std_logic; SIGNAL PostDivD_in : std_logic; SIGNAL PostDivE_in : std_logic; SIGNAL PostDivA_out : std_logic; SIGNAL PostDivB_out : std_logic; SIGNAL PostDivC_out : std_logic; SIGNAL PostDivD_out : std_logic; SIGNAL PostDivE_out : std_logic; SIGNAL S2, S1, S0 : std_logic := '0'; ---------------------------------------------------------------------------- -- Registers ---------------------------------------------------------------------------- SIGNAL R_08H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_09H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0AH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0BH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0CH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0DH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0EH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_0FH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_10H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_11H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_12H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_13H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_14H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_15H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_16H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_17H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_40H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_41H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_42H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_43H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_44H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_45H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_46H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_47H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_48H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_49H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4AH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4BH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4CH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4DH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4EH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_4FH : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_50H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_51H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_52H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_53H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_54H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_55H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_56H : std_logic_vector(7 downto 0) := "00000000"; SIGNAL R_57H : std_logic_vector(7 downto 0) := "00000000"; ALIAS ClkA0_FS0 : std_logic IS R_08H(7); ALIAS ClkA1_FS0 : std_logic IS R_09H(7); ALIAS ClkB0_FS0 : std_logic IS R_0AH(7); ALIAS ClkB1_FS0 : std_logic IS R_0BH(7); ALIAS ClkC_FS0 : std_logic IS R_0CH(7); ALIAS ClkD_FS0 : std_logic IS R_0DH(7); ALIAS ClkA0_Div : std_logic_vector(6 downto 0) IS R_08H(6 downto 0); ALIAS ClkA1_Div : std_logic_vector(6 downto 0) IS R_09H(6 downto 0); ALIAS ClkB0_Div : std_logic_vector(6 downto 0) IS R_0AH(6 downto 0); ALIAS ClkB1_Div : std_logic_vector(6 downto 0) IS R_0BH(6 downto 0); ALIAS ClkC_Div : std_logic_vector(6 downto 0) IS R_0CH(6 downto 0); ALIAS ClkD_Div : std_logic_vector(6 downto 0) IS R_0DH(6 downto 0); ALIAS ClkA_FS21 : std_logic_vector(1 downto 0) IS R_0EH(1 downto 0); ALIAS ClkB_FS21 : std_logic_vector(1 downto 0) IS R_0EH(3 downto 2); ALIAS ClkC_FS21 : std_logic_vector(1 downto 0) IS R_0EH(5 downto 4); ALIAS ClkD_FS21 : std_logic_vector(1 downto 0) IS R_0EH(7 downto 6); ALIAS ClkE_Div : std_logic_vector(1 downto 0) IS R_0FH(1 downto 0); ALIAS PdnEn : std_logic IS R_0FH(3); ALIAS PLL2_Q : std_logic_vector(7 downto 0) IS R_11H; ALIAS PLL2_P98 : std_logic_vector(1 downto 0) IS R_13H(1 downto 0); ALIAS PLL2_P70 : std_logic_vector(7 downto 0) IS R_12H; ALIAS PLL2_P0 : std_logic IS R_13H(2); ALIAS PLL2_En : std_logic IS R_13H(6); ALIAS PLL3_Q : std_logic_vector(7 downto 0) IS R_14H; ALIAS PLL3_P98 : std_logic_vector(1 downto 0) IS R_16H(1 downto 0); ALIAS PLL3_P70 : std_logic_vector(7 downto 0) IS R_15H; ALIAS PLL3_P0 : std_logic IS R_16H(2); ALIAS PLL3_En : std_logic IS R_16H(6); SIGNAL Pll1A_Q : std_logic_vector(7 DOWNTO 0) := "00000000"; SIGNAL PLL1A_P98 : std_logic_vector(1 downto 0) := "00"; SIGNAL PLL1A_P70 : std_logic_vector(7 downto 0) := "00000000"; SIGNAL PLL1A_P0 : std_logic := '0'; SIGNAL PLL1A_En : std_logic := '0'; SIGNAL PLL1A_DivSel : std_logic := '0'; SIGNAL Pll1B_Q : std_logic_vector(7 DOWNTO 0) := "00000000"; SIGNAL PLL1B_P98 : std_logic_vector(1 downto 0) := "00"; SIGNAL PLL1B_P70 : std_logic_vector(7 downto 0) := "00000000"; SIGNAL PLL1B_P0 : std_logic := '0'; SIGNAL PLL1B_En : std_logic := '0'; SIGNAL PLL1B_DivSel : std_logic := '0'; SIGNAL PLL1_Q : std_logic_vector(7 downto 0) := "00000000"; SIGNAL PLL1_P98 : std_logic_vector(1 downto 0) := "00"; SIGNAL PLL1_P70 : std_logic_vector(7 downto 0) := "00000000"; SIGNAL PLL1_P0 : std_logic := '0'; SIGNAL PLL1_En : std_logic := '0'; SIGNAL PLL1_DivSel : std_logic := '0'; FUNCTION NOTz(s : std_logic) RETURN std_logic IS BEGIN IF (s = 'Z') THEN RETURN 'Z'; ELSE RETURN NOT s; END IF; END NOTz; FUNCTION NOT1(s : std_logic) RETURN std_logic IS BEGIN IF (s = 'Z') THEN RETURN '1'; ELSE RETURN NOT s; END IF; END NOT1; BEGIN --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay( XTALIN_ipd, XTALIN, tipd_XTALIN ); w_2 : VitalWireDelay( SDAT_ipd, SDAT, tipd_SDAT ); w_3 : VitalWireDelay( SCLK_ipd, SCLK, tipd_SCLK ); w_4 : VitalWireDelay( S2SUSPENDNeg_ipd, S2SUSPENDNeg, tipd_S2SUSPENDNeg ); w_5 : VitalWireDelay( SHUTDOWNNegOE_ipd, SHUTDOWNNegOE, tipd_SHUTDOWNNegOE ); END BLOCK; --------------------------------------------------------------------------- -- Main Behavior Block --------------------------------------------------------------------------- Behavior: BLOCK BEGIN S2 <= S2SUSPENDNeg; -- purpose: Latching of S0 on power up -- type : combinational -- outputs: S0 S0_Latching: PROCESS VARIABLE first : BOOLEAN := true; BEGIN -- PROCESS S0_Latching IF first THEN first := false; S0 <= SDAT; ELSE WAIT; END IF; END PROCESS S0_Latching; -- purpose: Latching of SCLK pin in S1 signal on startup -- type : combinational -- inputs : -- outputs: S1 S1_Latching: PROCESS VARIABLE first : BOOLEAN := true; BEGIN -- PROCESS S1_Latching IF first THEN S1 <= SCLK; first := false; ELSE WAIT; END IF; END PROCESS S1_Latching; ----------------------------------------------------------------------- -- Selector Process ----------------------------------------------------------------------- Selector01 : PROCESS(S1, S0,R_40H,R_41H,R_42H,R_43H,R_44H,R_45H,R_46H, R_47H,R_48H,R_49H,R_4AH,R_4BH,R_4CH,R_4DH,R_4EH, R_4FH,R_50H,R_51H,R_52H, R_53H,R_54H,R_55H,R_56H,R_57H) VARIABLE S : natural range 0 to 3; BEGIN S := to_nat((S1,S0)); CASE S IS WHEN 0 => PLL1A_Q <= R_40H; PLL1A_P98 <= R_42H(1 downto 0); PLL1A_P70 <= R_41H; PLL1A_P0 <= R_42H(2); PLL1A_En <= R_42H(6); PLL1A_DivSel <= R_42H(7); PLL1B_Q <= R_4CH; PLL1B_P98 <= R_4EH(1 downto 0); PLL1B_P70 <= R_4DH; PLL1B_P0 <= R_4EH(2); PLL1B_En <= R_4EH(6); PLL1B_DivSel <= R_4EH(7); WHEN 1 => PLL1A_Q <= R_43H; PLL1A_P98 <= R_45H(1 downto 0); PLL1A_P70 <= R_44H; PLL1A_P0 <= R_45H(2); PLL1A_En <= R_45H(6); PLL1A_DivSel <= R_45H(7); PLL1B_Q <= R_4FH; PLL1B_P98 <= R_51H(1 downto 0); PLL1B_P70 <= R_50H; PLL1B_P0 <= R_51H(2); PLL1B_En <= R_51H(6); PLL1B_DivSel <= R_51H(7); WHEN 2 => PLL1A_Q <= R_46H; PLL1A_P98 <= R_48H(1 downto 0); PLL1A_P70 <= R_47H; PLL1A_P0 <= R_48H(2); PLL1A_En <= R_48H(6); PLL1A_DivSel <= R_48H(7); PLL1B_Q <= R_52H; PLL1B_P98 <= R_54H(1 downto 0); PLL1B_P70 <= R_53H; PLL1B_P0 <= R_54H(2); PLL1B_En <= R_54H(6); PLL1B_DivSel <= R_54H(7); WHEN 3 => PLL1A_Q <= R_49H; PLL1A_P98 <= R_4BH(1 downto 0); PLL1A_P70 <= R_4AH; PLL1A_P0 <= R_4BH(2); PLL1A_En <= R_4BH(6); PLL1A_DivSel <= R_4BH(7); PLL1B_Q <= R_55H; PLL1B_P98 <= R_57H(1 downto 0); PLL1B_P70 <= R_56H; PLL1B_P0 <= R_57H(2); PLL1B_En <= R_57H(6); PLL1B_DivSel <= R_57H(7); WHEN OTHERS => NULL; END CASE; END PROCESS Selector01; Selector2: PROCESS (PLL1A_Q,PLL1A_P98,PLL1A_P70,PLL1A_P0,PLL1A_En, PLL1A_DivSel,PLL1B_Q,PLL1B_P98,PLL1B_P70,PLL1B_P0, PLL1B_En,PLL1B_DivSel,S2) IS BEGIN -- PROCESS Selector2 CASE S2 IS WHEN '0' => PLL1_Q <= PLL1A_Q; PLL1_P98 <= PLL1A_P98; PLL1_P70 <= PLL1A_P70; PLL1_P0 <= PLL1A_P0; PLL1_En <= PLL1A_En; PLL1_DivSel <= PLL1A_DivSel; WHEN '1' => PLL1_Q <= PLL1B_Q; PLL1_P98 <= PLL1B_P98; PLL1_P70 <= PLL1B_P70; PLL1_P0 <= PLL1B_P0; PLL1_En <= PLL1B_En; PLL1_DivSel <= PLL1B_DivSel; WHEN OTHERS => NULL; END CASE; END PROCESS Selector2; ----------------------------------------------------------------------- -- PLL1 Process ----------------------------------------------------------------------- PLL1 : PROCESS (XTALIN, MULT1_OUT, PLL1_OUT) VARIABLE clk_period : time := 0 ns; VARIABLE prev_clk : time := 0 ns; VARIABLE mult_period : time := 0 ns; VARIABLE prev_mult : time := 0 ns; VARIABLE half_per : time := 3 ns; BEGIN ------------------------------------------------------------------- -- Functionality Section ------------------------------------------------------------------- IF rising_edge(XTALIN) THEN clk_period := NOW - prev_clk; prev_clk := NOW; END IF; IF rising_edge(MULT1_OUT) THEN mult_period := NOW - prev_mult; prev_mult := NOW; IF mult_period > (clk_period + 350 ns) THEN half_per := half_per - 60 ps; PLL1_LOCK <= false; ELSIF mult_period < (clk_period - 350 ns) THEN half_per := half_per + 59 ps; PLL1_LOCK <= false; ELSIF mult_period > (clk_period + 3 ns) THEN half_per := half_per - 6 ps; PLL1_LOCK <= false; ELSIF mult_period < (clk_period - 3 ns) THEN half_per := half_per + 5.9 ps; PLL1_LOCK <= false; ELSIF mult_period > (clk_period + 300 ps) THEN half_per := half_per - 600 fs; PLL1_LOCK <= false; ELSIF mult_period < (clk_period - 300 ps) THEN half_per := half_per + 590 fs; PLL1_LOCK <= false; ELSIF mult_period > (clk_period + 30 ps) THEN half_per := half_per - 60 fs; PLL1_LOCK <= false; ELSIF mult_period < (clk_period - 30 ps) THEN half_per := half_per + 59 fs; PLL1_LOCK <= false; ELSIF mult_period > (clk_period + 3 ps) THEN half_per := half_per - 6 fs; PLL1_LOCK <= false; ELSIF mult_period < (clk_period - 3 ps) THEN half_per := half_per + 5 fs; PLL1_LOCK <= false; ELSIF NOW > 0 ns THEN PLL1_LOCK <= true; ELSE PLL1_LOCK <= false; END IF; END IF; IF (PLL1_En='1'AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1')))AND NOT PLL1_OUT'event THEN PLL1_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; END IF; IF (rising_edge(PLL1_OUT) OR (NOW = 0 ns)) AND (PLL1_En = '1' AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1'))) THEN PLL1_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; ELSIF (PLL1_En = '0') OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '0') THEN PLL1_OUT <= 'Z'; END IF; END PROCESS PLL1; ------------------------------------------------------------------------ -- PLL2 Process ------------------------------------------------------------------------ PLL2 : PROCESS (XTALIN, MULT2_OUT, PLL2_OUT) VARIABLE clk_period : time := 0 ns; VARIABLE prev_clk : time := 0 ns; VARIABLE mult_period : time := 0 ns; VARIABLE prev_mult : time := 0 ns; VARIABLE half_per : time := 3 ns; BEGIN -------------------------------------------------------------------- -- Functionality Section -------------------------------------------------------------------- IF rising_edge(XTALIN) THEN clk_period := NOW - prev_clk; prev_clk := NOW; END IF; IF rising_edge(MULT2_OUT) THEN mult_period := NOW - prev_mult; prev_mult := NOW; IF mult_period > (clk_period + 350 ns) THEN half_per := half_per - 60 ps; PLL2_LOCK <= false; ELSIF mult_period < (clk_period - 350 ns) THEN half_per := half_per + 59 ps; PLL2_LOCK <= false; ELSIF mult_period > (clk_period + 3 ns) THEN half_per := half_per - 6 ps; PLL2_LOCK <= false; ELSIF mult_period < (clk_period - 3 ns) THEN half_per := half_per + 5.9 ps; PLL2_LOCK <= false; ELSIF mult_period > (clk_period + 300 ps) THEN half_per := half_per - 600 fs; PLL2_LOCK <= false; ELSIF mult_period < (clk_period - 300 ps) THEN half_per := half_per + 590 fs; PLL2_LOCK <= false; ELSIF mult_period > (clk_period + 30 ps) THEN half_per := half_per - 60 fs; PLL2_LOCK <= false; ELSIF mult_period < (clk_period - 30 ps) THEN half_per := half_per + 59 fs; PLL2_LOCK <= false; ELSIF mult_period > (clk_period + 3 ps) THEN half_per := half_per - 6 fs; PLL2_LOCK <= false; ELSIF mult_period < (clk_period - 3 ps) THEN half_per := half_per + 5 fs; PLL2_LOCK <= false; ELSIF NOW > 0 ns THEN PLL2_LOCK <= true; ELSE PLL2_LOCK <= false; END IF; END IF; IF (PLL2_En = '1' AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1')))AND NOT PLL2_OUT'event THEN PLL2_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; END IF; IF (rising_edge(PLL2_OUT) OR (NOW = 0 ns)) AND (PLL2_En = '1' AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1'))) THEN PLL2_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; ELSIF (PLL2_En = '0') OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '0') THEN PLL2_OUT <= 'Z'; END IF; END PROCESS PLL2; ----------------------------------------------------------------------- -- PLL3 Process ----------------------------------------------------------------------- PLL3 : PROCESS (XTALIN, MULT3_OUT, PLL3_OUT) VARIABLE clk_period : time := 0 ns; VARIABLE prev_clk : time := 0 ns; VARIABLE mult_period : time := 0 ns; VARIABLE prev_mult : time := 0 ns; VARIABLE half_per : time := 5 ns; BEGIN ------------------------------------------------------------------- -- Functionality Section ------------------------------------------------------------------- IF rising_edge(XTALIN) THEN clk_period := NOW - prev_clk; prev_clk := NOW; END IF; IF rising_edge(MULT3_OUT) THEN mult_period := NOW - prev_mult; prev_mult := NOW; IF mult_period > (clk_period + 350 ns) THEN half_per := half_per - 60 ps; PLL3_LOCK <= false; ELSIF mult_period < (clk_period - 350 ns) THEN half_per := half_per + 59 ps; PLL3_LOCK <= false; ELSIF mult_period > (clk_period + 3 ns) THEN half_per := half_per - 6 ps; PLL3_LOCK <= false; ELSIF mult_period < (clk_period - 3 ns) THEN half_per := half_per + 5.9 ps; PLL3_LOCK <= false; ELSIF mult_period > (clk_period + 300 ps) THEN half_per := half_per - 600 fs; PLL3_LOCK <= false; ELSIF mult_period < (clk_period - 300 ps) THEN half_per := half_per + 590 fs; PLL3_LOCK <= false; ELSIF mult_period > (clk_period + 30 ps) THEN half_per := half_per - 60 fs; PLL3_LOCK <= false; ELSIF mult_period < (clk_period - 30 ps) THEN half_per := half_per + 59 fs; PLL3_LOCK <= false; ELSIF mult_period > (clk_period + 3 ps) THEN half_per := half_per - 6 fs; PLL3_LOCK <= false; ELSIF mult_period < (clk_period - 3 ps) THEN half_per := half_per + 5 fs; PLL3_LOCK <= false; ELSIF NOW > 0 ns THEN PLL3_LOCK <= true; ELSE PLL3_LOCK <= false; END IF; END IF; IF (PLL3_En = '1' AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1')))AND NOT PLL3_OUT'event THEN PLL3_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; END IF; IF (rising_edge(PLL3_OUT) OR (NOW = 0 ns)) AND (PLL3_En = '1' AND (PdnEn = '0' OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '1'))) THEN PLL3_OUT <= '0' AFTER half_per, '1' AFTER 2*half_per; ELSIF (PLL3_En = '0') OR ( PdnEn = '1' AND SHUTDOWNNegOE_ipd = '0') THEN PLL3_OUT <= 'Z'; END IF; END PROCESS PLL3; ----------------------------------------------------------------------- -- Multiplier Process -- The "Multiplier" actually divides the PLL_OUT signal ----------------------------------------------------------------------- MULT1 : PROCESS (PLL1_OUT) VARIABLE mult_in : natural; VARIABLE mult_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN mult_in := 2 * (to_nat(PLL1_P98) * 16#100# + to_nat(PLL1_P70) + 3) + to_nat(PLL1_P0); IF PLL1_OUT /= 'Z' THEN IF PLL1_OUT'event THEN IF first THEN MULT1_OUT <= PLL1_OUT; first := false; mult_cnt := mult_cnt + 1; ELSIF mult_cnt < mult_in THEN mult_cnt := mult_cnt + 1; ELSE mult_cnt := 1; MULT1_OUT <= NOT1(MULT1_OUT); END IF; END IF; ELSE first := true; mult_cnt := 0; MULT1_OUT <= 'Z'; END IF; END PROCESS MULT1; ----------------------------------------------------------------------- -- Multiplier Process -- The "Multiplier" actually divides the PLL_OUT signal ----------------------------------------------------------------------- MULT2 : PROCESS (PLL2_OUT) VARIABLE mult_in : natural; VARIABLE mult_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN mult_in := 2 * (to_nat(PLL2_P98) * 16#100# + to_nat(PLL2_P70) + 3) + to_nat(PLL2_P0); IF PLL2_OUT /= 'Z' THEN IF PLL2_OUT'event THEN IF first THEN MULT2_OUT <= PLL2_OUT; first := false; mult_cnt := mult_cnt + 1; ELSIF mult_cnt < mult_in THEN mult_cnt := mult_cnt + 1; ELSE mult_cnt := 1; MULT2_OUT <= NOT1(MULT2_OUT); END IF; END IF; ELSE first := true; mult_cnt := 0; MULT2_OUT <= 'Z'; END IF; END PROCESS MULT2; ----------------------------------------------------------------------- -- Multiplier Process -- The "Multiplier" actually divides the PLL_OUT signal ----------------------------------------------------------------------- MULT3 : PROCESS (PLL3_OUT) VARIABLE mult_in : natural; VARIABLE mult_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN mult_in := 2 * (to_nat(PLL3_P98) * 16#100# + to_nat(PLL3_P70) + 3) + to_nat(PLL3_P0); IF PLL3_OUT /= 'Z' THEN IF PLL3_OUT'event THEN IF first THEN MULT3_OUT <= PLL3_OUT; first := false; mult_cnt := mult_cnt + 1; ELSIF mult_cnt < mult_in THEN mult_cnt := mult_cnt + 1; ELSE mult_cnt := 1; MULT3_OUT <= NOT1(MULT3_OUT); END IF; END IF; ELSE first := true; mult_cnt := 0; MULT3_OUT <= 'Z'; END IF; END PROCESS MULT3; ----------------------------------------------------------------------- -- Divider Process ----------------------------------------------------------------------- DIV1 : PROCESS (PLL1_OUT) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN div_in := to_nat(PLL1_Q) + 2; IF PLL1_OUT /= 'Z' THEN IF PLL1_OUT'event THEN IF first THEN DIV1_OUT <= PLL1_OUT; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; DIV1_OUT <= NOT1(DIV1_OUT); END IF; END IF; ELSE first := true; div_cnt := 0; DIV1_OUT <= 'Z'; END IF; END PROCESS DIV1; ----------------------------------------------------------------------- -- Divider Process ----------------------------------------------------------------------- DIV2 : PROCESS (PLL2_OUT) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN div_in := to_nat(PLL2_Q) + 2; IF PLL2_OUT /= 'Z' THEN IF PLL2_OUT'event THEN IF first THEN DIV2_OUT <= PLL2_OUT; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; DIV2_OUT <= NOT1(DIV2_OUT); END IF; END IF; ELSE first := true; div_cnt := 0; DIV2_OUT <= 'Z'; END IF; END PROCESS DIV2; ----------------------------------------------------------------------- -- Divider Process ----------------------------------------------------------------------- DIV3 : PROCESS (PLL3_OUT) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN div_in := to_nat(PLL3_Q) + 2; IF PLL3_OUT /= 'Z' THEN IF PLL3_OUT'event THEN IF first THEN DIV3_OUT <= PLL3_OUT; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; DIV3_OUT <= NOT1(DIV3_OUT); END IF; END IF; ELSE first := true; div_cnt := 0; DIV3_OUT <= 'Z'; END IF; END PROCESS DIV3; ----------------------------------------------------------------------- -- 4x4 Crosspoint Switch - Process ----------------------------------------------------------------------- CrosspointSwitch : PROCESS (XTALIN, DIV1_OUT, DIV2_OUT, DIV3_OUT) VARIABLE crossA : natural range 0 to 7; VARIABLE crossB : natural range 0 to 7; VARIABLE crossC : natural range 0 to 7; VARIABLE crossD : natural range 0 to 7; BEGIN IF PLL1_DivSel = '0' THEN crossA := to_nat((ClkA_FS21(1),ClkA_FS21(0),ClkA0_FS0)); crossB := to_nat((ClkB_FS21(1),ClkB_FS21(0),ClkB0_FS0)); ELSE crossA := to_nat((ClkA_FS21(1),ClkA_FS21(0),ClkA1_FS0)); crossB := to_nat((ClkB_FS21(1),ClkB_FS21(0),ClkB1_FS0)); END IF; crossC := to_nat((ClkC_FS21(1),ClkC_FS21(0),ClkC_FS0)); crossD := to_nat((ClkD_FS21(1),ClkD_FS21(0),ClkD_FS0)); CASE crossA IS WHEN 0 => PostDivA_in <= XTALIN; WHEN 1 => PostDivA_in <= NOTz(XTALIN); WHEN 2 => PostDivA_in <= DIV1_OUT; WHEN 3 => PostDivA_in <= NOTz(DIV1_OUT); WHEN 4 => PostDivA_in <= DIV2_OUT; WHEN 5 => PostDivA_in <= NOTz(DIV2_OUT); WHEN 6 => PostDivA_in <= DIV3_OUT; WHEN 7 => PostDivA_in <= NOTz(DIV3_OUT); WHEN OTHERS => NULL; END CASE; CASE crossB IS WHEN 0 => PostDivB_in <= XTALIN; WHEN 1 => PostDivB_in <= NOTz(XTALIN); WHEN 2 => PostDivB_in <= DIV1_OUT; WHEN 3 => PostDivB_in <= NOTz(DIV1_OUT); WHEN 4 => PostDivB_in <= DIV2_OUT; WHEN 5 => PostDivB_in <= NOTz(DIV2_OUT); WHEN 6 => PostDivB_in <= DIV3_OUT; WHEN 7 => PostDivB_in <= NOTz(DIV3_OUT); WHEN OTHERS => NULL; END CASE; CASE crossC IS WHEN 0 => PostDivC_in <= XTALIN; WHEN 1 => PostDivC_in <= NOTz(XTALIN); WHEN 2 => PostDivC_in <= DIV1_OUT; WHEN 3 => PostDivC_in <= NOTz(DIV1_OUT); WHEN 4 => PostDivC_in <= DIV2_OUT; WHEN 5 => PostDivC_in <= NOTz(DIV2_OUT); WHEN 6 => PostDivC_in <= DIV3_OUT; WHEN 7 => PostDivC_in <= NOTz(DIV3_OUT); WHEN OTHERS => NULL; END CASE; CASE crossD IS WHEN 0 => PostDivD_in <= XTALIN; WHEN 1 => PostDivD_in <= NOTz(XTALIN); WHEN 2 => PostDivD_in <= DIV1_OUT; WHEN 3 => PostDivD_in <= NOTz(DIV1_OUT); WHEN 4 => PostDivD_in <= DIV2_OUT; WHEN 5 => PostDivD_in <= NOTz(DIV2_OUT); WHEN 6 => PostDivD_in <= DIV3_OUT; WHEN 7 => PostDivD_in <= NOTz(DIV3_OUT); WHEN OTHERS => NULL; END CASE; END PROCESS CrosspointSwitch; PostDivE_in <= DIV1_OUT; ----------------------------------------------------------------------- -- Post Divider Process ----------------------------------------------------------------------- POST_DIV_A : PROCESS (PostDivA_in) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN IF PLL1_DivSel = '0' THEN div_in := to_nat(ClkA0_Div); ELSE div_in := to_nat(ClkA1_Div); END IF; IF div_in > 0 AND PostDivA_in /= 'Z' THEN IF PostDivA_in'event THEN IF first THEN PostDivA_out <= PostDivA_in; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; PostDivA_out <= NOT1(PostDivA_out); END IF; END IF; ELSE first := true; div_cnt := 0; PostDivA_out <= 'Z'; END IF; END PROCESS POST_DIV_A; ----------------------------------------------------------------------- -- Post Divider Process ----------------------------------------------------------------------- POST_DIV_B : PROCESS (PostDivB_in) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN IF PLL1_DivSel = '0' THEN div_in := to_nat(ClkB0_Div); ELSE div_in := to_nat(ClkB1_Div); END IF; IF div_in > 0 AND PostDivB_in /= 'Z' THEN IF PostDivB_in'event THEN IF first THEN PostDivB_out <= PostDivB_in; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; PostDivB_out <= NOT1(PostDivB_out); END IF; END IF; ELSE first := true; div_cnt := 0; PostDivB_out <= 'Z'; END IF; END PROCESS POST_DIV_B; ----------------------------------------------------------------------- -- Post Divider Process ----------------------------------------------------------------------- POST_DIV_C : PROCESS (PostDivC_in) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN div_in := to_nat(ClkC_Div); IF div_in > 0 AND PostDivC_in /= 'Z' THEN IF PostDivC_in'event THEN IF first THEN PostDivC_out <= PostDivC_in; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; PostDivC_out <= NOT1(PostDivC_out); END IF; END IF; ELSE first := true; div_cnt := 0; PostDivC_out <= 'Z'; END IF; END PROCESS POST_DIV_C; ----------------------------------------------------------------------- -- Post Divider Process ----------------------------------------------------------------------- POST_DIV_D : PROCESS (PostDivD_in) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; BEGIN div_in := to_nat(ClkD_Div); IF div_in > 0 AND PostDivD_in /= 'Z' THEN IF PostDivD_in'event THEN IF first THEN PostDivD_out <= PostDivD_in; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; PostDivD_out <= NOT1(PostDivD_out); END IF; END IF; ELSE first := true; div_cnt := 0; PostDivD_out <= 'Z'; END IF; END PROCESS POST_DIV_D; ----------------------------------------------------------------------- -- Post Divider Process ----------------------------------------------------------------------- POST_DIV_E : PROCESS (PostDivE_in) VARIABLE div_in : natural; VARIABLE div_cnt : natural; VARIABLE first : BOOLEAN := true; VARIABLE div_help: NATURAL; BEGIN div_help := to_nat(ClkE_Div); CASE div_help IS WHEN 0 => div_in := 0; WHEN 1 => div_in := 4; WHEN 2 => div_in := 2; WHEN 3 => div_in := 3; WHEN OTHERS => NULL; END CASE; IF div_in > 0 AND PostDivE_in /= 'Z' THEN IF PostDivE_in'event THEN IF first THEN PostDivE_out <= PostDivE_in; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < div_in THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; PostDivE_out <= NOT1(PostDivE_out); END IF; END IF; ELSE first := true; div_cnt := 0; PostDivE_out <= 'Z'; END IF; END PROCESS POST_DIV_E; CLKA <= PostDivA_out WHEN SHUTDOWNNegOE_ipd = '1' ELSE 'Z'; CLKB <= PostDivB_out WHEN SHUTDOWNNegOE_ipd = '1' ELSE 'Z'; CLKC <= PostDivC_out WHEN SHUTDOWNNegOE_ipd = '1' ELSE 'Z'; CLKD <= PostDivD_out WHEN SHUTDOWNNegOE_ipd = '1' ELSE 'Z'; CLKE <= PostDivE_out WHEN SHUTDOWNNegOE_ipd = '1' ELSE 'Z'; ----------------------------------------------------------------------- -- Serial Interface ----------------------------------------------------------------------- Serial : PROCESS (SDAT_ipd, SCLK_ipd) -- Type definitions TYPE SPI_State IS (STOP, START, IGNORE, READ, ADDRESS, WRITE ); VARIABLE State : SPI_State; VARIABLE BitCount : natural range 7 DOWNTO 0; VARIABLE RegAddr : natural range 0 to MaxAddr := 0; VARIABLE TmpByte : std_logic_vector(7 downto 0); VARIABLE SDAT_nwv : X01; VARIABLE SCLK_nwv : X01; VARIABLE Ack : boolean := false; VARIABLE WaitAck : boolean := false; -- Timing Check Variables VARIABLE Tviol_SDAT_SCLK : X01 := '0'; VARIABLE TD_SDAT_SCLK : VitalTimingDataType; VARIABLE Pviol_SCLK : X01 := '0'; VARIABLE PD_SCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; -- Functionality Results Variables VARIABLE SDAT_zd : std_ulogic; -- Output Glitch Detection Variables VARIABLE SDAT_GlitchData : VitalGlitchDataType; PROCEDURE Write( addr: natural; value: std_logic_vector(7 downto 0)) IS BEGIN CASE addr IS WHEN 16#08# => R_08H <= value; WHEN 16#09# => R_09H <= value; WHEN 16#0A# => R_0AH <= value; WHEN 16#0B# => R_0BH <= value; WHEN 16#0C# => R_0CH <= value; WHEN 16#0D# => R_0DH <= value; WHEN 16#0E# => R_0EH <= value; WHEN 16#0F# => R_0FH <= value; WHEN 16#10# => R_10H <= value; WHEN 16#11# => R_11H <= value; WHEN 16#12# => R_12H <= value; WHEN 16#13# => R_13H <= value; WHEN 16#14# => R_14H <= value; WHEN 16#15# => R_15H <= value; WHEN 16#16# => R_16H <= value; WHEN 16#17# => R_17H <= value; WHEN 16#40# => R_40H <= value; WHEN 16#41# => R_41H <= value; WHEN 16#42# => R_42H <= value; WHEN 16#43# => R_43H <= value; WHEN 16#44# => R_44H <= value; WHEN 16#45# => R_45H <= value; WHEN 16#46# => R_46H <= value; WHEN 16#47# => R_47H <= value; WHEN 16#48# => R_48H <= value; WHEN 16#49# => R_49H <= value; WHEN 16#4A# => R_4AH <= value; WHEN 16#4B# => R_4BH <= value; WHEN 16#4C# => R_4CH <= value; WHEN 16#4D# => R_4DH <= value; WHEN 16#4E# => R_4EH <= value; WHEN 16#4F# => R_4FH <= value; WHEN 16#50# => R_50H <= value; WHEN 16#51# => R_51H <= value; WHEN 16#52# => R_52H <= value; WHEN 16#53# => R_53H <= value; WHEN 16#54# => R_54H <= value; WHEN 16#55# => R_55H <= value; WHEN 16#56# => R_56H <= value; WHEN 16#57# => R_57H <= value; WHEN OTHERS => NULL; END CASE; END Write; IMPURE FUNCTION Read(addr: natural) RETURN natural IS VARIABLE value : natural; BEGIN CASE addr IS WHEN 16#08# => value := to_nat(R_08H); WHEN 16#09# => value := to_nat(R_09H); WHEN 16#0A# => value := to_nat(R_0AH); WHEN 16#0B# => value := to_nat(R_0BH); WHEN 16#0C# => value := to_nat(R_0CH); WHEN 16#0D# => value := to_nat(R_0DH); WHEN 16#0E# => value := to_nat(R_0EH); WHEN 16#0F# => value := to_nat(R_0FH); WHEN 16#10# => value := to_nat(R_10H); WHEN 16#11# => value := to_nat(R_11H); WHEN 16#12# => value := to_nat(R_12H); WHEN 16#13# => value := to_nat(R_13H); WHEN 16#14# => value := to_nat(R_14H); WHEN 16#15# => value := to_nat(R_15H); WHEN 16#16# => value := to_nat(R_16H); WHEN 16#17# => value := to_nat(R_17H); WHEN 16#40# => value := to_nat(R_40H); WHEN 16#41# => value := to_nat(R_41H); WHEN 16#42# => value := to_nat(R_42H); WHEN 16#43# => value := to_nat(R_43H); WHEN 16#44# => value := to_nat(R_44H); WHEN 16#45# => value := to_nat(R_45H); WHEN 16#46# => value := to_nat(R_46H); WHEN 16#47# => value := to_nat(R_47H); WHEN 16#48# => value := to_nat(R_48H); WHEN 16#49# => value := to_nat(R_49H); WHEN 16#4A# => value := to_nat(R_4AH); WHEN 16#4B# => value := to_nat(R_4BH); WHEN 16#4C# => value := to_nat(R_4CH); WHEN 16#4D# => value := to_nat(R_4DH); WHEN 16#4E# => value := to_nat(R_4EH); WHEN 16#4F# => value := to_nat(R_4FH); WHEN 16#50# => value := to_nat(R_50H); WHEN 16#51# => value := to_nat(R_51H); WHEN 16#52# => value := to_nat(R_52H); WHEN 16#53# => value := to_nat(R_53H); WHEN 16#54# => value := to_nat(R_54H); WHEN 16#55# => value := to_nat(R_55H); WHEN 16#56# => value := to_nat(R_56H); WHEN 16#57# => value := to_nat(R_57H); WHEN OTHERS => value := 0; END CASE; RETURN value; END Read; BEGIN SDAT_nwv := to_X01(SDAT_ipd); SCLK_nwv := to_X01(SCLK); ------------------------------------------------------------------- -- Timing Check Section ------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => SDAT_ipd, TestSignalName => "SDAT", RefSignal => SCLK_ipd, RefSignalName => "SCLK", SetupHigh => tsetup_SDAT_SCLK, SetupLow => tsetup_SDAT_SCLK, CheckEnabled => TRUE, RefTransition => '\', HeaderMsg => InstancePath & "/cy22395", TimingData => TD_SDAT_SCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_SDAT_SCLK ); VitalPeriodPulseCheck ( TestSignal => SCLK_ipd, TestSignalName => "SCLK", Period => tperiod_SCLK, PulseWidthHigh => tpw_SCLK_posedge, PulseWidthLow => tpw_SCLK_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & "/cy22395", PeriodData => PD_SCLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_SCLK ); END IF; ------------------------------------------------------------------ -- Functionality Section ------------------------------------------------------------------ Violation := Tviol_SDAT_SCLK OR Pviol_SCLK; ASSERT Violation = '0' REPORT InstancePath & " control registers may be" & " incorret due to I2C timing violation(s)" SEVERITY Warning; IF (falling_edge(SDAT_ipd) AND SCLK_ipd'stable AND SCLK_nwv = '1') THEN State := START; BitCount := 0; ELSIF (rising_edge(SDAT_ipd) AND SCLK_ipd'stable AND SCLK_nwv = '1') THEN State := STOP; END IF; IF (rising_edge(SCLK_ipd) AND Ack = false) THEN CASE State IS WHEN START => TmpByte(7-BitCount) := SDAT_nwv; IF (BitCount < 7) THEN BitCount := BitCount + 1; ELSIF (TmpByte(7 DOWNTO 1) = DeviceAddress(6 downto 0)) THEN IF TmpByte(0) = '0' THEN State := ADDRESS; ELSE State := READ; WaitAck := true; TmpByte := to_slv(Read(RegAddr),8); END IF; Ack := true; ELSE State := IGNORE; END IF; WHEN ADDRESS => TmpByte(7 - BitCount) := SDAT_nwv; IF (BitCount < 7) THEN BitCount := BitCount + 1; ELSE RegAddr := to_nat(TmpByte); State := WRITE; Ack := true; END IF; WHEN WRITE => TmpByte(7 - BitCount) := SDAT_nwv; IF (BitCount < 7) THEN BitCount := BitCount + 1; ELSE Write(RegAddr, TmpByte); RegAddr := (RegAddr + 1) MOD (MaxAddr + 1); Ack := true; END IF; WHEN OTHERS => NULL; END CASE; ELSIF falling_edge(SCLK_ipd) THEN CASE State IS WHEN READ => IF (BitCount < 7) THEN SDAT_zd := TmpByte(7 - BitCount); BitCount := BitCount + 1; ELSIF WaitAck = false THEN SDAT_zd := TmpByte(7 - BitCount); RegAddr := (RegAddr + 1) MOD (MaxAddr + 1); WaitAck := true; ELSE IF (Ack = true) THEN SDAT_zd := '0'; Ack := false; ELSE SDAT_zd := 'Z'; END IF; BitCount := 0; WaitAck := false; TmpByte := to_slv(Read(RegAddr),8); END IF; WHEN OTHERS => NULL; END CASE; END IF; IF (falling_edge(SCLK_ipd) AND Ack = true AND State /= READ) THEN IF (SDAT_zd = '0') THEN Ack := false; SDAT_zd := 'Z'; BitCount := 0; ELSE SDAT_zd := '0'; END IF; END IF; ------------------------------------------------------------------- -- Path Delay Section ------------------------------------------------------------------- VitalPathDelay01Z ( OutSignal => SDAT, OutSignalName => "SDAT", OutTemp => SDAT_zd, Paths => ( 0 => (InputChangeTime => SCLK_ipd'LAST_EVENT, PathDelay => UnitDelay01Z, PathCondition => TRUE ) ), GlitchData => SDAT_GlitchData ); END PROCESS Serial; END BLOCK; END vhdl_behavioral;