Sie sind auf Seite 1von 19

DIGITAL LOGIC DESIGN

VHDL Coding for FPGAs


Unit 4
STRUCTURAL DESCRIPTION
 Hierarchical design: port-map, for-generate, if-
generate.
 Examples: Adder, multiplier, ALU, Look-up Table.
 Introduction to Parametric Coding.

Daniel Llamocca
STRUCTURAL DESCRIPTION
 It is the generalization of the Concurrent Description. The circuits
are described via interconnection of its subcircuits. This subcircuits
can be described in concurrent code and/or sequential code.
 Example: Multiplexor 2-to-1.

a b
0
s
f
b f
1
a
s
 This case is trivial, since the interconnection is realised via logic
operators, but nevertheless it is an example of structural
description.
Daniel Llamocca
STRUCTURAL DESCRIPTION
 Example: 4-to-16 decoder
w0 y0 y0
w0
w1 y1 y1
 We can describe this w1
y2 y2
decoder in an structured E y3 y3

way based on 2-to-4 w0 y0 y4

decoders. w1
y1 y5
w2 y0 y2
w0 y6
 However, we can also w3 w1
y1 E
y3 y7
describe the 4-to-16 E E
y2
y0 y8
decoder using the with- y3 w0
y1 y9
select statement. w1
y2 y10
E
y3 y11

w0 y0 y12
y1 y13
w1
y2 y14
E
y3 y15

Daniel Llamocca
STRUCTURAL DESCRIPTION
 Example: DLX Processor

S1

ALU
CONTROLLER
 In this type of systems, it is best to

S2
describe each component first,
then assemble them to make the
A
large system. REGISTER C
FILE
B

X1
 We do not need to see such large
TEMP
system to realise the importance of
the Structural Description. IAR

X2
PC

IR MAR

MDR

Daniel Llamocca
STRUCTURAL DESCRIPTION
 Many systems can be described entirely in one single block: we
can use the behavioral description, and/or concurrent statements
(with-select, when-else).
 However, it is advisable not to abuse of this technique since it
makes: i) the code less readable, ii) the circuit verification process
more cumbersome, and iii) circuits improvements less evident.
 The structural description allows for a hierarchical design: we can
‘see’ the entire circuit as the pieces it is made of, then identify
critical points and/or propose improvements on each piece.
 It is always convenient to have basic building blocks from which we
can build more complex circuits. This also allows building block (or
sub-system) to be re-used in a different circuit.

Daniel Llamocca
STRUCTURAL DESCRIPTION
 Example: 4-bit add/sub for numbers in 2’s complement
x0 y0
 The circuit can be described in one single block.
However, it is best to describe the Full Adder as a c i+1
FA
ci

block in a separate file (full_add.vhd), then use


as many full adders to build the 4-bit adder. s0
my_addsub.vhd
 The place where we use and connect as many full
adders as desired, and possibly add extra circuitry full_add.vhd
is called the ‘top file’ (my_addsub.vhd). This
creates a hierarchy of files in the VHDL project:
x3 y3 x2 y2 x1 y1 x0 y0
add/sub
add =0
sub = 1
c out c4 c3 c2 c1 c 0 c in
FA FA FA FA
overflow

s3 s2 s1 s0
Daniel Llamocca
4-bit 2’s complement Adder
 Full Adder: VHDL Description (fulladd.vhd):

library ieee; x y
use ieee.std_logic_1164.all;
c out c in
entity fulladd is FA
port ( cin, x, y: in std_logic;
s, cout: out std_logic); s
end fulladd;

architecture struct of fulladd is


begin

s <= x xor y xor cin;


cout <= (x and y) or (x and cin) or (y and cin);

end struct;

Daniel Llamocca
4-bit 2’s complement Adder
 Top file (my_addsub.vhd): We need 4 full adders block and extra
logic circuitry. library ieee;
use ieee.std_logic_1164.all;

entity my_addsub is
port ( addsub: in std_logic;
x,y: in std_logic_vector(3 downto 0);
s: out std_logic_vector(3 downto 0);
cout, overflow: out std_logic);
In order to use theend my_addsub;
file ‘fulladd.vhd’
into the top file, we architecture struct of my_addsub is
component fulladd
need to declare it in port ( cin, x, y: in std_logic; We copy what
the top file: s, cout: out std_logic); is in the entity of
full_add.vhd
end component;

signal c: std_logic_vector(4 downto 0);


signal yt: std_logic_vector(3 downto 0);

begin -- continued on next page

Daniel Llamocca
4-bit 2’s complement Adder
 Here, we:
 Insert the required extra circuitry (xor gates and I/O
connections).
 Instantiate the full adders and interconnect them (using the
port map statement)

-- continuation from previous page


c(0) <= addsub; cout <= c(4);
overflow <= c(4) xor c(3);

yt(0) <= y(0) xor addsub; yt(1) <= y(1) xor addsub;
yt(2) <= y(2) xor addsub; yt(3) <= y(3) xor addsub;

f0: fulladd port map(cin=>c(0),x=>x(0),y=>yt(0),s=>s(0),cout=>c(1));


f1: fulladd port map(cin=>c(1),x=>x(1),y=>yt(1),s=>s(1),cout=>c(2));
f2: fulladd port map(cin=>c(2),x=>x(2),y=>yt(2),s=>s(2),cout=>c(3));
f3: fulladd port map(cin=>c(3),x=>x(3),y=>yt(3),s=>s(3),cout=>c(4));

end struct;

Daniel Llamocca
4-bit 2’s complement Adder
 Use of ‘port map’ statement:
port map (signal in full adder => signal in top file, ...)
 Instantiating and connecting the first full adder:

f0: fulladd port map(cin=>c(0),x=>x(0),y=>yt(0),s=>s(0),cout=>c(1));

x3 y3 x2 y2 x1 y1 x0 y0

add/sub

yt3 yt2 yt1 yt0


x y x y x y x y
c4 c3 c2 c1 c0
c out cout c in cout c in cout c in cout c in
overf low s s s s

s3 s2 s1 s0

Daniel Llamocca
4-bit 2’s complement Adder
 Use of ‘port map’ statement:
port map (signal in full adder => signal in top file, ...)
 Instantiating and connecting the second full adder:

f1: fulladd port map(cin=>c(1),x=>x(1),y=>yt(1),s=>s(1),cout=>c(2));

x3 y3 x2 y2 x1 y1 x0 y0

add/sub

yt3 yt2 yt1 yt0


x y x y x y x y
c4 c3 c2 c1 c0
c out cout c in cout c in cout c in cout c in
overf low s s s s

s3 s2 s1 s0

Daniel Llamocca
4-bit 2’s complement Adder
 Use of ‘port map’ statement:
port map (signal in full adder => signal in top file, ...)
 Instantiating and connecting the third full adder:

f2: fulladd port map(cin=>c(2),x=>x(2),y=>yt(2),s=>s(2),cout=>c(3));

x3 y3 x2 y2 x1 y1 x0 y0

add/sub

yt3 yt2 yt1 yt0


x y x y x y x y
c4 c3 c2 c1 c0
c out cout c in cout c in cout c in cout c in
overf low s s s s

s3 s2 s1 s0

Daniel Llamocca
4-bit 2’s complement Adder
 Use of ‘port map’ statement:
port map (signal in full adder => signal in top file, ...)
 Instantiating and connecting the fourth full adder:

f3: fulladd port map(cin=>c(3),x=>x(3),y=>yt(3),s=>s(3),cout=>c(4));

x3 y3 x2 y2 x1 y1 x0 y0

add/sub

yt3 yt2 yt1 yt0


x y x y x y x y
c4 c3 c2 c1 c0
c out cout c in cout c in cout c in cout c in
overf low s s s s

s3 s2 s1 s0

Daniel Llamocca
FOR-GENERATE Statement
 In the 4-bit adder example, if we wanted to use say 8 bits, we would
need to instantiate 8 full adders and write 8 port map statements.
 Instantiating components can be a repetitive task, thus the for-
generate statement is of great help here:
yt(0) <= y(0) xor addsub; yt(1) <= y(1) xor addsub;
yt(2) <= y(2) xor addsub; yt(3) <= y(3) xor addsub;

