0% found this document useful (0 votes)
33 views208 pages

VHDL

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views208 pages

VHDL

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 208

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,

a. Specify the desired behaviour of the circuit.

b. Synthesize the circuit.

c. Implement the circuit.

d. Test the circuit to check whether the desired specifications meet.

• 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).

• HDL describes the hardware of digital systems. This description is in textual


form. The Boolean expressions, logic diagrams and digital circuits (simple and
complex) can be represented using HDL. The features of HDL are :

■ 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.

■ It allows hardware designers to express their design with behavioral


constructs. An abstract representation helps the designer explore architectural
alternatives through simulations and to detect design bottlenecks before detailed
design begins.

■ The HDL makes it easy to exchange the ideas between the designers.

■ It resembles a programming language, but the orientation of the HDL is


specifically towards describing hardware structures and behavior. The storage,
retrieval and processing of programs written using HDL can be performed
easily and efficiently.

■ 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.

Structure of VHDL Module

Structure of VHDL Module


AU : Dec.-12, 17, May-15, 17

• The main components of a VHDL description consists of following kinds of


declarations :

■ 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.

• The syntax of a VHDL entity declaration is as shown below.

entity entity_name is

port ( signal_names : mode signal_type;

signalnames : mode signal_type;

signal_names : mode signal_type);

end entity_name ;
The following section describes the different elements of entity declaration.

entity_name : It is an identifier selected by the user to name the entity.

signal_names : It is a list of user selected identifiers to name external interface


signals.

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.

signal_type : It is a built-in or user defined signal type.

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.

entity gate_logic is port (

wr : in std_logic;

rd : in std_logic;

ad : inout std_logic_vector (7 downto 0) ;

ADD : in std_logic_vector (0 to 3) ;

x,y,z : out std_logic;

al : buffer std_logic_vector (7 downto 0)

);

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.

■ As a set of concurrent assignment statements (to represent dataflow)

■ As a set of interconnected components (to represent structure)

■ As a set of sequential assignment statement (to represent behavior)

■ As any combination of above three.

• The syntax for architecture is given below

architecture architecture_name of entity_name is Declarations

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.

variable variable_names : variables_type;


Example :

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.

• Example of configuration declaration :

library CMOS_LIB, MY_LIB

Configuration HA_BINDING of HALF_ADDER is

For HA_STRUCTURE

For XI : XOR2

Use entity CMOS_LIB.XOR_GATE (DATAFLOW);

end for;

For A1 : AND2

Use configuration MY_LIB.AND_CONFIG;

end for;

end for;
end HA_BINDING;

The library statement makes library names CMOS_LIB and MY_LIB visible
within the configuration declaration.

HA_BINDING is name of the configuration and it specifies a configuration for


the HALF_ADDER entity.

The statement for HA_STRUCTURE specifies that the architecture body


HA_STRUCTURE is selected for this configuration.

• 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 body (optional)

Package declaration

• It defines the interface to the package. The syntax of a package declaration is


given below.

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;

• The items declared in a package declaration can be accessed by other design


units by using the 'library' and 'use' clauses. This is explained in the further
section. The example of package declaration is given below.

package MUX 4-to-l_package is

component MUX 4-to-l

port (MO, Ml, M2, M3 : IN STD_LOGIC;

s : IN STD_LOGIC_VECTOR

(1 downto 0)

f : OUT STD_LOGIC ;

end component;

end MUX 4-to-l_package;


5. Package Body
• It contains the details of a package, that is the behavior of the subprograms
and the values of the deferred constants which are declared in a package
declaration. The package body may contain other declarations.

• The syntax of it is as given below.

package body package_name is

subprogram bodies

complete constant declarations

subprogram declarations

type and subtype declarations

file and alias 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

• In a VHDL or Verilog program, architecture body (VHDL) or the module


(Verilog) contains a series of concurrent statements. All concurrent statements
execute simultaneously. HDL has several different concurrent statements. Also,
it has a mechanism which bundles a set of sequential statements which
operate as a single concurrent statement. The way in which these statements
are used is called the modeling style or types of descriptions. Thus these
statements give rise to six different modeling styles or types of descriptions as,

* 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.

• In VHDL, the behavior of the entity is expressed using sequentially executed,


procedural code. The key mechanism used to model the behavior of the entity
is, a process statement.

Listing 10.3.1 : Example of VHDL behavioral

description

entity full_add is

port (A, B, Cin : in bit;


Sum, Cout : out bit);

end full_add;

architecture adder of full_add is

begin

process (A, B, Cin)

begin

Sum < = A xor B xor Cin;

Cout < = (A and B) or (Cin and A) or (Cin and B);

end process;

end adder;

In Verilog, the key mechanism used to model the behavior is predefined words
always or initial.

Listing 10.3.2 : Example of Verilog behavioral

description

module full_add (A, B, Cin, Cout, Sum);

input A, B, Cin;

output Sum, Cout;

reg Sum, Cout;

always @(A, B, Cin)

begin

Sum = (A Λ B) Λ Cin;

Cout = (A & B) | (Cin & A) | (Cin & B);

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.

Listing 10.3.3 : Example of VHDL data-flow

description

entity full_add is

port (A, B, Cin : in bit;

Sum, Cout : out bit); end full_add;

architecture adder of full add is

begin

Sum < = A xor B xor Cin;

Cout < = (A and B) or (Cin and A) or (Cin and B);

end adder;

In Verilog, predefined word assign is used to assign a value to the left-hand


side of a signal-assignment statement.

Listing 10.3.4 : Example of Verilog data-flow

description

module full_add (A, B, Cin, Cout, Sum);

input A, B, Cin;

output Sum, Cout;

assign Sum = (A Λ B) Λ Cin;


assign Cout = (A & B) | (Cin & A) | (Cin & B);

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

■ Components are used

■ Each component is simulated separately

• In the structural modeling, an entity is described as a set of components


connected by signals, that is, as a netlist. The components used in an
architecture may be from a library or may be ones that were previously
defined as part of a design.

entity full_add is

port (A, B, Cin : in bit;

Sum, Cout : out bit);

end full_add;

architecture adder of full_add is


component xor3

port ( II, I2,I3 : in bit;

O1 : out bit);

end component;

component and2

port ( I1, I2 : in bit;

O1 : out bit);

end component;

component or3

port ( I1, I2,I3 : in bit;

O1 : out bit);

end component;

signal S1, S2, S3 : bit;

begin

Y1 : xor3 port map (A, B, Cin, Sum);

XI : and2 port map (A, B, SI);

X2 : and2 port map (A, Cin, S2);

X3 : and2 port map (B, Cin, S3);

Y2 : or3 port map (SI, S2, S3, Cout);

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.

VHDL Identifiers and Types


VHDL Identifiers and Types
There are two types of identifiers in VHDL :

• Basic identifiers

• Extended identifiers

Basic identifier : The base identifier in VHDL is composed of a sequence of


one or more characters. Legal characters are ;

• Lower case letter (a ... z)

• Upper case letter (A ... Z)

• 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.

Examples : Signal l, H Adder

Extended identifier : The extended identifier in VHDL is a sequence of


characters written between two backslashes. Here, any allowable characters can
be used including characters like . , !, @, ', and $. Examples : /COUNT/ , /- 125/
, /TTL/ /Process/

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.

Other important points while representing any module in VHDL

1. Each statement in VHDL is terminated with a semicolon (;).

2. The name of the ports must be followed by a colon (:).

3. The architecture body starts with the predefined word begin, followed by
statements that detail the relationship between the outputs and inputs.

4. The comment should begin with two hyphens (“)•

5. Leaving the blank spaces between two words or at the beginning of the line
are allowed.

6. Leaving the blank line(s) is allowed in the module.

VHDL Data Objects


VHDL Data Objects
• A data object holds a value or a range of values of a specified type. It is
created by means of an object declaration. In VHDL, there are four classes of
data objects, signals, variables, constants and file.

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,

b) The declaration section of an architecture,

c) The declarative section of a package.

• The syntax for declaring signal is as follows :

SIGNAL signal_name : typename;


In this, the type_name indicates the legal value of the signal. The different
signal types are : BIT, BIT.VECTOR, BOOLEAN, INTEGER,ENUMERATION,
SIGNED, UNSIGNED, STD_LOGIC, STD_LOGIC_VECTOR, STD_ULOGIC etc.

The examples are given below.

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 :

VARIABLE variablename : variabletype : = initial value; For example,

VARIABLE index : INTEGER RANGE 0 TO 20 : = 0;

• 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.

They are also sometimes used to hold the results of computations.

3. Constant
• The syntax for declaring a constant in a VHDL is given below.

CONSTANT constant_name : type_name : = value;

For example,

CONSTANT BUS_SIZE : INTEGER := 32; - width of component

• It is to be noted that the value of a constant can be a simple expression.


4. File
• This is a special class of data objects. It serves as the interface between VHDL
programs and the host environment. There are some special operations that
can be performed only on files. These are reading and writing files. The basic
operations that we need for reading and writing files are as given below.

• Declaration of a file type

■ Declaration of a file

■ Opening and closing a file of a specified type

■ Reading from a file and writing to a file

• Now we will discuss each operation with example.

1. File type declarations

• 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,

TYPE file_type_name IS FILE OF type_name;

The type_name is the type of values contained in the file. For example,

TYPE TEXT IS FILE OF string;

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,

FILE file_names : file_type_name [open mode] IS string_expression;

• 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.

3. Opening and closing files

• 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 :

