-------------------------------------------------------------------------------- -- File Name: ak5393.vhd -------------------------------------------------------------------------------- -- Copyright (C) 2004 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.Radmanovic 04 Feb 18 Initial release -- -- This model must be compiled without VITAL compliance checking -- -- -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: CONVERTER_VHDL -- Technology: MIXED -- Part: AK5393 -- Description: Enhanced Dual Bit 96kHz 24-Bit ADC -------------------------------------------------------------------------------- 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 ak5393 IS GENERIC ( -- tipd delays: interconnect path delays tipd_ZCAL : VitalDelayType01 := VitalZeroDelay01; tipd_RSTNeg : VitalDelayType01 := VitalZeroDelay01; tipd_SMODE2 : VitalDelayType01 := VitalZeroDelay01; tipd_SMODE1 : VitalDelayType01 := VitalZeroDelay01; tipd_LRCK : VitalDelayType01 := VitalZeroDelay01; tipd_SCLK : VitalDelayType01 := VitalZeroDelay01; tipd_FSYNC : VitalDelayType01 := VitalZeroDelay01; tipd_MCLK : VitalDelayType01 := VitalZeroDelay01; tipd_DFS : VitalDelayType01 := VitalZeroDelay01; tipd_HPFE : VitalDelayType01 := VitalZeroDelay01; tipd_TEST : VitalDelayType01 := VitalZeroDelay01; -- tpd delays tpd_LRCK_SDATA : VitalDelayType01 := UnitDelay01; tpd_SCLK_SDATA : VitalDelayType01 := UnitDelay01; -- tperiod min (calculated as 1/max freq) tperiod_MCLK : VitalDelayType := UnitDelay; tperiod_SCLK : VitalDelayType := UnitDelay; -- tsetup values: setup times tsetup_LRCK_SCLK : VitalDelayType := UnitDelay; tsetup_LRCK_SCLK_SMODE1_EQ_1_noedge_negedge : VitalDelayType := UnitDelay; -- thold values: hold times thold_FSYNC_SCLK : VitalDelayType := UnitDelay; thold_FSYNC_SCLK_SMODE1_EQ_1_noedge_negedge : VitalDelayType := UnitDelay; thold_CAL_RSTNeg : VitalDelayType := UnitDelay; -- tpw values: pulse widths tpw_MCLK_posedge : VitalDelayType := UnitDelay; tpw_MCLK_negedge : VitalDelayType := UnitDelay; tpw_SCLK_posedge : VitalDelayType := UnitDelay; tpw_SCLK_negedge : VitalDelayType := UnitDelay; tpw_RSTNeg_negedge : VitalDelayType := UnitDelay; -- analog generics: VREFL : real; VCOML : real; VREFR : real; VCOMR : real; -- 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 ( AINL : IN real := 0.0; AINLNeg : IN real := 0.0; AINR : IN real := 0.0; AINRNeg : IN real := 0.0; ZCAL : IN std_ulogic := 'U'; CAL : OUT std_ulogic := 'U'; RSTNeg : IN std_ulogic := 'U'; SMODE1 : IN std_ulogic := 'U'; SMODE2 : IN std_ulogic := 'U'; LRCK : INOUT std_logic := 'U'; SCLK : INOUT std_logic := 'U'; SDATA : OUT std_ulogic := 'U'; FSYNC : INOUT std_logic := 'U'; MCLK : IN std_ulogic := 'U'; DFS : IN std_ulogic := 'U'; HPFE : IN std_ulogic := 'U'; TEST : IN std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of ak5393 : ENTITY IS TRUE; END ak5393; -------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION -------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of ak5393 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "ak5393"; SIGNAL ZCAL_ipd : std_ulogic := 'U'; SIGNAL RSTNeg_ipd : std_ulogic := 'U'; SIGNAL SMODE1_ipd : std_ulogic := 'U'; SIGNAL SMODE2_ipd : std_ulogic := 'U'; SIGNAL LRCK_ipd : std_ulogic := 'U'; SIGNAL SCLK_ipd : std_ulogic := 'U'; SIGNAL MCLK_ipd : std_ulogic := 'U'; SIGNAL DFS_ipd : std_ulogic := 'U'; SIGNAL FSYNC_ipd : std_ulogic := 'U'; SIGNAL HPFE_ipd : std_ulogic := 'U'; SIGNAL TEST_ipd : std_ulogic := 'U'; BEGIN ---------------------------------------------------------------------------- -- Wire Delays ---------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_9 : VitalWireDelay (ZCAL_ipd, ZCAL, tipd_ZCAL); w_11 : VitalWireDelay (RSTNeg_ipd, RSTNeg, tipd_RSTNeg); w_12 : VitalWireDelay (SMODE1_ipd, SMODE1, tipd_SMODE1); w_13 : VitalWireDelay (SMODE2_ipd, SMODE2, tipd_SMODE2); w_14 : VitalWireDelay (LRCK_ipd, LRCK, tipd_LRCK); w_15 : VitalWireDelay (SCLK_ipd, SCLK, tipd_SCLK); w_17 : VitalWireDelay (FSYNC_ipd, FSYNC, tipd_FSYNC); w_18 : VitalWireDelay (MCLK_ipd, MCLK, tipd_MCLK); w_19 : VitalWireDelay (DFS_ipd, DFS, tipd_DFS); w_20 : VitalWireDelay (HPFE_ipd, HPFE, tipd_HPFE); w_21 : VitalWireDelay (TEST_ipd, TEST, tipd_TEST); END BLOCK; Behavior : BLOCK PORT ( AINL : IN real := 0.0; AINLNeg : IN real := 0.0; AINR : IN real := 0.0; AINRNeg : IN real := 0.0; ZCAL : IN std_ulogic := 'U'; CAL : OUT std_ulogic := 'U'; RSTNeg : IN std_ulogic := 'U'; SMODE1 : IN std_ulogic := 'U'; SMODE2 : IN std_ulogic := 'U'; LRCKIn : IN std_ulogic := 'U'; LRCKOut : OUT std_ulogic := 'U'; SCLKIn : IN std_ulogic := 'U'; SCLKOut : OUT std_ulogic := 'U'; SDATA : OUT std_ulogic := 'U'; FSYNCIn : IN std_ulogic := 'U'; FSYNCOut : OUT std_ulogic := 'U'; MCLK : IN std_ulogic := 'U'; DFS : IN std_ulogic := 'U'; HPFE : IN std_ulogic := 'U'; TEST : IN std_ulogic := 'U' ); PORT MAP ( AINL => AINL, AINLNeg => AINLNeg, AINR => AINR, AINRNeg => AINRNeg, ZCAL => ZCAL_ipd, CAL => CAL, RSTNeg => RSTNeg_ipd, SMODE1 => SMODE1_ipd, SMODE2 => SMODE2_ipd, LRCKIn => LRCK_ipd, LRCKOut => LRCK, SCLKIn => SCLK_ipd, SCLKOut => SCLK, SDATA => SDATA, FSYNCIn => FSYNC_ipd, FSYNCOut => FSYNC, MCLK => MCLK_ipd, DFS => DFS_ipd, HPFE => HPFE_ipd, TEST => TEST_ipd ); TYPE Data_reg IS ARRAY (38 downto 0) OF std_logic_vector(23 downto 0); SIGNAL LchData_reg : Data_reg := (others =>(others => '0')); SIGNAL RchData_reg : Data_reg := (others =>(others => '0')); SIGNAL PeriodLRCK : TIME := 30720 ns; SIGNAL PeriodSCLK : TIME := 240 ns; SIGNAL PeriodFSYNC : TIME := 15360 ns; SIGNAL LRCKTmp : std_ulogic := '0'; SIGNAL LRCKInt : std_ulogic := '0'; SIGNAL SCLKTmp : std_ulogic := '0'; SIGNAL SCLKInt : std_ulogic := '0'; SIGNAL FSYNC_del : std_ulogic := '1'; SIGNAL FSYNCTmp : std_ulogic := '1'; SIGNAL FSYNCInt : std_ulogic := '1'; SIGNAL CAL_zd : std_ulogic := 'U'; SIGNAL SDATA_zd : std_ulogic := 'U'; BEGIN LRCKInt <= LRCKIn WHEN SMODE1 = '0' ELSE LRCKTmp; SCLKInt <= SCLKIn WHEN SMODE1 = '0' ELSE SCLKTmp; FSYNCInt <= FSYNCIn WHEN SMODE1 = '0' ELSE FSYNC_del; FSYNC_del <= FSYNCTmp AFTER PeriodSCLK*2; CAL <= CAL_zd; LROut : PROCESS (SMODE1, SMODE2, RSTNeg,LRCKTmp, SCLKTmp, FSYNCTmp) BEGIN IF SMODE1 = '1' THEN IF RSTNeg = '0' THEN SCLKOut <= '0'; FSYNCOut <= '0'; IF SMODE2 = '0' THEN LRCKOut <= '1'; ELSE LRCKOut <= '0'; END IF; ELSE LRCKOut <= LRCKTmp; SCLKOut <= SCLKTmp; FSYNCOut <= FSYNC_del; END IF; ELSE LRCKOut <= 'Z'; SCLKOut <= 'Z'; FSYNCOut <= 'Z'; END IF; END PROCESS LROut; Clock: PROCESS (MCLK) VARIABLE Previous : TIME := 0 ns; VARIABLE PeriodMCLK : TIME := 120 ns; BEGIN IF rising_edge(MCLK) THEN PeriodMCLK := NOW - Previous; Previous := NOW; IF DFS = '1' THEN PeriodLRCK <= 128 * (PeriodMCLK/2); PeriodFSYNC <= 64 * (PeriodMCLK/2); ELSE PeriodLRCK <= 256 * (PeriodMCLK/2); PeriodFSYNC <= 128 * (PeriodMCLK/2); END IF; PeriodSCLK <= 2 * (PeriodMCLK/2); END IF; END PROCESS Clock; LRClock : PROCESS VARIABLE SynchCLK : BOOLEAN := FALSE; BEGIN IF NOT SynchCLK THEN LRCKTmp <= not(LRCKTmp); ELSE LRCKTmp <= MCLK; SynchCLK := FALSE; END IF; WAIT UNTIL PeriodLRCK'EVENT FOR PeriodLRCK; IF PeriodLRCK'Event THEN SynchCLK := TRUE; END IF; END PROCESS LRClock; SClock : PROCESS VARIABLE SynchCLK : BOOLEAN := FALSE; BEGIN IF NOT SynchCLK THEN SCLKTmp <= not(SCLKTmp); ELSE SCLKTmp <= MCLK; SynchCLK := FALSE; END IF; WAIT UNTIL PeriodSCLK'EVENT FOR PeriodSCLK; IF PeriodSCLK'Event THEN SynchCLK := TRUE; END IF; END PROCESS SClock; FClock : PROCESS VARIABLE SynchCLK : BOOLEAN := FALSE; BEGIN IF NOT SynchCLK THEN FSYNCTmp <= not(FSYNCTmp); ELSE FSYNCTmp <= MCLK; SynchCLK := FALSE; END IF; WAIT UNTIL PeriodFSYNC'EVENT FOR PeriodFSYNC; IF PeriodFSYNC'Event THEN SynchCLK := TRUE; END IF; END PROCESS FClock; Analog : PROCESS(LRCKInt) VARIABLE LchData : INTEGER; VARIABLE RchData : INTEGER; BEGIN IF falling_edge(LRCKInt) THEN FOR I IN 38 DOWNTO 1 LOOP LchData_reg(i) <= LchData_reg(i-1); RchData_reg(i) <= RchData_reg(i-1); END LOOP; IF (ZCAL = '1' AND CAL_zd = '1') OR CAL_zd = '0' THEN -- analog input pin voltages are measured LchData := INTEGER((AINL - AINLNeg) / 10.0 * 8388607.0);--16#7FFFFF# RchData := INTEGER((AINR - AINRNeg) / 10.0 * 8388607.0);--16#7FFFFF# ELSE LchData := INTEGER((VCOML) / 2.75 * 8388607.0); RchData := INTEGER((VCOMR) / 2.75 * 8388607.0); END IF; LchData_reg(0) <= int_to_slv(LchData,24); RchData_reg(0) <= int_to_slv(RchData,24); END IF; END PROCESS Analog; ---------------------------------------------------------------------------- -- Main Behavior Process ---------------------------------------------------------------------------- Behavior : PROCESS (LRCKInt, SCLKInt, MCLK, RSTNeg, FSYNCInt) -- Timing Check Variables VARIABLE Tviol_LRCK_SCLK : X01 := '0'; VARIABLE TD_LRCK_SCLK : VitalTimingDataType; VARIABLE Tviol_LRCKM_SCLKM : X01 := '0'; VARIABLE TD_LRCKM_SCLKM : VitalTimingDataType; VARIABLE Tviol_FSYNC_SCLK : X01 := '0'; VARIABLE TD_FSYNC_SCLK : VitalTimingDataType; VARIABLE Tviol_FSYNCM_SCLKM : X01 := '0'; VARIABLE TD_FSYNCM_SCLKM : VitalTimingDataType; VARIABLE Tviol_LRCK_FSYNC : X01 := '0'; VARIABLE TD_LRCK_FSYNC : VitalTimingDataType; VARIABLE Tviol_CAL_RSTNeg : X01 := '0'; VARIABLE TD_CAL_RSTNeg : VitalTimingDataType; VARIABLE Tviol_CALL_RSTNeg : X01 := '0'; VARIABLE TD_CALL_RSTNeg : VitalTimingDataType; VARIABLE Tviol_CALH_RSTNeg : X01 := '0'; VARIABLE TD_CALH_RSTNeg : VitalTimingDataType; VARIABLE Pviol_MCLK : X01 := '0'; VARIABLE PD_MCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_SCLK : X01 := '0'; VARIABLE PD_SCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_FSYNC : X01 := '0'; VARIABLE PD_FSYNC : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_RSTNeg : X01 := '0'; VARIABLE PD_RSTNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE LchData : BOOLEAN := false; VARIABLE RchData : BOOLEAN := false; VARIABLE cnt : INTEGER := 0; VARIABLE Clock_cnt : INTEGER := 0; VARIABLE cnt_RTV : INTEGER := 0; VARIABLE calibration_cycle : TIME; VARIABLE RSTNeg_int : std_logic := '1'; VARIABLE Violation : X01 := '0'; BEGIN -------------------------------------------------------------------- -- Timing Check Section -------------------------------------------------------------------- IF (TimingChecksOn) THEN -- Slave Mode: SCLK falling to LRCK Edge tSLR VitalSetupHoldCheck ( TestSignal => LRCKInt, TestSignalName => "LRCK", RefSignal => SCLKInt, RefSignalName => "SCLK", SetupHigh => tsetup_LRCK_SCLK, SetupLow => tsetup_LRCK_SCLK, CheckEnabled => SMODE1 = '0' AND RSTNeg = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_LRCK_SCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LRCK_SCLK ); -- Master Mode: SCLK falling to LRCK Edge tSLR VitalSetupHoldCheck ( TestSignal => LRCKInt, TestSignalName => "LRCK", RefSignal => SCLKInt, RefSignalName => "SCLK", SetupHigh => tsetup_LRCK_SCLK_SMODE1_EQ_1_noedge_negedge, SetupLow => tsetup_LRCK_SCLK_SMODE1_EQ_1_noedge_negedge, CheckEnabled => SMODE1 = '1' AND RSTNeg = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_LRCKM_SCLKM, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LRCKM_SCLKM ); -- Slave Mode: SCLK falling to FSYNC Edge tSF VitalSetupHoldCheck ( TestSignal => FSYNCInt, TestSignalName => "FSYNC", RefSignal => SCLKInt, RefSignalName => "SCLK", HoldHigh => thold_FSYNC_SCLK, HoldLow => thold_FSYNC_SCLK, CheckEnabled => SMODE1 = '0' AND RSTNeg = '1' AND SMODE2 = '0', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_FSYNC_SCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_FSYNC_SCLK ); -- Master Mode: SCLK falling to FSYNC Edge tSF VitalSetupHoldCheck ( TestSignal => FSYNCInt, TestSignalName => "FSYNC", RefSignal => SCLKInt, RefSignalName => "SCLK", HoldHigh => thold_FSYNC_SCLK_SMODE1_EQ_1_noedge_negedge, HoldLow => thold_FSYNC_SCLK_SMODE1_EQ_1_noedge_negedge, CheckEnabled => SMODE1 = '1' AND RSTNeg = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_FSYNCM_SCLKM, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_FSYNCM_SCLKM ); -- Master Mode: LRCK Edge to FSYNC rising tLRF VitalSetupHoldCheck ( TestSignal => LRCKInt, TestSignalName => "LRCK", RefSignal => FSYNCInt, RefSignalName => "FSYNC", SetupHigh => 2*PeriodSCLK, SetupLow => 2*PeriodSCLK, CheckEnabled => SMODE1 = '1' AND RSTNeg = '1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_LRCK_FSYNC, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LRCK_FSYNC ); -- RSTNeg falling to CAL rising tRCR VitalSetupHoldCheck ( TestSignal => CAL_zd, TestSignalName => "CAL", RefSignal => RSTNeg, RefSignalName => "RSTNeg", HoldLow => thold_CAL_RSTNeg, CheckEnabled => true, RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_CAL_RSTNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CAL_RSTNeg ); -- RSTNeg rising to CAL falling tRCF; DFS = '0' VitalSetupHoldCheck ( TestSignal => CAL_zd, TestSignalName => "CAL", RefSignal => RSTNeg, RefSignalName => "RSTNeg", HoldHigh => 8704*2*PeriodLRCK, CheckEnabled => DFS = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CALL_RSTNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CALL_RSTNeg ); -- RSTNeg rising to CAL falling tRCF; DFS = '1' VitalSetupHoldCheck ( TestSignal => CAL_zd, TestSignalName => "CAL", RefSignal => RSTNeg, RefSignalName => "RSTNeg", HoldHigh => 17408*2*PeriodLRCK, CheckEnabled => DFS = '1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CALH_RSTNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CALH_RSTNeg ); -- Master Clock Frequency VitalPeriodPulseCheck ( TestSignal => MCLK, TestSignalName => "MCLK", Period => tperiod_MCLK, PulseWidthLow => tpw_MCLK_negedge, PulseWidthHigh => tpw_MCLK_posedge, PeriodData => PD_MCLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_MCLK, HeaderMsg => InstancePath & PartID, CheckEnabled => true ); -- Slave mode:SCLK Clock Frequency VitalPeriodPulseCheck ( TestSignal => SCLKInt, TestSignalName => "SCLK", Period => tperiod_SCLK, PulseWidthLow => tpw_SCLK_negedge, PulseWidthHigh => tpw_SCLK_posedge, PeriodData => PD_SCLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_SCLK, HeaderMsg => InstancePath & PartID, CheckEnabled => SMODE1 = '0' AND RSTNeg = '1' ); -- MASTER mode:FSYNC period VitalPeriodPulseCheck ( TestSignal => FSYNCInt, TestSignalName => "FSYNC", Period => PeriodLRCK, PeriodData => PD_FSYNC, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_FSYNC, HeaderMsg => InstancePath & PartID, CheckEnabled => SMODE1 = '1' AND RSTNeg = '1' ); -- RSTNeg Pulse width VitalPeriodPulseCheck ( TestSignal => RSTNeg, TestSignalName => "RSTNeg", PulseWidthLow => tpw_RSTNeg_negedge, PeriodData => PD_RSTNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RSTNeg, HeaderMsg => InstancePath & PartID, CheckEnabled => true ); Violation := Tviol_LRCK_SCLK OR Tviol_LRCKM_SCLKM OR Tviol_FSYNC_SCLK OR Tviol_FSYNCM_SCLKM OR Tviol_LRCK_FSYNC OR Tviol_CAL_RSTNeg OR Tviol_CALL_RSTNeg OR Tviol_CALH_RSTNeg OR Pviol_MCLK OR Pviol_SCLK OR Pviol_FSYNC OR Pviol_RSTNeg; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY Warning; END IF; ---------------------------------------------------------------------------- -- Functional Section ---------------------------------------------------------------------------- IF rising_edge(LRCKInt) THEN IF SMODE2 = '1' THEN -- I2S Master Mode RchData := true; LchData := false; ELSE LchData := true; RchData := false; END IF; cnt := 24; Clock_cnt := 0; IF RSTNeg = '1' AND cnt_RTV < 18000 THEN cnt_RTV := cnt_RTV + 1; END IF; ELSIF falling_edge(LRCKInt) THEN IF SMODE2 = '1' THEN --I2S Master Mode LchData := true; RchData := false; ELSE RchData := true; LchData := false; END IF; cnt := 24; Clock_cnt := 0; END IF; --MASTER Mode IF SMODE1 = '1' AND RSTNeg = '1' THEN IF falling_edge(SCLKInt) AND FSYNCInt = '1' THEN IF LchData = true AND cnt /= 0 THEN SDATA_zd <= LchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF RchData = true AND cnt /= 0 THEN SDATA_zd <= RchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF cnt = 0 THEN SDATA_zd <= '0'; END IF; END IF; IF (cnt_RTV = 8960 AND DFS= '0') OR (cnt_RTV = 17920 AND DFS = '1') THEN RSTNeg_int := '1'; END IF; ELSIF SMODE1 = '0' AND RSTNeg = '1' THEN -- SLAVE Mode IF SMODE2 = '0' THEN -- Slave Mode IF falling_edge(SCLKInt) AND FSYNCInt = '1' THEN IF LchData = true AND cnt /= 0 THEN SDATA_zd <= LchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF RchData = true AND cnt /= 0 THEN SDATA_zd <= RchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF cnt = 0 THEN SDATA_zd <= '0'; END IF; END IF; ELSE -- I2S Slave Mode, FSYNC don't care IF falling_edge(SCLKInt) THEN Clock_cnt := Clock_cnt + 1; IF Clock_cnt /= 1 THEN IF LchData = true AND cnt /= 0 THEN SDATA_zd <= LchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF RchData = true AND cnt /= 0 THEN SDATA_zd <= RchData_reg(38)(cnt-1); cnt := cnt - 1; ELSIF cnt = 0 THEN SDATA_zd <= '0'; END IF; ELSE SDATA_zd <= '0'; END IF; END IF; END IF; IF (cnt_RTV = 8961) THEN RSTNeg_int := '1'; END IF; ELSIF RSTNeg = '0' THEN SDATA_zd <= '0'; cnt_RTV := 0; RSTNeg_int := '0'; END IF; IF RSTNeg_int = '0' THEN SDATA_zd <= '0'; END IF; -- CALIBRATION CYCLE IF DFS = '0' THEN calibration_cycle := 8704 * 2 * PeriodLRCK; ELSE calibration_cycle := 17408 * 2 * PeriodLRCK; END IF; IF rising_edge(RSTNeg) THEN CAL_zd <= '1', '0' AFTER calibration_cycle; END IF; END PROCESS Behavior; ----------------------------------------------------------------------- -- Path Delay Section ----------------------------------------------------------------------- SDATA_OUT: PROCESS(SDATA_zd) VARIABLE SDATA_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01( OutSignal => SDATA, OutSignalName => "SDATA", OutTemp => SDATA_zd, Mode => VitalTransport, GlitchData => SDATA_GlitchData, Paths => ( 0 => (InputChangeTime => LRCK'LAST_EVENT, PathDelay => tpd_LRCK_SDATA, PathCondition => SMODE1 = '0' AND RSTNeg = '1'), 1 => (InputChangeTime => SCLK'LAST_EVENT, PathDelay => tpd_SCLK_SDATA, PathCondition => RSTNeg = '1') ) ); END PROCESS SDATA_OUT; END BLOCK; END vhdl_behavioral;