Operators 2

Welcome to the System Verilog tutorial series! If you have any doubts / suggestions, please let us know!  Dear visitor, please Sign up / Login for Free and get privileged access! You can copy code, download free tutorials and do more when you’re logged in!

Logical:

1-16

SystemVerilog added two new logical operators logical implication (->), and logical equivalence (<->). The logical implication expression1 -> expression2 is logically equivalent to (!expression1 || expression2), and the logical equivalence expression1 <-> expression2 is logically equivalent to ((expression1 -> expression2) && (expression2 -> expression1)).

1-17

EXAMPLE: Logical

program main ;
reg a_1,a_0,a_x,a_z;
reg b_1,b_0,b_x,b_z;
initial begin
a_1 = 'b1;a_0 = 'b0;a_x = 'bx;a_z = 'bz;
b_1 = 'b1;b_0 = 'b0;b_x = 'bx;b_z = 'bz;
$display("--------------------------");
$display (" && 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 && b_0,a_0 && b_1,a_0 && b_x,a_0
&& b_z);
$display (" 1 %b %b %b %b ",a_1 && b_0,a_1 && b_1,a_1 && b_x,a_1
&& b_z);
$display (" x %b %b %b %b ",a_x && b_0,a_x && b_1,a_x && b_x,a_x
&& b_z);
$display (" z %b %b %b %b ",a_z && b_0,a_z && b_1,a_z && b_x,a_z
&& b_z);
$display("--------------------------");
$display("--------------------------");
$display (" || 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 || b_0,a_0 || b_1,a_0 || b_x,a_0
|| b_z);
$display (" 1 %b %b %b %b ",a_1 || b_0,a_1 || b_1,a_1 || b_x,a_1
|| b_z);
$display (" x %b %b %b %b ",a_x || b_0,a_x || b_1,a_x || b_x,a_x
|| b_z);
$display (" z %b %b %b %b ",a_z || b_0,a_z || b_1,a_z || b_x,a_z
|| b_z);
$display("--------------------------");
$display("--------------------------");
$display (" ! 0 1 x z ");
$display("--------------------------");
$display (" %b %b %b %b ",!b_0,!b_1,!b_x,!b_z);
$display("--------------------------");
end
endprogram

RESULTS:
————————–
&& 0 1 x z
————————–
0 0 0 0 0
1 0 1 x x
x 0 x x x
z 0 x x x
————————–
————————–
|| 0 1 x z
————————–
0 0 1 x x
1 1 1 1 1
x x 1 x x
z x 1 x x
————————–
————————–
! 0 1 x z
————————–
1 0 x x
————————–

Bitwise:

1-18

In Systemverilog, bitwise exclusive nor has two notations (~^ and ^~).

EXAMPLE: Bitwise

