The code at https://www.edaplayground.com/x/D7LV is a very simple test of a F/F which has a data setup of 0ns, and a hold of 2ns, where the setup and hold are tested with a $setuphold. The F/F model is in the ‘dff’ module, and the test is in the ‘test’ module.
The F/F is tested by setting the data input to 1’b1 one delta before setting the clock input, and then holding it at 1’b1 for 2ns. The data input is set to 1’bx at all other times. The test runs for one clock cycle, and a pass message is printed if the F/F q output is 1’b1, and the $setuphold notifier does not toggle.
I’ve checked the delta timing in a list window: at 10ns, the data input is set in the first delta, and the clock input is set in the second delta. The notifier toggles in the third delta, so the $setuphold has detected an error, and the test fails (on all the major simulators, but it passes on Veriwell and GPL Cver). What’s happening is that the $setuphold is expecting the previous value of 1’bx to hold, instead of expecting the current value of 1’b1 to hold. I get exactly the same answer if I replace the $setuphold with the $hold which is commented out in the code.
Given this, how is it possible to test a cell with a zero setup? I guess the answer is that I have to delay the clock to the $setuphold by one time unit, but the LRM says nothing about this. This would also require the $setuphold implementation to have special knowledge that the current data value is not relevant, and that it should instead go back one tick. Thanks.