Anda di halaman 1dari 30

LAB 1:- Introduction to VHDL and FPGA designing

1) Introduction to FPGA:
A field-programmable gate array (FPGA) is an integrated circuit designed to be configured by the
customer or designerhence "field-programmable". The FPGA configuration is generally
specified using a hardware description language (HDL). A gate array, as its name suggests, is an
integrated circuit on which an array of logic gates has been created. FPGAs contain
programmable logic components called "logic blocks", and a hierarchy of reconfigurable
interconnects that allow the blocks to be "wired together". Logic blocks can be configured to
perform complex combinational functions, or merely simple logic gates like AND and XOR. In
most FPGAs, the logic blocks also include memory elements, which may be simple flip-flops or
more complete blocks of memory. We will focus on the most widely used and more popular
Spartan 3E family. The Spartan-3E family of Field-Programmable Gate Arrays (FPGAs) is
specifically designed to meet the needs of high volume, cost-sensitive consumer electronic
applications.

Sprtan 3E development board

2) Introduction to VHDL:
The VHSIC Hardware Description Language is an industry standard language used to describe
hardware from the abstract to the concrete level. The characteristic that distinguishes the HDL
from other programming languages is, as the name suggests any code written in a HDL generates
the virtual hardware for that code unlike c, c++. VHDL programming is similar to assembly level
programming, which requires elaborate programming and often prone errors. To make
programming much easier and user friendly some of the concepts of C Language were borrowed
resulting in very like C language called Verilog Hardware Description Language. Mostly highly
paid programmers in the world are VHDL developers.
Standard Development languages available for programming FPGAs are listed below:
VHDL (Very high speed integrated circuits Hardware Description Language).
Verilog (Very like C- Logic).
Handle C etc.

2.1) VHDL Programming:


VHDL programming consists of the following concepts:
Libraries:
Library ieee;
Use ieee.std_logic_1164.all;
Use ieee.std_logic_arith.all;
Use ieee.std_logic_signed.all;
Use ieee.std_logic_unsigned.all;
Data Types:
bit values: '0', '1'
boolean values: TRUE, FALSE
integer values: -(231) to +(231 - 1)
std_logic values: 'U','X','1','0','Z','W','H','L','-'
U' = uninitialized
'X' = unknown
'W' = weak 'X
'Z' = floating
'H'/'L' = weak '1'/'0
'-' = don't care

2.2) VHDL Examples:

2.3) VHDL Features:


Case insensitive - inputa, INPUTA and InputA are refer to same variable
Comments -- until end of line
If you want to comment multiple lines, -- need to be put at the beginning of every single line
Statements are terminated by ;
Signal assignment:

<=

User defined names: letters, numbers, underscores (_).start with a letter.

VHDL Structure:
Library - Definitions, constants
Entity - Interface
Architecture - Implementation, function
VHDL is rich in language abstractions. Abstractions are description of design in different
method. The different methods are given below:
Structural Description Method: expresses the design as an arrangement of interconnected
components It is basically schematic.
Behavioral Description Method: describes the functional behavior of a hardware design in
terms of circuits and signal responses to various stimuli. The hardware behavior is described
algorithmically.
Data-Flow Description Method: is similar to a register-transfer language. This method describes
the function of a design by defining the flow of information from one input or register to another
register or output.

3) Lab 1
3.1) LAB 1 Introduction
As described earlier VHDL is used as designing language for FPGA design and is
abbreviation of Very High Speed Integrated Circuit Design Hardware Description
Language. Mostly highly paid programmers in the world are VHDL developers. VHDL is
used in real-time systems and provides time resolution in nano-seconds. Familiarize
yourself with Xilinx 8.x software and make new project with name Lab1. You must save
files from this lab for future lab.
3.2) VHDL Terms
3.2.1) Entity
Entity is any object in VHDL which take some input/inputs process it and give some
output/outputs. Entity interfaces itself with outside world.
3.2.2) Architecture
It is behavior of entity or underlying functionality of entity.

3.2.3) Signal
Any internal variable in VHDL is called a signal.
3.2.4) Process
It is execution of instruction.

4) Syntax Details
Write all reserve keywords in capital letters like ENTITY, IN, OUT, ARCHITECTURE,
PORT etc.
Declarations in ENTITY are accessible in architecture.
There is no specific ordering of assignments/statements in VHDL unlike C/C++ and
Matlab. VHDL enables concurrent processing.
Signal/Variable assignment in VHDL is done by <= symbol rather than = sign as in
Matlab.
VHDL enables event scheduling DELAY in nano-seconds.
There are many ways to perform the same task.
5) Task
Implement OR gate VHDL code and test it. (Hint: And gate code is given change the
code to make it OR gate code)