program main ;
reg a_1,a_0,a_x,a_z;
reg b_1,b_0,b_x,b_z;
initial begin
a_1 = 'b1;a_0 = 'b0;a_x = 'bx;a_z = 'bz;
b_1 = 'b1;b_0 = 'b0;b_x = 'bx;b_z = 'bz;
$display("--------------------------");
$display (" ~ 0 1 x z ");
$display("--------------------------");
$display (" %b %b %b %b ",~b_0,~b_1,~b_x,~b_z);
$display("--------------------------");
$display("--------------------------");
$display (" & 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 & b_0,a_0 & b_1,a_0 & b_x,a_0 & b_z);
$display (" 1 %b %b %b %b ",a_1 & b_0,a_1 & b_1,a_1 & b_x,a_1 & b_z);
$display (" x %b %b %b %b ",a_x & b_0,a_x & b_1,a_x & b_x,a_x & b_z);
$display (" z %b %b %b %b ",a_z & b_0,a_z & b_1,a_z & b_x,a_z & b_z);
$display("--------------------------");
$display("--------------------------");
$display (" &~ 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 &~ b_0,a_0 &~ b_1,a_0 &~ b_x,a_0
&~ b_z);
$display (" 1 %b %b %b %b ",a_1 &~ b_0,a_1 &~ b_1,a_1 &~ b_x,a_1
&~ b_z);
$display (" x %b %b %b %b ",a_x &~ b_0,a_x &~ b_1,a_x &~ b_x,a_x
&~ b_z);
$display (" z %b %b %b %b ",a_z &~ b_0,a_z &~ b_1,a_z &~ b_x,a_z
&~ b_z);
$display("--------------------------");
$display("--------------------------");
$display (" | 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 | b_0,a_0 | b_1,a_0 | b_x,a_0 | b_z);
$display (" 1 %b %b %b %b ",a_1 | b_0,a_1 | b_1,a_1 | b_x,a_1 | b_z);
$display (" x %b %b %b %b ",a_x | b_0,a_x | b_1,a_x | b_x,a_x | b_z);
$display (" z %b %b %b %b ",a_z | b_0,a_z | b_1,a_z | b_x,a_z | b_z);
$display("--------------------------");
$display (" |~ 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 |~ b_0,a_0 |~ b_1,a_0 |~ b_x,a_0 |~ b_z);
$display (" 1 %b %b %b %b ",a_1 |~ b_0,a_1 |~ b_1,a_1 |~ b_x,a_1 |~ b_z);
$display (" x %b %b %b %b ",a_x |~ b_0,a_x |~ b_1,a_x |~ b_x,a_x |~ b_z);
$display (" z %b %b %b %b ",a_z |~ b_0,a_z |~ b_1,a_z |~ b_x,a_z |~ b_z);
$display("--------------------------");
$display("--------------------------");
$display (" ^ 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 ^ b_0,a_0 ^ b_1,a_0 ^ b_x,a_0 ^ b_z);
$display (" 1 %b %b %b %b ",a_1 ^ b_0,a_1 ^ b_1,a_1 ^ b_x,a_1 ^ b_z);
$display (" x %b %b %b %b ",a_x ^ b_0,a_x ^ b_1,a_x ^ b_x,a_x ^ b_z);
$display (" z %b %b %b %b ",a_z ^ b_0,a_z ^ b_1,a_z ^ b_x,a_z ^ b_z);
$display("--------------------------");
$display (" ^~ 0 1 x z ");
$display("--------------------------");
$display (" 0 %b %b %b %b ",a_0 ^~ b_0,a_0 ^~ b_1,a_0 ^~ b_x,a_0 ^~ b_z);
$display (" 1 %b %b %b %b ",a_1 ^~ b_0,a_1 ^~ b_1,a_1 ^~ b_x,a_1 ^~ b_z);
$display (" x %b %b %b %b ",a_x ^~ b_0,a_x ^~ b_1,a_x ^~ b_x,a_x ^~ b_z);
$display (" z %b %b %b %b ",a_z ^~ b_0,a_z ^~ b_1,a_z ^~ b_x,a_z ^~ b_z);
$display("--------------------------");
end
endprogram

RESULTS:
————————–
~ 0 1 x z
————————–
1 0 x x
————————–
————————–
& 0 1 x z
————————–
0 0 0 0 0
1 0 1 x x
x 0 x x x
z 0 x x x
————————–
————————–
&~ 0 1 x z
————————–
0 0 0 0 0
1 1 0 x x
x x 0 x x
z x 0 x x
————————–
————————–
| 0 1 x z
————————–
0 0 1 x x
1 1 1 1 1
x x 1 x x
z x 1 x x
————————–
|~ 0 1 x z
————————–
0 1 0 x x
1 1 1 1 1
x 1 x x x
z 1 x x x
————————–
————————–
^ 0 1 x z
————————–
0 0 1 x x
1 1 0 x x
x x x x x
z x x x x
————————–
^~ 0 1 x z
————————–
0 1 0 x x
1 0 1 x x
x x x x x
z x x x x
————————–

Reduction:

1-19

EXAMPLE: Reduction

program main ;
reg [3:0] a_1,a_0,a_01xz,a_1xz,a_0xz,a_0dd1,a_even1;
initial
begin
a_1 = 4'b1111 ;
a_0 = 4'b0000 ;
a_01xz = 4'b01xz ;
a_1xz = 4'b11xz ;
a_0xz = 4'b00xz ;
a_0dd1 = 4'b1110 ;
a_even1 = 4'b1100 ;
$display("-------------------------------------------");
$display(" a_1 a_0 a_01xz a_1xz a_0xz ");
$display("-------------------------------------------");
$display("& %b %b %b %b
%b ",&a_1,&a_0,&a_01xz,&a_1xz,&a_0xz);
$display("| %b %b %b %b
%b ",|a_1,|a_0,|a_01xz,|a_1xz,|a_0xz);
$display("~& %b %b %b %b
%b ",~&a_1,~&a_0,~&a_01xz,~&a_1xz,~&a_0xz);
$display("~| %b %b %b %b
%b ",~|a_1,~|a_0,~|a_01xz,~|a_1xz,~|a_0xz);
$display("-------------------------------------------");
$display(" a_ood1 a_even1 a_1xz");
$display("-------------------------------------------");
$display(" ^ %b %b %b ",^a_0dd1,^a_even1,^a_1xz);
$display(" ~^ %b %b %b ",~^a_0dd1,~^a_even1,~^a_1xz);
$display("-------------------------------------------");
end
endprogram

RESULTS:
——————————————-
a_1 a_0 a_01xz a_1xz a_0xz
——————————————-
& 1 0 0 x 0
| 1 0 1 1 x
~& 0 1 1 x 1
~| 0 1 0 0 x
——————————————-
a_ood1 a_even1 a_1xz
——————————————-
^ 1 0 x
~^ 0 1 x
——————————————-

Shift:

1-20

The left shift operators, << and <<<, shall shift their left operand to the left by the number by the number of bit positions given by the right operand. In both cases, the vacated bit positions shall be filled with zeros. The right shift operators, >> and >>>, shall shift their left operand to the right by the number of bit positions given by the right operand. The logical right shift shall fill the vacated bit positions with zeros.

The arithmetic right shift shall fill the vacated bit positions with zeros if the result type is unsigned. It shall fill the vacated bit positions with the value of the most significant (i.e., sign) bit of the left operand if the result type is signed. If the right operand has an x or z value, then the result shall be unknown. The right operand is always treated.

EXAMPLE:Shift

program main ;
integer a_1,a_0;
initial begin
a_1 = 4'b1100 ;
a_0 = 4'b0011 ;
$display(" << by 1 a_1 is %b a_0 is %b ",a_1 << 1,a_0 << 1);
$display(" >> by 2 a_1 is %b a_0 is %b ",a_1 >> 2,a_0 >> 2);
$display(" <<< by 1 a_1 is %b a_0 is %b ",a_1 <<< 1,a_0 <<< 1);
$display(" >>> by 2 a_1 is %b a_0 is %b ",a_1 >>> 2,a_0 >>> 2);
end
endprogram

RESULTS:
<< by 1 a_1 is 1000 a_0 is 0110
>> by 2 a_1 is 0011 a_0 is 0000
<<< by 1 a_1 is 1000 a_0 is 0110
>>> by 2 a_1 is 1111 a_0 is 0000

Increment And Decrement:

  • # ++ increment
  • # — decrement

SystemVerilog includes the C increment and decrement assignment operators ++i, –i, i++, and i–. These do not need parentheses when used in expressions. These increment and decrement assignment operators behave as blocking assignments.

The ordering of assignment operations relative to any other operation within an expression is undefined. An implementation can warn whenever a variable is both written and read-or-written within an integral expression or in other contexts where an implementation cannot guarantee order of evaluation.

For example:

  • i = 10;
  • j = i++ + (i = i – 1);

After execution, the value of j can be 18, 19, or 20 depending upon the relative ordering of the increment and the assignment statements. The increment and decrement operators, when applied to real operands, increment or decrement the
operand by 1.0.

EXAMPLE: Increment and Decrement

program main ;
integer a_1,a_0;
initial begin
a_1 = 20 ;
a_0 = 20 ;
a_1 ++ ;
a_0 -- ;
$display (" a_1 is %d a_0 is %d ",a_1,a_0);
end
endprogram

RESULTS:
a_1 is 21 a_0 is 19

Set:

  • # inside !inside dist

SystemVerilog supports singular value sets and set membership operators.

The syntax for the set membership operator is:

  • inside_expression ::= expression inside { open_range_list }

The expression on the left-hand side of the inside operator is any singular expression. The set-membership open_range_list on the right-hand side of the inside operator is a comma-separated list of expressions or ranges. If an expression in the list is an aggregate array, its elements are traversed by descending into the array until reaching a singular value.

The members of the set are scanned until a match is found and the operation returns 1’b1. Values can be repeated, so values and value ranges can overlap. The order of evaluation of the expressions and ranges is nondeterministic.

EXAMPLE: Set

program main ;
integer i;
initial begin
i = 20;
if( i inside {10,20,30})
$display(" I is in 10 20 30 ");
end
endprogram

RESULTS:
I is in 10 20 30

Streaming Operator:

The streaming operators perform packing of bit-stream types into a sequence of bits in a user-specified order.

When used in the left-hand side , the streaming operators perform the reverse operation, i.e., unpack a stream of bits intoone or more variables.

Re-Ordering Of The Generic Stream:

The stream_operator << or >> determines the order in which blocks of data are streamed.

  • >> causes blocks of data to be streamed in left-to-right order
  • << causes blocks of data to be streamed in right-to-left order

For Example:

int j = { "A", "B", "C", "D" };
{ >> {j}} // generates stream "A" "B" "C" "D"
{ << byte {j}} // generates stream "D" "C" "B" "A" (little endian)
{ << 16 {j}} // generates stream "C" "D" "A" "B"
{ << { 8'b0011_0101 }} // generates stream 'b1010_1100 (bit reverse)
{ << 4 { 6'b11_0101 }} // generates stream 'b0101_11
{ >> 4 { 6'b11_0101 }} // generates stream 'b1101_01 (same)
{ << 2 { { << { 4'b1101 }} }} // generates stream 'b1110

Packing Using Streaming Operator:

Packing is performed by using the streaming operator on thr RHS of the expression.

For example:

int j = { "A", "B", "C", "D" };
bit [7:0] arr;
arr = { >> {j}}
arr = { << byte {j}}
arr = { << 16 {j}}
arr = { << { 8'b0011_0101 }}
arr = { << 4 { 6'b11_0101 }}
arr = { >> 4 { 6'b11_0101 }}
arr = { << 2 { { << { 4'b1101 }} }}

Unpacking Using Streaming Operator:

UnPacking is performed by using the streaming operator on thr LHS of the expression.

For example:

int a, b, c;
logic [10:0] up [3:0];
logic [11:1] p1, p2, p3, p4;
bit [96:1] y = {>>{ a, b, c }}; // OK: pack a, b, c
int j = {>>{ a, b, c }}; // error: j is 32 bits < 96 bits
bit [99:0] d = {>>{ a, b, c }}; // OK: d is padded with 4 bits
{>>{ a, b, c }} = 23'b1; // error: too few bits in stream
{>>{ a, b, c }} = 96'b1; // OK: unpack a = 0, b = 0, c = 1
{>>{ a, b, c }} = 100'b1; // OK: unpack as above (4 bits unread)
{ >> {p1, p2, p3, p4}} = up; // OK: unpack p1 = up[3], p2 = up[2],
// p3 = up[1], p4 = up[0]

Streaming Dynamically Sized Data:
Stream = {<< byte{p.header, p.len, p.payload, p.crc}}; // packing
Stream = {<<byte{p.header, p.len, p.payload with [0 +: p.len], p.crc}};
{<< byte{ p.header, p.len, p.payload with [0 +: p.len], p.crc
}} = stream; //unpacking
q = {<<byte{p}}; // packing all the contents of an object.( p is a object )

OPERATOR PRECEDENCY:

() Highest precedence
++ —
& ~& | ~| ^ ~^ ~ >< –
(unary)
* / %
+ –
<< >>
< <= > >= in !in dist
=?= !?= == != === !==
& &~
^ ^~
| |~
&&
||
?:
= += -= *= /= %=
<<= >>= &= |= ^= ~&= ~|= ~^= Lowest precedence