{"id":155,"date":"2015-10-05T09:31:16","date_gmt":"2015-10-05T16:31:16","guid":{"rendered":"http:\/\/www.verilogpro.com\/?p=155"},"modified":"2022-06-26T00:09:32","modified_gmt":"2022-06-26T07:09:32","slug":"systemverilog-always_comb-always_ff","status":"publish","type":"post","link":"https:\/\/www.verilogpro.com\/systemverilog-always_comb-always_ff\/","title":{"rendered":"SystemVerilog always_comb, always_ff. New and Improved."},"content":{"rendered":"\n

Verilog engineers will be familiar with using Verilog always<\/b> to code recurring procedures like sequential logic (if not, refer to my article Verilog Always Block for RTL Modeling<\/a>), and most will have used always @(*)<\/b> to code combinational logic. SystemVerilog defines four forms of always procedures: always, always_comb, always_ff, always_latch<\/b>. What do the three new always<\/b> procedures bring, and should you be using them? This article will attempt to answer these questions.<\/p>\n\n\n\n

Verilog always @*<\/h3>\n\n\n\n

Verilog 2001 first introduced always @*<\/b> as a shortcut to code combinational logic. The always @*<\/b> is intended to infer a complete sensitivity list for both RTL simulation and synthesis from the contents of the block, saving a designer from having to manually specify a sensitivity list to code combinational logic. However, it does not infer a complete sensitivity list when the always @*<\/b> block contains functions. Namely, it will not infer sensitivity to signals that are externally referenced in a function or a task that is called from the always<\/b> block. It will only be sensitive to the signals passed into the function or task. Here is an example that illustrates the behaviour:<\/p>\n\n\n\n

module test;\n  logic a, b, c, always_d, always_comb_d;\n\n  function logic my_func(input logic m_c);\n    my_func = a | b | m_c;\n  endfunction\n\n  always @*\n    always_d = my_func(c);\n\n  always_comb\n    always_comb_d = my_func(c);\n\n  initial begin\n    $monitor(\"@%0t: a = %d, b = %d, c = %d, always_d = %d, always_com_d = %d\", $time, a, b, c, always_d, always_comb_d);\n  end\n  \n  initial begin\n    a = 0;\n    b = 0;\n    c = 0;\n    #10 a = 1;\n    #10 b = 1;\n    #10 c = 1;\n  end\nendmodule\n<\/pre>\n\n\n\n

When the code is executed, it gives the following output. Notice that change on a, b<\/i> does not trigger the always @*<\/b> block to be reevaluated, but change on c<\/i> does.<\/p>\n\n\n\n

@0: a = 0, b = 0, c = 0, always_d = 0, always_com_d = 0\n@10: a = 1, b = 0, c = 0, always_d = 0, always_com_d = 1\n@20: a = 1, b = 1, c = 0, always_d = 0, always_com_d = 1\n@30: a = 1, b = 1, c = 1, always_d = 1, always_com_d = 1<\/pre>\n\n\n\n