In this post, we will take a look and understand the working of operators in VHDL. Operators are great tools that offer us room to maneuver in our program. The main purpose of any code is to implement some kind of logic. Having a variety of operators helps in that endeavor. The operators in VHDL are divided into four categories:
 Arithmetic operators
 Shift operators
 Relational operators
 Logical operators
Each operator serves a welldefined purpose, and here we will learn to use these operators to our advantage in our programs. We’ll be using all of these operators extensively in our future modules in this VHDL course. Proper usage of operators can make a rather complex task shorter. Let’s first summarize all the operators in a neat little list that you can screenshot and keep handy.
Operator  Name 
Arithmetic  
+  addition 
–  subtraction 
*  multiplication 
/  division 
**  exponentiation 
abs  absolute value 
not  complement 
mod  modulo 
rem  remainder 
+  unary plus 
–  unary minus 
&  concatenation 
Shift  
sll  shift left logical 
srl  shift right logical 
sla 
shift left arithmetic

sra 
shift right arithmetic

rol  rotate left 
ror  rotate right 
shift_left() 
New and more
optimum. Read more below. 
shift_right()  
Relational  
=  test for equality 
/=  test for inequality 
<  test for less than 
<= 
test for less than or equal

> 
test for greater than

>= 
test for greater than or equal

Logical  
and  logical and 
or  logical or 
nand 
the logical complement of and

nor 
the logical complement of or

xor 
logical exclusive of or

xnor 
the logical complement of exclusive of or

Let’s dive into these operators.
Arithmetic operators
For the sake of simplicity, let’s classify the operators into three categories.
 Basic arithmetic operators
 Advanced arithmetic operators
 Special arithmetic operators
Basic arithmetic operators are used in almost every program, we will constantly come across examples, and they are easy to use with very low to no syntax restrictions.
Advanced arithmetic operators are not as frequently used but are equally important and powerful if used correctly. Again it is easy to use with a few syntax restrictions.
Special arithmetic operators perform nearly identical operations to simple arithmetic operators, the only difference being they are used under special conditions, with a specific syntax.
Basic arithmetic operators
The four basic arithmetic operators include,
 Addition
+
 Subtraction

 Multiplication
*
 Division
/
We can use these operators to perform basic mathematics in VHDL, and the syntax is as follows.
Addition
A simple addition operator, the syntax is as follows
<numeric> + <numeric>;
A '+'
sign is used to specify the addition between two numeric values. The <numeric>
is any numeric value given for addition, the yield is a summation of both the numeric values.
Subtraction
A simple subtraction operator, the syntax is as follows
<numeric>  <numeric>;
A ''
sign is used to specify the subtraction between two numeric values. The <numeric>
is any numeric value given for subtraction, the yield is the difference for both the numeric values.
Multiplication
A multiplicative operator, the syntax is as follows
<numeric> * <numeric>;
A '*'
sign is used to specify the multiplication between two numeric values. The <numeric>
is any numeric value given for subtraction, the yield is the multiplication of both the numeric values.
Division
A Division operator, the syntax is as follows
<numeric> / <numeric>;
A '/'
sign is used to specify the division between two numeric values. The <numeric>
is any numeric value given for subtraction, and the yield is the quotient after the division of both the numeric values.
Advanced arithmetic operators
Moving on to advanced mathematical operators. Here we have the following operators:
 Exponent
**
 Absolute value
abs
 Modulo
mod
 Remainder
rem
 Component
not
These operators are extremely important for advanced mathematics in VHDL. Let us have a look at the syntax for these operators.
Exponent
For the exponent operator, the syntax is as follows:
<numeric> ** <numeric>;
A '**'
sign is used to specify the use of exponentiation. The <numeric>
is any numeric value given for the operation, and the yield is the exponentiation of the numeric values. Let’s use an equation to understand the syntax better.
Absolute value
For the absolute value operator, the syntax is as follows:
abs <numeric>;
An 'abs'
is used to specify the absolute value. The <numeric>
is any numeric value given for the operation, and the yield is the absolute value, a.k.a. modulus for the given numeric value.
Modulo
A modulo operator, the syntax is as follows
<integer> mod <integer>;
A 'mod'
is used to specify the modulo operator. <integer>
values are used for the operation, and the yield is the modulo for the given integer values.
Remainder
For the remainder operator, the syntax is as follows:
<integer> rem <integer>;
An 'rem'
is used to specify the remainder operator. The <integer>
values are used for the operation, and the yield is the remainder for the given integer values.
Complement
For the complement operator, the syntax is as follows:
not <logic or boolean>;
A 'not'
is used to specify the complement operator. Logic or boolean data type (TRUE or FALSE) is used for this operation, the result is of the same data type and is a complement of the data provided.
Special arithmetic operators
Special arithmetic operators are used when special conditions arise. These operators include,
 Unary plus
