Operators represent an operation to be performed on one or two operands to produce a new value. Most operators are either unary operators that apply to only one operand or binary operators that apply to two operands. Two exceptions are conditional operators, which take three operands, and concatenation operators, which take any number of operands.
Foundation Express supports the Verilog language operators listed in the table below. A description of the operators and their order of precedence is given in the sections following the table.
Operator Type | Operator | Description |
---|---|---|
Arithmetic operators | + - * / | arithmetic |
% | modulus | |
Relational operators | > >= < <= | relational |
Equality operators | == | logical equality |
! = | logical inequality | |
Logical operators | ! | logical NOT |
&& | logical AND | |
| | | logical OR | |
Bit-wise operators | ~ | bit-wise NOT |
& | bit-wise AND | |
| | bit-wise OR | |
^ | bit-wise XOR | |
^~ or ~^ | bit-wise XNOR | |
Reduction operators | & | reduction AND |
| | reduction OR | |
~ & | reduction NAND | |
~ | | reduction NOR | |
^ | reduction XOR | |
~^ or ^~ | reduction XNOR | |
Shift operators | << | left shift |
>> | right shift | |
Conditional operator | ? : | conditional |
Concatenation | { } | concatenation |
In the following descriptions, the terms variable and variable operand refer to operands or expressions that are not constant-valued expressions. This group includes wires and registers, bit-selects and part-selects of wires and registers, function calls, and expressions that contain any of these elements.
Arithmetic operators perform simple arithmetic on operands. The Verilog arithmetic operators follow.
You can use the +, -, and * operators with any operand form (constants or variables). You can use the + and - operators as either unary or binary operators. Foundation Express requires that / and % operators have constant-valued operands.
The following example shows three forms of the addition operator. The circuitry built for each addition operation is different because of the different operand types. The first addition requires no logic, the second synthesizes an incrementer, and the third synthesizes an adder.
parameter size=8;
wire[3:0]a,b,c,d,e;
assign c=size + 2;//constant + constant
assign d=a + 1; //variable + constant
assign e=a + b; //variable + variable
Relational operators compare two quantities and yield a 0 or 1 value. A true comparison evaluates to 1; a false comparison evaluates to 0. All comparisons assume unsigned quantities. The circuitry synthesized for relational operators is a bit-wise comparator whose size is based on the sizes of the two operands.
The Verilog relational operators follow.
The following example shows a relational operator.
function [7:0] max(a,b);
input [7:0] a,b;
if(a>=b) max=a;
else max=b;
endfunction
Equality operators generate a 0 if compared expressions are not equal and a 1 if the expressions are equal. Equality and inequality comparisons are performed bit-wise.
The Verilog equality operators follow.
The following example shows the equality operator used to test for a JMP instruction. The output signal jump is set to 1 if the two high-order bits of instruction are equal to the value of parameter JMP; otherwise, jump is set to 0.
module is_jump_instruction(instruction,jump);
parameter JMP=2'h3;
input [7:0] instruction;
output jump;
assign jump=(instruction[7:6]==JMP);
endmodule
Handling Comparisons to X or Z
Comparisons to an X or a Z are always ignored. If your code contains a comparison to an X or a Z, a warning message is displayed indicating that the comparison is always evaluated to FALSE, which might cause simulation to disagree with synthesis.
The following example shows code from a file called test2.v. Variable B is always assigned to the value 1, because the comparison to X is ignored.
always begin
if (A==1'bx) //this is line 10
B=0;
else
B=1;
end
When Foundation Express reads this code, the following warning message is generated.
Warning: Comparisons to a don't care are treated as always being false in routine test2 line 10 in file `test2.v'. This may cause simulation to disagree with synthesis. (HDL-170)
For an alternate method of handling comparisons to X or Z, insert the
// synopsys translate_off directive before the comparison and insert the // synopsys translate_on directive after the comparison. Inserting these directives might cause simulation to disagree with synthesis.
Logical Operators
Logical operators generate a 1 or a 0, according to whether an expression evaluates to TRUE (1) or FALSE (0). The Verilog logical operators follow.
- Logical NOT (!)
- Logical AND (&&)
- Logical OR (||)
The logical NOT operator produces a value of 1 if its operand is zero and a value of 0 if its operand is nonzero. The logical AND operator produces a value of 1 if both operands are nonzero. The logical OR operator produces a value of 1 if either operand is nonzero.
The following example shows logical operators.
module is_valid_sub_inst(inst,mode,valid,unimp);
parameter IMMEDIATE=2'b00,DIRECT=2'b01;
parameter SUBA_imm=8'h80,SUBA_dir=8'h90,
SUBB_imm=8'hc0,SUBB_dir=8'hd0;
input [7:0]inst;
input [1:0] mode;
output valid, unimp;
assign valid=(((mode==IMMEDIATE) && (
(inst==SUBA_imm)||
(inst==SUBB_imm)))||
((mode==DIRECT) && (
(inst==SUBA_dir)||
(inst==SUBB_dir))));
assign unimp=!valid;
endmodule
Bit-Wise Operators
Bit-wise operators act on the operand bit by bit. The Verilog bit-wise operators follow.
- Unary negation (~)
- Bit-wise AND (&)
- Bit-wise OR (|)
- Bit-wise XOR (^)
- Bit-wise XNOR (^~ or ~^)
The following is an example of bit-wise operators.
module full_adder(a,b,cin,s,cout);
input a,b,cin;
output s,cout;
assign s =a^b^cin;
assign cout=(a&b)|(cin & (a|b));
endmodule
Reduction Operators
Reduction operators take one operand and return a single bit. For example, the reduction AND operator takes the AND value of all the bits of the operand and returns a 1-bit result. The Verilog reduction operators follow.
- Reduction AND (&)
- Reduction OR (|)
- Reduction NAND (~&)
- Reduction NOR (~|)
- Reduction XOR (^)
- Reduction XNOR (^~ or ~^)
The following example shows reduction operators.
module check_input(in,parity,all_ones);
input [7:0] in;
output parity,all_ones;
assign parity =^in;
assign all_ones=& in;
endmodule
Shift Operators
A shift operator takes two operands and shifts the value of the first operand right or left by the number of bits given by the second operand.
The Verilog shift operators follow.
- Shift left (<<)
- Shift right (>>)
After the shift, vacated bits are filled with zeros. Shifting by a constant, results in trivial circuitry (because only rewiring is required). Shifting by a variable causes a general shifter to be synthesized. The following example shows how a shift right operator is used to perform a division by 4.
module divide_by_4(dividend,quotient);
input [7:0] dividend;
output [7:0] quotient;
assign quotient=dividend>>2;//shift right 2 bits
endmodule
Conditional Operators
The conditional operator (? :) evaluates an expression and returns a value that is based on the truth of the expression. The following example shows how to use the conditional operator. If the expression (op == ADD) evaluates to TRUE, the value a+b is assigned to result; otherwise, the value a-b is assigned to result.
module add_or_subtract(a,b,op,result);
parameter ADD=1'b0;
input [7:0] a,b;
input op;
output [7:0] result;
assign result=(op==ADD)?a+b:a-b;
endmodule
You can nest conditional operators to produce an if...then construct. The following example shows the conditional operators used to evaluate the value of op successively and perform the correct operation.
module arithmetic(a,b,op,result);
parameter ADD=3'h0,SUB=3'h1,AND=3'h2,OR=3'h3, XOR=3'h4;
input [7:0] a,b;
input [2:0] op;
output [7:0] result;
assign result=((op==ADD)?a+b:(
(op==SUB)?a-b:(
(op==AND)?a&b:(
(op== OR)?a|b:(
(op==XOR)?a^b:(a))))));
endmodule
Concatenation Operator
Concatenation combines one or more expressions to form a larger vector. In the Verilog language, you indicate concatenation by listing all expressions to be concatenated, separated by commas, in curly braces ({ }). Any expression except an unsized constant is allowed in a concatenation. For example, the concatenation {1'b1,1'b0,1'b0} yields the value 3'b100.
You can also use a constant-valued repetition multiplier to repeat the concatenation of an expression. The concatenation {1'b1,1'b0,1'b0} can also be written as {1'b1,{2{1'b0}}} to yield 3'b100. The expression {2{expr}}within the concatenation repeats expr two times.
The following example shows a concatenation that forms the value of a condition-code register.
output [7:0] ccr;
wire half_carry,interrupt,negative,zero,
overflow,carry;
...
assign ccr={2'b00,half_carry,interrupt,
negative,zero,overflow,carry};
The following example shows a concatenation equivalent.
output [7:0] ccr;
...
assign ccr[7] = 1'b0;
assign ccr[6] = 1'b0;
assign ccr[5] = half_carry;
assign ccr[4] = interrupt;
assign ccr[3] = negative;
assign ccr[2] = zero;
assign ccr[1] = overflow;
assign ccr[0] = carry;
Operator Precedence
The following table lists the precedence of all operators, from highest to lowest. All operators at the same level in the table are evaluated from left to right, except the conditional operator (?:), which is evaluated from right to left.
Table 4_2 Operator Precedence
Operator
Description
[ ]
bit-select or part-select
( )
parentheses
! ~
logical and bit-wise negation
& | ~& ~| ^ ~^ ^~
reduction operators
+ -
unary arithmetic
{ }
concatenation
* / %
arithmetic
+ -
arithmetic
<< >>
shift
> >= < <=
relational
== !=
logical equality
&
bit-wise AND
^ ^~ ~^
bit-wise XOR and XNOR
|
bit-wise OR
& &
logical AND
| |
logical OR
? :
conditional