PROCEDURE FILE_OPEN (FILE FI: file_type_name;

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.

A file can be opened in three modes, READ_MODE, WRITE_MODE and


APPEND_MODE. The default mode is READ_MODE.

PROCEDURE FILE_OPEN (file_status : OUT

FILE_OPEN_STATUS;

file FI : file_type_name;

file_name : IN STRING

OPEN KIND : IN FILE OPEN KIND : = READ MODE);

- - This procedure returns the file open status, (other things are -similar to the
first procedure).

The FILE_OPEN_STATUS has a value returned by the procedure.

• This parameter may have one of the following four values.


1. OPEN_OK : File open operation was successful.

2. STATUS_ERROR : Attempted to open an already open file.

3. NAME_ERROR : File not found or not accessible.

4. MODE_ERROR : File cannot be opened in this mode.

• The value of FILE_OPEN_STATUS can be checked to ensure that the


FILE_OPEN call was successful.

PROCEDURE FILE_CLOSE (File F : file_type_name);

• The FILE_CLOSE procedure closes the file. There exists an implicit call to
FILE_CLOSE procedure which is called when execution terminates.

4. Reading and writing files

• 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.

PROCEDURE READ (FILE F : file_type_name; value : OUT type);

PROCEDURE WRITE (FILE F : file_typename; value : IN type);

FUNCTION ENDFILE (FILE F : file_type_name)

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.

VHDL Data Types and Operators


VHDL Data Types and Operators
AU : Dec.-11, 12, 15, 16, May-16

• VHDL supports a variety of data types. The type of a variable, signal, or


constant determines the operators that are predefined for that object as well
as the range of values that it can take on. 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.

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 :

type num is integer;

type long is range -32768 to 32768; -- 16-bit binary encoding.

type short is range 0 to 255; -- 8-bit binary encoding.


subtype shorter is short range 0 to 31; -- 5-bit binary encoding.

subtype shortest is short range 0 to 15; -- 4-bit binary encoding.

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 :

subtype shorter is short range 0 to 15;

• Then the object is synthesized into 4 wires. Objects declared type of type
integer without a range constraint will be synthesized into 32 wires.

Real (floating point) type

Example of integer object declaration :

Port (Il : in integer ;

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 :

type Real_data is real;

type Voltage is range to -12.0 to +12.0;

subtype min voltage is range -5.0 to +5.0;

Example of real object declaration :

Port (Il : in real ;

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 :

type Bit is (’0’, 1’);

type Switch_level is (’0’, ‘1’, ‘x’);

Examples of enumerated type object declaration :

Port (Il : in bit;

O1 : out Boolean);

Physical type

• Values of a physical type represent measurements of some quantity. Any


value of a physical type is an integral multiple of the base unit of measurement
for that type. For example, time (e.g. second, millisecond, microsecond, etc.)
and voltage (e.g., volt, millivolt, microvolt, etc.)

• 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 :

type time is range -1E18 to 1E18

units

fs; - femtosecond

ps = 1000 fs; - picosecond


ns = 1000 ps; - nanosecond

us = 1000 ns; - microsecond

ms = 1000 us; - millisecond

sec = 1000 ms; - second

min = 60 sec; - minute

end units;

type distance is range 0 to IE 16

units

- base unit:

A; - angstrom

- metric lengths;

nm = 10 A; - nanometer

um = 1000 nm; - micrometer (or micron)

mm = 1000 um; - millimeter

cm = 10 mm; - centimeter

m = 1000 mm; - meter

km = 1000 m; - kilometer

- - English lengths :

mil = 254000 A; - mil

inch = 1000 mil; - inch

ft = 12 inch; - foot

yd = 3 ft; - yard

fm = 6 ft; - fathom

mi = 5280 ft;- mile


lg = 3 mi; - league

end units;

x : distance; y : time; z : integer;

x := 5A + 13 ft - 27 inch; - arithmetic operations

y : = 3ns + 5 min; - on physical data type

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 :

type Multi_level_logic is (low, high, rising, falling);

type arith_op is (add, sub, mul, div);

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,

Variable operation : arithop := sub;

Variable level : Multi_level_logic := high;

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

• An array object is a composite object consisting of elements that have the


same subtype. The name for an element of an array uses one or more index
values belonging to specified discrete types. The value of an array object is a
composite value consisting of the values of its elements.

• An array object is characterized by the number of indices (the dimensionality


of the array), the type, position and range of each index and the type and
possible constraints of the elements. The order of the indices is significant.

• 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 :

type num is integer ;

type numarr is array (7 downto 0) of num;

-- numarr is an array of 8 integer numbers

type my_word is array (0 to 31) of BIT;

-- a memory word type with an ascending

range

type datain is array (7 downto 0) of five_level_logic;

-- an input port type with a descending

range
-- Example of unconstrained array

declarations

type memory is array (integer range o) of myword;

-- a memory array type

- Examples of array object declarations

signal dataline : datain ;

-- defines a data input line

variable mymemory : memory (0 to 2**n-1);

-- defines a memory of 2n 32-bit words

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;

subtype positive is integer range 1 to integerhigh;

type string is array (positive range o) of character;

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 :

subtype natural is integer range 0 to integerhigh;

type bit_vector is array (natural range <>) of bit;

- Examples of string and bit-vector object declaration

variable message : string (1 to 17) := "This is a message";

signal low_bite : bitvector (0 to 7);

Record type

• A record type is a composite type, objects of which consist of named


elements. The value of a record object is a composite value consisting of the
values of its elements. The record type is analogous to the record datatype in
pascal and the struct declaration in C.

• A record type definition creates a record types; it consists of the element


declarations, in the order in which they appear in the type definition.

Example :

type DATE is

record

DAY : INTEGER range 1 to 31 ;

MONTH : MONTH_NAME;

YEAR : INTEGER range 0 to 4000;

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 :

type ptr is access date;

- ptr is an access type whose values are

- addresses that point to object of type date.

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.

type_file_type_name is file of type_name;


• The type mark in a file type definition defines the subtype of the values
contained in the file. The type mark may denote either a constrained or an
unconstrained subtype. The base type of this subtype must not be a file type or
an access type. If the base type is a composite type, it must not contain a
subelement of an access type. If the base type is an array type, it must be a
one-dimensional array type.

Examples :

file of string - Defines a file type that can contain

- an indefinite number of strings

file of natural - Defines a file type that can contain

- only non-negative integer values

• Three operations are provided for objects of a file type. Given the following
file type declaration :

type FT is file of TM :

• Where type mark TM denotes a scalar type, a record type, or a constrained


array subtype, the following operations are implicitly declared immediately
following the file type declaration :

procedure read (F : in FT; value : out TM);

procedure write (F : out FT; value: in TM);

function endfile (F: in FT) return boolean;

• 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

The type stdjogic_vector represents an array of bits whose type is stdjogic.

Example :

Port (I : in stdjogic_vector (7 downto 0);


O : out bit);

In the above example, port I is declared as type std_logic_vector which has 8-


bits.

Signed

The type signed is a numeric type. It is declared in the external package


numeric_std and represents signed integer data in the form of an array. The
left most bit of objects of signed type represents sign and such objects are
represented in 2's complement form, let us see the object definition.

variable difference : signed (4 downto 0) := 10011;

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

• Shift and Rotate

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

• Relational operators are used to create equality or magnitude comparison


functions. VHDL provides the relational operators as shown in the Table 10.6.3.
• The following statement demonstrates the use of some of the above
relational operators :

if (A/=B) then ...

A is compared to B. If A is equal to B, then the value of the expression (A/= B) is


false (0); otherwise it is true (1).

if (A > B) then ...

If A is greater than B, the value of the expression

(A > B) is true (1); otherwise it is false (0).

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

• Arithmetic operators are used to create arithmetic functions. Arithmetic


operators provided by VHDL are listed in Table 10.6.4.
d. Shift and Rotate 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.

• Operators of higher precedence are associated with their operands before


operators of lower precedence. For a sequence of operators with the same
precedence level, the operators are associated with their operands in textual
order, from left to right. The precedence of an operator is fixed and may not be
changed by the user, but parentheses can be used to control the association of
operators and operands.

Structure of Behavioral Description


Structure of Behavioral Description
AU : Dec.-l0, 18, May-16, 17

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

generic (list of generics and their types);


Port (list of port names and their types

entity item declarations

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.

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 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;

Sum : out bit;

Cout : out 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.

• The syntax of an architecture body is :

architecture architecture_name of entity_name is

architecture item declarations

begin

Concurrent statements ; these include ->

process statement block statement

concurrent procedure call

statement

concurrent assertion statement

concurrent signal assignment

statement

component instantiation statement generate statement

end architecture_name;

• All concurrent statements execute in parallel and therefore their sequence in


the architecture body does not matter the behavior of the circuit. The
architecture body for half_adder is :
architecture adder of half_adder is

begin

process (A, B)

begin

Sum < = A xor B ;

Cout < = A and B ;

end process;

end adder;

3. Variable Assignment Statement


• We can use variables inside the processes. This is illustrated by the following
statements :

process (X)

variable A, B : bit; - variable declaration statement

begin

st l : A : =X; - Variable assignment statement

st2 : B := not A; - Variable assignment statement

st3 : O1 < = A; - use < = assignment operator

end process ;

• Variable assignment statements, as in C language, are calculated and


assigned immediately with no delay time between calculation and assignment.
The assignment operator : = is used assigned values to the variables instead of
assignment operator <=.

• 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

• An IF statement selects a sequence of statements for execution based on the


value of a condition. The condition can be any expression that evaluates to a
Boolean value.

VHDL Syntax :

if (Boolean Expression) then

statement 1;

statement 2;

else

statement x;

statement y;

end if;

Example :

if (EN = '1') then

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.

Ex. 10.7.1 : Execution of IF as a D latch.

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.

Ex. 10.7.2 : Execution of IF as ELSE-IF

VHDL syntax :

If (Boolean Expression 1) then

statement 1 ; statement 2; ...

elsif (Boolean Expression 2) then

statement x; statement y; ...

else

statement a; statement b; ...

end if ;

Example :

process (a, b, en)

begin

if en = '00' then

c < = a;

elsif en = '01' then


c < = b;

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'.

Ex. 10.7.3 : Behavioral description of 2 × 1 multiplexer using IF ELSE

VHDL 2 x 1 Multiplexer Using IF-ELSE

library ieee;

use ieee.std_logic_1164.all;

entity mux2 × 1 is

port ( DO, DI, S, Enbar : in std_logic;

Y : out std_logic);

end mux2 × 1;

architecture MUX of mux2 × 1 is

begin

process (S, DO, DI, Enbar)

- S, DO, DI and Enbar are the sensitivity

list of the process.

variable temp : std_logic;

- It is common practice in behavioral description to use variable(s) rather than


signal(s). This is done to avoid any timing errors that may arise due to the
sequential execution of signal statements.
begin

if Enbar = '0' then

if S = '1' then

temp := D1;

else

temp := D0;

end if;

Y < = temp;

else

Y < = 'Z';

end if;

end process;

end MUX;

Ex. 10.7.4 : Behavioral description of a 2 × 1 multiplexer using ELSE IF.

VHDL 2 × 1 Multiplexer Using ELSE-IF

library ieee;

use ieee.std_logic_1164.all;

entity mux2 × 1 is

port (DO, DI, S, Enbar : in std_logic;

Y : out std_logic);

end mux2×l;

architecture MUX of mux2×l is

begin
process (S, DO, DI, Enbar)

- S, DO, DI and Enbar are the sensitivity

list of the process.

variable temp : std_logic;

begin

if Enbar = 'O' and (S = '1') then

temp := D1;

elsif Enbar = '0' and (S = 'O') then

temp := D0;

else

temp := 'Z'; - 'Z' represents high impedance

state

end if;

Y < = temp;

end process;

end MUX;

b. Signal and Variable Assignment

• There is a difference between the execution of signal assignment statement


and variable assignment statement. We know that signal assignment
statement executes in two phases : calculation and assignment. For signal,
actual assignment of new value is delayed by the propagation delay. On the
other hand, when we use variable assignment statements, variables acquire
their new values instantaneously. Due to this difference in two assignments,
simulation result may be different if we use signals instead of variables. This is
illustrated in the example 10.7.5.
Ex. 10.7.5 : Behavioral description of a latch using variable and signal
assignment.

• 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

port (D, En : in bit;

Q, Qbar : out bit);

end DLatch_var;

architecture DL_Var of DLatch_var is

begin

VAR : process (D, En)

variable tempi, temp2 : bit;

begin

if En = '1' then

temp1 := D; - Variable assignment statement.

temp2 := not temp1; - Variable assignment statement

end if;

Q < = tempi; - Value of temp 1 is assignd to Q


Qbar <= temp2; - Value of temp 1 is assignd to Qbar

end process VAR;

end DL_Var;

Listing 10.7.2 : VHDL code for behavioral description of D-Latch using signal-
assignment statements

entity DLatchsig is

port (D, En : in bit;

Q : buffer bit;

Qbar : out bit);

- Q is declared as a buffer because it is an input/output signal.

- it appears on both the left and right hand sides of assignment statements.

end DLatch_sig;

architecture DL_sig of DLatch_sig is

begin

process (D, En)

begin

if En = '1' then

Q < = D; - signal assignment

Qbar < = not Q; - signal assignment

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

• The case statement is a special multi-way decision statement that tests


whether an expression matches one of a number of other expressions, and
branches accordingly. It has following syntax :

VHDL

case (control-expression) is
when test value or expression 1 ⇒ statements 1;

when test value or expression 2 ⇒ statements 2;

when others ⇒ statements n;

end case;

• The expression value may be expressed as single value, or as a range of


values or as a value of specified expression. The statement when others can be
used to guarantee that all conditions are covered. Use of multiple when others
statements in one case statement is illegal.

Example :

VHDL

case option is

when "00" ⇒ temp := a + b;

when "01" ⇒ temp := a - b;

when "10" ⇒ temp := a* b;

when others ⇒ temp : = a / b;

end case;

• In above example, the control is option. If option = 00, then temp = a + b; if


option = 01, then temp = a - b; if option = 10, then temp = a * b; if option = 11
(others or default), then temp = a / b;

d. Comparison between CASE and IF Statement

• IF statement produces priority encoded logic.

Example :

process (sel, a, b, c, d)

begin

if sel = '00' then


op < = a;

elsif sel ='01' then

op < = b;

elsif sel ='10' then

op < = c;

else

op < = d;

end if;

end process;

• Here, priority encoded logic means firstly the IF statement executes


sequentially, so depending on the first IF condition that particular input is
connected to output. Next depending on the second IF condition, the another
input is passed to output. According to this logic, for this example, three
multiplexer are generated by tool. So in this case hardware is more so the
delay generated by logic gates is more; so the speed is reduced.

• The case statement produces parallel logic. Here, in case statement


depending on the value of "sel" one of the four inputs is passed to the output.
So a single multiplexer of 4 inputs with two select lines and one output is
generated by a tool. So the generated hardware is less, so the delay by logic
gates is less; so the speed is high.

Example :

process (sel, a, b, c, d)

begin

case sel is

when '00' = >op < = a;

when '01' = >op < = b;

when '10' = >op <= c;

when others = >op < = d;


end case;

end process;

Ex. 10.7.6 : Behavioral description of a positive edge triggered JK flip-flop


using the case statement.

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.

VHDL Positive Edge-Triggered JK Flip-Flop Using Case

library ieee;

use ieee.std_logic_1164.all;

entity JK_FF is

port( JK : in bit_vector (1 downto 0);

clk : in std_logic;

Q, Qbar : out bit);


end JK_FF;

architecture Flip_Flop of JK_FF is

begin

P1 : process (elk)

variable tempi, temp2 : bit;

begin

if rising_edge (elk) then

case JK is

when "01" => tempi := '0';

when "10" => tempi := '1';

when "00" => tempi := temp1;

when "11" => tempi := not temp1;

end case;

Q < = temp1;

temp2 := not tempi;

Qbar < = temp2;

end if;

end process P1;

end Flip_Flop;

Ex. 10.7.7 : Behavioral description of a 3-bit up counter.

A counter is a register capable of arriving at its clock input. For up counters,


the next state is the increment of the present state. For example, if the present
state is 010, then the next state is Oil. For down counters, the next state is the
decrement of the present state. A 3-bit up counter counts from 0 to 7, i.e., it is
a mod 8 counter.
The Fig. 10.7.8 shows the logic symbol and excitation table for 3-bit counter. It
has two inputs : elk and Reset (active high). On the positive edge of the elk
(Clock) input counter increments only if Reset input is 0 (Low); otherwise
counter output is reset to 000.

Listing 10.7.4 : HDL code for a 3-bit binary counter using the case statement.

VHDL 3-Bit Binary Counter Case Statement Description

library ieee;

use ieee.std_logic_1164.all;

entity CTCase is
port ( elk, Reset : in std_logic;

Q : buffer std_logic_vector (2 downto 0));

end CT_Case;

architecture Counter_3b of CT_case is

begin

counter : process(clk)

variable temp : std_logic_vector (2 downto 0) := "011";

- 011 is the initial value, so the

counter starts from 100

begin

if rising_edge (elk) then

if Reset = '0' then

case temp is

when "000" => temp := "001";

when "001" => temp := "010";

when "010" => temp := "011";

when "Oil" => temp := "100";

when "100" => temp := "101";

when "101" => temp := "110";

when "110" => temp := "111";

when "111" => temp := "000";

when others => temp := "000";

end case;

else
temp := "000";

end if;

end if;

Q < = temp;

end process counter;

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

port ( SEL: in STD_LOGIC_VECTOR(3 downto 0);

P0, Pl, P2, P3, P4, P5, P6, P7, P8, P9, P10 , PH, P12,

P13, P14, P15 :in STD_LOGIC;

MUX_OUT: out STD_LOGIC );

end Mux8_l;

architecture BEHAVIORAL of Muxl6_l is

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;

when "0001" => MUXOUT <= Pl;

when "0010" => MUX OUT <= P2;

when "0011" => MUX_OUT <= P3;

when "0100" => MUX_OUT < = P4;

when "0101" => MUX_OUT <= P5;

when "0110" => MUX_OUT < = P6;

when "0111" => MUX_OUT <= P7;

when "1000" => MUX_OUT <= P8;

when "1001" => MUX_OUT <= P9

when "1010" => MUX OUT <= P10;

when "1011" => MUX OUT <= P11;

when "1100" => MUX_OUT < = P12;

when "1101" => MUX_OUT < = P13;

when "1110" => MUX_OUT <= P14;

when "1111" => MUX_OUT <= P15;

when others = > null;

end case;

end process;

end BEHAVIORAL;

e. Loop Statement

• Loop is a sequential statement. It includes a sequence of statements that is


to be executed repeatedly, zero or more times. The number of repetitions is
controlled by the range of an index parameter. The loop statement should be
written inside process in VHDL.
For-Loop Statement

VHDL for loop

• The general syntax for a for-loop is :

For index [iteration scheme] loop

statementl; statement2; statements;

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.

• We can use downto cause to create a descending range. Here is the


example :

for i in 10 downto 1 loop

i_squared (i) := 1 * 1;

end loop;

In this case, the iteration index (i) is decremented by


1 in each iteration.

While-Loop Statement

The general syntax of while-loop in VHDL is :

while (condition)

statement 1; statement2; statements;

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;

While (Count < 10) loop - Executes loop till count is 9

Count := Count + 1;

Result := Result + Count;

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.

VHDL Next and Exit

• 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)

constant max_limit : integer := 100;


begin

for i in 0 to max_limit loop

if (done(i) = true) then next;

else

done(i) := true;

end if;

mul(i) <= A(i) * B(i);

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

• It is used for internal consistency check or error message generation. The


syntax for an assert statement is :

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.

Example : assert j < 1 report "internal error, tell someone";

assert elk = '1' report "clock not up" severity

WARNING;
The predefined severity names are : NOTE, WARNING, ERROR, FAILURE and
default severity for assert is ERROR.

g. Report Statement

• It is used to output messages. The syntax for report statement is :

report string [severity name];

report "finished passl"; - default severity name is NOTE

report "Inconsistent data." severity FAILURE;

Structure of Data Flow Description


Structure of Data Flow Description
AU : Dec.-12, 16

• 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.

Listing 10.8.1 : VHDL code for AND-OR circuit

VHDL AND-OR Circuit Description.

entity AND_OR is

port (A, B, C, D, E : in bit;

Y : out bit);

end;

architecture digital_ckt of AND-OR is


signal I1, I2;

begin

stl : I1 < = A and B after 10ns;

st2 :I2 < = C and D and E after 10ns;

st3 : Y < = Il or 12 after 20ns;

end digital_ckt;

1. Signal Declaration and Assignment Statement


• Here, input and output signals are declared in the entity as ports. However,
the intermediate signals (Il and 12 in the listing 10.8.1) are declared using the
predefined word signal in the architecture. A signal assignment operator <= is
used in VHDL to assign a value to the left-hand side of a signal-assignment
statement. The left-hand side of the statement should be declared as a signal.
The right-hand side can be a signal, a variable or a constant.

2. Assigning a Delay Time to Signal Assignment


Statement
• The execution of assignment statement is done in two phases : calculation
and assignment. Consider the listing 10.8.1 and the simulation waveform
shown in the Fig. 10.8.2.
Calculation : The value of II is calculated using the current values of A and B at
time TO. This value is (1 and 0) = 0 in VHDL.

Assignment : The calculated value is not immediately assigned to II; however it


is assigned to II after a time delay of 10 ns. The delay time can be implicitly or
explicitly specified. In our case, we have assumed propagation delay of each
gate as 10 ns and hence we have explicitly specified time delay equal to 10 ns.

The change in the II at T = 110 ns constitute an event in signal assignment


statement st3 and this causes execution of st3. For statement st3, at T = 110
ns, 12 = 0 and II = 0 and hence the calculated new value of Y at T = 110 ns is (Il
or 12) = 0. This change in value for Y from 1 to 0 is assigned to Y after 10 ns -
that is, at T1 = 110 + 10 = 120 ns.

Important points

• To assign a delay time to a signal assignment statement, we use the


predefined word after (delay time) in VHDL.

• 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.

a. Simple Assignment Statements

• A logic or arithmetic expression is called a simple assignment statement.

• For example :

f <= X AND Y;

b. Selected Signal Assignment

• A selected signal assignment allows a signal to be assigned one of multiple


values, based on a selection criterion. Let us see the selected signal assignment
used in 2 to 1 multiplexer as an example. Assume that WO, W1 and S are the
inputs of multiplexer and f is the output. The selected signal assignment begins
with the keyword WITH, which specifies that S is to be used for the selection
criterion, as shown below. The two WHEN clauses state that f is assigned the
value of WO when S = 0; otherwise, f is assigned the value of Wl.

WITH S SELECT

f < = WO WHEN 'O'

W1WHEN OTHERS;

c. Conditional Signal Assignment

• It is similar to selected signal assignment. It allows a signal to be set to one of


several values. For 2 to 1 multiplexer, the conditional signal assignment is as
follows.

f < = WO WHEN S = 'O' ELSE W1;


• The common property of all the above statements is that the ordering of the
statements does not affect the meaning of the code. Hence, these statements
are called as 'the concurrent assignment statements'.

• 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;

• Drawback of concurrent statements is, it provides multiple drivers for a


single output. So to solve this problem you have to resolve the output. User
written resolution function defines it. The value of each driver is an input to
the resolution function and, based on the computation performed within
resolution function, the value returned from this function becomes the
resolved value for the signal.

Let us see different types of concurrent statements.

WHEN Statement

D <= A WHEN SEL_A = "0" ELSE

B WHEN SEL_B = "1" ELSE C;

• In this concurrent statement whenever an event is occurred on signal used in


condition, the conditional signal assignment statement is executed.

WITH SELECT

Syntax

WITH expression SELECT

Target < = Expressionl WHEN choicel

Expression2 WHEN choice2

Expressionn WHEN choicen


• It evaluates each choice expression and compares the value with each
choice. The selected signal assignment statement selects different values for
target signal based on the value of select expression. The semantics of a
selected signal assignment statement is, whenever an event occurs on a signal
in the select expression or on the expressions, the statement is executed.
Based on the value of the select expression that matches the choice value
specified, the value of the corresponding expression is scheduled to be
assigned to the target signal. Note that the choices are not evaluated in
sequence. An "others" choice may cover values not covered explicitly.

WITH SELECT

WITH sel_a SELECT

op < = a WHEN "00",

b WHEN "01",

c WHEN "10"

0 WHEN OTHERS;
4. Comparison between Concurrent and Sequential
Statement

5. Constant Declaration and Assignment


A constant in HDL is same as constant in C language; its value is constant within
the segment of the program where it is visible. A constant in VHDL can be
declared using predefined word constant. For example,

constant delay : time ;

In VHDL, we use the assignment operator := to assign a value to a constant.

delay := 10ns; - VHDL


It is possible to assign a value to the constant in the declaration statement
itself. This is shown in following examples.

constant delay : time := 10ns; - VHDL

6. Data type - Vectors

• The vector data type declares an array of similar elements, rather than
declaring each individual bit separately. For example,

Individual bit declaration :

signal A0, Al, A2, A3 : bit ; - VHDL

Vector declaration :

signal A : bitvector (3 downto 0) ; - VHDL

signal A : bit_vector (0 to 3) ; - VHDL

• 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 :

A[3] = 1, A[2] = 1, A[l] = 0, A[0] = 0

On the other hand, if the declaration is

signal A : bit_vector (0 to 3) then the elements of vector A are :

A[0] = 1, A[l] = 1, A[2] = 0, A[3] = 0.

Ex. 10.8.1 : 4 × 1 Multiplexer.

• 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.

VHDL 4 × 1 Multiplexer Description,

library ieee;

use ieee.std_lo9ic_1164.all;
entity mux4×1 is

port ( D : in std_logic_vector (3 downto 0);

S, Enbar : in std_logic;

Y : out std_logic);

end mux4×l;

architecture MUX of mux4×1is

signal II, 12, 13, 14, 15, 16,17 : std_logic;

begin

- Assume 10 nanoseconds propagation delay

- for all and, or, and not.

11 < = not SO after 10 ns;

12 < = not SI after 10 ns;

13 < = not Enbar after 10 ns;

14 < = DO and II and 12 and 13 after 10 ns;

15 < = DI and SO and 12 and 13 after 10 ns;

16 < = D2 and SI and II and 13 after 10 ns;

17 < = D3 and SO and SI and 13 after 10 ns;

Y < = 14 or 15 or 16 or 17 after 10 ns;

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;

Sum: out bit;

Cout: out bit);

end half_adder;

architecture adder of half_adder is

begin

Sum <= A xor B; -- signal assignment statement.

Cout <= A and B; -- signal assignment statement.

end adder;

Listing 10.8.4 VHDL code of a 2 × 1 multiplexer. VHDL 2 × 1 Multiplexer


Description.

library ieee;

use ieee.std_logic_1164.all;

entity mux2×1 is

port ( DO, D1, S, Enbar: in std_logic;

Y: out std_logic);

end mux2×1;

architecture MUX of mux2×1 is

signal II, 12, 13, 14 : stdlogic;


begin

- Assume 10 nanoseconds propagation delay

- for all and, or, and not.

11 < = not S after 10 ns;

12 < = not Enbar after 10 ns;

13 < = DO and II and 12 after 10 ns;

14 < = DI and S and 12 after 10 ns;

Y < = 13 or 14 after 10 ns;

end MUX;

Listing 10.8.5 : VHDL code of a 2 × 2 magnitude comparator,

library ieee;

use ieee.std_logic_1164.all;

entity COMP_2 is

port ( A, B : in std_logic_vector(l downto 0);

AgtB, AltB, AeqB : out std_logic;

end COMP 2;

architecture COMP of COMP_2 is

begin

AgtB < = (A(0) and not B(l) and not B(0)) or (A( 1) and not B(l))

or A(l) and A(0) and not B(0));

AltB <= (not A(l) and not A(0) and B(0)) or (not A(0) and B(l) and B(0))

or (not A(l) and B(l));

AeqB <= (A(0) xnor B(0)) and (A(l) xnor B(l));

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;

Q, Qbar : buffer std_logic);

- Q and Qbar are declared as buffer because they act as

- both input and output, they appear on the right and left

- hand side of signal assignment statements, inout or

- linkage could have been used instead of buffer.

end D_Latch;

architecture Latch of D_Latch is

constant Delay_Nand : Time := 10 ns;

begin

Q < = Qbar nand (D nand EN) after 2*Delay_Nand;

Qbar < = Q nand ((D nand D) nand EN) after 3*Delay_Nand;

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'

Use continuous assignment statements.

library ieee;

entity ckt is

port (A, B, C, D : in std_logic;

(x, y : out std_logic);


end ckt;

architecture COMB of ckt is

begin

x < = A or (B and C) or (not B and D);

y < = (not B and C) or (B and (not C) and (not D));

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

Port (port list);

end component;

For example, following description declares AND gate component.

component and2

port ( II, 12 : in std_logic;

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 :

component_label : component name port map(association list);

• 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.

Listing 10.9.1 : VHDL structural description.

library ieee;

use ieee.std_logic_1164.all;

entity half_adder is

port ( A, B : in std_logic;

Sum, Cout: out std_logic);

end half_add;

architecture adder of half_adder is

.. Component Declaration

component xor2

port ( II, 12 : in std_logic;

O1: out std_logic);

end component;

component and2
port ( II, 12 : in std_logic;

Ol : out std_logic);

end component;

begin

.. Statements instantiation

XI : xor2 port map (A, B, Sum);

A1 : and2 portmap (A, B, Cout);

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.

Listing 10.9.2 : VHDL code of half adder,

library ieee;

use ieee.std_logic_1164.all;

entity xor2 is

port(Il, 12 : in std_logic;

Ol : out std_logic);

end xor2;

architecture xor_gate of xor2 is

begin

O1 <= I1 xor I2;

end xor_gate;

library ieee;
use ieee.std_logic_1164.all;

entity and2 is

port (II, 12 : in std_logic; Ol : out std_logic);

end and2;

architecture and gate of and2 is

begin

O1 < = I1 and I2;

end and_gate;

library ieee;

use ieee.std_logic_1164.all;

entity half_adder is

port ( A, B : in std_logic;

Sum, Cout: out std_logic);

end half_adder;

architecture adder of half_adder is

component xor2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component and2

port ( I1, I2 : in std_logic;

O1 : out std_logic);

end component;

begin
XI : xor2 port map (a, b, S);

A1 : and2 port map (a, b, C);

end adder;

3. VHDL Program Examples


Listing 10.9.3 : VHDL code for the half adder,

library ieee;

use ieee.std_logic_1164.all;

entity I2_O2 is

port ( II, 12 : in std_logic;

Ol, 02 : out std_logic);

end I2_O2;

architecture HA of I2_O2 is

component xor2

port ( II, 12 : in std_logic;

Ol : out std_logic);

end component;

component and2

port ( II, 12 : in std_logic;

Ol : out std_logic);

end component;

for A1 : and2 use entity work.two_input (and2_4);

for XI : xor2 use entity work.two_input (xor2_4);

begin
XI : xor2 port map (II, I2, O1);

A1 : and2 port map (I1, I2, O2);

end HA;

Listing 10.9.4 : VHDL description of a full adder.

library ieee;

use ieee.std_logic_1164.all;

entity full_adder is

port ( A, B, Cin : in std_logic;

Sum, Cout: out std_logic);

end full_adder;

architecture adder of full_adder is

component HA

port ( II, 12 : in std_logic;

Ol, 02 : out std_logic);

end component;

component or2

port ( II, 12 : in std_logic;

Ol : out std_logic);

end component;

for all : HA use entity work.I2_O2 (HA);

for all : or2 use entity work.two_inout (or2_4);

signal SO, CO, Cl : stdlogic;

begin

HA1 : HA port map (A, B, S0, C0);


HA2 : HA port map (Cin, S0, Sum, C1);

OR1 : or2 port map (C0, C1, Cout);

end adder;

Listing 10.9.5 : HDL description of a 2 x 1 multiplexer with active low enable,

library ieee;

use ieeeR.std_logic_1164.all;

entity mux2 × 1 is

port ( DO, DI, S, Enbar : in std_logic;

Y : out std_logic);

end mux2 × 1;

architecture MUX of mux2 × 1 is

- Components declaration

component and3

port ( II, 2, I3 : in std_logic;

O1 : out std_logic);

end component;

- Only different types of components need be declared.

- Since the multiplexer has two identical AND gates,

- only one is declared.

component or2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component inv
port ( I1 : in std_logic;

O1 : out std_logic);

end component;

signal II, 12, 13,14 : std_logic;

for all: and3 use entity work.three_input (and3 7);

for all: inv use entity work.one_input (inv_7);

for all: or2 use entity work.two_input (or2_7);

begin

- instantiation

A1 : and3 port map (DO, II, 12,13);

A2 : and3 port map (DI, S, 12, 14);

IV1: inv port map (S, I1);

IV2: inv port map (Enbar, I2);

O : or2 port map (13, 14, Y);

end MUX;

Listing 10.9.6 : VHDL description of a 2 x 4 decoder with enable input,

library ieee;

use ieee.std_logic_1164.all;

entity decoder2 × 4 is

port ( A, B, En : in std_logic;

Y : out std_logic_vector (3 downto 0));

end decoder2 × 4;

architecture decoder of decoder2×4 is

component inv
port ( I1 : in std_logic;

O1 : out std_logic);

end component;

component and3

port ( I1, I2, I3 : in std_logic;

O1 : out std_logic);

end component;

for all: inv use entity work.one_input (inv_4);

for all: and3 use entity work.three_input (and3_4);

.. Signal Declaration

signal Abar, Bbar : stdlogic;

begin

IV0 : inv port map (A, Abar);

IV1: inv port map (B, Bbar);

A0 : and2 port map (Abar, Bbar, En, Y0);

A1 : and2 port map (Abar, B, En, Y1);

A2 : and2 port map (A, Bbar, En, Y2);

A3 : and2 port map (A, B, En, Y3);

end decoder;

Listing 10.9.7 : HDL description of a 2 x 4 decoder with tri-state output,

library ieee;

use ieee.std_logic_1164.all;

entity decoder2 × 4 is

port ( A, B : in std_logic;
En : in std_logic;

Y : out std_logic_vector (3 downto 0));

end decoder2 × 4;

architecture decoder of decoder2 × 4 is

component bufif1

port (I1, I2 : in std_logic; O1 : out std_logic);

end component;

component inv

port ( I1 : in std_logic;

O1 : out std_logic);

end component;

component and2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

for all: bufifl use entity work.two_input (bufifl);

for all : inv use entity work.one_input (inv_4);

for all: and2 use entity work.bind2 (and2_4);

- Signal Declaration

signal 10, II, 12, 13 : stdlogic;

signal Abar, Bbar : std logic;

begin

B0 : bufifl port map (10, En, Y(0));

BI : bufifl port map (II, En, Y(l));


B2 : bufifl port map (12, En, Y(2));

B3 : bufifl port map (13, En, Y(3));

IV0 : inv port map (A, Abar);

IV1 : inv port map (B, Bbar);

A0 : and2 port map (Abar, Bbar, 10);

A1 : and2 port map (Abar, B, II);

A2 : and2 port map (A, Bbar, 12);

A3 : and2 port map (A, B, 13);

end decoder;

Listing 10.9.8 : VHDL description of a 3-bit comparator using adders,

library ieee;

use ieee.std_logic_1164.all;

entity compare3_bit is

port ( A, B : in stdlogicvector (2 downto 0);

AgtB, AltB, AegB : buffer std_logic);

end compare3_bit;

architecture compare of compare3_bit is

component full_adder

port ( II, 12, 13 : in std_logic;

Ol, 02 : out std_logic);

end component;

component inv

port ( Il : in std logic;

O1 : out std_logic);
end component;

component nor2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component and3 port ( II, 12, 13 : in std_logic;

O1 : out std_logic);

end component;

for all: fulladder use entity work.full_adder (adder);

for all: inv use entity work.one_input (inv_4);

for all: nor2 use entity work.two_input (nor2_4);

for all: and3 use entity work.three_input (and3_7);

signal Sum, Bbar : stdlogicvector (2 downto 0);

signal C : std logic vector (2 downto 1);

begin

in1 : inv port map (B(0), Bbar(0));

in2 : inv port map (B(l), Bbar(l));

in3 : inv port map (B(2), Bbar(2));

F0 : full_adder port map (A(0), Bbar(0), 'O', Sum(0), C(l));

FI : full_adder port map (A(l), Bbar(l), C(l), Sum(l), C(2));

F2 : full_adder port map (A(2), Bbar(2), C(2), Sum(2), AgtB);

A1 : and3 port map (Sum(0), Sum(l), Sum(2), AeqB);

Nl : nor2 port map (AeqB, AgtB, AltB);

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 : buffer std_logic);

- Q, Qbar are declared buffer because they behave as input and output, end
SR_Latch;

architecture Latch of SR_Latch 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

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

for all: nor2 use entity work.two_input (nor2_7);

begin

nl : nor2 port map (S, Q, Qbar);

n2 : nor2 port map (R, Qbar, Q);

end Latch;

Listing 10.9.10 : VHDL description of a D latch,

library ieee;

use ieee.std_logic_1164.all;
entity D_Latch is

port ( D, En : in std_logic;

Q, Qbar : buffer std_logic);

end D_Latch;

architecture Latch of D_Latch is

- 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

- mapping. In this case, change all in and out to buffer,

component nand2

port ( I1, I2 : in std_logic;

O1 : out std_logic);

end component;

for all : nand2 use entity work.two_input (nand2_7);

signal SI, R, R1 : std_logic;

begin

NA1 : nand2 port map (D, En, S1);

NA2 : nand2 port map (R, En, R1);

NA3 : nand2 port map (D, D, R); - nand gate used as an inverter

NA4 : nand2 port map (SI, Qbar, Q);

NA5 : nand2 port map (Q, Rl, Qbar);

end Latch;

Listing 10.9.11 : VHDL description of a SR-flip-flop.

library ieee;

use ieee.std_logic_1164.all;
entity SR_FF is

port ( S, R, CP : in std_logic;

Q, Qbar : buffer stdlogic);

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

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

for all : nand2 use entity work.two_input (nand2_7);

signal SI, Rl : std logic;

begin

NA1 : nand2 port map (S1, Qbar, Q);

NA2 : nand2 port map (Q, Rl, Qbar);

NA3 : nand2 port map (S, CP, S1);

NA4 : nand2 port map (R, CP, R1);

end Latch;

Listing 10.9.12 : VHDL description of a D flip-flop,

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

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

for all : nand2 use entity work.two_input (nand2_7);

signal SI, R, Rl : std_logic;

begin

NA1 : nand2 port map (D, CP, S1);

NA2 : nand2 port map (R, CP, R1);

NA3 : nand2 port map (D, D, R); - nand gate used as an inverter

NA4 : nand2 port map (SI, Qbar, Q);

NA5 : nand2 port map (Q, Rl, Qbar);

end FF;

Listing 10.9.13 : VHDL description of JK flip-flop.

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

- mapping. In this case, change all in and out to buffer,

component nor2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component and3

port ( I1, I2,I3 : in std_logic;

O1 : out std_logic);

end component;

for all : nor2 use entity work.two_input (nor2_7);

for all: and3 use entity work.three_input (and3_7);

signal R, S

begin

N1 : nor2 port map (S, Q, Qbar);

N2 : nor2 port map (R, Qbar, Q);

A1 : and3 port map (Q, K, CP, R);

A2 : and3 port map (Qbar, J, CP, S);

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.

• In VHDL, the syntax of a simple iterative generate loop is given below.

label: for identifier in range generate

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

port ( A, B : in std_logic_vector (1 to 8);

O : out std_logic_vector (1 to 8));

end and8;

architecture and8_arch of and8 is

component and

port ( X, Y : in std_logic;

Z : out std_logic);
end component;

begin

G1 : for c in 1 to 8 generate

U1 : and port map (A(c), B(c), O(c));

end generate;

end and8_arch;

• We declare the parameters (For example : Bus width) as constants within a


VHDL program. The value of a constant must be known when a VHDL program
is compiled. But in many applications it is useful to design and compile a VHDL
program without specifying the values of some parameters. VHDL provides this
facility with generic statement.

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

generic (constant_names : constanttype;

constant_name : constant_type;

constant_name port ( signalname

signalnames

signal names : mode signal_type);

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

generic (width : integer := 8);

port ( A : in std_logic_vector(width-l downto 0);

B : out std_logic_vector (width-1 downto 0));

end businv;

architecture businv_arch of businv is

component inv port ( I: in std_logic)

O : out stdlogic);

end component;

begin

gl : for w in width-1 downto 0 generate

ul : inv port map (A(w), B(w));

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.

Ex. 10.9.1 : Structural description of (N + 1) - Bit magnitude comparator using


Generate statement.

We have seen the structural description of 3-bit comparator in listing 10.9.8.


Here, we will see the description of (N + 1) - bit comparator using generate
statement.

Listing 10.9.14 : VHDL description of N-bit magnitude comparator using


generate statement,

library ieee;

use ieee.std_logic_1164.all;
entity comp_gen is

generic (N : integer := 3);

port (A, B : in std_logic_vector (N downto 0);

AgtB, AltB, AeqB : buffer std_logic);

end comp_gen;

architecture compare of comp_gen is

component full_adder

port (II, 12, 13 : in std_logic; Ol, 02 : out std_logic);

end component;

component inv

port (I1 : in std_logic; O1 : out std_logic);

end component;

component nor2

port (II, 12 : in std_logic; Ol : out std_logic);

end component;

component and2

port (I1, I2 : in std_logic; O1 : out std_logic);

end component;

signal Sum, Bbar : std_logic_vector (N downto 0);

signal C, eq : std_logic_vector (N + 1 downto 0);

for all: fulladder use entity work.bind32 (fulladd);

for all : inv use entity work.bindl (inv_0);

for all: nor2 use entity work.bind2 (nor2_7);

for all: and2 use entity work.bind2 (and2_7);


begin

C(0) <= 'O';

eq(0) <= '1';

G1 : for i in 0 to N generate

vl : inv port map (B(i), Bbar(i));

FA : full_adder port map (A(i), Bbar(i), C(i), Sum(i),

C(i+1));

A1 : and2 port map (eq(i), Sum(i), eq(i+1));

end generate Gl;

AgtB <= C(N+1);

AeqB <= eq(N+l);

nl : nor2 port map (AeqB, AgtB, AltB); end compare;

Ex. 10.9.2: Structural description of an N-bit Asynchronous Down counter


using generate.

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

generic (N : integer := 4); - This is a 4-bit counter.

port ( CP : in std_logic ;

Q, Qbar : buffer std_logic_vector (N-l downto 0));

end asyn_ctr;

architecture asyn_ctr_gen of asyn_ctr is

component JK_FF is

port( II, 12, 13 : in std_logic;

Ol, 02 : buffer std_logic);

end component;

for ail: JK_FF use entity work. JKFF (FF);

signal s : std_logic_vector (N downto 0);

begin

s <= (Q & CP);


- s is the concatenation of Q and CP. This concatenation is necessary to

- specify the clock of each JK flip-flop in generic statement.

Gnlop : for i in (N-l) downto 0 generate

G1 : JK_FF port map ('1', '1', s(i), Q(i), Qbar(i));

end generate GnLop;

end asyn_ctr_gen;

Ex. 10.9.3 : Structural description of an N-bit memory word using Generate.

This single memory cell can be expanded to N-bit using the generate
statement. This is illustrated in listing 10.9.16.

Listing 10.9.16 : VHDL description of N-bit memory word using generate

library ieee;

use ieee.std_lo9ic_1164.all;

entity memory_word is

generic (N : integer := 8);

port ( D_in : in std_logic_vector (N downto 0);

Sel, R_W : in std_logic;

D_out : out std_logic_vector (N downto 0));

end memoryword;

architecture word_gen of memory_word is

component memory_cell

port ( Sel, RW, Din : in std_logic;

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

M : memory_cell port map (sel, R_W, D_in(i), D_out(i));

end generate;

end word_gen;

Ex. 10.9.4 : Structural description of N-bit register.

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.

Listing 10.9.17 : VHDL description of N-bit register.

library ieee;

use ieee.stdlogicl 164.all;

entity Regis is

generic (N : integer : = 8); - 8-bit register

port(D : in std_logic_vector(N-l downto 0);

CP : in std_logic;
Q, Qbar : out std_logic_vector(N-l downto 0));

end Regis;

architecture register_nBit of Regis is

component D_FF is

port( I1, I2 : in std_logic;

Ol, 02 : buffer std_logic);

end component ;

begin

build: for i in 0 to N-l generate

for ail: D_FF use entity work.DFF (FF);

begin

d : D_FF port map(D(i),CP, Q(i), Qbar(i));

end generate build;

end register_nBit;

Ex. 10.9.5 : Structural description of N-bit shift register.

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

generic (N : integer := 8); - 8-bit register

port(Din : in std_logic;

CP : in std_logic;

Dout : out std_logic;

Q, Qbar : out std_logic_vector(N-l downto 0));

end Regis_Ls;

architecture register_nBit of Regis_Ls is

component D_FF is

port( I1, I2 : in std_logic;

O1, O2 : buffer std_logic);

end component ;

begin

build: for i in 0 to N-l generate

for all: D_FF use entity work.DFF (FF);

signal D : std_logic_vector (N downto 0);


begin

D < = (Q 8c Din);

d : D_FF port map(D(i), CP, Q(i), Qbar(i));

end generate build;

Dout <= D(N);

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.

• Function : Function performs sequential computations and return a value as


a the value of the function.

1. Must have at least one input argument.

2. Computes and returns a single value.

3. Executes in zero simulation time.

4. Always terminated by return statement.

5. Can be called only from within process.

• Procedure : Procedure performs sequential computations and return values


in global objects or by storing values into formal parameters.

1. May be used to partition large behavioral descriptions.

2. May return zero or more values.


3. May or may not execute in zero simulation time, depending on whether it
has a wait statement or not.

4. Can be called only from within process.

5. Can have more than one input and output.

• 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

end [function / procedure] [subprogram_name[;

• Subprogram specification gives name of subprogram and it defines the


formal parameters, their class (i.e., signal, variable, file or constant), their type,
and their mode (in, out or inout).

• 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.

• The subroutine-item-declaration contains a set of declaration (e.g., type and


object declarations) that are accessible for use within the subprogram. Every
time, when subprogram is called, declarations come into effect - variables are
created and initialized. Their existence is within the subprogram.

• The subprogram-statement contains sequential statements. These sequential


statements define the computation to be performed by the subprogram.

• The subprograms are terminated by return statement. The format of a return


statement is :

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

[pure I impure] function function-name (parameter list)

return return type

• 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

port ( a : in bitvector (0 to 2);

m : out bit_vector (0 to 2));

end func;

architecture example of func is

function simple (w, x, y : bit) return bit is - function declaration

begin

return (w and x) or y; - function body

end;

being

process (a)

begin
m(0) < = simple (a(0), a(l), a(2)) ; - function call

m(l) < = simple (a(2), a(0), a(l)); - function call

m(2) < = simple (a( 1), a(2), a(0)); - 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.

• As shown in the example, the function is called by a sequential statement


that should appear inside the process. When the statement, m(0) <= simple
(a(0), a(l), a(2)); is called, the w takes the value of a(0). x takes the value of a(l),
and y takes the value of a(2). The function returns the value of sequential
statement in the function body using predefined word return and it is assigned
to m(0). Similarly, other two statements are executed, and m(l) and m(2) are
assigned with corresponding values.

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,

procedure procedure-name (parameter list)

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 :

procedure simple ( signal x : in bit;

signal z : out bit) is


The body of the procedure contains behavioural statements which mainly
describes the relationship between the input(s) and the output(s). It is
important to note that the body of the procedure cannot include the
behavioural statement process.

entity proc is

port ( a : in bitvector ( 0 to 2 );

m : out bit_vector (0 to 2 ));

end proc ;

architecture example of subprograms is

procedure simple (w, x, y : in bit; z : out bit) is

- - declaration

begin

z < = (w and x) or y ; - - body of procedure

end;

begin

process (a)

begin

simple (a(0), a(l), a(2), m(0));

simple (a(2), a(0), a(l), m(l));

simple (a(l), a(2), a(0), m(2));

end process;

end example;

As shown in the example, the procedure is called by a sequential statement


that should appear inside the process. When the statement simple (a(0), a(l),
a(2), m(0)); is called, the w takes the value of a(0), x takes the value of a(l), y
takes the value of a(2). The procedure determines the value of z by executing
the sequential statement and this value is passed to m(0) after execution of
the statement.

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

It is important to note that, passing vectors to procedures, the length of


vectors is not specified.

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

• Subprograms may be declared / defined in any declarative part of a VHDL


object. The actual definition of the behaviour may also be separated from the
declaration, which is often the case when packages are split into package and
package body. In such cases, the subprogram body may be described possibly in
a package body and then, in the package declaration, the corresponding
subprogram declaration is specified. The subprogram which is declared in a
package may be used in all unit that reference this package. The syntax for
subprogram declaration is :

subprogram-specification;

Examples of subprogram declaration are :

procedure calculate (A, B, C : in INTEGER;

OP : in OP_CODE;

Z : out INTEGER;

function add (a, b : in INTEGER) return INTEGER;


Subprogram Overloading
Subprogram Overloading
• It is possible to define two or more different subprograms having the same
name but differing in number or type of parameters. The function is said to be
overloaded in this case. The simulator or synthesizer automatically selects the
correct subprogram by looking at the parameters in the call statement.
Overloading is a very convenient mechanism for defining a set of functions that
perform the same operation on different data types.

• Let us consider following two declarations :

function add (a, b : INTEGER) return INTEGER;

function add (x, y : BIT) return BIT;

• The above two function are overloaded since they have the same name but
different type of parameters

function largest (Nl, N2, N3 : INTEGER) return INTEGER;

function largest (Nl, N2, N3, N4 : INTEGER) return INTEGER;

• The above two functions are overloaded since they have the same name but
different number of parameters.

Examples of Procedure and Functions


Examples of Procedure and Functions
Ex. 10.13.1 : Behavioural description of a full adder using procedure and
task.

We have seen the structural description of full-adder using two half-adders.


Here, we see the behavioral description of half-adder using the procedure in
VHDL. The Fig. 3.11.9 shows the block diagram of a full-adder using two half-
adders and the OR-gate and the listing 10.13.1 shows the HDL description for
the full adder.

Listing 10.13.1 : VHDL description of a full adder using procedure.

library ieee;

use ieee.std_logic_1164.all;
entity full_adder is

port ( A, B. Cin : in std_logic;

Sum, Cout: out std_logic);

end full_adder;

architecture two_h_adders of full_adder is

procedure H_Addr ( S, C : out std_logic;

a, b : in std_logic) is - procedure half adder

begin

S : = a xor b;

C := a and b;

end H_Addr;

begin

addfull: process (A, B, Cin)

variable Suml, Sum2, Cl, C2, temp: std_logic;

begin

H_Addr (Suml, Cl, A, B); - First call to procedure Half Adder

H_Addr (Sum2, C2, Suml, Cin); - Second call to procedure Half Adder

temp := Cl or C2;

Sum <= Sum2;

Cout <= temp;

end process;

end two_h_adders;

Ex. 10.13.2 : Behavioural description of an N-bit ripple carry adder using


procedure and task.
Here, we see the VHDL behavioural description of N-bit full adder using
procedure.

Listing 10.13.2 : VHDL description of an N-bit ripple carry adder using


procedure,

library ieee;

use ieee.std_logic_1164.all;

entity adder is

generic (N : integer := 4);

port ( A, B : in std_logic_vector (N downto 0);

Cin : in std_logic;

Sum : out std_logic_vector (N downto 0);

Cout : out std_logic);

end adder;

architecture adder_ripple of adder is

procedure full_addr ( S, C : out std_logic;

a, b, cin : in std_logic) is -procedure full adder

begin

S := a xor b xor cin;

C : = (a and b) or (a and cin) or (b and cin);

end full_addr;

begin

ri_addr: process (A, B, Cin)

variable cl, c2, teml, tem2 : std_logic;

variable carry : std_logic_vector (N+l downto 0);

variable suml : std_logic_vector (N downto 0);

begin
carry(O) := Cin;

for i in 0 to N loop

full_adder (suml(i), carry(i+l), A(i), B(i), carry(i));

- calls procedure full_addr

end loop;

Sum <= suml;

Cout <= carry(N-l-l);

end process;

end adder_ripple;

Ex. 10.13.3 : Function to calculate a XOR b.

Listing 10.13.3 shows the use of function to calculate a XOR b.

Listing 10.13.3

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity Func_XOR is

port ( al, bl : in std_logic;

yl : out std_logic);

end Func_XOR;

architecture Behavioral of Func_XOR is

function exor (a, b : in std_logic) return std_logic is

variable y : stdlogic;

begin

y : = a xor b;

return y;
end function exor;

begin

process (al, bl)

begin

yl <= exor (al, bl); - function call

end process;

end Behavioral;

VHDL Description of Flip-Flops


VHDL Description of Flip-Flops
AU : Dec.-11, 15, 17, May-15

1. Behavioral Description of D Flip-Flop using IF-THEN


Statements
• Consider a positive edge-triggered D flip-flop. We know that the D flip-flop is
similar to D-latch except 'clock pulse' is used instead of enable input. So VHDL
code for D flip-flop is same as that of D-latch with two exceptions.

• 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.

• ii) Positive edge triggering is required at the Clk input.

• In VHDL, 'attribute' refers to a property of an object, such as a signal. For D


flip-flop, two conditions are required at the Clk input. First is, change in the Clk
signal and second is, Clk should be equal to one. We are using 'EVENT attribute
to indicate any change in the Clk signal and Clock = 1 condition. Thus, positive
edge triggering condition can be obtained by logically ANDing Clock'EVENT
condition with the condition, Clock = 1.

• The VHDL code for a positive-edge-triggered D flip-flop is given below.

LIBRARY IEEE;
USE IEEE. std_logic_1164.all;

ENTITY DFF IS

PORT (D, Clock : IN STD_LOGIC;

Q : OUT STD_LOGIC);

END DFF;

ARCHITECTURE Behavior OF DFF IS

BEGIN

PROCESS (Clock)

BEGIN

IF ClockEVENT AND Clock = ‘1’

Q < = D;

END IF;

END PROCESS;

END Behavior;

2. Behavioral Description of D Flip-Flop using WAIT-UNTIL


Statement
• In the previous code, we have used IF-THEN statement. The similar code can
be written using WAIT-UNTIL statement. This statement has the same effect as
IF-THEN statement. In this case, the sensitivity list is omitted. The VHDL code
for a positive-edge triggered D flip-flop using a WAIT-UNTIL statement is given
below. The WAIT-UNTIL construct implies that the sensitivity list includes only
the clock signal.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY DFF IS
PORT(D, Clock : IN STD_LOGIC;

Q : OUT STD_LOGIC);

END DFF;

ARCHITECTURE Behavior OF DFF IS

BEGIN

PROCESS

BEGIN

WAIT UNTIL Clock'EVENT AND Clock = 1';

Q < = D;

END PROCESS;

END Behavior;

3. Behavioral Description of D Flip-Flop with Asynchronous


Reset/Clear
• In this section we are describing a D flip-flop with an asynchronous active-low
Reset (Clear) input. When Reset input is equal to 0, the flip-flop's Q output is
set to 0. The VHDL code for a D flip-flop with asynchronous Reset/Clear input is
given below.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY DFF IS

PORT(D, Resetn, Clock : IN STD_LOGIC

Q : OUT STD_ LOGIC)

END DFF;

ARCHITECTURE Behavior OF DFF IS


BEGIN

IF Resetn = ‘0’ THEN

Q < = ‘0’

ELSIF Clock EVENT AND Clock = ‘1’ THEN

Q<=D;

END IF;

END PROCESS;

END Behavior;

4. Behavioral Description of D Flip-Flop with


Synchronous Reset/CIear
• Consider a positive edge triggered D flip-flop. The reset signal of the flip-flop
is acted upon only when a positive clock edge arrives. The VHDL code for a D
flip-flop with synchronous Reset/Clear input is given here.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY DFF IS

PORT(D, Resetn, Clock : IN STDLOGIC;

Q : OUT STD_LOGIC);

END DFF;

ARCHITECTURE Behavior OF DFF IS

BEGIN

PROCESS

BEGIN

WATT UNTIL Clock'EVENT AND Clock = '1';


IF Resetn='O' THEN

Q< = 0';

ELSE

Q<=D;

END IF;

END PROCESS;

END Behavior;

• This code generates the circuit shown in Fig. 10.14.1.

5. Behavioral Description of DFF with a Negative-Edge Clock and


Asynchronous Clear
• The input/output pin description of the D flip-flop is as shown in Table
10.14.1.

• 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;

ENTITY flop IS ""

PORT(C, D, CLR : IN stdjogic;

Q : OUT stdjogic);

END flop;

ARCHITECTURE archi OF flop IS

BEGIN

PROCESS (C, CLR)

BEGIN

IF (CLR = ‘l')THEN

Q <= ‘O';

ELSIF (C'event and C=’0’)THEN

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;

ARCHITECTURE archi OF flop IS

BEGIN

PROCESS (C)

BEGIN

IF (C'event and C='l') THEN


IF (S='l’) THEN

Q < = ‘1’;

ELSE

Q <= D;

END IF;

END IF;

END PROCESS;

END archi;

7. Behavioral Description of DFF with Positive-Edge Clock and Clock


Enable
• The input/output pin description of the D flip-flop is as shown in Table
10.14.3.

• 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;

ARCHITECTURE archi OF flop IS

BEGIN

PROCESS (C)

BEGIN

IF (C’event and C=’T) THEN

IF (CE = ’T) THEN

Q <= D;

END IF;

END IF;

END PROCESS;

END archi;

8. Structural Description of Pulse Triggered SR Flip-Flop


• The Fig. 10.14.2 shows the pulse triggered SR flip-flop.
• The Fig. 10.14.3 shows the logic symbol and truth table of clocked SR flip-
flop.

Listing 10.14.1 : VHDL description of a SR-Flip-Flop.

library ieee;

use ieee.std_logic_1164.all;

entity SR_FF is

port ( S, R, CP : in std_logic;

Q. Qbar : buffer 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

- mapping. In this case, change all in and out to buffer,

component nand2

port ( I1, I2 : in std_logic;

O1 : out std_logic);

end component;

for all : nand2 use entity work.two_input (nand2_7);

signal S1, R1 : stdlogic;

begin

NA1 : nand2 port map (SI, Qbar, Q);

NA2 : nand2 port map (Q, Rl, Qbar);

NA3 : nand2 port map (S, CP, S1);

NA4 : nand2 port map (R, CP, R1);

end Latch;

9. Structural Description of Pulse Triggered D Flip-Flop


Like in D-latch, in D flip-flop the basic SR flip-flop is used with complemented
inputs. The D flip-flop is similar to D-latch except clock pulse is usedinstead of
enable input. Fig. 10.14.4 shows logic symbol and truth table for D flip-flop and
Fig. 10.14.5 shows the input and output waveforms.
Listing 10.14.2 : VHDL description of a D flip-flop,

library ieee;

use ieee.std_logic_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

port ( I1, I2 : in std_logic;

O1 : out std_logic);

end component;

for all: nand2 use entity work.two_input (nand2_7);

signal SI, R, Rl : std_logic;

begin

NA1 : nand2 port map (D, CP, SI);

NA2 : nand2 port map (R, CP, Rl);

NA3 : nand2 port map (D, D, R); — nand gate used as an inverter

NA4 : nand2 port map (SI, Qbar, Q);

NA5 : nand2 port map (Q, Rl, Qbar);

end FF;

10. Structural Description of JK Flip-Flop


• The Fig. 10.14.6 (a) shows the pulse triggered JK flip-flop, and Fig. 10.14.6 (b)
and (c) shows the logic symbol and truth table for JK flip-flop.
Listing 10.14.3 VHDL description of JK flip-flop.

library ieee;

use ieee.std_logic_1164.all;

entity JK_FF 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
mapping. In this case, change all in and out to buffer,

component nor2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component and3

port ( II, 12, 13 : in std_logic;

O1 : out std_logic);

end component;

for all : nor2 use entity work.two_input (nor2_7);

for all: and3 use entity work.three_input (and3_7);

signal R, S

begin

N1 : nor2 port map (S, Q, Qbar);

N2 : nor2 port map (R, Qbar, Q);

A1 : and3 port map (Q, K, CP, R);

A2 : and3 port map (Qbar, J, CP, S);

end FF;

11. Behavioral Description of JK Flip-Flop using Case Statement


Listing 10.14.4 : VHDL code for a positive edge-triggered JK flip-flop using the
case statement,

library ieee;

use ieee.std_logic_1164.all;
entity JKFF is

port(JK : in bit_vector (1 downto 0);

clk : in std_logic;

Q, Qbar : out bit);

end JK_FF;

architecture Flip_Flop of JK_FF is

begin

P1 : process (elk)

variable tempi, temp2 : bit;

begin

if rising_edge (elk) then

case JK is

when "01" => tempi := 'O';

when "10" => tempi := '1';

when "00" => tempi := tempi;

when "11" => tempi := not tempi;

end case;

Q < = temp1;

temp2 := not temp1;

Qbar < = temp2;

end if;

end process P1;

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.

Listing 10.14.5 : VHDL function to describe the edge trigger D flip-flop.

library ieee;

use ieee.std_logic_1164.all;

entity DFF is

port ( D, elk : in std_logic;

Q : out stdlogic);

end DFF

architecture Dflip_flop of DFF is

function rising_edge (signal s : std_logic) - function declaration

return boolean is - function declaration

begin

if (s'event) and (s = '1') and – s’event and s’last_value are signal attributes

(s'last_value = '0') then - s’event returns true if an event occurred during

return true; - current delta; otherwise it returns false

else – s’last value return the previous value of s

return false; - before the last event, Thus, rising edge is

end if; - detected if (s’event) and (s=’1’) and

end rising_edge; = (s’last_vale = ‘0’) results true.

begin
process( clk)

begin

if rising_edge(clk) then

Q < = D;

end if;

end process;

end Dflip_flop;

VHDL Description for Counters


VHDL Description for Counters

1. VHDL Code for a Four-bit Up Counter


• The VHDL code for a four-bit up-counter having Reset and Enable inputs is
given below. Since the counter is 4-bit, four flip-flops are used in a counter and
they are represented by the signal named 'Count'. Clock and Reset signals are
included in the sensitivity list. The process statement includes an asynchronous
reset of Count if Reset input (Resetn) is 0. At the end of the code, the Q
outputs are assigned the value of Count.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

USE IEEE.std_logic_unsigned.all;

ENTITY upctr IS

PORT( Clock,Resetn.EN : IN STDLOGIC;

Q : OUT STD_LOGIC_VECTOR (3 DOWNTO 0));

END upctr;

ARCHITECTURE Behavior OF upctr IS

SIGNAL Count: STD_LOGIC_VECTOR(3 DOWNTO 0);


BEGIN

PROCESS(Clock, Resetn)

BEGIN

IF Resetn = '0' THEN

Count < = "0000";

ELSIF(Clock'EVENT AND Clock = '1') THEN

IF EN = '1' THEN

Count< =Count+1;

ELSE

Count< =Count;

END IF;

END IF;

END PROCESS;

Q<= Count;

END Behavior;

2. VHDL Code for a 4-bit Up Counter using Integer


Signals
• This section gives the VHDL code for a four-bit up counter having parallel
load and reset inputs. In this code, we are declaring parallel data P and output
of the counter Q as an INTEGER type. Since the counter is four bit, the range of
P as well as Q is (24 = 16) 0 to 15. These signals represent four-bit quantities.
Output Q is defined in a buffer mode which represents outputs of the flip-
flops. The process statement specifies an asynchronous reset of Q if Resetn is
0. On positive clock edge, if 'Load' input is 1, then the flip-flops in the counter
are loaded in parallel from P inputs. If 'Load' input is 0, then the counter output
Q is incremented. The Q outputs have the buffer mode.

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;

ENTITY upctr IS

PORT(P : IN INTEGER RANGE 0 TO 15 ;

Clock, Resetn, : IN STD_LOGIC;

Q : BUFFER INTEGER RANGE 0 TO 15);

END upctr;

ARCHITECTURE Behavior OF upctr IS

BEGIN

PROCESS(Clock, Resetn)

BEGIN

IF Resetn = '0' THEN

Q <=0;

ELSIF(Clock'EVENT AND Clock = I1) THEN

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

GENERIC(MOD : INTEGER :=8;

PORT (Clock, Load, EN : IN STD_LOGIC;

Q : OUT INTEGER RANGE 0 TO MOD-1);

END downctr;

ARCHITECTURE Behavior OF downctr IS

SIGNAL Count : INTEGER RANGE 0 TO MOD-1;

BEGIN

PROCESS

BEGIN

WAIT UNTIL (Clock'EVENT AND Clock = 1);

IF EN = '1' THEN

IF LOAD = THEN

Count <= MOD-1;

ELSE

Count <= Count-1

END IF;
END IF;

END PROCESS;

Q<= Count;

END Behavior;

4. VHDL Code for a 3-bit Asynchronous Counter


• Let us see the VHDL code for 3-bit asynchronous counter with active high
Reset and Set inputs.

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY Counterl IS

PORT(

CLK : IN STD_LOGIC;

Resetp : IN STDLOGIC;

Setp : IN STD_LOGIC;

Q : INOUT STD_LOGIC_VECTOR (2 DOWNTO 0)

);

END Counterl;

ARCHITECTURE AsynchCntr OF Counterl IS

BEGIN

PROCESS(CLK, Resetp, Setp, Q)

BEGIN

IF Resetp='O' THEN

Q<="000";
ELSIF Setp='O' THEN

Q<="111";

ELSIF CLK ='0' AND CLK'event THEN

Q(0)< = NOT Q(0);

END IF;

IF Q(0)='0' AND Q(0)'EVENT THEN

Q(l)< = NOTQ(l);

END IF ;

IF Q(1)='O' AND Q(1)'EVENT THEN

Q(2)< = NOT Q(2);

END IF ;

END PROCESS;

END Asynch_Cntr;

5. VHDL Code for Asynchronous Counter with GLITCH


• Let us see the VHDL code for an asynchronous mod-6 Counter with GLITCH
and active low Reset and Set inputs.

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;

ARCHITECTURE Asynch_Glitch OF Counter2 IS

BEGIN

PROCESS(CLK, Resetn, Setn, Q)

VARIABLE Qtemp: STD_LOGIC_VECTOR (2 DOWNTO 0);

BEGIN

IF Resetn='0' THEN

Qtemp :="000";

ELSIF Setn='0' THEN

Qtemp :="111";

ELSIF CLK = '0' AND CLK'event THEN

Qtemp(0) := NOT Qtemp(0);

END IF;

IF Q(0)='0' AND Q(0)'EVENT THEN

Qtemp(l) := NOT Qtemp(l);

END IF;

IF Q(1)='O' AND Q(1)'EVENT THEN

Qtemp(2) := NOT Qtemp(2);

END IF;

Q < = Qtemp;

IF Qtemp > "101" THEN

Qtemp := "000";
Q < = "000" AFTER 2ns;

END IF;

END PROCESS;

END Asynch_GIitch;

6. VHDL Code for Synchronous Mod-6 Counter


• Let us see the VHDL code for synchronous mod-6 Counter with active low
Reset and Set inputs.

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE ,STD_LOGIC_unsigned.ALL;

ENTITY Counter3 IS

PORT(

CLK : IN STDLOGIC;

Resetn : IN STD_LOGIC;

Setn : IN STD_LOGIC;

Q : INOUT STD_LOGIC_VECTOR (2 DOWNTO 0)

);

END Counter3;

ARCHITECTURE Synch_Cntr OF Counter3 IS

BEGIN

PROCESS(CLK, Resetn, Setn)

VARIABLE Qtemp: STD_LOGIC_VECTOR (2 DOWNTO 0);

BEGIN
IF Resetn='0' THEN

Qtemp := "000";

ELSIF Setn='0' THEN

Qtemp := "111";

ELSIF CLK ='l' AND CLK'event THEN

IF Qtemp < 5 THEN

Qtemp := Qtemp + 1;

ELSE

Qtemp := "000";

END IF;

END IF;

Q < = Qtemp;

END PROCESS;

END Synch_Cntr;

7. 4-bit Unsigned Up Counter with Asynchronous Load


from Primary Input
• The pin description of 4-bit unsigned up counter is as shown in the Table
10.15.1.
• The VHDL code for a 4-bit unsigned up counter with asynchronous load from
primary input is as follows.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

USE IEEE.std_logic_unsigned.all;

ENTITY counter IS

PORT(C, ALOAD : IN std_logic;

D : IN std_logic_vector(3 downto 0);

Q : OUT std_logic_vector(3 downto 0));

END counter;

ARCHITECTURE archi OF counter IS

signal tmp: std_logic_vector(3 downto 0);

BEGIN

PROCESS (C, ALOAD, D)

BEGIN

IF (ALOAD = 'T) THEN

tmp <= D;
ELSIF (C'event and C=’T) THEN

tmp <= tmp + 1;

END IF;

END PROCESS;

Q < = tmp;

END archi;

8. 4-bit Unsigned Up Counter with Synchronous Load with a


Constant
• The pin description of 4-bit unsigned up counter is as shown in the Table
10.15.2.

• 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

PORT(C, SLOAD: IN std_logic;

Q : OUT std_logic_vector(3 downto 0));


END counter;

ARCHITECTURE archi OF counter IS

signal tmp: std_logic_vector(3 downto 0);

BEGIN

PROCESS (C)

BEGIN

IF (C'event and C=’T) THEN

IF (SLOAD=’l') THEN

tmp < = "1010";

ELSE

tmp <= tmp + 1;

END IF;

END IF;

END PROCESS;

Q < = tmp;

END archi;

9. Structural Description of 3-bit Synchronous Binary


Counter
• The Fig. 10.15.1 shows the logic diagram of 3-bit synchronous binary counter.
The Listing 10.15.1 gives the structural description of 3-bit synchronous binary
counter.
Listing 10.15.1 : VHDL description for 3-bit synchronous binary counter,

library ieee;

use ieee.std_logic_1164.all;

entity counter is

port ( CP : in std_logic;

Q, Qbar: buffer std_logic_vector(2 downto 0));

end counter;

architecture cnt_3Bit of counter is

component and2

port ( II, 12 : in std_logic;

O1 : out std_logic);

end component;

component JK_FF

port ( II, 12, 13 : in std_logic;

Ol, 02 : buffer std_logic);

end component;

for all : and2 use entity work.two_input (and2_4);


for all : JKFF use entity work.JKFF (FF);

signal J2 std_logic;

begin

A1 : and2 port map (Q(0), Q(l), J2);

JK1 : JK_FF port map ('1', '1', CP, Q(0), Qbar(0));

JK2 : JK FF port map (Q(0), Q(0), CP, Q(l), Qbar(l));

JK3 : JK_FF port map (J2, J2, CP, Q(2), Qbar(2));

end cnt_3Bit;

VHDL Code for Registers


VHDL Code for Registers
• In the section 10.14, we have seen the VHDL code for a D flip-flop. The n-bit
register can be described in VHDL by writing a hierarchical code that includes
n-instances of the D flip-flop subcircuit.

1. VHDL Code for a Four-bit Register


• Let us discuss a VHDL code for a four-bit register with asynchronous
reset/clear. This code is same as the code for D flip-flop with asynchronous
reset except that the input D and output Q are declared as multibit signals.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY reg4 IS

PORT(D : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

Resetn,Clock : IN STD_LOGIC;

Q : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END reg4;
ARCHITECTURE Behavior OF reg4 IS

BEGIN

PROCESS(Resetn,Clock)

BEGIN

IF Resetn='0' THEN

Q<="0000";

ELSIF Clock'EVENT AND Clock = '1' THEN

Q<=D;

END IF;

END PROCESS;

END Behavior;

2. 4-bit Register with Positive-Edge Clock, Asynchronous Set and


Clock Enable
• The pin description of 4-bit register is as shown in the Table 10.16.1

• 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

PORT( C, CE, PRE : IN std_logic;

D : IN std_logic_vector (3 downto 0);

Q : OUT std_logic_vector (3 downto 0));

END flop;

ARCHITECTURE archi OF flop IS

BEGIN

PROCESS (C, PRE)

BEGIN

IF (PRE = 'l') THEN

Q < = “1111'';

ELSIF (C'event and C=’1’)THEN

IF (CE = ’T) THEN

Q < = D;

END IF;

END IF;

END PROCESS;

END archi;

3. VHDL Code for an N-bit Register


• Oftenly the registers of different sizes are required in logic circuits. So it is
advisable to write a VHDL code for a register in which number of bits of a
register can be changed easily. The number of bits in a register are decided by
number of flip-flops used to build a register. The code discussed in the
previous section, i.e. code for a 4-bit register is modified by a parameter that
sets the number of flip-flops. This code is given below.

• Here, we are using N as a parameter which is an integer called in VHDL as


GENERIC.

• 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;

ENTITY regN IS GENERIC(N:INTEGER : = 16);

PORT(D : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);

Resetn,Clock : IN STD_LOGIC;

Q : OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0));

END regN;

ARCHITECTURE Behavior OF regN IS

BEGIN

PROCESS(Resetn, Clock)

BEGIN

IF Resetn='0'THEN

Q<=(OTHERS=> '0');

ELSIF Clock'EVENT AND Clock = T THEN

Q<=D;

END IF;

END PROCESS;

END Behavior;
4. VHDL Code for a Shift Register
a. Using Sequential Statements

• Fig. 10.16.1 shows a 4-bit shift right register.

• 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;

Q : BUFFER STD_LOGIC_VECTOR (3 DOWNTO 0));

END shiftreg;

ARCHITECTURE Behavior OF shiftreg IS

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).

b. Hierarchical Code for a 4-bit Shift Register

• 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

Q : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

END shiftreg;

ARCHITECTURE Structure OF shiftreg IS

COMPONENT DFF

PORT(D,Clock : IN STDLOGIC;

Q : OUT STD_LOGIC);

END COMPONENT;

BEGIN

Stage3 : DFF PORT MAP (I, Clock, Q(3));

Stage2 : DFF PORT MAP (Q(3), Clock, Q(2));

Stage1 : DFF PORT MAP (Q(2), Clock, Q(l));

Stage0 : DFF PORT MAP (Q(l), Clock, Q(0));

END Structure;

c. VHDL Code for an n-bit Left-to-Right Shift Register

• 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);

PORT ( P : IN STD_LOGIC_VECTOR(n-l DOWNTO 0);

Clock : IN STD_LOGIC ;

Load,I : IN STD_LOGIC;

Q : BUFFER STD_LOGIC_VECTOR (n-1 DOWNTO 0));

END sftregn;

ARCHITECTURE Behavior OF sftregn IS

BEGIN

PROCESS

BEGIN

WAIT UNTIL Clock'EVENT AND Clock = 1'; IF Load = '1' THEN

Q<=P;

ELSE

Genbits:FOR i IN 0 TO n-2 LOOP

Q(i) <= Q(i+1);

END LOOP;

Q(n-l)<=I;

END IF;

END PROCESS;

END Behavior;

d. VHDL Code for a Left-to-Right Shift Register with an Enable Input

• 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;

-left-to-right shift register with parallel load and enable

ENTITY sftregne IS

GENERIC(n:INTEGER: = 16);

PORT(P : IN STD_LOGIC_VECTOR(n-l DOWNTO 0);

Load, EN, I : IN STDLOGIC ;

Clock : IN STD_LOGIC ;

Q : BUFFER STD_LOGIC_VECTOR (n-1 DOWNTO 0));

END sftregne;

ARCHITECTURE Behavior OF sftregne IS BEGIN

PROCESS

BEGIN

WAIT UNTIL Clock'EVENT AND Clock = 1';

IF EN = '1' THEN

IF Load = 'I' THEN

Q < = P;

ELSE

Genbits:FOR i IN 0 TO n-2 LOOP

Q(i)<= Q(i+1);

END LOOP;

Q(n-l)<=I;
END IF;

END IF;

END PROCESS;

END Behavior;

5. VHDL Code for a 4-bit Parallel Access Shift Register


a. Using Sequential Statements

• A 4-bit parallel access shift register is shown in Fig. 10.16.2.

• The VHDL code for this shift register is given below.

• 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;

USE IEEE. std_logic_1164.all;

ENTITY sftreg4 IS

PORT ( P : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

Clock : IN STD_LOGIC;

Load,I : IN STDLOGIC;

Q : BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));

END sftreg4;

ARCHITECTURE Behavior OF sftreg4 IS

BEGIN

PROCESS

BEGIN

WAIT UNTIL Clock'EVENT AND Clock = 1';

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;

b. Hierarchical Code for a 4-bit Parallel Access Shift Register

• In a hierarchical code, we are taking D flip-flop with 2-to-l multiplexer as a


subcircuit. So four instantiations of such subdrcuits are needed. We are calling
this subcircuit as MUXDFF as shown in Fig. 10.16.3. The VHDL code for this
subcircuit is given here. There are two data inputs, DQ and Dp They are
selected using Sel input. The process statement specifies that on positive clock
edge, if sel is 0, then Q is assigned the value of DQ; otherwise Q is assigned the
value of DI.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY MUXDFF IS

PORT (DO, DI, Sel, Clock : IN STD LOGIC;

Q : OUT STD_LOGIC);

END MUXDFF;

ARCHITECTURE Behavior OF MUXDFF IS

BEGIN

PROCESS

BEGIN

WAIT UNTIL Clock'EVENT AND Clock = 1';

IF Sel = O' THEN

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

PORT (P : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

Load,I,Clock : IN STDLOGIC;

Q : BUFFER STD_LOGIC_VECTOR (3 DOWNTO 0));

END sftreg4;

ARCHITECTURE Structure OF sftreg4 IS

COMPONENT MUXDFF

PORT (DO, DI, Sel, Clock : IN STD_LOGIC;

Q : OUT STD_LOGIC);

END COMPONENT;

BEGIN

Stage3 : MUXDFF PORT MAP (I, P(3), Sel, Clock, Q(3));

Stage2 : MUXDFF PORT MAP (Q(3), P(2), Sel, Clock, Q(2));

Stagel : MUXDFF PORT MAP (Q(2), P(l), Sel, Clock, Q(l));

StageO : MUXDFF PORT MAP (Q(l), P(0), Sel, Clock, Q(0));

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

PORT(C, SI, ALOAD : IN stdjogic;

D : IN std_logic_vector(7 downto 0);

SO : OUT stdjogic);

END shift;

ARCHITECTURE archi OF shift IS

signal tmp: std_logic_vector(7 downto 0);

BEGIN

PROCESS (C, ALOAD, D)

BEGIN

IF (ALOAD='l’) THEN

tmp <= D;

ELSIF (C'event and C=T) THEN

tmp < = tmp(6 downto 0) & SI;

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

PORT( C, SI, SLOAD : IN stdjogic;

D : IN std_logic_vector(7 downto 0);

SO : OUT stdjogic);

END shift;

ARCHITECTURE archi OF shift IS

signal tmp: std_logic_vector(7 downto 0);

BEGIN

PROCESS (C)

BEGIN
IF (C'event and C=’l') THEN

IF (SLOAD=’l’) THEN

tmp <= D;

ELSE

tmp < = tmp(6 downto 0) & SI;

END IF;

END IF;

END PROCESS;

SO <= tmp(7);

END archi;

8. 8-bit Shift-Left/Shift-Right Register with Positive-Edge Clock,


Serial IN, and Parallel OUT
• The pin description of 8-bit shift-left/shift-right register is as shown in the
Table 10.16.4.

• The VHDL code for an 8-bit shift-left/shift-right register with a positive-edge


clock, serial in, and serial out is as follows.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;
ENTITY shift IS

PORT(C, SI. left_right : IN std_logic;

PO : OUT std_logic_vector(7 downto 0));

END shift;

ARCHITECTURE archi OF shift IS

signal tmp: std_logic_vector(7 downto 0);

BEGIN

PROCESS (C)

BEGIN

IF (C’event and C=’l’) THEN

IF (left_right='O') THEN

tmp < = tmp(6 downto 0) & SI;

ELSE

tmp < = SI & tmp(7 downto 1);

END IF;

END IF;

END PROCESS;

PO <= tmp;

END archi;

9. VHDL Code for Universal Shift Register


• Let us consider a universal shift register with four control modes as shown in
Fig. 10.16.4 Table 10.16.5 shows action to be performed by universal shift
register in different modes.
VHDL CODE

library IEEE;

Use IEEE.std_logic_1164.all; entity usr is

generic (n : NATURAL : = 8);

port (a : in std_logic_vector (n-1) downto 0);

Left_in, Right_in : in stdlogic ;

s : in std_logic_vector (1 downto 0);

Clk, reset : in std_logic;


q = out std_logic_vector (n-1 downto 0));

end entity usr;

architecture rtl of usr is

begin

P0 : process (Clk, reset) is

variable reg : std_logic_vector (n-1 downto 0);

begin

if (reset = '0') then

reg : = (others => '0');

elsif risingedge (Clk) then

case s is

when "11" => reg : = a;

when "10" = > reg : = reg (n-2 downto 0) and left_in ;

when "01" => reg : Right_in & reg (n-1) downto 1);

when others = > null;

end case;

end if;

q < = reg;

end process P0 ;

end architecture rtl ;

VHDL Description for Finite State


Machines (FSM)
VHDL Description for Finite State Machines (FSM)
• A VHDL description of a state machine can be written using communicating
concurrent processes for the following components.

1. Combinational Component

• This component can be implemented within one process. Being a


combinational, this process is sensitive to events on the input signals and
changes in the state. So whenever there is a change in any of the input signals
or the state variables, this process is executed and computes new values for
the output signals and the new state variables.

2. Sequential Component

• This component can be implemented within a second process. Being a


sequential, this process is sensitive to the positive/negative edge of the clock
signal. When this process is executed, the state variables are updated. These
state variables are applied as inputs to the combinational component. Because
of the change in the input signal, the combinational component computes the
new value as the next state.

• 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.

• Consider the state diagram shown in Fig. 10.17.1.

• From the 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.

• The PROCESS statement describes the machine as a sequential circuit.

• The VHDL description of this state machine is given below.

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;

ARCHITECTURE Behavior OF State_machine IS

TYPE state_type IS (state0, state1);

SIGNAL state, next_state : state_type: =state0;

BEGIN

comb_process : PROCESS (State, X) IS

BEGIN

CASE State IS - depending upon the current state

WHEN StateO => - set output signals and next state

IF X = '0' THEN
next_State <= State 1;

Y <= '1';

ELSE next_State < = StateO;

Y<='0';

END IF;

WHEN statel = >

IF x='l' THEN

next_state<= state 0;

Y <='l';

ELSE next_state <= state 1;

Y<='0';

END IF;

END CASE;

END PROCESS conib_process;

clk_process : PROCESS IS

BEGIN

WAIT UNTIL(rising_edge(clk)); - wait until the rising edge

IF Reset = '1' THEN — check for Reset and initialize state

STATE <=state_type'left;

ELSE State < =next_State;

END IF;

END PROCESS clk_process;

END ARCHITECTURE Behavior;


• We know that state machines are classified as Mealy and Moore. The VHDL
descriptions for both the types of machines are explained in the further
sections.

1. VHDL Code for Mealy-Type State Machines


• Consider Mealy-type State Machine having state diagram as shown below.

• 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.

• The PROCESS statement describes the machine as a sequential circuit. The


signals used by the process are Clock, Resetn, X and Z. Only the Z signal is
modified by the process. The Clock and Resetn are the only signals used by the
process to change Z. So only they are included in the sensitivity list. It is to be
noted that Z is not included in the sensitivity list because any change in X
cannot affect Z until a change occurs in the clock signal.

• A separate CASE statement is used to define output Y. This CASE statement


describes the logic needed for output Y. It states that when the state machine
is in state A, Y takes the value of X but when it is in state B, Y should be 0. It is
to be noted that the value of Y is not specified inside the CASE statement
which defines the state transitions. The reason is that, in Mealy-type state
machine; the value of output must depend on state of the machine and on the
input signal. Here the CASE statement for the state transitions is nested inside
the IF-THEN statement which waits for a positive edge clock to occur. So, by
placing the code for output Y inside this CASE statement the output Y could
change only as a result of a positive edge clock. This does not fulfil the
requirements of Mealy-type state machine.

• VHDL code for the Mealy-type state machine.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

ENTITY Mealy IS

PORT (Clock, Resetn, X : IN STD_LOGIC;

Y : OUT STDLOGIC);

END Mealy;

ARCHITECTURE Behavior OF Mealy IS

TYPE State_type IS (A,B);

SIGNAL Z : State_type;

BEGIN

PROCESS (Resetn, Clock)

BEGIN

IF Resetn = '0' THEN

Z <=A;

ELSIF(Clock'EVENT AND Clock = '1') THEN

CASE Z IS

WHEN A =>

IF X='O' THEN Z <=B;

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;

a. VHDL Code for a Serial Adder

• 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

GENERIC(length : INTEGER :=8);

PORT (Clock : IN STD_LOGIC;

Reset : IN STDLOGIC;

A. B : IN STD_LOGIC_VECTOR(length - 1 DOWNTO 0);

S : BUFFER STD_LOGIC_VECTOR (length - 1 DOWNTO 0));

END Serial;

ARCHITECTURE Behavior OF Serial IS

COMPONENT sftregne

GENERIC(N : INTEGER := 4);

PORT(R : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);

LOAD EN,I : IN STD_LOGIC;


Clock : IN STD_LOGIC;

Q : BUFFER STD_LOGIC_VECTOR(N-1 DOWNTO 0));

END COMPONENT;

SIGNAL X, Y, Null_in : STD_LOGIC_VECTOR (length-1 DOWNTO 0);

SIGNAL ADD_S, Low,High, Run : STD_LOGIC;

SIGNAL Count : INTEGER RANGE 0 TO length;

TYPE State_type IS : (a,b)

SIGNAL Z : State_type;

BEGIN

Low < ='0"; High <=1';

ShiftA : sftregne GENERIC MAP (n = > length)

PORT MAP(A, Reset, High, Low, Clock, X);

ShiftB : sftregne GENERIC MAP (n = > length)

PORT MAP(B, Reset, High, Low, Clock, Y);

AdderFSM : PROCESS (Reset, Clock)

BEGIN

IF Reset = T' THEN

Z < = a;

ELSIF Clock'EVENT AND Clock = T' THEN

CASE Y IS

WHEN a=>

IF X(0) = T' AND Y(0) = T' THEN Z<=b;

ELSE Z<=a;

END IF;
WHENb=>

IF X(0)='0' AND Y(0)='0' THEN Z<=a;

ELSE Z = b;

END IF;

END CASE;

END IF;

END PROCESS AdderFSM;

WITH Z SELECT

ADD_S <= X(0) XOR Y(0) WHEN a

NOT (X(0) XOR Y(0)) WHEN b;

Null_in <= (OTHERS => '0');

Shifts : sftregne GENERIC MAP (n = > length)

PORT MAP (Null_in, Reset, EN, ADD S, Clock, S);

Stop : PROCESS

BEGIN

WAIT UNTIL (Clock'EVENT AND Clock = 1);

IF Reset = '1' THEN

Count <= length;

ELSIF Run = 1' THEN

Count <= Count-1;

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.

• When the machine is in states B, C, D, its behavior can be described in the


same manner.
• The VHDL description of this state machine is given here.

• The PROCESS statement describes the machine as a sequential circuit. The


signals used by the process are Clock, Resetn, X and Z. Only the Z signal is
modified by the process. Out of all these signals, only Clock and Resetn signals
are given in the sensitivity list because these are only the signals used by the
process to change Z. It is to be noted that X is not included in the sensitivity list
because any change in X cannot affect Z without a change in the clock signal.

• 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

PORT(Clock, Resetn, X : IN STD_LOGIC;

Y : OUT STD_LOGIC);

END Moore;

ARCHITECTURE Behavior OF Moore IS

TYPE state_type IS (A,B,C,D);

SIGNAL Z : Statetype;

BEGIN

PROCESS (Resetn, Clock)

BEGIN

IF Resetn = '0' THEN Z=A;

ELSE IF(Clock'EVENT AND Clock = '1') THEN

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;

Y<='1'WHEN Z=B ELSE 'O';

END Behavior

Memory Description in VHDL


Memory Description in VHDL
• Memory is nothing but the array of registers. Each register in the array is
identified by its unique address. The number of bits in each register decides the
word length. Thus, in VHDL we can model memory using two dimensional
array which implements an array of registers.

Read and Write Memory Operation

• 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 control inputs : Enable and Read Write.

• 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 :

Read Operation : Dataout ← Memory [A]

Enable = 1 and ReadWrite = 1

Write operation : Memory [A] ← Dataln;

Enable = 1 and ReadWrite = 0

• 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

constant N : integer := 1023; - N + 1 is the number of elements in the array,

constant L : integer := 7; - M + 1 is the number of bits of each element of


the array,

subtype Ele_width is std_logic_vector (M downto 0);

type Ele is array (N downto 0) of Ele_width;

end array_2D;

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.array_2D.all;

entity meml024x8 is

generic ( N : integer := 1023;

L : integer : = 7); - N + 1 is the number of words in the memory

- M + 1 is the number of bits of each word.

Port ( Memory : inout Ele;

Enable : in std_logic;

Address : in unsigned (9 downto 0); — To address 1024 words 10_bit address


bus

Dataln : in std_logic_vector (7 downto 0);

ReadWrite : in std_logic;

DataOut: out std_logic_vector (7 downto 0));

end meml024x8;

architecture SRAM of meml024x8 is

begin

rd_wr : process (Enable, Address, Dataln, ReadWrite)


variable A : integer range 0 to 1023;

begin

if (Enable = '0') then

A := To_Integer (Address); — To_Integer is a built-in function

if (ReadWrite = '0') then

Memory (A) < = Dataln;

else

DataOut <= Memory (A);

end if;

else

DataOut < = "ZZZZZZZZ"; - Make D_out high impedance.

end if;

end process rd_wr;

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,

2. Determine the logic and arithmetic operations that need to be performed on


these register contents and

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).

• As a simple example, consider a device that needs to add four numbers. In


VHDL, given signals of the correct type, we can simply write :

s<=((a + b) + c) + d;

• This particular description is simple enough that it can be synthesized.


However, the resulting circuit will be a fairly large combinational circuit
comprising three adder circuits as shown in Fig. 10.19.1.

• A behavioral description, not being concerned with implementation details,


would be complete at this point. However, if we were concerned about the cost
of the implementation we might decide to break down the computation into a
sequence of steps, each one involving only a single addition :

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.

• An RTL design is composed of :

1. Registers and combinational function blocks (e.g. adders and multiplexers)


called the datapath and

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.

RTL Design using VHDL with example


RTL Design Example
AU : May-12, Dec.-15
• To show how an RTL design is described in VHDL and to clarify the concepts
involved, we will design a four-input adder. This design will also demonstrate
how to create packages of components that can be re-used.

• 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.

— RTL design of 4-input summer

— subtype used in design

library ieee ;
use ieee.std_logic_1164.

use ieee.std_logic_arith.all;

package summer is

subtype num is unsigned (7 downto 0) ;

type states is ( clr, add_a, add_b, add_c,

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 ;

sum : out num ;

sel: in std_logic_vector (1 downto 0) ;

load, clear, elk : in std_logic

);

end datapath ;

architecture rtl of datapath is

signal mux_out, sum_reg, next_sum_reg : num ;

constant sum_zero : num :=

conv_unsigned(0,next_sum_reg’length) ; begin

— mux to select input to add

with sel select mux_out < =

a when “00",

b when “01",

c when “10",

d when others ;

— mux to select register input

next sum reg < =

sum_reg + muxout when load = T’ else

sum_zero when clear = 1' else

sum_reg ;

— register sum

process(clk)
begin

if elk'event and elk = 1' then

sum_reg < = next_sum_reg ;

end if;

end process ;

— entity output is register output

sum <= sum_reg ;

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.

— controller library ieee ;

use ieee.std_logic_1164.all;

use work.summer.all;

entity controller is

port ( update : in std_logic ;

sel : out std_logic_vector (1 downto 0) ;

load, clear : out std_logic ;

clk : in std_logic

);

end controller ;

architecture rtl of controller is


signal s, holdns, ns : states ;

signal tmp : std_logic_vector (3 downto 0);

begin

— select next state

with s select ns < =

add_a when clr,

add_b when add_a,

add_c when add_b,

add_d when add_c,

hold when add_d,

holdns when others ; — hold

— next state if in hold state

holdns < =

clr when update = T’ else

hold ;

— state register

process(clk)

begin

if elk’event and elk = ’I’ then

s < = ns ;

end if;

end process ;

— controller outputs

with s select sel < =

“00" when add_a,


“01" when add_b,

“10" when add_c,

“11" when others ;

load < = ’0’ when s = clr or s = hold else 1’ ;

clear <= ’I’ when s = clr else ’0’ ;

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.

— package for datapath and controller

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 ;

sum : out num ;

sel: in std_logic_vector (1 downto 0) ;

load, clear, clk : in std_logic

);

end component ;

component controller

port ( update : in std_logic ;

sel: out std_logic_vector (1 downto 0) ;


load, clear: out std_logic ; clk : in std_logic

);

end component;

end summer_components ;

• The top-level summer entity instantiates the two components and


interconnects them.

— summer

library ieee ;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use work.summer.all;

use work.summer_components.all;

entity summer is port ( a, b, c, d : in num ;

sum : out num ; update, elk : in std_logic ) ;

end summer ;

architecture rtl of summer is

signal sel: std_logic_vector (1 downto 0) ;

signal load, clear : stdlogic ;

— other declarations (e.g. components) here

begin

dl: datapath port map ( a, b, c, d, sum, sel, load, clear, clk ) ;

cl: controller port map ( update, sel, load, clear, clk );

end rtl;

• The result of the synthesizing the datapath is :


• The register flip-flops are at the upper right, the adder is in the middle and the
input multiplexer is at the lower left. The result of the synthesizing the
controller is :
Testbenches
Testbenches
AU : Dec.-l0, May-16

• 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 use
of a VHDL module that is referred to as testbench. It verify the functionality of
the design at each step in the HDL synthesis - based methodology.

• 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.

• The objectives of the testbench can be summarized as :

• Instantiate the DUT/UUT,

• 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.

• Provide pass/fail indications


1. Types of Testbenches
The types of writing testbenches are :

• 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.

• Simulator specific : This testbench is written in a simulator-specific format.

• 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.

• The Table 10.21.1 shows the advantages and disadvantages of above


discussed test benches.
2. Writing a Testbench
• When writing a testbench, the DUT (Design Under Test) is included as a
component in the testbench model. Testbench is written as an entity just like
any other VHDL model with an architecture body which includes DUT as a
component.

Syntax of testbench

entity tb is

end tb;

architecture tb of tb is

component DUT port

( port_name: mode type)

end component;

Local signals;

begin

M1: DUT port map {association list);

process begin

signal assignments to create stimulus (generating test_vectors)

applying test vectors to DUT;

[verify or compare or store results;]

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.

• The executable part includes the statements to generate test_vectors (the


values applied as stimulus to inputs.)

• With VHDL, there are three ways to generate test vectors :

1. Generation by an algorithm : It includes,

a) simple assignments of signals,

b) continuous loops for periodic signals or

c) procedures for complex signal patterns (procedural stimuli)

2. Generation from constants stored in an array

3. Generation from constants stored in a separate file

• 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.

2. Testbench allows to simulate DUT under a variety of test conditions


including correct and faulty test inputs.

3. Testbench makes it easier to create a wide range of stimulus inputs,


particularly with respect to timing of input signals.

4. Its structure is well defined and flexible to accept changes if there are
changes in the circuit under test.

5. The output generated by testbench can be observed as waveforms or can be


stored as values for comparison against expected values or for later analysis or
to compare two simulations.

6. It gives an idea about the timing requirements of the DUT (Design under
test).

7. The testbench approach is useful for post-fit verification.

Q.1 What is HDL ?

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 ?

Ans. : The main components of a VHDL description are :

1. Package (optional)

2. Entity

3. Architecture

4. Configuration(optional)

3. What is entity?

Ans.: Entity gives the specification of input/output signals to external circuitry.


It 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.

Q.4 Give the syntax for VHDL entity declaration.

Ans. : The syntax of a VHDL entity declaration is as shown below :

entity entity_name is

port ( signal_names : mode signal_type;

signal_names : mode signal_type;

signal_names : mode signal_type);

end entity_name ;

Q.5 What is architecture ?

Ans. : 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.

Q.6 List the internal details of an entity specified by architecture body.

Ans. : An architecture body specifies the following internal details of an entity :

• As a set of concurrent assignment statements (to represent dataflow)

• As a set of interconnected components (to represent structure)

• As a set of sequential assignment statement (to represent behavior)

• As any combination of above three.

Q.7 Give the syntax for VHDL architecture declaration.

Ans. : The syntax for architecture is given below : architecture


architecture_name of entity_name is Declarations

begin

concurrent statements;

sequential statements;

end arclutecture_name;

Q.8 What is the use of configuration declaration ?

Ans. : 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.

Q.9 What is the need of package declaration ?

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.

Q.10 How is package represented ?

Ans. : A package is represented by : 1. Package declaration 2. Package body


(optional)

Q.11 What are the various modeling techniques in HDL ?

Ans. : There are three modelling techniques in HDL for describing a module :

1. Gate-level modeling/Structural modeling

2. Dataflow modeling

3. Behavioral modeling.

Q.12 What is 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.

Q.13 Write HDL behavioural model of D flip flop.

(Refer section 10.14.2)

Q.14 What is data flow modeling ?

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.

Q.16 List the data objects supported by VHDL.

Ans. : The data objects supported by VHDL are :

1. Signals 2.Variable 3. Constants 4. File

Q.17 Give the classication of data types supported by VHDL.

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)

Q.19 Give the comparison between concurrent and sequential statement.

(Refer section 10.8.4)


Q.20 State the use of generate statement in VHDL.

Ans. : A generate statement in VHDL is used to create repetitive structures for


repetitive subdrcuits. 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.

Q.21 What is subprogram ?

Ans. : 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.

Q.22 How procedure differs from function ?

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).

Q.23 What do you mean by subprogram overloading ?

Ans. : It is possible to define two or more different subprograms having the


same name but differing in number or type of parameters. The function is said
to be overloaded in this case. The simulator or synthesizer automatically selects
the correct subprogram by looking at the parameters in the call statement.
Overloading is a very convenient mechanism for defining a set of functions that
perform the same operation on different data types.

Q.24 Write HDL for half adder.

Ans. :

module half_adder (A, B, Sum, Cout);

input A;

input B;
output Sum;

output Cout;

reg Sum, Cout;

always @(A, B)

begin

#10 Sum = a ^ b ;

#10 Cout = a & b ;

end

endmodule

Q.25 When can RTL be used to represent digital systems ?

Ans. : When digital systems are composed of registers and combinational


function blocks, the RTL can be used to represent digital systems.

Q.26 What is testbench ?

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.

Q.27 List the different type of testbenches ?

Ans. : The different type of testbenches are :

1. Stimulus only

2. Full testbench

3. Simulator specific

4. Hybrid test-bench
5. Fast testbench

Q.28 What is the meaning of the following RTL statement ?

T1 : ACC ← ACC and MDR.

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.29 What are the advantages of hardware languages ?

(Refer section 10.1) AU : June-14

Q.30 Write VHDL code for half adder in data flow model.

AU : June-14

Ans. :

entity half-add is

port (A, B, : in bit;

sum, cout : out bit);

end half_add;

architecture adder of half_add is

begin

sum < = A XOR B ;

cout < = A and B ;

end adder

Q.31 Write a VHDL code for 2×1 .MUX.

(Refer Listing 10.9.5)

Q.32 State the advantage of package declaration over component declaration.


(Refer section 10.2.4)

Q.33 What is the need for VHDL ?

(Refer section 10.1)

Q. 34 What are the operators present in VHDL ?

(Refer section 10.6)

Q.35 What is a package in VHDL ?

(Refer section 10.2.4)

Q. 36 Write the behavioral modeling code for a D flip flop.

(Refer section 10.14.1)

Q. 37 List out the operators present in VHDL.

(Refer section 10.6)

Q. 38 Write the behavioral model of D flip flop.

(Refer section 10.14.1)

Q. 39 What is data flow modelling in VHDL? Give its basic mechanism.

(Refer section 10.3.2)

Q. 40 Write the VHDL code to realize a 2 × 1 multiplexer.

(Refer example 10.7.4)

AU : May-16

Q. 41 Write VHDL behavioral model for D flip flop.

(Refer section 10.14.1)

AU : Dec.-16

Q.42 Give the syntax for package declaration and package body in VHDL.

(Refer sections 10.2.4 and 10.2.5)

Q.43 Write the VHDL code for 2 x 1 multiplexer using behavioral modeling.

(Refer example 10.7.3)


Q.44 What are the languages that are combined together to get VHDL
language ?

(Long Answered Questions)


(Regulation 2008)

Dec.-10

Q.1 Explain the design procedure of RTL using VHDL. [Section 10.19] [10]

Q.2 Write a note on testbenches. [Section 10.21] [6]

May-11

Q.3 Describe the RTL in VHDL. [Section 10.19] [16]

Dec.-11

Q.4 Construct a VHDL module for a JK flipflop. [Section 10.14] [8]

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.9 Briefly discuss the use of ’Packages’ in VHDL.[Section 10.2] [6]

Q.10 List and briefly explain different data types supported by VHDL. [Section
10.6] [6]

Q.11 Write an HDL code that implements an 8:1 multiplexer. [Section


10.8] [10]

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

Q.16 Write a VHDL code to realize a full adder using.

i) Behavioral modeling [Section 10.3.1]

ii) Structural modeling [Section 10.3.3] [16]

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.20 Explain functions and subprograms with suitable examples. [Sections


10.10 and 10.13] [6]

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.

[Refer similar example in section 10.15.6] [8]

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]

Q.24 Write a short notes on built-in operators used in VHDL programming.


[Section 10.6.6] [6]

Q.25 Write VHDL coding for 4 x 1 Multiplexer.

[Listing 10.8.2] [7]

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.

(Refer listing 10.3.1 and 10.9.4) [10]

Q.30 Discuss briefly the packages in VHDL.

(Refer sections 10.2.4 and 10.2.5) [6]


Q.31 Write an VHDL coding for realization of clocked SR flip - flop. (Refer
listing 10.14.1) [7]

Dec.-18

Q.32 Write a VHDL code to realize a half adder using behavioral modeling and
structural modeling.

(Refer section 10.7.1 and Refer listing 10.9.2) [13]

You might also like