System Verilog Assignment Operators
This tutorial covers the various operators available in Verilog. If you have programmed in C/C++ or Java, then many of these operators will be familiar. However, there are a few new usages that are handy for dealing with hardware.
Bitwise Operators
Function  Operator 

NOT  ~ 
AND  & 
OR   
XOR  ^ 
XNOR  ~^ or ^~ 
These operators are called bitwise operators because they operate on each bit individually. These are used to perform basic logic functions and they get synthesized into their equivalent logic gate.
Take a look at the following example.
wire [3:0] a,b,c; assign a = 4'b1010; assign b = 4'b1100; assign c = a & b;c will now have the value 4'b1000. This is because the mostsignificant bits of a and b are the only ones that are both 1.
When you perform a bitwise operator on multibit values like above, you are essentially using multiple gates to perform the bitwise operation. In this case, we need four AND gates to and each bit of a and b together. The results of each AND gate is the value c.
All of these operators are used on two values except the NOT (~) operator which only takes one value. Take a look at this example where we replace the last line of the previous example.
assign c = ~a;Now c will have the value 4'b0101. Again, this is because each bit of a is individually inverted and assigned to c.
If the two values used by a bitwise operator are different in length, the shorter one is filled with zeros to make the lengths match.
Reduction Operators
Function  Operator 

AND  & 
NAND  ~& 
OR   
NOR  ~ 
XOR  ^ 
XNOR  ~^ or ^~ 
Reduction operators are very similar to the bitwise operators, except they are performed on all the bits of a single value. They are used to reduce the number of bits to one by performing the specified function on every bit.
Take a look at this example.
wire [3:0] a; wire b; assign a = 4'b1010; assign b = &a;In this example b will be 0. This is because each bit of a is anded with each other. In other words, it is equivalent to the following.
assign b = a[0] & a[1] & a[2] & a[3];This essentially synthesizes a large single logic gate with enough inputs to fit the input value. In this case, a four input AND gate would be synthesized.
Shift Operators
Function  Operator 

Shift Right  >> 
Shift Left  << 
Arithmetic Shift Right  >>> 
Arithmetic Shift Left  <<< 
The shift operators in Verilog are very similar to the ones in other languages. They simply shift the bits in a value over that many times to the right of left.
The basic shift operators are zerofilling meaning that bits that don't have a value shifted into them are replaced with zeros. Take a look at the following example.
wire [4:0] a,b,c; assign a = 5'b10100; assign b = a << 2; assign c = a >> 2;In this example b will have the value 5'b10000 and c will have the value 5'b00101. You can see with b the top two bits of a are lost, and with c the bottom two bits are lost.
Now let's take a look at the arithmetic shift operators. These vary from the basic shift operators because they perform signextended shifts. When shifting left, it performs exactly the same as the basic shift operator, but when shifting to the right, the mostsignificant bit (the signbit) plays a role.
If the sign bit is 0, then the arithmetic shift operator acts the same way as the basic shift operator. However, if the sign bit is 1, the shift will fill the left side with ones.
Take a look at this example.
wire [4:0] a,b,c; assign a = 5'b10100; assign b = a <<< 2; assign c = a >>> 2;Now b will have the value 5'b10000 just like before, but c will have the value 5'b11101.
Why would you ever want to fill the left side with the mostsignificant bit? The reason is because shifting bits is a very cheap way to perform multiplication and division by powers of two. Take the value 6 (4'b0110). If we shift it to the left one bit we get 4'b1100 or 12 and if we shift it to the right one bit we get 4'b0011 or 3. Now what about the value 4 (4'b1100)? If we shift it to the left one bit we get 4'b1000 or 8. However if we shift it to the right one bit we get 4'b0110 or 6! This is because we need to use the arithmetic shift. If we use the arithmetic shift we get 4'b1110 or 2!
Shift operations are very cheap! This is because they are essentially just a signal renaming.
Concatenation and Replication Operators
Function  Operator 

Concatenation  { , } 
Replication  { { } } 
These are two very useful operators for manipulating bits.
The concatenation operator is used to merge two values together into a wider value.
wire [3:0] a,b; wire [7:0] c; assign a = 4'b1100; assign b = 4'b1010; assign c = {a,b};In this example c has the value 8'b11001010. You can concatenate as many signals together as you want by adding them to the commaseparated list.
The replication operator is used to duplicate a value multiple times.
wire [1:0] a; wire [7:0] b; assign a = 4'b10; assign b = {4{a}};In this example a is replicated 4 times making the value of b be 8'b10101010.
Arithmetic Operators
Function  Operator 

