You are on page 1of 48

ap

Ch ter
Programming
11 in
VHDL

11.1 Introduction
VHDL (VHSIC hardware description language) is a hardware description lan-
guage used in electronic design automation to describe digital and mixed-signal
systems such as field programmable gate arrays and integrated circuits where
VHSIC stands for Very High Speed Integrated Circuit.
The VHSIC hardware description language is an industry standard used to
describe hardware from the abstraction to the concrete level. VHDL resulted from
work done in 70s and early 80s by the US Department of Defence. In 1986,
VHDL was proposed as an IEEE standard. It went through a number of revisions
and changes until it was adopted as the IEEE 1076 standard in December 1987.

11.2 VHDL Libraries


VHDL libraries allow us to store commonly used packages and entities that we
can use in our VHDL files. A VHDL package file contains common design ele-
ments that we can use in the VHDL source files to make up our own design.
For example, as in C language, we use certain standard library files by includ-
ing them in the program. Programming in VHDL also allows including certain
library files so that a programmer can design any program with minimal effort.
A library is introduced into the VHDL listing using statements of the form,

Library <Library_name>;
11.2 Digital Electronics, an easy approach to learn

Table 11.1 Comparison between C language and VHDL language


In C language In VHDL
#include<stdio.h> library IEEE
#include<conio.h> use IEEE.STD logic 1164.all

For example, one particularly useful standard library is called IEEE, this stands
for the Institute of Electrical and Electronics Engineers (IEEE), which is a profes-
sional Society for Electrical and Electronics Engineers. It is introduced by means
of the command

Library IEEE;

Once a library is referenced, any definition from the library may be used in writing
a VHDL description of a digital system.
Information in library is contained in subgroups called packages. A particular
useful package is called IEEE 1164, which is based on the VHDL language defi-
nition. This defines types and functions that are convenient to use in writing code,
and it is usually placed in library.

11.3 Data Types


Data types are used to specify different characteristics of the variable, signals, and
constants used in a VHDL code.
To define a data type, one must create a type declaration. A type declaration
defines the name of the data type and range of the data type. Type declarations are
allowed in package declaration sections, entity declaration section, architecture
declaration sections, sub-program declaration sections, and process declaration
section.
For example,
A : in bit Data type of the variable (suggests its range)

Name of Suggest that


the A is an input
variable variable

In VHDL, we have different data types which can be used as per the needs of
the designer. Some common data type are:
Programming in VHDL 11.3

1. Bit 6. Std ulogic


2. Bit vector 7. Std ulogic vector
3. Boolean 8. Std logic
4. Character 9. Std logic vector
5. Integer

1) Bit
It is a very basic data type. The variable which is declared as bit data type can
have only two values, 0 & 1.
Syntax:
SIGNAL bit name: BIT :=0
Bit name <= 1;
The operator := is used for variable assignment, that is, we may change the
value later.
The operator <= is used for fixed assignment, we cannot change the value of
the variable which is assigned by using the operator <=.
Here, in the above syntax, SIGNAL is a keyword to initialize a bit variable in
the architecture.

2) Bit vector
A bit vector data type is used for array of bits. It must be declared with a value for
the vector range.
Syntax:
SIGNAL bit ArrayName : bit vector (3 down to)) :=0000;
An entire bit vector can be assigned to a value by using double quotes; as
shown below.
bitArrayName <= 1101;
The above statement assigns (1101)2 = 13 to variable bitArrayName

3) Boolean
Boolean is a standard VHDL data type typically used as a variable or as a constant
to signify some sort of condition.
Syntax:
SIGNAL BooleanName : Boolean := false;
11.4 Digital Electronics, an easy approach to learn

Boolean Name <= true;

4) Character

The character data type is a predefined type declared in the STANDARD package
and the value of this type are the 256 character of the ISO 8859-1 (Latin 1)
The set of predefined operation for the CHARACTER type contains all rela-
tional functions: =, /=, <, <=, >, >=

5) Integer

The VHDL integer type has similar semantics to the integer type in most other
computer language. It is defined to have at least the range -2 31 to 231 -1.

6) Std-ulogic

The std-ulogic types are part of the IEEE library, and can have the values:
U Uninitialized
X Forcing unknown
0 Forcing 0
1 Forcing 1
Z High impedance
W Weak Unknown
L Weak 0
# Weak 1
dont care
Syntax:
SIGNAL StdLogicName: stdulogic := 0;
StdLogicName <=Z;

7) Std ulogic vector

It is an array of std ulogic.


Syntax:
SIGNAL stdLogicVectorName : STD ULOGIC VECTOR (5 downto
0):= 000000
stdLogicVectorName <= 111111;
Programming in VHDL 11.5

8) Std logic
Std logic data type is derived from std ulogic. Specifically it is a resolved
std ulogic. In VHDL, if a data type (that is std ulogic) doesnt have a function
defined for it, then it is called resolved, i.e., if two or more drivers are allocated
for a signal, the compiler will compile.
For example,
a <= 1
a <= 1 or 0
If signal a is of type std ulogic, then any compiler will immediately flag
this code as an error & there wont be any need to simulate to find it (infect the
simulator wont even let u get started)
U Uninitialized
X Forcing unknown
0 Forcing 0
1 Forcing 1
Z High impedance
W Weak Unknown
L Weak 0
H Weak 1
Dont care
Syntax is same as that of std ulogic.

9) Std logic vector


It is an array of std logic & the syntax is similar to that of std ulogic vector.

11.4 Keywords in VHDL


As with any computer language, VHDL requires that we adhere to a set of rules
that defines keywords and syntax. A keyword (also called a reserved word) is a
word that has a special meaning in the language, and cannot be used for any other
purpose.
For example, entity would indicate that entity is a keyword in VHDL. The
keywords of VHDL is described below,

abs begin disconnect generate


access black downto generic
after body else group
11.6 Digital Electronics, an easy approach to learn

alias buffer elseif guarded


all bus end if
and case entity initial
architecture component exit impure
array configuration file in
assert constant for inout
attribute is function label
then of range to
library open record Transport
linkage or resister Type
literal out rem unaffected
loop report units subtype
map port No1 Use
mod postponed variable wait
nand procedure select when
new process shared while
next puse signal srl
nor with sla
not sll xor
null sra xnor

Syntax refers to the word usage and order that must be used to write state-
ment and also to the punctuation requirements that defines special points in the
statement, such as the end of a command.

11.5 Operators
Table 11.2 VHDL operators
Sl. No. Classes
1 Logical operator and or nand nor xor x-nor
2 Relational operator = /= < <= > >=
3 Shift operator sll srl sla sra rol ror
4 Additional Operator + = &
5 Unary operator + -
6 Multiplying Operator * / mod rem
7 Miscellaneous Operator ** abs not
Programming in VHDL 11.7

VHDL supports efficient classes of operators that operate on signals, variables


and constants. The different classes of operators are summarized above.
The order of precedence is the highest for the operators of class 7, followed
by class 6 with the lowest precedence for class 1. Unless parenthesis is used, the
operators with the highest precedence are applied first. Operators of the same
class have the same precedence and are applied from left to right in an expression.
As for example consider the following std ulogic vectors.
X=010, Y=10 Z=10101
The expression, not X & Y xor Z rol 1 is equivalent to,
((not X) & Y) xor (Z rol 1) = ((101) & 10) xor (01011)
= (10110 xor 01011) =11101.

A) Logical operators
The logical operators (and, or, xor, nand, nor, xnor) are defined for the bit,
Boolean, std logic and std ulogic, data types and their vectors. They are
used to define Boolean logic expression or to perform, bit by bit operations on
arrays of bits. They give a result of the same type as the operand (bit, Boolean
etc). These operators can be applied to signals, variables and constants.
Note: The NAND and NOR operator are not associative. One should use
parenthesis in a sequence of nand and nor operator to prevent a syn-
tax error. As for example, X nand Y nand Z will give a syntax error and
should be written as (X nand Y) nand Z.

B) Relational operators
The relational operators test the relative values of two scalar types and give the
result as Boolean output of TRUE or FALSE.
Table 11.3 Description of relational operators
Operators Description Operand types Result type
= Equality Any type Boolean
/= Inequality Any type Boolean
< Smaller than Scalar or discrete array type Boolean
<= Smaller than or equal Scalar or discrete array type Boolean
> Greater than Scalar or discrete array type Boolean
>= Greater than or equal Scalar or discrete array type Boolean
11.8 Digital Electronics, an easy approach to learn

Note: The symbol of operator <= (smaller or equal to) is the same one as the
assignment operator used to assign a value to a signal or variable.

C) Shift operators
These operators perform a bit-wise shift or rotate operation on a one dimensional
array of elements of the type bit (or std logic) or Boolean.
Table 11.4 Description of shift operators
Operators Description Operand types Result
type
sll Shift left log- Left: any one dimensional array type with ele- Same as
ical (fill right ments of type bit or Boolean Right: integer left type
vacant bit with
0)
srl Shift right Left: any one dimensional array type with ele- Same as
logical (fill left ments of type bit or Boolean Right: integer left type
vacant bit with
0)
sla Shift left arith- Left: any one dimensional array type with ele- Same as
metic (fill right ments of type bit or Boolean Right: integer left type
vacant bit with
right most bit)
sra Shift right Left: any one dimensional array type with ele- Same as
arithmetic (fill ments of type bit or Boolean Right: integer left type
left vacant bit
with right most
bit)
rol Rotate left (cir- Left: any one dimensional array type with ele- Same as
cular) ments of type bit or Boolean Right: integer left type
ror Rotate right Left: any one dimensional array type with ele- Same as
(circular) ments of type bit or Boolean Right: integer left type

The operand resides on the left of the operator and the number (integer) of
shifts resides on the right side of the operator. As for example,
Variable NUM1 : bit vector:=10010110
NUM1 srl 2;
Will result in, NUM=00100101.

D) Addition operators
The addition operators are used to perform arithmetic operation (addition and
subtraction) on operands of any numeric type.
Programming in VHDL 11.9

The concatenation (&) operators is used to concatenate two vectors together


to make a longer one.
Table 11.5 Description of addition operators
Operators Description left operand types Right operand types Result type
+ Addition Numeric type Numeric type Same type
- Subtraction Numeric type Numeric type Same type
& Concatenation Array or Array or Same array
element type element type type

E) Unary operators
The unary operator + and - are used to specify the sign of a numeric type.
Table 11.6 Description of unary operators
Operators Description Operand type Result type
+ Identity Any Numeric type Same type
- Negation Any Numeric type Same type

F) Multiplying operators
The multiplying operators are used to perform mathematical function on numeric
types (integer or floating point).
Table 11.7 Description of multiplying operators
Operators Description left operand types Right operand types Result type
Any integer or Same type Same type
floating type
* Multiplication Any physical Integer or real Same as left
type type
Any integer or Any physical Same as right
real type type
Any integer or Same type Same type
floating type
/ Any physical Integer or real Same as left
type type
Any integer or Any physical Integer
real type type
Mod Modulus Any integer type Same type
rem Remainder Any integer type Same type

G) Miscellaneous operators
These are the absolute value and exponentiation operators that can be applied to
numeric types.
11.10 Digital Electronics, an easy approach to learn

The logical negation (not) results in the inverse polarity but of the same type.
Table 11.8 Description of miscellaneous operators
Operators Description left operand types Right operand types Result type
** Exponentiation Integer type Integer type Same as left
Floating type Integer type
abs Absolute value Any numeric type Same as left
not Logical negation Any bit or Boolean type Same type

11.6 Identifier
Identifiers are user-defined words used to name objects in VHDL models. We
have seen examples of identifiers for input and output signals as well as the name
of a design entity and architecture body. When choosing an identifier one needs
to follow these basic rules:
(a) May contain only alphanumeric characteristics (A to Z, a through z, 0 to 9)
and the underscore ( ) character.
(b) The first character must be a letter and the last character cant be an under-
score.
(c) An identifier cant include two consecutive underscore.
(d) An identifier is case insensitive, (and2 or AND2 or And2 refer to the same
variable)
(e) An object can be of any length.
(f) An identifier cant be a keyword.
Examples of valid identifiers are: X10, x10, my gate1, my gate 1, etc.
Some invalid identifiers are: X10, mygate@input, my gate, gate-input,
etc.

11.7 Data Objects: Signals, Variables and Constants


A data object is created by an object declaration and has a value and type associ-
ated with it. An object can be a constant, variable, signal or a file.
Signals can be considered as wires in a schematic, that can have a current
value and future values, and that are a function of a signal assignment statements.
On the other hand, variables and constants are used to model the behavior of a
circuit and are used to process, procedure and functions.
Programming in VHDL 11.11

Signals
Signals are declared outside the process using the following statement:
Signal list of signal names:type [:=initial values];
For example, signal sum, carry:std logic

Constant
A constant can have a single value of a given type and cant be changed during
the simulation. A constant is declared as follows.
Constant list of name of constant:type [:=initial value];
where the initial value is optional. Constant can be declared at the start of
an architecture and then can be used anywhere within the architecture. Constant
declared within a process can only be used inside that specific process.
For example,
Constant rise fall time:=2ns

Variable
A variable can have a single value, as with a constant but a variable can be updated
using a variable assignment statement. The variable is updated without any delay
as soon as the statement is executed. Variable must be declared inside a process
(and are local to the process). The variable declaration is as follows,
Variable list of variable names: type [:=initial value]
For example,
Variable cntr bit: bit:=0;

11.8 Entity Declaration


It defines the names, input output signals and modes of hardware module.
Syntax:
entity entity name is
port declaration;
end entity name;
An entity declaration should start with entity and ends with end keyword.
Ports are interfaces through which an entity can communicate with its envi-
ronment. Each port must have a name, direction and a type declaration. The
11.12 Digital Electronics, an easy approach to learn

direction may be input, output or inout. An entity may have no port declaration
also.
Table 11.9 Port description
Direction Description
In Port can be read
Out Port can be written
Inout Port can be read and written
buffer Port can be read and written, it can have only one source

An entity is declared below and each term are described for better understand-
ing,

Architecture
It describes the internal description of design or it tells what is there inside design.
Each entity has at least one architecture. But, an entity can have many architec-
tures. Architecture can be described, using structural, data, behavioral or mixed
style.
Architecture can be used to describe a design at different levels of abstraction
like gate level, register transfer level (RTL) or behavior level.
Syntax:
architecture architecture name of entity name is
begin
statements;
end architecture name;
Here we should specify the entity name for which we are writing the archi-
tecture body. The architecture statements should be inside the begin and end
keyword. Architecture declarative part may contain variables, constants or com-
ponent declaration.
Programming in VHDL 11.13

The internal working of an entity can be defined using different modeling


styles inside architecture body. They are
1. Dataflow modeling (based on logic expression)
2. Behavioral modeling (based on truth table)
3. Structural modeling (based on logic diagram)
Structure of an entity: Fig.11.1 describes the structure of an entity, that is, it de-
scribes the way to write VHDL codes.
entity
port declaration
(entity declaration)

internal wiring
(architecture body)
(data flow, behavioral
structural or mixed)

Fig. 11.1 Structure of an entity

11.9 Dataflow Modelling


Dataflow description contains only concurrent statement. Concurrent statements
executes when data is available on their inputs. These statements occur in any
order within the architecture.
In this style of modeling, the internal working of an entity can be implemented
using concurrent signal assignment.
Let us take the example of half adder which is having one XOR gate and a
AND gate.

Fig. 11.2 Half adder

The VHDL code for half adder can be written as,

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
11.14 Digital Electronics, an easy approach to learn

entity half_adder is
port (A : in bit;
B : in bit;
sum : out bit;
carry : out bit);
end half_adder;
architecture dataflow of half_adder is
begin
sum <= A xor B;
carry <= A and B;
end dataflow;

Here STD LOGIC 1164 is an IEEE standard which defines a nine value logic
type, called STD ULOGIC. use is a keyword, which imports all the decla-
rations from this package. The architecture body consists of concurrent signal
assignments, which describes the functionality of the design. Whenever there is a
change in RHS, the expression is evaluated and the value is assigned to LHS.
Note: In data flow modeling, the VHDL programs are based on Boolean expres-
sion/logic expression.

Example 11.1 Write a VHDL code for AND gate using data using dataflow
model.
I Solution
Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity AND_2 is
port ( A, B : in std_logic;
F : out std_logic);
end AND_2;

architecture dataflow of AND_2 is


begin
F <= A and B;
end dataflow;
Programming in VHDL 11.15

Example 11.2 Write a VHDL code for F = (A + B) + CD

I Solution
Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity expression is
port ( A, B, C, D : in std_logic;
F : out std_logic);
end expression;

architecture dataflow of expression is


begin
F <= ((A or B)or(not(C and D)));
end dataflow;

11.10 Behavioural Modelling


In this type of modelling, the internal working of an entity can be implemented
using set of statements. Behavioral modelling is based on the truth table. In this
type of modelling the truth table are represented by using conditional statements
like if, else, elseif, elsif, case etc. The conditional statements in VHDL are similar
to the conditional statements in C language. The basis for behavioral modelling
is the process construct.

