Sie sind auf Seite 1von 14

Jon Turner

signal attributes

arrays and records

variables

functions and procedures

assertions

packages
Designing with VHDL part 3
2
Signal Attributes

or signal x: std_logic_vector(15 downto 0),

xleft!"#$ xright!%

these are referred to as attributes of &

other attributes include xhigh '!"#($ xlow '!%($


xrange '!"# downto %( and xlength '!")(

Signal attributes can be used to write code that is


less dependent on specific signal lengths

for e&a*ple
x(xhigh) <= 1; x(xlow+3 downto xlow) <= xc;
x <= (xhigh => 1, xlow => 1, others => 0);

+his can *ake code easier to change and is useful


when writing *odules with generic signal lengths
3
Arrays of std_logic_vectors
-- using these declarations
subtype word is std_logic_vector(wordSize-1 downto 0);
type regFileTyp is array(0 to regFileSize-1) of word;
signal reg: regFileType;
-- we can write things like
reg(2) <= reg(1) + reg(4);
reg(3 downto 0) <= reg(7 downto 4);
reg(3)(5) <= 1;
reg(int(x)) <= reg(int(y)) -- int() converts to integer

Synthesi,er can i*ple*ent such arrays using registers


constructed fro* flip flops

So*eti*es can be i*ple*ented using *e*ory blocks

depends on how the array is used in the VHDL

for large arrays of words that are accessed one at a ti*e$


synthesi,er will typically use a *e*ory block
-
Defining 2d .onstant Arrays

.onstant arrays can be used to define tables of values


subtype asciiChar is std_logic_vector(7 downto 0)
type hex2AsciiMap is array(0 to 15) of asciiChar;
constant hex2Ascii: hex2AsciiMap := (
x"30", x"31", x"32", x"33",x"34", -- 0-4
x"35", x"36", x"37",x"38", x"39", -- 5-9
x"61", x"62",x"63", x"64", x"65", x"66" -- a-f
);
...
ascii3 <= hex2Ascii(3);

.onstant arrays are /read0only1 so$ synthesi,er can


i*ple*ent using 2ead03nly 4e*ory '234(

234s are generally less /e&pensive1 than read5write *e*ory


#
Defining 2ecords
-- with these definitions
type entryType is record
valid: std_logic;
key, value: word
end record entryType;
constant tableSize: integer := 8;
type tableTyp is array(0 to tableSize-1) of entryType;
signal table: tableType
-- we can write
table(2).key <= table(1).value
if table(0).valid = 1 then
table(5) <= (1, xabcd, x0123);
end if;

Synthesi,er can i*ple*ent using registers


)
2eview 6uestions
"7 .onsider the declaration
signal x: std_logic_vector(0 to 7);
what are the values of the following attributes
xlow xhigh xleft xright xrange xlength
27 8rite the declarations needed to define a constant array called
firstOne$ with ") entries of - bits each$ where the value of
firstOne'x( is the position in x of the right*ost " bit7 So for
e&a*ple$ firstOne'/%%"%1(!/%"1$ firstOne'/""%%1(!/"%17 9f none
of the bits in x are "$ *ake firstOne'x(!/%%1
37 8rite the declarations to define a table in which each entry has
three fields$ x$ y and z$ where x is a single bit signal and y and z
are eight bit signals7 :ntries should be nu*bered "$ 2$777$;7 8rite
an assign*ent that copies the y field of the second entry in the
table to the z field of the fifth entry if the x fields of both entries
are e<ual7
=
Variables

VHDL provides variables in addition to signals

unlike signals$ variables do not correspond to wires

best to think of variable assign*ent as an abbreviation


a <= x"3a";
y := a + x"01"; -- assignment to variable y
b <= y;
y := y + x"10"; -- defines new abbreviation for y
c <= y;
-- e!ivalent code segment wit"o!t variables
a <= x"3a";
b <= a + x"01";
c <= #a+x"01"$ + x"10";

+o reduce confusion$ no variable should be used in both a


synchronous and asynchronous conte&t
;
>se of Variables in Loops
arc"itect!re a1 of find%irst&ne is
signal got1: std_logic_vector#word'i(e downto 0$;
begin
)rocess #d*n+got1$ begin
got1#0$ <= ,0-; index <= #ot"ers =. ,0-$;
for i in 0 to word'i(e-1 loo)
if got1#i$ < d*n#i$ t"en index <= slv#i+lg/ord'i(e$; end if;
got1#i+1$ <= d*n#i$ or got#i$;
end loo);
valid <= got1#word'i(e$;
end )rocess;
end a1;
arc"itect!re a1 of find%irst&ne is begin
)rocess #d*n$
variable got1: std_logic;
begin
got1 := ,0-; index <= #ot"ers =. ,0-$;
for i in 0 to word'i(e-1 loo)
if got1 < d*n#i$ t"en index <= slv#i+lg/ord'i(e$; end if;
got1 := d*n#i$ or got1;
end loo);
valid <= got1;
end )rocess;
end a1;
got"'i( is high if there is a "
that co*es before bit i in array
got" signal plays sa*e role?
can yield *ore efficient circuit
@
unctions

unctions can be used to define sub0circuits that are


used repeatedly within a larger circuit
f!nction max#x+y: word$ ret!rn word is
begin
if x . y t"en ret!rn x; else ret!rn y; end if;
end f!nction max;

:ach distinct use of a function causes a copy of the


subcircuit to be synthesi,ed
<= max#s+t$;
r <= max#!+$;

e&ceptionA *ultiple uses


with sa*e inputs donBt
re<uire separate copies
"%
Crocedures

Crocedures can be used to define subcircuits with


*ultiple outputs
procedure inRange(x: in word;
inRange: out std_logic;
tooHigh: out std_logic;
tooLow: out std_logic) is
constant loBound: word := x1234";
constant hiBound: word := xabcd";
begin
tooLow := '0'; inRange := '0'; tooHigh := '0';
if x < loBound then tooLow := '1';
elsif x <= hiBound then inRange := '1';
else tooHigh := '1';
end if;
end procedure;

Crocedure para*eters are variables

use variable assign*ent when assigning output values


""
Assertions

Assertion state*ents are useful for debugging a


circuit specification

assert 0 < x and x < y;

the condition in the assert state*ent is checked during


si*ulation and triggers an error *essage if violated

Add report clause to specify error *essage

assert 0 < x and x < y re)ort 0x o!t of range1;

Add severity clause to force early ter*ination

assert 0 < x and x < y severity fail!re;

Also useful in testbenches to co*pare circuit


output with e&pected output
"2
Cackages

Cackages can be used to define constants$ types and functions5procedures used by


*ultiple *odules
library *222;
!se *2223std_logic_11453all;
!se *2223std_logic_arit"3all;
!se *2223std_logic_!nsigned3all;
)ac6age common7efs is
constant wordsi(e: integer := 14;
constant n8tn: integer := 5;333
s!bty)e word is std_logic_vector#word'i(e-1 downto 0$;
s!bty)e b!ttons is std_logic_vector#n8tn-1 downto 0$;333
f!nction int#d: std_logic_vector$ ret!rn integer;
end )ac6age common7efs;
library *222; 333
)ac6age body common7efs is
f!nction int#d: std_logic_vector$ ret!rn integer is
begin ret!rn conv_integer#!nsigned#d$$; end f!nction int;
end )ac6age body common7efs;

+ypically placed in a separate source file


constant$ type$ subtype
definitions$ function and
procedure declarations
package body
with function$
procedure
definitions
"3
:&ercises
"7 8rite a VHDL declaration for an array
of records$ where the inde& range for
the record is the sa*e as the inde&
range for a stdDlogicDvector$ called (7
:ach record in your array should have
two fields? field A is a stdDlogicDvector
with a descending range that has the
sa*e li*its as ($ field E is a
stdDlogicDvector with an ascending
range that has the sa*e li*its as (7

27 9n the VHDL code seg*ent shown
below$ deter*ine the value assigned to
each of the signals x and y on the ne&t
clock tick assu*ing that their initial
values are x151 and x1917
if rising_edge#cl6$ t"en
a := x + y;
x <= a + x111;
y <= a + x;
a := y - x131;
x <= a + x1:1;
end if;
37 8rite a VHDL procedure min;ax that
takes two eight bit inputs and produces
two eight bit outputs7 +he first of the
outputs is e<ual to the s*aller of the
two input values$ while the second is
e<ual to the larger of the two inputs7
"-
Solutions
"7type recTyp: record is
A: std_logic_vector(zhigh
downto zlow);
B: std_logic_vector(zlow
to zhigh);
end record;
type recArray: array(zrange)
of recType;
27 +he first assign*ent to x has no effect$
so the new value of x is a+x1:1$
where a=y<x131=x151? so the new
value of x is x1417
+he new value of y is a+x$
where a=x+y=x1b1$ so the new value
of y is x1f17

37procedure minMax(
a, b: in SLV(7 downto 0);
x, y: out SLV(7 downto 0))
is begin
if a < b then
x := a; y := b;
else
x := b; y := a;
end if;
end procedure minMax;

Das könnte Ihnen auch gefallen