Verilog Always Block
In Verilog, the always block is one of the procedural blocks. Statements inside an always block are executed sequentially.
An always block always executes, unlike initial blocks that execute only once at the beginning of the simulation. The always block should have a sensitive list or a delay associated with it
The sensitive list is the one that tells the always block when to execute the block of code.
Syntax
The Verilog always block the following syntax
Examples
The symbol @ after reserved word always, indicates that the block will be triggered at the condition in parenthesis after symbol @.
In the above example, we describe a 2:1 mux, with input x and y. The sel is the select input, and m is the mux output.
In any combinational logic, output changes whenever input changes. When this theory is applied to always blocks, then the code inside always blocks needs to be executed whenever the input or output variables change.
NOTE: It can drive reg and integer data types but cannot drive wire data types.
There are two types of sensitive list in the Verilog, such as:
- Level sensitive (for combinational circuits).
- Edge sensitive (for flip-flops).
The code below is the same 2:1 mux, but the output m is now a flip-flop output.
NOTE: The always block is executed at some particular event. A sensitivity list defines the event.
Sensitivity List
A sensitivity list is an expression that defines when the always block executed, and it is specified after the @ operator within the parentheses ( ). This list may contain either one or a group of signals whose value change will execute the always block.
In the code shown below, all statements inside the always block executed whenever the value of signals x or y change.
Need of Sensitivity List
The always block repeats continuously throughout a simulation. The sensitivity list brings a certain sense of timing, i.e., whenever any signal in the sensitivity list changes, the always block is triggered.
If there are no timing control statements within an always block, the simulation will hang because of a zero-delay infinite loop.
For example, always block attempts to invert the value of the signal clk. The statement is executed after every 0-time units. Hence, it executes forever because of the absence of a delay in the statement.
If the sensitivity list is empty, there should be some other form of time delay. Simulation time is advanced by a delay statement within the always construct.
Now, the clock inversion is done after every 10-time units. That’s why the real Verilog design code always requires a sensitivity list.
NOTE: Explicit delays are not synthesizable into logic gates.
Uses of always block
An always block can be used to realize combinational or sequential elements. A sequential element like flip flop becomes active when it is provided with a clock and reset.
Similarly, a combinational block becomes active when one of its input values change. These hardware blocks are all working concurrently independently of each other. The connection between each is what determines the flow of data.
An always block is made as a continuous process that gets triggered and performs some action when a signal within the sensitivity list becomes active.
In the following example, all statements within the always block executed at every positive edge of the signal clk
Sequential Element Design
The below code defines a module called tff that accepts a data input, clock, and active-low reset. Here, the always block is triggered either at the positive edge of the clk or the negative edge of rstn.
1. The positive edge of the clock
The following events happen at the positive edge of the clock and are repeated for all positive edge of the clock.
Step 1: First, if statement checks the value of active-low reset rstn.
- If rstn is zero, then output q should be reset to the default value of 0.
- If rstn is one, then it means reset is not applied and should follow default behavior.
Step 2: If the previous step is false, then
- Check the value of d, and if it is found to be one, then invert the value of q.
- If d is 0, then maintain value of q.
2. Negative edge of reset
The following events happen at the negative edge of rstn.
Step 1: First, if statement checks the value of active-low reset rstn. At the negative edge of the signal, its value is 0.
- If the value of rstn is 0, then it means reset is applied, and output should be reset to the default value of 0.
- And if the value of rstn is 1, then it is not considered because the current event is a negative edge of the rstn.
Combinational Element Design
An always block can also be used in the design of combinational blocks.
For example, the digital circuit below represents three different logic gates that provide a specific output at signal o.
The code shown below is a module with four input ports and a single output port called o. The always block is triggered whenever any of the signals in the sensitivity list changes in value.
The output signal is declared as type reg in the module port list because it is used in a procedural block. All signals used in a procedural block should be declared as type reg.
The signal o becomes 1 whenever the combinational expression on the RHS becomes true. Similarly, o becomes 0 when RHS is false.