------------------------------------------------------------------------------- -- File Name: ad7304.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 Mar 28 Initial release -- ------------------------------------------------------------------------------- -- IMPORTANT -- This model must be compiled without VITAL compliance checking ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: CONVERTER_VHDL -- Technology: CMOS -- Part: AD7304 -- Description: 3V/5V, Rail to Rail, Quad, 8-Bit DAC ------------------------------------------------------------------------------- -- NOTE -- Hardware Shutdown SHDN mode is not implemented -- because it is voltage dependent. -- It is adopted for Output voltage in shutdown mode to be 0 V because it is -- pooled down to ground through resistor of 120 ohms resistance. ------------------------------------------------------------------------------- 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 ad7304 IS GENERIC ( -- tipd delays: interconnect path delays tipd_CSNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CLK : VitalDelayType01 := VitalZeroDelay01; tipd_SDI : VitalDelayType01 := VitalZeroDelay01; tipd_LDACNeg : VitalDelayType01 := VitalZeroDelay01; tipd_CLRNeg : VitalDelayType01 := VitalZeroDelay01; -- tsetup values: setup times tsetup_CSNeg_CLK : VitalDelayType := UnitDelay; tsetup_SDI_CLK : VitalDelayType := UnitDelay; tsetup_LDACNeg_CLK : VitalDelayType := UnitDelay; -- thold values: hold times thold_CSNeg_CLK : VitalDelayType := UnitDelay; thold_SDI_CLK : VitalDelayType := UnitDelay; thold_LDACNeg_CLK : VitalDelayType := UnitDelay; -- tpw values: pulse widths tpw_CLK_posedge : VitalDelayType := UnitDelay; tpw_CLK_negedge : VitalDelayType := UnitDelay; tpw_CLRNeg_negedge : VitalDelayType := UnitDelay; tpw_LDACNeg_negedge : VitalDelayType := UnitDelay; -- analog generics: values of Vref inputs In Volts Vdd : real; Vss : 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 ( VrefA : IN real := 0.0; VrefB : IN real := 0.0; VrefC : IN real := 0.0; VrefD : IN real := 0.0; VOUTA : OUT real := 0.0; VOUTB : OUT real := 0.0; VOUTC : OUT real := 0.0; VOUTD : OUT real := 0.0; CLK : IN std_ulogic := 'U'; CSNeg : IN std_ulogic := 'U'; SDI : IN std_ulogic := 'U'; LDACNeg : IN std_ulogic := 'U'; CLRNeg : IN std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of ad7304 : ENTITY IS TRUE; END ad7304; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of ad7304 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "ad7304"; CONSTANT resolution : INTEGER := 8; SUBTYPE dacval_type IS NATURAL RANGE 0 TO (2**resolution-1); SUBTYPE stdl8 IS STD_LOGIC_VECTOR (resolution-1 DOWNTO 0); SIGNAL CLK_ipd : std_ulogic := 'U'; SIGNAL CSNeg_ipd : std_ulogic := 'U'; SIGNAL SDI_ipd : std_ulogic := 'U'; SIGNAL LDACNeg_ipd : std_ulogic := 'U'; SIGNAL CLRNeg_ipd : std_ulogic := 'U'; SHARED VARIABLE PowerDown : BOOLEAN := true; -- True if power down is on SHARED VARIABLE PowerDownA : BOOLEAN := false; SHARED VARIABLE PowerDownB : BOOLEAN := false; SHARED VARIABLE PowerDownC : BOOLEAN := false; SHARED VARIABLE PowerDownD : BOOLEAN := false; BEGIN --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay (CLK_ipd, CLK, tipd_CLK); w_2 : VitalWireDelay (CSNeg_ipd, CSNeg, tipd_CSNeg); w_3 : VitalWireDelay (SDI_ipd, SDI, tipd_SDI); w_4 : VitalWireDelay (LDACNeg_ipd, LDACNeg, tipd_LDACNeg); w_5 : VitalWireDelay (CLRNeg_ipd, CLRNeg, tipd_CLRNeg); END BLOCK; Behavior : BLOCK PORT ( CLK : IN std_ulogic; CSNeg : IN std_ulogic; SDI : IN std_ulogic; LDACNeg : IN std_ulogic; CLRNeg : IN std_ulogic); PORT MAP ( CLK => CLK_ipd, CSNeg => CSNeg_ipd, SDI => SDI_ipd, LDACNeg => LDACNeg_ipd, CLRNeg => CLRNeg_ipd); CONSTANT tsettle : time := 2 us; CONSTANT tsdr : time := 2 us; -- recovery from shutdown CONSTANT tsdn : time := 15 us; -- time to shut down -- State machine state type TYPE state_type IS (DEFAULT, SERIAL); -- State machine current state SIGNAL current_state : state_type; -- Registers SIGNAL inregA : stdl8 := (OTHERS => '0'); SIGNAL inregB : stdl8 := (OTHERS => '0'); SIGNAL inregC : stdl8 := (OTHERS => '0'); SIGNAL inregD : stdl8 := (OTHERS => '0'); SIGNAL decregA : stdl8 := (OTHERS => '0'); SIGNAL decregB : stdl8 := (OTHERS => '0'); SIGNAL decregC : stdl8 := (OTHERS => '0'); SIGNAL decregD : stdl8 := (OTHERS => '0'); SIGNAL shift_reg : STD_LOGIC_VECTOR(11 DOWNTO 0) := (OTHERS => '0'); -- alias ALIAS SAC : STD_LOGIC IS shift_reg(11); ALIAS SDC : STD_LOGIC IS shift_reg(10); ALIAS Address : STD_LOGIC_VECTOR(1 DOWNTO 0) IS shift_reg(9 DOWNTO 8); ALIAS Data : stdl8 IS shift_reg(7 DOWNTO 0); -- Internal signals SIGNAL VOUTA_zd : real := 0.0; SIGNAL VOUTB_zd : real := 0.0; SIGNAL VOUTC_zd : real := 0.0; SIGNAL VOUTD_zd : real := 0.0; SIGNAL VrefA_int : real; -- Internal VrefA voltage SIGNAL VrefB_int : real; SIGNAL VrefC_int : real; SIGNAL VrefD_int : real; -- model signals SIGNAL update : BOOLEAN := false; SIGNAL update_out : BOOLEAN := true; SIGNAL update_outA : BOOLEAN := false; SIGNAL update_outB : BOOLEAN := false; SIGNAL update_outC : BOOLEAN := false; SIGNAL update_outD : BOOLEAN := false; -- signals for upadating output SIGNAL settleA : STD_LOGIC := '0'; SIGNAL settleB : STD_LOGIC := '0'; SIGNAL settleC : STD_LOGIC := '0'; SIGNAL settleD : STD_LOGIC := '0'; -- Increment values for output SHARED VARIABLE StepA : real := 0.0; SHARED VARIABLE StepB : real := 0.0; SHARED VARIABLE StepC : real := 0.0; SHARED VARIABLE StepD : real := 0.0; --End values on outputs SHARED VARIABLE EndValA : real := 0.0; SHARED VARIABLE EndValB : real := 0.0; SHARED VARIABLE EndValC : real := 0.0; SHARED VARIABLE EndValD : real := 0.0; -- Pull up signals SIGNAL CLK_nwv : X01; SIGNAL CSNeg_nwv : X01; SIGNAL SDI_nwv : X01; SIGNAL LDACNeg_nwv : X01; SIGNAL CLRNeg_nwv : X01; -- purpose: Calculate output voltage from 8 bit input PROCEDURE DAConvert ( in_reg : IN stdl8; vref_in : IN real; out_v : OUT real) IS BEGIN -- PROCEDURE DAConvert out_v := vref_in * (real(to_nat(in_reg)) / real(2**resolution)); END PROCEDURE DAConvert; BEGIN CLK_nwv <= to_X01(CLK); CSNeg_nwv <= to_X01(CSNeg); SDI_nwv <= to_X01(SDI); LDACNeg_nwv <= to_X01(LDACNeg); CLRNeg_nwv <= to_X01(CLRNeg); ---------------------------------------------------------------------- -- Behavior Process ---------------------------------------------------------------------- -- purpose: Determine current state -- type : combinational -- inputs : CSNeg, CLRNeg state_decode: PROCESS (CSNeg_nwv, CLRNeg_nwv) BEGIN -- PROCESS state_decode IF CLRNeg_nwv='1' THEN IF falling_edge(CSNeg_nwv) THEN current_state <= SERIAL; ELSE current_state <= DEFAULT; END IF; ELSE current_state <= DEFAULT; END IF; END PROCESS state_decode; -- purpose: Control of referent voltages -- type : combinational -- inputs : VrefA, VrefB, VrefC, VrefD Vref_contorl: PROCESS (VrefA, VrefB, VrefC, VrefD) VARIABLE MaxV : real := Vdd; VARIABLE MinV : real := Vss; BEGIN -- PROCESS Vref_contorl IF NOT (VrefA <= MaxV AND VrefA >= MinV) THEN ASSERT false REPORT LF & InstancePath & partID & ": simulation may be"& LF&"inaccurate due to VrefA range exceeding violations" SEVERITY WARNING; -- If reference voltage is out of range -- set it to first closest valid value. IF VrefA > MaxV THEN VrefA_int <= Vdd; ELSE VrefA_int <= Vss; END IF; ELSE VrefA_int <= VrefA; END IF; IF NOT (VrefB <= MaxV AND VrefB >= MinV) THEN ASSERT false REPORT LF & InstancePath & partID & ": simulation may be"& LF&"inaccurate due to VrefB range exceeding violations" SEVERITY WARNING; IF VrefB > MaxV THEN VrefB_int <= Vdd; ELSE VrefB_int <= Vss; END IF; ELSE VrefB_int <= VrefB; END IF; IF NOT (VrefC <= MaxV AND VrefC >= MinV) THEN ASSERT false REPORT LF & InstancePath & partID & ": simulation may be"& LF&"inaccurate due to VrefC range exceeding violations" SEVERITY WARNING; -- If reference voltage is out of range -- set it to first closest valid value. IF VrefC > MaxV THEN VrefC_int <= Vdd; ELSE VrefC_int <= Vss; END IF; ELSE VrefC_int <= VrefC; END IF; IF NOT (VrefD <= MaxV AND VrefD >= MinV) THEN ASSERT false REPORT LF & InstancePath & partID & ": simulation may be"& LF&"inaccurate due to VrefD range exceeding violations" SEVERITY WARNING; -- If reference voltage is out of range -- set it to first closest valid value. IF VrefD > MaxV THEN VrefD_int <= Vdd; ELSE VrefD_int <= Vss; END IF; ELSE VrefD_int <= VrefD; END IF; END PROCESS Vref_contorl; -- purpose: check for shut down mode -- type : combinational -- inputs : update -- outputs: update_intreg: PROCESS (update) IS BEGIN -- PROCESS update_intreg IF update THEN PowerDown := false; IF SAC='0' THEN PowerDown := true; END IF; IF SDC='0' THEN CASE to_nat(Address) IS WHEN 0 => PowerDownA := true; WHEN 1 => PowerDownB := true; WHEN 2 => PowerDownC := true; WHEN 3 => PowerDownD := true; WHEN OTHERS => NULL ; END CASE; ELSE CASE to_nat(Address) IS WHEN 0 => PowerDownA := false; WHEN 1 => PowerDownB := false; WHEN 2 => PowerDownC := false; WHEN 3 => PowerDownD := false; WHEN OTHERS => NULL ; END CASE; END IF; END IF; update_out <= NOT update_out; END PROCESS update_intreg; -- purpose: update DAC registers -- type : combinational -- inputs : CLRNeg, LDACNeg, update, PowerDownD, PowerDownC, -- PowerDownB, PowerDownA, PowerDown -- outputs: decregx hdw_cnt: PROCESS (CLRNeg_nwv, LDACNeg_nwv, update_out) IS BEGIN -- PROCESS hdw_cnt IF (LDACNeg_nwv='0' AND CLRNeg_nwv='1') THEN IF NOT (PowerDown OR (PowerDownA OR PowerDownB) OR (PowerDownC OR PowerDownD)) THEN decregA <= inregA; decregB <= inregB; decregC <= inregC; decregD <= inregD; END IF; END IF; IF PowerDown THEN decregA <= (OTHERS => '0'); decregB <= (OTHERS => '0'); decregC <= (OTHERS => '0'); decregD <= (OTHERS => '0'); ELSE IF LDACNeg_nwv='0' THEN decregA <= inregA; decregB <= inregB; decregC <= inregC; decregD <= inregD; END IF; IF PowerDownA THEN decregA <= (OTHERS => '0'); END IF; IF PowerDownB THEN decregB <= (OTHERS => '0'); END IF; IF PowerDownC THEN decregC <= (OTHERS => '0'); END IF; IF PowerDownD THEN decregD <= (OTHERS => '0'); END IF; END if; IF CLRNeg_nwv='0' THEN decregA <= (OTHERS => '0'); decregB <= (OTHERS => '0'); decregC <= (OTHERS => '0'); decregD <= (OTHERS => '0'); END IF; END PROCESS hdw_cnt; digital : PROCESS (CLK_nwv, CSNeg_nwv, LDACNeg_nwv, CLRNeg_nwv) -- Timing Check Variables VARIABLE Tviol_CSNeg_CLK : X01 := '0'; VARIABLE TD_CSNeg_CLK : VitalTimingDataType; VARIABLE Tviol_SDI_CLK : X01 := '0'; VARIABLE TD_SDI_CLK : VitalTimingDataType; VARIABLE Tviol_LDACNeg_CLK : X01 := '0'; VARIABLE TD_LDACNeg_CLK : VitalTimingDataType; VARIABLE PD_CLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CLK : X01 := '0'; VARIABLE PD_CSNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CSNeg : X01 := '0'; VARIABLE PD_LDACNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_LDACNeg : X01 := '0'; VARIABLE PD_CLRNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_CLRNeg : X01 := '0'; VARIABLE Violation : X01 := '0'; -- purpose: Shift one data in shift reg in lsb position PROCEDURE shiftData ( din : IN STD_LOGIC) IS VARIABLE tmp : STD_LOGIC_VECTOR(11 DOWNTO 0); BEGIN -- PROCEDURE shiftData tmp := shift_reg; shift_reg(11 DOWNTO 1) <= tmp(10 DOWNTO 0); shift_reg(0) <= din; END PROCEDURE shiftData; BEGIN ------------------------------------------------------------------- -- Timing Check Section ------------------------------------------------------------------- IF (TimingChecksOn) THEN VitalSetupHoldCheck ( TestSignal => CSNeg, TestSignalName => "CSNeg", RefSignal => CLK, RefSignalName => "CLK", SetupLow => tsetup_CSNeg_CLK, HoldLow => thold_CSNeg_CLK, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_CSNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_CSNeg_CLK ); VitalSetupHoldCheck ( TestSignal => SDI, TestSignalName => "SDI", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_SDI_CLK, SetupLow => tsetup_SDI_CLK, HoldHigh => thold_SDI_CLK, HoldLow => thold_SDI_CLK, CheckEnabled => CSNeg = '0', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_SDI_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_SDI_CLK ); VitalSetupHoldCheck ( TestSignal => LDACNeg, TestSignalName => "LDACNeg", RefSignal => CLK, RefSignalName => "CLK", SetupHigh => tsetup_LDACNeg_CLK, HoldHigh => thold_LDACNeg_CLK, CheckEnabled => true, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_LDACNeg_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_LDACNeg_CLK ); VitalPeriodPulseCheck ( TestSignal => CLK, TestSignalName => "CLK", PulseWidthHigh => tpw_CLK_posedge, PulseWidthLow => tpw_CLK_negedge, HeaderMsg => InstancePath & partID, CheckEnabled => current_state = SERIAL, PeriodData => PD_CLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CLK ); VitalPeriodPulseCheck ( TestSignal => CLRNeg, TestSignalName => "CLRNeg", PulseWidthLow => tpw_CLRNeg_negedge, HeaderMsg => InstancePath & partID, CheckEnabled => TRUE, PeriodData => PD_CLRNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_CLRNeg ); VitalPeriodPulseCheck ( TestSignal => LDACNeg, TestSignalName => "LDACNeg", PulseWidthLow => tpw_LDACNeg_negedge, HeaderMsg => InstancePath & partID, CheckEnabled => TRUE, PeriodData => PD_LDACNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_LDACNeg ); Violation := Tviol_CSNeg_CLK OR Tviol_SDI_CLK OR Tviol_LDACNeg_CLK OR Pviol_CLK OR Pviol_CLRNeg OR Pviol_LDACNeg; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY Warning; END IF; ------------------------------------------------------------------- -- Functionality Section ------------------------------------------------------------------- IF rising_edge(CLK_nwv) AND current_state = SERIAL THEN shiftData(SDI_nwv); END IF; IF rising_edge(CSNeg_nwv) AND current_state = SERIAL THEN CASE to_nat(Address) IS WHEN 0 => inregA <= Data; WHEN 1 => inregB <= Data; WHEN 2 => inregC <= Data; WHEN 3 => inregD <= Data; WHEN OTHERS => NULL; END CASE; update <= true, false AFTER 1 ns; END IF; IF CLRNeg_nwv='0' THEN inregA <= (OTHERS => '0'); inregB <= (OTHERS => '0'); inregC <= (OTHERS => '0'); inregD <= (OTHERS => '0'); shift_reg <= (OTHERS => '0'); END IF; END PROCESS digital; -- purpose: Convert to analog value -- type : combinational -- inputs : decregA -- outputs: VOUTA DACA : PROCESS (decregA,VrefA_int) VARIABLE timeout_A : time := tsettle; VARIABLE start_value : real := 0.0; -- previous shut down VARIABLE prev_SD : BOOLEAN := true; BEGIN -- PROCESS DACA start_value := VOUTA_zd; DAConvert(decregA,VrefA_int,EndValA); -- this part stores previous mode of operation, shut down or -- normal,and calculate time needed for settling of output. IF prev_SD THEN IF PowerDown OR PowerDownA THEN prev_SD := true; ELSE prev_SD := false; timeout_A := tsdr; END IF; ELSE IF PowerDown OR PowerDownA THEN prev_SD := true; timeout_A := tsdn; ELSE timeout_A := tsettle; END IF; END IF; StepA := (EndValA - start_value) / real((timeout_A)/100 ns); settleA <= '1', '0' AFTER timeout_A; END PROCESS DACA; out_A: PROCESS (update_outA, settleA) IS BEGIN -- PROCESS out_A IF settleA = '0' THEN VOUTA_zd <= EndValA; ELSE update_outA <= NOT update_outA AFTER 100 ns; IF update_outA'event THEN VOUTA_zd <= VOUTA_zd + StepA; END IF; END IF; END PROCESS out_A; DACB : PROCESS (decregB,VrefB_int) VARIABLE timeout_B : time := tsettle; VARIABLE start_value : real := 0.0; -- previous shut down VARIABLE prev_SD : BOOLEAN := true; BEGIN -- PROCESS DACB start_value := VOUTB_zd; DAConvert(decregB,VrefB_int,EndValB); -- this part stores previous mode of operation, shut down or -- normal,and calculate time needed for settling of output. IF prev_SD THEN IF PowerDown OR PowerDownB THEN prev_SD := true; ELSE prev_SD := false; timeout_B := tsdr; END IF; ELSE IF PowerDown OR PowerDownB THEN prev_SD := true; timeout_B := tsdn; ELSE timeout_B := tsettle; END IF; END IF; StepB := (EndValB - start_value) / real((timeout_B)/100 ns); settleB <= '1', '0' AFTER timeout_B; END PROCESS DACB; out_B: PROCESS (update_outB, settleB) IS BEGIN -- PROCESS out_B IF settleB = '0' THEN VOUTB_zd <= EndValB; ELSE update_outB <= (NOT update_outB) AFTER 100 ns; IF update_outB'event THEN VOUTB_zd <= VOUTB_zd + StepB; END IF; END IF; END PROCESS out_B; DACC : PROCESS (decregC,VrefC_int) VARIABLE timeout_C : time := tsettle; VARIABLE start_value : real := 0.0; -- previous shut down VARIABLE prev_SD : BOOLEAN := true; BEGIN -- PROCESS DACC start_value := VOUTC_zd; DAConvert(decregC,VrefC_int,EndValC); -- this part stores previous mode of operation, shut down or -- normal,and calculate time needed for settling of output. IF prev_SD THEN IF PowerDown OR PowerDownC THEN prev_SD := true; ELSE prev_SD := false; timeout_C := tsdr; END IF; ELSE IF PowerDown OR PowerDownC THEN prev_SD := true; timeout_C := tsdn; ELSE timeout_C := tsettle; END IF; END IF; StepC := (EndValC - start_value) / real((timeout_C)/100 ns); settleC <= '1', '0' AFTER timeout_C; END PROCESS DACC; out_C: PROCESS (update_outC, settleC) IS BEGIN -- PROCESS out_C IF settleC = '0' THEN VOUTC_zd <= EndValC; ELSE update_outC <= (NOT update_outC) AFTER 100 ns; IF update_outC'event THEN VOUTC_zd <= VOUTC_zd + StepC; END IF; END IF; END PROCESS out_C; DACD : PROCESS (decregD,VrefD_int) VARIABLE timeout_D : time := tsettle; VARIABLE start_value : real := 0.0; -- previous shut down VARIABLE prev_SD : BOOLEAN := true; BEGIN -- PROCESS DACD start_value := VOUTD_zd; DAConvert(decregD,VrefD_int,EndValD); -- this part stores previous mode of operation, shut down or -- normal,and calculate time needed for settling of output. IF prev_SD THEN IF PowerDown OR PowerDownD THEN prev_SD := true; ELSE prev_SD := false; timeout_D := tsdr; END IF; ELSE IF PowerDown OR PowerDownD THEN prev_SD := true; timeout_D := tsdn; ELSE timeout_D := tsettle; END IF; END IF; StepD := (EndValD - start_value) / real((timeout_D)/100 ns); settleD <= '1', '0' AFTER timeout_D; END PROCESS DACD; out_D: PROCESS (update_outD, settleD) IS BEGIN -- PROCESS out_D IF settleD = '0' THEN VOUTD_zd <= EndValD; ELSE update_outD <= (NOT update_outD) AFTER 100 ns; IF update_outD'event THEN VOUTD_zd <= VOUTD_zd + StepD; END IF; END IF; END PROCESS out_D; VOUTA <= VOUTA_zd; VOUTB <= VOUTB_zd; VOUTC <= VOUTC_zd; VOUTD <= VOUTD_zd; END BLOCK; END vhdl_behavioral;