always_comb, always_ff & Better Procedural Code

Intent-checking always blocks, unique/priority case, C-style loops and operators, '0 and '1 fills.

Verilog's always block is used for flip-flops, combinational logic and latches alike, so tools cannot tell what you meant. SystemVerilog adds always_comb, always_ff and always_latch: the same hardware, but tools check that the code really describes what the keyword promises.

Intent-specific always blocks

idx = '0 fills idx with zeros at whatever width it has, with no need to write 4'd0.

for (int k = 0; ...; k++) declares the loop variable inside the loop.

The last set bit found wins, because later loop iterations overwrite earlier ones.

unique and priority

always @(*) begin y = a & b; end always_comb begin y = a & b; end

Both work, but always_comb lets the tools check for latches and multiple drivers, and evaluates at time zero.

always_ff @(posedge clk) begin if (en) q = d; // blocking end always_ff @(posedge clk) begin if (en) q <= d; end

The blocking/non-blocking rules from Verilog still apply: non-blocking in always_ff, blocking in always_comb.

Name three checks always_comb enables that always @(*) does not.

Tools warn if the block infers a latch; it is an error for another process to write its variables; and it runs at time zero even if no input changes. Its sensitivity list also includes signals read inside called functions.

What do '0, '1, 'x and 'z mean?

Fill literals: every bit of the target is set to 0, 1, X or Z, whatever its width.