-------------------------------------------------------------------------------- -- File Name: ak4380.vhd -------------------------------------------------------------------------------- -- Copyright (C) 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.Radmanovic 03 Aug 14 Initial release -- -- This model must be compiled without VITAL compliance checking -- -- At the power-down mode the value 0.0 is assigned to analog outputs -- to represent high impedance -- -------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: CONVERTER_VHDL -- Technology: MIXED -- Part: AK4380 -- Description: 100 dB 24Bit 96kHz 2ch DAC -------------------------------------------------------------------------------- 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 ak4380 IS GENERIC ( -- tipd delays: interconnect path delays tipd_MCLK : VitalDelayType01 := VitalZeroDelay01; tipd_BICK : VitalDelayType01 := VitalZeroDelay01; tipd_SDTI : VitalDelayType01 := VitalZeroDelay01; tipd_LRCK : VitalDelayType01 := VitalZeroDelay01; tipd_PDNNeg : VitalDelayType01 := VitalZeroDelay01; tipd_SP : VitalDelayType01 := VitalZeroDelay01; tipd_CSN : VitalDelayType01 := VitalZeroDelay01; tipd_CCLK : VitalDelayType01 := VitalZeroDelay01; tipd_CDTI : VitalDelayType01 := VitalZeroDelay01; -- tpd delays -- tsetup values: setup times tsetup_SDTI_BICK : VitalDelayType := UnitDelay; tsetup_LRCK_BICK : VitalDelayType := UnitDelay; tsetup_CDTI_CCLK : VitalDelayType := UnitDelay; tsetup_CSN_CCLK : VitalDelayType := UnitDelay; -- thold values: hold times thold_SDTI_BICK : VitalDelayType := UnitDelay; thold_LRCK_BICK : VitalDelayType := UnitDelay; thold_CDTI_CCLK : VitalDelayType := UnitDelay; thold_CSN_CCLK : VitalDelayType := UnitDelay; -- tpw values: pulse widths tpw_CCLK_posedge : VitalDelayType := UnitDelay; tpw_CCLK_negedge : VitalDelayType := UnitDelay; tpw_BICK_posedge : VitalDelayType := UnitDelay; tpw_BICK_negedge : VitalDelayType := UnitDelay; tpw_CSN_posedge : VitalDelayType := UnitDelay; tpw_PDNNeg_negedge : VitalDelayType := UnitDelay; -- tperiod min (calculated as 1/max freq) tperiod_MCLK : VitalDelayType := UnitDelay; tperiod_LRCK : VitalDelayType := UnitDelay; tperiod_CCLK : VitalDelayType := UnitDelay; tperiod_BICKN : VitalDelayType := UnitDelay; tperiod_BICKD : VitalDelayType := UnitDelay; -- analog generics: Vref : real; --value of Vref input In Volts VCOM : real; --Voltage pin Vdd/2 -- 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 ( MCLK : IN std_ulogic := 'U'; BICK : IN std_ulogic := 'U'; SDTI : IN std_ulogic := 'U'; LRCK : IN std_ulogic := 'U'; AOUTR : OUT real := 0.0;-- 0.0 is used to represent Hi-Z AOUTL : OUT real := 0.0;-- 0.0 is used to represent Hi-Z PDNNeg : IN std_ulogic := 'U'; SP : IN std_ulogic := 'U'; CSN : IN std_ulogic := 'U'; CCLK : IN std_ulogic := 'U'; CDTI : IN std_ulogic := 'U'; DZF : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of ak4380 : ENTITY IS TRUE; END ak4380 ; -------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION -------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of ak4380 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "ak4380"; CONSTANT tmaxperiod_MCLK : TIME := 0.5 us;-- 1/min fMCLK CONSTANT tmaxperiod_LRCK : TIME := 125 us;-- 1/min fs SIGNAL MCLK_ipd : std_ulogic := 'U'; SIGNAL BICK_ipd : std_ulogic := 'U'; SIGNAL SDTI_ipd : std_ulogic := 'U'; SIGNAL LRCK_ipd : std_ulogic := 'U'; SIGNAL PDNNeg_ipd : std_ulogic := 'U'; SIGNAL SP_ipd : std_ulogic := 'U'; SIGNAL CSN_ipd : std_ulogic := 'U'; --SMUTE in parallel mode SIGNAL CCLK_ipd : std_ulogic := 'U'; --DFS in parallel mode SIGNAL CDTI_ipd : std_ulogic := 'U'; --DIF0 in parallel mode BEGIN ---------------------------------------------------------------------------- -- Wire Delays ---------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (MCLK_ipd, MCLK, tipd_MCLK); w_2 : VitalWireDelay (BICK_ipd, BICK, tipd_BICK); w_3 : VitalWireDelay (SDTI_ipd, SDTI, tipd_SDTI); w_4 : VitalWireDelay (LRCK_ipd, LRCK, tipd_LRCK); w_7 : VitalWireDelay (PDNNeg_ipd, PDNNeg, tipd_PDNNeg); w_8 : VitalWireDelay (SP_ipd, SP, tipd_SP); w_9 : VitalWireDelay (CSN_ipd, CSN, tipd_CSN); w_10 : VitalWireDelay (CCLK_ipd, CCLK, tipd_CCLK); w_11 : VitalWireDelay (CDTI_ipd, CDTI, tipd_CDTI); END BLOCK; Behavior : BLOCK SIGNAL Reset : std_ulogic := '1'; SIGNAL RSTN : std_ulogic := '1'; SIGNAL SMUTE : std_ulogic := '0'; SIGNAL Pwdn : std_ulogic := '1'; SIGNAL DFS : std_ulogic := 'U'; SIGNAL MOff : BOOLEAN := true; SIGNAL LROff : BOOLEAN := true; SIGNAL Powerup : BOOLEAN := true; SIGNAL ControlM : std_ulogic := '0'; SIGNAL ControlLR : std_ulogic := '0'; SIGNAL Period : TIME := 0 ns; SIGNAL AOUTR_zd19 : real := 0.0; SIGNAL AOUTL_zd19 : real := 0.0; BEGIN Clock: PROCESS (MCLK_ipd, LRCK_ipd, ControlM, ControlLR) VARIABLE TmpLRCK : TIME := 0 ns; BEGIN IF rising_edge(ControlM) THEN MOff <= true; END IF; IF rising_edge(MCLK_ipd) THEN MOff <= false; ControlM <= '0', '1' AFTER tmaxperiod_MCLK; END IF; IF rising_edge(ControlLR) THEN LROff <= true; END IF; IF rising_edge(LRCK_ipd) THEN LROff <= false; ControlLR <= '0', '1' AFTER tmaxperiod_LRCK; Period <= NOW - TmpLRCK; TmpLRCK := NOW; END IF; END PROCESS Clock; PwrUp: PROCESS (PDNNeg_ipd, MOff, LROff, Pwdn) BEGIN IF rising_edge(PDNNeg_ipd) OR rising_edge(Pwdn) THEN IF MOff OR LROff THEN --AK4380 is in power down until MCLK and LRCK are input Powerup <= false; ELSE Powerup <= true; END IF; END IF; IF not(Powerup) THEN IF not(MOff) AND not(LROff) THEN Powerup <= true; END IF; END IF; END PROCESS PwrUp; ---------------------------------------------------------------------------- -- Behavior Process ---------------------------------------------------------------------------- Behavior: PROCESS (BICK_ipd, SDTI_ipd, LRCK_ipd, CSN_ipd, CCLK_ipd, CDTI_ipd, SP_ipd, PDNNeg_ipd, Powerup, MOff, LROff, Reset, Smute, Pwdn) -- Timing Check Variables VARIABLE Tviol_SDTI_BICK : X01 := '0'; VARIABLE TD_SDTI_BICK : VitalTimingDataType; VARIABLE Tviol_LRCK_BICK : X01 := '0'; VARIABLE TD_LRCK_BICK : VitalTimingDataType; VARIABLE Tviol_CDTI_CCLK : X01 := '0'; VARIABLE TD_CDTI_CCLK : VitalTimingDataType; VARIABLE Tviol_CSN_CCLK : X01 := '0'; VARIABLE TD_CSN_CCLK : VitalTimingDataType; VARIABLE Pviol_CCLK : X01 := '0'; VARIABLE TD_CCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_BICKN : X01 := '0'; VARIABLE TD_BICKN : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_BICKD : X01 := '0'; VARIABLE TD_BICKD : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CSN : X01 := '0'; VARIABLE TD_CSN : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_PDNNeg : X01 := '0'; VARIABLE TD_PDNNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_LRCK : X01 := '0'; VARIABLE TD_LRCK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_MCLK : X01 := '0'; VARIABLE TD_MCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; SUBTYPE controlreg_type IS std_logic_vector(7 DOWNTO 0); VARIABLE inreg : std_logic_vector(15 DOWNTO 0); VARIABLE control1 : controlreg_type := "00001111"; VARIABLE control2 : controlreg_type := "00000010"; VARIABLE AOUTL_zd : REAL := 0.0; VARIABLE AOUTR_zd : REAL := 0.0; VARIABLE AOUTR_zd1 : REAL := 0.0; VARIABLE AOUTR_zd2 : REAL := 0.0; VARIABLE AOUTR_zd3 : REAL := 0.0; VARIABLE AOUTR_zd4 : REAL := 0.0; VARIABLE AOUTR_zd5 : REAL := 0.0; VARIABLE AOUTR_zd6 : REAL := 0.0; VARIABLE AOUTR_zd7 : REAL := 0.0; VARIABLE AOUTR_zd8 : REAL := 0.0; VARIABLE AOUTR_zd9 : REAL := 0.0; VARIABLE AOUTR_zd10 : REAL := 0.0; VARIABLE AOUTR_zd11 : REAL := 0.0; VARIABLE AOUTR_zd12 : REAL := 0.0; VARIABLE AOUTR_zd13 : REAL := 0.0; VARIABLE AOUTR_zd14 : REAL := 0.0; VARIABLE AOUTR_zd15 : REAL := 0.0; VARIABLE AOUTR_zd16 : REAL := 0.0; VARIABLE AOUTR_zd17 : REAL := 0.0; VARIABLE AOUTR_zd18 : REAL := 0.0; VARIABLE AOUTL_zd1 : REAL := 0.0; VARIABLE AOUTL_zd2 : REAL := 0.0; VARIABLE AOUTL_zd3 : REAL := 0.0; VARIABLE AOUTL_zd4 : REAL := 0.0; VARIABLE AOUTL_zd5 : REAL := 0.0; VARIABLE AOUTL_zd6 : REAL := 0.0; VARIABLE AOUTL_zd7 : REAL := 0.0; VARIABLE AOUTL_zd8 : REAL := 0.0; VARIABLE AOUTL_zd9 : REAL := 0.0; VARIABLE AOUTL_zd10 : REAL := 0.0; VARIABLE AOUTL_zd11 : REAL := 0.0; VARIABLE AOUTL_zd12 : REAL := 0.0; VARIABLE AOUTL_zd13 : REAL := 0.0; VARIABLE AOUTL_zd14 : REAL := 0.0; VARIABLE AOUTL_zd15 : REAL := 0.0; VARIABLE AOUTL_zd16 : REAL := 0.0; VARIABLE AOUTL_zd17 : REAL := 0.0; VARIABLE AOUTL_zd18 : REAL := 0.0; VARIABLE LchData : std_logic_vector(31 DOWNTO 0) := (others => '0'); VARIABLE RchData : std_logic_vector(31 DOWNTO 0) := (others => '0'); VARIABLE Lchreg0 : std_logic_vector(15 DOWNTO 0) := (others => '0'); VARIABLE Rchreg0 : std_logic_vector(15 DOWNTO 0) := (others => '0'); VARIABLE Lchreg1 : std_logic_vector(19 DOWNTO 0) := (others => '0'); VARIABLE Rchreg1 : std_logic_vector(19 DOWNTO 0) := (others => '0'); VARIABLE Lchreg : std_logic_vector(23 DOWNTO 0) := (others => '0'); VARIABLE Rchreg : std_logic_vector(23 DOWNTO 0) := (others => '0'); VARIABLE TmpL : REAL := 0.0; VARIABLE TmpR : REAL := 0.0; VARIABLE Mode : NATURAL RANGE 0 TO 4 := 3; VARIABLE delaycnt : NATURAL RANGE 0 TO 4; VARIABLE delaycnt1 : NATURAL RANGE 0 TO 3; VARIABLE delaycnt2 : NATURAL RANGE 0 TO 2; VARIABLE smutecnt : NATURAL RANGE 0 TO 1024 := 0; VARIABLE dzfcnt : NATURAL RANGE 0 TO 8192 := 0; VARIABLE ResetOn : BOOLEAN := false; VARIABLE ResetOff : BOOLEAN := false; VARIABLE SmuteOff : BOOLEAN := false; VARIABLE inv : BOOLEAN := false; VARIABLE size : INTEGER; VARIABLE MCLK_nwv : X01; VARIABLE BICK_nwv : X01; VARIABLE SDTI_nwv : X01; VARIABLE LRCK_nwv : X01; VARIABLE CSN_nwv : X01; VARIABLE CCLK_nwv : X01; VARIABLE CDTI_nwv : X01; VARIABLE SP_nwv : X01; VARIABLE PDNNeg_nwv : X01; BEGIN MCLK_nwv := to_X01(MCLK_ipd); BICK_nwv := to_X01(BICK_ipd); SDTI_nwv := to_X01(SDTI_ipd); LRCK_nwv := to_X01(LRCK_ipd); CSN_nwv := to_X01(CSN_ipd); CCLK_nwv := to_X01(CCLK_ipd); CDTI_nwv := to_X01(CDTI_ipd); SP_nwv := to_X01(SP_ipd); PDNNeg_nwv := to_X01(PDNNeg_ipd); ------------------------------------------------------------------------ -- Timing Check Section ------------------------------------------------------------------------ IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => SDTI_ipd, TestSignalName => "SDTI", RefSignal => BICK_ipd, RefSignalName => "BICK", SetupHigh => tsetup_SDTI_BICK, SetupLow => tsetup_SDTI_BICK, HoldHigh => thold_SDTI_BICK, HoldLow => thold_SDTI_BICK, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_SDTI_BICK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_SDTI_BICK ); VitalSetupHoldCheck ( TestSignal => LRCK_ipd, TestSignalName => "LRCK", RefSignal => BICK_ipd, RefSignalName => "BICK", SetupHigh => tsetup_LRCK_BICK, SetupLow => tsetup_LRCK_BICK, HoldHigh => thold_LRCK_BICK, HoldLow => thold_LRCK_BICK, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_LRCK_BICK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LRCK_BICK ); VitalSetupHoldCheck ( TestSignal => CDTI_ipd, TestSignalName => "CDTI", RefSignal => CCLK_ipd, RefSignalName => "CCLK", SetupHigh => tsetup_CDTI_CCLK, SetupLow => tsetup_CDTI_CCLK, HoldHigh => thold_CDTI_CCLK, HoldLow => thold_CDTI_CCLK, CheckEnabled => (SP_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CDTI_CCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CDTI_CCLK ); VitalSetupHoldCheck ( TestSignal => CSN_ipd, TestSignalName => "CSN", RefSignal => CCLK_ipd, RefSignalName => "CCLK", SetupLow => tsetup_CSN_CCLK, HoldLow => thold_CSN_CCLK, CheckEnabled => (SP_nwv = '0'), RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CSN_CCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CSN_CCLK ); VitalPeriodPulseCheck ( TestSignal => CCLK_ipd, TestSignalName => "CCLK", Period => tperiod_CCLK, PulseWidthLow => tpw_CCLK_negedge, PulseWidthHigh => tpw_CCLK_posedge, PeriodData => TD_CCLK, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_CCLK ); VitalPeriodPulseCheck ( TestSignal => BICK_ipd, TestSignalName => "BICK", Period => tperiod_BICKN, PulseWidthLow => tpw_BICK_negedge, PulseWidthHigh => tpw_BICK_posedge, PeriodData => TD_BICKN, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => (DFS = '0'), Violation => Pviol_BICKN ); VitalPeriodPulseCheck ( TestSignal => BICK_ipd, TestSignalName => "BICK", Period => tperiod_BICKD, PulseWidthLow => tpw_BICK_negedge, PulseWidthHigh => tpw_BICK_posedge, PeriodData => TD_BICKD, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => (DFS = '1'), Violation => Pviol_BICKD ); VitalPeriodPulseCheck ( TestSignal => CSN_ipd, TestSignalName => "CSN", PulseWidthHigh => tpw_CSN_posedge, PeriodData => TD_CSN, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => (SP_nwv = '0'), Violation => Pviol_CSN ); VitalPeriodPulseCheck ( TestSignal => PDNNeg, TestSignalName => "PDNNeg", PulseWidthLow => tpw_PDNNeg_negedge, PeriodData => TD_PDNNeg, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_PDNNeg ); VitalPeriodPulseCheck ( TestSignal => LRCK, TestSignalName => "LRCK", Period => tperiod_LRCK, PeriodData => TD_LRCK, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_LRCK ); VitalPeriodPulseCheck ( TestSignal => MCLK, TestSignalName => "MCLK", Period => tperiod_MCLK, PeriodData => TD_MCLK, XOn => XOn, MsgOn => MsgOn, HeaderMsg => InstancePath & PartID, CheckEnabled => TRUE, Violation => Pviol_MCLK ); Violation := Tviol_SDTI_BICK OR Tviol_LRCK_BICK OR Tviol_CDTI_CCLK OR Tviol_CSN_CCLK OR Pviol_CCLK OR Pviol_BICKN OR Pviol_BICKD OR Pviol_CSN OR Pviol_PDNNeg OR Pviol_LRCK OR Pviol_MCLK; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY Warning; END IF; ---------------------------------------------------------------------------- -- Functionality Section ---------------------------------------------------------------------------- --Mode control Interface IF PDNNeg_nwv = '0' THEN control1 := "00001111"; control2 := "00000010"; Mode := 3; Pwdn <= '1'; Reset <= '1'; SMUTE <= '0'; DFS <= '0'; ELSIF SP_nwv = '0' AND not(MOff) THEN --serial control mode IF CSN_nwv = '0' AND rising_edge(CCLK_ipd) THEN --clock in FOR I IN 15 DOWNTO 1 LOOP inreg(i) := inreg(i-1); END LOOP; inreg(0) := CDTI_nwv; ELSIF rising_edge(CSN_ipd) AND CCLK_nwv = '1' THEN IF inreg(15 downto 13) = "011" THEN IF inreg(12 downto 8) = "00000" THEN control1 := inreg(7 downto 0); Mode := to_nat(control1(4 downto 2)); Pwdn <= control1(1); Reset <= control1(0); ELSIF inreg(12 downto 8) = "00001" THEN control2 := inreg(7 downto 0); SMUTE <= control2(0); DFS <= control2(3); ELSE ASSERT false REPORT InstancePath & partID & ": For addresses" & " from 02H to 1FH, data must not be written" SEVERITY Warning; END IF; ELSE ASSERT false REPORT InstancePath & partID & ": Does not support " & " the read command and chip address" SEVERITY Warning; END IF; END IF; END IF; IF SP_nwv = '1' THEN -- parallel control mode IF CSN_nwv = '1' THEN SMUTE <= '1';-- outputs soft-muted ELSE SMUTE <= '0'; END IF; IF CCLK_nwv = '1' THEN DFS <= '1'; --double speed ELSE DFS <= '0'; --normal speed END IF; IF CDTI_nwv = '1' THEN Mode := 3; ELSE Mode := 2; END IF; END IF; IF falling_edge(Reset) AND SP_nwv = '0' THEN DZF <= '1'; ResetOn := true; ResetOff := false; END IF; IF falling_edge(Smute) THEN SmuteOff := true; END IF; --Audio Data Interface IF PDNNeg_nwv = '0' OR Pwdn = '0' OR not(Powerup) THEN --power-down DZF <= '0'; delaycnt := 0; delaycnt1 := 0; dzfcnt := 0; ResetOn := false; ELSIF RSTN = '0' THEN --reset DZF <= '1'; IF rising_edge(Reset) THEN ResetOff := true; END IF; IF ResetOff = true THEN IF rising_edge(LRCK_ipd) THEN delaycnt1 := delaycnt1 + 1; IF delaycnt1 = 3 THEN delaycnt1 := 0; RSTN <= '1'; END IF; END IF; END IF; ELSIF rising_edge(LRCK_ipd) THEN CASE Mode IS WHEN 0 => Rchreg0 := RchData(15 downto 0); TmpR := REAL(to_int(Rchreg0(15 downto 0))); Lchreg0 := LchData(15 downto 0); TmpL := REAL(to_int(Lchreg0(15 downto 0))); size := 15; WHEN 1 => Rchreg1 := RchData(19 downto 0); TmpR := REAL(to_int(Rchreg1(19 downto 0))); Lchreg1 := LchData(19 downto 0); TmpL := REAL(to_int(Lchreg1(19 downto 0))); size := 19; WHEN 2 => Rchreg := RchData(31 downto 8); TmpR := REAL(to_int(Rchreg(23 downto 0))); Lchreg := LchData(31 downto 8); TmpL := REAL(to_int(Lchreg(23 downto 0))); size := 23; WHEN 3 => Rchreg := LchData(30 downto 7); TmpR := REAL(to_int(Rchreg(23 downto 0))); Lchreg := RchData(30 downto 7); TmpL := REAL(to_int(Lchreg(23 downto 0))); size := 23; WHEN 4 => Rchreg := RchData(23 downto 0); TmpR := REAL(to_int(Rchreg(23 downto 0))); Lchreg := LchData(23 downto 0); TmpL := REAL(to_int(Lchreg(23 downto 0))); size := 23; END CASE; TmpR := TmpR * 1.7 * Vref / (5.0 * REAL(2**(size) - 1)); TmpL := TmpL * 1.7 * Vref / (5.0 * REAL(2**(size) - 1)); IF Smute = '1' OR rising_edge(Smute) THEN -- Soft mute IF smutecnt = 1024 THEN TmpR := 0.0; TmpL := 0.0; ELSE --step -0.125dB smutecnt := smutecnt + 1; TmpR := TmpR * (0.9857119 ** smutecnt); TmpL := TmpL * (0.9857119 ** smutecnt); END IF; ELSIF Smute = '0' AND SmuteOff THEN smutecnt := smutecnt - 1; TmpR := TmpR * (0.9857119 ** smutecnt); TmpL := TmpL * (0.9857119 ** smutecnt); IF smutecnt = 0 THEN SmuteOff := false; END IF; END IF; IF ResetOn THEN -- Internal reset delaycnt := delaycnt + 1; IF delaycnt = 4 THEN delaycnt := 0; RSTN <= '0'; ResetOn := false; END IF; END IF; IF TmpR = 0.0 AND TmpL = 0.0 THEN --zero detection IF dzfcnt = 8192 THEN DZF <= '1'; ELSE dzfcnt := dzfcnt + 1; END IF; ELSIF Reset = '1' AND not(ResetOff) THEN dzfcnt := 0; DZF <= '0'; END IF; IF ResetOff THEN delaycnt2 := delaycnt2 + 1; IF delaycnt2 = 2 THEN delaycnt2 := 0; DZF <= '0'; ResetOff := false; dzfcnt := 0; END IF; END IF; AOUTR_zd := VCOM +TmpR; AOUTL_zd := VCOM +TmpL; AOUTR_zd19 <= AOUTR_zd18; AOUTR_zd18 := AOUTR_zd17; AOUTR_zd17 := AOUTR_zd16; AOUTR_zd16 := AOUTR_zd15; AOUTR_zd15 := AOUTR_zd14; AOUTR_zd14 := AOUTR_zd13; AOUTR_zd13 := AOUTR_zd12; AOUTR_zd12 := AOUTR_zd11; AOUTR_zd11 := AOUTR_zd10; AOUTR_zd10 := AOUTR_zd9; AOUTR_zd9 := AOUTR_zd8; AOUTR_zd8 := AOUTR_zd7; AOUTR_zd7 := AOUTR_zd6; AOUTR_zd6 := AOUTR_zd5; AOUTR_zd5 := AOUTR_zd4; AOUTR_zd4 := AOUTR_zd3; AOUTR_zd3 := AOUTR_zd2; AOUTR_zd2 := AOUTR_zd1; AOUTR_zd1 := AOUTR_zd; AOUTL_zd19 <= AOUTL_zd18; AOUTL_zd18 := AOUTL_zd17; AOUTL_zd17 := AOUTL_zd16; AOUTL_zd16 := AOUTL_zd15; AOUTL_zd15 := AOUTL_zd14; AOUTL_zd14 := AOUTL_zd13; AOUTL_zd13 := AOUTL_zd12; AOUTL_zd12 := AOUTL_zd11; AOUTL_zd11 := AOUTL_zd10; AOUTL_zd10 := AOUTL_zd9; AOUTL_zd9 := AOUTL_zd8; AOUTL_zd8 := AOUTL_zd7; AOUTL_zd7 := AOUTL_zd6; AOUTL_zd6 := AOUTL_zd5; AOUTL_zd5 := AOUTL_zd4; AOUTL_zd4 := AOUTL_zd3; AOUTL_zd3 := AOUTL_zd2; AOUTL_zd2 := AOUTL_zd1; AOUTL_zd1 := AOUTL_zd; ELSIF LRCK_nwv = '1' THEN IF rising_edge(BICK_ipd) THEN FOR I IN 31 DOWNTO 1 LOOP -- LRCK=fs, BICK=64fs LchData(i) := LchData(i-1); END LOOP; LchData(0) := SDTI_nwv; END IF; ELSIF LRCK_nwv = '0' THEN IF rising_edge(BICK_ipd) THEN FOR I IN 31 DOWNTO 1 LOOP -- LRCK=fs, BICK=64fs RchData(i) := RchData(i-1); END LOOP; RchData(0) := SDTI_nwv; END IF; END IF; END PROCESS Behavior; AnalogOut : PROCESS(PDNNeg_ipd, Pwdn, Powerup, RSTN, LRCK_ipd) BEGIN IF to_X01(PDNNeg_ipd) = '0' OR Pwdn = '0' OR not(Powerup) THEN AOUTR <= 0.0; ELSIF RSTN = '0' THEN AOUTR <= VCOM; ELSIF rising_edge(LRCK_ipd) THEN AOUTR <= AOUTR_zd19 AFTER 0.1 * Period; END IF; IF to_X01(PDNNeg_ipd) = '0' OR Pwdn = '0' OR not(Powerup) THEN AOUTL <= 0.0; ELSIF RSTN = '0' THEN AOUTL <= VCOM; ELSIF rising_edge(LRCK_ipd) THEN AOUTL <= AOUTL_zd19 AFTER 0.1 * Period; END IF; END PROCESS AnalogOut; END BLOCK; END vhdl_behavioral;