6) Hints
Signal assignment
A<=b; (assigns value of b to a)
A<=b after 10ns; (assigns value of b to a and give output after 10 ns)
Above statements will be executed whenever b changes its value.
Read the code given and make 2 files, create files in project you have made with name
Lab1:
AND GATE CODE (name file as andGate)
library ieee;
use ieee.std_logic_1164.all;
--ENTITY DECLARATION: name, inputs, outputs

entity andGate is
port( A, B : in std_logic;
F : out std_logic);
end andGate;
--FUNCTIONAL DESCRIPTION: how the AND Gate works
architecture func of andGate is
begin
F <= A and B;
end func;

AND GATE TEST CODE (name file as andGate_tb)


library ieee;
use ieee.std_logic_1164.all;
entity andGate_tb is
end andGate_tb;
-- Describe how to test the AND Gate
architecture tb of andGate_tb is
component andGate is
port( A, B : in std_logic;
F : out std_logic);
end component;
signal inA, inB, outF : std_logic;
begin
mapping: andGate port map(inA, inB, outF);
process
variable errCnt : integer := 0;
begin
--TEST 1
inA <= '0';
inB <= '0';
wait for 15 ns;
assert(outF = '0') report "Error 1"
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
--TEST 2
inA <= '0';
inB <= '1';
wait for 15 ns;
assert(outF = '0') report "Error 2"
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
--TEST 3
inA <= '1';
inB <= '1';
wait for 15 ns;
assert(outF = '1') report "Error 3"
if(outF /= '1') then
errCnt := errCnt + 1;
end if;

severity error;

severity error;

severity error;

-------------- SUMMARY ------------if(errCnt = 0) then


assert false report "Good!" severity note;
else
assert true report "Error!" severity error;
end if;
end process;
end tb;

Simulation Results for Lab1

Lab 2 Half-Adder Digital Circuit

1) Introduction
A half-adder circuit takes two 1-bit inputs and adds them together. The output of the
circuit is sum out and carry-out bits. So the circuit has two inputs and two outputs. Half
adder doesnt take carry in and there are more than one digital logic circuits having
functionality of a half-adder. Given below are the two constructions of half-adders.

Figure 1 (Half-Adder)

Figure 2 (Half-Adder an alternate construction)

2) Tasks
2.1) Design a circuit in VHDL with functionality of half-adder according to construction
as given in figure 1. You also need to make test bench for this and check if your output is
consistent.
2.2) now change your circuit to figure 2 and show from output that both digital circuits
are equivalent.
2.3) when your half-adder of figure 2 works fine and is checked by test-bench file.
Change order of lines in Architecture implementing figure 2 and convince each other that
order of lines are un-important in this particular task. Why?
3) Hints
You only need to make 1 test bench file for both tasks.
You may also write figure 1 entity module first and when it works and is checked by testbench and simulations, change your architecture to figure 2.
Take help from AndGate_tb test-bench file to create test bench for half adder.

The command if (Cout /= '1' or Sout/= '0') is useful. Where Cout is Carry-Out and Sout is
Sum-Out for your half-adder.
AND GATE TEST CODE (name file as andGate_tb)
library ieee;
use ieee.std_logic_1164.all;
entity andGate_tb is
end andGate_tb;
-- Describe how to test the AND Gate
architecture tb of andGate_tb is
component andGate is
port( A, B : in std_logic;
F : out std_logic);
end component;
signal inA, inB, outF : std_logic;
begin
mapping: andGate port map(inA, inB, outF);
process
variable errCnt : integer := 0;
begin
--TEST 1
inA <= '0';
inB <= '0';
wait for 15 ns;
assert(outF = '0') report "Error 1"
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
--TEST 2
inA <= '0';
inB <= '1';
wait for 15 ns;
assert(outF = '0') report "Error 2"
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
--TEST 3
inA <= '1';
inB <= '1';
wait for 15 ns;
assert(outF = '1') report "Error 3"
if(outF /= '1') then
errCnt := errCnt + 1;
end if;

severity error;

severity error;

severity error;

-------------- SUMMARY ------------if(errCnt = 0) then


assert false report "Good!" severity note;
else
assert true report "Error!" severity error;
end if;
end process;
end tb;

Simulation Results for Lab 2

Output and inputs of a Unit Half adder (s is for sum and c is for carry, note that it
adds you bits a and b)

Lab 3 Full-Adder Digital Circuit

1) Introduction

Just like a half-adder circuit that takes two 1-bit inputs, adds them together and the output
of half-adder circuit is sum out and carry-out bits. So the circuit has two inputs and two
outputs. This can be useful only for least significant bits. For more than one bit system
the operation of addition will require full adder circuit. A full adder circuit takes 3 inputs,
two one bit binaries and one bit of carry-in and gives 2 output bits namely sum and carry
out. One can connect carry-out of one adder to carryin of another full-adder and can add
two binaries with increasing number of bits. The output will be carry-out of most
significant bit and sum bits.

Figure 1 (Full-Adder)
2) Tasks
2.1) Design a circuit in VHDL with functionality of full-adder according to construction
as given in figure 1. You also need to make test bench for this and check if your output is
consistent.

3) Hints

Take help from adder_tb_vhd test-bench file to create test bench for full-adder.
There will be minimum 6 tests for a full-adder. You can use your test bench code for
half-adder and one example is also given below.
The command if (Cout /= '1' or Sout/= '0') is useful. Where Cout is Carry-Out and Sout is
Sum-Out for your half-adder/full-adder.
HALF-ADDER TEST CODE (name file as adder_tb_vhd)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY adder_tb_vhd IS
END adder_tb_vhd;
ARCHITECTURE behavior OF adder_tb_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT adder
PORT(
a : IN std_logic;
b : IN std_logic;
s : OUT std_logic;
c : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL ina : std_logic := '0';
SIGNAL inb : std_logic := '0';
--Outputs
SIGNAL sout : std_logic;
SIGNAL cout : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
Mapping: adder PORT MAP (ina,inb,sout,cout);
tb : PROCESS
Variable errCnt:integer:=0;
BEGIN
inA <= '0';
inB <= '0';
wait for 15 ns;

assert(cout = '0' and sout='0') report "Error 1" severity error;


if(cout /= '0' or sout/='0') then
errCnt := errCnt + 1;
end if;
--TEST 2
inA <= '0';
inB <= '1';
wait for 15 ns;
assert(cout = '0' and sout='1') report "Error 2" severity error;
if(cout /= '0' or sout/='1') then
errCnt := errCnt + 1;
end if;
--TEST 3
inA <= '1';
inB <= '1';
wait for 15 ns;
assert(cout = '1' and sout='0') report "Error 3" severity error;
if(cout /= '1' or sout/='0') then
errCnt := errCnt + 1;
end if;

if(errCnt = 0) then
assert false report "Good!"
else
assert true report "Error!"
end if;

END PROCESS;
END;

severity note;
severity error;

Simulation Results for Lab 3

Output and inputs of a Unit Full adder adder (s is for sum and cin is for carry in,
cout is carry out, note that it adds two bits a and b and carry in cin)

Lab 4 Multiplexers
1) Introduction

Multiplexer is a logic circuit usually used to select one output from many inputs. The
multiplexer have many inputs including input channels and selection bits and usually one
output. 2-bit (2 selection bits) multiplexer can have 4 input channels and is able to give
output of any of the four channels; it is also written as 4-to-1 Mux. Multiplexer is
essential component for microprocessors, FPGAs and other digital devices. Multiplexer
takes instructions on its selection bits and depending upon this input; it controls or selects
output from some specific units like shift registers or binary adder components.
Furthermore, addressing in digital world is actually a multiplexing where addresses are
taken as selection bits input and depending upon these bits physical memory sources
input channels are given binaries to save in itself. Thus, to develop your own processor
you must understand thoroughly the working of multiplexers.

Figure 1 (4-to-1 Multiplexer)

2) Tasks
2.1) Design a multiplexer in VHDL according to construction as given in figure 1. You
also need to make test bench for this and check if your output is consistent. Can you
devise a method for its test bench? (Hint: you dont need to have error count etc or any
other messages statements in test bench, send 1 on some input channel and 0 on all others
and try to check which sequence of selection bits give you output 1, just verify the output
by simulation)
2.2) another person came and made multiplexer as given in hints; verify that his
multiplexer works by using the same test bench. (Hint: you only need to rename some
inputs or check the order of selection bits)
3) Optional Task
3.1) can you make logic circuit on paper of 4-to-1 multiplexer by using two 2-to-1
multiplexers?

4) Hints

Keep order of selection bits in mind when you implement circuit and when you do test
bench!
Make test bench for at least 2-3 cases.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mux2 is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
c : in STD_LOGIC;
d : in STD_LOGIC;
s0 : in STD_LOGIC;
s1 : in STD_LOGIC;
q : out STD_LOGIC);
end mux2;

architecture Behavioral of mux2 is


SIGNAL sel: INTEGER;
begin
WITH sel SELECT
q <= a AFTER 10 ns WHEN 0,
b AFTER 10 ns WHEN 1,
c AFTER 10 ns WHEN 2,
d AFTER 10 ns WHEN 3,
'X' AFTER 10 ns WHEN OTHERS;
sel <= 0 WHEN s0 = '0' AND s1 = '0' ELSE
1 WHEN s0 = '1' AND s1 = '0' ELSE
2 WHEN s0 = '0' AND s1 = '1' ELSE
3 WHEN s0 = '1' AND s1 = '1' ELSE
4;
end Behavioral;

Simulation Results for Lab 4

Testing of 4x1 multiplexer (note that only one channel input is made 1 at one time
and appropriate selection bits are also changed)

Lab 5 Adder Digital Circuit (4 bit adder)

1) Introduction

With half adder and full adders designed, one can easily scale it to multiple bits adder.
The LSB (Least significant bit) is a half-adder and all other bits are full-adders. One can
design a 4-bit adder from these components by connecting carry out of previous (Less
Significant) bit to carry in of next bit. Thus, we need to connect 4 adder including one
half-adder and three full adders as shown in figure below. VHDL provides solution to
scaling of bits of any system. We can connect various components and can increase bits
in our ALU (Arithmetic and Logic Unit) and registers etc.

Figure 1 (a 4-bit Adder)


2) Tasks
2.1) Design a 4-bit adder by using one half adder and three full adders. Verify it with help
of given test bench. (Half adder and full adders code is given along with test bench of 4bit adder)

2.2) Can you make 8-bit adder from this 4 bits adder? Why?

3) Hints

Make first a half-adder and full adder circuits in separate files. Add these as components
in VHDL circuit module, you need only add full adder only one time. Your mapping for
different inputs/output will replicate components on your final FPGA design. Your
solution must contain 4 files including one test bench files.
See closely add4tb_vhd (4 bit adder circuit test bench)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY add4tb_vhd IS
END add4tb_vhd;
ARCHITECTURE behavior OF add4tb_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT add4
PORT(
a0 : IN std_logic;
a1 : IN std_logic;
a2 : IN std_logic;
a3 : IN std_logic;
b0 : IN std_logic;
b1 : IN std_logic;
b2 : IN std_logic;
b3 : IN std_logic;
s0 : OUT std_logic;
s1 : OUT std_logic;
s2 : OUT std_logic;
s3 : OUT std_logic;
c : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL a0 :
SIGNAL a1 :
SIGNAL a2 :
SIGNAL a3 :
SIGNAL b0 :
SIGNAL b1 :
SIGNAL b2 :
SIGNAL b3 :

std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic := '0';

--Outputs
SIGNAL s0 : std_logic;
SIGNAL s1 : std_logic;
SIGNAL s2 : std_logic;
SIGNAL s3 : std_logic;
SIGNAL c : std_logic;

BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: add4 PORT MAP(
a0 => a0,
a1 => a1,
a2 => a2,
a3 => a3,
b0 => b0,
b1 => b1,
b2 => b2,
b3 => b3,
s0 => s0,
s1 => s1,
s2 => s2,
s3 => s3,
c => c
);
tb : PROCESS
BEGIN
a0<='1';
a1<='1';
a2<='0';
a3<='1';
b0<='0';
b1<='0';
b2<='1';
b3<='1';

-- Wait 100 ns for global reset to finish


wait for 10 ns;
-- Place stimulus here
wait; -- will wait forever
END PROCESS;
END;

HALF ADDER
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity halfadder is
Port ( aa : in STD_LOGIC;
bb : in STD_LOGIC;
ss : out STD_LOGIC;
cc : out STD_LOGIC);
end halfadder;

architecture Behavioral of halfadder is


begin
ss<= aa xor bb;
cc<= aa and bb;
end Behavioral;

FULL ADDER
entity fulladder is
Port ( a : in STD_LOGIC;
b : in STD_LOGIC;
cin : in STD_LOGIC;
s : out STD_LOGIC;
cout : out STD_LOGIC);
end fulladder;
architecture Behavioral of fulladder is
signal d,h,i:std_logic;
begin
d<= a xor b;
i<= a and b;
h<= a and cin;
s<= d xor cin;
cout<= h or i;
end Behavioral;

Simulation Results for Lab 5

Testing of 4-bit adder, note that you can change input numbers (a and b) and
validate output

LAB 6 Binary Counters


1) Introduction
One of the important components of Digital Integrated circuits, CPUs etc is the binary
counter. A binary counter is a digital device/component having ability to count digital
signals clock pulses. Usually, the clock signal gives logic 1 and 0 after specific period of
time. The time difference between two consecutive raising edges of clocks signal is
called clock period. Input/output of devices is synchronized by clocks signal.
A counter on other hands just increments with each 1 or 0 pulses of its input signal. We
will implement a basic counter with one binary input signal as clock and one input signal
called reset. When reset is 1 with clock raising edge the counter must transit back to its
initial state i.e. 0000 for four bits counter. The counters output in our case is four bit
number which increments with every raising edge. The number of bits of output of
counter is also called stage of counters e.g. a four bit counter is also called four stage
counter generally (as it also has flip-flop stages in its construction but here we will only
use registers and adders although the flip flop construction is more robust ).
We will use now some built in functionality of VHDL for example we dont need to write
4 bits adder for increments in counters value; we will just called addition operation.
Also, when we need to reset our counter we will just write synchronous statement giving
value of register as 0000.

Figure 1 and 2 (description of a counter)


2) Tasks
2.1) implement a 4 bit counter that takes input of clock signal and counts number of ON
pulses of clock. If reset is 1 with clock ON pulse, the counter must re-initialize to 0000
state. Write VHDL module as well as test bench file. You should generate clock signal in
test bench file only. You are only given with the description of a counter as given in the
figures. (Hint: - See code of clock given in hints section, use if else conditions in entity
file and use process)

3) Hints
Process (clock) in architecture of entity module will run every time when clock value is
changed.
Use if else within process (clock)
Clockevent and clock=1 is a useful command for if statement.
Variable COUNT: unsigned(3 downto 0) := "0000"; will initialize your 4-bit register to
0000 value.
COUNT := COUNT + 1; is a synchronous command
Following lines will generate clock pulses in clock signal.
for i in 1 to 12 loop
clk<='1';
wait for 10 ns;
clk<='0';
wait for 10ns;
end loop;

Simulation Results for Lab 6

Output of 4-bit counter (reset is off)

Output of 4-bit counter with reset on after some value

LAB 7 Delays in devices


1) Introduction
No device can work instantly; there is a delay in every device. A delay is a time interval
taken by device to give respective output for given input. There can be many types of
delay, a transport delay is delay related to transport of information, like through buffer etc
; this delay simply shift output by some time interval . Inertial delay is the delay specific
to some device and describes time it needs to update its output according to some input.
For example if you apply logic ones (at 0 ns) to input of AND gate and after 1 ns it gives
you logic one, then you can say the device has inertial delay of 1ns.
We will study the behavior of half adder under conditions of inertial delays. If your
device has inertial delay of 4 ns and you are giving it input pulse of 3ns it may never
update and if you give it pulse of more than 4 ns, than it will give you output after delay
of 4 ns and this output duration is at least for 4 ns, i.e. even if your inputs change during
that time.

Figure 1, Example of transport delay (use to model buss delays etc) (B _Out<= transport
B_IN after 1 ns;)

Figure 2, Example of inertial delay on 1 ns. (L_OUT<= inertial L_IN after 1 ns;)

2) Tasks
2.1) make a unit half adder from XOR and AND gate subject to the condition that XOR
gate has 4 ns inertial delay and AND gate has 5 ns inertial delay. Simulate and explain
your output as given in test bench code.
3) Hints
Look at the picture closely.
(TEST BENCH FOR HALFADDER WITH DELAYS)
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY halfaddertb_vhd IS
END halfaddertb_vhd;
ARCHITECTURE behavior OF halfaddertb_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT halfadder
PORT(
a : IN std_logic;
b : IN std_logic;
s : OUT std_logic;
c : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL a : std_logic := '0';
SIGNAL b : std_logic := '0';
--Outputs
SIGNAL s : std_logic;
SIGNAL c : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: halfadder PORT MAP(
a => a,

b => b,
s => s,
c => c
);
tb : PROCESS
BEGIN
a<='0';
b<='0';
wait for 6 ns;
a<='0';
b<='1';
wait for 6 ns;
a<='1';
b<='0';
wait for 4 ns;
a<='1';
b<='1';
wait for 3 ns;
a<='0';
b<='0';
wait for 6 ns;
wait; -- will wait forever
END PROCESS;
END;

Simulation Results for Lab7

Output of half adder with inertial delays

Anda mungkin juga menyukai