Few examples on Verilog assignment
If you refer to v2005 LRM, there are 2 interesting definitions, an extract of which is pasted below –
6.1 Continuous assignments
Drives values onto nets, both vector and scalar; this assignment shall occur whenever the value of the right-hand side changes. An example is below:
assign a = b;
9.2 Procedural assignments
Are used for updating reg, integer, time, real, realtime, and memory data types. Procedural assignments update the value of variables under the control of the procedural flow constructs that surround them. An example is below:
always @(b) a = b;
Functionally, both of the above examples produce similar outputs for the same stimulus. One of them continuously evaluates the RHS and applies any updates to LHS. The other one looks for an event on the sensitivity list, and executes the assignment from RHS to LHS immediately. That said, let’s not spend much time on these. However, I am showing you another interesting definition from the same LRM — pasted below:
9.3.1 The assign and deassign procedural statements
The assign procedural continuous assignment statement shall override all procedural assignments to a variable. The deassign procedural statement shall end a procedural continuous assignment to a variable.
Now what does this mean? How is it modelled? See the example below, where d is a reg datatype:
1. always @(g) begin
2. if (g == 1’b1) assign d = a;
3. else deassign d;
4. end
The explanation to this code is very simple!
· Line (1) says — start evaluating the code-block whenever ‘g’ changes
· Line (2) says — if (g) is true (when line-1 detects a change), assign ‘a’ to ‘d’ like a continuous assignment. That is, as long as ‘g’ is true, evaluate ‘d’ continuously and keep updating ‘a’.
· Line (3) says — if (g) is not true, deassign ‘d’. That is, since ‘d’ is ‘a’ reg datatype, it just retains that last value it was driven with whenever g is false
Well, that’s special! ‘d’ acts like a net with continuous assignment in line (2), but acts like a reg in line (3). Specifically, in this example, if ‘g’ is true, ‘a’ is continuously evaluated and assigned to ‘d’. This happens even though ‘a’ is NOT in the sensitivity list of the always block! If ‘g’ is false, any new change on ‘a’ does not affect the value of ‘d’.
Like to verify what I said? It’s a good practice and I strongly encourage you to do so. Please use the test stimulus given below to check it for yourself. In all likelihood, you will see a waveform similar to the one that I have provided towards the end of this write-up.
initial begin // CONTROLLING THE VALUE OF a
a = 0;
#15 a = 1;
#10 a = 0;
#5 a = 1; #5 a = 0;
#5 a = 1; #5 a = 0;
#5 a = 1; #5 a = 0;
#5 a = 1; #5 a = 0;
#5 a = 1; #5 a = 0;
#5 a = 1; #5 a = 0;
#15 $finish;
end
initial begin // CONTROLLING THE VALUE OF g
g = 0; #10 g = 1;
#15 g = 0;
#20 g = 1;
#20 g = 0;
#15 g = 1;
end
Note that if we call ‘g’ as gate, ‘a’ as input and ‘d’ as output, this code just models an active-high latch.