The always block is a fundamental component in Verilog. It allows you to model both combinational and sequential logic in hardware designs. This block executes a set of statements based on certain events, defined in the sensitivity list. Let’s explore the details and examples to understand its usage better.

What is an Verilog Always Block ?

An always block in Verilog is a procedural block used to execute a set of statements sequentially whenever specific conditions are met. The block is executed based on changes in the signals listed in the sensitivity list.

Syntax:

always @ (event) begin
    [statements]
end

Here, the event refers to changes in signals, and the statements inside the block get executed when these changes occur.

Alternatively:

always @ (event)
    [statement]

What is the Sensitivity List?

The sensitivity list defines the conditions under which the always block will execute. It is specified after the @ symbol inside parentheses. This list may contain one or more signals, and whenever any of these signals change, the always block gets triggered.

Example:

// The always block executes whenever the value of "a" or "b" changes
always @ (a or b) begin
    [statements]
end

What is the Verilog Always Block Used For?

Verilog always block is primarily used to model sequential or combinational logic:

  • Sequential logic: In sequential logic, like flip-flops, the block is triggered by a clock signal or reset.
  • Combinational logic: In combinational logic, the block is triggered when any input signal changes.

What Happens if There is No Sensitivity List?

Without a sensitivity list, the always block would execute continuously throughout the simulation, resulting in an infinite loop. The absence of a trigger (like a clock or signal change) can cause the simulation to hang. To prevent this, always include a proper sensitivity list.

Example of an issue without a sensitivity list:

// This block will cause an infinite loop
always clk = ~clk;

The above code will keep toggling the clock signal, causing the simulation to freeze. To fix this, introduce a delay or sensitivity list.

Corrected Example:

// Execute the block every 10 time units
always #10 clk = ~clk;

Note: Delays like #10 are not synthesizable into physical hardware, and hence, should be avoided in real designs.

Sequential Element Design Example with Verilog always block

In sequential logic, the always block is commonly used with clock and reset signals to design flip-flops. The example below shows how to design a T flip-flop.

T Flip-Flop Design

module t_ff(
    input d,
    input clk,
    input rstn,
    output reg q
);

  always @ (posedge clk or negedge rstn) begin
      if (!rstn)
          q <= 0;  // Reset the output
      else
          if (d)
              q <= ~q;  // Toggle the output
          else
              q <= q;  // Hold the output
  end
endmodule

Events at the Positive Edge of the Clock

  • At the positive edge of the clock (posedge clk):
  • The always block checks the state of the reset (rstn).
  • If rstn is 0 (active-low reset), the output q is reset to 0.
  • If rstn is 1, the output follows the default behavior:
    • If d is 1, q toggles (inverts).
    • If d is 0, q holds its previous value.

What Happens at the Negative Edge of Reset on verilog always block?

At the negative edge of reset (negedge rstn), the always block checks if the reset signal rstn is low. If rstn is low (0), the output q is reset to 0.

The rstn signal is active-low, so the reset action happens when rstn is 0.


Combinational Element Design Example

Verilog’s always block is also used to design combinational logic. Here’s an example where the always block triggers based on changes in input signals.

Combinational Logic Example

module combo (
    input a, b, c, d,
    output reg o
);

always @ (a or b or c or d) begin
    o <= ~((a & b) | (c ^ d));  // Logic operation
end

endmodule

In this example, the output o depends on the combination of the inputs a, b, c, and d. The output changes whenever any of the inputs change.

Synthesis Considerations for Verilog always block

In hardware design, always blocks should follow specific templates to be synthesis-friendly. Improper use of always blocks can lead to issues like unintended latches or simulation mismatches.

Recommended Templates for Synthesis

  1. Combinational Logic:
   always @ (all_inputs) begin
       // Combinational logic
   end
  1. Avoiding Latches (Use Else Clause):
   always @ (all_inputs) begin
       if (enable) begin
           // Latch value assignments
       end
   end
  1. Sequential Logic (Clocked Behavior):
   always @ (posedge clk) begin
       // Behavior on the positive edge of the clock
   end
  1. Reset with Clock (Clock and Async Reset):
   always @ (posedge clk or negedge resetn) begin
       if (!resetn) begin
           // Behavior during reset
       end else begin
           // Behavior when not in reset
       end
   end

Conclusion

The always block in Verilog is a crucial tool for designing both combinational and sequential circuits. By understanding the syntax, sensitivity list, and usage patterns, you can effectively model complex hardware behavior. Always remember to include the sensitivity list to avoid infinite loops and ensure correct simulation results.

Scroll to Top