|
11.3 Operators
Chapter start
Previous page
Next page
11.3 Operators
An expression uses
any of the three types of operators: unary operators, binary operators,
and a single ternary operator [Verilog
LRM 4.1]. The Verilog operators are similar to those in the C programming
language--except there is no autoincrement ( ++ ) or autodecrement (
-- ) in Verilog. Table 11.1 shows
the operators in their (increasing) order of precedence and Table 11.2
shows the unary operators. Here is an example that illustrates the use
of the Verilog operators:
TABLE 11.1 Verilog
operators (in increasing order of precedence). |
?: (conditional) [legal for
real; associates right to left (others associate left to right)] |
|| (logical or) [A smaller
operand is zero-filled from its msb (0-fill); legal for real] |
&& (logical and)[0-fill,
legal for real] |
| (bitwise or) ~| (bitwise
nor) [0-fill] |
^ (bitwise xor) ^~ ~^
(bitwise xnor, equivalence) [0-fill] |
& (bitwise and) ~&
(bitwise nand) [0-fill] |
== (logical) != (logical)
=== (case) !== (case) [0-fill, logical versions are legal for real] |
< (lt) <= (lt or equal)
> (gt) >= (gt or equal) [0-fill, all arelegal for real] |
<< (shift left) >>
(shift right) [zero fill; no -ve shifts; shift by x or z results in unknown] |
+ (addition) - (subtraction)
[if any bit is x or z for + - * / % then entire result is unknown] |
* (multiply) / (divide) %
(modulus) [integer divide truncates fraction; + - * / legal for real] |
Unary operators: ! ~ & ~& | ~| ^ ~^ ^~ + -
[see Table 11.2 for precedence] |
TABLE 11.2 Verilog
unary operators. |
Operator |
Name |
Examples |
! |
logical negation |
!123 is 'b0 [0, 1, or x for
ambiguous; legal for real] |
~ |
bitwise unary negation |
~1'b10xz is 1'b01xx |
& |
unary reduction and |
& 4'b1111 is 1'b1, &
2'bx1 is 1'bx, & 2'bz1 is 1'bx |
~& |
unary reduction nand |
~& 4'b1111 is 1'b0, ~&
2'bx1 is 1'bx |
| |
unary reduction or |
Note: |
~| |
unary reduction nor |
Reduction is performed
left (first bit) to right |
^ |
unary reduction xor |
Beware of the non-associative
reduction operators |
~^ ^~ |
unary reduction xnor |
z is treated as x for
all unary operators |
+ |
unary plus |
+2'bxz is +2'bxz [+m is the
same as m; legal for real] |
- |
unary minus |
-2'bxz is x [-m is unary
minus m; legal for real] |
module operators;
parameter A10xz = {1'b1,1'b0,1'bx,1'bz}; // Concatenation and
parameter A01010101 = {4{2'b01}}; // replication, illegal for real.
// Arithmetic operators: +, -, *, /, and modulus %
parameter A1 = (3+2) %2; // The sign of a % b is the same as sign of a.
// Logical shift operators: << (left), >> (right)
parameter A2 = 4 >> 1; parameter A4 = 1 << 2; // Note: zero fill.
// Relational operators: <, <=, >, >=
initial if (1 > 2) ;
// Logical operators: ! (negation), && (and), || (or)
parameter B0 = !12; parameter B1 = 1 && 2;
reg [2:0] A00x; initial begin A00x = 'b111; A00x = !2'bx1; end
parameter C1 = 1 || (1/0); /* This may or may not cause an
error: the short-circuit behavior of && and || is undefined. An
evaluation including && or || may stop when an expression is known
to be true or false. */
// == (logical equality), != (logical inequality)
parameter Ax = (1==1'bx); parameter Bx = (1'bx!=1'bz);
parameter D0 = (1==0); parameter D1 = (1==1);
// === case equality, !== (case inequality)
// The case operators only return true (1) or false (0).
parameter E0 = (1===1'bx); parameter E1 = 4'b01xz === 4'b01xz;
parameter F1 = (4'bxxxx === 4'bxxxx);
// Bitwise logical operators:
// ~ (negation), & (and), | (inclusive or),
// ^ (exclusive or), ~^ or ^~ (equivalence)
parameter A00 = 2'b01 & 2'b10;
// Unary logical reduction operators:
// & (and), ~& (nand), | (or), ~| (nor),
// ^ (xor), ~^ or ^~ (xnor)
parameter G1= & 4'b1111;
// Conditional expression f = a ? b : c [if (a) then f=b else f=c]
// if a=(x or z), then (bitwise) f=0 if b=c=0, f=1 if b=c=1, else f=x
reg H0, a, b, c; initial begin a=1; b=0; c=1; H0=a?b:c; end
reg[2:0] J01x, Jxxx, J01z, J011;
initial begin Jxxx = 3'bxxx; J01z = 3'b01z; J011 = 3'b011;
J01x = Jxxx ? J01z : J011; end // A bitwise result.
initial begin #1;
("A10xz=%b",A10xz," A01010101=%b",A01010101);
("A1=%0d",A1," A2=%0d",A2," A4=%0d",A4);
("B1=%b",B1," B0=%b",B0," A00x=%b",A00x);
("C1=%b",C1," Ax=%b",Ax," Bx=%b",Bx);
("D0=%b",D0," D1=%b",D1);
("E0=%b",E0," E1=%b",E1," F1=%b",F1);
("A00=%b",A00," G1=%b",G1," H0=%b",H0);
("J01x=%b",J01x); end
endmodule
A10xz=10xz A01010101=01010101
A1=1 A2=2 A4=4
B1=1 B0=0 A00x=00x
C1=1 Ax=x Bx=x
D0=0 D1=1
E0=0 E1=1 F1=1
A00=00 G1=1 H0=0
J01x=01x
11.3.1 Arithmetic
Arithmetic operations
on n-bit objects are performed modulo 2n
in Verilog,
module modulo; reg [2:0] Seven;
initial begin
#1 Seven = 7; #1 ("Before=", Seven);
#1 Seven = Seven + 1; #1 ("After =", Seven);
end
endmodule
Before=7
After =0
Arithmetic operations in Verilog
(addition, subtraction, comparison, and so on) on vectors ( reg
or wire ) are predefined (Tables 11.1
and 11.2 show which operators are legal for real
). This is a very important difference for ASIC designers from the situation
in VHDL. However, there are some subtleties with Verilog arithmetic and
negative numbers that are illustrated by the following example (based on
an example in the LRM [Verilog LRM4.1]):
module LRM_arithmetic;
integer IA, IB, IC, ID, IE; reg [15:0] RA, RB, RC;
initial begin
IA = -4'd12; RA = IA / 3; // reg is treated as unsigned.
RB = -4'd12; IB = RB / 3; //
IC = -4'd12 / 3; RC = -12 / 3; // real is treated as signed
ID = -12 / 3; IE = IA / 3; // (two's complement).
end
initial begin #1;
(" hex default");
("IA = -4'd12 = %h%d",IA,IA);
("RA = IA / 3 = %h %d",RA,RA);
("RB = -4'd12 = %h %d",RB,RB);
("IB = RB / 3 = %h%d",IB,IB);
("IC = -4'd12 / 3 = %h%d",IC,IC);
("RC = -12 / 3 = %h %d",RC,RC);
("ID = -12 / 3 = %h%d",ID,ID);
("IE = IA / 3 = %h%d",IE,IE);
end
endmodule
hex default
IA = -4'd12 = fffffff4 -12
RA = IA / 3 = fffc 65532
RB = -4'd12 = fff4 65524
IB = RB / 3 = 00005551 21841
IC = -4'd12 / 3 = 55555551 1431655761
RC = -12 / 3 = fffc 65532
ID = -12 / 3 = fffffffc -4
IE = IA / 3 = fffffffc -4
We might expect the results
of all these divisions to be - 4 = -12/3. For integer assignments, the results
are correctly signed ( ID and IE ). Hex fffc
(decimal 65532) is the 16-bit two's complement of - 4, so RA
and RC are also correct if we keep track of the signs ourselves.
The integer result IB is incorrect because Verilog treats RB
as an unsigned number. Verilog also treats -4'd12 as an unsigned
number in the calculation of IC . Once Verilog "loses"
a sign, it cannot get it back (see also Section 11.2.5).
Chapter start
Previous page
Next page
|
|