Common Mistakes in Verilog
1. Missing begin end
e.g
always @(w0, w1, s)------------------------------------begin-end after always
if ( s == 1 )
f = w1; f = w0;
2. Missing semi-colon, {}
3. Accidental assignment
always @(w0, w1, s)
if ( s = 1 )------------------------- s==1 , should have used logical operator
f = w1; f = w0;
4. Incomplete Sensitivity list
always @(x)--------- y not included, the change of y will not reflect on s,c
begin
s = x ∧ y;
c = x & y;
end
5. Variables versus Nets
Only nets can serve as the targets of continuous assignment statements. Variables assigned values
inside an always block have to be of type reg or integer. It is not possible to make an assignment to a
signal both inside an always block and via a continuous assignment statement.
6. Assignments in multiple always blocks
Always blocks are concurrent with one another. So a variable should not be
assigned value in more than one always blocks
7. Blocking versus Non-blocking Assignments
When describing a combinational circuit in an always construct, it is best to use only blocking
assignments . For sequential circuits, non-blocking assignments should be used (see Section A.14.5).
Blocking and non-blocking assignments should not be mixed in a single always block.
8. Module Instantiation
A defparam statement must reference the instance name of a module, but not just the subcircuit’s
module name. The code
bit_count cbits (T, C);
defparam bit_count.n = 8, bit_count.logn = 3;
is illegal, while the code
bit_count cbits (T, C);
defparam cbits.n = 8, cbits.logn = 3;
is syntactically correct.
9. Label, net, variable names---- illegal to use keywords
10. Labeled Begin-End Blocks
It is legal to define a variable or parameter inside a begin-end block, but only if the block has
a label. The code
always @(X)
begin
integer k; Count = 0;
for (k = 0; k < n; k = k+1) Count = Count + X[k];
end
is illegal, while the code
always @(X)
begin: label
integer k; Count = 0;
for (k = 0; k < n; k = k+1) Count = Count + X[k];
end
is syntactically correct.
11. Implied Memory
As shown in Section A.14.1, implied memory is used to describe storage elements.
Care must be taken to avoid unintentional implied memory. The code
always @(LA)
if (LA == 1)
EA = 1;
results in implied memory for the EA variable. If this is not desired, then the code can
be fixed by writing
always @(LA)
if (LA == 1)
EA = 1;
else
EA = 0;
Implied memory also applies to case statements. The code
always @(W) case (W)
2’b01: EA = 1;
2’b10: EB = 1;
endcase
does not specify the value of the EA variable when W is not equal to 01, and it does
not specify the value of EB when W is not equal to 10. To avoid having implied
memory for both EA and EB, these variables should be assigned default values, as in
the code
always @(W)
begin
EA = 0; EB = 0;
case (W)
2’b01: EA = 1;
2’b10: EB = 1;
endcase
end