f0: fulladd port map(cin=>c(0),x=>x(0),y=>yt(0),s=>s(0),cout=>c(1));


f1: fulladd port map(cin=>c(1),x=>x(1),y=>yt(1),s=>s(1),cout=>c(2));
f2: fulladd port map(cin=>c(2),x=>x(2),y=>yt(2),s=>s(2),cout=>c(3));
f3: fulladd port map(cin=>c(3),x=>x(3),y=>yt(3),s=>s(3),cout=>c(4));

-- continuation from previous page


c(0) <= addsub; cout <= c(4);
overflow <= c(4) xor c(3);

gi: for i in 0 to 3 generate


yt(i) <= y(i) xor addsub;
fi: fulladd port map(cin=>c(i),x=>x(i),y=>yt(i),s=>s(i),cout=>c(i+1));
end generate;
end struct;

Daniel Llamocca
INTRODUCTION TO PARAMETRIC CODING
 N-bit adder/ library ieee;
subtractor. We can use ieee.std_logic_1164.all;

choose the value of N entity my_addsub is


in the entity. generic (N: INTEGER:= 4);
port( addsub : in std_logic;
x, y : in std_logic_vector (N-1 downto 0);
s : out std_logic_vector (N-1 downto 0);
 The architecture code overflow : out std_logic;
cout : out std_logic);
is tweaked so as to end my_addsub;
make it parametric.
architecture structure of my_addsub is
component fulladd
port( cin, x, y : in std_logic;
s, cout : out std_logic);
end component;

Example: Parametric N-bit signal c: std_logic_vector (N downto 0);


adder/subtractor in 2’s signal yx: std_logic_vector (N-1 downto 0);
begin
complement:
c(0) <= addsub; cout <= c(N);
 my_addsub.zip: overflow <= c(N) xor c(N-1);
gi: for i in 0 to N-1 generate
my_addsub.vhd, yx(i) <= y(i) xor addsub;
fulladd.vhd fi: fulladd port map (cin=>c(i),x=>x(i),y=>yx(i),
tb_my_addsub.vhd, s=>s(i),cout=>c(i+1));
my_addsub.ucf end generate;
end structure;
Daniel Llamocca
INTRODUCTION TO PARAMETRIC CODING
 Example: N-bit library ieee;
use ieee.std_logic_1164.all;
adder/subtractor. use ieee.std_logic_arith.all; -- for conv_std_logic_vector

entity tb_my_addsub is
generic (N: INTEGER:= 4); -- must match the HW description
end tb_my_addsub;
 Testbench: Use of
‘for loop’ inside the
architecture structure of my_addsub is
component my_addsub -- Do not do 'generic map' in testbench
stimulus process to port( addsub
x, y
: in std_logic;
: in std_logic_vector (N-1 downto 0);
generate all possible s : out std_logic_vector (N-1 downto 0);
overflow,cout : out std_logic);
input combinations. end component;
-- Inputs
signal addsub: std_logic:='0';
signal x,y: std_logic_vector (N-1 downto 0):= others => '0');
 Parametric Testbench: -- Outputs
signal overflow, cout: std_logic;
It depends on N, signal s: std_logic_vector (N-1 downto 0);

which must match the begin


uut: my_addsub port map (addsub, x, y, s, overflow, cout);
hardware description st: process
begin
wait for 100 ns;
y<="0000"; x<="0000"; wait for 10 ns; addsub <= '0'; -- Pick '1' to test subtraction
y<="0000"; x<="0001"; wait for 10 ns; gi: for i in 0 to 2**N-1 loop
... y <= conv_std_logic_vector(i,N); wait for 10 ns;
y<="0000"; x<="1111"; wait for 10 ns;
y<="0001"; x<="0000"; wait for 10 ns; gj: for j in 0 to 2**N-1 loop
y<="0001"; x<="0001"; wait for 10 ns; x <= conv_std_logic_vector(j,N); wait for 10 ns;
... end loop;
y<="0001"; x<="1111"; wait for 10 ns; end loop;
...
wait;
end process;
Daniel Llamocca end;
Example: 4-bit array multiplier
 Interesting example of b(3) b(2) b(1) b(0)

structural description. By a(0) x


cin
y
connecting full adders
a0b3 a0b2 a0b1 a0b0
m03 m02 m01 m00 FULL
and AND gates, we build s03 s02 s01 s00
ADDER

the array multiplier. c02 c01 c00


cout
s

 We parameterize the
a(1)
a1b3 a1b2 a1b1 a1b0

circuit with ‘if-generate’, m13 m12 m11 m10 p(0)

‘for-generate’, and the s13


c12
s12
c11
s11
c10
s10

use of arrays in VHDL. a(2)


a2b3 a2b2 a2b1 a2b0
 Testbench: we use m23 m22 m21 m20 p(1)

conv_std_logic_vector to s23
c22
s22
c21
s21
c20
s20

specify input values


a(3)
a3b3 a3b2 a3b1 a3b0
m33 m32 m31 m30 p(2)
Parametric N-bit array multiplier: s33 s32 s31 s30
c32 c31 c30
 my_mult.zip:
my_mult.vhd.vhd, m43 m42 m41 m40
fulladd.vhd p(3)

tb_my_mult.vhd,
my_mult.ucf
p(7) p(6) p(5) p(4)
Daniel Llamocca
Example: Arithmetic Logic Unit
 This circuit executes two types of
a N
operations: logic (or bit-wise) and ARITHMETIC
arithmetic. b
N UNIT

 The arithmetic unit and the logic unit 0

are described in different VHDL files. N y


1
 The arithmetic unit relies heavily on
the parametric adder/subtractor unit. LOGIC UNIT

 The VHDL code is parameterized so as sel(3)

to allow for two N-bit operands.


4
 The ‘sel’ inputs selects the operationselto Operation
sel
Function Unit
be carried on (as per the table). 0 0 0 0 y <= a Transfer 'a'
0 0 0 1 y <= a + 1 Increment 'a'
0 0 1 0 y <= a - 1 Decrement 'a'
 my_alu.zip: 0 0 1 1 y <= b Transfer 'b'
Arithmetic
0 1 0 0 y <= b + 1 Increment 'b'
my_alu.vhd, 0 1 0 1 y <= b - 1 Decrement 'b'
my_alu_arith.vhd, 0 1 1 0 y <= a + b Add 'a' and 'b'
0 1 1 1 y <= a - b Subtract 'b' from 'a'
my_alu_logic.vhd, 1 0 0 0 y <= NOT a Complement 'a'
1 0 0 1 y <= NOT b Complement 'b'
my_addsub.vhd, 1 0 1 0 y <= a AND b AND
fulladd.vhd 1 0 1 1 y <= a OR b OR
Logic
1 1 0 0 y <= a NAND b NAND
tb_my_alu.vhd 1 1 0 1 y <= a NOR b NOR
1 1 1 0 y <= a XOR b XOR
Daniel Llamocca 1 1 1 1 y <= a XNOR b XNOR
Example: 6-to-6 LUT
 The LUT contents (64 bytes ) are specified as a set of 6
parameters. These 6 parameters are ‘generics’ in the VHDL code.
 Note that if the parameters are modified, we will get a different
circuit that needs to be re-synthesized. In other words, the LUT
contents are NOT inputs to the circuit.
ILUT

6 4 LSBs LI(3..0)
6 bits
4 4 4 4 6 6 LUT
6 to 1
b5 ... b1 b0
b5
2 MSBs

64 words of 6 bits
6
LUT4

LUT4

LUT4

LUT4
LUT
6 to 1
6

column 5

column 1
column 0
b4
 6
...
6

...
LI(4)
MUX MUX
6 LUT
LI(5) 6 to 1
LUT5-to-1 b0
MUX

LUT 6-to-6 LUT 6-to-6


OLUT(i) LUT6-to-1

 my6to6LUT.zip: my6to6LUT.vhd, my6to1LUT.vhd, my5to1LUT.vhd,


my4to1LUT.vhd, tb_my6to6LUT.vhd, my6to6LUT.ucf
Daniel Llamocca