Expressions, Operators, and Operands
Expressions, Operators, and Operands
6.3.1 Expressions
Expressions are constructs that combine operators and operands to produce a result.
6.3.2 Operands
Operands can be any one of the data types defined in Section 3.2, Data Types. Some
constructs will take only certain types of operands. Operands can be constants, integers,
real numbers, nets, registers, times, bit-select (one bit of vector net or a vector register),
part-select (selected bits of the vector net or register vector), and memories or function
calls (functions are discussed later).
real a, b, c;
c = a - b; //a and b are real operands
reg ret_value;
ret_value = calculate_parity(A, B);//calculate_parity is a
//function type operand
6.3.3 Operators
Operators act on the operands to produce desired results. Verilog provides various types
of operators. Operator types are discussed in detail in Section 6.4, Operator Types.
Verilog provides many different operator types. Operators can be arithmetic, logical,
relational, equality, bitwise, reduction, shift, concatenation, or conditional. Some of these
operators are similar to the operators used in the C programming language. Each operator
type is denoted by a symbol. Table 6-1 shows the complete listing of operator symbols
classified by category.
/ divide two
+ add two
Arithmetic
- subtract two
% modulus two
|| logical or two
> greater than two
!= inequality two
Equality
=== case equality two
103
~ bitwise negation one
| reduction or one
Reduction
~| reduction nor one
Binary operators
Binary arithmetic operators are multiply (*), divide (/), add (+), subtract (-), power (**),
and modulus (%). Binary operators take two operands.
104
A = 4'b0011; B = 4'b0100; // A and B are register vectors
D = 6; E = 4; F=2// D and E are integers
If any operand bit has a value x, then the result of the entire expression is x. This seems
intuitive because if an operand value is not known precisely, the result should be an
unknown.
in1 = 4'b101x;
in2 = 4'b1010;
sum = in1 + in2; // sum will be evaluated to the value 4'bx
Modulus operators produce the remainder from the division of two numbers. They
operate similarly to the modulus operator in the C programming language.
13 % 3 // Evaluates to 1
16 % 4 // Evaluates to 0
-7 % 2 // Evaluates to -1, takes sign of the first operand
7 % -2 // Evaluates to +1, takes sign of the first operand
Unary operators
The operators + and - can also work as unary operators. They are used to specify the
positive or negative sign of the operand. Unary + or ? operators have higher precedence
than the binary + or ? operators.
-4 // Negative 4
+5 // Positive 5
105
6.4.2 Logical Operators
Logical operators are logical-and (&&), logical-or (||) and logical-not (!). Operators &&
and || are binary operators. Operator ! is a unary operator. Logical operators follow these
conditions:
// Logical operations
A = 3; B = 0;
A && B // Evaluates to 0. Equivalent to (logical-1 && logical-0)
A || B // Evaluates to 1. Equivalent to (logical-1 || logical-0)
!A// Evaluates to 0. Equivalent to not(logical-1)
!B// Evaluates to 1. Equivalent to not(logical-0)
// Unknowns
A = 2'b0x; B = 2'b10;
A && B // Evaluates to x. Equivalent to (x && logical 1)
// Expressions
(a == 2) && (b == 3) // Evaluates to 1 if both a == 2 and b == 3 are
true.
// Evaluates to 0 if either is false.
Relational operators are greater-than (>), less-than (<), greater-than-or-equal-to (>=), and
less-than-or-equal-to (<=). If relational operators are used in an expression, the
expression returns a logical value of 1 if the expression is true and 0 if the expression is
false. If there are any unknown or z bits in the operands, the expression takes a value x.
These operators function exactly as the corresponding operators in the C programming
language.
106
// A = 4, B = 3
// X = 4'b1010, Y = 4'b1101, Z = 4'b1xxx
Equality operators are logical equality (==), logical inequality (!=), case equality (===),
and case inequality (!==). When used in an expression, equality operators return logical
value 1 if true, 0 if false. These operators compare the two operands bit by bit, with zero
filling if the operands are of unequal length. Table 6-2 lists the operators.
Possible Logical
Expression Description
Value
a == b a equal to b, result unknown if x or z in a or b 0, 1, x
a not equal to b, result unknown if x or z in a or
a != b 0, 1, x
b
a === b a equal to b, including x and z 0, 1
a !== b a not equal to b, including x and z 0, 1
It is important to note the difference between the logical equality operators (==, !=) and
case equality operators (===, !==). The logical equality operators (==, !=) will yield an x
if either operand has x or z in its bits. However, the case equality operators ( ===, !== )
compare both operands bit by bit and compare all bits, including x and z. The result is 1 if
the operands match exactly, including x and z bits. The result is 0 if the operands do not
match exactly. Case equality operators never result in an x.
// A = 4, B = 3
// X = 4'b1010, Y = 4'b1101
// Z = 4'b1xxz, M = 4'b1xxz, N = 4'b1xxx
A == B // Results in logical 0
X != Y // Results in logical 1
X == Z // Results in x
Z === M // Results in logical 1 (all bits match, including x and z)
Z === N // Results in logical 0 (least significant bit does not match)
M !== N // Results in logical 1
107
6.4.5 Bitwise Operators
Bitwise operators are negation (~), and(&), or (|), xor (^), xnor (^~, ~^). Bitwise operators
perform a bit-by-bit operation on two operands. They take each bit in one operand and
perform the operation with the corresponding bit in the other operand. If one operand is
shorter than the other, it will be bit-extended with zeros to match the length of the longer
operand. Logic tables for the bit-by-bit computation are shown in Table 6-3. A z is
treated as an x in a bitwise operation. The exception is the unary negation operator (~),
which takes only one operand and operates on the bits of the single operand.
// X = 4'b1010, Y = 4'b1101
// Z = 4'b10x1
108
It is important to distinguish bitwise operators ~, &, and | from logical operators !, &&, ||.
Logical operators always yield a logical value 0, 1, x, whereas bitwise operators yield a
bit-by-bit value. Logical operators perform a logical operation, not a bit-by-bit operation.
// X = 4'b1010, Y = 4'b0000
Reduction operators are and (&), nand (~&), or (|), nor (~|), xor (^), and xnor (~^, ^~).
Reduction operators take only one operand. Reduction operators perform a bitwise
operation on a single vector operand and yield a 1-bit result. The logic tables for the
operators are the same as shown in Section 6.4.5, Bitwise Operators. The difference is
that bitwise operations are on bits from two different operands, whereas reduction
operations are on the bits of the same operand. Reduction operators work bit by bit from
right to left. Reduction nand, reduction nor, and reduction xnor are computed by inverting
the result of the reduction and, reduction or, and reduction xor, respectively.
// X = 4'b1010
The use of a similar set of symbols for logical (!, &&, ||), bitwise (~, &, |, ^), and
reduction operators (&, |, ^) is somewhat confusing initially. The difference lies in the
number of operands each operator takes and also the value of results computed.
Shift operators are right shift ( >>), left shift (<<), arithmetic right shift (>>>), and
arithmetic left shift (<<<). Regular shift operators shift a vector operand to the right or
the left by a specified number of bits. The operands are the vector and the number of bits
to shift. When the bits are shifted, the vacant bit positions are filled with zeros. Shift
operations do not wrap around. Arithmetic shift operators use the context of the
expression to determine the value with which to fill the vacated bits.
// X = 4'b1100
109
Y = X << 1; //Y is 4'b1000. Shift left 1 bit. 0 filled in LSB position.
Y = X << 2; //Y is 4'b0000. Shift left 2 bits.
Shift operators are useful because they allow the designer to model shift operations, shift-
and-add algorithms for multiplication, and other useful operations.
Concatenations are expressed as operands within braces, with commas separating the
operands. Operands can be scalar nets or registers, vector nets or registers, bit-select,
part-select, or sized constants.
Y = {B , C} // Result Y is 4'b0010
Y = {A , B , C , D , 3'b001} // Result Y is 11'b10010110001
Y = {A , B[0], C[1]} // Result Y is 3'b101
reg A;
reg [1:0] B, C;
reg [2:0] D;
A = 1'b1; B = 2'b00; C = 2'b10; D = 3'b110;
110
6.4.10 Conditional Operator
The conditional operator(?:) takes three operands.
The condition expression (condition_expr) is first evaluated. If the result is true (logical
1), then the true_expr is evaluated. If the result is false (logical 0), then the false_expr is
evaluated. If the result is x (ambiguous), then both true_expr and false_expr are evaluated
and their results are compared, bit by bit, to return for each bit position an x if the bits are
different and the value of the bits if they are the same.
111
6.4.11 Operator Precedence
Reduction ^ ^~
|, ~|
&&
Logical
||
Conditional ?: Lowest precedence
112