You are on page 1of 70

F3 : Data Types, Functions &

Packages

1
VHDL – A Strongly typed language
• VHDL is a strongly typed language. This means that it is hard
(sometimes annoyingly hard) to get a construct through the compile
stage. The types must be absolutely correct to be able to simulate it.
– Even if the types are correct, you might find that the simulation doesn’t
work properly. Some types or bit ranges are only checked during
simulation.
– Once the compiler and simulator stops complaining, it will be correct by
construction.

• Verilog on the other hand is weakly typed. It is rather easy to get


things through, but sometimes this leads to incorrect behaviour. You
might even say that the notation is a bit sloppy.
– Assignments containing different bit ranges are not checked. Rather, it
copies them as they are written, until you reach the end of the variable.
Thus, the compiler and simulator does not help you to get it correct. You
have to figure it out by yourself.
2
Predefined (STANDARD) Data types

- boolean (true or false)


- bit ('0' or '1')
- bit_vector (array of bits)
- integer
- real
- time (physical data type)
- character
- string
- severity_level -- used for assertions
3
Types of VHDL Data types

Types

Access Composite

Array Record
Scalar

Integer Physical
Real Enumerated

4
Scalar Types - Integer

• Integer
– Minimum range for any implementation as defined by standard:
- 2,147,483,647 to 2,147,483,647
– Integer assignment example

ARCHITECTURE test_int OF test IS


BEGIN
PROCESS (X)
VARIABLE a: INTEGER;
BEGIN
a := 1; -- OK
a := -1; -- OK
a := 1.0; -- bad
END PROCESS;
END TEST;

5
Scalar Types - Real

• Real
– Minimum range for any implementation as defined by standard:
- 1.0E38 to 1.0E38
– Real assignment example

ARCHITECTURE test_real OF test IS


BEGIN
PROCESS (X)
VARIABLE a: REAL;
BEGIN
a := 1.3; -- OK
a := -7.5; -- OK
a := 1; -- bad
a := 1.7E13; --OK
a := 5.3 ns; -- bad
END PROCESS;
END TEST; 6
Scalar Types - Enumerated
• Enumerated
– User defined range
– Enumerated example
– Extremely useful for modelling state machines

ARCHITECTURE test_enum OF test IS


TYPE binary IS ( ON, OFF );
BEGIN
PROCESS (X)
VARIABLE a: binary;
BEGIN
a := ON; -- OK
... more statements ...
a := off; -- OK VHDL is Case insensitive
... more statements ...
END PROCESS;
END TEST;
7
Enumerated standard types:
Boolean, Bit, Character and Severity_level

Type Boolean is (false, true);


Type Bit is ('0', '1');
type Character is (NUL, SOH,…, DEL); -- 128 chars in VHDL’87
-- 256 chars in VHDL’93
Type Severity_level is (Note, Warning, Error, Failure);

8
Enumerated IEEE data types:
std_logic

Type std_ulogic is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
'U' -- Uninitialized
'X' -- Forcing unknown
'0' -- Forcing zero
'1' -- Forcing one
'Z' -- High Impedance
'W' -- Weak Unknown
'L' -- Weak Low
'H' -- Weak High
'-' -- Don’t Care

9
Testing all combinations
in an enumerated type
type mvl7 is ('X', '0', '1', 'Z', 'W', 'L', 'H');
signal a:mvl7;

process
begin
for i in mvl7 loop -- loop variable i becomes of mvl7 type
a <= i; -- a must be declared as mvl7
wait 10 ns;
end loop;
end process;

a 'X' '0' '1' 'Z' 'W' 'L' 'H'


10 20 30 40 50 60 70
10
Scalar Types - Physical

• Physical
– Can be user defined range
– Physical type example

TYPE resistance IS RANGE 0 to 100000000


UNITS
ohm; -- ohm
Kohm = 1000 ohm; -- 1 K
Mohm = 1000 kohm; -- 1 M
END UNITS;

– Time units are the only predefined physical type in VHDL