Addition  + 
Subtraction   
Multiply  * 
Divide  / 
Modulus  % 
Power  ** 
Verilog provides these six basic arithmetic operators to make basic math simpler. However, it is important to remember when using these operators how they will be implemented in hardware.
The most important thing to remember is that not all of these operators can be synthesized! Only addition, subtraction, and multiplication are synthesizable! Some synthesizers will allow you to use divide if you are dividing by a power of two, but you should use a shift operator for that anyways. The reason the other three aren't synthesizable is because the circuits required to implement them are quite complicated. There are many trade offs that as a designer you need to make if you need to use divide, modulous, or power, that the synthesizer can't make for you. In most cases these operations will be pipelined to provide speed or reduce the amount of hardware used. This is something that the synthesizer can't do for you.
When using addition and subtraction, the synthesizer will probably synthesize a circuit similar to the one shown in this tutorial. However, the synthesizer is free to make optimizations as long as it adds the two values.
For multiplication, many FPGAs (including the one used by the Mojo) have special resources dedicated to fast math. If these are available they will be used, however, if you run out of them a multiplication circuit will have to be generated which can be large and slow. Because of this you should never multiply by a power of two, but shift instead. Most synthesizers will be smart enough to do this for you but it is good practice not to rely on that.
Also note that the  operator can be used to negate a number.
When two Nbit numbers are added or subtracted, an N+1but number is produced. If you add or subtract two Nbit numbers and store the value in an Nbit number you need to think about overflow. For example, if you have a two bit number 3 (2'b11) and you add it to 2 (2'b10) the result will be 5 (3'b101) but if you store the value in a two bit number you get 1 (2'b01).
For multiplication of two Nbit numbers, the result will be an N*2bit number. For example, 7 (3'b111) * 6 (3'b110) = 42 (6'b101010).
Comparison Operators
Function  Operator 

Less Than  < 
Greater Than  > 
Less Than or Equal  <= 
Greater Than or Equal  >= 
Equality  == 
Inequality  != 
Case Equality  === 
Case Inequality  !== 
These operators compare two values and produce a single bit to represent the result. A 1 is true and a 0 is false.
The only strange thing to note is the case version of the equality tests. Bits in Verilog aren't only 0 or 1, but they can also be x or z. For the standard equality tests, if either value has an x or z in it the result will be an x. However, for the case equality tests, it will test to see if these are matched in the other value. For example 4'b01x0 == 4'b01x0 produces an x, but 4'b01x0 === 4'b01x0 produces a 1.
In reality, hardware can't have an x value so the case equality tests are not synthesizable but are useful for simulations.
Logical Operators
Function  Operator 

Logical And  && 
Logical Or   
Logical Not  ! 
These operators are used for combining multiple comparison operations. Take a look at this example.
if ((4'b1100 > 4'b1011) && (4'b0111 == 4'b0111)) begin ... endIt is important to note that these operators will produce a single bit value like the comparison operators. Also anything that is not zero is considered to be true while zero is false.
wire [3:0] a,b; wire c; assign a = 4'b1010; assign b = 4'b1110; assign c = a && b;In this example, c will have the value 1 because a and b are both nonzero.
Conditional Operator
Function  Operator 

Conditional  ? 
The conditional operator is a way to write compact if statements. It is used to select a value based on a logical value.
wire [3:0] a,b,c,d; assign a = 4'b1000; assign b = 4'b0111; assign c = 4'b1010; assign d = a > b ? c : 4'b0000;In this example d will have the value 4'b1010. When the expression on the left of the ? is true (nonzero) the value on the left of the : will be assigned. If the expression is false the value on the right is used. In this case since a is greater than b, the value of c was assigned to d.
Verilog
Operators
Arithmetic Operators
These perform arithmetic operations. The + and  can be used as either unary (z) or binary (xy) operators.
Operators + (addition)  (subtraction) * (multiplication) / (division) % (modulus) 
Relational Operators
Relational operators compare two operands and return a single bit 1or 0. These operators synthesize into comparators.
Wire and reg variables are positive Thus (3’b001) = = 3’b111 and (3d001)>3d110. However for integers 1< 6.
Operators < (less than) <= (less than or equal to) > (greater than) >= (greater than or equal to) == (equal to) != (not equal to) 
Bitwise Operators
Bitwise operators do a bitbybit comparison between two operands. However see“Reduction Operators” on p. 7.
Operators ~ (bitwise NOT) & (bitwise AND)  (bitwise OR) ^ (bitwise XOR) ~^ or ^~(bitwise XNOR) 
Logical Operators
Logical operators return a single bit 1 or 0. They are the same as bitwise operators only for single bit operands. They can work on expressions, integers or groups of bits, and treat all values that are nonzero as “1”. Logical operators are typically used in conditional (if ... else) statements since they work with expressions.
Operators ! (logical NOT) && (logical AND)  (logical OR) 
Reduction Operators
Reduction operators operate on all the bits of an operand vector and return a singlebit value. These are the unary (one argument) form of the bitwise operators above.
Operators & (reduction AND)  (reduction OR) ~& (reduction NAND) ~ (reduction NOR) ^ (reduction XOR) ~^ or ^~(reduction XNOR) 
Shift Operators
Shift operators shift the first operand by the number of bits specified by the second operand. Vacated positions are filled with zeros for both left and right shifts (There is no sign extension).
Operators << (shift left) >> (shift right) 
Concatenation Operator
The concatenation operator combines two or more operands to form a larger vector.
Operators { } (concatenation) 
Replication Operator
The replication operator makes multiple copies of an item.
Operators {n{item}} (n fold replication of an item) For synthesis, Synopsis did not like a zero replication. For example:

Conditional Operator: “?”
Conditional operator is like those in C/C++. They evaluate one of the two expressions based on a condition. It will synthesize to a multiplexer (MUX).
Operators (cond) ? (result if cond true): (result if cond false) 
Operator Precedence
Table below shows the precedence of operators from highest to lowest. Operators on the same level evaluate from left to
right. It is strongly recommended to use parentheses to define order of precedence and improve the readability of
your code.
0 thoughts on “System Verilog Assignment Operators”