VHDL Unit 2 Part 4
VHDL Unit 2 Part 4
VHDL Unit 2 Part 4
HDLs are indeed similar to programming languages but not exactly the same. We
utilize a programming language to build or create software, whereas we use a
hardware description language to describe or express the behavioral characteristics
of digital logic circuits.
Hardware description languages allow you to describe a circuit using words and
symbols, and then development software can convert that textual description into
configuration data that is loaded into the FPGA in order to implement the desired
functionality.
VHDL is a hardware description language that is used to describe the behavior and
structure of digital systems. The acronym VHDL stands for VHSIC Hardware
Description Language, and VHSIC in turn stands for Very High Speed Integrated
Circuit. However, VHDL is a general-purpose hardware description language which
can be used to describe and simulate the operation of a wide variety of digital
systems. Keep in mind it’s H D L…
Advantages of VHDL
– It’s like the assembly language of HDLs.
– Simple
VHDL a1 b1
VHDL 2
a2 b2
6
CODE Synthsize 3
a3
FPLD b3
7
4 8
Software a4
GND
0
b4
Widely used for FPGAs and military A better grasp on hardware modeling
VHDL Terminologies
1) Entity: All designs are expressed in terms of entities. An entity is
themost basic building block in a design.
2) Architecture: All entities that can be simulated have an architecture
description. The architecture describes the behavior
of the entity. A single entity can have multiple
architectures. One architecture might be behavioral while
another might be a structural description of the design.
3) Configuration: A configuration statement is used to bind a
component instance to an entity-architecture pair. A
configuration can be considered like a parts list
for a design. It describes which behavior to use for each entity,
much like a parts list describes which part to use for each part in
the design.
4) Package: A package is a collection (library) of
commonly used data types and subprograms
used in a design. Think of a package as a tool- box that
contains tools used to build designs.
5) Driver. This is a source on a signal. If a signal is driven by two
sources, then when both sources are active, the signal will have
two drivers.
6) Bus. The term “bus” usually brings to mind a group of signals
or a particular method of communication used in the design of
hardware. In VHDL, a bus is a special kind of signal that may
have its drivers turned off.
7) Attribute: An attribute is data that are
attached to VHDL objects or predefined data
about VHDL objects (type of objects like type
of variables in C). Examples are the current drive
capability of a buffer or the maximum operating temperature
of the device.
8) Generic: A generic is VHDL’s term for a parameter
that passes information to an entity. For
instance, if an entity is a gate level model with a
rise and a fall delay, values for the rise and
fall delays could be passed into the entity
with generics.
The following is an example of an entity for an AND gate that
has threegenerics associated with it:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY test IS
COMPONENT AND2
GENERIC(rise, fall : TIME; load : INTEGER);
PORT ( a, b : IN std_logic;
c : OUT std_logic);
END COMPONENT;
BEGIN
U1: AND2
GENERIC MAP(10 ns, 12 ns, 3 )
PORT MAP (ina, inb, out1 );
U2: AND2
GENERIC MAP(9 ns, 11 ns, 5 )
Structural Description
The circuit of Figure can also be described using structural VHDL code. To do so
requires that a two-input AND-gate component and a two-input
OR-gate component be declared and defined. Components may be
declared and defined either in a library or within the
architecture part of the VHDL code.
Lexical Elements
Lexical elements are basic syntactical units in a VHDL program and include
1) Comments:
Comments start with two dashes, e.g.,
-- This is a comment in VHDL
2) Identifiers:
An identifier can only contain alphabetic letters, decimal digits
and underscore; the first character must be a letter and the last character
cannot be an underscore. Also,two successive underscores are not allowed.
Valid examples:
A10, next_state, NextState, mem_addr_enable
Invalid examples:
sig#3, _X10, 7segment, X10_, hi_ _there
3) Reserved words
4) Numbers:
Integer: 0, 1234, 98E7
Real: 0.0, 1.23456 or 9.87E6
Base 2: 2#101101#
5) Characters
‘A’, ‘Z’, ‘1’
6) Strings
“Hello”, “1100111”
Note that 0 and ‘0’ are different
7) VHDL is case INsensitive, i.e., the following identifiers are the same
nextstate,NextState, NEXTSTATE, nEXTsTATE.
8) Use CAPITAL_LETTERs for constant names and the suffix_n to indicate active
low signals
Propagation Delay
When we initially describe a circuit, we may not be concerned about propagation
delays. If we write
C <= A and B;
E <= C or D;
this implies that the propagation delays are 0 ns. In this case, the
simulator will assume an infinitesimal delay referred to as Δ (delta).
Assume that initially A = 1 and B = C = D = E = 0. If B is changed to 1 at time = 1
ns, then C will change at time 1 + Δ and E will change at time 1 + 2 Δ.
Unlike a sequential program, the order of the above
concurrent statements is unimportant. If we write
E <= C or D;
C <= A and B;
the simulation results would be exactly the same as before. In general, a signal
assignment statement has the form
value of ‘sel’)
i1 AFTER 10 ns WHEN 1,
i2 AFTER 10 ns WHEN 2,
i3 AFTER 10 ns WHEN 3,
‘X’ AFTER 10 ns WHEN OTHERS;
Repeated Execution
Even if a VHDL program has no explicit loops, concurrent statements may execute
repeatedly as if they were in a loop. Figure shows an inverter with the output
connected back to the input. If the output is ‘0’, then this ‘0’ feeds back to the input
and the inverter output changes to ‘1’ after the inverter delay, assumed to be 10 ns.
Then, the ‘1’ feeds back to the input, and the output changes to ‘0’ after the inverter
delay. The signal CLK will continue to oscillate between ‘0’ and ‘1’, as shown in
the waveform. The corresponding concurrent VHDL statement will produce the
same result. If CLK is initialized to ‘0’, the statement executes and CLK changes to
‘1’ after 10 ns. Because CLK has changed, the statement executes again, and CLK
will change back to ‘0’ after another 10 ns. This process will continue indefinitely.
Syntax Rules
In general, VHDL is not case sensitive, that is, capital and
lower case letters are treated the same by the compiler and
the simulator. Thus, the statements
Clk <= NOT clk After 10 NS;
and CLK <= not CLK after 10 ns;
would be treated exactly the same.
Signal names and other VHDL identifiers may contain letters, numbers, and the
underscore character (_). An identifier must start with a letter, and it cannot end with
an underscore. Thus, C123 and ab_23 are legal identifiers, but 1ABC and ABC_ are
not. Every VHDL statement must be terminated with a
semicolon. Spaces, tabs, andcarriage returns are treated in the same way. This
means that a VHDL statement can be continued over several lines, or several
statements can be placed on one line. In a line of VHDL code, anything
following a double dash (--) is treated as a comment.Words such
as and, or, and after are reserved words (or keywords) which have a special
meaning to the VHDL compiler.
Figure shows three gates that have the signal A as a common input and the corresponding
VHDL code. The three concurrent statements execute simultaneously
whenever A changes, just as the three gates start processing the
signal change at the same time. This is Instantiation. If all 3 gates
have same propagation delays, output D,E and F after at the same
time. However, if the gates have different delays, the gate outputs
can change at different times. If the gates have delays of 2 ns, 1 ns,
and 3 ns, respectively, and A changes at time 5 ns, then the gate
outputs D, E, and F can change at times 7 ns, 6 ns, and 8 ns,
respectively. The VHDL statements work in the same way. Even
though the statements execute simultaneously, the signals D, E,
and F areupdated at times 7 ns, 6 ns, and 8 ns.
Figure shows a 2-to-1 multiplexer (MUX) with two data inputs and one
control input. The MUX output is F = A’.I0 + A·I1. The
corresponding VHDL statement is F <= (not A and I0) or
(A and I1);
Alternatively, we can represent the MUX by a Conditional Signal
Assignment Statement, as shown in Figure. This statement
executes whenever A, I0, or I1 changes. The MUX output is I0 when A
= ‘0’, and else it is I1. In the conditional statement, I0, I1, and F can
either be bits or bit-vectors.
The general form of a conditional signal assignment statement is:
when condition1
else expression2
when condition2
[else expressionN];
else
I1 when
A&B=“01”
else
I2 when
A&B=“10”
else I3;
else I1 when
else I2 when A
else I3;
Select Statement
A third way to model the MUX is to use a selected signal
assignment statement, as shown in Figure . A&B cannot be used in
this type of statement, so
...
[expression_n [after delay-time] when others];
Sequential Statements
1) IF Statement
IF condition THEN sequence_of_statements
{ELSIF condition THEN sequence_of_statements}
[ELSE
sequence_of_statements]
END IF;
Example:
2) CASE Statement
Example:
TYPE vectype IS ARRAY(0 TO 1) OF BIT;
VARIABLE bit_vec : vectype;
.
CASE bit_vec IS
WHEN “00” =>RETURN 0;
WHEN “01” =>RETURN 1;
WHEN “10” =>RETURN 2;
WHEN “11” =>RETURN 3;
END CASE;
3) LOOP Statement
Example:
Syntax is:
[label:] process (sensitivity list)
constant or variable declarations
begin
sequential statements;
end process [label];
Example:
PROCESS(i)
BEGIN
x <= i + 1; -- x is a signal
FOR i IN 1 to a/2 LOOP
q(i) := a; -- q is a variable
END LOOP;
END PROCESS;
5) NEXT Statement:
The process statement contains one LOOP statement. This LOOP statement logically
“and”s the bits of arrays a and b and puts the results in array q. The NEXT statement
allows the designer the ability to stop execution of this iteration and go on to the next
iteration. There are other cases when the need exists to stop execution of a loop
completely. This capability is provided with the EXIT statement. This behavior
continues whenever the flag in array done is not true. If the done flag is already set for
this value of index i, then the NEXT statement is executed. If the value of the done
array is not true, then the NEXT statement is not executed, and execution continues with
the statement contained in the ELSE clause for the IF statement.
Example:
PROCESS(A, B)
CONSTANT max_limit : INTEGER := 255;BEGIN
FOR i IN 0 TO max_limit LOOP
IF (done(i) = TRUE) THEN
NEXT;
ELSE
done(i) := TRUE;
END IF;
q(i) <= a(i) AND b(i);
END LOOP;
END PROCESS;
6) EXIT Statement
During the execution of a LOOP statement, it may be necessary to jump out of the loop.
This can occur because a significant error has occurred during the execution of the model
or all of the processing has finished early. The VHDL EXIT statement allows the
designer to exit or jump out of a LOOP statement currently in execution.
Example:
PROCESS(a)
variable int_a : integer;
BEGIN
int_a := a;
y <= q;
END PROCESS;
7) WAIT Statements
The WAIT statement gives the designer the ability to suspend the sequential execution of
a process or subprogram. The conditions for resuming execution of the suspended process
or subprogram can be specified by the following three different means:
WAIT ON signal changes
WAIT UNTIL an expression is true
WAIT FOR a specific amount of time
PROCESS
BEGIN
WAIT UNTIL clock = ‘1’ AND clock’EVENT;
q <= d;
END PROCESS;
This process is used to generate a flip-flop that clocks the value of d into q when the
clock input has a rising edge. The attribute ‘EVENT attached to input clock is true
whenever the clock input has had an event during the current delta timepoint. The
effect is that the process is held at the WAIT statement until the clock has a rising
edge. Then the current value of d is assigned to q.
Reading this description into a synthesis tool creates a D flip-flop without a set or reset
input. A synchronous reset can be created by the following:
PROCESS
BEGIN
WAIT UNTIL clock = ‘1’ AND clock’EVENT;
IF (reset = ‘1’) THEN
q <= ‘0’;
ELSE
q <= d;
END IF;
END PROCESS;
PROCESS
BEGIN
IF (reset = ‘1’) THEN
q <= ‘0’;
ELSIF clock’EVENT AND clock = ‘1’ THEN
q <= d;
END IF;
To write a complete VHDL module, we must declare all of the input and output
signals using an entity declaration, and then specify the internal operation of the
module using an architecture declaration.
As an example, consider above Figure. The entity declaration gives the name “two_gates” to the
module. The port declaration specifies the inputs and outputs to the module. A, B, and D are
input signals of type bit, and E is an output signal of type bit. The architecture is named “gates”.
The signal C is declared within the architecture because it is an internal signal. The two
concurrent statements that describe the gates are placed between the keywords begin and end.
When we describe a system in VHDL, we must specify an entity and an architecture at the top
level, and also specify an entity and architecture for each of the component modules that are
part of the system (see below figure).
Entity Declaration
Each entity declaration includes a list of interface signals that can be used to connect to other
modules or to the outside world. We will use entity declarations of the form:
entity entity-name is
[port(interface-signal-declaration);]
end [entity] [entity-name];
A system (an entity) can be specified with different architectures.
Port Clause:
I/O Signals are called ports. The optional initial-value is used to initialize the signals on the
associated list; otherwise, the default initial value is used for the specified type. For example,
the port declaration
indicates that A and B are input signals of type integer that are initially set to 2, and
C and D are output signals of type bit that are initialized by default to ‘0’.
Note port signals i.e ports, of the same mode and type or subtype may be declared on the same
line. Input signals are of mode in, output signals are of mode out, and bi-directional signals are
of mode inout.
2) Out - data travels out this port. The signal driver is inside this component.
3) Buffer - data may travel in either direction, but only one signal driver may be ON
at any one time. There may be signal drivers inside and outside this component.
However, only one of these drivers can be driving the signal at any one time.
4) Inout - data may travel in either direction with any number of active drivers
allowed; requires a Bus Resolution Function. There may be signal drivers inside and
outside this component. Any number of these drivers can be driving the signal
simultaneously.
5) Linkage - direction of data flow is unknown. The location of signal drivers is not
known.
Driver Creation
Drivers are created by signal assignment statements. A concurrent signal assignment
inside of an architecture produces one driver for each signal assignment.
Therefore, multiple signal assignments produce multiple drivers for a signal.
Consider the following architecture:
Signal a is being driven from two sources, b and c. Each concurrent signal
assignment statement creates a driver for signal a. The first statement creates a driver
that contains the value of signal b delayed by 10 nanoseconds. The second statement
creates a driver that contains the value of signal c delayed by 10 nanoseconds.
Event Scheduling
The assignment to signal x does not happen instantly. Each of the values assigned to
signal x contain an AFTER clause. The mechanism for delaying the new value is
called scheduling an event. By assigning port x a new value, an event was scheduled
0.5 nanoseconds in the future that contains the new value for signal x. When the
event matures (0.5 nanoseconds in the future), signal x receives the new value.
1) AND Gate
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
2) OR Gate
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
3) 4-to-1 Multiplexer
1) AND Gate
2) OR Gate
3) 4-to-1 Multiplexer
The instantiation has 3 key parts: Name, Component type and Port map
Example of Instantiation:
VHDL Design Examples
I) Half-adder Module
Entity Declaration:
As a first step, the entity declaration describes the interface of the component: input and output
ports are declared.
The PORT statement lists the signals in the component’s interface, the direction of dataflow for
each signal listed and the type of each signal. Here signals x,y and enable are of direction IN
(input) of type BIT and carry and result are OUT of type BIT.
Architecture Declaration:
Architecture Body describes the operation of the component. It consists of two parts:
1) Declarative part -- includes necessary declarations
e.g. type declarations, signal declarations, component declarations, subprogram
declarations
2) Statement part -- includes statements that describe organization and/or functional
operation of component
e.g. concurrent signal assignment statements, process statements, component instantiation
statements.
The architecture body starts with the keyword ARCHITECTURE followed by the name
of the architecture (e.g. half_adder_d above) and the name of the entity with which the
architecture is associated. The keyword BEGIN marks the beginning of the architecture
statement part which may include concurrent signal assignment statements and processes.
Any signals that are used internally in the architecture description but are not found in
the entity's ports are declared in the architecture’s declarative part before the BEGIN
statement of the architecture body. The keyword END marks the end of architecture body.
A) Behavioral Specification:
A high-level description can be used to describe the function of the circuit.
B) Data Flow Specification:
A second method is to use logic equations to develop a data flow description.
C) Structural Specification:
As a third method, a structural description can be created from pre-described components in
ENTITY.
The structural description shows the declaration of a local signal ( i.e xor_res defined with
keyword SIGNAL) to be used in connecting the components together.
A) Behavioral Specification:
B) Data Flow Specification:
C) Structural Specification:
COMPONENT and_gate
PORT(m,n: IN BIT;
o:OUT BIT);
END COMPONENT
COMPONENT or_gate
PORT(s,t: IN BIT;
u:OUT BIT);
END COMPONENT
END
III) 4-to-1Multiplexer
Structural Specification:
A variable ‘temp’ is declared in Architecture whose value will be assigned to A/B/C/D and
ultimately to output Q
IV) 2-to-4 Decoder
Structural Specification:
The components used in the design are defined using the VHDL description shown here:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY inv IS -- Entity of Inverter defined
PORT( a : IN std_logic;
b : OUT std_logic);
END inv;
I2 : inv
PORT MAP(b, notb);
A1 : and3
PORT MAP(nota, en, notb, Q0);
A2 : and3
PORT MAP(a, en, notb, Q1);
A3 : and3
END structural;
D SET Qn+1
D Q
Clock
CLR
Q
Reset
Behavioral Description:
Process (d,clock,reset)
begin
if (reset = ‘0’) then
q <= ‘0’;
elsif( clock’event and clock=‘1’) then
q <= d;
end if;
end process;
VI) Register
ns R ps
E
G
clk
Reset
Behavioral Description:
We can also define a S0 as constant to indicate reset state value of the register.
Signal ns,ps:std_logic_vector(7 downto 0);
Constant S0:std_logic_vector(7 downto 0) := “00000000”;
……..
reg:Process (ns,clock,reset) --‘reg’ is a process here
begin
if (reset = ‘0’) then
ps <= s0; --- use ‘reset’ state -- output is assigned to the constant defined
elsif( clock’event and clock=‘1’) then
ps <= ns;
end if;
end process reg;
bit1
d_latch
d1 q1
d q
clk
bit2
d_latch
d2 q2
d q
clk
bit3
d_latch
d3 q3
d q
gate clk
and2
en int_clk
a y
clk
b
First define entity and architecture for D-Latch and AND gate as follows:
ENTITY reg4 IS
port(d0,d1,d2,d3,en,clk : IN std_logic; -- OR write as IN bit
q0,q1,q2,q3: OUT std_logic); -- OR write as OUT bit
END reg4
COMPONENT d_latch
port(d, clk : IN std_logic; -- OR write as IN bit
q: OUT std_logic); --OR write as OUT bit
end COMPONENT
COMPONENT and2
port(a, b: IN std_logic; -- OR write as IN bit
y: OUT std_logic); --OR write as OUT bit
end COMPONENT
library ieee;
use ieee.std_logic_1164.all;
entity shift is
port (CLK, RST, LOAD : in bit;
Data : in bit_vector(0 to 7);
Q : out bit_vector(0 to 7));
end shift;
A variable ‘temp’ is declared in Architecture of Vector type, whose value will be assigned
to ‘data’ and which will be ultimately shifted
IX) Full-adder
Next, we will write the entity and architecture for a full adder module. The entity specifies the
inputs and outputs of the adder module, as shown in following Figure. The port declaration
specifies that X, Y and Cin are input signals of type bit, and that Cout and Sum are output
signals of type bit.
The VHDL assignment statements for Sum and Cout represent the logic equations
(dataflow statements) for the full adder. Several other architectural descriptions such as a
truth table (behavioral description) or an interconnection of gates (structural description)
could have been used instead. In the Cout equation, parentheses are required around (X and
Y) because VHDL does not specify an order of precedence for the logic operators.
Alternate Way
entity FULLADDER is
port (a,b,c: in bit
sum,carry: out bit)
end FULLADDER
Use of two-valued logic (bits and bit vectors) is generally not adequate for simulation of digital
systems. In addition to ‘0’ and ‘1’, values of ‘Z’ (high-impedance or no connection) and
‘X’ (unknown) are frequently used in digital system simulation. The IEEE Standard 1164
defines a std_logic type that actually has nine values (‘U’, ‘X’, ‘0’, ‘1’, ‘Z’, ‘W’, ‘L’, ‘H’,
and ‘–’). We will only be concerned with the first five values. ‘U’ stands for uninitialized.
When a logic circuit is first turned on and before it is reset, the signals will be
uninitialized. If these signals are represented by std_logic, they will have a value of ‘U’
until they are changed. Just like a group of bits is represented by a bit_vector, a group of
std_logic signals is represented by a std_logic_vector.
Figure shows how a tri-state buffer can be represented by a concurrent statement. When the
buffer is enabled (B = ‘1’), the output is A, or else it is high impedance (‘Z’). A and C
could be std_logic_vectors instead of std_logic bits.
Figure shows two tri-state buffers with their outputs connected together by a tri-state bus. If
buffer 1 has an output of ‘1’ and buffer 2 has a hi-Z output, the bus value is ‘1’. When
both buffers are enabled, if buffer 1 drives ‘0’ onto the bus and buffer 2 drives ‘1’ onto the
bus, the result is a bus conflict. In this case, the bus value is unknown, which we represent
by an ‘X’.
In the VHDL code, A, C, and F are std_logic_vectors and F represents the tri-state bus. The
signal F is driven from two different sources. If the two concurrent statements assign
different values to F, VHDL automatically calls a resolution function to determine the
resulting value. This is similar to the way the hardware works if the two buffers have
different output values, the hardware resolves the values and comes up with an
appropriate value on the bus. VHDL uses the following table to resolve the bus value when
two different std_logic signals, S1 and S2, drive the bus. (Only signal values ‘U’, ‘X’, ‘0’, ‘1’,
and ‘Z’ are considered here.) When an uninitialized signal is connected to any other signal,
VHDL considers that the result is uninitialized.
If A, B, and F are bits (or bit_vectors) and we write the concurrent statements
F <= A; F <= not B;
the compiler will flag an error because no resolution function exists for signals of type bit.
If A, B, and F are std_logic bits or vectors, the compiler will generate a call to the
resolution function and not report an error. If F is assigned conflicting values during
simulation, then F will be set to ‘X’ (unknown).
library ieee;
use ieee.std_logic_1164.all;
The IEEE std_logic_1164 package defines std_logic and related types, logic operations on
these types, and functions for working with these types.
The original IEEE standards for VHDL do not define arithmetic operations on bit_
vectors or on std_logic vectors.
For example, if A and B are bit_vectors, the expression A + B is not allowed. However, VHDL
libraries and packages are available that define arithmetic and comparison operations on
std_logic_vectors. The operators defined in these packages are referred to as overloaded
operators. This means that the compiler will automatically use the proper definition of the
operator depending on its context. For example, when evaluating the expression A + B, if A
and B are integers, the compiler will use the integer arithmetic routine to do the addition. On the
other hand, if A and B are of type std_logic_vector, the compiler will use the addition routine
for standard logic vectors. In order to use overloaded operators, the appropriate library
and use statements must be included in the VHDL code so that the compiler can locate the
definitions of these operators.
If A and B are 4-bit std_logic vectors, A+B gives their sum as a 4-bit vector and carry, if any, is
lost. If the carry is needed then A must be extended to 5-bits before addition. This is
accomplished by concatenating a ‘0’ in-front of A. Then ‘0’& A+B gives a 5-bit addition
which can be split into 4-bit sum and 1-bit carry.
The figure shows a binary adder and its equivalent VHDL code using the std_logic_unsigned
package. Addout is a 5-bit addition which is split into 4-bit sum and 1-bit carry. e.g if
A=”1011” and B=”1001” and Cin = 1 then Addout = “10101” which is split into sum=”0101”
and carry=’1’.
Use Clause
Achieves direct visibility of declarations that are visible by selection.
Syntax
use library_name.package_name.item;
use library_name.package_name;
use library_name.package_name.all;
Description
The use clause makes visible items specified as suffixes in selected names listed in the clause. In
practice, the use clause makes visible declarations specified in packages and has the following
form:
USE library_name.package_name.item
If a designer wants to have all declarations in a package visible, then the 'item' clause
should be substituted by the reserved word all.
The use clause is valid for the design unit immediately following it and for all secondary design
units assigned to this design unit (if it is a primary design unit).
Examples
In the first example, all declarations specified in the package Std_Logic_1164 (which belongs
to the library IEEE) have been made visible.
The second example makes visible the Rising_Edge function, which is declared in the same
package i.e Std_Logic_1164. The function uses the type Std_ulogic, therefore declaration of
this type is also made visible.
All declarations of VHDL ports, signals, and variables must specify their corresponding type or
subtype.
1) Scalar Type
A) Integer, Natural, Positive
Minimum range for any implementation as defined by standard: - 2,147,483,647 to
2,147,483,647
The data types integer, natural, positive are defined in standard package, i.e., we don’t
need to include an extra package at the header of the VHDL program. The data type
integer is used to represent integer numbers in the range —231 to 231 — 1 (- 2,147,483,647
to 2,147,483,646)
The data type natural is used to represent the integers in the range 0 to 231 — 1. On the
other hand, the data type positive is used to represent the integers in the range 1 to 231 —
1.
B) Unsigned, Signed
The data types unsigned and signed are defined in the packages numeric_std and
std_logic_arith. One of these packages should be included in the header of the VHDL
program to be able to use these data types in entity declarations. The data type unsigned is
used to represent unsigned numbers, i.e., non-negative integers, and the data type signed
is used to represent the signed numbers, i.e., integers.
C) Real:
Minimum range for any implementation as defined by -1.0E38 to 1.0E38
D) Enumerated
User specifies list of possible values. Example declaration and usage of enumerated data type:
E) Physical
Require associated units. Range must be specified. Example of physical type declaration:
2) Access Type
Analogous to pointers in other languages. Allows for dynamic allocation of storage. Useful for
implementing queues, etc.
3) Package Type
A package allows items to be shared, such as: constants, data types, subprograms (procedures
and functions). A package contains a package declaration and (optional) package body.
A) Standard Package
Used implicitly by all design entities. Included in VHDL source files by implicit USE
clause. Defined in VHDL Language Reference Manual. In this package, the data types
included are: bit, bit_vector, integer, positive, natural, character, string, boolean.
The data type is mentioned using keyword TYPE.
i) bit
The bit data type is defined in standard package, i.e., we don’t need to include an extra
package at the header of the VHDL program. For instance, if we use data type bit for port
I/Os, we can write following VHDL code where it is seen that no header file is needed.
entity my_circuit_name is
port( inp1: in bit;
inp2: in bit;
outp1: out bit;
outp2: out bit;
outp3: out bit);
end my_circuit_name;
ii) bit_vector
The bit_vector data type is defined in standard package, i.e., we don’t need to include
an extra package at the header of the VHDL program. If an I/O port has data type of
bit_vector, it means that the I/O port has a number of bit values.
B) IEEE std_logic_1164 package
To use:
library ieee;
use ieee.std_logic_1164.all;
i) std_logic
entity my_circuit_name is
port( inp1, inp2: in std_logic; --Input ports
outp1, outp2, outp3: out std_logic ); --Output ports
end my_circuit_name; -- End of entity
In PR 1.17 the data type used for the ports is std_logic defined in the package IEEE.
std_logic_1164.all. For std_logic data type, there are 8 possible values available, and these
values are listed below:
ii) std_logic_vector
The std_logic_vector data type is defined in the library IEEE.std_logic_1164.all. If an
I/O port has data type of std_logic_vector, it means that the I/O port has a number of
std_logic values.
e.g.,
signal a: std_logic_vector(7 downto 0);
Most significant bit is labelled 7 -- best representation for numbers. Another form can be used
in cases where you are not representing numbers, but rather control signals
signal a: std_logic_vector(0 to 7);
Example
The black box representation of an electronic circuit is shown in following figure.
Describe the electronic circuit ports by a VHDL program.
(a) Use the data type std_logic_vector to describe the ports in entity part.
(b) Use the data type bit_vector to describe the ports in entity part.
(c) Use the data type integer to describe the ports in entity part.
(d) Use the data type natural to describe the ports in entity part.
(e) Use the data type positive to describe the ports in entity part.
(f) Use the data type unsigned to describe the ports in entity part.
(g) Use the data type signed to describe the ports in entity part.
Solution
(a)
We can write the entity segment using the data type std_logic_vector. However, in this
case since bit_vector is not defined in standard package, we need to include header
file i.e IEEE package which is IEEE.std_logic_1164.all
library IEEE;
use IEEE.std_logic_1164.all;
entity FourBit_Circuit is
port( inp1: in std_logic_vector(3 downto 0);
inp2: in std_logic_vector(3 downto 0);
outp1: out std_logic_vector(4 downto
0); outp2: out std_logic_vector(4
downto 0) );
end entity;
(b)
We can write the entity segment using the data type bit_vector. However, in this case
since bit_vector is defined in standard package, we don’t need to include any header
file.
entity FourBit_Circuit is
port( inp1: in bit_vector(3 downto 0);
inp2: in bit_vector(3 downto 0);
outp1: out bit_vector(4 downto 0);
outp2: out bit_vector(4 downto 0)
);
end entity;
(c)
We can write the entity segment using the data type integer. The data type integer is defined
in standard package; we don’t need to include any header file. However, it is logical to
indicate a range for the integer data type. It is seen from given figure that the circuit accepts
4-bit inputs, and there is no additional information about the sign of the input number. If we
assume that the port accepts non-negative integers, with 4-bits we can get integers in the
range 0–15 and 0 to 31 with 5-bits. Thus, we can write the entity segment as below:
entity FourBit_Circuit is
port( inp1: in integer range 0 to 15;
inp2: in integer range 0 to 15;
outp1: out integer range 0 to 31;
outp2: out integer range 0 to 31 );
end entity;
However, if we assume that the circuit port accepts both positive and negative integers, in
this case, using 4-bits we can get the integers in the range —8 to 7, and using 5-bits we
can get integers in the range —16 to 15.
entity FourBit_Circuit is
port( inp1: in integer range -8 to 7;
inp2: in integer range -8 to 7;
outp1: out integer range -16 to
15;
outp2: out integer range -16 to 15 );
end entity;
(d)
The data type natural is used to indicate the non-negative integers. Using 4 bits we can
represent the non-negative integers in the range 0–15. The natural is defined in the standard
package.
entity FourBit_Circuit is
port( inp1: in natural range 0 to 15;
inp2: in natural range 0 to 15;
outp1: out natural range 0 to 31;
outp2: out natural range 0 to 31
);
end entity;
(e)
The data type positive is used to indicate the positive integers. Using 4 bits we can
represent the positive integers in the range 1–15. The positive is defined in the
standard package.
entity FourBit_Circuit is
port( inp1: in positive range 1 to 15;
inp2: in positive range 1 to 15;
outp1: out positive range 1 to 31;
outp2: out positive range 1 to 31 );
end entity;
(f)
The data type unsigned is used to represent the non-negative integers of any
number of bits. The difference of this representation from that of the natural is that
we decide on the number of bits to be used to represent the non-negative integers as
a bit vector. To be able to use the unsigned data type in our VHDL programs we need to
use IEEE.numeric_std.all package at our header.
library IEEE;
use IEEE.numeric_std.all;
entity FourBit_Circuit is
port( inp1: in unsigned(3 downto 0);
inp2: in unsigned (3 downto 0);
outp1: out unsigned (4 downto 0);
outp2: out unsigned (4 downto 0) );
end entity;
(g)
The data type signed is used to represent the integers of any number of bits. The
difference of this representation from that of the integer is that we decide on the
number of bits to be used to represent integers as a bit vector. To be able to use the
signed data type in our VHDL programs we need to use IEEE. numeric_std.all package
at our header.
library IEEE;
use IEEE.numeric_std.all;
entity FourBit_Circuit is
port( inp1: in signed (3 downto 0);
inp2: in signed (3 downto 0);
outp1: out signed (4 downto 0);
outp2: out signed (4 downto 0)
);
end entity;
Example
The black box representation of an electronic circuit is shown in following figure.
Describe the electronic circuit ports by a VHDL entity segment. Use std_logic_vector
for the data types of the ports.
Solution
The black box illustration of the circuit shown in the figure has input, output, input/output
and buffer ports. Considering the port types, we can write a VHDL code as:
library IEEE;
use IEEE.std_logic_1164.all;
entity Electronic_Circuit is
port( inp1: in std_logic_vector(3 downto 0);
inp2: in std_logic_vector(3 downto 0);
outp1: inout std_logic_vector(3 downto 0);
outp2: out std_logic_vector(4 downto 0);
outp3: buffer std_logic_vector(4 downto 0) );
end entity;
4) Composite Type
A) Array
Used to group elements of the same type into a single VHDL object. Here the data type i.e
array is declared with keyword TYPE.
DOWNTO keyword must be used if leftmost index is greater than rightmost index
e.g. Big-Endian: bit ordering.
a <= "10100000"; -- positional association
a <= (7=>’1’, 6=>’0’, , 5=>’1’, 4=>’0’, 3=>’0’, 2=>’1’, 1=>’0’, 0=>’0’); -- named association
B) Records
Used to group elements of possibly different types into a single VHDL object. Elements are
indexed via field names.
TYPE declaration is used to define a record. Note that the types of a record’s
elements must be defined before the record is defined.
VHDL Objects
1) Constants:
Name assigned to a specific value of a type. Allows for easy update and readability.
Declaration of constant may omit value so that the value assignment may be deferred.
2) Variables:
3) Signals:
Used for communication between VHDL components. Real i.e physical signals in
system are often mapped to VHDL signals. All VHDL signal assignments require either
delta cycle or user-specified delay before new value is assumed.
A key difference between variables and signals is the assignment delay. If variable
changes then process sensitivity list fires and the new output is calculated there itself.
Whereas if signal changes then process sensitivity list fires and the new output is
calculated after the delay (mentioned or delta).
In this example, a, b, c, out_1, and out_2 are signals that are declared
elsewhere, e.g. in the component’s entity. The table indicates the values for the
various signals at the key times in the example. At time 1, a new value of 1 is
observed on a. This causes the process sensitivity list to fire and results in a 0
being assigned to out_1. The signal assignment statement for out_2 will also be
executed but will not result in a new assignment to out_2 because neither out_1 nor c
will be changed at this time. At time 1+d (i.e. 1 plus 1 delta cycle), out_1
assumes its new value i.e 0, causing the process sensitivity list to fire again. In
this process execution, the statement for out_1 will be executed again but no new
assignment will be made because its right hand side parameters have not changed.
The out_2 assignment statement, however, results in a 1 being assigned to out_2. At
time 1+2d, out_2 assumes its new value of 1. This example, then, requires 2
delta cycles and two process executions to arrive at its quiescent state
following a single change in a .
In this example, variables are used to achieve the same functionality as the example
in the previous slide. In this example, however, when there is a change in a at
time 1, out_3 will assume its new value at time 1 because it is a variable, and
VHDL variable assignment statements result in the new values being assumed
immediately. The new value for out_4, therefore, will be calculated with the new
out_3 value and results in an assignment to a value of ‘1’ being scheduled for
one delta cycle in the future.
Also note, however, that in this example, the order in which the statements appear
within the process is important because the two statements are executed
sequentially, and the process will only be executed once as a result of the
single change in a.