Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
VHDL is a Hardware Description programming language used to design hardware systems such as FPGA and is an alternative to Verilog. It stands for Very High Speed IC Description Language. VHDL has finer control and can be used to design low level systems like gates to high level systems like in Verilog.
VHDL is a strongly typed language and is not case sensitive.
A program in VHDL is known as a VHDL model and each VHDL model has two components:
- entity
- architecture
In simple terms, Entity can be though of as a class while architecture is a function.
Entity represents the interface specification of the component in the model and the architecture represents the internal structure or implementation of the entity.
A design entity is a basic element in a VHDL model. It can have different levels of abstraction like gate, printed circuit board or the entire system. The different levels of abstraction is classified into:
- Behavorial
- Dataflow
- Structural
In VHDL, a design entity is a module (as in software system) with its inputs and output which are refered as ports.
An entity is declared as:
ENTITY entity_name IS
[GENERIC (generic list);]
[PORT (port list);]
END [entity_name];
Example of entity declaration as a Half Adder gate:
ENTITY half_adder IS
[PORT (x, y, enable : IN BIT;
carry, result : OUT BIT);
END half_adder;
The architecture/ behaviour can be defined as follows:
ARCHITECTURE architecture_name OF entity_name IS
BEGIN
PROCESS (x, y, enable)
BEGIN
<some code statements>
END PROCESS;
END architecture_name;
Example of architecture for Half adder gate:
BEGIN
PROCESS (x, y, enable)
BEGIN
IF enable = ‘1’ THEN
result <= x XOR y;
carry <= x AND y;
ELSE
carry <= ‘0’;
result <= ‘0’;
END IF;
END PROCESS;
END half_adder_a;
Note an entity can have multiple architectures. One can think of entity as the function interface and architecture as different method implementations.
There can be three types of architectures like:
- one can defined structure using design of sub-components and interconnections
- second type is to have a sequence of statements (dataflow)
- third type captures the timing and functional characteristics
Key terms in VHDL programming:
- Packages: collection of declaration, constants and subprograms for entities and architecture
- Generics: method for storing data (like a variable)
- Ports: method for a device to communicate with external devices. It defines name, direction and default value for signals.
- Configuration: method to attach instances to entities
- Bus: method for communication
- Driver: source of signal
- Attribute: information about an VHDL object
Ports
Port defines the interface for signals (information) for the external devices. Port has the following components:
- Name
- Mode
- Data type
- Initial value of signal (optional)
Syntax:
PORT (signal_name : mode data_type);
Example:
PORT ( input : IN BIT_VECTOR(3 DOWNTO 0);
ready, output : OUT BIT );
Mode in Port defines the direction of signal. It can have the following values:
- In: data comes in only for reading
- Out: data goes to an external device
- Buffer: data is birectional and it takes one direction at a time based on driver
- Inout: data is birectional and controlled by multiple drivers
- Linkage: direction of data is not predefined
Generics
Generics defines the method to store data like a variable.
Syntax:
GENERIC (generic_name : type [:= default_value]);
Example:
GENERIC (My_ID : INTEGER := 37);
VHDL programming constructs
- Comments
Comment is defined by two dashes like:
-- this is a comment
- Identifier
An letter including underscore and digit like
og
- Character and strings
Characters are defined by single quotes and strings are defined by double quotes like:
'o' -- this is a character
"opengenus" -- this is a string
- Bit strings
Bit strings have a special identifer at the beginning followed by a string like:
B"0101" -- binary
O"641" -- octal
X"9A" -- hexadecimal
Data types
VHDL is a strongly typed language. There are three types of data types:
-
Scalar
-
Composite
-
Access
-
Scalar is atomic unit of information like an integer
-
Composite is a data structure like array
-
Access to pointer to a data
Variables are defined in PROCESS section of architecture and used in BEGIN section like:
ARCHITECTURE test_int OF test IS
BEGIN
PROCESS (X)
VARIABLE a: INTEGER;
BEGIN
a := 1; -- OK
a := 1.0; -- error as 1.0 is not integer
END PROCESS;
END test_int;
Accordingly, REAL datatype can be real value between -1 * 10^38 and 1 * 10^38. Example of using REAL:
ARCHITECTURE test_real OF test IS
BEGIN
PROCESS (X)
VARIABLE a: REAL;
BEGIN
a := 1.01; -- OK
a := -10.01; -- OK
a := 1.1E11; -- OK
a := 1; -- error
END PROCESS;
END test_real;
Enumerated datatype
Enumerated data types define possible values for a given variable like:
TYPE bit IS ( 0, 1 );
bit can take only 0 and 1.
Complete Example:
TYPE bit IS ( 0, 1 );
... some statements ...
ARCHITECTURE test_enum OF test IS
BEGIN
PROCESS (X)
VARIABLE a: binary;
BEGIN
a := 0; -- OK
-- more statements ...
a := 1; -- OK
-- more statements ...
END PROCESS;
END test_enum;
Array
An array in VHDL is defined as follows:
type 2Darray is array ( 0 to 4, 0 to 40 ) of real;
Example of 1D array as a data bus:
TYPE data_bus IS ARRAY(0 TO 31) OF BIT;
Use:
VARIABLE X : data_bus;
VARIABLE Y : BIT;
Y := X(10); -- Y gets value of element at index 10
Record
RECORD is used to group different variables of different types in the same VHDL object like (data_info is a record):
TYPE binary IS ( ON, OFF );
TYPE data_info IS
RECORD
status : BINARY;
ID : INTEGER;
END RECORD;
...
VARIABLE data : data_info;
data.status := ON; -- status of the data
data.ID := 30; -- ID of the data
Subtypes
Subtypes allow user defined constraints on existing data types.
Syntax:
SUBTYPE name IS base_type RANGE <user range>;
Example:
SUBTYPE first_ten IS INTEGER RANGE 0 TO 9;
There are four types of objects in VHDL:
- Constants
- Variables
- Signals
- Files
Constant
Constants are variables whose data does not change after initialization.
Syntax:
CONSTANT constant_name:type_name[:=value/expression];
Example:
CONSTANT PI : REAL := 3.14;
CONSTANT SPEED : INTEGER;
CONSTANT N : INTEGER := 8*SPEED;
Variable
Syntax for variable:
VARIABLE variable_name : type_name [:= value];
Syntax for assignment of value to a variable:
[label:] name := expression ;
Example:
VARIABLE opcode : BIT_VECTOR(3 DOWNTO 0) := "0000";
VARIABLE freq : INTEGER;
VARIABLE start : time := 0 ns;
VARIABLE finish : time := 0 ns;
-- equivalent to
VARIABLE start, finish : time := 0 ns;
ns is the unit defined by default in VHDL.
Signal
Signal is used for communication between different VHDL components.
Syntax:
SIGNAL signal_name : type_name [:= value]
Example:
SIGNAL day : BIT;
day <= ‘0’ AFTER 5ns, ‘1’ AFTER 10ns;
This brings in the concept of timing model as if day is 0, next statement is executed after 5 nanoseconds and if it is 1, the delay becomes 10 nanoseconds.
There are different types of delay like inertia delay but we shall cover it in a separate post.
Following are the types of operators in VHDL:
- Miscellaneous operators:
**
, abs, not - Multiplication operators: *, /, mod, rem
- Sign operator: +, -
- Addition operators: +, -, &
- Shift operators: sll, srl, sla, sra, rol, ror
- Relational operators: =, /=, <, <=, >, >=
- Logical operators: AND, OR, NAND, NOR, XOR, XNOR
We can use the above operators to do calculations within a VHDL program like:
result <= a AND NOT(B) OR NOT(a) AND b;
There are multiple control flow statements in VHDL. One of them is if statement.
Syntax:
if_statement <=
[if_label : ]
if boolean_expression then
{ sequential_statement }
{ elsif boolean_expression then
{sequential_statement }}
[else
{ sequential_statement }]
end if [if_label];
Example:
if mode=immediate then
operand:=immed_operand;
elsif opcode=load or opcode=add or opcode=subtract then
operand:=memory_operand;
else
operand:=address_operand;
end if;
There are multiple ways to implement a loop in VHDL. We will explore a simple type with an example.
Example of a nested loop in VHDL:
begin
count<= count_value;
loop
loop
wait until clk=‘1’ or reset =‘1’;
exit when reset =‘1’;
count_value:=(count_value +1) mod 16;
Wait statement is used to pause execution while a condition is statified like:
WAIT FOR 150 ns;
Example:
Summation: PROCESS
BEGIN
Sum <= A XOR B XOR Cin;
WAIT UNTIL A = ‘1’;
END PROCESS Summation;
Functions
We can define functions in VHDL as well. Example of function:
FUNCTION add_bits
(a, b : IN BIT)s
Example of using the above function:
ARCHITECTURE behavior OF adder IS
BEGIN
PROCESS (enable, x, y)
BEGIN
IF (enable = '1') THEN
result <= add_bits(x, y);
carry <= x AND y;
ELSE
carry, result <= '0';
END PROCESS;
END behavior;
Further, we can define several VHDL program components like packages, assertions, subprograms, binding, generic maps and others which is covered in our advanced guide to VHDL programming.
In this article, we have explored all basic VHDL programming concepts and you are good to write most basic programs like implementing a half adder, full adder, stimulating a data flow system and many more.