Process
A process statement is the main construct in behavioral modelling that allows
us to use sequential statements to describe the behavior of system overtime. A
process is declared within architecture and is concurrent statement. However the
statements inside a process are executed sequentially.
The syntax for a process statement is:
[process label:]process[(sensitivity list)][is]
[process declaration]
begin
list of sequential statements such as:
signal assignments
11.16 Digital Electronics, an easy approach to learn

variable assignments
case statement
exit statement
if statement
loop statement
next statement
null statement
procedure call
wait statement
end process[process label]

if statement
The if statement is used to select one or none of a collection of statements depend-
ing on some condition expression. Note that conditions are expressions resulting
in Boolean values. If the condition is evaluated to be true, the corresponding
statement list is executed. Otherwise, if the else clause is present, the else
statement is executed. The example 11.3 well describes the behavioral modeling
in VHDL.

Example 11.3 Write a VHDL code for OR gate using behavioral code.

I Solution
The behavioral VHDL code is based on truth table, hence the truth table for OR
gate is given by,
Table 11.10 Truth table for OR gate
A B F
0 0 0
0 1 1
1 0 1
1 1 1

VHDL code for OR gate

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Programming in VHDL 11.17

entity OR_2 is
port( A, B : in std_logic;
F : out std_logic);
end OR_2;

architecture behavioral of OR_2 is


begin
process(A,B)
begin
if((A=0)and(B=0))then
F<=0;
else
F<=1;
end if;
end process;
end behavioral;

elseif statement
Multiple conditions can be built with if statement followed by elseif clause(s).

Example 11.4 Write a VHDL code for the truth table shown below, using be-
havioral modeling.
Table 11.11 Truth table
A B F
0 0 0
0 1 1
1 0 Z
I Solution
The behavioral VHDL code is based on truth table.

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity model is
port( A, B : in std_logic;
F : out std_logic);
11.18 Digital Electronics, an easy approach to learn

end model;

architecture behavioral of model is


begin
process(A,B)
begin
if((A=0)and(B=0))then
F<=0;
elsif((A=0)and(B=1))then
F<=1;
elsif((A=1)and(B=0))then
F<=Z;
end if;
end process;
end behavioral;

case statement
The case statement is used to select a collection of statement based on the range of
values of a given expression called selection expression. The selection must be of
discrete type or a one dimensional array. For the matching choice the expression
is selected and statement link is executed. All the choices must be distinct, all
values must be represented in the choice lists. If some choice is not specified,
then the default choice must be indicated through the use of other keyword.

Example 11.5 Write a VHDL code to implement a 4:1 MUX using VHDL code
(use case statement).

I Solution
The case statement comes under behavioral modeling, and behavioral modeling
is based on truth table, hence the truth table for 4:1 MUX is given by,
Table 11.12 Truth table for 4:1 MUX
S1 S0 Output(F)
0 0 I0
0 1 I1
1 0 I2
1 1 I3
Programming in VHDL 11.19

The VHDL code for 4:1 MUX is given by,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity MUX4_1 is
port(S1,S0: in std_logic;
I0, I1, I2, I3: in std_logic;
output : out std_logic);
end MUX4_1;

architecture behavioral of MUX4_1 is


begin
process(S1,S0, I0, I1, I2, I3)
variable sel:std_logic_vector(1 downto 0);
begin
sel:=S1 & S0;

case sel is
when "00" => output<=I0;
when "01" => output<=I1;
when "10" => output<=I2;
when "11" => output<=I3;
when others => output<=X;
end case;
end process;
end behavioral;

with select
It is another constraint to model a behavioral problem in VHDL. The same exam-
ple of MUX which is discussed in previous example (11.4) using case statement
can also be implemented using with select as discussed below,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity MUX4_1 is
11.20 Digital Electronics, an easy approach to learn

port(S1,S0: in std_logic;
I0, I1, I2, I3: in std_logic;
F : out std_logic);
end MUX4_1;

architecture behavioral of MUX4_1 is


signal sel : std_logic_vector(1 downto 0);
begin
sel<=S1 & S0;

with sel select


F<= I0 when "00",
I1 when "01",
I2 when "10",
I3 when "11",
X when others;
end behavioral;

when else
It is another constraint to model a behavioral problem in VHDL. The same exam-
ple of MUX which is discussed in previous example (11.4) using case statement
can also be implemented using when else as discussed below,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity MUX4_1 is
port(S1,S0: in std_logic;
I0, I1, I2, I3: in std_logic;
F : out std_logic);
end MUX4_1;

architecture behavioral of MUX4_1 is


begin
F<= I0 when (S1 & S0)="00" else
I1 when (S1 & S0)="01" else
I2 when (S1 & S0)="10" else
Programming in VHDL 11.21

I3 when (S1 & S0)="11" else


X;
end behavioral;

11.11 Structural Modelling


Complex logic networks are built by combining logic gates and other basic units.
A VHDL structural description of a logic module is based on the same concept.
By means of structural modelling, the modulus internal construction can be
described as single sub modules, which are put together. Each sub modules again
consist of further such sub modules, and thus a hierarchical structure results. The
VHDL description of the lowest hierarchical levels can however no longer be
structural modelled, but must be described by means of behavioral modelling.
Let us examine how structural modelling can be applied to AOI (AND, OR,
invert) circuit shown in Fig.11.3. Here the AOI schematic is created by cascading
two AND gates (G1 and G2 ) into an OR gate (G3 ).

A
G1
B X1 F
G3
C X2
G2
D
AOI - network

Fig. 11.3 AOI logic

We can write by inspection that the output is given by,

F = A.B + C.D

Let the two AND gates produce the outputs X1 and X2 .

X1 = A.B and X2 = C.D

which are used as input to the OR gate such that,

F = X 1 + X2

The three equations for F , X1 and X2 provide the basic structure of the logic
network in which they provide the information needed to reconstruct the logic
diagram exactly as it was originally presented, and structural models are written
using the same concept.
11.22 Digital Electronics, an easy approach to learn

VHDL structural models are created by first introducing the concept of a


building block called a component. This building block is a logic model that
has been defined by the usual entity and architecture listings and is used to cre-
ate another logic network. A component may be as simple as logic gates, or it
may itself represent a complicated network. We always view a component as a
simple building block regardless of its internal complexity. To create a structural
model, we first choose the component and then we describe how the components
are wired together. The wiring is specified by formal listing that maps the port of
the modules.
Using the above concepts, let us write a structural description of the module
AOI network shown in Fig.11.3.
structural description (comment line)

entity AOI_network is
port(A, B, C, D: in bit;
F : out bit);
end AOI_network;

the listing below builds the network using component architecture structural
of AOI network,
define an AND gate as a component

component AND_2
port(X, Y: in bit;
Z : out bit);
end component;

define an OR gate as a component

component OR_2
port(X, Y: in bit;
Z : out bit);
end component;

the next statements declares the internal module signals

signal X1,X2:bit;
Programming in VHDL 11.23

the port map specifies the internal wiring

begin
G1:AND_2 port map(A,B,X1);
G2:AND_2 port map(C,D,X2);
G3:OR_2 port map(X1,X2,F);
end structural;

To use a module as a component in this network, it must have been previously de-
fined by entity and architecture statements. This means that, we have to include
declarations such as:
For AND 2 component,

entity AND_2
port(u, v: in bit;
q : out bit);
end AND_2;

architecture logic of AND_2 is


begin
q<=u and v;
end logic;

For OR 2 component,

entity OR_2
port(u, v: in bit;
q : out bit);
end OR_2;

architecture logic of OR_2 is


begin
q<=u or v;
end logic;

In the complete VHDL listing of the network, the concept of component can be
understood using the concept of a design library. A design library is a collection
of different modules, each defined by entity and architecture statements. Once the
11.24 Digital Electronics, an easy approach to learn

cells are defined in the library, we may use copies of the cells in our design via
the component command. This is called instancing the cell, and the component
itself is called an instance of the original logic diagram.
The Fig.11.4 portrays the concept of a library and instancing. Note that any
instance is not the same as withdrawing the cell from the library. Instead, an
instance should be viewed as literal copy of the cell that is currently stored in
the library. This means that if we change the cell in the library, all the instances
changes accordingly. A cell may be instanced as many times as desired in the
network. It is easy to see that, this saves time and work in creating complex
networks, since the library entries only need to be defined once.
AND2 OR2
u u
q q
v v

network = wired instance

Fig. 11.4 Instancing from a cell library

Next, let us examine the use of the keyword signal. Signal is used to define
the internal identifiers X1 and X2 that defines the outputs of the AND2 gates G 1
and G2 in the original logic diagram. The signal definitions are different from
the identifier used in the port statement that they exist inside the module. Internal
identifiers are then used to wire the gates together to form the port connections.
Once the component has been declared, the network is described by the use
of the port map statements. These provide the wiring diagram information by
specifying how component signals interface.
Lets examine the entries,
the port map specifies the internal wiring

begin
G1:AND_2 port map(A,B,X1);
G2:AND_2 port map(C,D,X2);
G3:OR_2 port map(X1,X2,F);
end structural;
Programming in VHDL 11.25

In detail the first map,

G1:AND_2 port map(A,B,X1);

tells us that gate G1 is the AND2 component and is wired to the port identifiers A,
B and internal signal X1 . The order of the signal in the AND2 component state-
ment was given as [u, v, q] corresponds to input1(A), input2(B) and output(X 1 ).
The port map maintains this implied order.
Similarly,

G2:AND_2 port map(C,D,X2);

is another AND2 instance that maps the AOI module inputs C and D to the inputs
of the AND2 gate and produces an output X2 .
Finally,

G3:OR_2 port map(X1,X2,F);

says that G3 uses the internal signals X1 and X2 as inputs to the OR2 instance and
provide the output F of the module AOI network. This completes the structural
listings.

Some important programs of VHDL


1. VHDL code to implement a XOR gate.
import std logic from the IEEE library

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY DECLARATION: name, inputs, outputs

entity xorGate is
port( A, B : in std_logic;
F : out std_logic);
end xorGate;
11.26 Digital Electronics, an easy approach to learn

BEHAVIORAL DESCRIPTION: how the XOR Gate works

architecture dataflow of xorGate is


begin
F <= A xor B;
end dataflow;

2. VHDL code to implement a NAND gate.

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity NANDGATE2 is
port( A, B : in std_logic;
F : out std_logic);
end NANDGATE2;

architecture dataflow of NANDGATE2 is


begin
F <= A nand B;
end dataflow;

3. VHDL code to implement a half adder.


For a half adder we know that....
Sum(S) = A B
Carry(cr) = A.B

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity half_adder is
Port ( A : in std_logic;
B : in std_logic;
Programming in VHDL 11.27

sum : out std_logic;


carry : out std_logic);
end half_adder;

architecture dataflow of half_adder is


begin
sum <= A xor B ;
carry <= A and B;
end dataflow;

4. VHDL code to implement a full adder.


For a full adder we know that....
Sum(S) = A B Cin
Carry(cr) = A.B + B.Cin + Cin .A

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity fulladd is
Port(Cin,A,B:in std_logic;
S,cr:out std_logic);
end full add;
architecture dataflow of fulladd is
begin
s <= A xor B xor Cin ;
Cout <= (A and B) or (Cin and A) or (Cin and B);
end dataflow ;

5. VHDL code to implement a half subtractor


