Operators identify the operation to be performed on their 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 following table. 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 Modules |
Relational Operators | > >= < <= | Relational |
Equality Operators | == ! = | Logical equality Logical inequality |
Logical Operators | ! && | | | Logical NOT Logical AND Logical OR |
Bit-wise Operators | ~ & | ^ ^~ or ~^ | Bit-wise NOT Bit-wise AND Bit-wise OR Bit-wise XOR Bit-wise XNOR |
Reduction Operators | & | ~ & ~ | ^ ~^ or ^~ | Reduction AND Reduction OR Reduction NAND Reduction NOR Reduction XOR Reduction XNOR |
Shift Operators | << >> | Shift left Shift right |
Conditional Operator | ? : | Conditions |
Concatenation Operator | { } | 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 by bit.
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
Foundation Express always ignores comparisons to an X or a Z. 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. Foundation Express always assigns Variable B 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, it generates the following warning message.
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, use the
translate_on and translate_off directives to comment out the condition and its first branch (the true clause) so that only the else branch goes through synthesis.
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.
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 act on the operand bit by bit. The Verilog bit-wise operators follow.
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 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.
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
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.
After the shift, vacated bits are filled with zeros. Shifting by a constant, results in minor circuitry modification (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
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 - 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 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 an equivalent description for the concatenation.
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;
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.
Operator | Description |
---|---|
[ ] | Bit-select or part-select |
( ) | Parentheses |
! ~ | Logical and bit-wise negation |
& | ~& ~| ^ ~^ ^~ | Reduction operators |
+ - | Unary arithmetic |
{ } | Concatenation |
* / % | Arithmetic |
+ - | Arithmetic |
<< >> | Shift |
> >= < <= | Relational |
== != | Logical equality and inequality |
& | Bit-wise AND |
^ ^~ ~^ | Bit-wise XOR and XNOR |
| | Bit-wise OR |
& & | Logical AND |
| | | Logical OR |
? : | Conditional |