📄 timing_b.vhdl
字号:
BEGIN -- Initialization of working area. IF (TimingData.NotFirstFlag = FALSE) THEN TimingData.TestLastA := NEW std_logic_vector(TestSignal'RANGE); TimingData.TestTimeA := NEW VitalTimeArrayT(TestSignal'RANGE); TimingData.HoldEnA := NEW VitalBoolArrayT(TestSignal'RANGE); TimingData.SetupEnA := NEW VitalBoolArrayT(TestSignal'RANGE); FOR i IN TestSignal'RANGE LOOP TimingData.TestLastA(i) := To_X01(TestSignal(i)); END LOOP; TimingData.RefLast := To_X01(RefSignal); TimingData.NotFirstFlag := TRUE; END IF; -- Detect reference edges and record the time of the last edge RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), RefTransition); TimingData.RefLast := To_X01(RefSignal); IF RefEdge THEN TimingData.RefTime := NOW; TimingData.SetupEn := TimingData.SetupEn AND EnableSetupOnRef; --IR252 3/23/98 TimingData.HoldEnA.all := (TestSignal'RANGE => EnableHoldOnRef); --IR252 3/23/98 END IF; -- Detect test (data) changes and record the time of the last change FOR i IN TestSignal'RANGE LOOP TestEvent(i) := TimingData.TestLastA(i) /= To_X01Z(TestSignal(i)); TimingData.TestLastA(i) := To_X01Z(TestSignal(i)); IF TestEvent(i) THEN TimingData.TestTimeA(i) := NOW; TimingData.SetupEnA(i) := EnableSetupOnTest; --IR252 3/23/98 TimingData.HoldEnA(i) := TimingData.HoldEn AND EnableHoldOnTest; --IR252 3/23/98 TimingData.TestTime := NOW; --IR252 3/23/98 END IF; END LOOP; -- Check to see if the Bus subelements changed all at the same time. -- If so, then we can reduce the volume of error messages since we no -- longer have to report every subelement individually FOR i IN TestSignal'RANGE LOOP IF TimingData.TestTimeA(i) /= TimingData.TestTime THEN ChangedAllAtOnce := FALSE; EXIT; END IF; END LOOP; -- Perform timing checks (if enabled) Violation := '0'; IF (CheckEnabled) THEN FOR i IN TestSignal'RANGE LOOP InternalTimingCheck ( TestSignal => TestSignal(i), RefSignal => RefSignal, TestDelay => TestDly, RefDelay => RefDly, SetupHigh => SetupHigh, SetupLow => SetupLow, HoldHigh => HoldHigh, HoldLow => HoldLow, RefTime => TimingData.RefTime, RefEdge => RefEdge, TestTime => TimingData.TestTimeA(i), TestEvent => TestEvent(i), SetupEn => TimingData.SetupEnA(i), HoldEn => TimingData.HoldEnA(i), CheckInfo => CheckInfo, MsgOn => MsgOn ); -- Report any detected violations and set return violation flag IF CheckInfo.Violation THEN IF (MsgOn) THEN IF ( ChangedAllAtOnce AND (i = TestSignal'LEFT) ) THEN ReportViolation (TestSignalName&"(...)", RefSignalName, HeaderMsg, CheckInfo, MsgSeverity ); ELSIF (NOT ChangedAllAtOnce) THEN Write (StrPtr1, i); ReportViolation (TestSignalName & "(" & StrPtr1.ALL & ")", RefSignalName, HeaderMsg, CheckInfo, MsgSeverity ); DEALLOCATE (StrPtr1); END IF; END IF; IF (XOn) THEN Violation := 'X'; END IF; END IF; END LOOP; END IF; DEALLOCATE (StrPtr1); END VitalSetupHoldCheck; --------------------------------------------------------------------------- -- Function : VitalRecoveryRemovalCheck --------------------------------------------------------------------------- PROCEDURE VitalRecoveryRemovalCheck ( VARIABLE Violation : OUT X01; VARIABLE TimingData : INOUT VitalTimingDataType; SIGNAL TestSignal : IN std_ulogic; CONSTANT TestSignalName: IN STRING := ""; CONSTANT TestDelay : IN TIME := 0 ns; SIGNAL RefSignal : IN std_ulogic; CONSTANT RefSignalName : IN STRING := ""; CONSTANT RefDelay : IN TIME := 0 ns; CONSTANT Recovery : IN TIME := 0 ns; CONSTANT Removal : IN TIME := 0 ns; CONSTANT ActiveLow : IN BOOLEAN := TRUE; CONSTANT CheckEnabled : IN BOOLEAN := TRUE; CONSTANT RefTransition : IN VitalEdgeSymbolType; CONSTANT HeaderMsg : IN STRING := " "; CONSTANT XOn : IN BOOLEAN := TRUE; CONSTANT MsgOn : IN BOOLEAN := TRUE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING; CONSTANT EnableRecOnTest : IN BOOLEAN := TRUE; --IR252 3/23/98 CONSTANT EnableRecOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 CONSTANT EnableRemOnRef : IN BOOLEAN := TRUE; --IR252 3/23/98 CONSTANT EnableRemOnTest : IN BOOLEAN := TRUE --IR252 3/23/98 ) IS VARIABLE CheckInfo : CheckInfoType; VARIABLE RefEdge, TestEvent : BOOLEAN; VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); VARIABLE RefDly : TIME := Maximum(0 ns, RefDelay); VARIABLE bias : TIME; BEGIN IF (TimingData.NotFirstFlag = FALSE) THEN TimingData.TestLast := To_X01(TestSignal); TimingData.RefLast := To_X01(RefSignal); TimingData.NotFirstFlag := TRUE; END IF; -- Detect reference edges and record the time of the last edge RefEdge := EdgeSymbolMatch(TimingData.RefLast, To_X01(RefSignal), RefTransition); TimingData.RefLast := To_X01(RefSignal); IF RefEdge THEN TimingData.RefTime := NOW; TimingData.SetupEn := TimingData.SetupEn AND EnableRecOnRef; --IR252 3/23/98 TimingData.HoldEn := EnableRemOnRef; --IR252 3/23/98 END IF; -- Detect test (data) changes and record the time of the last change TestEvent := TimingData.TestLast /= To_X01Z(TestSignal); TimingData.TestLast := To_X01Z(TestSignal); IF TestEvent THEN TimingData.TestTime := NOW; TimingData.SetupEn := EnableRecOnTest; --IR252 3/23/98 TimingData.HoldEn := TimingData.HoldEn AND EnableRemOnTest; --IR252 3/23/98 END IF; -- Perform timing checks (if enabled) Violation := '0'; IF (CheckEnabled) THEN IF ActiveLow THEN InternalTimingCheck ( TestSignal, RefSignal, TestDly, RefDly, Recovery, 0 ns, 0 ns, Removal, TimingData.RefTime, RefEdge, TimingData.TestTime, TestEvent, TimingData.SetupEn, TimingData.HoldEn, CheckInfo, MsgOn ); ELSE InternalTimingCheck ( TestSignal, RefSignal, TestDly, RefDly, 0 ns, Recovery, Removal, 0 ns, TimingData.RefTime, RefEdge, TimingData.TestTime, TestEvent, TimingData.SetupEn, TimingData.HoldEn, CheckInfo, MsgOn ); END IF; -- Report any detected violations and set return violation flag IF CheckInfo.Violation THEN IF CheckInfo.CheckKind = SetupCheck THEN CheckInfo.CheckKind := RecoveryCheck; ELSE CheckInfo.CheckKind := RemovalCheck; END IF; IF (MsgOn) THEN ReportViolation (TestSignalName, RefSignalName, HeaderMsg, CheckInfo, MsgSeverity ); END IF; IF (XOn) THEN Violation := 'X'; END IF; END IF; END IF; END VitalRecoveryRemovalCheck; --------------------------------------------------------------------------- PROCEDURE VitalPeriodPulseCheck ( VARIABLE Violation : OUT X01; VARIABLE PeriodData : INOUT VitalPeriodDataType; SIGNAL TestSignal : IN std_ulogic; CONSTANT TestSignalName : IN STRING := ""; CONSTANT TestDelay : IN TIME := 0 ns; CONSTANT Period : IN TIME := 0 ns; CONSTANT PulseWidthHigh : IN TIME := 0 ns; CONSTANT PulseWidthLow : IN TIME := 0 ns; CONSTANT CheckEnabled : IN BOOLEAN := TRUE; CONSTANT HeaderMsg : IN STRING := " "; CONSTANT XOn : IN BOOLEAN := TRUE; CONSTANT MsgOn : IN BOOLEAN := TRUE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS VARIABLE TestDly : TIME := Maximum(0 ns, TestDelay); VARIABLE CheckInfo : CheckInfoType; VARIABLE PeriodObs : TIME; VARIABLE PulseTest, PeriodTest : BOOLEAN; VARIABLE TestValue : X01 := To_X01(TestSignal); BEGIN IF (PeriodData.NotFirstFlag = FALSE) THEN PeriodData.Rise := -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow)); PeriodData.Fall := -maximum(Period, maximum(PulseWidthHigh, PulseWidthLow)); PeriodData.Last := To_X01(TestSignal); PeriodData.NotFirstFlag := TRUE; END IF; -- Initialize for no violation -- No violation possible if no test signal change Violation := '0'; IF (PeriodData.Last = TestValue) THEN RETURN; END IF; -- record starting pulse times IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'P') THEN -- Compute period times, then record the High Rise Time PeriodObs := NOW - PeriodData.Rise; PeriodData.Rise := NOW; PeriodTest := TRUE; ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'N') THEN -- Compute period times, then record the Low Fall Time PeriodObs := NOW - PeriodData.Fall; PeriodData.Fall := NOW; PeriodTest := TRUE; ELSE PeriodTest := FALSE; END IF; -- do checks on pulse ends IF EdgeSymbolMatch(PeriodData.Last, TestValue, 'p') THEN -- Compute pulse times CheckInfo.ObsTime := NOW - PeriodData.Fall; CheckInfo.ExpTime := PulseWidthLow; PulseTest := TRUE; ELSIF EdgeSymbolMatch(PeriodData.Last, TestValue, 'n') THEN -- Compute pulse times CheckInfo.ObsTime := NOW - PeriodData.Rise; CheckInfo.ExpTime := PulseWidthHigh; PulseTest := TRUE; ELSE PulseTest := FALSE; END IF; IF PulseTest AND CheckEnabled THEN -- Verify Pulse Width [ignore 1st edge] IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN IF (XOn) THEN Violation := 'X'; END IF; IF (MsgOn) THEN CheckInfo.Violation := TRUE; CheckInfo.CheckKind := PulseWidCheck; CheckInfo.DetTime := NOW - TestDly; CheckInfo.State := PeriodData.Last; ReportViolation (TestSignalName, "", HeaderMsg, CheckInfo, MsgSeverity ); END IF; -- MsgOn END IF; END IF; IF PeriodTest AND CheckEnabled THEN -- Verify the Period [ignore 1st edge] CheckInfo.ObsTime := PeriodObs; CheckInfo.ExpTime := Period; IF ( CheckInfo.ObsTime < CheckInfo.ExpTime ) THEN IF (XOn) THEN Violation := 'X'; END IF; IF (MsgOn) THEN CheckInfo.Violation := TRUE; CheckInfo.CheckKind := PeriodCheck; CheckInfo.DetTime := NOW - TestDly; CheckInfo.State := TestValue; ReportViolation (TestSignalName, "", HeaderMsg, CheckInfo, MsgSeverity ); END IF; -- MsgOn END IF; END IF; PeriodData.Last := TestValue; END VitalPeriodPulseCheck; PROCEDURE ReportSkewViolation ( CONSTANT Signal1Name : IN STRING := ""; CONSTANT Signal2Name : IN STRING := ""; CONSTANT ExpectedTime : IN TIME; CONSTANT OccuranceTime : IN TIME; CONSTANT HeaderMsg : IN STRING; CON
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -