Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 50

EC 452 - VHDL LAB

LIST OF EXPERIMENTS :

VHDL Modeling and Synthesis of the following Experiments :

1. Logic Gates
2. Combinational Logic
3. JK, D, T, and SR flip-flops with preset and clear inputs
4. 4-bit shift register and bidirectional shift register with parallel load
5. 4-bit Ripple/Synchronous counters
6. 4-bit carry look ahead adder
7. Implementation of Moore and Mealy state machines
8. Implementation of two 4-bit numbers multiplication using Booth's algorithm
9. Traffic light controller
10. Construct an 8-bit dedicated data path to generate and add the numbers from
n down to 1, where 'n' is an 8-bit user input number.
INTRODUCTION TO HDL :
In electronics, a hardware description language or HDL is any language from a class
of computer languages for formal description of electronic circuits. It can describe the
circuit's operation, its design and organization, and tests to verify its operation by means
of simulation.
HDLs are standard text-based expressions of the spatial and temporal structure and

behavior of electronic systems. In contrast to a software programming language, HDL

syntax and semantics include explicit notations for expressing time and concurrency,

which are the primary attributes of hardware. Languages whose only characteristic is to

express circuit connectivity between a hierarchy of blocks are properly classified as

netlist languages.

HDLs are used to write executable specifications of some piece of hardware. A


simulation program, designed to implement the underlying semantics of the language
statements, coupled with simulating the progress of time, provides the hardware
designer with the ability to model a piece of hardware before it is created physically. It
is this executability that gives HDLs the illusion of being programming languages.
Simulators capable of supporting discrete-event and continuous-time (analog) modeling
exist, and HDLs targeted for each are available.
It is certainly possible to represent hardware semantics using traditional
programming languages such as C++, although to function such programs must be
augmented with extensive and unwieldy class libraries. Primarily, however, software
programming languages do not include any capability for explicitly expressing time and
this is why they do not function as a hardware description language.
Using the proper subset of virtually any language, a software program called a

synthesizer can infer hardware logic operations from the language statements and

produce an equivalent netlist of generic hardware primitives to implement the specified

behavior. This typically requires the synthesizer to ignore the expression of any timing

constructs in the text. The two most widely-used and well-supported HDL varieties used

in industry are:
1. VHDL(VHSIC HDL)
2. Verilog

VHDL
VHDL(Very High Speed Integrated Circuit Hardware Description Language) is
commonly used as a design-entry language for field-programmable gate arrays and
application-specific integrated circuits in electronic design automation of digital circuits
VHDL is a fairly general-purpose language, and it doesn't require a simulator on
which to run the code. There are a lot of VHDL compilers, which build executable
binaries. It can read and write files on the host computer, so a VHDL program can be
written that generates another VHDL program to be incorporated in the design being
developed. Because of this general-purpose nature, it is possible to use VHDL to write a
testbench that verifies the functionality of the design using files on the host computer to
define stimuli, interacts with the user, and compares results with those expected. This is
similar to the capabilities of the Verilog language.
VHDL is not a case sensitive language. One can design hardware in a VHDL IDE
(such as Xilinx or Quartus) to produce the RTL schematic of the desired circuit. After
that, the generated schematic can be verified using simulation software (such as
ModelSim) which shows the waveforms of inputs and outputs of the circuit after
generating the appropriate testbench. To generate an appropriate testbench for a
particular circuit or VHDL code, the inputs have to be defined correctly. For example,
for clock input, a loop process or an iterative statement is required.
The key advantage of VHDL when used for systems design is that it allows the

behavior of the required system to be described (modeled) and verified (simulated)

before synthesis tools translate the design into real hardware (gates and wires). When a

VHDL model is translated into the "gates and wires" that are mapped onto a

programmable logic device such as a CPLD or FPGA, then it is the actual hardware

being configured, rather than the VHDL code being "executed" as if on some form of a

processor chip.

Both VHDL and Verilog emerged as the dominant HDLs in the electronics industry,
while older and less-capable HDLs gradually disappeared from use. But VHDL and
Verilog share many of the same limitations: neither HDL is suitable for analog/mixed-
signal circuit simulation. Neither possesses language constructs to describe recursively-
generated logic structures.

Verilog
Verilog is a hardware description language (HDL) used to model electronic systems.
The language supports the design, verification, and implementation of analog, digital,
and mixed-signal circuits at various levels of abstraction.
The designers of Verilog wanted a language with syntax similar to the C
programming language so that it would be familiar to engineers and readily accepted.
The language is case-sensitive, has a preprocessor like C, and the major control flow
keywords, such as "if" and "while", are similar. The formatting mechanism in the
printing routines and language operators and their precedence are also similar.
The language differs in some fundamental ways. Verilog uses Begin/End instead of
curly braces to define a block of code. The concept of time, so important to a HDL
won't be found in C.
The language differs from a conventional programming language in that the

execution of statements is not strictly sequential. A Verilog design consists of a

hierarchy of modules. Modules are defined with a set of input, output, and bidirectional