11
Scalar Types - Time

• The predefined time units are as follows


TYPE TIME IS RANGE <implementation defined>
UNITS
fs; -- femtosecond
ps = 1000 fs; -- picosecond
ns = 1000 ps; -- nanosecond
us = 1000 ns; -- microsecond
ms = 1000 us; -- millisecond
sec = 1000 ms; -- second
min = 60 sec; -- minute
hr = 60 min; -- hour
END UNITS;

12
Composite Types - Array (ascending)

• Array
– Used to collect one or more elements of a similar type in a single
construct
– Elements can be any VHDL data type
– Sample one-dimensional array (vector)

TYPE data_bus IS ARRAY (0 TO 31) OF BIT;

0...element numbers... 31
0 ...array values... 1
VARIABLE X: data_bus;
VARIABLE Y: BIT;

Y := X(12); -- Y gets value of 13th element from left


13
Composite Types - Array (descending)

• Another sample one-dimensional array (using the DOWNTO order)

TYPE register IS ARRAY (15 DOWNTO 0) OF BIT;

15...element numbers... 0
0 ...array values... 1
VARIABLE X: register;
VARIABLE Y: BIT;

Y := X(4); -- Y gets value of 5th element from the right

• DOWNTO keyword orders elements from left to right, with


decreasing element indices
14
Left and Right is important
signal reg1:std_logic_vector(9 downto 0);
signal reg2:std_logic_vector(0 to 9);

reg1 <= reg2;

9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9

<=

reg1(3 downto 0) <= reg2(4 to 7);


9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9

<=

15
Composite Types - Generic Array Ranges

• If the start and stop index is generic, the range of the


array becomes parametrizable and can be specified later.
– Only one level of parametrization is allowed

Generic parameter

type bit_vector is array(integer range <>) of bit;


subtype bit8 is bit_vector(7 downto 0); Must be 100% statically defined

Only natural indeces

type byte_vector is array(natural range <>) of bit8;


subtype memory_type is byte_vector(1023 downto 0);

16
Array Standard Types:
Bit_vector and String
type Bit is ('0', '1');
type Bit_vector is array(integer range <>) of bit;

type Character is (NUL, SOH,…, DEL); -- 128 chars in VHDL’87


-- 256 chars in VHDL’93
type String is array(positive range <>) of Character;

17
Array IEEE data types:
std_logic_vector

Type std_ulogic is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
type std_logic is resolved std_ulogic; -- resolution function call
type std_logic_vector is array (integer range <>) of std_logic;

18
Composite Types - Record
• Records
– Used to collect one or more elements of different types in a single
construct
– Elements can be of any VHDL data type
– Elements are accessed through field name
– Sample record statement
TYPE binary IS ( ON, OFF );
TYPE switch_info IS
RECORD
status : binary;
IDnumber : integer;
END RECORD;

VARIABLE switch : switch_info;

switch.status := on; -- status of the switch


switch.IDnumber := 30; --
19 number of the switch
Access Types - Pointers

• Access
– Similar to pointers in other languages
– Allows for dynamic allocation of storage (=c.f. malloc in C)
– Useful for simulating queues, fifos, etc. Used for accessing the
file system (see the LINE type, which is an access string type).

TYPE name IS ACCESS base_type;

TYPE nat_ptr IS ACCESS natural;


VARIABLE count:nat_ptr;

count:=new natural;
count.ALL=10;
deallocate(count);
20
Access Standard Types: TEXTIO
• The VHDL file system is defined in the package
TEXTIO in the STD library.
– It uses an access type to write strings to the file
– Access types are not synthesizable
– We will talk more about the file system in a later lecture

type LINE is access string;


type TEXT is file of string;

21
Example: Dynamic Pointers

-- declaring a pointer type


type natural_ptr is access natural;

-- declaring the pointer


variable count: nautral_ptr;

-- allocating the pointer


count:=new natural;

-- assigning a value to the pointer’s data


count.all:=10; alt. count:=new natural’(10);

22
Example: Dynamic Pointers (ctd.)

• If we declare our own access type, the simulator also creates an


implicitly defined and overloaded deallocate()-procedure;

-- declaring a pointer type


type T_ptr is access T;

-- creates the implictly defined procedure


procedure dellaocate (P: inout T_ptr);

-- Only useful in really advanced testbenches


-- Read more in a VHDL-reference book (e.g. Ashenden, Chapter 17).

23
Subtype

• Subtype
– Allows for user defined constraints on a data type
– May include entire range of base type
– Assignments that are out of the subtype range result in error
– Subtype example

SUBTYPE name IS base_type RANGE <user range>;

SUBTYPE first_ten IS INTEGER RANGE 0 to 9;

24
Potential Problems (subtype)
• Objects defined by subtypes derived from the same base type are
considered being of the same type
– Example
PROCESS
SUBTYPE smallintA IS integer (RANGE 0 TO 10);
SUBTYPE smallintB IS integer (RANGE 0 TO 15);
VARIABLE A: smallintA := 5;
VARIABLE B: smallintB := 8;
VARIABLE C: integer;
VARIABLE D: smallintB;
BEGIN
C := B * A; -- OK
B := B+1; -- OK, but will eventually overflow
D := B * A; -- OK, but will result in an overflow
END;

25
Natural and Positive Integers

Predefined Integer subtypes:


• Subtype Natural is integer range 0 to integer’high;
• Subtype Positive is integer range 1 to integer’high;

26
Attributes
• Attributes are used to retrieve information about
the object associated with it
• Syntax:

<object>’<attribute_name>

• Valid objects (the most used ones in bold):


Entity, architecture, configuration, package
Signal, variable, constant
Function, Procedure
Type, subtype

27
Type Attributes

Integer’high = 2,147,483,647

Integer’low = -2,147,483,647

Bit’left = '0'

Bit’right = '1'

28
Array Type attributes

Subtype a_type is Bit_vector(7 downto 0);

a_type’range = 7 downto 0

a_type’reversed_range = 0 to 7

a_type’length = 8

29
Multi-dimensional Vector & Array assignments

subtype instruction:bit_vector(31 downto 0);


signal regs:array(0 to 15) of instruction;
signal bad:array(0 to 15, 31 downto 0) of bit; -- multiple-array indexing is in general not synthesizable

regs(2)<=regs(0)+regs(1);

regs(1)(7 downto 4)<=reg(0)(11 downto 8);

Index within the subtype instructions

Index within the array of instructions

30
Alias Statement

signal instruction:bit_vector(31 downto 0);


signal reg:array(0 to 15) of instruction;

alias op1:bit_vector(3 downto 0) is instruction(23 downto 20);


alias op2:bit_vector(3 downto 0) is instruction(19 downto 16);
alias op3:bit_vector(3 downto 0) is instruction(15 downto 12);

op1<="0000";
op2<="0001"; instruction 31..24 23..20 19..16 15..12 11..0
op3<="0010"; instr op1 op2 op3 offset

ADD: reg(op1) <= reg(op2) + reg(op3) -- not ok


reg(bit2int(op1)) <= reg(bit2int(op2)) + reg(bit2int(op3)); -- ok
reg(0) <= reg(1) + reg(2); -- ok
31
Useful Shorthand Notation in Array Assignments

signal b:bit_vector(11 downto 0);


alias b:bit_vector(11 downto 0) is instruction(11 downto 0);

b<="000000010010";
b<=B"000000010010";
b<=B"0000_0001_0010";
b<=X"012"; -- Hexadecimal assignment
b<=O"0022"; -- Octal Assignment

32
Aggregates

type reg_array is array(integer range<>) of bit_vector(31 downto 0);


signal reg:reg_array(1023 downto 0):=(others => (others =>'1'));

signal example:bit_vector(31 downto 0);


example<=(0 =>'1', 15 => d(0), 20 to 23 => op1(0), others =>'0');

Type must be of the base type (bit)

33
Aggregates (ctd.)

type rec_type is record


a:integer;
b:real;
c:bit_vector(3 downto 0);
end record;

signal rec:rec_type:=(1,1.0,"1111");

rec<=(a => 1, b => 1.0, c =>(others=>'1'));

34
LHS Aggregates

Signal a,b,cin,cout,sum:std_logic;

Process(a,b,cin)
variable carry:std_logic;
begin
carry:=(a AND b) OR (a AND cin) OR (b AND cin);
(cout,sum)<=carry & (a XOR b XOR cin);
End process;
Left bit Right bit

35
Type Conversion

36
Type conversion (Similar Base)

Similar but not the same base type:

signal i:integer;
signal r:real;

i<=integer(r);
r<=real(i);

37
Type conversion (Same Base)

Same base type:


type a_type is array(0 to 4) of bit;
signal a:a_type;
signal s:bit_vector(0 to 4);

a<=s; -- Error, RHS is a bit_vector, not an a_type…


a<=a_type’("00101"); -- type qualifier
a<=a_type(s); -- type conversion
38
Type conversion (Different Base)

Different base types:


Function int2bits(value:integer;ret_size:integer) return bit_vector;
Function bits2int(value:bit_vector) return integer:

signal i:integer;
signal b:bit_vector(3 downto 0)

i<=bits2int(b);
b<=int2bits(i,4);

39
Example: Integer to Bits and vice
versa

package my_package is
Function int2bits(value:integer;ret_size:integer) return bit_vector;
Function bits2int(value:bit_vector) return integer;

end my_package;

40
Example: Integer to Bits
package body my_package is
Function int2bits(value:integer;ret_size:integer) return bit_vector is
variable res:bit_vector(ret_size-1 downto 0);
variable tmp:integer;
begin
tmp:=value;
for i in 0 to ret_size-1 loop
if (tmp mod 2=1) then
res(i):=‘1’;
tmp:=tmp-1;
else
res(i):=‘0’;
end if;
tmp:=tmp/2;
end loop;
return res;
end int2bits;
41
Example: Bits to Integer

Function bits2int(value:bit_vector) return integer is


variable res:integer:=0;
begin
for i in value’high downto value’low loop
if (value(i)=‘1’) then
res:=2*res+1;
else
res:=2*res;
end if;
end loop;
return res;
end bits2int;
end my_package;
42
Packages

43
VHDL Hierarchy

Package

Generics Entity Ports

Architecture Architecture Architecture

Concurrent Process
Concurrent
Statements
Statements
44 Sequential Statements
VHDL Packages
• Packages encapsulate elements that can be globally shared among
two or more design units
• A package consists of two parts

Declaration Interface for all


elements contained
in the package
Body

Definition of all
elements contained
in the package

45
Packages
• What can you put in a package?
– Subprograms (i.e., functions and procedures)
– Data and type declarations such as
• User record definitions
• User types and enumerated types
• Constants
• Files
• Aliases
• Attributes
– Component declarations
• Entities and Architectures cannot be declared or defined in a
package
• To use a package, make it visible via the “use” language construct

46
Subprograms

• Similar to subprograms found in other languages

• Allow repeatedly used code to be referenced many times without


duplication

• Break down large chunks of code in small, more manageable parts

• VHDL provides functions and procedures for use

47
Functions
• Produce a single return value
• Called by expressions
• Can not modify the parameters passed to it
• Requires a RETURN statement

FUNCTION add_bits (a, b : IN BIT) RETURN BIT IS


BEGIN -- functions can NOT return multiple values
RETURN (a XOR b);
END add_bits;

FUNCTION add_bits2 (a, b : IN BIT) RETURN BIT IS


VARIABLE result : BIT; -- variable is local to function
BEGIN
result := (a XOR b);
RETURN result; -- the two functions are equivalent
END add_bits2;

48
Functions

ARCHITECTURE behavior OF adder IS


BEGIN
PROCESS (enable, x, y)
BEGIN FUNCTION add_bits
IF (enable = '1') THEN
result <= add_bits(x, y); (a, b : IN BIT)
carry <= x AND y;
ELSE
(carry, result) <= "00";
END PROCESS;
END behavior;

• Functions must be called by other statements


• Parameters use positional association

49
Procedures
• Produce many output values
• Are invoked by statements
• May modify the parameters

PROCEDURE add_bits3 (SIGNAL a, b, en : IN BIT;


SIGNAL temp_result, temp_carry : OUT BIT) IS

BEGIN -- procedures can return multiple values


temp_result <= (a XOR b) AND en;
temp_carry <= a AND b AND en;

END add_bits3;

 Do not require a RETURN statement


50
Procedures

ARCHITECTURE behavior OF adder IS • With parameter passing, it is


BEGIN possible to further simplify the
PROCESS (enable, x, y) architecture
BEGIN
add_bits3(x, y, enable,
result, carry);
END PROCESS;
END behavior;

 The parameters must


be compatible both in PROCEDURE add_bits3
terms of data flow and (SIGNAL a, b, en : IN BIT;
data type SIGNAL temp_result,
temp_carry : OUT BIT)
51
Concurrent Procedure Calls

ARCHITECTURE example OF adder IS


BEGIN
U0: add_bits3 (a, b, en, temp_result, temp_carry ) ;
END example;

Arguments must be declared as signals

Name of procedure

52
Procedure calling parameters

Parameter defined as:


• signal - mode In, Inout, Out.
Inout and Out must be connected to a signal.
• variable - mode In, Inout, Out.
Inout and Out must be connected to a variable.
Default for Inout, and Out.
• constant - mode In only.
Can be connected any expression that evaluates to a
constant within the procedure. The default for In.

53
Operators

54
Built-in Operators

• Logical operators
– AND, OR, NAND, NOR, XOR, XNOR (XNOR in VHDL’93 on only !!!)
• Relational operators
– =, /=, <, <=, >, >=
• Addition operators
– +, -, &
• Multiplication operators
– *, /, mod, rem
• Miscellaneous operators
– **, abs, not

55
Synthesis of Logical Operators
...
signal A, B, C: BIT_VECTOR(3 downto 0);
signal D, E, F, G: BIT_VECTOR(1 downto 0);
signal H, I, J, K: BIT;
signal L, M, N, O, P: BOOLEAN;
...
A <= B and C;
D <= E or F or G;
H <= (I nand J) nand K;
L <= (M xor N) and (O xor P);

56
Synthesis of relational operators
signal A, B: BIT_VECTOR(3 downto 0);
signal C, D: BIT_VECTOR(1 downto 0);
signal E, F, G, H, I, J: BOOLEAN;
G <= (A = B);
H <= (C < D);
I <= (C >= D);
J <= (E > F);

57
Miscellaneous Operators
• The concatenation operator &
VARIABLE shifted, shiftin : BIT_VECTOR (0 TO 3);
...
shifted := shiftin(1 TO 3) & '0';

0 1 2 3
SHIFTIN 1 0 0 1

SHIFTED 0 0 1 0

 The exponentiation operator **


x := 5**5 -- 5^5, OK
y := 0.5**3 -- 0.5^3, OK
x := 4**0.5 -- 4^0.5, bad
y := 0.5**(-2) -- 0.5^(-2), OK

58
Operator overloading

• Operators manipulate the supplied data

• Most operators require both operands to be of the same type


– Exception: operands of physical type may be multiplied and
divided by integers and real numbers
– Result of an expression with a relational operator will be Boolean

• If one of the data types in the operator is not supported, the operator
has to be overloaded.

59
Operator overloading (ctd.)

Function "+" (a,b:std_logic_vector) return std_logic_vector;


Function "+" (a:std_logic_vector;b:integer) return std_logic_vector;
...
signal a,b,q:std_logic_vector;
...
q<=a + b; -- Normal operator usage
q<=a+1; -- Adding with other types (like integers) can also be defined
q<="+" (a,b); -- This is ok too!

