Hi Ben,
Wanted to check with you on 2 quick changes
(1) As the task t() should be called only when ‘a’ is deasserted, shouldn’t we write $fell(a) ?
always@(posedge clk) begin
if( $fell(a) ) // Infers clocking event from procedural block
t(); // Call task 't' only when $fell(a) is true
endtask
(2) Within the task, shouldn’t we write $rose(a,@(posedge clk)) instead of @(posedge clk) ?
@(posedge clk) would unexpectedly unblock for 0 → X or 0 → Z transition whereas
$rose(a,@(posedge clk) ) would be true only when there 0/X/Z to 1 transition
task automatic t();
int count,pass; // Default value of 0
realtime vnow = $realtime; // Used in 'alow_2_ahigh'
realtime vend = 0; // Will be at default incase 'b' doesn't transition at all
fork
begin
wait( $rose(a,@(posedge clk) ); // Replaced @(posedge a) !!
end
begin
forever begin
@(b) count++;
vend = $realtime();
end
end
join_any;
disable fork; // Added
if( count > 0 ) // True if 'b' toggled at least once
// Check that 'b' toggled 20 times and last toggle of 'b' was at least 20ns prior to $rose(a)
am_ab: assert( ($realtime-vend >= 20ns) && count ==20);
else
$error("Signal b did not toggle between $fell(a) & $rose(a)");
// Check that 'a' was de-asserted for 100ns
alow_2_ahigh: assert($realtime-vnow == 100ns);
endtask