------------------------------------------------------------------------------- -- File Name: max9378.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 Dj.Tanasijevic 05 July 22 Initial release ------------------------------------------------------------------------------- -- PART DESCRIPTION: -- -- Library: ECLPS -- Technology: LVDS -- Part: max9378 -- Description: Anything-to-LVDS Translator -- with Pin-Selectable Divide-by-Four ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- SIMULATION RESOLUTION MUST BE 1 ps ------------------------------------------------------------------------------- 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; ------------------------------------------------------------------------------- -- ENTITY DECLARATION ------------------------------------------------------------------------------- ENTITY max9378 IS GENERIC ( -- tipd delays: interconnect path delays tipd_VIN : VitalDelayType01 := VitalZeroDelay01; tipd_VINNeg : VitalDelayType01 := VitalZeroDelay01; tipd_SEL : VitalDelayType01 := VitalZeroDelay01; tipd_RST : VitalDelayType01 := VitalZeroDelay01; -- tpd delay: propagation from input to output tpd_VIN_VOUT : VitalDelayType01 := UnitDelay01; -- tPLH, tPHL -- tpd delay: clock to divider output popagation delay tpd_VINNeg_VOUT : VitalDelayType01 := UnitDelay01; -- tPCO+tPLH -- tsetup: reset-to-input setup time tsetup_RST_VIN : VitalDelayType := UnitDelay; -- tSET -- tperiod_min - minimum clock period - 1/max freq tperiod_VIN : VitalDelayType := UnitDelay; -- 1/fMAX -- tdevice: RST to differential output delay tdevice_RESET : VitalDelayType := 800 ps; -- tDR -- tdevice: SEL to switched output delay tdevice_SELEC : VitalDelayType := 300 ps; -- tSEL -- 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 ( VIN : IN std_ulogic := 'U'; VINNeg : IN std_ulogic := 'U'; SEL : IN std_ulogic := 'U'; RST : IN std_ulogic := 'U'; VOUT : OUT std_ulogic := 'U'; VOUTNeg : OUT std_ulogic := 'U' ); ATTRIBUTE VITAL_LEVEL0 of max9378 : ENTITY IS TRUE; END max9378; ------------------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ------------------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral of max9378 IS ATTRIBUTE VITAL_LEVEL0 of vhdl_behavioral : ARCHITECTURE IS TRUE; CONSTANT partID : STRING := "max9378"; SIGNAL VIN_ipd : std_ulogic := 'U'; SIGNAL VINNeg_ipd : std_ulogic := 'U'; SIGNAL SEL_ipd : std_ulogic := 'U'; SIGNAL RST_ipd : std_ulogic := 'U'; SIGNAL SEL_in : std_ulogic := '0'; SIGNAL SEL_out : std_ulogic := '0'; SIGNAL RST_in : std_ulogic := '0'; SIGNAL RST_out : std_ulogic := '0'; BEGIN --------------------------------------------------------------------------- -- Internal delays --------------------------------------------------------------------------- -- Artificial VITAL primitives to incorporate internal delays RESET : VitalBUF(RST_out,RST_in,(tdevice_RESET,UnitDelay)); SELEC : VitalBUF(SEL_out,SEL_in,(tdevice_SELEC,UnitDelay)); --------------------------------------------------------------------------- -- Wire Delays --------------------------------------------------------------------------- WireDelay : BLOCK BEGIN w_1 : VitalWireDelay(VIN_ipd,VIN,tipd_VIN); w_2 : VitalWireDelay(VINNeg_ipd,VINNeg,tipd_VINNeg); w_3 : VitalWireDelay(SEL_ipd,SEL,tipd_SEL); w_4 : VitalWireDelay(RST_ipd,RST,tipd_RST); END BLOCK; Behavior : BLOCK PORT ( VIN : IN std_ulogic := 'U'; VINNeg : IN std_ulogic := 'U'; SEL : IN std_ulogic := 'U'; RST : IN std_ulogic := 'U'; VOUT : OUT std_ulogic := 'U'; VOUTNeg : OUT std_ulogic := 'U' ); PORT MAP ( VIN => VIN_ipd, VINNeg => VINNeg_ipd, SEL => SEL_ipd, RST => RST_ipd, VOUT => VOUT, VOUTNeg => VOUTNeg ); CONSTANT diff_single_rec_tab : VitalStateTableType := ( ------INPUTS--|-PREV--|-OUTPUT---- -- IN INNeg| INint | INint' -- --------------|-------|----------- ( '\', '0', '1', '0'), -- single fall. - supplement to diff_rec_tab ( '0', '\', '0', '1'), -- single fall.7 - supplement to diff_rec_tab ( 'X', '-', '-', 'X'), -- A unknown ( '-', 'X', '-', 'X'), -- A unknown ( '1', '-', 'X', '1'), -- Recover from 'X' ( '0', '-', 'X', '0'), -- Recover from 'X' ( '/', '0', '0', '1'), -- valid diff. rising edge ( '1', '\', '0', '1'), -- valid diff. rising edge ( '\', '1', '1', '0'), -- valid diff. falling edge ( '0', '/', '1', '0'), -- valid diff. falling edge ( '-', '-', '-', 'S') -- default ); SIGNAL VIN_reg : std_ulogic := 'U'; SIGNAL VOUT_zd : std_ulogic := 'U'; SIGNAL VOUT_tmp : std_logic := 'U'; SIGNAL viol : X01 := '0'; SIGNAL RST_ACT : BOOLEAN := FALSE; SIGNAL SEL_ACT : BOOLEAN := FALSE; BEGIN RST_in <= RST; RESET_P: PROCESS (RST_out) IS BEGIN IF falling_edge(RST_out) THEN RST_ACT <= FALSE; ELSIF rising_edge(RST_out) THEN RST_ACT <= TRUE; END IF; END PROCESS RESET_P; SEL_in <= SEL; SELECT_P: PROCESS (SEL_out) IS BEGIN IF falling_edge(SEL_out) THEN SEL_ACT <= FALSE; ELSIF rising_edge(SEL_out) THEN SEL_ACT <= TRUE; END IF; END PROCESS SELECT_P; --------------------------------------------------------------------------- -- VITAL Timing Checks Procedures --------------------------------------------------------------------------- VITALTimingCheck : PROCESS (VIN, VINNeg, RST) VARIABLE Tviol_RST_VIN_posedge : X01 := '0'; VARIABLE TD_RST_VIN_posedge : VitalTimingDataType; VARIABLE Tviol_RST_VIN_negedge : X01 := '0'; VARIABLE TD_RST_VIN_negedge : VitalTimingDataType; VARIABLE Pviol_VIN : X01 := '0'; VARIABLE PD_VIN : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_VINNeg : X01 := '0'; VARIABLE PD_VINNeg : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Violation : X01 := '0'; VARIABLE PrevData : std_logic_vector(0 TO 1); BEGIN IF TimingChecksOn THEN Violation := '0'; -- Setup/Hold Checks VitalSetupHoldCheck ( TestSignal => RST, TestSignalName => "RST", RefSignal => VIN, RefSignalName => "VIN", SetupLow => tsetup_RST_VIN, CheckEnabled => SEL = '1', RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_RST_VIN_posedge, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RST_VIN_posedge ); VitalSetupHoldCheck ( TestSignal => RST, TestSignalName => "RST", RefSignal => VIN, RefSignalName => "VIN", SetupLow => tsetup_RST_VIN, CheckEnabled => SEL = '1', RefTransition => '\', HeaderMsg => InstancePath & partID, TimingData => TD_RST_VIN_negedge, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_RST_VIN_negedge ); -- Pulse Period Checks VitalPeriodPulseCheck ( TestSignal => VIN, TestSignalName => "VIN", Period => tperiod_VIN, CheckEnabled => TRUE, HeaderMsg => InstancePath & partID, PeriodData => PD_VIN, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_VIN ); VitalPeriodPulseCheck ( TestSignal => VINNeg, TestSignalName => "VINNeg", Period => tperiod_VIN, CheckEnabled => TRUE, HeaderMsg => InstancePath & partID, PeriodData => PD_VINNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_VINNeg ); Violation := Tviol_RST_VIN_posedge or Tviol_RST_VIN_negedge or Pviol_VIN OR Pviol_VINNeg; ASSERT Violation = '0' REPORT InstancePath & partID & ": simulation may be" & " inaccurate due to timing violations" SEVERITY Warning; viol <= violation; END IF; END PROCESS VITALTimingCheck; ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- Diff. Receiver Process ----------------------------------------------------------------------- DiffRec : PROCESS (VIN_ipd, VINNeg_ipd, VIN_reg) -- Functionality Results Variables VARIABLE PrevData : std_logic_vector(0 to 1); VARIABLE Vreg : std_ulogic := 'U'; BEGIN VitalStateTable ( StateTable => diff_single_rec_tab, DataIn => (VIN_ipd, VINNeg_ipd), Result => Vreg, PreviousDataIn => PrevData ); VIN_reg <= Vreg; END PROCESS DiffRec; ----------------------------------------------------------------------- -- Divider Process ----------------------------------------------------------------------- DIVVIN : PROCESS (VIN_reg, RST_ACT) VARIABLE first : BOOLEAN := true; VARIABLE div_cnt : natural; BEGIN IF (SEL_ACT = FALSE) THEN VOUT_zd <= VIN_reg; ELSIF (SEL_ACT = TRUE) AND (RST_ACT = TRUE) THEN VOUT_zd <= '0'; first := true; div_cnt := 0; ELSE IF first THEN VOUT_zd <= VIN_reg; first := false; div_cnt := div_cnt + 1; ELSIF div_cnt < 4 THEN div_cnt := div_cnt + 1; ELSE div_cnt := 1; VOUT_zd <= NOT(VOUT_zd); END IF; END IF; END PROCESS DIVVIN; ------------------------------------------------ -- Path Delay Section ------------------------------------------------ VOUT_output: PROCESS(VOUT_zd) VARIABLE VOUT_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01( OutSignal => VOUT_tmp, OutSignalName => "VOUT_tmp", OutTemp => VOUT_zd, Mode => VitalTransport, GlitchData => VOUT_GlitchData, Paths => ( 0 => (InputChangeTime => VIN_reg'LAST_EVENT, PathDelay => tpd_VIN_VOUT, PathCondition => (SEL_ACT = FALSE)), 1 => (InputChangeTime => VIN_reg'LAST_EVENT, PathDelay => tpd_VINNeg_VOUT, PathCondition => (SEL_ACT = TRUE)) ) ); END PROCESS VOUT_output; ------------------------------------------------------------------------ -- Output generation ------------------------------------------------------------------------ VOUT <= VOUT_tmp; VOUTNeg <= NOT VOUT_tmp; END BLOCK; END vhdl_behavioral;