Welcome back readers :)
So far, we discussed modules and ports. Now we will see how Verilog helps in writing code in behavioural description and translates it to structural description i.e., the actual circuit.
Verilog allows us to describe the abstract behaviour of our module and the synthesis tool synthesizes the behaviour into actual hardware. There are two types of behavioural blocks in Verilog, they are initial and always.
- Behaviour declared by initialย is known as single-pass behaviourย where, which means that all the statements inside this block will execute once and once all the statements are executed then this block will terminate. On the other hand, behaviour described by alwaysย block is known as cyclic behaviourย and it will always execute when the event control expression is true.
- Before moving ahead letโs have a look at the different ways of assignment. There are two types of assignment in Verilog, they are continuous assignmentย and procedural assignment.
- For โcontinuous assignmentโย the syntax is as follows:
assignย {Y} = {expression};
ย ย Here Y should be of โnetโย data type, โnetโ data types are declared explicitly by syntax wire.
ย ย Below is an example of 3 input AND gate using continuous assignment
moduleย AND3 (Y,A,B,C);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย inputย A,B,C;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย outputย Y;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย wireย Y; ย //net declaration
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย assignย Y =ย (A &ย B &ย C);
endmodule
ย ย Letโs see one more example of a 2:1 multiplexer
moduleย MUX2to1 (Y,I_0,I_1,S);
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย inputย I_0,I_1,S;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย outputย Y;
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย wireย Y; ย //net declaration
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย assignย Y =ย (S ?ย I_1 :ย I_0);
endmodule
- "Procedural assignmentsโย are the assignments that are done inside the behavioural blocks (initial and always). Here the variable to the left (variable which is assigned) must be of typeย โregโย data type.
ย ย
ย Further there are two different kinds of procedural assignments, they are blockingย andย non-blockingย assignments.
- Blocking assignments: Operator used for blocking assignment is (=) {equal to}. In case of blocking assignment, the statements are executed sequentially in the order they are written.
- Non-blocking assignments: Operator used for non-blocking assignment is (<=) {less than equal to)}. In this case the right-hand side of the operator is computed and then they are assigned to left hand side variables.
- A general rule of thumb is to use blocking assignments when there is a sequential ordering of statements in a cyclic behaviour, i.e., in level sensitive cases (combinational logic) and use non-blocking assignments in case of modelling edge sensitive cases like synchronous concurrent register transfer or latched behaviour.
Letโs take an example to make it clearer.
In the blocking case the value of X is stored in Y and then Y+1 in Z so Z stores X+1. whereas in non-blocking case X is temporarily stored to some location say temp1 and similarly Y+1 to temp2 and then temp1 is assigned to Y and temp2 to Z so here Z stores previous value of Y added to 1.
So now we know different assignment methods letโs visit the behavioural blocks once again.
- initial block: The abstract behaviour declared by this block is also known as single-pass behaviour because all the statements are executed once and after that this block terminates. When we have a list of statements then we use keywords begin . . . endย or fork . . . joinย to enclose all the statements of the block.
- always block: The abstract behaviour declared by this block is also known as cyclic behaviour because statements are executed always whenever the event control expressionย is true. Event control operationย specifies the condition that must be true in order to kick start the always block. Itโs also known as sensitivity list. For example, posedge or negedge of a clock.
This sensitivity list can specify level-sensitive eventsย or edge-sensitive eventsย or a combination of both. However in practice designers avoid using the 3rd option as the synthesis tool is not able to translate it to actual hardware.
Comma โ,โย can also be used in place ofย โorโ.
I think itโs enough for this blog. We will continue this in the next blog.
This blog has been submitted by KRSSG, IIT-Kharagpur under the Robocraze Club Outreach Program.
Author: Anubhav Prasad