HDL Programming
Through
FPGA
Prepared by
Prof. Tejal Deshpande
Asst. Professor
EXTC Dept.
VHDL
VHDL <= VHSICHDL.
Very High Speed Integrated Circuit Hardware
Descriptive Language.
Use
Features
VHDL is …
Concurrent language
Sequential language
Netlist Language
Timing specification
Simulation language
Test language
Hierarchical language
Supports design libraries
Tool independent & portable
History
Instituteof Defense Analysis(IDA) had
arranged a workshop in 1981 to study
Various Hardware Description methods
Need for a standard language
A team of three companies,IBM,Texas
Instruments and Intermetrics were awarded
contract by DoD to develop a language.
Version 7.2 of VHDL was released in 1985
along with its LRM
Standardized by IEEE in 1987 as IEEE Std
1076-1987.
CAPABILITIES
Design specification
Design capture
Design simulation
Design documentation
Alternative to schematics
Alternative to proprietary languages
Why VHDL?
LEVELS OF ABSTRACTION
• ABSTRACTION
– It defines the details about the design
specified in a particular description.
• The levels of Abstraction …
– Behavioral level
– Register transfer level
– Logic level
– Layout level
Data Types
Data Types
STD LOGIC Data Type
• A 9 value package STD_LOGIC_1164
• ‘U’ : Un-initialized
• ‘X’ : Unknown
• ‘0’ : Logic 0
• ‘1’ : Logic 1
• ‘Z’ : High Impedance
• ‘W’ : Unknown
• ‘L’ : Low Logic 0
• ‘H’ : Low Logic 1
• ‘-’ : Don’t Care
A FIRST LOOK AT VHDL
Package Declaration
Package Body
Library Declaration
Entity Declaration
Architecture Declaration
Writing First Program
Entity Nand_dataflow is
Port ( a_in : in bit;
A_in
b_in : in bit;
Nand_o
Nand_out : out bit); ut
end Nand_dataflow;
B_in
Architecture dataflow of
Nand_dataflow is
Begin
nand_out <= a_in nand b_in;
end dataflow;
I/O PORTS
Mode “IN”
Value can be read but not assigned.
Mode “OUT”
Value can be assigned but not
read.
Mode “INOUT”
Value can be read and also
assigned.
Mode “BUFFER”
Value can be assigned and read
back.
13
VHDL PROGRAMMING
STYLES
1. Dataflow
2. Behavioral
3. Structural
DATAFLOW
BEHAVIORAL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
architecture Behavioral of
entity Nand_dataflow is Nand_behave is
Port ( a_in : in STD_LOGIC;
b_in : in STD_LOGIC; begin
Nand_out : out ---Process Statement
STD_LOGIC); nand_process :
end Nand_dataflow; Process(a_in,b_in) -------
Senesitivity List
architecture dataflow of begin
Nand_dataflow is if(a_in = '1' and b_in =
begin '1') then
nand_out <= a_in nand b_in; nand_out <= '0';
else
end dataflow; nand_out <= '1';
end if;
end process;
end Behavioral;
COMPONENTS
DEFINATION
library IEEE;
library ieee; use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_1164.all;
entity and_gate is entity not_gate is
port(a,b : in std_logic; y : out Port ( not_in : in STD_LOGIC;
std_logic ); not_out : out
end and_gate; STD_LOGIC);
end not_gate;
architecture and_gate_arch of
and_gate is architecture Behavioral of
begin not_gate is
y <= a and b;
end; begin
not_out <= not not_in;
end Behavioral;
STRUCTURAL
library IEEE;
use
IEEE.STD_LOGIC_1164.ALL;
Architecture structural of
entity nand_gate_struct is nand_gate_struct is
Port ( a_in : in --- Component Declaration
STD_LOGIC; component not_gate is
b_in : in STD_LOGIC; Port ( not_in : in STD_LOGIC;
nand_out : out not_out : out
STD_LOGIC); STD_LOGIC);
end nand_gate_struct; end component;
component and_gate is
entity not_gate is port(a,b : in std_logic;
Port ( not_in : in STD_LOGIC; y : out std_logic );
not_out : out end component;
STD_LOGIC);
end not_gate; --- Signal Declaration
entity and_gate is signal and_sig : std_logic;
port(a,b : in std_logic; begin
y : out std_logic );
end and_gate;
--- Port Mapping
-----Associative mapping
-- and_gate ports => nand_gate_ports
uut1 : and_gate port map( a => a_in,
b => b_in,
y =>and_sig );
uut2 : not_gate port map( not_in => and_sig,
not_out => nand_out);
--Positional mapping
---uut1 : and_gate port map( a_in, b_in, and_sig);
---uut2 : not_gate port map( and_sig, nand_out);
end structural;
How to Test ?
How to Apply
Stimulus?
How to test Functionality?
TESTBENCH
--Inputs
LIBRARY ieee; signal a_in : std_logic :=
USE ieee.std_logic_1164.ALL; '0';
signal b_in : std_logic :=
ENTITY nand_tb_datafow IS '0';
-------No ports
END nand_tb_datafow; --Outputs
signal Nand_out : std_logic;
ARCHITECTURE dataflow OF
nand_tb_datafow IS BEGIN
-- Instantiate the Unit Under
-- Component Declaration for the Unit Test (UUT)
Under Test (UUT)
uut: Nand_dataflow PORT MAP (
COMPONENT Nand_dataflow a_in => a_in,
PORT( b_in => b_in,
a_in : IN std_logic; Nand_out => Nand_out
b_in : IN std_logic; );
Nand_out : OUT std_logic
);
END COMPONENT;
TESTBENCH (STYLE-3)
TESTBENCH (STYLE-2) a_in <= not a_in after 10
ns;
-- Stimulus process b_in <= not b_in after 5
stim_a_in: process ns;
begin
a_in <= '1'; TESTBENCH (STYLE-1)
wait for 10 ns; -- Stimulus process
a_in <= '0'; process
wait for 10 ns; begin
a_in <= '0';
end process; b_in <= '0';
wait for 10 ns;
-- Stimulus a_in <= '0';
process b_in <= '1';
stim_b_in: process wait for 10 ns;
begin a_in <= '1';
b_in <= '1'; b_in <= '0';
wait for 5 ns; wait for 10 ns;
b_in <= '0'; a_in <= '1';
wait for 5 ns; b_in <= '1';
end process; wait for 10 ns;
end process;
END;
Comparing if and case
Statements
“If” statements produces priority-encoded logic.
Example :
process(s,c,d,e,f)
begin f
if (s=“00”) then
pout<=c; e
elsif (s=“01”) then d
pout<=d; c pout
elsif (s=“10”) then
pout<=e; 10
else 01
pout<=f; 11
end if;
end process;
Comparing if and case
Statements
“case” statement produces parallel logic.
Example :
process (s,c,d,e,f)
begin c
case s is
when “00” => d
pout<= c; pout
e
when “01” =>
pout<=d; f
when “10” =>
pout<=e;
when others => s
pout<=f;
end case;
end process;
Signals v/s Variables
Determine the values of Y and Z in both cases ?
signal A,B,C,Y,Z : integer ; signal A,B,C,Y,Z : integer ;
begin signal M,N : integer ;
process(A,B,C) begin
variable M,N : integer; process(A,B,C,M,N)
begin begin
M := A ; M<= A ;
N := B ; N<= B ;
Z<= M+N ; Z<= M + N ;
M := C ; M<= C ;
Y<= M+N ; Y<= M+N ;
end process; end process;
Signals v/s Variables
Architecture sig of par is
signal temp : std_logic ;
begin
process (a)
begin
temp<= ‘0’ ; [7] p
a[7:0]
for i in 0 to n loop
temp<=temp xor a(i) ;
end loop ;
p<=temp ;
end process ;
end sig ;
Signals v/s Variables
Architecture var of parity is
begin [7]
process (a) [6]
variable temp : std_logic ; [5]
begin [4]
temp := ‘0’ ;
p
for i in 0 to n loop
[3]
temp :=temp xor a(i) ;
[2]
end loop ; [0]
p<=temp ; [1]
a[7:0]
end process ;
end var ;
Signals v/s Variables
A Signal has three properties attached: Type, Value
and Time.
While a Variable has only two properties to it type
and value.
Use signals as channels of communications between
concurrent statements. In non-synthesizable models
avoid using signals to describe storage elements. Use
variables instead.
Signal occupy about two orders of magnitude more
storage than variables during Simulation.
Procedure
The design of the GCD calculator should be divided
into 2 parts –
a controller and
a datapath.
The controller is an FSM which issues commands to
the datapath based on the current state and the
external inputs. This can be a behavioral description.
The datapath contains a netlist of functional units like
multiplexors, registers, subtractors and a comparator,
and hence this design is structural.
The controller basically steps through the GCD
algorithm.
If x = y, we have finished computing the GCD, and we
go to the final state and assert the data output line.
The Datapath does the actual GCD computation.
Algorithm
x = 10
y=2
Is x = y? No, x > y therefore x = x - y
in our case, x = 10 - 2 = 8.
Is x = y? No, x > y therefore x = x - y
In our case, x = 8 - 2 = 6.
Is x = y? No, x > y there fore x = x - y
In our case, x = 6 - 2 = 4.
Is x = y? No, x > y therefore x = x - y
In our case, x = 4 - 2 = 2.
Is x = y? Yes, therefore the GCD of 10 and 2 is 2.
Procedure
Mux: takes 2 4-bit inputs and one select line. Based on
the select line, it outputs either the 1st 4-bit number or
the 2nd 4-bit number.
Register: Takes a 4-bit input, a load signal, reset, and a
clock signal. If the load signal is high and the clock is
pulsed, it outputs the 4-bit number.
Comparator: Takes 2 4-bit numbers, and assets one of
3 signals depending on whether the 1st number is less
than, greater than or equal to the 2nd number.
Subtractor: Takes 2 4-bit numbers, subtracts the
smaller number from the larger.
Output Register: Holds the GCD value. When x = y
the GCD has been found and can be outputted. Because
it is a register entity it should also take a clock and
reset signal.
Creating the controller’s FSM
!1 go_i
1:
Controller !1
Same structure as
1 !(!go_i) 0000 1:
2:
!
0001 2:
1 !(!go_i) FSMD
!
2-J:
go_i
00102-J:
go_i Replace complex
actions/conditions
3: x = x_i x_sel =
0011 3: 0
x_ld = 1
4: y = y_i
0100 4:
y_sel =
0
with datapath
x_i y_i
Datapath
configurations
!(x! y_ld = 1
5: !x_neq_y
=y) 0101 5: x_se
x! l n-bit 2x1 n-bit 2x1
=y x_neq_y y_se
6: 0110 6:
lx_ld
x<y ! x_lt_y !x_lt_y 0: x 0: y
(x<y) y_sel = 1 x_sel = y_ld
7: y = y -x 8: x = x - y 7: 8:
y_ld = 1 1
0111 x_ld 1000
=1
6-J: != < subtractor subtractor
10016-J:
5: x! 6: 8: x-y 7: y-x
5-J: x_neq_
=y x<y
10105-J:
y
x_lt_y 9: d
9: d_o = x 1011 9: d_ld = 1
d_ld
1-J: 11001-J: d_
o
32
Splitting into a controller and
datapath
go_i
Controller implementation Controller !1
0000 1: x_i y_i
model
go_i
x_sel 1 !(!go_i) (b) Datapath
Combinational y_sel 0001 2:
logic ! x_se
x_ld l n-bit 2x1 n-bit 2x1
go_i
y_ld 00102-J: y_se
lx_ld
x_neq_y x_sel =
0011 3: 0: x 0: y
0
x_lt_y y_ld
x_ld = 1
d_ld
y_sel =
0100 4: 0
!= < subtractor subtractor
y_ld = 1
x_neq_y= 5: x! 6: 8: x-y 7: y-x
0101 5: 0 x_neq_
=y x<y
Q3 Q2 Q1 Q0 x_neq_y y
0110 6: x_lt_y 9: d
=1
State register d_ld
x_lt_y=1 x_lt_y=
I3 I2 I1 I0 y_sel = 1 0 =
x_sel d_
7: 8:
y_ld = 1 1 o
0111 x_ld =1
1000
10016-J:
10105-J:
1011 9: d_ld = 1
11001-J:
33