For a half subtractor we know that....
diff = A B
borrow = A.B

Library IEEE;
11.28 Digital Electronics, an easy approach to learn

use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity half_sub is
Port ( A : in std_logic;
B : in std_logic;
diff : out std_logic;
borrow : out std_logic);
end half_sub;

architecture dataflow of half_sub is


begin
diff <= A xor B ;
borrow <= A and not(B);
end dataflow;

6. VHDL code to implement a full subtractor


For a full adder we know that....
diff = A B Cin
borrow = Cin (A B) + AB

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity fullsub is
Port(Cin,A,B:in std_logic;
diff,br:out std_logic);
end fullsub;
architecture dataflow of fullsub is
begin
diff <= A xor B xor Cin ;
br <= (cin and (A xnor B)) or (not(A) and B);
end dataflow ;
Programming in VHDL 11.29

7. VHDL code to implement a 4:1 MUX


The boolean equation for a 4-to-1 multiplexer is:

F = (A.S 0 .S 1 ) + (B.S0 .S 1 ) + (C.S 0 .S1 ) + (D.S1 .S0 )

Table 11.13 Truth table for 4:1 MUX


S1 S0 Output(F)
0 0 A
0 1 B
1 0 C
1 1 D

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity MUX_4 is
port (
A : in std_logic;
B : in std_logic;
C : in std_logic;
D : in std_logic;
s : in std_logic_vector(1 downto 0);
F : out std_logic
);
end MUX_4;

architecture behavioral of MUX_4 is


begin

process(A,B,C,D,S)
begin
case S is
when "00" => F <= A;
when "01" => F <= B;
when "10" => F <= C;
11.30 Digital Electronics, an easy approach to learn

when others => F <= D;


end case;
end process;
end behavioral;

8. VHDL code to implement a 1:4 Demux


Truth table of 1:4 Demux
Table 11.14 Truth table for 1:4 Demux
Input Select lines Output(y)
S1 S0 Y0 Y1 Y2 Y3
Inbit 0 0 Inbit 0 0 0
Inbit 0 1 0 Inbit 0 0
Inbit 1 0 0 0 Inbit 0
Inbit 1 1 0 0 0 Inbit

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity demux1_4 is
port (yo,y1,y2,y3 : out std_logic;
s : in std_logic_vector(1 downto 0);
bitin : in std_logic );
end demux1_4;

architecture behavioral of demux1_4 is

begin
process(bitin,)
begin
case s is
when "00"=>y0<= bitin; y1<=0;y2<=0;y3 <=0;
when "01"=>y1<= bitin; y0<=0;y2<=0;y3 <=0;
when "10"=>y2<= bitin; y0<=0;y1<=0;y3<=0;
Programming in VHDL 11.31

when others => y3<= bitin; y0<=0;y1<=0;y2<=0;


end case;
end process;
end behavioral;

9. VHDL code to implement a 3:8 decoder


Truth table of 3:8 decoder
Table 11.15 Truth table of 3:8 Decoder
Input Output
S2 S1 S0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0 0 0
1 0 1 0 0 1 0 0 0 0 0
1 1 0 0 1 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity decoder3_8 is
port ( s : in std_logic_vector (2 downto 0);
y : out std_logic_vector (7 downto 0) );
end decoder3_8;

architecture behavioral of decoder3_8 is


begin
y <= "00000001" when s = "000" else
"00000010" when s = "001" else
"00000100" when s = "010" else
"00001000" when s = "011" else
"00010000" when s = "100" else
11.32 Digital Electronics, an easy approach to learn

"00100000" when s = "101" else


"01000000" when s = "110" else
"10000000" ;

end behavioral;

10. VHDL code to implement 4-bit magnitude comparator

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity compare is
port ( A, B : in std_logic_vector(3 downto 0) ;
AeqB, AgtB, AltB : out std_logic ) ;
end compare ;
architecture behavioral of compare is
begin
AeqB <= 1 when A = B else 0 ;
AgtB <= 1 when A > B else 0 ;
AltB <= 1 when A < B else 0 ;
end behavioral ;

11. VHDL code to implement 4-bit binary to gray converter


Let a 4-bit binary number b = b3 , b2 , b1 , b0 .
And the corresponding gray code, g = g3 , g2 , g1 , g0
Where,
g3 = b3
g2 = b3 b2
g1 = b2 b1
g0 = b1 b0

So, the required VHDL code is,

Library IEEE;
Programming in VHDL 11.33

use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity bin_gray is
port(b:in std_logic_vector(3 downto 0);
g:out std_logic_vector(3 downto 0));
end bin_gray;

architecture behavioral of bin_gray is


begin
g(3)<=b(3);
g(2)<=b(3) xor b(2);
g(1)<=b(2) xor b(1);
g(0)<=b(1) xor b(0);
end behavioral;

12. VHDL code to implement 4-bit gray to binary converter


Let a 4-bit gray code is represented as g = g3 g2 g1 g0 .
Then the corresponding Binary code, b = b3 b2 b1 b0 ,
Where
b3 = g3
b2 = b3 g2
b1 = b1 g1
b0 = b1 g0

So, the required VHDL code is,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity gray_bin is
port(g:in std_logic_vector(3 downto 0);
b:inout std_logic_vector(3 downto 0));
11.34 Digital Electronics, an easy approach to learn

end gray_bin;

architecture behavioral of gray_bin is


begin
b(3)<=g(3);
b(2)<=b(3) xor g(2);
b(1)<=b(2) xor g(1);
b(0)<=b(1) xor g(0);
end behavioral;

13. VHDL code for S-R latch


Logic diagram of S-R latch is

R Qn

S Qn

Fig. 11.5 NOR based SR latch

So, by considering the above logic diagram the VHDL code may be written
as,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity SR_latch is
port(S,R : in std_logic;
q,nq : inout std_logic);
end SR_latch;