ports. Internally, a module contains a list of wires and registers. Concurrent and

sequential statements define the behavior of the module by defining the relationships

between the ports, wires, and registers. Sequential statements are placed inside a

begin/end block and executed in sequential order within the block. But all concurrent

statements and all begin/end blocks in the design are executed in parallel, qualifying

Verilog as a Dataflow language. A module can also contain one or more instances of

another module to define sub-behavior.

A subset of statements in the language is synthesizable. If the modules in a design


contain only synthesizable statements, software can be used to transform or synthesize
the design into a netlist that describes the basic components and connections to be
implemented in hardware. The netlist may then be transformed into, for example, a form
describing the standard cells of an integrated circuit (e.g. an ASIC) or a bitstream for a
programmable logic device (e.g. a FPGA).
Describing a design
In VHDL an entity is used to describe a hardware module.
An entity can be described using,
1. Entity declaration.
2. Architecture.

Entity declaration:
It defines the names, input output signals and modes of a hardware module.
Syntax:
entity entity_name is
Port declaration;
end entity_name;

An entity declaration should starts with „entity‟ and ends with „end‟ keywords.
Ports are interfaces through which an entity can communicate with its environment.
Each port must have a name, direction and a type. An entity may have no port
declaration also. The direction will be input, output or inout.
In Port can be read
Out Port can be written
Inout Port can be read and written
Port can be read and written, it
Buffer
can have only one source.

Architecture:

It describes the internal description of design or it tells what is there inside design. Each
entity has atleast one architecture and an entity can have many architectures. Architecture
can be described using structural, dataflow, behavioral or mixed style.
Syntax:
architecture architecture_name of entity_name
architecture_declarative_part;
begin
Statements;
end architecture_name;
Here we should specify the entity name for which we are writing the architecture body.
The architecture statements should be inside the begin and end keyword. Architecture
declarative part may contain variables, constants, or component declaration.
The internal working of an entity can be defined using different modeling styles inside
architecture body. They are

1. Dataflow modeling.
2. Behavioral modeling.
3. Structural modeling.

Structure of an entity:

Dataflow modeling:
In this style of modeling, the internal working of an entity can be implemented
using concurrent signal assignment.
Consider a half adder as an example which is having one XOR gate and a AND
gate as shown below.

Library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ha is
port (A,B:in bit;S,C:out bit);
end ha;

architecture ha_arch of ha is
begin
S<=A xor B;
C<=A and B;

end ha_ar;

Here STD_LOGIC_1164 is an IEEE standard which defines a nine-value logic type,


called STD_ULOGIC. use is a keyword, which imports all the declarations from this
package. The architecture body consists of concurrent signal assignments, which
describes the functionality of the design. Whenever there is a change in RHS, the
expression is evaluated and the value is assigned to LHS.

Behavioral modeling:
In this style of modeling, the internal working of an entity can be implemented
using set of statements.
It contains:
 Process statements
 Sequential statements
 Signal assignment statements
Process statement is the primary mechanism used to model the behavior of an

entity. It contains sequential statements, variable assignment (:=) statements or signal

assignment (<=) statements etc. It may or may not contain sensitivity list. If there is an

event occurs on any of the signals in the sensitivity list, the statements within the

process are executed.

Inside the process the execution of statements will be sequential and if one entity
is having two processes the execution of these processes will be concurrent. At the end
it waits for another event to occur.

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ha is
port(
A : in BIT;
B : in BIT;
S : out BIT;
C : out BIT
);
end ha;

architecture ha_arch of ha is
begin
process(A,B)
begin
S<= A xor B;
C<=A and B;
end process;

end ha_arch;

Here whenever there is a change in the value of a or b the process statements are executed.
Structural modeling:
The implementation of an entity is done through set of interconnected components.
It contains:
 Signal Declaration
 Componet Instance
 Port Maps
 Wait Statement
Component declaration:
Syntax:
component component_name
List_of_interface ports;
end component component_name;

Before instantiating the component it should be declared using component declaration


as shown above. Component declaration declares the name of the entity and interface of
a component.
Consider the example of full adder using 2 half adder and 1 OR gate.

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity fa is
port(A,B,Cin:in bit; SUM, CARRY:out bit);
end fa;

architecture fa_arch of fa is

component ha
port(A,B:in bit;S,C:out bit);
end component;

signal C1,C2,S1:bit;

begin
HA1:ha port map(A,B,S1,C1);
HA2:ha port map(S1,Cin,SUM,C2);
CARRY <= C1 or C2;
end fa_arch;

The program written for half adder in dataflow modeling is instantiated as


shown above. ha is the name of the entity in dataflow modeling. C1, C2, S1 are the
signals used for internal connections of the component which are declared using the
keyword signal. Port map is used to connect different components as well as connect
components to ports of the entity. Component instantiation is done as follows.
Component_label: component_name port map (signal_list);
Signal_list is the architecture signals which will be connected to component ports. This
can be done in different ways. What is declared above is positional binding. One more
type is the named binding. The above can be written as,
HA1:ha port map(A => A,B => B, S => S1 ,C => C1 );
HA2:ha port map(A => S1,B => Cin, S=> SUM, C => C2);

