------------------------------------------------------------------------------- -- File name : idt72851.vhd ------------------------------------------------------------------------------- -- Copyright (C) 1998 Integrated Device Technology; http://www.idt.com/ -- Developed by SEVA Technologies Inc. (Moscow branch) under contract to IDT -- and supported by 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. -- -- This VHDL model is provided on an "AS IS" basis and IDT makes absolutely no -- warranty with respect to the information contained herein. IDT DISCLAIMS -- AND CUSTOMER WAIVES ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING -- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -- ENTIRE RISK AS TO QUALITY AND PERFORMANCE IS WITH THE USER ACCORDINGLY, IN -- NO EVENT SHALL IDT BE LIABLE FOR ANY DIRECT OR INDIRECT DAMAGES, WHETHER IN -- CONTRACT OR TORT, INCLUDING ANY LOST PROFITS OR OTHER INCIDENTAL, -- CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES ARISING OUT OF THE USE OR -- APPLICATION OF THE VHDL model. Further, IDT reserves the right to make -- changes without notice to any product herein to improve reliability, -- function, or design. IDT does not convey any license under patent rights -- or any other intellectual property rights, including those of third parties. -- IDT is not obligated to provide maintenance or support for the licensed VHDL -- model. -- -- MODIFICATION HISTORY : -- -- version | author | mod date | changes made -- V1.0 | ZGA, PAV | 98 MAY 17 | initial coding -- V1.1 | R. Munden | 02 MAY 19 | licensing changed to GPL ------------------------------------------------------------------------------- -- PART DESCRIPTION : -- -- Library: IDT_FIFO -- Technology: CMOS -- Part: IDT72851 -- -- Description: SyncFIFO Memory 4096x9 -- ------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.vital_primitives.ALL; USE ieee.vital_timing.ALL; USE ieee.std_logic_1164.ALL; LIBRARY fmf; USE fmf.ff_package.ALL; USE fmf.gen_utils.ALL; USE fmf.conversions.to_nat; USE fmf.conversions.to_slv; ------------------------------------------------------------------------------- -- ENTITY DECLARATION ------------------------------------------------------------------------------- ENTITY IDT72851 IS GENERIC ( -- tipd delays: interconnect path delays -- (there must be one generic for each input pin) tipd_D0 : VitalDelayType01 := VitalZeroDelay01; tipd_D1 : VitalDelayType01 := VitalZeroDelay01; tipd_D2 : VitalDelayType01 := VitalZeroDelay01; tipd_D3 : VitalDelayType01 := VitalZeroDelay01; tipd_D4 : VitalDelayType01 := VitalZeroDelay01; tipd_D5 : VitalDelayType01 := VitalZeroDelay01; tipd_D6 : VitalDelayType01 := VitalZeroDelay01; tipd_D7 : VitalDelayType01 := VitalZeroDelay01; tipd_D8 : VitalDelayType01 := VitalZeroDelay01; tipd_RSNeg : VitalDelayType01 := VitalZeroDelay01; tipd_WCLK : VitalDelayType01 := VitalZeroDelay01; tipd_WEN1Neg : VitalDelayType01 := VitalZeroDelay01; tipd_WEN2LDNeg : VitalDelayType01 := VitalZeroDelay01; tipd_RCLK : VitalDelayType01 := VitalZeroDelay01; tipd_REN1Neg : VitalDelayType01 := VitalZeroDelay01; tipd_REN2Neg : VitalDelayType01 := VitalZeroDelay01; tipd_OENeg : VitalDelayType01 := VitalZeroDelay01; -- tpd delays: propagation delays -- tRSF ( for all flag ) tpd_RSNeg_EFNeg : VitalDelayType01 := UnitDelay01; -- tRSF (applicable for Q) tpd_RSNeg_Q0 : VitalDelayType01Z := UnitDelay01Z; -- tA (applicable for RCLKxQ-valid tpd_RCLK_Q0 : VitalDelayType01Z := UnitDelay01Z; -- tOLZ/tOE/tOHZ tpd_OENeg_Q0 : VitalDelayType01Z := UnitDelay01Z; -- tWFF tpd_WCLK_FFNeg : VitalDelayType01 := UnitDelay01; -- tREF tpd_RCLK_EFNeg : VitalDelayType01 := UnitDelay01; -- tPAF tpd_WCLK_PAFNeg : VitalDelayType01 := UnitDelay01; -- tPAE tpd_RCLK_PAENeg : VitalDelayType01 := UnitDelay01; -- tpw values: pulse widths -- tRCLKH tpw_RCLK_posedge : VitalDelayType := UnitDelay; -- tRCLKL tpw_RCLK_negedge : VitalDelayType := UnitDelay; -- tWCLKH tpw_WCLK_posedge : VitalDelayType := UnitDelay; -- tWCLKL tpw_WCLK_negedge : VitalDelayType := UnitDelay; -- tRS tpw_RSNeg_negedge : VitalDelayType := UnitDelay; -- tperiod values: min calculated as 1/max freq -- tperiod_RCLK_posedge tperiod_RCLK_posedge : VitalDelayType := UnitDelay; -- tWCLK tperiod_WCLK_posedge : VitalDelayType := UnitDelay; -- tsetup values: setup times -- tDS tsetup_D0_WCLK : VitalDelayType := UnitDelay; -- tENS tsetup_REN1Neg_RCLK : VitalDelayType := UnitDelay; -- tRSS tsetup_REN1Neg_RSNeg : VitalDelayType := UnitDelay; -- thold values: hold times -- tDH thold_D0_WCLK : VitalDelayType := UnitDelay; -- tENH thold_REN1Neg_RCLK : VitalDelayType := UnitDelay; -- trecovery values: recovery times -- tRSR trecovery_REN1Neg_RSNeg : VitalDelayType := UnitDelay; -- tskew values(Note: these values are passed through the -- SDF DEVICE construct) -- tSKEW1 (skew time /RCLK/WCLK(for FFIR) tdevice_SKEW1 : VitalDelayType := UnitDelay; -- tSKEW2 (skew time /RCLK/WCLK(for PAE&PAF) tdevice_SKEW2 : VitalDelayType := UnitDelay; -- generic control parameters InstancePath : STRING := DefaultInstancePath; TimingChecksOn : BOOLEAN := DefaultTimingChecks; MsgOn : BOOLEAN := DefaultMsgOn; XOn : BOOLEAN := DefaultXOn; TimingModel : STRING := DefaultTimingModel ); PORT ( D0 : IN std_logic := 'X'; -------------------------------- D1 : IN std_logic := 'X'; -- D2 : IN std_logic := 'X'; -- D3 : IN std_logic := 'X'; -- D4 : IN std_logic := 'X'; -- Data Input Bus D5 : IN std_logic := 'X'; -- D6 : IN std_logic := 'X'; -- D7 : IN std_logic := 'X'; -- D8 : IN std_logic := 'X'; -------------------------------- RSNeg : IN std_logic := 'X'; -- Reset WCLK : IN std_logic := 'X'; -- Write Clock WEN1Neg : IN std_logic := 'X'; -- Write Enable 1 WEN2LDNeg : IN std_logic := 'X'; -- Write Enable 2 RCLK : IN std_logic := 'X'; -- Read Clock REN1Neg : IN std_logic := 'X'; -- Read Enabled 1 REN2Neg : IN std_logic := 'X'; -- Read Enabled 2 OENeg : IN std_logic := 'X'; -- Output Enable Q0 : OUT std_logic := 'U'; -------------------------------- Q1 : OUT std_logic := 'U'; -- Q2 : OUT std_logic := 'U'; -- Q3 : OUT std_logic := 'U'; -- Q4 : OUT std_logic := 'U'; -- Data Output Bus Q5 : OUT std_logic := 'U'; -- Q6 : OUT std_logic := 'U'; -- Q7 : OUT std_logic := 'U'; -- Q8 : OUT std_logic := 'U'; -------------------------------- EFNeg : OUT std_logic := 'U'; -- Empty Flag PAENeg : OUT std_logic := 'U'; -- Programmable Almost-Empty Flag PAFNeg : OUT std_logic := 'U'; -- Programmable Almost-Full Flag FFNeg : OUT std_logic := 'U' -- Full Flag ); ATTRIBUTE vital_level0 OF IDT72851: ENTITY IS True; END IDT72851; ----------------------------------------------------------------------- -- ARCHITECTURE DECLARATION ----------------------------------------------------------------------- ARCHITECTURE vhdl_behavioral OF IDT72851 IS ATTRIBUTE vital_level0 OF vhdl_behavioral : ARCHITECTURE IS True; CONSTANT partID : String := "IDT72851"; -- delayed inputs (func. sec. must use these signals instead of actual inputs) SIGNAL D0_ipd : std_ulogic := 'X'; SIGNAL D1_ipd : std_ulogic := 'X'; SIGNAL D2_ipd : std_ulogic := 'X'; SIGNAL D3_ipd : std_ulogic := 'X'; SIGNAL D4_ipd : std_ulogic := 'X'; SIGNAL D5_ipd : std_ulogic := 'X'; SIGNAL D6_ipd : std_ulogic := 'X'; SIGNAL D7_ipd : std_ulogic := 'X'; SIGNAL D8_ipd : std_ulogic := 'X'; SIGNAL RSNeg_ipd : std_ulogic := 'X'; SIGNAL WCLK_ipd : std_ulogic := 'X'; SIGNAL WEN1Neg_ipd : std_ulogic := 'X'; SIGNAL WEN2LDNeg_ipd : std_ulogic := 'X'; SIGNAL RCLK_ipd : std_ulogic := 'X'; SIGNAL REN1Neg_ipd : std_ulogic := 'X'; SIGNAL REN2Neg_ipd : std_ulogic := 'X'; SIGNAL OENeg_ipd : std_ulogic := 'X'; -- FIFO memory definations CONSTANT FIFOSize : positive := 8192; CONSTANT FIFOWordLenght : positive := 9; SUBTYPE FIFOWord is std_logic_vector(0 to FIFOWordLenght - 1); TYPE FIFOArray is array (0 to FIFOSize) of FIFOWord; TYPE FIFOStates is (unknown, standby, idle); -- internal signals SIGNAL Pointer : Natural RANGE 0 TO FIFOSize := FIFOSize-1; SIGNAL EmptyOffReg : Natural; SIGNAL FullOffReg : Natural; SIGNAL OffRegSwitch: Natural; SIGNAL Start : std_ulogic := '0'; -- SKEW stuff (see also generics list) ALIAS tSKEW1 : VitalDelayType IS tdevice_SKEW1; ALIAS tSKEW2 : VitalDelayType IS tdevice_SKEW2; SIGNAL tSKEW_WCLK_RCLK : Time := 0 ns; -- actual /WCLK/RCLK skew time SIGNAL tSKEW_RCLK_WCLK : Time := 0 ns; -- actual /RCLK/WCLK skew time SIGNAL OpenIn, OpenOut : std_logic; ALIAS tRCLK : VitalDelayType IS tperiod_RCLK_posedge; ALIAS tWCLK : VitalDelayType IS tperiod_WCLK_posedge; BEGIN -------------------------------------------------------------------------------- -- Dummy instances for exporting tSKEW vals from SDF file -- using DEVICE construct -------------------------------------------------------------------------------- SKEW1: VitalBuf (OpenOut, OpenIn, (tdevice_SKEW1, tdevice_SKEW1)); SKEW2: VitalBuf (OpenOut, OpenIn, (tdevice_SKEW2, tdevice_SKEW2)); ------------------------------------------------------------------- -- Wire Delays ------------------------------------------------------------------- WireDelay: BLOCK BEGIN w_1: VitalWireDelay (D0_ipd , D0 , tipd_D0 ); w_2: VitalWireDelay (D1_ipd , D1 , tipd_D1 ); w_3: VitalWireDelay (D2_ipd , D2 , tipd_D2 ); w_4: VitalWireDelay (D3_ipd , D3 , tipd_D3 ); w_5: VitalWireDelay (D4_ipd , D4 , tipd_D4 ); w_6: VitalWireDelay (D5_ipd , D5 , tipd_D5 ); w_7: VitalWireDelay (D6_ipd , D6 , tipd_D6 ); w_8: VitalWireDelay (D7_ipd , D7 , tipd_D7 ); w_9: VitalWireDelay (D8_ipd , D8 , tipd_D8 ); w_11: VitalWireDelay (RSNeg_ipd , RSNeg , tipd_RSNeg ); w_12: VitalWireDelay (WCLK_ipd , WCLK , tipd_WCLK ); w_13: VitalWireDelay (WEN1Neg_ipd , WEN1Neg , tipd_WEN1Neg ); w_14: VitalWireDelay (WEN2LDNeg_ipd, WEN2LDNeg, tipd_WEN2LDNeg ); w_15: VitalWireDelay (RCLK_ipd , RCLK , tipd_RCLK ); w_16: VitalWireDelay (REN1Neg_ipd , REN1Neg , tipd_REN1Neg ); w_17: VitalWireDelay (REN2Neg_ipd , REN2Neg , tipd_REN2Neg ); w_18: VitalWireDelay (OENeg_ipd , OENeg , tipd_OENeg ); END BLOCK WireDelay; ------------------------------------------------------------------- -- Main behavior Block ------------------------------------------------------------------- VitalBehavior: BLOCK PORT ( D : IN std_logic_vector( FIFOWordLenght-1 DOWNTO 0):= (OTHERS => 'X' ); RSNeg : IN std_logic := 'X'; WCLK : IN std_logic := 'X'; WEN1Neg : IN std_logic := 'X'; WEN2LDNeg: IN std_logic := 'X'; RCLK : IN std_logic := 'X'; REN1Neg : IN std_logic := 'X'; REN2Neg : IN std_logic := 'X'; OENeg : IN std_logic := 'X'; Q : OUT std_logic_vector( FIFOWordLenght-1 DOWNTO 0):= (OTHERS => 'U' ); EFNeg : OUT std_logic := 'U'; PAENeg : OUT std_logic := 'U'; PAFNeg : OUT std_logic := 'U'; FFNeg : OUT std_logic := 'U'); PORT MAP ( D(0) => D0_ipd, D(1) => D1_ipd, D(2) => D2_ipd, D(3) => D3_ipd, D(4) => D4_ipd, D(5) => D5_ipd, D(6) => D6_ipd, D(7) => D7_ipd, D(8) => D8_ipd, RSNeg => RSNeg_ipd, WCLK => WCLK_ipd, WEN1Neg => WEN1Neg_ipd, WEN2LDNeg => WEN2LDNeg_ipd, RCLK => RCLK_ipd, REN1Neg => REN1Neg_ipd, REN2Neg => REN2Neg_ipd, OENeg => OENeg_ipd, Q(0) => Q0, Q(1) => Q1, Q(2) => Q2, Q(3) => Q3, Q(4) => Q4, Q(5) => Q5, Q(6) => Q6, Q(7) => Q7, Q(8) => Q8, EFNeg => EFNeg, PAENeg => PAENeg, PAFNeg => PAFNeg, FFNeg => FFNeg); SIGNAL FFNeg_zd : std_ulogic := 'X'; -------------------- SIGNAL EFNeg_zd : std_ulogic := 'X'; -- regs for output SIGNAL PAENeg_zd : std_ulogic := 'X'; -- flags SIGNAL PAFNeg_zd : std_ulogic := 'X'; -------------------- SIGNAL Q_zd : std_logic_vector(FIFOWordLenght-1 DOWNTO 0); BEGIN -- VitalBehavior block --------------------------------------------------------------- -- Timinf Check Section --------------------------------------------------------------- TimingChecks: PROCESS (D, RSNeg, WCLK, WEN1Neg, WEN2LDNeg, RCLK, REN1Neg, REN2Neg, OENeg ) -- Timing Check Variable -- Pulse Width and Period Check Variables VARIABLE Pviol_WCLK : X01 := '0'; VARIABLE PD_WCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_RCLK : X01 := '0'; VARIABLE PD_RCLK : VitalPeriodDataType := VitalPeriodDataInit; VARIABLE Pviol_RSNeg : X01 := '0'; VARIABLE PD_RSNeg : VitalPeriodDataType := VitalPeriodDataInit; -- Setup/Hold Check Variables VARIABLE Tviol_D0_WCLK : X01 := '0'; VARIABLE TD_D0_WCLK : VitalTimingDataType; VARIABLE Tviol_REN1Neg_RCLK : X01 := '0'; VARIABLE TD_REN1Neg_RCLK : VitalTimingDataType; VARIABLE Tviol_REN2Neg_RCLK : X01 := '0'; VARIABLE TD_REN2Neg_RCLK : VitalTimingDataType; VARIABLE Tviol_WEN1Neg_WCLK : X01 := '0'; VARIABLE TD_WEN1Neg_WCLK : VitalTimingDataType; VARIABLE Tviol_WEN2LDNeg_WCLK : X01 := '0'; VARIABLE TD_WEN2LDNeg_WCLK : VitalTimingDataType; VARIABLE Tviol_REN1Neg_RSNeg : X01 := '0'; VARIABLE TD_REN1Neg_RSNeg : VitalTimingDataType; VARIABLE Tviol_REN2Neg_RSNeg : X01 := '0'; VARIABLE TD_REN2Neg_RSNeg : VitalTimingDataType; VARIABLE Tviol_WEN1Neg_RSNeg : X01 := '0'; VARIABLE TD_WEN1Neg_RSNeg : VitalTimingDataType; VARIABLE Tviol_WEN2LDNeg_RSNeg : X01 := '0'; VARIABLE TD_WEN2LDNeg_RSNeg : VitalTimingDataType; -- Recovery Check Variables VARIABLE Rviol_REN1Neg_RSNeg : X01 := '0'; VARIABLE RD_REN1Neg_RSNeg : VitalTimingDataType; VARIABLE Rviol_REN2Neg_RSNeg : X01 := '0'; VARIABLE RD_REN2Neg_RSNeg : VitalTimingDataType; VARIABLE Rviol_WEN1Neg_RSNeg : X01 := '0'; VARIABLE RD_WEN1Neg_RSNeg : VitalTimingDataType; VARIABLE Rviol_WEN2LDNeg_RSNeg : X01 := '0'; VARIABLE RD_WEN2LDNeg_RSNeg : VitalTimingDataType; -- Violation variable (used to OR all individual violatiions) VARIABLE Violation : X01 := '0'; BEGIN -- timing check process IF (TimingChecksON) THEN Pviol_WCLK := '0'; Pviol_RCLK := '0'; Pviol_RSNeg := '0'; Tviol_D0_WCLK := '0'; Tviol_REN1Neg_RCLK := '0'; Tviol_REN2Neg_RCLK := '0'; Tviol_WEN1Neg_WCLK := '0'; Tviol_WEN2LDNeg_WCLK := '0'; Tviol_REN1Neg_RSNeg := '0'; Tviol_REN2Neg_RSNeg := '0'; Tviol_WEN1Neg_RSNeg := '0'; Tviol_WEN2LDNeg_RSNeg := '0'; Rviol_REN1Neg_RSNeg := '0'; Rviol_REN2Neg_RSNeg := '0'; Rviol_WEN1Neg_RSNeg := '0'; Rviol_WEN2LDNeg_RSNeg := '0'; --1. WCLK pulse ( low&high ) width and period check -- ( tCLK, tCLKL, tCLKH ) IF WCLK'Event THEN VitalPeriodPulseCheck ( TestSignal => WCLK, TestSignalName => "WCLK", Period => tperiod_WCLK_posedge, PulseWidthHigh => tpw_RCLK_posedge, PulseWidthLow => tpw_RCLK_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & partID, PeriodData => PD_WCLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_WCLK); END IF; --2. RCLK pulse ( low&high ) width and period check -- ( tCLK, tCLKL, tCLKH ) IF RCLK'Event THEN VitalPeriodPulseCheck ( TestSignal => RCLK, TestSignalName => "RCLK", Period => tperiod_RCLK_posedge, PulseWidthHigh => tpw_RCLK_posedge, PulseWidthLow => tpw_RCLK_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & partID, PeriodData => PD_RCLK, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RCLK); END IF; --3. RSNeg pulse low width check (tRS) IF RSNeg'Event THEN VitalPeriodPulseCheck ( TestSignal => RSNeg, TestSignalName => "RSNeg", PulseWidthLow => tpw_RSNeg_negedge, CheckEnabled => TRUE, HeaderMsg => InstancePath & partID, PeriodData => PD_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Pviol_RSNeg); END IF; --4. D/WCLK setup/hold time check (tDS, tDH) IF D'Event AND WCLK'Event THEN VitalSetupHoldCheck ( TestSignal => D, TestSignalName => "D", RefSignal => WCLK, RefSignalName => "WCLK", SetupHigh => tSetup_D0_WCLK, SetupLow => tSetup_D0_WCLK, HoldHigh => tHold_D0_WCLK, HoldLow => tHold_D0_WCLK, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_D0_WCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_D0_WCLK); END IF; --5. WEN1Neg/WCLK setup/hold time check (tENS, tENH) IF WEN1Neg'Event AND WCLK'Event THEN VitalSetupHoldCheck ( TestSignal => WEN1Neg, TestSignalName => "WEN1Neg", RefSignal => WCLK, RefSignalName => "WCLK", SetupLow => tSetup_REN1Neg_RCLK, HoldLow => tHold_REN1Neg_RCLK, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WEN1Neg_WCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WEN1Neg_WCLK); END IF; --6. WEN2LDNeg/WCLK setup/hold time check (tENS, tENH) IF WEN2LDNeg'Event AND WCLK'Event THEN VitalSetupHoldCheck ( TestSignal => WEN2LDNeg, TestSignalName => "WEN2LDNeg", RefSignal => WCLK, RefSignalName => "WCLK", SetupHigh => tSetup_REN1Neg_RCLK, SetupLow => tSetup_REN1Neg_RCLK, HoldHigh => tHold_REN1Neg_RCLK, HoldLow => tHold_REN1Neg_RCLK, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WEN2LDNeg_WCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WEN2LDNeg_WCLK); END IF; --7. REN1Neg/RCLK setup/hold time check (tENS, tENH) IF REN1Neg'Event AND RCLK'Event THEN VitalSetupHoldCheck ( TestSignal => REN1Neg, TestSignalName => "REN1Neg", RefSignal => RCLK, RefSignalName => "RCLK", SetupLow => tSetup_REN1Neg_RCLK, HoldLow => tHold_REN1Neg_RCLK, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_REN1Neg_RCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_REN1Neg_RCLK); END IF; --8. REN2Neg/RCLK setup/hold time check (tENS, tENH) IF REN2Neg'Event AND RCLK'Event THEN VitalSetupHoldCheck ( TestSignal => REN2Neg, TestSignalName => "REN2Neg", RefSignal => RCLK, RefSignalName => "RCLK", SetupLow => tSetup_REN1Neg_RCLK, HoldLow => tHold_REN1Neg_RCLK, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_REN2Neg_RCLK, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_REN2Neg_RCLK); END IF; --9. REN1Neg/RSNeg setup time check (tRSS) IF REN1Neg'Event AND RSNeg'Event THEN VitalSetupHoldCheck ( TestSignal => REN1Neg, TestSignalName => "REN1Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", SetupLow => tSetup_REN1Neg_RSNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_REN1Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_REN1Neg_RSNeg); END IF; --10. REN2Neg/RSNeg setup time check (tRSS) IF REN2Neg'Event AND RSNeg'Event THEN VitalSetupHoldCheck ( TestSignal => REN2Neg, TestSignalName => "REN2Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", SetupLow => tSetup_REN1Neg_RSNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_REN2Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_REN2Neg_RSNeg); END IF; --11. WEN1Neg/RSNeg setup time check (tRSS) IF WEN1Neg'Event AND RSNeg'Event THEN VitalSetupHoldCheck ( TestSignal => WEN1Neg, TestSignalName => "WEN1Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", SetupLow => tSetup_REN1Neg_RSNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WEN1Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WEN1Neg_RSNeg); END IF; --12. WEN2LDNeg/RSNeg setup time check (tRSS) IF WEN2LDNeg'Event AND RSNeg'Event THEN VitalSetupHoldCheck ( TestSignal => WEN2LDNeg, TestSignalName => "WEN2LDNeg", RefSignal => RSNeg, RefSignalName => "RSNeg", SetupLow => tSetup_REN1Neg_RSNeg, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => TD_WEN2LDNeg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Tviol_WEN2LDNeg_RSNeg); END IF; --13. REN1Neg/RSNeg Recovery time check (tRSR) IF REN1Neg'Event AND (RSNeg'Event AND RSNeg = '1') THEN VitalRecoveryRemovalCheck ( TestSignal => REN1Neg, TestSignalName => "REN1Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", Recovery => tRecovery_REN1Neg_RSNeg, ActiveLow => FALSE, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_REN1Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_REN1Neg_RSNeg); END IF; --14. REN2Neg/RSNeg Recovery time check (tRSR) IF REN2Neg'Event AND RSNeg'Event THEN VitalRecoveryRemovalCheck ( TestSignal => REN2Neg, TestSignalName => "REN2Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", Recovery => tRecovery_REN1Neg_RSNeg, ActiveLow => FALSE, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_REN2Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_REN2Neg_RSNeg); END IF; --15. WEN1Neg/RSNeg Recovery time check (tRSR) IF WEN1Neg'Event AND RSNeg'Event THEN VitalRecoveryRemovalCheck ( TestSignal => WEN1Neg, TestSignalName => "WEN1Neg", RefSignal => RSNeg, RefSignalName => "RSNeg", Recovery => tRecovery_REN1Neg_RSNeg, ActiveLow => FALSE, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_WEN1Neg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_WEN1Neg_RSNeg); END IF; --16. WEN2LDNeg/RSNeg Recovery time check (tRSR) IF WEN2LDNeg'Event AND RSNeg'Event THEN VitalRecoveryRemovalCheck ( TestSignal => WEN2LDNeg, TestSignalName => "WEN2LDNeg", RefSignal => RSNeg, RefSignalName => "RSNeg", Recovery => tRecovery_REN1Neg_RSNeg, ActiveLow => FALSE, CheckEnabled => TRUE, RefTransition => '/', HeaderMsg => InstancePath & partID, TimingData => RD_WEN2LDNeg_RSNeg, XOn => XOn, MsgOn => MsgOn, Violation => Rviol_WEN2LDNeg_RSNeg); END IF; Violation := Pviol_WCLK OR Pviol_RCLK OR Pviol_RSNeg OR Tviol_D0_WCLK OR Tviol_WEN1Neg_WCLK OR Tviol_WEN2LDNeg_WCLK OR Tviol_REN1Neg_RCLK OR Tviol_REN2Neg_RCLK OR Tviol_WEN1Neg_RSNeg OR Tviol_WEN2LDNeg_RSNeg OR Tviol_REN1Neg_RSNeg OR Tviol_REN2Neg_RSNeg OR Rviol_REN1Neg_RSNeg OR Rviol_REN2Neg_RSNeg OR Rviol_WEN1Neg_RSNeg OR Rviol_WEN2LDNeg_RSNeg; ASSERT Violation = '0' REPORT InstancePath & partID & " : signal values may be" & " incorrect due timing violation(s)" SEVERITY Warning; END IF; END PROCESS TimingChecks; --------------------------------------------------------------- -- Functionality section --------------------------------------------------------------- MainReadWrite: PROCESS( RSNeg, WCLK, RCLK, WEN1Neg, WEN2LDNeg, REN1Neg, REN2Neg, D, OENeg ) VARIABLE FIFOMemory : FIFOArray := (FIFOArray'range => FIFOWord'(OTHERS => 'X')); BEGIN IF RSNeg'Event AND RSNeg = '0' THEN FFNeg_zd <= '1'; PAFNeg_zd <= '1'; EFNeg_zd <= '0'; PAENeg_zd <= '0'; Pointer <= 0; IF OENeg = '0' THEN Q_zd <= (OTHERS => '0'); ELSIF OENeg = '1' THEN Q_zd <= (OTHERS => 'Z'); END IF; Start <= '1'; ELSIF Start = '1' THEN IF WCLK'Event AND WCLK = '1' THEN IF WEN1Neg ='0' AND WEN2LDNeg = '1' AND Pointer < FIFOSize THEN IF Pointer = FIFOSize - 1 THEN IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '0'; ELSE FFNeg_zd <= '0' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '0'; ELSE PAFNeg_zd <= '0' AFTER (tWCLK); END IF; FIFOMemory( Pointer ) := D; Pointer <= Pointer + 1; ELSIF Pointer >= FIFOSize - FullOffReg - 1 THEN IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '0'; ELSE PAFNeg_zd <= '0' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '1'; ELSE FFNeg_zd <= '1' AFTER (tWCLK); END IF; FIFOMemory( Pointer ) := D; Pointer <= Pointer + 1; ELSE IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '1'; ELSE FFNeg_zd <= '1' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '1'; ELSE PAFNeg_zd <= '1' AFTER (tWCLK); END IF; FIFOMemory( Pointer ) := D; Pointer <= Pointer + 1; END IF; ELSIF Pointer = FIFOSize THEN IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '0'; ELSE FFNeg_zd <= '0' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '0'; ELSE PAFNeg_zd <= '0' AFTER (tWCLK); END IF; ELSIF Pointer >= FIFOSize - FullOffReg THEN IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '0'; ELSE PAFNeg_zd <= '0' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '1'; ELSE FFNeg_zd <= '1' AFTER (tWCLK); END IF; ELSE IF tSKEW_RCLK_WCLK >= tSKEW1 THEN FFNeg_zd <= '1'; ELSE FFNeg_zd <= '1' AFTER (tWCLK); END IF; IF tSKEW_RCLK_WCLK >= tSKEW2 THEN PAFNeg_zd <= '1'; ELSE PAFNeg_zd <= '1' AFTER (tWCLK); END IF; END IF; END IF; IF RCLK'Event AND RCLK = '1' THEN IF REN1Neg = '0' AND REN2Neg = '0' AND Pointer > 0 THEN IF Pointer = 1 THEN IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '0'; ELSE EFNeg_zd <= '0' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '0'; ELSE PAENeg_zd <= '0' AFTER (tRCLK); END IF; IF OENeg = '0' THEN Q_zd <= FIFOMemory(0); END IF; Pointer <= Pointer - 1; FOR i IN 0 TO Pointer - 1 LOOP FIFOMemory(i) := FIFOMemory(i + 1); END LOOP; ELSIF Pointer > EmptyOffReg + 1 THEN IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '1'; ELSE PAENeg_zd <= '1' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '1'; ELSE EFNeg_zd <= '1' AFTER (tRCLK); END IF; IF OENeg = '0' THEN Q_zd <= FIFOMemory(0); END IF; Pointer <= Pointer - 1; FOR i IN 0 TO Pointer - 1 LOOP FIFOMemory(i) := FIFOMemory(i + 1); END LOOP; ELSE IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '0'; ELSE PAENeg_zd <= '0' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '1'; ELSE EFNeg_zd <= '1' AFTER (tRCLK); END IF;EFNeg_zd <= '1'; IF OENeg = '0' THEN Q_zd <= FIFOMemory(0); END IF; Pointer <= Pointer - 1; FOR i IN 0 TO Pointer - 1 LOOP FIFOMemory(i) := FIFOMemory(i + 1); END LOOP; END IF; ELSIF Pointer = 0 THEN IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '0'; ELSE EFNeg_zd <= '0' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '0'; ELSE PAENeg_zd <= '0' AFTER (tRCLK); END IF; ELSIF Pointer > EmptyOffReg THEN IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '1'; ELSE PAENeg_zd <= '1' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '1'; ELSE EFNeg_zd <= '1' AFTER (tRCLK); END IF; ELSE IF tSKEW_WCLK_RCLK >= tSKEW2 THEN PAENeg_zd <= '0'; ELSE PAENeg_zd <= '0' AFTER (tRCLK); END IF; IF tSKEW_WCLK_RCLK >= tSKEW1 THEN EFNeg_zd <= '1'; ELSE EFNeg_zd <= '1' AFTER (tRCLK); END IF; END IF; END IF; IF OENeg'Event AND OENeg = '1' THEN Q_zd <= ( OTHERS => 'Z' ); END IF; END IF; END PROCESS MainReadWrite; SetOffReg: PROCESS( RSNeg, WCLK, RCLK, Pointer ) BEGIN IF RSNeg'Event AND RSNeg = '0' THEN EmptyOffReg <= 7; FullOffReg <= 7; OffRegSwitch <= 1; ELSIF Start = '1' THEN IF WCLK'Event AND WCLK = '1' THEN IF WEN1Neg = '0' AND WEN2LDNeg = '0' THEN IF OffRegSwitch = 1 THEN -- EMPTY: Least Significant Bit EmptyOffReg <= to_nat(D(7 DOWNTO 0)); OffRegSwitch <= OffRegSwitch + 1; ELSIF OffRegSwitch = 2 THEN -- EMPTY: Most Significant Bit OffRegSwitch <= OffRegSwitch + 1; ELSIF OffRegSwitch = 3 THEN -- FULL: Least Significant Bit FullOffReg <= to_nat(D(7 DOWNTO 0)); OffRegSwitch <= OffRegSwitch + 1; ELSIF OffRegSwitch = 4 THEN -- FULL: Most Significant Bit OffRegSwitch <= 1; END IF; END IF; END IF; END IF; END PROCESS SetOffReg; ------------------------------------------------------------------------ -- Detection of the actual tSKEW vals -- ------------------------------------------------------------------------ SkewDetector: PROCESS(RCLK, WCLK) VARIABLE tRCLKposedge : Time := 0 ns; VARIABLE tWCLKposedge : Time := 0 ns; BEGIN IF RCLK'event AND RCLK = '1' THEN tRCLKposedge := Now; tSKEW_WCLK_RCLK <= Now - tWCLKposedge; END IF; IF WCLK'event AND WCLK = '1' THEN tWCLKposedge := Now; tSKEW_RCLK_WCLK <= Now - tRCLKposedge; END IF; END PROCESS SkewDetector; ------------------------------------------------------------------------ -- Path delay section -- ------------------------------------------------------------------------ -- path delay for EFNeg EFPathDelay: PROCESS (EFNeg_zd) VARIABLE EFNeg_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 (OutSignal => EFNeg, OutSignalName => "EFNeg", OutTemp => EFNeg_zd, GlitchData => EFNeg_GlitchData, Paths => (0 => (InputChangeTime => RSNeg'last_event, PathDelay => tpd_RSNeg_EFNeg, PathCondition => true), 1 => (InputChangeTime => RCLK'last_event, PathDelay => tpd_RCLK_EFNeg, PathCondition => true))); END PROCESS EFPathDelay; -- path delay for PAENeg PAEPathDelay: PROCESS (PAENeg_zd) VARIABLE PAENeg_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 (OutSignal => PAENeg, OutSignalName => "PAENeg", OutTemp => PAENeg_zd, GlitchData => PAENeg_GlitchData, Paths => (0 => (InputChangeTime => RSNeg'last_event, PathDelay => tpd_RSNeg_EFNeg, PathCondition => true), 1 => (InputChangeTime => RCLK'last_event, PathDelay => tpd_RCLK_PAENeg, PathCondition => true))); END PROCESS PAEPathDelay; -- path delay for PAFNeg PAFPathDelay: PROCESS (PAFNeg_zd) VARIABLE PAFNeg_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 (OutSignal => PAFNeg, OutSignalName => "PAFNeg", OutTemp => PAFNeg_zd, GlitchData => PAFNeg_GlitchData, Paths => (0 => (InputChangeTime => RSNeg'last_event, PathDelay => tpd_RSNeg_EFNeg, PathCondition => true), 1 => (InputChangeTime => WCLK'last_event, PathDelay => tpd_WCLK_PAFNeg, PathCondition => true))); END PROCESS PAFPathDelay; -- path delay for FFNeg FFPathDelay: PROCESS (FFNeg_zd) VARIABLE FFNeg_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01 (OutSignal => FFNeg, OutSignalName => "FFNeg", OutTemp => FFNeg_zd, GlitchData => FFNeg_GlitchData, Paths => (0 => (InputChangeTime => RSNeg'last_event, PathDelay => tpd_RSNeg_EFNeg, PathCondition => true), 1 => (InputChangeTime => WCLK'last_event, PathDelay => tpd_WCLK_FFNeg, PathCondition => true))); END PROCESS FFPathDelay; -- path delay for Q QPathDelay_Gen: FOR i IN Q'range GENERATE PROCESS (Q_zd(i)) VARIABLE Q_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z (OutSignal => Q(i), OutSignalName => "Q", OutTemp => Q_zd(i), GlitchData => Q_GlitchData, Paths => (0 => (InputChangeTime =>RSNeg'last_event, PathDelay =>tpd_RSNeg_Q0, PathCondition =>true), 1 => (InputChangeTime =>RCLK'last_event, PathDelay =>tpd_RCLK_Q0, PathCondition =>true), 2 => (InputChangeTime =>OENeg'last_event, PathDelay =>tpd_OENeg_Q0, PathCondition =>OENeg = '1'))); END PROCESS; END GENERATE QPathDelay_Gen; END BLOCK VitalBehavior; END vhdl_behavioral;