I'm coming from a Verilog-95 background, and I'm trying to figure out what Verilog-95 hoops I don't have to jump through anymore.
The obvious way to write a flip flop with async set and reset in Verilog-95 is:
always @(posedge clk or negedge resetb or negedge setb) begin
if (!resetb) q <= 0;
else if (!setb) q <= 1;
else q <= d;
end
This works in synthesis. But, this doesn't work in simulation if we ever assert both resetb and setb, and then de-assert resetb before de-asserting setb, since there's no posedge trigger for either of those signals. We need to add the following (which varies depending on your synthesis tool), to get simulation to match synthesis:
// synopsys translate_off
always @(resetb or setb)
if (resetb && !setb) force q = 1;
else release q;
// synopsys translate_on
Is there a SystemVerilog construct that will let you do this without this extra junk? Better yet, is there a straightforward way to do it in Verilog-95?
Flip-flops with multiple asynchronous controls are best avoided. The timing checks necessary to ensure they function properly are complex and easy to mess up. If you really need to use them, then it's probably best to instantiate them by hand where needed. If you let your synthesis tool infer them, it may use them in places you don't intend, which increases the risk that the timing checks don't get done properly.
One final aside, there is a similar simulation-synthesis mismatch issue with all asynchronous flops, if the active edge of reset is at time zero and is simulated before the flop is initialized to x, and the clock isn't running in reset. I believe some simulators have special cases to ensure the logic is not initialized in this order.
That said, I had luck moving the priority logic outside the sequential
always
block. Note I'm using active-high signals for simplicity.