Design using HDL


The vast majority of modern digital circuit design revolves around an HDL
description of the desired circuit, device, or subsystem.
Most designs begin as a written set of requirements or a high-level architectural

diagram. The process of writing the HDL description is highly dependent on the

designer's background and the circuit's nature. The HDL is merely the 'capture

language'—often begin with a high-level algorithmic description such as MATLAB or a

C++ mathematical model. Control and decision structures are often prototyped in

flowchart applications, or entered in a state-diagram editor. Designers even use scripting

languages (such as PERL) to automatically generate repetitive circuit structures in the

HDL language. Advanced text editors (such as Emacs) offer editor templates for

automatic indentation, syntax-dependent coloration, and macro-based expansion of

entity/architecture/signal declaration.

As the design's implementation is fleshed out, the HDL code invariably must

undergo code review, or auditing. In preparation for synthesis, the HDL description is

subject to an array of automated checkers. The checkers enforce standardized code

guidelines, identifying ambiguous code constructs before they can cause

misinterpretation by downstream synthesis, and check for common logical coding

errors, such as dangling ports or shorted outputs.

In industry parlance, HDL design generally ends at the synthesis stage. Once the

synthesis tool has mapped the HDL description into a gate netlist, this netlist is passed

off to the back-end stage. Depending on the physical technology (FPGA, ASIC gate-

array, ASIC standard-cell), HDLs may or may not play a significant role in the back-end

flow. In general, as the design flow progresses toward a physically realizable form, the

design database becomes progressively more laden with technology-specific

information, which cannot be stored in a generic HDL-description. Finally, a silicon

chip is manufactured in a fab.


Simulating & debugging HDL code
Essential to HDL design is the ability to simulate HDL programs. Simulation
allows a HDL description of a design (called a model) to pass design verification, an
important milestone that validates the design's intended function (specification) against
the code implementation in the HDL description. It also permits architectural
exploration. The engineer can experiment with design choices by writing multiple
variations of a base design, then comparing their behavior in simulation. Thus,
simulation is critical for successful HDL design.

To simulate an HDL model, an engineer writes a top-level simulation environment


(called a testbench). At minimum, a testbench contains an instantiation of the model
(called the device under test or DUT), pin/signal declarations for the model's I/O, and a
clock waveform. An HDL simulator—the program that executes the testbench—
maintains the simulator clock, which is the master reference for all events in the
testbench simulation. Events occur only at the instants dictated by the testbench HDL,
or in reaction to stimulus and triggering events.
Design verification is often the most time-consuming portion of the design

process, due to the disconnect between a device's functional specification, the designer's

interpretation of the specification, and the imprecision of the HDL language. The

majority of the initial test/debug cycle is conducted in the HDL simulator environment,

as the early stage of the design is subject to frequent and major circuit changes. An HDL

description can also be prototyped and tested in hardware—programmable logic devices

are often used for this purpose. Hardware prototyping is comparatively more expensive

than HDL simulation, but offers a real-world view of the design. Prototyping is the best

way to check interfacing against other hardware devices, and hardware prototypes, even

those running on slow FPGAs, offer much faster simulation times than pure HDL

simulation.
Requirements & Procedure
Requirements:
1. HDL software with both front-end and backend (Design entry, synthesis,
simulation, implementation and programming)
2. FPGA kit with minimum 400,000 gate density
Procedure:
Software part
1. Click on the Project navigator icon on the desktop of your PC. Write the vhdl code,
check syntax and perform the functional simulation using ModelsimXE.
2. Open a new UCF file and lock the pins of the design with FPGA I/O pins.
3. Implement the design by double clicking on the implementation tool selection.
4. Check the implementation reports.
5. Create programming file.
1. VHDL code for Logic Gates

A logic gate performs a logical operation on one or more logic inputs and
produces a single logic output. The logic normally performed is Boolean logic and is
most commonly found in digital circuits.
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity gates is
Port ( A,B : in std_logic;
ynor : out std_logic;
ynand, yxor, yxnor : out std_logic );
end gates;
architecture Behavioral of gates is
begin
ynot <= not A;
yor <= A or B;
yand <= A and B;
ynor <= A nor B;
ynand <= A nand B;
yxor <= A xor B;
yxnor <= A xnor B;
end Behavioral;
2. VHDL code for Combinational Circuits :

2-4 Decoder
A decoder is a multiple-input, multiple-output logic circuit that converts data
inputs from one form to another form, where the input and output codes are different.
e.g. n-to-2n. Enable inputs must be ON for the decoder to function, otherwise its outputs
assume a single "disabled" output code word.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Decoder2_4 is
port (
Enable: in STD_LOGIC;
Din: in STD_LOGIC_VECTOR (1 downto 0);
Dout: out STD_LOGIC_VECTOR (3 downto 0));
end decoder2_4;
architecture Decoder_arc of Decoder2_4 is
begin
process (Enable,Din)
begin
if (Enable = '1') then
Dout <= "0000";
else
case Din is
when "00" => Dout <= "0001";
when "01" => Dout <= "0010";
when "10" => Dout <= "0100";
when "11" => Dout <= "1000";
when others => NULL;
end case;
end process;
end decoder2_4;
8-3 Encoder (without priority)
Encoders are also similar to decoders that convert one binary code to

another. In encoders the number of input lines is more than the number of output

lines. e.g. 2n -to- n.

Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Encoder is
port ( EN: in STD_LOGIC;
Din: in STD_LOGIC_VECTOR(7 downto 0);
Dout: out STD_LOGIC_VECTOR(2 downto 0) );
end Encoder;
architecture encoder_arch of encoder is
begin
process(EN,Din)
begin
if ( EN = '1') then
Dout <= "ZZZ";
else
case Din is
when "00000001" => Dout <= "000";
when "00000010" => Dout <= "001";
when "00000100" => Dout <= "010";
when "00001000" => Dout <= "011";
when "00010000" => Dout <= "100";
when "00100000" => Dout <= "101";
when "01000000" => Dout <= "110";
when "10000000" => Dout <= "111";
when others => NULL;
end case;
end if;
end process;
end encoder_arch;

3 Encoder (with priority)

In a general encoder (without priority) it is possible that when more than one
inputs is high there may be an error in the output code, this problem is overcome by an
encoder with priority. Observe in the table given below higher order bits have higher
priority, E.g.: If y(2) is 1 then irrespective of the values of y(1) & y(0) output is 010.
Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity prtenc is
Port ( en : in STD_LOGIC;
din : in STD_LOGIC_VECTOR (07downto 00);
dout : out STD_LOGIC_VECTOR (02downto 00));
end prtenc;
architecture Behavioral of prtenc is
begin
dout<="000" when (en='1') else
"111" when din(7)='1' else
"110" when din(6)='1' else
"101" when din(5)='1' else
"100" when din(4)='1' else
"011" when din(3)='1' else
"010" when din(2)='1' else
"001" when din(1)='1' else
"000";
end Behavioral;

8-1 Multiplexer
A multiplexer or mux is a device that performs multiplexing; it selects one of
many analog or digital input signals and outputs that into a single line. A multiplexer
makes it possible for several signals to share one expensive device or other resource. A
multiplexer can be considered as a multiple-input, single-output switch.
Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Mux8 is
port ( SEL: in STD_LOGIC_VECTOR(2 downto 0);
A :in STD_LOGIC_VECTOR (7
downto 0); y: out STD_LOGIC );
end Mux8;

architecture mux8_arch of Mux8 is


begin
process (SEL,A)
begin
case SEL is
when "000" => Y <= A(0);
when "001" => Y <= A(1);
when "010" => Y <= A(2);
when "011" => Y <= A(3);
when "100" => Y <= A(4);
when "101" => Y <= A(5);
when "110" => Y <= A(6);
when "111" => Y <= A(7);
when others => null;
end case;
end process;
end mux8_arch;

4-Bit Binary To Gray Converter


The reflected binary code, also known as Gray code after Frank Gray, is a binary
numeral system where two successive values differ in only one digit. The reflected
binary code was originally designed to prevent spurious output from electromechanical
switches. Today, Gray codes are widely used to facilitate error correction.

Fig. Circuit Diagram


Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Binary_Gray is
port( b: in std_logic_vector(3 downto 0);
g: out std_logic_vector(3 downto
0)); end binary_gray;
architecture behavioral of
binary_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;
4-1 Demultiplexer
A demultiplexer (or demux) is a device taking a single input signal and selecting
one of many data-output-lines, which is connected to the single input. A multiplexer is
often used with a complementary demultiplexer on the receiving end
Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
entity Demux4 is
port ( din: in STD_LOGIC;
sel: in STD_LOGIC_VECTOR (1 downto 0);
dout: out STD_LOGIC_VECTOR (3 downto 0));
end Demux4;
architecture demux4_arch of Demux4 is
begin
process(din,sel)
begin
dout<="0000";
case sel is
when "00" => dout(0)<=din;
when "01" => dout(1)<=din;
when "10" => dout(2)<=din;
when “11” => dout(3)<=din;
when others => null;
end case;
end process;
end demux4_arch;
4-bit Comparator
A digital comparator is a hardware electronic device that compares two numbers
in binary form and generates a one or a zero at its output depending on whether they are
the same or not. Comparators can be used in a central processing unit (CPU)

Note: AEB---A=B, AGB---A>B, ALB---A<B


Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity comp is
Port( A,B: in STD_LOGIC_VECTOR(4 downto 0);
ALB,AGB,AEB: out STD_LOGIC);
end comp;
architecture Comp_arc of comp is
begin
process(A,B)
begin
if ( A < B ) then ALB <= '1';
else ALB <= '0';
end if;
if ( A > B ) then AGB <= '1';
else AGB <= '0';
end if;
if ( A = B ) then AEB <= '1';
else AEB <= '0';
end if;
end process;
end Comp_arc;

Full Adder

Structural modeling:
The full-adder circuit adds two one-bit binary numbers with carry in and outputs
two one-bit binary numbers, a sum and a carry out.
Code

Half Adder
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Ha is
Port ( X, Y : in std_logic;
S, C : out std_logic);
end Ha;
architecture Behavioral of Ha is
begin
S <= X xor Y;
C<= X and Y;
end Behavioral;
- Full
Adder
library
IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use
IEEE.STD_LOGIC_ARITH.ALL;
use
IEEE.STD_LOGIC_UNSIGNED.AL
L; entity FA is
Port ( A,B,Cin : in std_logic;
Sum,Cout : out
std_logic); end FA; architecture Behavioral of FA is
Component Ha Port ( X,Y : in std_logic;
S,C : out std_logic);
end Component;
Signal temp1,temp2, temp3:
std_logic; begin
L1: Ha port map( A,B,temp1,temp2);
L2: Ha port
map( temp1,Cin,Sum,temp3); Cout
<= temp2 or temp3;
end Behavioral;
Dataflow modeling

Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity FA is
Port ( A,B,Cin : in std_logic;
Sum,Cout : out std_logic);
end FA;
architecture Behavioral of FA is
begin
sum<= a xor b xor cin;

cout<= ((a xor b) and cin )or (a and b);

end behavioural;
Behavioral modeling

Code:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity FA is
Port ( abcin : in std_logic_vector(2 downto 0);
sum,cout : out std_logic);
end FA;
architecture Behavioral of FA is
begin
process(abcin)
begin
case abcin is
when"000"=>sum<='0';cout<='0';
when"001"=>sum<='1';cout<='0';
when"010"=>sum<='1';cout<='0';
when"011"=>sum<='0';cout<='1';
when"100"=>sum<='1';cout<='0';
when"101"=>sum<='0';cout<='1';
when"110"=>sum<='0';cout<='1';
when"111"=>sum<='1';cout<='1';
when others=>null;
end case;
end process;
end Behavioral;
32-bit ALU

An arithmetic logic unit (ALU) is a digital circuit that performs arithmetic (eg:
addition, subtraction,...) and logical operations (eg: and, or,...). The ALU is a
fundamental building block of the central processing unit (CPU) of a computer, and
even the simplest microprocessors contain at least one. The processors found inside
modern CPUs have inside them very powerful and very complex ALUs, a single
component may contain a number of ALUs.
Code for 32-bit ALU (for simulation only):

VHDL

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

entity alu is
Port ( a,b : in std_logic_vector(31 downto 0);
opcode : in std_logic_vector(3 downto 0);
cout : out std_logic:='0';
en : in std_logic;
y : out std_logic_vector(31 downto 0));
end alu;

architecture Behavioral of alu is


begin
process(a,b,en,opcode)
variable temp:std_logic_vector(32 downto 0);
begin
if (en='1') then
case opcode is
when "0001"=>temp:=('0'&a) + ('0'&b);
when "0010"=>temp:=('0'&a) - ('0'&b);
when "0011"=>temp(31 downto 0):=not a;
when "0100"=>temp:=a(15 downto 0) * b(15
downto 0);
when "0101"=>temp(31 downto 0):=a and b;
when "0110"=>temp(31 downto 0):=a or b;
when "0111"=>temp(31 downto 0):=a nand b;
when "1000"=>temp(31 downto 0):=a xor b;
when others=>null;
end case;
y<=temp(31 downto 0); cout<=temp(32);
temp(32):='0';
7-bit ALU:
Code for 7-bit ALU (for FPGA or LA or simulation):

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

entity alu is
Port ( a,b : in std_logic_vector(6 downto 0);
opcode : in std_logic_vector(3 downto 0);
cout : out std_logic:='0';
en : in std_logic;
y : out std_logic_vector(6 downto 0));
end alu;

architecture Behavioral of alu is


begin
process(a,b,en,opcode)
variable temp:std_logic_vector(7 downto 0);
begin
if (en='1') then
case opcode is
when "0001"=>temp:=('0'&a) + ('0'&b);
when "0010"=>temp:=('0'&a) - ('0'&b);
when "0011"=>temp(6 downto 0):=not a;
when "0100"=>temp(7 downto 0):=a(3 downto 0)
* b(3 downto 0);
when "0101"=>temp(6 downto 0):=a and b;
when "0110"=>temp(6 downto 0):=a or b;
when "0111"=>temp(6 downto 0):=a nand b;
when "1000"=>temp(6 downto 0):=a xor b;
when others=>null;
end case;
y<=temp(6 downto 0); cout<=temp(7);
temp(7):='0';
else y<=(others => 'Z');
end if;
end process;
end Behavioral;