+
 Unary minus

 Concatenation
&
Unary plus
For the unary plus operator, the syntax is as follows:
+ <numeric>;
An '+'
is used before the <numeric>
to specify a unary plus operator. The <numeric>
value is used for the operation, and the yield is a numeric value. When this operator is used, the numeric value returns unchanged.
Unary minus
For the unary plus operator, the syntax is as follows:
 <numeric>;
An ''
is used before the <numeric>
to specify a unary minus operator. The <numeric>
value is used for the operation, and the yield is a numeric value. When this operator is used, the numeric value returns with the negated sign. Remember to use this operator with parenthesis in the case of any other operator preceding it. For example, 4 * 2 is invalid. It should be 4 * (2).
Concatenation
For the concatenation operator, the syntax is as follows:
<array or element> & <array or element>;
An '&'
is used before the <array or element>
to specify a concatenation operator. The <array or element>
value is used for the operation, and the yield is a concatenation (joining) of the arrays or elements value.
Shift operators
Shift operators are used to shift an element of an array of numbers or alphabets left or right by a desired number of steps. Further elaboration with each operator is provided below. Shift operators include:
 Shift Left logical
sll
& Shift Right logicalsrl
 Shift Left arithmetic
sla
& Shift Right arithmeticsra
 Rotate Left
rol
& Rotate Rightror
Shift Left logical & Shift Right logical
<logical array> sll <integer>; shift left logical <logical array> srl <integer>; shift right logical
The sll
is the left logical shifter and srl
is the right logical shifter. The <integer>
is used as the number of times we want to shift <logical array>
left or right logically. The result of these operations is also a logical array.
Shift Left arithmetic & Shift Right arithmetic
<logical array> sla <integer>; shift left arithmetic <logical array> sra <integer>; shift right arithmetic
The sla
is the left arithmetic shifter and sra
is the right arithmetic shifter. The <integer>
is used as the number of times we want to shift <logical array>
left or right arithmetically. The result of these operations is also a logical array.
Rotate Left and Rotate Right
<logical array> rol <integer>; rotate left <logical array> ror <integer>; rotate right
The rol
is the left rotator and ror
is the right rotator. The <integer>
is used as the number of times we want to rotate<logical array>
left or right. The result of these operations is also a logical array.
Shift Functions
A more optimum method for the implementation of shifting is by using shift functions. Shift functions are found in the numeric_std
package of VHDL. These instructions have a simple syntax and are easy to understand. The keywords are shift_left()
and shift_right()
. The functions require two inputs: the signal to shift and the number of bits to shift by. There are two types of shifting:
 Arithmetic shift – Here, the positions left vacant after shifting are substituted with the right bits to keep the sign of the original number intact.
 Logical shift – Here, the positions left vacant after shifting are filled with ‘0’.
We can perform shifting logically and arithmetically use keywords unsigned
and signed
respectively.
Let us have a look at the syntax.
syntax for logical shift (unsigned) <initial_string> contains the initial string <shifted_string> = shift_left(unsigned(<initial_string>), <integer>); <shifted_string> = shift_right(unsigned(<initial_string>), <integer>); syntax for arithmetic shift (signed) <initial_string> contains the initial string <shifted_string> = shift_left(signed(<initial_string>), <integer>); <shifted_string> = shift_right(signed(<initial_string>), <integer>); example for shigting logically (unsigned) <initial_string> contains the initial string <shifted_string> = shift_left(unsigned(<initial_string>), 1); shifts the <initial_string> towards the left logically by 1 <shifted_string> = shift_right(unsigned(<initial_string>), 1); shifts the <initial_string> towards the right logically by 1 example for shigting arithmetically (signed) <initial_string> contains the initial string <shifted_string> = shift_left(signed(<initial_string>), 1); shifts the <initial_string> towards the left arithmetically by 1 <shifted_string> = shift_right(signed(<initial_string>), 1); shifts the <initial_string> towards the right arithmetically by 1
The <initial_string>
could be any kind of string std_logic
, signed
, unsigned
etc. The shift_left
indicates a shift towards the left and shift_right
indicated a shift towards the right. And the <integer>
is used to indical the number of steps we want the string to be shifted.
Relational operators
As the name suggests, relational operators are used to test the quantitative relationship of two numbers or/and characters. It could also be two strings/arrays of numbers or characters.
We use these relational operators to compare these elements, and the result is a yield of boolean values: 1=true and 0=false.
The relational operators include
 Test for equality
=
and inequality/=
 Test for less than
<
and less than or equal<=
 Test for greater than
