pub fn infer_structural_clock<'d>(
block: &Symbol<'d>,
) -> Result<Option<TimingControl<'d>>, AnalysisError>Expand description
LRM 16.14.6 (a)/(b)/(c) for a procedure that slang’s analysis does not list:
one inside a procedural checker instance’s body (17.3). slang analyzes such
a body as a side effect of analyzing the enclosing procedure and files no scope
result for it, so infer_procedural_clock has no AnalyzedProcedure to ask
(and an AnalyzedAssertion::procedure handle into that scope is not safe to
follow: slang keeps the procedures in a std::vector and the assertions point
into it before it has finished growing). This is therefore the one place the
three conditions are decided here rather than by slang, mirroring
DFAResults::inferClock for the shapes a checker’s procedure can take:
- (a) no blocking timing control: a delay,
wait, or a timing control on anything but a statement makes the answerNone(the last is an error here instead, sincea = #1 bis not modelled by this walk); - (b) exactly one event control (a nonblocking assignment’s does not count);
- (c) exactly one
edge expr [iff cond]event of it none of whose terms is referenced anywhere else in the procedure other than inside assertion statements or as a clocking event.
An event control that is not of the edge expr form (an event variable, a
clocking block name, @*) is an error rather than a guess, since that path
would need the event-variable and clocking-block rules of (c) as well.
Unlike infer_procedural_clock, a None means only that the procedure
itself yields no clock; the default clocking (16.15) is for the caller.