Most definitions that ever will be needed are defined in the different IEEE
std_logic packages!!!
60
Potential problems (overloaded functions)

• Overloaded items cannot be resolved by return type


– Example: These overloaded functions cannot be disambiguated

FUNCTION "-" (a,b: natural) RETURN integer;


FUNCTION "-" (a,b: natural) RETURN natural;

61
Resolving Difficulties
• Overloaded items cannot be resolved if the argument types include
common literals, i.e.,
TYPE twobit IS ('0', '1');
TYPE fourbit IS ('U', '0', '1', 'Z');
FUNCTION abc (x: twobit) RETURN INTEGER;
FUNCTION abc (x: fourbit) RETURN INTEGER;
....
y <= abc('0'); -- Which function do we use?

– Resolve the ambiguity by qualifying the literal:


y <= abc(twobit’("0"));

– General tip: Use qualification to avoid numerous problems where the


compiler cannot seem to select a specific meaning, e.g., read (abc,
string’(“abcabc”));
62
Useful IEEE-packages...
use ieee.std_logic_1164.all; -- defines the type std_logic

use ieee.std_logic_arith.all; -- defines the types signed and unsigned (Synopsys std)
use ieee.numeric_std.all; -- alternative for declaring signed and unsigned (IEEE std)

-- define std_logic_vector to be interpreted as signed numbers


use ieee.std_logic_signed.all;
-- use ieee.numeric_std_signed.all; There is no IEEE numeric_std_signed

-- define std_logic_vector to be interpreted as unsigned numbers


use ieee.std_logic_unsigned.all;
use ieee.numeric_std_unsigned.all;

-- define std_logic_vector fixed and floating point subtypes


use ieee.float_pkg.all;
use ieee.fixed_pkg.all;

63
Floating Point Added in VHDL-2008

64
New subtypes
• VHDL-2008 introduces overloads of the
std_logic_vector to support synthesis of IEEE
floating and fixed point implementations:

– New subtypes: float32, float64, and float128


– New conversion function: to_real

– Plus a lot of configuration options...

65
Floating-Point

• A floating point number is represented by a sign bit,


exponent bits, and a mantissa (also called fraction
bits)
S Exponent Mantissa
Sign-Bit exp m

• The value is calculated as


FlP(B) = (-1)s * (1.m) * 2exp

• The exp often has a bias (offset) value, i.e,


FlP(B) = (-1)s * (1.m) * 2exp-(bias)

66
IEEE-754

• IEEE-754 defines a 32-bit floating point number as

27 exp 20 2-1 m 2-23


S Exponent Mantissa
32 31 exp 23 22 m 1

• The value of the 8 bit exponent is done according to


FlP(B) = (-1)s * (1.m) * 2exp-(127)
• Special bit patterns have been reserved

67
Floating-Point Numbers (IEEE)
• Exponent Values 1 to 254: normalized non-zero floating-point
numbers; biased exponent (-126...+127)
• Exponent of zero and fraction of zero: positive or negative zero
• Exponent of ones and fraction of zero: positive or negative
infinity
• Exponent of ones with a non-zero fraction: NotANumber (NAN -
Exception Condition)
• Exponent of zero and fraction of non-zero: Denormalized
number (true exponent is –126), represent numbers from
0 to 2-126
FlP(B) = (-1)s * (0.m) * 2-126
• There is also a standard for a 64-bit numbers, and 128-bit
numbers (IEEE 874)
68
VHDL-2008: Overloaded operators
• Implementation of
– Relational operators
– Logical operators
– Arithmetic operators
• Yes, it is now possible to synthesize mod, rem and /...

69
Restrictions
• The std_logic additions for supporting floating
point operators are synthesizable, but
– Excellent for modelling
– Not so good for synthesis
• Pipelining does not seem to work properly

• Use the inbuilt IP generators until synthesis tools


improve

70

You might also like