I wrote here that
It’s not uncommon for the right-hand side of a continuous assignment statement to be a function call, or to contain a function call. If the function depends on a global net or variable, then it’s more accurate to use always_comb, because it “is sensitive to changes within the contents of a function”.
For example,
module test(input in, output logic out1, out2); function f(); return in; endfunction assign out1 = f(); always_comb out2 = f(); initial begin #1 $display(out1, , out2); force in = 1'b1; #1 $display(out1, , out2); force in = 1'b0; #1 $display(out1, , out2); end endmodule
Additionally, if you want to be warned about latches, use always_comb instead of assign. For example, the following Verilog uses latched logic
module test(input in0, in1, sel_in, output out0, out1, sel_out); reg side0, side1; assign sel_out = f(sel_in); assign {out0, out1} = {side0, side1}; function automatic f(input sel_in); begin case (sel_in) 1'b0: side0 = in0; 1'b1: side1 = in1; endcase f = sel_in; end endfunction initial begin force in0 = 1'b1; force in1 = 1'b0; force sel_in = 1'b0; #1 $displayb({out0, out1, sel_out}); force in0 = 1'b0; force in1 = 1'b1; force sel_in = 1'b1; #1 $displayb({out0, out1, sel_out}); end endmodule
But rewriting with a SystemVerilog always_comb will cause a warning to be issued
module test(input in0, in1, sel_in, output out0, out1, sel_out); reg side0, side1; logic temp; assign sel_out = temp; always_comb begin temp = f(sel_in); end assign {out0, out1} = {side0, side1}; function automatic f(input sel_in); begin case (sel_in) 1'b0: side0 = in0; 1'b1: side1 = in1; endcase f = sel_in; end endfunction initial begin force in0 = 1'b1; force in1 = 1'b0; force sel_in = 1'b0; #1 $displayb({out0, out1, sel_out}); force in0 = 1'b0; force in1 = 1'b1; force sel_in = 1'b1; #1 $displayb({out0, out1, sel_out}); end endmodule
Or, if you really intend to use latched logic, then you can indicate that clearly by rewriting with always_latch instead.
the hardware modelled by the synthesizer should functionally be the same regardless if we use always_comb or assign ,
would you think that is a correct or complete statement….
BTW I like the topic you have raised in this blog 🙂
thanks
LikeLike
Yes, gate-level simulations of the synthesized results should be the same if derived from either style of RTL. But with assign, the RTL-level simulation is less likely to match the gate-level simulation.
LikeLike
Linked to by here.
LikeLike