0% found this document useful (0 votes)
100 views

Digital Logic Design: VHDL Coding For Fpgas Unit 4

The document describes structural description in VHDL. It discusses hierarchical design using components like multiplexers, decoders, processors. Structural description allows building complex circuits by connecting simpler sub-components, making the design reusable and more modular. Examples shown include a 4-bit adder built by instantiating and connecting four full-adder components using port maps. Structural description improves readability, verification and modification of designs compared to flat behavioral descriptions.

Uploaded by

Srinivas Cheruku
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views

Digital Logic Design: VHDL Coding For Fpgas Unit 4

The document describes structural description in VHDL. It discusses hierarchical design using components like multiplexers, decoders, processors. Structural description allows building complex circuits by connecting simpler sub-components, making the design reusable and more modular. Examples shown include a 4-bit adder built by instantiating and connecting four full-adder components using port maps. Structural description improves readability, verification and modification of designs compared to flat behavioral descriptions.

Uploaded by

Srinivas Cheruku
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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

You might also like