3. Flip flops
A flip-flop is a bistable multivibrator, an electronic circuit that has two stable
states and thereby is capable of serving as one bit of memory.
A flip-flop is usually controlled by one or two control signals and/or a gate or
clock signal. The output often includes the complement as well as the normal output.

SR-flip flop

The most fundamental flip flop is the SR flip-flop, where S and R stand for set
and reset. Normally, in storage mode, the S and R inputs are both low, and feedback
maintains the Q and Qb outputs in a constant state, with Qb the complement of Q. If S
(Set) is pulsed high while R is held low, then the Q output is forced high, and stays high
even after S returns low; similarly, if R (Reset) is pulsed high while S is held low, then
the Q output is forced low, and stays low even after R returns low.

Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SRFF is
port ( clk,s,r: in bit;
q,qb: buffer std_logic );
end SRFF;
architecture srff_arch of SRFF is
begin
process(clk)
variable temp:std_logic;
begin
if (clk='1' and clk'event) then
if(s='0' and r='0')then temp:=temp;
elsif(s='0' and r='1')then temp:='0';
elsif(s='1' and r='0')then temp:='1';
elsif (s='1' and r='1')then temp:='Z';
end if;end if;
q<=temp;
qb<=not temp;
end process;
end srff_arch;

D- flip flop

The Q output always takes on the state of the D input at the moment of a rising
clock edge or at the moment of the falling clock edge but not both at the falling and
rising edges and never at any other time. It is called the D flip-flop for this reason, since
the output takes the value of the D input or Data input, and Delays it by one clock
count. The D flip-flop can be interpreted as a primitive memory cell or delay line.
Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity dff is
port ( clk,d: in STD_LOGIC;
q,qb: inout STD_LOGIC );
end dff;
architecture dff_arch of dff is
begin
process(clk)
begin
if(clk'event and clk='1')then
q<=d;qb<=not q;
end if;
end process;
end dff_arch;

JK-flip flop

The JK flip-flop augments the behavior of the SR flip-flop by interpreting the


S=R=1 condition as a "flip" or toggle command. Specifically, When J=1, K=0 output, Q
is set; when J= 0, K = 1 output, Q is reset; and when J=K=1 output, Q toggles, i.e.,
change its output to the complement of its current state. Setting J=K=0 will hold the
current state. To synthesize a D flip-flop, simply set K equal to the complement of J. To
synthesize a T flip-flop, simply set K equal J. The JK flip-flop is therefore a universal
flip-flop, because it can be configured to work as a D flip-flop or a T flip-flop

Code:
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity JKFF is
port ( clk,J,k : in std_logic;
q,qb : inout std_logic );
end JKFF;
architecture jkff_arch of JKFF is
begin
process(clk)
variable temp:std_logic;
begin
if(clk'event and clk='1')then
if(j='0' and k='0') then temp:=temp;
elsif(j='0' and k='1') then temp:='0';
elsif(j='1' and k='0') then temp:='1';
elsif(j='1' and k='1') then temp:=not temp;
end if;
end if;
q<= temp;
qb<= not temp;
end process; end jkff_arch;

T-flip flop

If the T input is low, the flip-flop holds the previous value. If the T input is high,
the T flip-flop changes state ("toggles") whenever the clock input is strobed. This
behavior is described by the characteristic equation:

or
Code(for simulation & LA only):

VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tff is
Port ( t,clk : in STD_LOGIC;
q : inout
STD_LOGIC:='0'; qb :
inout STD_LOGIC:='1');
end tff;
architecture Behavioral of tff is
begin
process(clk)
begin
if(clk'event and clk='1') then
if(t='0') then q<=q;
elsif(t='1') then q<=not q;
end if;
end if;
end process;
qb<=not q;
end Behavioral;
5 Synchronous reset Counter (Mod 16 for simulation & LA Without CLK
Division)
In digital logic and computing, a counter is a device which stores (and sometimes
displays) the number of times a particular event or process has occurred, often in
relationship to a clock signal. In practice, there are two types of counters:
a. up counters which increase (increment) in value
b. down counters which decrease (decrement) in value
Synchronous reset Counter is one in which the output is reset only if reset signal is
high and clock is triggered simultaneously. Here clock is positive edge triggered. Mod
16 up counter is one which counts up from 0 to 15 then goes back to the initial state.

Code:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sync_counter is
port( CLK: in STD_LOGIC; RESET: in STD_LOGIC;
COUNT: out STD_LOGIC_VECTOR( 3
DOWNTO 0)); end sync_counter;
architecture counter_arch of sync_counter is
signal TEMP:STD_LOGIC_VECTOR( 3
DOWNTO 0); begin
process (CLK)
begin
if CLK='1' and CLK'event then
if RESET='1' then --Synchronous reset
TEMP <= “0000”;
ELSE
TEMP <= TEMP + 1;
end if;
end if;
COUNT<= TEMP;
end process;
end counter_arch;
Asynchronous reset Counter (Mod 16 for simulation & LA Without CLK Division)

Asynchronous reset Counter is one in which the output is reset if reset signal
is high irrespective of the status of clock.
Code:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sync_counter is
port( CLK: in STD_LOGIC; RESET: in
STD_LOGIC; COUNT: out
STD_LOGIC_VECTOR( 3 DOWNTO 0));
end sync_counter;
architecture counter_arch of sync_counter is
begin
process (CLK)
variable TEMP:STD_LOGIC_VECTOR( 3
DOWNTO 0):="0000";
begin
if RESET='1' then --asynchronous reset
TEMP := "0000";
Else
if (CLK='1' and CLK'event) then
TEMP := TEMP + 1;
end if;
end if;
COUNT<= TEMP;
end process;
end counter_arch;
Mod 6 down Counter (for sim & LA Without CLK Division)
Mod 6 down counter is one which counts down from 5 to 0 then goes back to the
initial state
initial state.

Code:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity counter is
port( CLK, RESET: in STD_LOGIC;
COUNT: out STD_LOGIC_VECTOR( 3
DOWNTO 0));
end counter;
architecture counter_arch of counter is
begin
process (CLK)
variable TEMP:STD_LOGIC_VECTOR( 3
DOWNTO 0):="0101";
begin
if CLK='1' and CLK'event then
if RESET='1' then --Synchronous reset
TEMP := "0000";
elsif(temp="0000") then
temp:="0101";
else
TEMP := TEMP - 1;
end if;
end if;
COUNT<= TEMP;
end process;
end counter_arch;
Synchronous counter (Mod 16 with clock division for FPGA only)

Code:
VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sync_counter is
port( CLK, RESET: in STD_LOGIC; COUNT: out
STD_LOGIC_VECTOR( 3 DOWNTO 0));
end sync_counter;
architecture counter_arch of sync_counter is
signal TEMP:STD_LOGIC_VECTOR( 3 DOWNTO 0);
signal dclk:STD_LOGIC_VECTOR(20 DOWNTO 0);
begin
process(CLK)
begin
if rising_edge(CLK) then
dclk<=dclk+‟1‟;
end if;
end process;
process (dclk(18))
begin
if rising_edge(dclk(18)) then
if RESET='1' then --Synchronous reset
TEMP <= (OTHERS=>'0');
ELSE
TEMP <= TEMP + 1;
end if;
end if;
COUNT<= TEMP;
end process;
end counter_arch;
Asynchronous counter (Mod 16 with clock division for FPGA only)
Code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sync_counter is

port( CLK,RESET: in STD_LOGIC; COUNT:


out STD_LOGIC_VECTOR( 3 DOWNTO 0));
end sync_counter;
architecture counter_arch of sync_counter is
signal TEMP:STD_LOGIC_VECTOR( 3 DOWNTO 0);
signal dclk:STD_LOGIC_VECTOR(20 DOWNTO 0);
begin
process(CLK)
begin
if rising_edge(CLK) then
dclk<=dclk+1;
end if;
end process;
process (dclk(18))
begin
if RESET='1' then --asynchronous reset
TEMP <= (OTHERS=>'0');
ELSE
If( dclk(18)='1' and dclk(18)'event) then
TEMP <= TEMP + 1;
end if;
end if;
COUNT<= TEMP;
end process;
end counter_arch;
4. Shift Register

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity
SFTLREG is
port(
din : in
STD_LOGIC; clk :
in STD_LOGIC;
reset : in
STD_LOGIC;
dout : out STD_LOGIC_VECTOR(3downto 0) );
end SFTLREG;
architecture Behavioral of SFTLREG is
begin
process (clk,din,reset) is
variable s : std_logic_vector(3 downto 0) :="0000" ;
begin
if (reset='1')
then s :="0000";
elsif (rising_edge (clk))
then s := (din & s(3downto 1));
end if;
dout<=s;
end process;
end Behavioral;
SHIFT RIGHT REGISTER

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

entity SHR is
port(
din : in
STD_LOGIC; clk :
in STD_LOGIC;
reset : in
STD_LOGIC;
dout : out STD_LOGIC_VECTOR(3downto 0) );
end SHR;

architecture Behavioral of SHRis


begin
process (clk,din,reset) is
variable s : std_logic_vector(3 downto 0) :="0000" ;
begin
if (reset='1')
then s :="0000";
elsif (rising_edge (clk))then
s := (s(2 downto 0)& din );
end if;
dout<=s;
end process;
end Behavioral;
BIDIRECTIONAL SHIFT REGISTERS

Entity BISFTREG is
port(din : inSTD_LOGIC;
clk : in STD_LOGIC;
m: inSTD_LOGIC;
reset : in STD_LOGIC;
dout : out STD_LOGIC_VECTOR(3downto 0) );
end BISFTREG;
architecture Behavioral of BISFTREG is
begin
process (clk,din,reset) is
variable s : std_logic_vector(3 downto 0) :="0000";
begin
if (reset='1')
then s :="0000";
elsif (rising_edge (clk)) then
else
end if;
if (m='1') then
s := (s(2 downto 0) & din );
s := (din & s(3downto 1));
end if;
dout <=s;
end process;
end Behavioral;
6. CLA

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

entity cla1 is
port (P : in std_logic_vector(3 downto 0);
G : in std_logic_vector(3 downto 0);
C : out std_logic_vector(3 downto 0);
cin : in std_logic);
end cla1;

architecture Behavioral of cla1 is


begin
C(0) <= G(0) or (P(0) and cin);
C(1) <= G(1) or (P(1) and G(0)) or (P(1) and P(0) and cin);
C(2) <= G(2) or (P(2) and G(1)) or (P(2) and P(1) and G(0)) or (P(2) and P(1)
and P(0) and cin);

C(3) <= G(3) or (P(3) and G(2)) or (P(3) and P(2) and G(1)) or (P(3) and P(2)
and P(1) and G(0)) or (P(3) and P(2) and P(1) and P(0) and cin);

end Behavioral;
7. Melay detector

Entity melay is
Port(x,clk,rst:in std_logic;
Z:out std_logic);
End melay;

Architecture melay1 of melay is


Type state is (reset,got1,got10);
Signal current:state:=reset;
Begin

Process(clk,rst)
Begin
If rst=’1’ then
Current<=reset;
Elsif rising_edge(clk) then
Case current is
When reset => If x=’1’ then current <=got1;
Else current<=reset;
End if;
When got1=> If x=’1’ then current <=got1;
Else current <=got10;

End if;
When got10 => If x=’1’ then current <=got1;
Else current <=reset;
End if;
When others => current <=reset;

End case;
End if;
End process;

Z<= ‘1’ when(current =got10 and x=’1’)


else ‘0’;
End melay1;
Moore Detector

Entity moore is
Port(x,rst,clk:in std_logic;
z:out std_logic);
end moore;
Architecture moore1 of moore is
Type state is (reset,got1,got10,got101);
Signal current:state:=reset;
Begin
process(clk)
begin
if rising_edge(clk) then
if rst=’1’ then
current <=reset;
else
case current is
when reset=> if x=’1’ then current <=got1;
else current<=reset;
end if;
when got1=> if x=’0’ then current <=got10;
else current<=got1;
end if;
when got10=> if x=’1’ then current<=got101;
else current<=reset;
end if;
when got101=> if x=’1’ then current<=got1;
else current<=got10;
end if;
when others=>current<=reset;
end case;
end if;
end if;
end process;
z<=’1’ when current=got101 else ‘0’;
end moore1;
8. Booth multiplier

entity boot is
port(x,y:in std_logic_vector(3 downto 0);
o:out std_logic_vector(7 downto 0));
end boot;
architecture behavioural of boot is
begin
process(x,y)
variable a:std_logic_vector(8 downto 0);
variable s,p:std_logic_vector(3 downto 0);
variable i:integer;
begin
a:=”000000000”;
s:=y;
a(4 downto 1):=x;
for i in 0 to 3 loop
if(a(1)='1' and a(0)='0') then
p:=(a(8 downto 5));
a(8 downto 5):=(p-s);
else if (a(1)='0' and a(o)='1') then

p:=(a(8 downto 5));


a(8 downto 5):=(p+s);
end if;
a(7 downto 0):=a(8 downto 1);
end loop;
o(7 downto 0)<=a(8 downto 1);
end process;
end behaviroual;
9. Traffic light controller

entity trafic_light is
port(clk,sa,sb:in bit;
ra,rb,ga,gb,ya,yb:out bit);
end traffic_light;
architecture behaviroual of traffic_light is
signal state,next state:integer range 0 to12;
type light is(r,y,g);
signal lighta,lightb:light;
brgin
process(state,sa,sb)
begin
ra<='0';rb<='0';ga<='0';gb<='0';ya<='0';yb<='0';
case state is
when 0 to4=>ga<='1';rb<='1';
next state<=state+1;
when 5=>ga<='1';rb<='1';
if sb<='1' then nextstate<=6;
end if;
when 6=>ya<='1';rb<='1';nextstate<='7';
when 7to 10=>ra<='1';gb<='1';nextstate<=state+1;
when 11=>ra<='1';gb<='1';
if (sa<='1' or sb<='0') then nextstate<=12;
end if;
whren 12=>ra<='1';yb<='1';nextstate<=0;
end case;
end process;
process(clk)
begin
if clk='1' then state<= nextstate;
end if;
end process;
light a<=rwhen ra<='1' else y when ya='1' else g when
ga='1';
light b<=r when rb='1' else y when yb='1' else g when
gb='1';
end behavioural;
10. Addition of numbers from 0 to N

entity sum is
port(start:in std_logic;
done:out std_logic;
output: out integer);
end sum;

architecture sum1 of sum is


begin
process(start)
variuable n :integer;
variable sum:integer;
begin
if start='0' then
done<='0';
output<='0';
else
sum:=0;
n:=10;
for i in n downto 1 loop
sum:= sum+i;
end loop;
done<='1';
output<=sum;
end if;
end process;

You might also like