Ok, this might be a silly question but we often assume that a signal is clocked in a specific clock domain and therefore do not pay too much attention to make sure that it’s the case. Especially when you deal with external IPs or VIPs and you want to make sure no extra synchronization is needed.
I unfortunately haven’t found anything similar, except maybe from an answer from Ben Cohen to a similar thread. The issue I have with that approach is that my simulation is purely RTL so I do not have the chance to observe a setup/hold time and therefore the recommended $setuphold timing check is not a valid option (since both setup and hold times will be 1 entire clock cycle).
So I came up with the following:
// Macro: `check_clk_domain
// to make sure a signal is in a specific clock domain
`define check_clk_domain(clk, signal, msg) \
always @(signal) begin \
time signal_time; \
time delta_time; \
time clk_per; \
signal_time = $realtime; \
@(posedge clk); \
delta_time = $realtime - signal_time; \
@(posedge clk); \
clk_per = $realtime - signal_time - delta_time; \
assert(delta_time % clk_per == 0) else \
`sva_error("CLKDOM", $sformatf("%s: delta found = %t", msg, delta_time)); \
end
So what I’m trying to do here is to capture the signal time of arrival and measure it compared to the clock one. delta_time should normally be 0 since all blocking assignments should execute in 0 delay but I’ve noticed that when signal is a bus and multiple bits are changing at the same time, it looks like the order of execution changes, screwing everything up. That’s the reason why I added an extra @(posedge clk to measure the period and make sure we have our signal changing on a multiple of the clk.
Since I consider this code rather ugly, I’d tend to say that it will not work consistently (and indeed it doesn’t with transitions from X to value before the reset is deasserted).
Any idea on how to improve on this or provide more indication on how to achieve my goal?
Thanks a lot,
Al