More Combinational Logic
always statements can also be used to describe combinational logic behaviorally if the sensitivity list is written to respond to changes in all of the inputs and the body prescribes the output value for every possible input combination.
HDLs support blocking and nonblocking assignments in an always statement.
A group of blocking statements are evaluated in the order in which they appear in the code, just as one would expect in a standard programming language.
A gourp of nonblocking assignments are evaluated concurrently; all of the statements are evaluated before any of the signals on the left hand sides are updated.
HDL Example 4.23 defines a full adder using intermediate signals p and g to compute s and cout. It produces the same circuit as code Example 4.7, but uses always statements in place of assignment statements.
module fulladder(input logic a, b, cin,
output logic s, cout);
logic p, g;
always_comb begin
p = a ^ b; // blocking
g = a & b; // blocking
s = p ^ cin; // blocking
cout = g | (p & cin); // blocking
end
endmodulemodule fulladder(input a, b, cin,
output reg s, cout);
reg p, g;
always @(*) begin
p = a ^ b; // blocking
g = a & b; // blocking
s = p ^ cin; // blocking
cout = g | (p & cin); // blocking
end
endmoduleCode Explanation
In this case, an
@(a, b, cin)would have been equivalent to@(*). However,@(*)is better because it avoids common mistakes of missing signals in the stimulus/sensitivity list.Point 1 in SystemVerilog also applies here.
Because
pandgappear on the left hand side of an assignment in analwaysstatement, they must be declared to bereg.
Case statements
A better application of using always statement for combinational logic is a seven-segment display that takes advantage of the case statement that must appear inside an always statement.
HDL Example 4.24 uses case statements to describe a seven-segment display decoder based on its truth table.
This HDL code will synthesize into a ROM containing the 7 outputs for each of the 16 possible inputs. This utilises the property of logic using memory arrays.

A case statement implies combinational logic if all possible input combinations are defined; otherwise it implies sequential logic, because the output will keep its old value in the undefined cases.
If statements
always statements may also contain if statements. The if statement may be followed by an else statement. If all possible input combinations are handled, the statement implies combinational logic; otherwise, it produces sequential logic (like the latch in the previous section)
In SystemVerilog/Verilog, if statements must appear inside of always statements.
Truth Tables with Don't Cares
As examined previously, truth tables may include don't care's to allow more logic simplification. HDL Example 4.27 shows how to describe a priority circuit with don't cares.
Blocking and Nonblocking Assignments
The following guidelines explain when and how to use each type of assignment. If these guidelines are not followed, it is possible to write code that appears to work in simulation but synthesizes to incorrect hardware.
Use
always_ff @(posedge clk)and nonblocking assigments to model synchronous sequential logic.Use continuous assignments to model simple combinational logic.
Use
always_comband blocking assignments to model more complicated combinational logic where thealwaysstatement is helpful.Do not make assignments to the same signal in more than one
alwaysstatement or continuous assignment statement.
Use
always @ (posedge clk)and nonblocking assigments to model synchronous sequential logic.Use continuous assignments to model simple combinational logic.
Use
always @ (*)and blocking assignments to model more complicated combinational logic where thealwaysstatement is helpful.Do not make assignments to the same signal in more than one
alwaysstatement or continuous assignment statement.
Inside an always @ (posedge clk) block, it is possible to use the if/case statements, but the signals inside the if/case statements should use blocking assignment =, but always keep in mind which signal you want it to be a real register, then use nonblocking assignment <= on that signal (it can be assigned anywhere as long as it is in the always @ (posedge clk))
Last updated