>
and greater than or equal>=
Test for equality and inequality
These operators check if the given data is equal or not. In the case of the test for equality ‘=,’ if the given data is equal, the result is a boolean true, and if unequal, the result is a boolean false.
In the case of the test for inequality ‘/=,’ if data is inequal, the result is a boolean true, and if the data is equal, the result is a boolean false. Let us use an ‘ifelse’ statement to better understand the concept.
<instance_A> <instance_B> two data instances process (check_equality) Equality begin if (<instance_A> = <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process; <instance_A> <instance_B> two data instances process (check_inequality) inEquality begin if (<instance_A> /= <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process;
The <instance_A>, <instance_B> are data instances of any data type. In the first process, the test for equality if <instance_A> is equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> and <instance_B> are not equal the <instance_C> is given a binary 0 value.
In the second process, the test for inequality if <instance_A> is not equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> and <instance_B> are equal the <instance_C> is given a binary 0 value.
Test for less than and less than or equal
These operators check the relation for the given data A and B. In the case of less than ‘<‘, if in the given data A is less than but not equal to B, the result is a boolean true. And if A is greater than or equal to B, the result is a boolean false.
In the case of test for less than or equal ‘<=’, if A is less than or equal to B, the result is a boolean true. And if A is greater than B, the result is a boolean false. Let us use an ‘ifelse’ statement to better understand the concept.
<instance_A> <instance_B> two data instances process (check_lessthan) less than begin if (<instance_A> < <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process; <instance_A> <instance_B> two data instances process (check_lessthan_equal) less than or equaly begin if (<instance_A> <= <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process;
The <instance_A>, <instance_B> are data instances of any data type. In the first process, the test for less than if <instance_A> is less then and not equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> greater than or equal to <instance_B> only then the <instance_C> is given a binary 0 value.
In the second process, the test for less than or equal if <instance_A> is less than or equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> greater <instance_B> only then the <instance_C> is given a binary 0 value.
Test for greater than and greater than or equal
These operators check the relationship between given data A and B. In the case of greater than ‘>’, if A is greater than but not equal to B, the result is a boolean true. If A is less than or equal to B, the result is a boolean false.
In the case of test for greater than or equal ‘>=’, if A is greater than or equal to B, the result is a boolean true. If A is less than B, the result is a boolean false. Let us use an ‘ifelse’ statement to better understand the application.
<instance_A> <instance_B> two data instances process (check_greaterthan) greaterthan begin if (<instance_A> > <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process; <instance_A> <instance_B> two data instances process (check_greaterthan_equal) greaterthan or equal begin if (<instance_A> >= <instance_B>) then <instance_C> <= '1'; else <instance_C> <= '0'; end if; end process;
The <instance_A>, <instance_B> are data instances of any data type. In the first process, the test for greater than if <instance_A> is greater then and not equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> less than or equal to <instance_B> only then the <instance_C> is given a binary 0 value.
In the second process, the test for greater than or equal if <instance_A> is greater than or equal to <instance_B> only then the <instance_C> is given a binary 1 value. If <instance_A> less <instance_B> only then the <instance_C> is given a binary 0 value.
Logical operators
Logical operators perform logic operations between logical array or boolean data. Logical operators in VHDL include:
 Logical AND
and
 Logical OR
or
 Logical NOT of AND
nand
 Logical NOT of OR
nor
 Logical Exclusive of OR
xor
 Logical Exclusive of NOT of OR
xnor
Logical AND
Performs logical AND operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> and <logical _array>; <boolean_storage> <= <boolean> and <boolean>;
The and
keyword is used to specify an AND between the two elements. The AND operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the AND operation here.
Logical OR
Performs logical OR operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> or <logical _array>; <boolean_storage> <= <boolean> or <boolean>;
The or
keyword is used to specify an OR between the two elements. The OR operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the OR operation here.
Logical NAND
Performs logical NAND operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> nand <logical _array>; <boolean_storage> <= <boolean> nand <boolean>;
The nand
keyword is used to specify a NAND between the two elements. The nand operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the NAND operation here.
Logical NOR
Performs logical NOR operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> nor <logical _array>; <boolean_storage> <= <boolean> nor <boolean>;
The nor
keyword is used to specify a NOR between the two elements. The NOR operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the NOR operation here.
Logical XOR
Performs logical XOR operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> xor <logical _array>; <boolean_storage> <= <boolean> xor <boolean>;
The xor
keyword is used to specify an XOR between the two elements. The XOR operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the XOR operation here.
Logical XNOR
Performs logical OR operation with a logical array or boolean.
<logical_array_storage> <= <logical_array> xnor <logical _array>; <boolean_storage> <= <boolean> xnor <boolean>;
The xnor
keyword is used to specify an XNOR between the two elements. The XNOR operation is performed and stored in their respective <logical_array_storage> or <boolean_storage>. You can check out the truth table of the XNOR operation here.
As you can see, operators in VHDL (or any language for that matter) are easy to use and also very powerful tools. With an increase in the scale of our designs, smart implementation of these operators can help us make our program efficient and save on resources.