Vous êtes sur la page 1sur 60

F3 : Data Types & Packages

Types of VHDL Data types

Types

Access Composite

Array Record
Scalar

Integer Physical
Real Enumerated
Predefined (STANDARD) Data types

- bit ('0' or '1')


- bit_vector (array of bits)
- integer
- real
- time (physical data type)
- character
- string
(severity_level – used for assertions, more about that in exercise 2)
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;
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;
Enumerated
• Enumerated
– User defined range
– Enumerated example

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
... more statements ...
END PROCESS;
END TEST;
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


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;
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


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
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; -- number of the switch
Access Types

• 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);
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);
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);

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


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;


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;
Boolean, Bit and Bit_vector

Type Boolean is (false, true);


Type Bit is ('0', '1');
Type Bit_vector is array(integer range <>) of bit;
Character and String

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


-- 256 chars in VHDL’93

type String is array(positive range <>) of Character;


IEEE Predefined data types

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

type std_logic is resolved std_ulogic; -- resolution function call


type std_logic_vector is array (integer range <>) of std_logic;
Voltage levels

VOH VH

Noise Margin = 'X'


VOL VL

Logic Level '1' '0' Typical output voltages

TTL VH>2.4 V, VL<0.8 V, VOH=3.3 V, VOL=0.4V

CMOS VH>90% of VDD -VSS, VL<10% of VDD –VSS VOH=~VDD, VOL=~VSS


Equivalent Two-pole of output stage

VDD R
VL
VOH V=VOH
V
R=ROH
VL
VSS
Representation of 1’s and 0’s

VOH = 3.3V 'H', '1'


VIH = 2.4V
'W', 'X'
VIL = 0.8V
VOL = 0.4V 'L', '0'

Ri
~10 Mohms => 'Z'

Vi Ri = ~10 kOhms => 'L', 'H', 'W'

~10 Ohms => '0', '1', 'X'


Physical representation of std_ulogic

Vres
<0.8V >0.8V,<2.4V >2.4V - TTL
Rres <10% >10%, <90% >90% - CMOS (% of VDD-VSS)

<1kOhm '0' 'X' '1'

>1kOhm, <1MOhm 'L' 'W' 'H'

>1 MOhm (TTL)


'Z' 'Z' 'Z'
>1 GOhm (CMOS)
Testing all combinations
using std_logic

type mvl7 is ('X', '0', '1', 'Z', 'W', 'L', 'H');…

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;

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


10 20 30 40 50 60 70
Useful Shorthand Notation in
Assignments
constant a:integer:=523;
signal b:bit_vector(11 downto 0);

b<="000000010010";
b<=B"000000010010";
b<=B"0000_0001_0010";
b<=X"012"; -- Hexadecimal assignment
b<=O"0022"; -- Octal Assignment
Multi-dimensional Vector & Array
assignments
subtype instruction:bit_vector(31 downto 0);
signal regs:array(0 to 15) of instruction;

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


Alias Statement

signal instruction:bit_vector(31 downto 0);

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";
instruction 31..24 23..20 19..16 15..12 11..0
op2<="0001"; op1 op2 op3
op3<="0010";

ADD: -- reg(op1)<=reg(op2)+reg(op3)
reg(bit2int(op1))<=reg(bit2int(op2))+reg(bit2int(op3));
-- reg(0)<=reg(1)+reg(2)
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, others =>'0');
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'));


Aggregates (ctd.)

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
Type Attributes

Integer’high = 2,147,483,647

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

Bit’left = '0'

Bit’right = '1'
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
Type conversion (Similar Base)

Similar but not the same base type:

signal i:integer;
signal r:real;

i<=integer(r);
r<=real(i);
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<="00101" -- Error, is RHS a bit_vector or an a_type?


a<=a_type'("00101"); -- type qualifier
a<=a_type(s); -- type conversion
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);
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;
Packages
VHDL Hierarchy

Package

Generics Entity Ports

Architecture Architecture Architecture

Concurrent Process
Concurrent
Statements
Statements
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
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
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


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;
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
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


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 in terms PROCEDURE add_bits3
of data flow and data (SIGNAL a, b, en : IN BIT;
type SIGNAL temp_result,
temp_carry : OUT BIT)
Concurrent Procedure Calls

ARCHITECTURE example OF adder IS


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

Name of procedure
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.
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;
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;
Operators
In-built Operators

• Logical operators
– AND, OR, NAND, NOR, XOR, XNOR (XNOR in VHDL’93 only !!!)
• Relational operators
– =, /=, <, <=, >, >=
• Addition operators
– +, -, &
• Multiplication operators
– *, /, mod, rem
• Miscellaneous operators
– **, abs, not
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);
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);
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
Overloading Operators

• 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
Operator overloading

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


signal a,b,q:std_logic_vector;
...

q<=a + b; -- Normal operator usage


q<="+"(a,b); -- This is ok too!

Most definitions that are needed are defined in the


different IEEE std_logic packages!!!
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


use ieee.numeric_std.all; -- alternative for declaring signed and unsigned

-- define std_logic_vector to be interpreted as signed numbers


use ieee.std_logic_signed.all;
use ieee.numeric_std_signed.all;

-- 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;
Potential Problems
• Objects defined by subtypes derived from a 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;
BEGIN
C := B * A; -- OK
B := B+1; -- OK
END;
Potential problems (ctd.)

• 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;
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"));

Vous aimerez peut-être aussi