architecture behavioral of SR_latch is


begin
q<=nq nor R;
nq<=q nor S;
end behavioral;
Programming in VHDL 11.35

14. VHDL code for D flip flop.

Truth table of D flip flop

Table 11.16 Truth table of D flip flop


Clock D Qn+1
(rising edge) 0 0
(rising edge) 1 1
Non-rising X Qn

So, by considering the above truth table the VHDL code may be written as,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity d_ff is
port(d,clock :in std_logic;
Q:out std_logic);
end d_ff;

architecture behavioral of d_ff is

begin
process(clock)
begin

if (clockevent and clock=1) then


Q<=D;
end if;
end process;

end behavioral;
11.36 Digital Electronics, an easy approach to learn

15. VHDL code for J-K flip flop.


Truth table of J-K flip flop
Table 11.17 Truth table of JK flip flop
Clock J K Qn+1
Non-rising X X Qn
0 0 Qn
0 1 0
1 0 1
1 1 Qn

So, by considering the above truth table the VHDL code may be written as,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity JK_ff is
port(J,K,clock :in std_logic;
Qn:inout std_logic);
end JK_ff;

architecture behavioral of JK_ff is

begin
process(clock,J,K)
begin

if (clockevent and clock=1) then


if (J = 0 and K = 0) then
Qn <= Qn;
elsif (J = 1 and K = 0) then
Qn <= 1;
elsif (J = 0 and K = 1) then
Qn <= 0;
Programming in VHDL 11.37

elsif (J = 1 and K = 1) then


Qn <= not(Qn);
end if;
end if;
end process;

end behavioral;

16. VHDL code for T Flip flop.


Truth table of T flip flop
Table 11.18 Truth table of T flip flop
Clock Input(T) Qn+1
Non-rising X Qn
0 Qn
1 Qn

So, by considering the above truth table the VHDL code may be written as,

Library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity T_ff is
port(T,clock :in std_logic;
Qn:inout std_logic);
end T_ff;

architecture behavioral of T_ff is

begin
process(clock,T)
begin

if (clockevent and clock=1) then


11.38 Digital Electronics, an easy approach to learn

if (T = 0)then
Qn<=Qn;
else
Qn<=not(Qn);
end if;
end if;
end process;

end behavioral;

17. VHDL code for Serial In Serial Out(SISO) shift register.


The code for SISO can be written using structural modeling. In the code
given below D flip flop is used as component(need to be defined while com-
pilation).
Data in QA QB QC QD
D D D D
Data out
Clock clk clk clk clk

CL CL CL CL
Clear

Fig. 11.6 SISO shift register

From the above logic diagram the VHDL code using structural modelling
can be written as,

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity siso is
port (si: in std_logic;
clk: in std_logic;
so: out std_logic);
end siso;
Programming in VHDL 11.39

architecture structural of siso is


component d_ff is
port( d,clk: in std_logic;
q,qbar :inout std_logic);
end component;
signal a1, a2, a3, d1, d2, d3, d4:std_logic;
begin
L1:d_ff port map (si, clk, a1, d1);
L2:d_ff port map (a1, clk, a2, d2);
L3:d_ff port map (a2, clk, a3, d3);
L4:d_ff port map (a3, clk, so, d4);
end structural;

18. VHDL code for Serial In Parallel Out(SIPO) shift register.


The VHDL code for SIPO can be written using structural modelling. In the
code given below, D flip flop is used as component(need to be defined while
compilation).
Data in QA QB QC QD
D D D D

Clock clk clk clk clk

CL CL CL CL
Clear

Data out

Fig. 11.7 SIPO shift register

From the above logic diagram the VHDL code using structural modelling
can be written as,

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity sipo is
11.40 Digital Electronics, an easy approach to learn

port (si: in std_logic;


clk: in std_logic;
po:inout std_logic_vector(3 downto 0));
end sipo;

architecture structural of sipo is


signal d:std _logic_ vector(4 downto 0);
component d_ff
port (d,clk: in std_logic;
q,qbar :in out std_logic);
end component;
begin
a1:d_ff port map(si,clk,po(3),d(3));
a2:d_ff port map(po(3),clk,po(2),d(2));
a3:d_ff port map(po(2),clk,po(1),d(1));
a4:d_ff port map(po(1),clk,po(0),d(0));
end structural;

19. VHDL code for Parallel In Serial Out(PISO) shift register.


The VHDL code to implement PISO can be written in the form of structural
modelling, writing it in structural domain is easier as compare to data flow
or behavioral.
Parallel-to-serial shift register
Parallel input data

D0 D1 D2 D3

SHIFT/LOAD

LOAD SHIFT

X X X

D0 Q0 D1 Q1 D2 Q2 D3 Q3
Serial
CLK CLK CLK CLK output

f-f 0 f-f 1 f-f 2 f-f 3

CLK

Fig. 11.8 PISO shift register

From the above logic diagram the VHDL code using structural modelling
can be written as,
Programming in VHDL 11.41

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity piso is
port (pi: in std_logic _vector (3 downto 0);
c: in std_logic;
clk: in std_logic;
so:inout std_logic);
end piso;

architecture structural of piso is


signal d:std_ logic vector(3 downto 0);
signal q:std _logic vector(3 downto 1);
signal a:std_ logic vector(3 downto 1);
signal r:std _logic;
component d_ff is
port (d,clk: in std_logic;
q,qbar :in out std_logic);
end component;
component aoi is
port (a,b,c,d: in std_logic;
c: out std_logic);
end component;
begin
a1:aio port map (q (3),r,c,pi(2)a(3));
a2:aio port map( q (2),r,c,pi(1)a(2));
a3:aio port map (q (1),r,c,pi(0)a(1));
L1:d_ff port map( pi(3), clk, q(3),d(3));
L2:d_ff port map(a(3), clk, q(2),d(2));
L3:d_ff port map(a(2), clk, q(1),d(1));
L4:d_ff port map(a(1), clk, so,d(0));
end structural;
11.42 Digital Electronics, an easy approach to learn

