Apa itu VHDL?
VHDL adalah Very High-Speed Integrated Circuit (VHSIC) Hardware Description Language. VHDL adalah salah satu bahasa pemrograman yang digunakan untuk memodelkan sistem digital dengan pemodelan dataflow, behavioral dan struktural. Bahasa ini pertama kali diperkenalkan di 1981 oleh Departemen Pertahanan USA (Department of Defense (DoD) dibawah program VHSIC. Selanjutnya pada tahun 1983 IBM, Texas instruments dan Intermetrics mulai mengembangkan bahasa pemrograman ini, sehingga diluncurkanlah VHDL versi 7.2 diluncurkan di tahun 1985. Dan akhirnya di tahun 1987, bahasa permograman ini distandirisasi IEEE (Institute of Electrical and Electronic Engineering).
Gambar 1. Struktur Entity
Pada sistem VHDL sebuah entity digunakan untuk mendeskripsikan sebuah module hardware. Sebuah entity dapat dideskripsikan dengan menggunakan:
1. Entity declaration.
4. Package declaration.
5. Package body.
1. Entity declaration
It defines the names, input output signals and modes of a hardware module.
entity entity_name is
An entity declaration should starts with ‘entity’ and ends with ‘end’ keywords.
Ports are interfaces through which an entity can communicate with its environment. Each port must have a name, direction and a type. An entity may have no port declaration also. The direction will be input, output or inout.
Port can be read
Port can be written
Port can be read and written
Port can be read and written, it
can have only one source.
It describes the internal description of design or it tells what is there inside design. Each entity has atleast one architecture and an entity can have many architecture. Architecture can be described using structural, dataflow, behavioral or mixed style. Architecture can be used to describe a design at different levels of abstraction like gate level, register transfer level (RTL) or behavior level.
architecture architecture_name of entity_name
Here we should specify the entity name for which we are writing the architecture body. The architecture statements should be inside the begin and end keyword. Architecture declarative part may contain variables, constants, or component declaration.
If an entity contains many architectures and any one of the possible architecture binding with its entity is done using configuration. It is used to bind the architecture body to its entity and a component with an entity.
configuration configuration_name of entity_name is
Block_configuration defines the binding of components in a block. This can be written as
block_name is the name of the architecture body. Component binding binds the components of the block to entities. This can be written as,
4. Package declaration:
Package declaration is used to declare components, types, constants, functions and so on.
package package_name is
5. Package body:
A package body is used to declare the definitions and procedures that are declared in corresponding package. Values can be assigned to constants declared in package in package body.
package body package_name is
The internal working of an entity can be defined using different modeling styles inside architcture body. They are
a. Dataflow modeling.
b. Behavioral modeling.
c. Structural modeling.
Let’s try to understand with the help of one example.
a. Dataflow modeling:
In this style of modeling, the internal working of an entity can be implemented using concurrent signal assignment.
Let’s take half adder example which is having one XOR gate and a AND gate.
entity ha_en is
port (A,B:in bit;S,C:out bit);
architecture ha_ar of ha_en is
S<=A xor B;
C<=A and B;
Here STD_LOGIC_1164 is an IEEE standard which defines a nine-value logic type, called STD_ULOGIC. use is a keyword, which imports all the declarations from this package. The architecture body consists of concurrent signal assignments, which describes the functionality of the design. Whenever there is a change in RHS, the expression is evaluated and the value is assigned to LHS.
b. Behavioral modeling:
In this style of modeling, the internal working of an entity can be implemented using set of statements. It contains:
· Process statements
· Sequential statements
· Signal assignment statements
· Wait statements
Process statement is the primary mechanism used to model the behavior of an entity. It contains sequential statements, variable assignment (:=) statements or signal assignment (<=) statements etc. It may or may not contain sensitivity list. If there is an event occurs on any of the signals in the sensitivity list, the statements within the process is executed.
Inside the process the execution of statements will be sequential and if one entity is having two processes the execution of these processes will be concurrent. At the end it waits for another event to occur.
entity ha_beha_en is
A : in BIT;
B : in BIT;
S : out BIT;
C : out BIT
architecture ha_beha_ar of ha_beha_en is
S<= A xor B;
C<=A and B;
end process process_beh;
Here whenever there is a change in the value of a or b the process statements are executed.
c. Structural modeling:
The implementation of an entity is done through set of interconnected components. It contains:
· Signal declaration.
· Component instances
· Port maps.
· Wait statements.
component component_name [is]
end component component_name;
Before instantiating the component it should be declared using component declaration as shown above. Component declaration declares the name of the entity and interface of a component.
Let’s try to understand this by taking the example of full adder using 2 half adder and 1 OR gate.
entity fa_en is
port(A,B,Cin:in bit; SUM, CARRY:out bit);
architecture fa_ar of fa_en is
port(A,B:in bit;S,C:out bit);
HA1:ha_en port map(A,B,S1,C1);
HA2:ha_en port map(S1,Cin,SUM,C2);
CARRY <= C1 or C2;
The program we have written for half adder in dataflow modeling is instantiated as shown above. ha_en is the name of the entity in dataflow modeling. C1, C2, S1 are the signals used for internal connections of the component which are declared using the keyword signal. Port map is used to connect different components as well as connect components to ports of the entity.
Component instantiation is done as follows.
Component_label: component_name port map (signal_list);
Signal_list is the architecture signals which we are connecting to component ports. This can be done in different ways. What we declared above is positional binding. One more type is the named binding. The above can be written as,
HA1:ha_en port map(A => A,B => B, S => S1 ,C => C1 );
HA2:ha_en port map(A => S1,B => Cin, S=> SUM, C => C2);
The correctness of the above program can be checked by writing the test bench.
The test bench is used for generating stimulus for the entity under test. Let’s write a simple test bench for full adder.
entity tb_en is
architecture tb_ar of tb_en is
eut: entity work.fa_en(fa_ar)
wait for 10ns;
wait for 10ns;
wait for 10ns;
if now=30ns then
end process stimulus;
Here now is a predefined function that returns the current simulation time
What we saw upto this is component instantiation by positional and by name. In this test bench example the entity is directly instantiated. The direct entity instantiation syntax is:
Component_label: entity entity_name (architecture_name)