VHDL
VHDL
Introduuction to HDL
Introduuction to HDL
• We are familiar with the design of a digital system. The basic steps involved in
this process are,
• But as the size and complexity of digital systems increase, they cannot be
designed manually; their design becomes highly complex. At their most detailed
level, they may consists of millions of elements, i.e. transistors or logic gates.
So Computer Aided Design (CAD) tools are used in the design of such systems.
One such a tool is a Hardware Description Language (HDL).
■ The HDL provides the digital designer with a means of describing a digital
system at a wide range of levels of abstraction and at the same time, provides
access to computer-aided design tools to aid in the design process at these
levels.
■ The HDL, represents digital systems in the form of documentation which can
be understood by human as well as computers.
■ The HDL makes it easy to exchange the ideas between the designers.
■ HDLs are used to describe hardware for the purpose of simulation, modeling,
testing, design and documentation.
■ The most prominent modem HDLs in industry are Verilog and VHDL.
Verilog is one of the two major Hardware Description Languages (HDLs) used
by hardware designers in industry and academia. Of course, VHDL is the other
one.
■ Verilog is very C-like and liked by electrical and computer engineers as most
learn the C language in college. VHDL is very Ada-like and most engineers
have no experience with Ada.
■ Package (optional)
■ Entity
■ Architecture
■ Configuration (optional)
• The Fig. 10.2.1 shows the relationship of these basic blocks of VHDL program.
A design may include any number of package, entity, architecture and
configuration declarations. It is important to note that the entity and
architecture blocks are compulsorily required; however, the package and
configuration blocks are optional.
1. Entity Declaration
• It gives the specification of input/output signals to external circuitry. An
entity is modeled using an entity declaration and at least one architecture
body. An entity X, when used in another entity Y, becomes a component for
the entity Y. Entity gives interfacing between device and the other peripherals.
An entity usually has one or more ports, which are analogous to the pins on a
schematic symbol. All information must flow into and out of the entity through
the ports. Each port must contain name, data flow direction and type.
entity entity_name is
end entity_name ;
The following section describes the different elements of entity declaration.
mode : The ports can be declared in four types which specify the signal
direction.
in : This mode is used for a signal that is an input to an entity (value is read not
written).
out : It is used for a signal that is an output from an entity. The value of such a
signal can not be read inside the entity's architecture. But it can be read by
other entities those use it.
inout : It is used for a signal that is both, an input to an entity and an output
from the entity.
buffer : The signal is an output from the entity and its value can also be read
inside the entity's architecture.
For example, there is a system having its inputs and outputs like rd, wr, ADD, x,
y, z, ad, al. The entity for this can be written as shown below.
wr : in std_logic;
rd : in std_logic;
ADD : in std_logic_vector (0 to 3) ;
);
end gate_logic ;
Here rd, wr are inputs to the system so they are input ports. The ad is also
input signal but it is 8 bit so it is defined as vector (7 downto 0). It means 7 is
assigned to MSB of your signal and 0 is assigned to LSB of your signal. Similarly
x, y, z are output signals so they are defined as output ports. The al is coming
out and is defined as buffer signal, so that you can also read this signal.
2. Architecture
• Architecture specifies behavior, functionality, interconnections or
relationship between inputs and outputs. It is the actual description of the
design. An architecture consists of two portions : architecture declaration and
architecture body. An architecture body specifies the internal details of an
entity.
begin
concurrent statements;
sequential statements;
end architecture_name;
• To design any system, first we have to write the entity. In the architecture,
we write architecture_name for that entity. In declaration part, types, signals,
constants, function definitions, procedure definitions, component definitions
etc. can be declared. The variables can also be declared here. VHDL variables
are similar to signals, except that they usually do not have physical significance
in a circuit. A variable declaration is similar to a signal declaration, except that
the 'variable' keyword is used as shown below.
3. Configuration Declaration
• Configuration declarations may be used to associate particular design entities
to component instances (unique references to lower-level components) in a
hierarchical design, or to associate a particular architecture to an entity. As
their name implies, configuration declarations are used to provide
configuration management and project organization for a large design.
For HA_STRUCTURE
For XI : XOR2
end for;
For A1 : AND2
end for;
end for;
end HA_BINDING;
The library statement makes library names CMOS_LIB and MY_LIB visible
within the configuration declaration.
• As shown by the shaded portions there are two component bindings. The
component instantiation XI is bound to an entity represented by XOR-GATE
entity declaration and the DATAFLOW architecture body, which resides in the
CMOS_LIB design library. Similarly, component instantiation A1 is bound to a
configuration of an entity defined by the configuration declaration, with name
AND_CONFIG, residing in the MYJLIB design library.
4. Package Declaration
• There are some declarations which are common across many design units. A
package is a convenient mechanism to store and share such declarations. It is
an optional design unit. A set of declarations contained in a package
declaration may be shared by many design units. It defines items that can be
made visible to other design units. A package is represented by :
■ Package declaration
Package declaration
PACKAGE package_name IS
type declarations
subtype declarations
constant declarations
signal declarations
variable declarations
subprogram declarations
file declarations
alise declarations
component declarations
attribute declarations
attribute specifications
disconnection specifications
use clauses
END package_name;
s : IN STD_LOGIC_VECTOR
(1 downto 0)
f : OUT STD_LOGIC ;
end component;
subprogram bodies
subprogram declarations
use clauses
end package_name;
• The name of the package must be same as the name of its corresponding
package declaration. If the package declaration does not have any subprogram
or deferred constant declarations, a package body is not necessary.
Styles of Modeling
Styles of Modeling
AU : Dec.-14, 15, 16, 17, May-15
* Behavioral
* Data flow
* Structural
* Switch-level
* Mixed-Type
* Mixed-Language
• Let us see the VHDL description of full adder shown in the Fig. 10.3.1 in
various modeling styles.
1. Behavioral Description
• It is sometimes possible to directly describe the behavior or the functionality
of a circuit. Such a modeling style is called behavioral modeling which is very
similar in syntax and semantics to that of a high-level programming language
(For example : C, Pascal). A behavioral description models the system as to
how the outputs behave with the inputs.
description
entity full_add is
end full_add;
begin
begin
end process;
end adder;
In Verilog, the key mechanism used to model the behavior is predefined words
always or initial.
description
input A, B, Cin;
begin
Sum = (A Λ B) Λ Cin;
end
endmodule
2. Dataflow Description
• Data flow describes how the circuit signals flow from the inputs to the
outputs. There are some concurrent statements which allow to describe the
circuit in terms of operations on signals and flow of signals in the circuit. When
such concurrent statements are used in a program, the style is called a
'dataflow design'. Concurrent signal assignment statements are used in this
type of modeling style.
description
entity full_add is
begin
end adder;
description
input A, B, Cin;
endmodule
• The built in operators of VHDL (for example : AND, OR, NOT) and verilog (for
example & I A) are used in the expression.
• Here, the data flow model for the full_add is described using a two
concurrent signal assignment. In a signal assignment statement, the symbol <=
implies an assignment of a value to a signal in VHDL. The value of the
expression on the right-hand-side of the statement is computed and is
assigned to the signal on the left-hand-side, called a target signal. In Verilog,
predefined word assign is used to assign a value to a signal. A concurrent signal
assignment is executed only when any signal in the expression on the right-
hand-side has an event on it, that is, the value of the signal changes.
3. Structural Description
• In structural design, a VHDL and verilog uses components or gates to model
the system. The important features of VHDL structural type of architecture
body are :
■ Design hierarchy
entity full_add is
end full_add;
O1 : out bit);
end component;
component and2
O1 : out bit);
end component;
component or3
O1 : out bit);
end component;
begin
end adder;
• The name of the architecture body is adder. The entity declaration for
full_add specifies the interface ports for this architecture body. The
architecture body is composed of two parts : the declarative part (before the
keyword begin) and the statement parts (after the keyword begin). The
components may either be predefined components in a library or they may
later be bound to other components in a library. The declared components are
instantiated in the statement part of the architecture body using component
instantiation statement. Yl, XI, X2, X3, Y2 are component labels for this
component instantiations. Il is connected to signal A, 12 is connected to signal
B, 13 is connected to signal Cin, and O1 is connected to Sum in portmap xor3
gate. Similarly, port maps for and 2 and or 3 are defined. Note that in this case,
the signals in the port map of a component instantiation and the port signals in
the component declaration are associated by position. A component
instantiation statement is a concurrent statement.
• Basic identifiers
• Extended identifiers
• Digit (0 ... 9)
• Underscore (_)
Note 1. The first character in a basic identifier must be a letter, and the last
character may not be an underscore.
2. The characters are not case sensitive. Therefore, as an example, NUM, num
and Num are considered to be same identifier.
Note 1. Extended identifiers are case sensitive. Thus Num and NUM are distinct
identifiers.
2. Even though two blackslashes includes keyword it is a valid identifier. For
example, /process/ is distinct from keyword process.
3. The architecture body starts with the predefined word begin, followed by
statements that detail the relationship between the outputs and inputs.
5. Leaving the blank spaces between two words or at the beginning of the line
are allowed.
1. Signal
• A signal is data object which holds a list of values. These values include the
current value of the signal and also a set of possible future values that are to
appear on the signal. The signal represents a wire/logic signal in a circuit. In
VHDL, the signal can be placed in any of the following three places,
a) An entity declaration,
SIGNAL X : BIT;
• This signal declares the signal object X which is of type BIT. The initial value of
this signal is 'O' as 'O' is the leftmost value of type BIT.
2. Variable
• A variable is used to hold a signal value of a given type. Unlike a signal, a
variable does not necessarily represent a wire in a circuit. Variables can be
assigned a single value of a specific type. The different values can be assigned
to the variable at different times. For this a variable assignment statement is
used. The variable declaration has the following form :
• Here, the variable 'index' is an integer having values between 0 and 20 and is
initialized to the value 0.
• The variables are used for computations within procedures, functions and
processes. The variables are sometimes used for the index variables in loops.
3. Constant
• The syntax for declaring a constant in a VHDL is given below.
For example,
■ Declaration of a file
• While declaring a file, we should ensure that the host environment correctly
interprets the format of the data which is stored in the file. So before
declaration of the file, it is necessary to declare its type. For example, text file.
This file consists of text strings of variable length. The syntax of a file type
declaration is as given below,
The type_name is the type of values contained in the file. For example,
This defines a file of type TEXT that has a sequence of strings as values in it.
2. File declarations
• After declaring a particular type of a file, we can declare a file object. The
syntax of a file declaration is as given below,
• The file can be used as a read-only, write-only or in the append mode. The
mode in the syntax specifies any of these utilization. The host-environment
interprets the string expression as the physical name of a file. For example,
FILE Input_File : TEXT OPEN READ-MODE IS
"/user/home/add.txt";
• Here, a file Input_File is declared to be of file type TEXT. That is, it has a
sequence of strings. The READ_MODE specifies that the file will be opened in
read-only mode. The string expression given after the keyword 'IS' specifies the
path name to a physical file in the host environment.
• After declaring file of a specific type, it is necessary to open the file before
using it and to close it before terminating the program. There are procedures
and functions to open and close a file. These are given below :
file_name : IN STRING;
OPENKIND : IN FILEOPENKIND : =
READMODE);
- - Opens the file FI that points to the physical file specified in the string
file_name - - with the specified mode. Type FILE_OPEN_KIND has value
READ_MODE.
FILE_OPEN_STATUS;
file FI : file_type_name;
file_name : IN STRING
- - This procedure returns the file open status, (other things are -similar to the
first procedure).
• The FILE_CLOSE procedure closes the file. There exists an implicit call to
FILE_CLOSE procedure which is called when execution terminates.
• We need procedures and functions to read and write files of the declared
type. The standard VHDL procedures and function can be declared as given
below.
RETURN BOOLEAN;
• The above I/O procedures are implicitly declared following a file type
declaration. It is not required to declare these procedures prior to their use.
The procedures READ and WRITE are used for I/O operations. When we are
reading from files, the ENDFILE function is used to test for the end of file. The
different data types such as character, integer, real etc. can be read or written
with a set of procedures supported by VHDL.
1. Scalar types : The scalar types include numeric data types and enumerated
data types. The numeric types consist of integer, floating point (real) and
physical types. Bit, Boolean and character are all enumerated types.
2. Composite types : Array and record types are composite data types. The
values of these types are collection of their elements.
3. Access types : They are pointers; they provide access to objects of a given
data type.
4. File type : They provide access to object that contain a sequence of values of
a given type.
5. Other types : They include the data types provided by the several external
libraries.
1. Scalar Types
• We have seen that, the scalar types consist of enumeration types, integer
types, physical types, and floating point types. Enumeration, data types and
integer types are called discrete types. On the other hand, integer types,
floating point types and physical types are called numeric types.
Integer type
• As the name indicates, it covers all integer values, the values can be positive
or negative. The default range of Integer is -2147483647 to +2147483647.
However, user can specify a shorter range by using the predefined word range.
The shorter range may require less bits to represent the number when binary
encoded. We can define the subtype of base type whose range must be wholly
contained within the bounds of the range of base type.
Examples :
Note : The encoding of integers in a binary format means that all ranges are
rounded up to the nearest power of two. This means that if shorter had been
declared as :
• Then the object is synthesized into 4 wires. Objects declared type of type
integer without a range constraint will be synthesized into 32 wires.
O1 : out integer);
• Floating point type definition defines both a type and subtype of that types.
The default range of floating point is -1E38 to + IE38. Like integer type, here
also we can specify the shorter range by using the predefined word range.
Examples :
O1 : out real);
Enumerated types
Bit, Boolean, Character and severity_level are the enumerated types. These are
defined in a library such as std or ieee.
Bit data type allows only two values 0 or 1. It is used to describe a signal that
takes only l(High) or 0(Low). The type Boolean has two values, True(l) or
False(0). Both True and False are predefined words.
The type character constitutes the 128 characters of the ASCII character set.
These character values are called character literals and are always written
between two single quotes (' ')• F°r example, 'A', ‘_’ ' 3 ' and so on.
An object with type severity can take one of four values ; note, warning, error
or failure. This type is typically used in assertion statements.
Examples :
O1 : out Boolean);
Physical type
• A physical type definition defines both a type and a subtype of that type.
Each unit declaration (either the base unit declaration or a secondary unit
declaration) defines a unit name. Unit name declared in secondary unit
declaration must be directly or indirectly defined in terms of integral multiples
of the base unit of the type declaration in which they appear.
Examples :
units
fs; - femtosecond
end units;
units
- base unit:
A; - angstrom
- metric lengths;
nm = 10 A; - nanometer
cm = 10 mm; - centimeter
km = 1000 m; - kilometer
- - English lengths :
ft = 12 inch; - foot
yd = 3 ft; - yard
fm = 6 ft; - fathom
end units;
z : = ns/ps;
x : = z mi;
y : = y/10;
• The arithmetic operations are predefined for all physical types. It is an error if
the execution of such an operation cannot deliver the correct result (that is, if
the value corresponding to the mathematical result is not a value of the
physical type).
User-defined types
The user can define a type by using the predefined word type.
Example :
Here, multi_level_logic and arith_op are the user defined types. The variables
declared using such data types can take values mentioned in the data type
definition. For example,
2. Composite Types
• Composite types are used to define collection of values. These include both
arrays of values (collection of values of a single type) and records of values
(collection of values of the same or different types).
• An object of a composite type represents a collection of objects, one for each
element of the composite object. A composite type may only contain elements
that are of scalar, composite, or access types; elements of file types are not
allowed in a composite type. Thus, an object of a composite type ultimately
represents a collection of objects of scalar or access types, one for each non-
composite subelement of the composite object.
Array types
• A one-dimensional array has a distinct element for each possible index value.
A multidimensional array has a distinct element for each possible sequence of
index values that can be formed by selecting one value for each index (in the
given order). The possible values for a given index are all the values that
belong to the corresponding range; this range of values is called the index
range.
Example :
range
range
-- Example of unconstrained array
declarations
string and bit_vector are the predefined array types, which are defined in
package std.
The values of the predefined type string are one-dimensional arrays of the
predefined type character, indexed by values of the predefined subtype
positive;
The values of the predefined type bit_vector are one-dimensional arrays of the
predefined type BIT, indexed by values of the predefined subtype natural :
Record type
Example :
type DATE is
record
MONTH : MONTH_NAME;
end record;
3. Access Types
• Values belonging to an access type are pointers to a dynamically allocated
object of some other type. These are similar to pointers in pascal or C
languages.
Example :
4. File Type
• File types are used to define objects representing files in the host system
environment. The value of a file object is the sequence of values contained in
the host system file.
Examples :
• Three operations are provided for objects of a file type. Given the following
file type declaration :
type FT is file of TM :
• Procedure read retrieves the next value from a file. Procedure write appends
a value to a file. Function endfile returns False if a subsequent read operation
on an input file can retrieve another value from the file; otherwise it returns
true. Function endfile always returns true for an output file.
5. Other Types
• There are several other types provided by external library, IEEE. This library
contains a std_logic_1164 package which supports more types. Let us discuss
them.
Std_logic type
• std_logic is a data type defined by IEEE standard 1164, and defined in the file
ieee.vhd.std_logic is an enumerated type. This logic has nine values as listed in
Table. 10.6.1.
• The std_logic data type is very important for both simulation and synthesis.
Std_logic includes values that allow us to accurately simulate such circuit
conditions as unknowns and high-impedance stages. For synthesis purposes,
the high-impedance and don't care values provide a convenient and easily
recognizable way to represent three-state enables and don't care logic. For
synthesis, only the values 0, 1, z and have meaning and are supported.
std_logic_vector type
Example :
Signed
In the above definition, the variable difference is declared as signed type and
has 5-bits with initial value 10011, or - 13.
Unsigned
The type unsigned represents integer data in the form of an array of stdjogic
and it is declared in the external package numeric_std. Let us see the object
definition variable num: unsigned (4 downto 0) := 10011; In the above
definition, the variable num is declared as unsigned type and has 5-bits with
initial value 10011, or 19.
6. Operation in VHDL
VHDL includes the following kinds of operators :
• Logical
• Relational
• Arithmetic
a. Logical Operators
Logical operators, when combined with signals and/or variables, are used to
create combinational logic. VHDL provides the logical operators as shown in
the Table 10.6.2.
• These operators are defined for the types bit, std_logic and Boolean, and for
one-dimensional arrays of these types (for example, an array of type bit_vector
or std_logic_vector).
• The effects of the logical operators are defined in the following tables. The
symbol T represents TRUE for type BOOLEAN, T for type BIT; the symbol F
represents FALSE for type BOOLEAN, 'O' for type BIT.
b. Relational Operators
Note : The operands of each relational operator must be of the same type. The
result type of each relational operator is the predefined type Boolean.
c. Arithmetic Operators
• These operators shift or rotate the bits of the operand right or left by some
specified number of bit positions. There are two types of shift operators : Logic
shift operator and arithmetic shift operator. When logical shift operator is
used, the vacant positions created due to shift operation are filled with zeros.
On the other hand, when arithmetic right shift operator is used the vacant
positions created due to shift operation are filled with MSB (sign bit). The
arithmetic left shift is same as the logical left shift.
• The Table 10.6.5 shows the shift and rotate operators supported in VHDL. To
understand the function of these operators, assume that operand A is the 4-bit
vector with value 1101.
Note :
• Shift left by 1 bit performs multiplication by two while shift right by 1 bit
performs division by two.
• With rotate operation we can restore the original contents after one
complete cyclic rotation. This is not the case with shift operation.
e. Operators Precedence
• The precedence of operators is shown in Table 10.6.6. The operators belongs
to same row have the same precedence level. Operators are listed in order of
decreasing precedence.
1. Entity Declaration
• An entity declaration describes the external interface of the entity. It
specifies the name of the entity, the names of input/output ports, and the type
of ports. The syntax for an entity declaration is as shown below.
entity entity_name is
begin
entity statements
end entity_name;
The port in the behavioral modeling can have one of the following modes :
in : This mode is used for a signal that is an input to an entity (value is read not
written).
out: It is used for a signal that is an output from an entity. The value of such a
signal can not be read inside the entity's architecture. But it can be read by
other entities those use it.
buffer : The signal is an output from the entity and its value can also be read
inside the architecture of entity. The buffer is different from inout mode in that
it cannot have more than one source.
Linkage : The value of a linkage port can be read and updated. This can be
done only by another port of mode linkage.
• The entity item declaration includes those declarations that are common to
all the design unit. The Fig. 10.7.1 shows the circuit for half-adder and its entity
declaration is
entity half_adder is
port ( A : in bit;
B : in bit;
end half_adder;
2. Architecture Body
• Architecture specifies behavior, functionality, interconnections or
relationship between inputs and outputs. It is the actual description of the
design.
begin
statement
statement
end architecture_name;
begin
process (A, B)
begin
end process;
end adder;
process (X)
begin
end process ;
• One important thing to note that we can label any statement in the VHDL
such as stl, st2 and st3 in the previous description.
4. Sequential Statements
• The various forms of sequential statements are associated with behavioral
description. These statements have to appear inside process in VHDL. These
statements execute in the order in which they appear. Let us study these
sequential statements.
a. IF Statement
VHDL Syntax :
statement 1;
statement 2;
else
statement x;
statement y;
end if;
Example :
Q := S1;
else
Q: = S2;
end if;
In the above examples, if EN = T' (high), then the value of SI is assigned to Q;
otherwise, the value of S2 is assigned to Q.
if Clk = '1'
then Q:= D;
end if;
if Clk is T (high), then the value of D is assigned to output Q. If Clk is not high, Q
retains its current value, thus simulating a latch.
VHDL syntax :
else
end if ;
Example :
begin
if en = '00' then
c < = a;
else
c < = '0';
end if;
end process;
Here 'en' signal is in sensitivity list. If en = 00, signal 'a' is assigned to output 'c'.
Similarly if 'en' = '01' then 'b' is assigned to 'c' else 'O' value is assigned to 'c'.
library ieee;
use ieee.std_logic_1164.all;
entity mux2 × 1 is
Y : out std_logic);
end mux2 × 1;
begin
if S = '1' then
temp := D1;
else
temp := D0;
end if;
Y < = temp;
else
Y < = 'Z';
end if;
end process;
end MUX;
library ieee;
use ieee.std_logic_1164.all;
entity mux2 × 1 is
Y : out std_logic);
end mux2×l;
begin
process (S, DO, DI, Enbar)
begin
temp := D1;
temp := D0;
else
state
end if;
Y < = temp;
end process;
end MUX;
• The Fig. 10.7.2 shows the logic symbol for D latch. It has input (D), output Q
and Qbar and active high enables input (En). When En is high, the output Q
follows input D and Qbar is always the invert of Q.
Listing 10.7.1 : VHDL code for behavioral description of D-Latch using variable -
assignment statements
entity DLatch_var is
end DLatch_var;
begin
begin
if En = '1' then
end if;
end DL_Var;
Listing 10.7.2 : VHDL code for behavioral description of D-Latch using signal-
assignment statements
entity DLatchsig is
Q : buffer bit;
- it appears on both the left and right hand sides of assignment statements.
end DLatch_sig;
begin
begin
if En = '1' then
end if;
end process;
end DL_sig;
The Table 10.7.1 gives the comparison between signal and variable.
• The Fig. 10.7.2 shows the simulation waveform of D latch using variable
assignment statement. This waveform correctly describes D-latch. The Fig.
10.7.4 shows the simulation waveform of D latch using signal assignment
statement. As shown in the Fig. 10.7.4, at T = 50 ns, En changes from 0 to 1,
and D is 1 at T = 50 ns. Therefore, new value for Q is calculated as 1; however,
it is assigned at T = 50 + A Since at T = 50 ns, value of Q is still 0, Qbar is
calculated as 1 using old value of Q.
c. Case Statement
VHDL
case (control-expression) is
when test value or expression 1 ⇒ statements 1;
end case;
Example :
VHDL
case option is
end case;
Example :
process (sel, a, b, c, d)
begin
op < = b;
op < = c;
else
op < = d;
end if;
end process;
Example :
process (sel, a, b, c, d)
begin
case sel is
end process;
The Fig. 10.7.5 (a) shows the clocked JK flip-flop, logic symbol and truth table
for clocked edge triggered or pulse triggered JK flip-flop.
We know that, in case of pulse or edge triggering the flip-flop changes state
either at the positive edge (rising edge) or at the negative edge (falling edge) of
the clock pulse and is sensitive to its inputs only at this transition of the clock.
Fig. 10.7.6 shows the input and output waveforms for positive edge triggering
JK flip-flop.
Looking at the truth table for JK flip-flop and simplifying Qn +1 function by K-
map we get the characteristic equation for JK flip-flop as
Listing 10.7.3 : HDL code for a positive edge-triggered JK flip-flop using the
case statement-VHDL.
library ieee;
use ieee.std_logic_1164.all;
entity JK_FF is
clk : in std_logic;
begin
P1 : process (elk)
begin
case JK is
end case;
Q < = temp1;
end if;
end Flip_Flop;
Listing 10.7.4 : HDL code for a 3-bit binary counter using the case statement.
library ieee;
use ieee.std_logic_1164.all;
entity CTCase is
port ( elk, Reset : in std_logic;
end CT_Case;
begin
counter : process(clk)
begin
case temp is
end case;
else
temp := "000";
end if;
end if;
Q < = temp;
end counter_3b;
Ex. 10.7.8 : Construct a VHDL module listing for a 16 : 1 MUX that is based on
the assignment statement. Use a 4-bit select word S3, S2, S1 , S0 to map the
selected input Pi (i = 0, 15) to the output
AU : Dec.-10, Marks 16
Solution :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Mux8_1 is
P0, Pl, P2, P3, P4, P5, P6, P7, P8, P9, P10 , PH, P12,
end Mux8_l;
begin
process (SEL.PO, Pl, P2, P3, P4, P5, P6, P7, P8, P9, P10 , Pll, P12, P13, P14, P15)
begin
case SEL is
when "0000" => MUX_OUT <= P0;
end case;
end process;
end BEHAVIORAL;
e. Loop Statement
end loop
Example :
For i in 1 to 10 loop
i_squared(i) := i * i;
end loop;
• This for loop executes 10 times whenever execution begins. Its function is to
calculate the squares from 1 to 10 and insert them into the i_squared signal
array. The index variable i starts at the leftmost (lower) value (1) of the range
and is incremented until the rightmost (higher) value (10) of the range. In each
iteration index is incremented by 1. When the value of index is greater than
the higher value, the loop is terminated.
• In some languages, the loop index (in this example, i) can be assigned a value
inside the loop to change its value. VHDL does not allow any assignment to the
loop index. VHDL locally declares the index; it is not necessary to declare
variable i explicitly in the process, function or procedure. If another variable of
the same name exists in the process, function or procedure, then these two
variables are treated as separate variables.
i_squared (i) := 1 * 1;
end loop;
While-Loop Statement
while (condition)
end
This loop executes all the statement written in the while loop body as long as
the condition is true. When condition is false, program exits the loop.
VHDL while-loop
Count: = 0;
Result : = 0;
Count := Count + 1;
end loop;
Key Point : Instead of direct value we can use variable to specify the
termination condition. For example, we can write, while (Count < x). In this
case, loop is executed till value of Count is less than value of x.
• The VHDL supports, two sequential statements next and exit associated with
the loop. The exit causes program to exit the loop whereas next causes the
program to jump to the end of the loop, skipping all statements written
between next and end loop. The index is incremented and if its value is still
within the range of the loop, the loop is repeated, otherwise the program exits
the loop.
process (A, B)
else
done(i) := true;
end if;
end loop;
end process;
• In the above example, the for loop multiplies the numbers in arrays A and B
and puts the results in array mul. This behavior continues whenever the flag is
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. It skips the further statements and goto
next iteration. If value of i is still within the range of loop i.e. less than
max_limit. The loop is repeated.
f. Assertion Statement
assert boolean_condition
[report string]
[severity name];
• If the value of the Boolean expression is false, the report message is printed
along with the severity level.
WARNING;
The predefined severity names are : NOTE, WARNING, ERROR, FAILURE and
default severity for assert is ERROR.
g. Report Statement
• The listing 10.8.1 shows the HDL code for the circuit shown in the Fig. 10.8.1.
The circuit is an AND-OR circuit in which signals A, B, C, D and E are input
signals, signal Y is an output signal and signals II and 12 are intermediate
signals.
entity AND_OR is
Y : out bit);
end;
begin
end digital_ckt;
Important points
• In VHDL we specify delay in time units such as nsec, msec, sec etc.
3. Concurrent Signal Assignment Statements
• Concurrent statements are order-independent and asynchronous. The most
important concurrent statement is the process declaration. Other concurrent
statements are the concurrent signal assignment statement : conditional
signal assignment (WHEN-ELSE) and selected signal assignment (WITH-SELECT-
WHEN), the block statement, the concurrent assert statement, the concurrent
procedure call statement, the component instantiation statement, and the
generate statement. Let us see examples and concurrent statements.
• For example :
f <= X AND Y;
WITH S SELECT
W1WHEN OTHERS;
• Hardware is not always a sequential circuit. There are many circuits which
generate output signal in parallel. To model such hardware we need
concurrent statements. The VHDL support concurrent statements. When
statements are concurrent, they execute in parallel. Concurrent signal
assignment statement produces multiple drivers, e.g. C <=A
• Multiple Drivers
C <= A AND B;
C <= D AND E;
WHEN Statement
WITH SELECT
Syntax
WITH SELECT
b WHEN "01",
c WHEN "10"
0 WHEN OTHERS;
4. Comparison between Concurrent and Sequential
Statement
• The vector data type declares an array of similar elements, rather than
declaring each individual bit separately. For example,
Vector declaration :
• In VHDL, downto and to are predefined operators that describe the width of
the vector. Operator downto is used when zeroth element is the least
significant element, and operator to is used when zeroth element is the most
significant element. For example, if A has value 1100 and declaration is signal A
: bit_vector (3 downto 0) then the elements of vector A are :
• The Fig. 10.8.3 shows 4 × 1 multiplexer. Each of the four lines, DO to D3, is
applied to one input of an AND gate. Selection lines are decoded to select a
particular AND gate.
Listing 10.8.2 : HDL code of a 4 × 1 multiplexer - VHDL.
library ieee;
use ieee.std_lo9ic_1164.all;
entity mux4×1 is
S, Enbar : in std_logic;
Y : out std_logic);
end mux4×l;
begin
end MUX;
7. VHDL Program Examples
Listing 10.8.3 VHDL code for half-adder.
entity half_adder is
port (
A: in bit;
B: in bit;
end half_adder;
begin
end adder;
library ieee;
use ieee.std_logic_1164.all;
entity mux2×1 is
Y: out std_logic);
end mux2×1;
end MUX;
library ieee;
use ieee.std_logic_1164.all;
entity COMP_2 is
end COMP 2;
begin
AgtB < = (A(0) and not B(l) and not B(0)) or (A( 1) and not B(l))
AltB <= (not A(l) and not A(0) and B(0)) or (not A(0) and B(l) and B(0))
end COMP;
Listing 10.8.6 : VHDL code for a D-latch-VHDL
library ieee;
use ieee.std_logic_1164.all;
entity D_Latch is
port ( D, EN : in std_logic;
- both input and output, they appear on the right and left
end D_Latch;
begin
end Latch;
Listing 10.8.7 : Write the HDL description of the circuit specified by the
following Boolean functions : x = A + BC + B'D, y = B'C + B C' D'
library ieee;
entity ckt is
begin
end COMB;
Organization of Structural
Description
Organization of Structuural Description
• The listing shows the VHDL structural description for half-adder. In the VHDL
description, the entity part is same as that of behavioral description. However,
architecture part has two components : declaration and instantiation.
1. Component Declaration
• In declaration part all different components used in the system description
are declared. The syntax for component declaration is
component component-name
end component;
component and2
O1 : out std_logic);
end component;
The and2 components has two inputs : Il and 12 and one output Ol. Once the
component is declared we can use the same component one or more times in
the system description.
2. Component Instantiation
• The instantiation part of the code maps the geneic inputs/outputs to the
actual inputs/outputs of the system. The format of a component statement is :
• For example, the statement and2 port map (A, B, Cout); maps A to input II of
and2, input B to input 12 of and2, and output Cout to output O1 of and2. This
mapping means that the logic relationship between A, B and Cout is the same
as between II, I2 and O1.
library ieee;
use ieee.std_logic_1164.all;
entity half_adder is
port ( A, B : in std_logic;
end half_add;
.. Component Declaration
component xor2
end component;
component and2
port ( II, 12 : in std_logic;
Ol : out std_logic);
end component;
begin
.. Statements instantiation
end adder;
• The VHDL part of listing 10.9.1, does not give the complete code for
half_adder. It does not specify the function of the components and2 and xor2.
To specify and2 as an AND gate or xor2 as an XOR gate, we have to link the
entity having the same name as component which specifies the relationship
between II, 12 and Ol as AND gate or XOR gate, respectively. This is illustrated
in Listing 10.9.2.
library ieee;
use ieee.std_logic_1164.all;
entity xor2 is
port(Il, 12 : in std_logic;
Ol : out std_logic);
end xor2;
begin
end xor_gate;
library ieee;
use ieee.std_logic_1164.all;
entity and2 is
end and2;
begin
end and_gate;
library ieee;
use ieee.std_logic_1164.all;
entity half_adder is
port ( A, B : in std_logic;
end half_adder;
component xor2
O1 : out std_logic);
end component;
component and2
O1 : out std_logic);
end component;
begin
XI : xor2 port map (a, b, S);
end adder;
library ieee;
use ieee.std_logic_1164.all;
entity I2_O2 is
end I2_O2;
architecture HA of I2_O2 is
component xor2
Ol : out std_logic);
end component;
component and2
Ol : out std_logic);
end component;
begin
XI : xor2 port map (II, I2, O1);
end HA;
library ieee;
use ieee.std_logic_1164.all;
entity full_adder is
end full_adder;
component HA
end component;
component or2
Ol : out std_logic);
end component;
begin
end adder;
library ieee;
use ieeeR.std_logic_1164.all;
entity mux2 × 1 is
Y : out std_logic);
end mux2 × 1;
- Components declaration
component and3
O1 : out std_logic);
end component;
component or2
O1 : out std_logic);
end component;
component inv
port ( I1 : in std_logic;
O1 : out std_logic);
end component;
begin
- instantiation
end MUX;
library ieee;
use ieee.std_logic_1164.all;
entity decoder2 × 4 is
port ( A, B, En : in std_logic;
end decoder2 × 4;
component inv
port ( I1 : in std_logic;
O1 : out std_logic);
end component;
component and3
O1 : out std_logic);
end component;
.. Signal Declaration
begin
end decoder;
library ieee;
use ieee.std_logic_1164.all;
entity decoder2 × 4 is
port ( A, B : in std_logic;
En : in std_logic;
end decoder2 × 4;
component bufif1
end component;
component inv
port ( I1 : in std_logic;
O1 : out std_logic);
end component;
component and2
O1 : out std_logic);
end component;
- Signal Declaration
begin
end decoder;
library ieee;
use ieee.std_logic_1164.all;
entity compare3_bit is
end compare3_bit;
component full_adder
end component;
component inv
O1 : out std_logic);
end component;
component nor2
O1 : out std_logic);
end component;
O1 : out std_logic);
end component;
begin
end compare;
Listing 10.9.9 : VHDL description of an SR latch with NOR gates,
library ieee;
use ieee.std_logic_1164.all;
entity SR_Latch is
port ( R, S : in std_logic;
- Q, Qbar are declared buffer because they behave as input and output, end
SR_Latch;
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
component nor2
O1 : out std_logic);
end component;
begin
end Latch;
library ieee;
use ieee.std_logic_1164.all;
entity D_Latch is
port ( D, En : in std_logic;
end D_Latch;
- Here Q arid Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
component nand2
O1 : out std_logic);
end component;
begin
NA3 : nand2 port map (D, D, R); - nand gate used as an inverter
end Latch;
library ieee;
use ieee.std_logic_1164.all;
entity SR_FF is
port ( S, R, CP : in std_logic;
end SRFF;
architecture FF of SR_FF is
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
- mapping. In this case, change all in and out to buffer, component nand2
O1 : out std_logic);
end component;
begin
end Latch;
library ieee;
use ieee.std_lo9ic_1164.all;
entity D_FF is
port ( D, CP : in std_logic;
Q, Qbar : buffer std_logic);
end D_FF;
architecture FF of D_FF is
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
- mapping. In this case, change all in and out to buffer, component nand2
O1 : out std_logic);
end component;
begin
NA3 : nand2 port map (D, D, R); - nand gate used as an inverter
end FF;
library ieee;
use ieee.std_logic_1164.all;
entity JKFF is
port ( J, K, CP : in std_logic;
Q, Qbar : buffer std_logic);
- Q, Qbar are declared buffer because they behave as input and output,
end JK_FF;
architecture FF of JK_FF is
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
component nor2
O1 : out std_logic);
end component;
component and3
O1 : out std_logic);
end component;
signal R, S
begin
end FF;
4. Generic Statement and Its Declaration
• We can consider a circuit consisting of subcircuits. In some cases, these
subdrcuits are repetitive. For example, an n-bit "ripple adder" consists of n "full
adders". A generate statement in VHDL is used to create repetitive structures
for such repetitive subcircuits. This concept is similar to use a FOR loop. When
generate statement is used, it is not necessary to write out all of the
component instantiations individually.
concurrent statement
end generate;
• The identifier is a variable with type compatible with the range. This
identifier may be used within the concurrent statement given within a FOR
loop. The concurrent statement is executed for each possible value of the
identifier within the range. For example, consider a circuit consisting of 8 AND
gates. A generate statement can be used to create repetitive (8) structures of
AND gate as shown below.
library ieee;
use ieee.std_logic_1164.all;
entity and8 is
end and8;
component and
port ( X, Y : in std_logic;
Z : out std_logic);
end component;
begin
G1 : for c in 1 to 8 generate
end generate;
end and8_arch;
Generic Declaration
• The constants whose values are not specified within a VHDL program are
called generic constants. These are defined in an entity declaration with a
generic declaration before the port declaration. The syntax of generic
declaration is given below.
entity entity_name is
constant_name : constant_type;
signalnames
end entity_name;
For example, consider an arbitrary_width bus inverter. The bus_width for this
bus inverter is user_specifiable. The VHDL program for this bus inverter is given
below.
library ieee;
use ieee.std_logic_1164.all;
entity businv is
end businv;
O : out stdlogic);
end component;
begin
end generate;
end businv_arch;
Multiple (in our example, 8) copies of this inverter can be instantiated in the
program by taking different user-specified widths.
library ieee;
use ieee.std_logic_1164.all;
entity comp_gen is
end comp_gen;
component full_adder
end component;
component inv
end component;
component nor2
end component;
component and2
end component;
G1 : for i in 0 to N generate
C(i+1));
The Fig. 10.9.1 shows the 4-bit asynchronous down counter using JK flip-flops.
Here, the clock signal is connected to the clock input of only first flip-flop. This
connection is same as asynchronous/ripple up counter. However, the clock
input of the remaining flip-flop is triggered by the Q output of the previous
stage.
Listing 10.9.15 : VHDL description of an N-bit asynchronous down counter
using generate statement.
library ieee;
use ieee.std_logic_1164.all;
entity asyn_ctr is
port ( CP : in std_logic ;
end asyn_ctr;
component JK_FF is
end component;
begin
end asyn_ctr_gen;
This single memory cell can be expanded to N-bit using the generate
statement. This is illustrated in listing 10.9.16.
library ieee;
use ieee.std_lo9ic_1164.all;
entity memory_word is
end memoryword;
component memory_cell
O1 : buffer std_logic );
end component;
for all: memory cell use entity work.memory (mem_cell);
begin
G1 : for i in 0 to N generate
end generate;
end word_gen;
The group of flip-flops can be used to store a word, such a group is called
register. The Fig. 10.9.2 shows the N-bit register constructed with D flip-flops.
This register is called buffer register. Each D flip-flop is triggered with a
common clock pulse.
library ieee;
entity Regis is
CP : in std_logic;
Q, Qbar : out std_logic_vector(N-l downto 0));
end Regis;
component D_FF is
end component ;
begin
begin
end register_nBit;
The binary information (data) in a register can be moved from stage to stage
within the register or into or out of the register upon application of clock
pulses. This type of bit movement or shifting is essential for certain arithmetic
and logic operations used in microprocessors. This gives rise to a group of
registers called 'shift registers'. They are very important in applications
involving the storage and transfer of data in a digital system.
The Fig. 10.9.3 shows the N-bit left shift register. Here, the data is shifted left
by one bit on receiving every clock pulse. Din is a serial input signal and Dout is
a data output signal.
Listing 10.9.18 : VHDL description of N-bit left shift register library ieee;
use ieee.std_logic_1164.all;
entity Regis_Ls is
port(Din : in std_logic;
CP : in std_logic;
end Regis_Ls;
component D_FF is
end component ;
begin
D < = (Q 8c Din);
end register_nBit;
Subprograms
Subprograms
• A subprogram defines a sequential algorithm that performs particular task.
Two types of subprograms are used in VHDL : Procedures and functions.
Procedures and functions in VHDL, are directly analogous to functions and
procedures in a high-level programming language such as C or Pascal.
• They provide the ability to execute common routines from several different
places in a description. They also provide a means of breaking up large
programs into smaller ones to make it easier to read and debug the source
descriptions.
• Subprograms written in VHDL must have body and may have declaration. The
typical format for a subprogram body is :
subprogram-specification is
subprogram-item-declarations
begin
Subprogram statements
• When parameters are of a variable or constant class, values are passed to the
subprogram by value. On the other hand, files and signals are passed by
reference.
return [expression];
• The value of the expression in the return statement is returned to the calling
program.
1. Functions
• The functions in VHDL have two parts the declaration and the body. The
following listing gives the example of function. The declaration of function
includes the name of the function, the inputs to the function and their types,
and the type of the return data type. The general syntax of function body is
• The pure and impure are keywords and are optional. They specify whether
the function is pure or impure. The function that returns the same value each
time when it is called with the same set of actuals is called pure function. By
default, the function is pure. The function that returns different values each
time it is called with the same set of actuals is called impure function.
• The parameter list describes the list of formal parameters for the function. In
the example function given below, the name of the function is simple, the
inputs of the functions are w, x and y with data type bit, and the type of the
return data type is bit.
entity func is
end func;
begin
end;
being
process (a)
begin
m(0) < = simple (a(0), a(l), a(2)) ; - function call
end process;
end example;
• The body of the function lists the relationship between the inputs and the
output to be returned. All statements in the function body are behavioural
(sequential). The predefined word return is used to point of the output of the
function.
b. Procedure
• A procedure differs from a function in that there is no return value, and the
arguments of the procedure have modes (in, out, or inout). The procedure has
two parts: the declaration and the body. The declaration includes the name of
the procedure, the inputs to the procedure and their types, and the outputs of
the procedure and their types. The syntax for a procedure body is,
In the example procedure given below, the name of the procedure is simple,
the inputs of the procedure are w, x and y with data type bit, and the output of
the procedure is z with data type bit. In the declaration statement, procedure
and is are predefined words. It is important to note that if the inputs or
outputs are signals, they should be explicitly specified as follows :
entity proc is
port ( a : in bitvector ( 0 to 2 );
end proc ;
- - declaration
begin
end;
begin
process (a)
begin
end process;
end example;
We can even pass the values having data type std_logic_vector to the
procedures as follows : procedure simple_vector (x : in std_logic_vector ;
z : out std_logic_vector) is
Declaration of Subprogram
Declaration of Subprogram
• VHDL distinguishes between a subprogram declaration and a corresponding
subprogram body. The subprogram declaration contains only interface
information, while the subprogram body contains :
- Interface information
- Local declarations
- Statements
subprogram-specification;
OP : in OP_CODE;
Z : out INTEGER;
• The above two function are overloaded since they have the same name but
different type of parameters
• The above two functions are overloaded since they have the same name but
different number of parameters.
library ieee;
use ieee.std_logic_1164.all;
entity full_adder is
end full_adder;
begin
S : = a xor b;
C := a and b;
end H_Addr;
begin
begin
H_Addr (Sum2, C2, Suml, Cin); - Second call to procedure Half Adder
temp := Cl or C2;
end process;
end two_h_adders;
library ieee;
use ieee.std_logic_1164.all;
entity adder is
Cin : in std_logic;
end adder;
begin
end full_addr;
begin
begin
carry(O) := Cin;
for i in 0 to N loop
end loop;
end process;
end adder_ripple;
Listing 10.13.3
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Func_XOR is
yl : out std_logic);
end Func_XOR;
variable y : stdlogic;
begin
y : = a xor b;
return y;
end function exor;
begin
begin
end process;
end Behavioral;
• i) The Clk signal is the only signal that can cause a change in the Q output. So
only Clk signal is to be given in the process sensitivity list.
LIBRARY IEEE;
USE IEEE. std_logic_1164.all;
ENTITY DFF IS
Q : OUT STD_LOGIC);
END DFF;
BEGIN
PROCESS (Clock)
BEGIN
Q < = D;
END IF;
END PROCESS;
END Behavior;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY DFF IS
PORT(D, Clock : IN STD_LOGIC;
Q : OUT STD_LOGIC);
END DFF;
BEGIN
PROCESS
BEGIN
Q < = D;
END PROCESS;
END Behavior;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY DFF IS
END DFF;
Q < = ‘0’
Q<=D;
END IF;
END PROCESS;
END Behavior;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY DFF IS
Q : OUT STD_LOGIC);
END DFF;
BEGIN
PROCESS
BEGIN
Q< = 0';
ELSE
Q<=D;
END IF;
END PROCESS;
END Behavior;
• The equivalent VHDL code for a DFF with a negative-edge clock and
asynchronous clear is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
Q : OUT stdjogic);
END flop;
BEGIN
BEGIN
IF (CLR = ‘l')THEN
Q <= ‘O';
Q < = D;
END IF;
END PROCESS;
END archi;
6. Behavioral Description of DFF with Positive-Edge
Clock and Synchronous Set
• The input/output pin description of the D flip-flop is as shown in Table
10.14.2.
• The equivalent VHDL code for the D flip-flop with a positive-edge clock and
synchronous set is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY flop IS
PORT(C, D, S : IN std_logic;
Q : OUT std_logic);
END flop;
BEGIN
PROCESS (C)
BEGIN
Q < = ‘1’;
ELSE
Q <= D;
END IF;
END IF;
END PROCESS;
END archi;
• The equivalent VHDL code for the D flip-flop with a positive-edge clock and
clock enable is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY flop IS
PORT(C, D, CE : IN std_logic;
Q : OUT stdlogic);
END flop;
BEGIN
PROCESS (C)
BEGIN
Q <= D;
END IF;
END IF;
END PROCESS;
END archi;
library ieee;
use ieee.std_logic_1164.all;
entity SR_FF is
port ( S, R, CP : in std_logic;
end SR_FF;
architecture FF of SR FF is
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
component nand2
O1 : out std_logic);
end component;
begin
end Latch;
library ieee;
use ieee.std_logic_1164.all;
entity D_FF is
port ( D, CP : in std_logic;
end D_FF;
architecture FF of D_FF is
- Here Q and Qbar signals are declared as buffer; however these signals are
- mapped with in and out signals. Some simulators may not allow such
- mapping. In this case, change all in and out to buffer,
component nand2
O1 : out std_logic);
end component;
begin
NA3 : nand2 port map (D, D, R); — nand gate used as an inverter
end FF;
library ieee;
use ieee.std_logic_1164.all;
entity JK_FF is
--Q, Qbar are declared buffer because they behave as input and output.
end JK_FF;
architecture FF of JK_FF is
-- Here Q and Qbar signals are declared as buffer; however these signals are
-- mapped with in and out signals. Some simulators may not allow such
mapping. In this case, change all in and out to buffer,
component nor2
O1 : out std_logic);
end component;
component and3
O1 : out std_logic);
end component;
signal R, S
begin
end FF;
library ieee;
use ieee.std_logic_1164.all;
entity JKFF is
clk : in std_logic;
end JK_FF;
begin
P1 : process (elk)
begin
case JK is
end case;
Q < = temp1;
end if;
end Flip_Flop;
12. Description of D Flip-Flop using VHDL Function
• The listing 10.14.5 shows the VHDL description of positive edge trigger D flip-
flop. The positive edge detection is accomplished by the use of S'event and
S'last value signal attributes. The S'event attribute indicates any occurrence of
the event and S'last_value gives the previous value of S. Thus if previous value
is 0 and S'event is true then there is a rising edge or positive edge.
library ieee;
use ieee.std_logic_1164.all;
entity DFF is
Q : out stdlogic);
end DFF
begin
if (s'event) and (s = '1') and – s’event and s’last_value are signal attributes
begin
process( clk)
begin
if rising_edge(clk) then
Q < = D;
end if;
end process;
end Dflip_flop;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
ENTITY upctr IS
END upctr;
PROCESS(Clock, Resetn)
BEGIN
IF EN = '1' THEN
Count< =Count+1;
ELSE
Count< =Count;
END IF;
END IF;
END PROCESS;
Q<= Count;
END Behavior;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY upctr IS
END upctr;
BEGIN
PROCESS(Clock, Resetn)
BEGIN
Q <=0;
IF Load='T THEN
Q<=P;
ELSE
Q<=Q + 1;
END IF;
END IF;
END PROCESS;
END Behavior;
3. VHDL Code for a 4-bit Down Counter
• This section gives a VHDL code for a four-bit down counter with parallel load.
The starting count is declared as a GENERIC parameter in this code so that it
can be changed easily. In this code, we are calling it as a 'MOD'. On the positive
clock edge, if 'Load' input is 1, then the counter is loaded with the count MOD-
1. If the 'Load' is 0, then the Count is decremented. At the end of the code, the
Q outputs are assigned the value of Count.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY downctr IS
END downctr;
BEGIN
PROCESS
BEGIN
IF EN = '1' THEN
IF LOAD = THEN
ELSE
END IF;
END IF;
END PROCESS;
Q<= Count;
END Behavior;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Counterl IS
PORT(
CLK : IN STD_LOGIC;
Resetp : IN STDLOGIC;
Setp : IN STD_LOGIC;
);
END Counterl;
BEGIN
BEGIN
IF Resetp='O' THEN
Q<="000";
ELSIF Setp='O' THEN
Q<="111";
END IF;
Q(l)< = NOTQ(l);
END IF ;
END IF ;
END PROCESS;
END Asynch_Cntr;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Counter2 IS
PORT(
CLK : IN STD_LOGIC;
Resetn : IN STD_LOGIC;
Setn : IN STD_LOGIC;
Q : INOUT STD_LOGIC_VECTOR (2 DOWNTO 0)
);
END Counter2;
BEGIN
BEGIN
IF Resetn='0' THEN
Qtemp :="000";
Qtemp :="111";
END IF;
END IF;
END IF;
Q < = Qtemp;
Qtemp := "000";
Q < = "000" AFTER 2ns;
END IF;
END PROCESS;
END Asynch_GIitch;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Counter3 IS
PORT(
CLK : IN STDLOGIC;
Resetn : IN STD_LOGIC;
Setn : IN STD_LOGIC;
);
END Counter3;
BEGIN
BEGIN
IF Resetn='0' THEN
Qtemp := "000";
Qtemp := "111";
Qtemp := Qtemp + 1;
ELSE
Qtemp := "000";
END IF;
END IF;
Q < = Qtemp;
END PROCESS;
END Synch_Cntr;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
ENTITY counter IS
END counter;
BEGIN
BEGIN
tmp <= D;
ELSIF (C'event and C=’T) THEN
END IF;
END PROCESS;
Q < = tmp;
END archi;
• The VHDL code for a 4-bit unsigned up counter with synchronous load with a
constant is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
ENTITY counter IS
BEGIN
PROCESS (C)
BEGIN
IF (SLOAD=’l') THEN
ELSE
END IF;
END IF;
END PROCESS;
Q < = tmp;
END archi;
library ieee;
use ieee.std_logic_1164.all;
entity counter is
port ( CP : in std_logic;
end counter;
component and2
O1 : out std_logic);
end component;
component JK_FF
end component;
signal J2 std_logic;
begin
end cnt_3Bit;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY reg4 IS
Resetn,Clock : IN STD_LOGIC;
END reg4;
ARCHITECTURE Behavior OF reg4 IS
BEGIN
PROCESS(Resetn,Clock)
BEGIN
IF Resetn='0' THEN
Q<="0000";
Q<=D;
END IF;
END PROCESS;
END Behavior;
• The equivalent VHDL code for a 4-bit register with a positive edge clock,
asynchronous set and clock enable is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY flop IS
END flop;
BEGIN
BEGIN
Q < = “1111'';
Q < = D;
END IF;
END IF;
END PROCESS;
END archi;
• Here, the assignment operator (:=) is used to set the value of N to 16. A
register of any number of bits can be obtained just by changing this parameter.
Since the code is written for N-bit register, the D and Q signals are also defined
interms of N. The OTHERS => 'O' statement assigns a 'O' to each bit of Q.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
Resetn,Clock : IN STD_LOGIC;
END regN;
BEGIN
PROCESS(Resetn, Clock)
BEGIN
IF Resetn='0'THEN
Q<=(OTHERS=> '0');
Q<=D;
END IF;
END PROCESS;
END Behavior;
4. VHDL Code for a Shift Register
a. Using Sequential Statements
• The VHDL code for this register is given below. Here, the shift register is
described using sequential statements. Because of the WAIT-UNTIL statement,
any signal that is assigned a value inside the process has to be implemented as
the output of the flip-flop.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY shiftreg IS
PORT(Clock : IN STD_LOGIC;
I : IN STD_LOGIC;
END shiftreg;
BEGIN
PROCESS
BEGIN
WAIT UNTIL clock'EVENT AND Clock = 1';
Q(0)<= Q(l);
Q(l)<= Q(2);
Q(2)< = Q(3);
Q(3)< = I;
END PROCESS;
END Behavior;
• It is to be noted that in this VHDL code, the lines which perform the shift
operation can be written in reverse order i.e. Q(3) <= I as the first and Q(0) <=
Q(l) as the last line. The code produces the same circuit with any sequence of
these four lines. The reason is that due to the semantics of the process
statement, all of the statements inside the process are evaluated separately
and values are assigned to Q(0), Q(l), Q(2) and Q(3).
• As shown in Fig. 10.16.1, 4-bit shift register consists of four D-flip-flops. Each
D-flip-flop can be considered as a subdrcuit. CAD system generally includes
libraries of prebuilt subcircuits. A good example of a library of macrofunctions
is the Library of Parameterized Modules (LPM) which is included as part of the
MAX + plus II CAD system. Each module in the library can be used in different
ways, i.e. parameterized and also technology independent. The LPM includes
subcircuits that have flip-flops. The predefined subcircuits in the LPM library
can be instantiated in VHDL code.
• In the hierarchical code for a 4-bit shift register, we can use D flip-flop as a
subcircuit and 4 stages of it can be instantiated. The code is given below. Here
we are using VHDL construct PORT MAP to assign signal names to the ports of
a D flip-flop.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY shiftreg IS
PORT(Clock : IN STD_LOGIC
I : IN STD_LOGIC
END shiftreg;
COMPONENT DFF
PORT(D,Clock : IN STDLOGIC;
Q : OUT STD_LOGIC);
END COMPONENT;
BEGIN
END Structure;
• We can write the VHDL code for an n-bit left to right shift register by using
the GENERIC parameter n. The VHDL code is given below. Here, we have taken
n = 16, but we can set size of the shift register to any number of bits. Here we
have taken parallel input P(bits ... P3P2P1P0) for loading data into the register
in parallel. Remaining code is same as the code for 4-bit shift register with two
exceptions. First is, P and output Q are to be given interms of n. Second is, the
ELSE clause which describes the shift right operation is generalized to work for
n number of flip-flops.
• The 'Load' signal is used to control two operations. When 'Load' signal is 1,
the data is loaded in parallel into the register; otherwise the shift left-to-right
operation takes place.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY sftregn IS GENERIC (n : INTEGER := 16);
Clock : IN STD_LOGIC ;
Load,I : IN STD_LOGIC;
END sftregn;
BEGIN
PROCESS
BEGIN
Q<=P;
ELSE
END LOOP;
Q(n-l)<=I;
END IF;
END PROCESS;
END Behavior;
• This code is same as the code given in the previous section with an exception
of an enable input, EN. When 'EN' signal is 1, the shift register behaves in the
same way as the normal left-to-right shift register. If 'EN' signal is 0, the shift
operation does not take place. That is, 'EN' equals to 0 prevents the contents
of the shift register from changing. The VHDL code for such a register is given
below.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY sftregne IS
GENERIC(n:INTEGER: = 16);
Clock : IN STD_LOGIC ;
END sftregne;
PROCESS
BEGIN
IF EN = '1' THEN
Q < = P;
ELSE
Q(i)<= Q(i+1);
END LOOP;
Q(n-l)<=I;
END IF;
END IF;
END PROCESS;
END Behavior;
• When a positive edge clock signal is applied, if 'Load' signal is 1, then the
parallel input data, P is loaded into the shift register and same is obtained at
the output Q; otherwise the shift-right operation takes place, i.e. the value of
Q1 is shifted into the flip-flop with output Q 0, value of Q2 is shifted into Q1 value
of Q3 is shifted into Q2 and the value of serial input, I is shifted into Q3.
LIBRARY IEEE;
ENTITY sftreg4 IS
Clock : IN STD_LOGIC;
Load,I : IN STDLOGIC;
END sftreg4;
BEGIN
PROCESS
BEGIN
IF Load = 'l'THEN
Q<=P;
ELSE
Q(0)<= Q(l);
Q(l)< = 0(2);
Q(2)<= Q(3);
Q(3)< = I;
END IF;
END PROCESS;
END Behavior;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY MUXDFF IS
Q : OUT STD_LOGIC);
END MUXDFF;
BEGIN
PROCESS
BEGIN
Q<=D0;
ELSE
Q<=D1;
END IF;
END PROCESS;
END Behavior;
• The hierarchical code is given below. Four stages of the subcircuit MUXDFF
are instantiated in this code. The stage3 instantiates the leftmost subcircuit
MUXDFF having output Q3 and the stage0 instantiates the rightmost subcircuit
MUXDFF having output Q0.
• When 'Load' signal is 1, data is loaded in parallel from the P input. When
'Load' signal is 0, shift right operation takes place as discussed earlier.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY sftreg4 IS
Load,I,Clock : IN STDLOGIC;
END sftreg4;
COMPONENT MUXDFF
Q : OUT STD_LOGIC);
END COMPONENT;
BEGIN
END Structure;
6. 8-bit Shift-Left Register with Positive-Edge Clock, Asynchronous
Parallel Load, Serial IN, and Serial OUT
• The pin description of 8-bit shift-left register is as shown in the Table 10.16.2
• The VHDL code for an 8-bit shift-left register with a positive-edge clock,
asynchronous parallel load, serial in, and serial out is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY shift IS
SO : OUT stdjogic);
END shift;
BEGIN
BEGIN
IF (ALOAD='l’) THEN
tmp <= D;
END IF;
END PROCESS;
SO < = tmp(7);
END archi;
7. 8-bit Shift-Left Register with Positive-Edge Clock,
Synchronous Parallel Load, Serial IN, and Serial OUT
• The pin description of 8-bit shift-left register is as shown in the Table 10.16.3
• The VHDL code for an 8-bit shift-left register with a positive-edge clock,
synchronous parallel load, serial in, and serial out is as follows.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY shift IS
SO : OUT stdjogic);
END shift;
BEGIN
PROCESS (C)
BEGIN
IF (C'event and C=’l') THEN
IF (SLOAD=’l’) THEN
tmp <= D;
ELSE
END IF;
END IF;
END PROCESS;
SO <= tmp(7);
END archi;
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY shift IS
END shift;
BEGIN
PROCESS (C)
BEGIN
IF (left_right='O') THEN
ELSE
END IF;
END IF;
END PROCESS;
PO <= tmp;
END archi;
library IEEE;
begin
begin
case s is
when "01" => reg : Right_in & reg (n-1) downto 1);
end case;
end if;
q < = reg;
end process P0 ;
1. Combinational Component
2. Sequential Component
• The behavior of the state machine can be understood with the help of its
state diagram. So, for the implementation of the state machine, we can refer
the state diagram. Let us discuss an example of VHDL implementation of a
state machine using a state diagram.
* If the machine is in state SO and the input signal has a value of 0, then the
machine transitions to state SI and sets the value of the output signal to 1.
* If the machine is in state SO and the input signal has a value of 1, then the
machine remains in the same state SO and sets the value of the output signal
to 0.
• When the machine is in state SI, its behavior can be described in the same
manner.
• The VHDL description of state machine having state diagram as shown in Fig.
10.17.1. As per the state diagram, there are two states. In this code, we are
calling the states SO and SI as state 0 and state 1 respectively. The signal Z
represents the state of the flip-flops. The state_type indicates that Z can have
values state 0 and state 1.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY Statemachine IS
PORT(Reset,cIk, X : IN STD_LOGIC;
Y : OUT STD_LOGIC);
END State_machine;
BEGIN
BEGIN
IF X = '0' THEN
next_State <= State 1;
Y <= '1';
Y<='0';
END IF;
IF x='l' THEN
next_state<= state 0;
Y <='l';
Y<='0';
END IF;
END CASE;
clk_process : PROCESS IS
BEGIN
STATE <=state_type'left;
END IF;
• The VHDL description of Mealy state machine having state diagram as shown
in Fig. 10.17.2 (a). As per the state diagram, there are two states A and B.
As given in the VHDL code, the signal Z represents the state of the flip-flops.
The state_type indicates that Z can have the values A and B.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY Mealy IS
Y : OUT STDLOGIC);
END Mealy;
SIGNAL Z : State_type;
BEGIN
BEGIN
Z <=A;
CASE Z IS
WHEN A =>
ELSE Z<=A;
END IF;
WHEN B =>
IF X='O' THEN Z <=A;
ELSE Z<= B;
END IF;
END CASE;
END IF;
END PROCESS;
PROCESS(Z,X)
BEGIN
CASE Z IS
WHEN A =>
Y<=X;
WHEN B=>
Y<=0;
END CASE;
END PROCESS;
END Behavior;
• This section explains the VHDL code for a serial adder using Mealy-type FSM.
The code is given at the end of this section. This code is written by taking the
reference of block diagram for the serial adder shown in Fig. 10.17.2 (b), state
diagram for the serial adder FSM shown in Fig. 10.17.2 (c) and state table for
the serial adder FSM shown in Fig. 10.17.2 (d). Go through the following points
for the clear understanding of the VHDL code for a serial adder.
1. The number of bits in the serial adder are set by the GENERIC parameter
'length'. In this code we have taken length equal to 8. Just by changing the
length, we can set the length to any number of bits. The final sum, S is stored
in a buffer having size same as length.
2. As shown in Fig. 10.17.2 (b), three shift registers are needed for a serial
adder. So we will use the shift register as a subcircuit in the serial adder. We
have discussed the VHDL code for a left-to-right shift register with an enable
input. The code for a serial adder instantiates three shift registers, one for
input A, second for input B and third for the output sum, S.
3. Active high reset signal is used for the shift registers. When Reset is one, the
circuit is reset and the shift registers are loaded with parallel data.
4. As shown in the state diagram (Fig. 10.17.2 (c)), there are two states a and b.
When the machine is in state a, if both the inputs for FSM adder are high, then
only the machine transitions to state b; otherwise it remains in state a only.
When the machine is in state b, if both the inputs for FSM adder are low, then
only the machine transitions to state a; otherwise it remains in state b only.
5. According to the state table shown in Fig. 10.17.2 (d) the sum, ADD_S is
calculated by XORing the least significant bits at the outputs of the shift
registers A and B when the machine is in state a and by complementing this
XORed output when the machine is in state b. We are calling the parallel
outputs of shift registers A and B as X and Y respectively. Hence the least
significant bits of these outputs are X(0) and Y(0) respectively.
6. As discussed in the first point, we are using a left to right shift register with
an enable input as a subcircuit. We are calling this as a COMPONENT sftregne.
Three such components are needed since the serial adder includes three shift
registers. Enable input (EN) of this component is connected to the signal
named high, which is set to 1. There is one more signal in this component i.e.
serial input, I. For the input shift registers A and B, this signal does not matter.
So we can connect it either to 1 or 0. In this code, we are connecting it to low,
which is set to 0. We are using the signals high and low and then setting them
to 1 and 0 respectively because the VHDL syntax does not allow the constants
0 and 1 to be attached to the ports of a component.
7. The output shift register C which gives the output sum, S does not need a
parallel data input. It needs only the serial input ADD_S. We are using the
component sftregne for this shift register which has the parallel data input
port. So signal must be connected to it. We are using the signal named 'ZERO'
and setting it to all 0s for this purpose. In the initial part of the code, we have
declared this signal as STD_LOGIC_VECTOR and number of bits in this signal by
the length constant. All the bits of the signal cannot be set to 0 by a string of 0s
inside the double quotes. So we are using the syntax, OTHERS => 'O'.
8. After completing the addition of all the input bits and obtaining the output
sum, the adder should be halted. We are using a down counter for this
purpose. When the circuit is reset, this counter is loaded with the number of
bits in the serial adder, i.e. length. During each positive clock edge, the counter
is decremented by one. Thus the counter counts down to 0. When the count
reaches to 0, the counter stops and the further changes in the output shift
register C are disabled.
9. For shift register COMPONENT sftregne used for shift register, we know that
the 'EN' signal is used as an enable input. As long as EN is 1, count loaded in
the down counter (length) is decremented in each clock cycle. When count
becomes 0, EN is set to 0 which stops the operation of the adder. Since we are
using a count which is of type integer, in the condition count = 0, 0 is given
without quotes.
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
ENTITY Serial IS
Reset : IN STDLOGIC;
END Serial;
COMPONENT sftregne
END COMPONENT;
SIGNAL Z : State_type;
BEGIN
BEGIN
Z < = a;
CASE Y IS
WHEN a=>
ELSE Z<=a;
END IF;
WHENb=>
ELSE Z = b;
END IF;
END CASE;
END IF;
WITH Z SELECT
Stop : PROCESS
BEGIN
END IF;
END PROCESS;
EN < = 'O' WHEN Count = 0 ELSE '1' ; - stops counter and Shifts
END Behavior;
2. VHDL Code for Moore-Type State Machines
• Consider Moore-type state machine having state diagram as shown in Fig.
10.17.3.
• In this example, we have taken four states A, B, C and D for a state machine.
The state A is selected as a starting state, i.e. the circuit should enter in state A
when power is turned on or when a 'Reset' signal is applied. In Moore-type
state machine, the output value must depend only on the state of the
machine. So the output values are given in each state as shown in state
diagram. For example, A/0 indicates when the machine is in state A, output
value is 0.
• When the machine is in state A and the input signal X Fjg 1Q „ 3 state
djagram for MowMype state has a value of 0, the machine remains in the same
state A machine and sets the value of the output signal to 0. When the input
signal has a value of 1, then the machine transitions to state B and sets the
value of the output signal to 0.
• The last part of the VHDL code specifies that if the machine is in state B then
only the output is 1; otherwise output is 0.
LIBRARY IEEE;
Use IEEE.std_logic_1164.all;
ENTITY Moore IS
Y : OUT STD_LOGIC);
END Moore;
SIGNAL Z : Statetype;
BEGIN
BEGIN
CASE Z IS
WHEN A=>
IF X='0'THEN
Z<=A;
ELSE
Z<=B;
END IF;
WHEN B = >
IF X = '0' THEN
Z<=C;
ELSE
Z<=B;
END IF;
WHEN C=>
IF X='0'THEN
Z<=D;
ELSE
Z<=C;
END IF;
WHEND=>
IF X='0'THEN
Z<=D;
ELSE
Z<=A;
END IF;
END CASE;
END IF;
END PROCESS;
END Behavior
• The example 10.17.1 illustrates the read and write operation of memory. The
memory used in this example has 1024 words of 8-bit each (IK × 8 memory).
There are 10 address bits (since 210 = 1024).
• There are two data lines : Dataln and DataOut; each have 8-bits.
• A memory operation is enabled only when Enable input is active (logic 1).
Read and Write operations are performed as shown below :
• When Enable is 0, the memory is disabled and the outputs are in high
impedance state (z).
Ex. 10.18.1 Write an VHDL code that illustrates the read and write
operations of memory.
library ieee;
use ieee.std_logic_1164.all;
package array_2D is
end array_2D;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.array_2D.all;
entity meml024x8 is
Enable : in std_logic;
ReadWrite : in std_logic;
end meml024x8;
begin
begin
else
end if;
else
end if;
end SRAM;
RTL Design
RTL Design
• Register Transfer Level, or RTL design lies between a purely behavioral
description of the desired circuit and a purely structural one. An RTL
description describes a circuit's registers and the sequence of transfers between
these registers but does not describe the hardware used to carry out these
operations. The steps in RTL design are :
1. Determine the number and sizes of registers needed to hold the data used by
the device,
3. Design a sequential circuit whose outputs control how the register contents
are updated in order to obtain the desired results.
• Producing an RTL design is similar to writing a computer program in a
conventional programming language. Choosing registers is the same as
choosing variables. Designing the flow of data in the "datapath" is analogous to
writing expressions involving the variables (registers) and operators
(combinational functions). Designing the controller sequential circuit is similar
to deciding on the flow of control within the program (if/then/else, while-loops,
etc).
s<=((a + b) + c) + d;
s = 0;
s=s+a;
s=s+b;
s=s+c;
s=s+d;
• Where each operation is executed sequentially. The logic required is now one
adder, a register to hold the value of s in-between operations, a multiplexer to
select the input to be added, and a circuit to clear s at the start of the
computation.
• Although this approach only needs one adder, the process requires more steps
and will take longer time. Circuits that divide up a computation into a sequence
of arithmetic and logic operations are quite common and this type of design is
called Register Transfer Level (RTL) or "dataflow" design.
2. A finite sequential circuit, called the controller that controls the transfer of
data through the function blocks and between the registers.
• In VHDL RTL design, the gate-level design and optimization of the datapath
(registers, multiplexers, and combinational functions) is done by the
synthesizer. However, the designer must design the sequential circuit and decide
which register transfers are performed in which state.
• The RTL designer can trade off datapath complexity (e.g. using more adders
and thus using more chip area) against speed (e.g. having more adders means
fewer steps are required to obtain the result). RTL design is well suited for the
design of CPUs and special-purpose processors such as disk drive controllers,
video display cards, network adapter cards, etc. It gives the designer great
flexibility in choosing between processing speed and circuit complexity.
• The Fig. 10.19.2 shows a generic component in the datapath. Each RTL design
will be composed of one of the following building blocks for each register. The
structure allows the contents of each register to be updated at the end of each
clock period with a value selected by the controller. The widths of the registers,
the types of combinational functions and their inputs will be determined by the
application. A typical design will include many of these components.
• The datapath shown in Fig. 10.20.1 can load the register at the start of each
clock cycle with one of : zero, the current value of the register, or the stun of the
register and one of the four inputs. It includes one 8-bit register, an 8-bit adder
and a multiplexer that selects one of the four possible inputs as the value to be
added to the current value of the register.
• The first design unit is a package that defines a new type, num, for eight-bit
unsigned numbers and an enumerated type, states, with six possible values,
nums are defined as a subtype of the unsigned type.
library ieee ;
use ieee.std_logic_1164.
use ieee.std_logic_arith.all;
package summer is
add_d, hold) ;
end summer ;
• The first entity defines the datapath. In this case the four numbers to be added
are available as inputs to the entity and there is one output for the current sum.
The inputs to the datapath from the controller are a 2-bit selector for the
multiplexer and two control signals to load or clear (set to 0) the register.
— datapath
library ieee ;
use ieee.std_logic_1164.
use ieee.std_logic_arith.all ;
use work.summer.all;
entity datapath is
port ( a, b, c, d : in num ;
);
end datapath ;
conv_unsigned(0,next_sum_reg’length) ; begin
a when “00",
b when “01",
c when “10",
d when others ;
sum_reg ;
— register sum
process(clk)
begin
end if;
end process ;
end rtl;
• The RTL design's controller is a sequential circuit whose outputs control the
multiplexers in the datapath. The controller's inputs are signals that control the
controller's state transitions. In this case the only input is an update signal that
tells our device to recompute the sum when one or more of the inputs changes.
• This particular state machine will remain in the "hold" state until the update
signal is true. It then sequences through the other five states and then stops at
the hold state again. The other five states are used to clear the register and to
add the four inputs to the current value of the register.
use ieee.std_logic_1164.all;
use work.summer.all;
entity controller is
clk : in std_logic
);
end controller ;
begin
holdns < =
hold ;
— state register
process(clk)
begin
s < = ns ;
end if;
end process ;
— controller outputs
end rtl;
• The next section of code is an example of how the datapath and the controller
entities can be placed in a package, summer_components, as components. In
practice the datapath and controller component declarations would probably
have been placed in the top-level architecture since they are not likely to be re-
used in other designs.
library ieee ;
use ieee.std_logic_1164.all;
use work.summer.all;
package summer_components is
component datapath
port ( a, b, c, d : in num ;
);
end component ;
component controller
);
end component;
end summer_components ;
— summer
library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.summer.all;
use work.summer_components.all;
end summer ;
begin
end rtl;
• Test benches can be very simple, for example, just providing a sequence of
test inputs to the circuit overtime. Sometimes this sequence represents a
simple periodic waveform used to describe a system clock. However,
sometimes it can be a very complex one and stored in a file. The testbench has
to provide a reading of text vectors from the file, and also the writing of results
to a report file. Even more, it can be required to provide reference vectors and
compare them with the output of the unit under test during simulation to
provide a pass or fail indication.
• The Fig. 10.21.1 shows the typical structure of testbench. As shown in the
Fig. 10.21.1, the test bench instantiates the 'Design Under Test' (DUT) / 'Unit
Under Test' (UUT). The testbench provides the necessary input stimulus (input
vectors to be applied) to the DUT and examines the output from the DUT.
• Generate stimuli waveforms and apply them to the DUT/UUT in the form of
test vectors during simulation,
• Generate reference waveforms and compare them with the output from the
DUT/UUT model during simulation.
• Stimulus only : This testbench contains only the stimulus driver and DUT;
does not contain any results verification.
• Full testbench : This testbench contains stimulus driver, known good results
and results comparison.
• Hybrid testbench : This testbench combines techniques from more than one
testbench style.
• Fast testbench : These testbenches are written to get ultimate speed from
simulation, i.e. they are optimized for speed.
Syntax of testbench
entity tb is
end tb;
architecture tb of tb is
end component;
Local signals;
begin
process begin
end process;
end tb;
• The entity declaration for a testbench is usually empty. This is because the
test bench itself does not have any inputs or outputs. Test vectors are
generated and applied to the unit under test within the test bench. Note that it
is illegal to have an architecture body without an entity declaration.
• The architecture part has a component with is DUT with the same name and
matching ports. Its declaration is needed in the test bench in order to pull the
entity into the test bench. In order that the VHDL simulator can bind the design
entity to the component, the names and types of the ports must match
between the entity and the component.
• Once the test vectors are available, they are applied to DUT. Finally, output is
verified or written to the result file or error is reported. It is important to note
that monitoring of output values in the testbench is optional. We can simply
observe the output as waveform in the simulation windows. If the output is to
be compared against the expected values, a set of expected values for output
parameters is required.
The waveforms generated for the SEL, A, B, C and D signals are as shown in Fig.
10.21.2.
Advantages of using Testbenches
1. Testbench provide the user with the capability to test the DUT thoroughly
through simulation.
4. Its structure is well defined and flexible to accept changes if there are
changes in the circuit under test.
6. It gives an idea about the timing requirements of the DUT (Design under
test).
Ans. : Computer Aided Design (CAD) tools are used in the design of digital
systems. One such a tool is a Hardware Description Language (HDL).
Q.2 What are the main components of a VHDL description ?
1. Package (optional)
2. Entity
3. Architecture
4. Configuration(optional)
3. What is entity?
entity entity_name is
end entity_name ;
begin
concurrent statements;
sequential statements;
end arclutecture_name;
Ans. : There are some declarations which are common across many design
units. A package is a convenient mechanism to store and share such
declarations. A set of declarations contained in a package declaration may be
shared by many design units. It defines items that can be made visible to other
design units.
Ans. : There are three modelling techniques in HDL for describing a module :
2. Dataflow modeling
3. Behavioral modeling.
Ans. : The modeling style which directly describe the behavior or the
functionality of a circuit is called behavioral modeling. It is very similar in
syntax and semantics to that of a high-level programming language (For
example : C, Pascal). A behavioral description models the system as to how the
outputs behave with the inputs.
Ans. : Data flow describes how the circuit signals flow from the inputs to the
outputs. There are some concurrent statements which allow to describe the
circuit in terms of operations on signals and flow of signals in the circuit. When
such concurrent statements are used in a program, the style is called a dataflow
modeling.
Q.15 What is structural modeling ?
Ans. : The modeling style which uses components or gates to model the system
is called structural modeling.
Ans. : The VHDL data types can be broadly classified into following five data
types :
1. Scalar types : The scalar types include numeric data types and enumerated
data types. The numeric types consist of integer, floating point (real) and
physical types. Bit, Boolean and character are all enumerated types.
2. Composite types : Array and record types are composite data types. The
values of these types are collection of their elements.
3. Access types : They are pointers; they provide access to objects of a given
data type.
4. File type : They provide access to object that contain a sequence of values of
a given type.
5. Other types : They include the data types provided by the several external
libraries.
Q.18 Give the comparison between signal and variable. (Refer Table 10.7.1)
Ans. : A procedure differs from a function in that there is no return value, and
the arguments of the procedure have modes (in, out, or inout).
Ans. :
input A;
input B;
output Sum;
output Cout;
always @(A, B)
begin
#10 Sum = a ^ b ;
end
endmodule
Ans. : Before processing a design by synthesis tool, the designer usually wants
to verify that the design performs according to the specification. This is almost
always done by running a simulation. Simulating a design requires generation of
test data and observation of simulation results. This process is done by used of a
VHDL module that is referred to as testbench.
1. Stimulus only
2. Full testbench
3. Simulator specific
4. Hybrid test-bench
5. Fast testbench
Ans. : The contents of register ACC are bitwised ANDed with the contents of
MDR register and the result is stored in the ACC register when control signal
T1 is activated.
Q.30 Write VHDL code for half adder in data flow model.
AU : June-14
Ans. :
entity half-add is
end half_add;
begin
end adder
AU : May-16
AU : Dec.-16
Q.42 Give the syntax for package declaration and package body in VHDL.
Q.43 Write the VHDL code for 2 x 1 multiplexer using behavioral modeling.
Dec.-10
Q.1 Explain the design procedure of RTL using VHDL. [Section 10.19] [10]
May-11
Dec.-11
Q.5 Explain in detail the design procedure for register transfer language.
[Section 10.19] [16]
Q.6 Express how arithmetic and logic operations are expressed using RTL.
[Section 10.19] [8]
May-12
Q.7 Write the VHDL code for mod 6 counter.[Section 10.15] [16]
Q.8 Explain RTL design using VHDL with the help of example. [Section 10.20]
[16]
Dec.-12
Q.10 List and briefly explain different data types supported by VHDL. [Section
10.6] [6]
Q.12 How is memory modelled in VHDL ? Write a VHDL code that illustrates
the read and write operations of memory. [Section 10.18] [8]
(Regulation 2013)
Dec.-14
Q.13 Explain the concept of Behavioural modeling and Structural modeling in.
VHDL. Take the example of Tull Adder design for both and write the coding.
[Section 10.3] [16]
Q.14 Write a VHDL code for a 4-bit universal shift register. [Section
10.16] [8]
Q.15 Write a VHDL code for a 4-bit universal shift register. [Section
10.17] [8]
May-15
Dec.-15
Q.17 Write a VHDL program for full adder using structural modelling. [Section
10.3.3] [8]
Q.18 Explain in detail the RTL design procedure. [Section 10.20] [16]
May-16
Q.19 Explain the various operators supported by VHDL. [Section 10.6.6] [8]
Q.21 Write the VHDL code to realize a 4 - bit parallel binary adder with
structural modelling and write the test bench to verify its functionality.
[Sections 10.9 and 10.21] [10]
Q.22 Write the VHDL code to realize a decade counter with behavioural
modelling.
Dec.-16
Q.23 Explain in detail the concept of structural modeling in VHDL with an
example of full adder. [Section 10.3.3] [13]
May-17
Q.26 Design a 3 - bit magnitude comparator and write the VHDL code to
realize it using structural modeling. (Refer listing 10.9.8) [13]
Q.27 Design a 4 x 4 array multiplier and write the VHDL code to realize it
using structural modeling. [13]
Q.28 Write the VHDL code for the given state diagram, using behavioral
modeling. [7]
Dec.-17
Q.29 Write a VHDL code to realize a full adder using behavioural modeling
and structural modeling.
Dec.-18
Q.32 Write a VHDL code to realize a half adder using behavioral modeling and
structural modeling.