📄 vital_timing_body.vhdl
字号:
CONSTANT Paths : IN VitalPathArray01Type; CONSTANT DefaultDelay : IN VitalDelayType01 ) RETURN TIME IS VARIABLE TmpDelay : TIME; VARIABLE InputAge : TIME := TIME'HIGH; VARIABLE PropDelay : TIME := TIME'HIGH; BEGIN -- for each delay path FOR i IN Paths'RANGE LOOP -- ignore the delay path if it is not enabled NEXT WHEN NOT Paths(i).PathCondition; -- ignore the delay path if a more recent input event has been seen NEXT WHEN Paths(i).InputChangeTime > InputAge; -- This is the most recent input change (so far) -- Get the transition dependent delay TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay); -- If other inputs changed at the same time, -- then use the minimum of their propagation delays, -- else use the propagation delay from this input. IF Paths(i).InputChangeTime < InputAge THEN PropDelay := TmpDelay; ELSE -- Simultaneous inputs change IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF; end if; InputAge := Paths(i).InputChangeTime; END LOOP; -- If there were no paths (with an enabled condition), -- use the default the delay IF (PropDelay = TIME'HIGH ) THEN PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); -- If the time since the most recent input event is greater than the -- propagation delay from that input then -- use the default the delay ELSIF (InputAge > PropDelay) THEN PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); -- Adjust the propagation delay by the time since the -- the input event occurred (Usually 0 ns). ELSE PropDelay := PropDelay - InputAge; END IF; RETURN PropDelay; END; FUNCTION VitalSelectPathDelay ( CONSTANT NewValue : IN std_logic; CONSTANT OldValue : IN std_logic; CONSTANT OutSignalName : IN string; CONSTANT Paths : IN VitalPathArray01ZType; CONSTANT DefaultDelay : IN VitalDelayType01Z ) RETURN TIME IS VARIABLE TmpDelay : TIME; VARIABLE InputAge : TIME := TIME'HIGH; VARIABLE PropDelay : TIME := TIME'HIGH; BEGIN -- for each delay path FOR i IN Paths'RANGE LOOP -- ignore the delay path if it is not enabled NEXT WHEN NOT Paths(i).PathCondition; -- ignore the delay path if a more recent input event has been seen NEXT WHEN Paths(i).InputChangeTime > InputAge; -- This is the most recent input change (so far) -- Get the transition dependent delay TmpDelay := VitalCalcDelay(NewValue, OldValue, Paths(i).PathDelay); -- If other inputs changed at the same time, -- then use the minimum of their propagation delays, -- else use the propagation delay from this input. IF Paths(i).InputChangeTime < InputAge THEN PropDelay := TmpDelay; ELSE -- Simultaneous inputs change IF TmpDelay < PropDelay THEN PropDelay := TmpDelay; END IF; end if; InputAge := Paths(i).InputChangeTime; END LOOP; -- If there were no paths (with an enabled condition), -- use the default the delay IF (PropDelay = TIME'HIGH ) THEN PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); -- If the time since the most recent input event is greater than the -- propagation delay from that input then -- use the default the delay ELSIF (InputAge > PropDelay) THEN PropDelay := VitalCalcDelay(NewValue, OldValue, DefaultDelay); -- Adjust the propagation delay by the time since the -- the input event occurred (Usually 0 ns). ELSE PropDelay := PropDelay - InputAge; END IF; RETURN PropDelay; END; --------------------------------------------------------------------------- --------------------------------------------------------------------------- -- Glitch Handlers --------------------------------------------------------------------------- --------------------------------------------------------------------------- PROCEDURE ReportGlitch ( CONSTANT GlitchRoutine : IN STRING; CONSTANT OutSignalName : IN STRING; CONSTANT PreemptedTime : IN TIME; CONSTANT PreemptedValue : IN std_ulogic; CONSTANT NewTime : IN TIME; CONSTANT NewValue : IN std_ulogic; CONSTANT Index : IN INTEGER := 0; CONSTANT IsArraySignal : IN BOOLEAN := FALSE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS VARIABLE StrPtr1, StrPtr2, StrPtr3, StrPtr4, StrPtr5 : LINE; BEGIN Write (StrPtr1, PreemptedTime ); Write (StrPtr2, NewTime); Write (StrPtr3, LogicCvtTable(PreemptedValue)); Write (StrPtr4, LogicCvtTable(NewValue)); IF IsArraySignal THEN Write (StrPtr5, STRING'( "(" ) ); Write (StrPtr5, Index); Write (StrPtr5, STRING'( ")" ) ); ELSE Write (StrPtr5, STRING'( " " ) ); END IF; -- Issue Report only if Preempted value has not been -- removed from event queue ASSERT PreemptedTime > NewTime REPORT GlitchRoutine & ": GLITCH Detected on port " & OutSignalName & StrPtr5.ALL & "; Preempted Future Value := " & StrPtr3.ALL & " @ " & StrPtr1.ALL & "; Newly Scheduled Value := " & StrPtr4.ALL & " @ " & StrPtr2.ALL & ";" SEVERITY MsgSeverity; DEALLOCATE(StrPtr1); DEALLOCATE(StrPtr2); DEALLOCATE(StrPtr3); DEALLOCATE(StrPtr4); DEALLOCATE(StrPtr5); RETURN; END ReportGlitch; --------------------------------------------------------------------------- PROCEDURE VitalGlitch ( SIGNAL OutSignal : OUT std_logic; VARIABLE GlitchData : INOUT VitalGlitchDataType; CONSTANT OutSignalName : IN string; CONSTANT NewValue : IN std_logic; CONSTANT NewDelay : IN TIME := 0 ns; CONSTANT Mode : IN VitalGlitchKindType := OnEvent; CONSTANT XOn : IN BOOLEAN := TRUE; CONSTANT MsgOn : IN BOOLEAN := FALSE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS --------------------------------------------------------------------------- VARIABLE NewGlitch : BOOLEAN := TRUE; VARIABLE dly : TIME := NewDelay; BEGIN -- If nothing to schedule, just return IF NewDelay < 0 ns THEN IF (NewValue /= GlitchData.SchedValue) THEN VitalError ( "VitalGlitch", ErrNegDel, OutSignalName ); END IF; RETURN; END IF; -- If simple signal assignment -- perform the signal assignment IF ( Mode = VitalInertial) THEN OutSignal <= NewValue AFTER dly; ELSIF ( Mode = VitalTransport ) THEN OutSignal <= TRANSPORT NewValue AFTER dly; ELSE -- Glitch Processing --- -- If nothing currently scheduled IF GlitchData.SchedTime <= NOW THEN -- Note: NewValue is always /= OldValue when called from VPPD IF (NewValue = GlitchData.SchedValue) THEN RETURN; END IF; -- No new glitch, save time for possable future glitch NewGlitch := FALSE; GlitchData.GlitchTime := NOW+dly; -- New value earlier than the earliest previous value scheduled ELSIF (NOW+dly <= GlitchData.GlitchTime) AND (NOW+dly <= GlitchData.SchedTime) THEN -- No new glitch, save time for possible future glitch NewGlitch := FALSE; GlitchData.GlitchTime := NOW+dly; -- Transaction currently scheduled - if glitch already happened ELSIF GlitchData.GlitchTime <= NOW THEN IF (GlitchData.SchedValue = NewValue) THEN dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); END IF; NewGlitch := FALSE; -- Transaction currently scheduled (no glitch if same value) ELSIF (GlitchData.SchedValue = NewValue) AND (GlitchData.SchedTime = GlitchData.GlitchTime) THEN -- revise scheduled output time if new delay is sooner dly := Minimum( GlitchData.SchedTime-NOW, NewDelay ); -- No new glitch, save time for possable future glitch NewGlitch := FALSE; GlitchData.GlitchTime := NOW+dly; -- Transaction currently scheduled represents a glitch ELSE -- A new glitch has been detected NewGlitch := TRUE; END IF; IF NewGlitch THEN -- If messages requested, report the glitch IF MsgOn THEN ReportGlitch ("VitalGlitch", OutSignalName, GlitchData.GlitchTime, GlitchData.SchedValue, (dly + NOW), NewValue, MsgSeverity=>MsgSeverity ); END IF; -- Force immediate glitch for "OnDetect" mode. IF (Mode = OnDetect) THEN GlitchData.GlitchTime := NOW; END IF; -- If 'X' generation is requested, schedule the new value -- preceeded by a glitch pulse. -- Otherwise just schedule the new value (inertial mode). IF XOn THEN OutSignal <= 'X' AFTER GlitchData.GlitchTime-NOW; OutSignal <= TRANSPORT NewValue AFTER dly; ELSE OutSignal <= NewValue AFTER dly; END IF; -- If there no new glitch was detected, just schedule the new value. ELSE OutSignal <= NewValue AFTER dly; END IF; END IF; -- Record the new value and time just scheduled. GlitchData.SchedValue := NewValue; GlitchData.SchedTime := NOW+dly; RETURN; END; --------------------------------------------------------------------------- PROCEDURE VitalPathDelay ( SIGNAL OutSignal : OUT std_logic; VARIABLE GlitchData : INOUT VitalGlitchDataType; CONSTANT OutSignalName : IN string; CONSTANT OutTemp : IN std_logic; CONSTANT Paths : IN VitalPathArrayType; CONSTANT DefaultDelay : IN VitalDelayType := VitalZeroDelay; CONSTANT Mode : IN VitalGlitchKindType := OnEvent; CONSTANT XOn : IN BOOLEAN := TRUE; CONSTANT MsgOn : IN BOOLEAN := TRUE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS VARIABLE PropDelay : TIME; BEGIN -- Check if the new value to be scheduled is different than the -- previously scheduled value IF (GlitchData.SchedTime <= NOW) AND (GlitchData.SchedValue = OutTemp) THEN RETURN; END IF; -- Evaluate propagation delay paths PropDelay := VitalSelectPathDelay (OutTemp, GlitchData.LastValue, OutSignalName, Paths, DefaultDelay); GlitchData.LastValue := OutTemp; -- Schedule the output transactions - including glitch handling VitalGlitch (OutSignal, GlitchData, OutSignalName, OutTemp, PropDelay, Mode, XOn, MsgOn, MsgSeverity ); END VitalPathDelay; PROCEDURE VitalPathDelay01 ( SIGNAL OutSignal : OUT std_logic; VARIABLE GlitchData : INOUT VitalGlitchDataType; CONSTANT OutSignalName : IN string; CONSTANT OutTemp : IN std_logic; CONSTANT Paths : IN VitalPathArray01Type; CONSTANT DefaultDelay : IN VitalDelayType01 := VitalZeroDelay01; CONSTANT Mode : IN VitalGlitchKindType := OnEvent; CONSTANT XOn : IN BOOLEAN := TRUE; CONSTANT MsgOn : IN BOOLEAN := TRUE; CONSTANT MsgSeverity : IN SEVERITY_LEVEL := WARNING ) IS VARIABLE PropDelay : TIME; BEGIN -- Check if the new value to be scheduled is different than the -- previously scheduled value IF (GlitchData.SchedTime <= NOW) AND (GlitchData.SchedValue = OutTemp) THEN RETURN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -