That’s a frequent SystemVerilog question I’m asked. Program blocks came directly from donation of the Vera language to SystemVerilog by Synopsys , and try to mimic the scheduling semantics that a PLI application has interacting with a Verilog simulator. So coming from a Vera background, program blocks make perfect sense and do help people transitioning from Vera to SV. But looking at SV from scratch, they are just extra language baggage.
Who would have ever thought we’d be having language wars within the same language!
As far as I can tell, a program block by itself only addresses two race conditions between the testbench and DUT, both of which are covered by using a clocking block by itself.
- Erroneous use of blocking assignments for sequential logic. You have a race within your DUT regardless of the race between your testbench and DUT.
- Erroneous use of non-blocking assignments in combinational gated clock logic. You may have a race within your DUT regardless of the race between your testbench and DUT.
As a user, if you don’t understand why these create races within your DUT, you’re going to have the same races within your testbench, and there’s nothing a program block does that prevent races within your testbench. There lays the false sense of security of having a race-free testbench.