20. VHDL code for Parallel In Parallel Out(PIPO) shift register.


The VHDL code to implement PIPO can be written in the form of structural
modelling, writing it in structural domain is easier as compare to data flow
or behavioral.
Data in

D QA D QB D QC D QD

Clock clk clk clk clk

CL CL CL CL
Clear

Data out

Fig. 11.9 PIPO shift register

From the above logic diagram the VHDL code using structural modelling
can be written as,

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity pipo is
port (pi: in std_logic _vector (3 downto 0);
clk: in std_logic;
po:inout std_logic _vector (3 downto 0));
end pipo;

architecture structural of pipo is


signal d:std_ logic vector(3 downto 0);
component d_ff is
port (d,clk: in std_logic;
q,qbar :in out std_logic);
end component;
Programming in VHDL 11.43

begin
L1:d_ff port map(pi(3), clk, po(3),d(3));
L2:d_ff port map(pi(2), clk, po(2),d(2));
L3:d_ff port map(pi(1), clk, po(1),d(1));
L4:d_ff port map(pi(0), clk, po(0),d(0));
end structural;

21. VHDL code to implement 4-bit ripple counter


State table for binary counter
Table 11.19 State table of binary counter
Decimal equivalent Q3 Q2 Q1 Q0
0 0 0 0 0
1 0 0 0 1
2 0 0 1 0
3 0 0 1 1
4 0 1 0 0
5 0 1 0 1
6 0 1 1 0
7 0 1 1 1
8 1 0 0 0
9 1 0 0 1
10 1 0 1 0
11 1 0 1 1
12 1 1 0 0
13 1 1 0 1
14 1 1 1 0
15 1 1 1 1

Note that each bit in this four-bit sequence toggles when the bit before it
(the bit having a lesser significance, or place-weight), toggles in a particular
direction: from 1 to 0.
This key point is used in the code given below,

library IEEE;
use IEEE.STD_LOGIC_1164.All;
11.44 Digital Electronics, an easy approach to learn

use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity ripple_count is
port (ce: in std_logic;
clk: in std_logic;
n:in std_logic _vector (3 downto 0);
q:inout std_logic _vector (3 downto 0));
end ripple_count;

architecture behavioral of ripple_count is


begin
process (ce, clk,q);
begin
if (ceevent and ce =1)then
q<="0000";
end if;
if(q<n)then
if (clkevent and clk =1)then
q(0)<=not q(0);
if (q(0) =1)then
q(1)<=not q(1);
if (q(1) =1)then
q(2)<=not q(2);
if (q(2) =1)then
q(3)<=not q(3);
end if;
end if;
end if;
end if;
else
q<="0000";
end if;
end process;
end behavioral;
Programming in VHDL 11.45

22. VHDL code to implement 4-bit Johnson counter


The VHDL code to implement 4-bit Johnson counter can be written in the
form of structural modelling

reset
PRE PRE PRE PRE
D3 Q3 D2 Q2 D1 Q1 D0 Q0
FF3 FF2 FF1 FF0

Q3 Q2 Q1 Q0

CLK

Fig. 11.10 4-bit Johnson counter

From the above logic diagram the VHDL code using structural modelling
can be written as,

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity Johnson is
port(clk, reset: in std_logic;
q,qbar: inout std_logic_vector(3 downto 0));
end Johnson;

architecture structural of johnson is


component d_ff is
port (d,clk,reset: in std_logic;
q,qbar :in out std_logic);
end component;
begin
L1:d_ff port map(qbar(3),clk,reset,q(0),qbar(0));
L2:d_ff port map(q(0),clk,reset,q(1),qbar(1));
L3:d_ff port map(q(1),clk,reset,q(2),qbar(2));
11.46 Digital Electronics, an easy approach to learn

L4:d_ff port map(q(2),clk,reset,q(3),qbar(3));


end structural;

23. VHDL code to implement 4-bit ring counter


The code for ring counter can be written using behavioral approach, as it is
the easier in this case.

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;
entity ring is
port(clk, clr: in std_logic;
q: inout std_logic_vector(3 downto 0));
end ring;

architecture behavioral of ring is


begin
process (clk,clr);
begin
if (clr = 0)then
q<="1000";
elsif(clr = 1)then
if (clkevent and clk =1)then
q(0)<= q(3);
for i in 0 to 2 loop
q(i+1)<=q(i);
end loop;
end if;
end if;
end process;
end behavioral;

24. VHDL code to implement 4-bit up/down counter.


The code for ring counter can be written using behavioral approach, as it is
the easier in this case.
Programming in VHDL 11.47

library IEEE;
use IEEE.STD_LOGIC_1164.All;
use IEEE.STD_LOGIC_ARITH.All;
use IEEE.STD_LOGIC_UNSIGNED.All;

entity up_down is
port(clk, rst: in std_logic;
ud:in std_logic;
q: inout std_logic_vector(3 downto 0));
end up_down;

architecture behavioral of up_down is


signal cnt: std_logic_vector (3 downto 0);
signal en : std_logic;
begin
q <= cnt;
process(clk)
begin
if(clk event and clk = 1) then
if (rst = 1) then
cnt <= "0000";
elsif (ud = 1 and en = 1) then
cnt <= cnt + 1;elsif (en = 0) then
cnt <= cnt - 1;
end if;
end if;
end process;
process(cnt)
begin
if (cnt = "0000") then
en <= 1;
elsif (cnt = "1111") then
en <= 0;
end if;
end process;
end behavioral;

You might also like