You are on page 1of 59

ECOM 4423

Hardware Description Language VHDL

Chapter 3
Signals and Data Types

Instructor: Dr. Ruba A. Salamah


Islamic University of Gaza

1
Objectives
• Object Classes and Object Types
• Signal Objects
• Scalar Types
• Type Std_Logic
• Scalar Literals and Scalar Constants
• Composite Types
• Arrays
• Types Unsigned and Signed
• Composite Literals and Composite Constants
• Integer Types
• Port Types for Synthesis
• Operators and Expressions
2
Object Classes
• An object’s class represents the nature of the object and
how it is used, for example, whether the object’s value
can be modified and whether it has a time element
associated with it.
• VHDL has four classes:
• Signal: an object with a current value and projected (future)
values. The projected values can be changed using signal
assignment statements.
• Constant: an object whose value cannot be changed after it
is initially specified.
• Variable: an object with only a current value. A variable’s
value can be changed using variable assignment statements.
• File: an object that consists of a sequence of values of a
specified type.
3
Object Types

• Each VHDL object must be of some type. An object’s


type defines the set of values the object can assume
and the set of operations that can be performed on
those values.
• There are five types:
• Scalar type
• Composite type
• Access type
• File type
• Protected type
4
Strong Typing

• VHDL is a strongly typed language with strictly


enforced type rules.
• If we mix different types in an expression or exceed
a type’s range of values, the compiler or simulator
generates an error message.
• For example, the integer value 0, the real number
0.0, and the bit value '0' are not the same type, and,
therefore, are not the same.
• VHDL’s strong typing makes it easier for a compiler
to detect errors.
5
Object Declarations

• All objects must be declared before being used. A


declaration introduces the name of an object, defines
its type, and, optionally, assigns an initial value.

signal x_bar, y_bar: std_logic;

6
Signal Objects

• As seen in Chapter 2, the ports of a design entity are


signals.
• From the viewpoint of a design entity, its ports can
be thought of as external signals, which are simply
referred to as ports.
• Signals within a design entity can be thought of as
local or internal signals, which are simply referred to
as signals.

7
Scope and Visibility
• For each signal declared, VHDL language rules define a
certain region of text, called scope or namespace, where
the signal’s name can be used.
• A signal is said to be visible (accessible) within its
scope.
• Outside of its scope, a signal is unknown. Any attempt to
use a signal outside of its scope causes a compilation
error.
• A signal’s scope is determined by where it is declared.
• A signal can be declared in the declarative part of an
entity declaration, the declarative part of an architecture
body, or in a package declaration.

8
Port Visibility & Signal Visibility
• Port Visibility A port’s name is visible in the entity
declaration in which it is declared and in any
architecture bodies associated with that entity
declaration.
• A component declaration in the declarative part of
an architecture makes that component’s port signals
visible in that architecture.
• Signal Visibility A signal declared in the declarative
part of an architecture body can only be used within
that architecture; it is not visible outside of that
architecture.(information hiding)
9
Port Declaration

• Port is used to refer only to signals declared by port


declarations
[signal] identifier_list : [ mode ] subtype_indication
[ := static_expression ]

• Example:
port (x, y: in std_logic;
eq: out std_logic);
• or
port (x: in std_logic;
y: in std_logic;
eq: out std_logic);
10
1-bit Comparator Example
library ieee;
use ieee.std_logic_1164.all;
entity compare is
port (x, y: in std_logic;
eq: out std_logic);
end compare;
architecture dataflow of compare is
begin
eq <=(not x and not y) or (x and y);
end dataflow;

Since x, y, and eq are declared in the port clause for compare, these signals are
visible (can be used) in any architecture associated with compare
11
Signal Declaration

• Signals are declared in the declarative part of an


architecture using a signal declaration statement.
signal identifier_list : subtype_indication [:= static_expression] ;

signal x_bar: std_logic := ‘0’ ;

• The syntax for a signal declaration looks just like that of


an interface signal declaration, except that the keyword
signal is required, and no mode is specified.
• Unlike ports, signals do not have a mode. A signal can
transfer information in either direction.
12
Example: 1-bit comparator using local signals
library ieee;
use ieee.std_logic_1164.all;
entity compare is
port (x, y: in std_logic; eq: out std_logic);
end compare;
architecture dataflow2 of compare is
signal x_bar, y_bar: std_logic;
begin
x_bar <= not x;
y_bar <= not y;
eq <= (x_bar and y_bar) or (x and y);
end dataflow2;

13
Scalar Types

14
Type Declaration

• Just as all signals must be declared with a type before


they are used, all types must also be declared before
use.
• Types are declared using a type declaration

type identifier is type_definition ;

• The type definition portion of a type declaration defines


the set of values an object of that type can have.
• Types used for ports must be declared in a package, so
that the type is visible to entity declarations.
15
Predefined types

• Predefined (built-in) types are those defined in


packages STANDARD and TEXTIO in the library
STD. This library is provided with all VHDL
compilers.
library std, work;
use std.standard.all;

• The predefined types in package STANDARD are


directly visible in a design without explicitly using any
library or use clauses.

16
Enumeration Types

• An enumeration type is declared by simply listing


(enumerating) all possible values for the type. There
must be at least one value in the list.
enumeration_type_declaration ::=
type identifier is ( enumeration_literal { , enumeraton_literal } )
enumeration_literal ::= identifier | character_literal

type state is (idle, state1, state2, state3);


signal current_state: state := idle;

17
Enumeration Types

• Examples:

18
Enumeration Types

• Each enumeration literal must be unique within the


type being declared.
• However, different enumeration types may use the
same literal. In such cases, the literal is said to be
overloaded.
• All scalar types are ordered. All relational operators
(>, <, =, and so on) are predefined for their values.
• Enumeration literals are ordered, in ascending order,
by their textual position in the list of literals defining
the type.
19
Enumeration Types

• Literal Overloading

20
Type Character

• Type character is an enumeration type, predefined in


package STANDARD, that corresponds to the
International Organization for Standardization (ISO)
8-bit encoded character set ISO 8859-1:1987. This
character set includes graphic characters and format
effectors.
• The definition of type character contains a mixture of
character literals and identifiers as elements:
• See table in the book page 91

variable my_char : character := 'A';


21
22
Type Bit

• Type bit is an enumeration type used as a simple


representation for a logic signal.
• The type declaration for bit appears in package
STANDARD as:
type bit is ('0','1');

Signal x: bit;

23
Subtype Declarations
• A type derived from another type is a subtype. The type from
which the subtype is derived is its base type.
• Creating and using a subtype allows us to make it clear which
values from the base type are valid for an object.
subtype identifier is [ resolution_function_name ] type_mark [ constraint ] ;

EX. subtype digitt is integer range 0 to 9;


signal f , g : digitt;

• A subtype declaration does not define a new type. The type of


a subtype is the same as its base type. Accordingly, the set of
operations allowed on a subtype is the same as the set
allowed on its base type.
24
Package STD_LOGIC_1164

• While VHDL has several predefined types, it does not


have one that provides more than two values to
represent a logic signal.
• A logic system that has more than two logic states (0
and 1) is a multivalued logic system.
• The IEEE Library, included with VHDL compilers,
includes package STD_LOGIC_ 1164.
• Package STD_LOGIC_1164 defines a nine value logic
system. Type std_ulogic and its subtype std_logic are
defined in this package.
• Also defined in this package are operators and functions
for operands of these types.
25
Std_ulogic

• Type std_ulogic is declared in package


STD_LOGIC_1164 as:
type std_ulogic is
(
'U' -- Uninitialized Lowercase versions of
'X' -- Forcing Unknown these characters are
'0' -- Forcing Low not valid
'1' -- Forcing High representations of
'Z' -- High Impedance std_ulogic values.
'W' -- Weak Unknown
'L' -- Weak Low
'H' -- Weak High
'-' -- Don't Care
);
26
State and Strength Properties

27
Unresolved & Resolved Types
• Type std_ulogic is an unresolved type.
• It is illegal for two (or more) sources to drive the same signal if
that signal is of an unresolved type.
• A resolved type is a type declared with a resolution function. A
resolution function is a function that defines, for all possible
combinations of one or more source values, the resulting
(resolved) value of a signal.

If we are describing a circuit


with three-state outputs used
in a bus interface, we need to
use a resolved data type.

28
Std_logic as a Resolved Subtype
• Std_logic is a subtype of
std_ulogic and is declared
in package
STD_LOGIC_1164 as:
subtype std_logic is resolved std_ulogic;

• Std_logic’s resolution
function resolved is defined
in package STD_LOGIC_
1164. In the case of
multiple sources for a
signal, the effect of the
multiple source values is
resolved to a single value.

29
Scalar Constants
• A constant is an object that is assigned a value only
once, normally when it is declared.
• The value of a constant cannot be changed in a
program. We can think of a constant as a literal
value with a name and type.
• Constants are used to make programs more
readable and to make it easier to change a value
throughout a program, by changing the value only in
the constant’s declaration.
constant identifier_list : subtype_indication := expression ;
constant high_impedance : std_logic := 'Z';
30
Composite Type
• A composite type consists of a collection of related elements that form
either an array or a record.

A composite object can be


operated on as a single
object or its constituent
elements can be operated
on individually.
An element of an array is
selected by the
array’s name and the
element’s index value.

31
Array Types
• Array types group elements of the same type together
as a single object. Arrays can be one dimensional or
multidimensional.
• A one-dimensional array is also called a vector. It has an
index whose value selects an element in the array by its
position.
• An element of a multidimensional array is selected
using its indices.
• A one-dimensional array is commonly used to represent
a bus in a digital system; for example, the address bus,
data bus, or control bus of a computer.
• Even though a two-dimensional array is not supported
for synthesis, an array of arrays is supported.
32
Unconstrained Array
• Before an array object can be declared, its array type
must be declared using an array type declaration.
• One way to declare an array type is as an
unconstrained array.
• An unconstrained array (unbounded array) is an array
whose dimensions and indices types are specified when
the array type is declared, but the bounds for each
dimension are left unspecified.

type identifier is array ( type_mark range <> ) of element_subtype_indication;

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

33
Type Std_logic_vector
• Std_logic_vector is a one-dimensional unconstrained array of
elements of type std_logic that is defined in package
STD_LOGIC_1164 as:
type std_logic_vector is array ( natural range <> ) of std_logic;
• When we declare an object of an unconstrained array type, we must
specify a constraint for the index bounds.
• the index range can be either an ascending (integer to integer) or
descending (integer downto integer)For example:

signal databyte: std_logic_vector (0 to 7);


signal databyte: std_logic_vector (7 downto 0);

• descending (downto) is recommended for ports and the lower


bound recommended to be 0. 34
A 4-bit comparator using std_logic_vector inputs.

35
Modeling Wires and Buses
SIGNAL a : STD_LOGIC;

a
1 wire
SIGNAL b : STD_LOGIC_VECTOR(7 DOWNTO 0);

b
8 bus

36
Constrained Array

• Another way to declare an array object is to declare


a constrained subtype of an
• unconstrained type and then declare the array object
using that subtype.
• For example:
subtype byte is std_logic_vector (7 downto 0);
signal databyte: byte;

type word is array (15 downto 0) of std_logic;


signal dataword: word;

37
Treating an Array
• We can treat an array as a single composite object
signal x, y : std_logic_vector (3 downto 0);
x <= y;
• Sometimes we want to deal with a single array element or a subset of
consecutive array elements.
x(3) <= '0';

x <= ('1','0','1','1');
x(3) <= '1';
x(2) <= '0'; named association
positional association
x(1) <= '1';
x(0) <= '1';
x <= (3 =>'1', 1 => '1', 0 => '1', 2 => '0');

38
Bit String Literals
• A bit string literal is a special form of string literal used to
represent a sequence of bit values as either binary,
octal, or hexadecimal numeric data.
• A bit string literal can contain any of the characters from
0 through 9, and a through f, or A through F.
• It must be prefixed by a B, O, or X to indicate binary,
octal, or hexadecimal base, respectively.
low_address <= B"01111001";
low_address <= X"79";

low_address <= O"171"; -- invalid assignment


low_address <= B"0111_1001";
low_address <= "0111_1001"; -- invalid assignment
39
Operators over an array data type

• Several operators are defined over the 1-D array


data type, including
• Array aggregate operator
• Concatenation operator
• Relational operator

40
Array aggregate

• Aggregate is a VHDL construct to assign a value to an array-


typed object
• E.g.,
a <= "10100000";
x <= (2 => '0', others => '1'); x <= (3|1|0 =>'1', 2 => '0');

a <= (7=>'1', 6=>'0', 0=>'0', 1=>'0', 5=>'1',


4=>'0', 3=>'0', 2=>'1');
a <= (7|5=>'1', 6|4|3|2|1|0=>'0');
a <= (7|5=>'1', others=>'0');
• E.g.,
a <= "00000000"
signal Data_Bus : Std_Logic_Vector (15 downto 0);
a <= (others=>'0'); Data_Bus <= (15 downto 8 => '0', 7 downto 0 => '1');
41
Array aggregate

• An aggregate can also be used to combine scalar signals


together so that their values can be assigned to an array and
treated as a vector within an architecture’s body.
signal rd_bar, wr_bar, s2_bar : std_logic;
signal cntrl : std_logic_vector(2 downto 0);
cntrl <= (rd_bar, wr_bar, s2_bar);

(rd_bar, wr_bar, s2_bar) <= "010";


slice

signal address : std_logic_vector (15 downto 0);


signal low_address: std_logic_vector (7 downto 0);
low_address <= address(7 downto 0);
42
Concatenation operator (&)

• The concatenation operator '&'


d <= "1011" & "0101";

d <= '0' & "1100101";


• Very useful operator -- can be used to shift elements
• e.g.,
y <= "00" & a(7 downto 2);
y <= a(7) & a(7) & a(7 downto 2);
y <= a(1 downto 0) & a(7 downto 2);

43
Relational operators for array

• operands must have the same element type but their


lengths may differ
• Two arrays are compared element by element, form the
left most element
• All following returns true
• "011"="011", "011">"010", "011">"00010", "0110">"011“
• Be careful – the following always returns false if sig1 is
shorter than sig2
if (sig1 = sig2) then

44
Composite Constants

• A composite constant is a constant that is an array or


record.
• When a constant of an unconstrained array type is
declared, its array bounds can be inferred from the
expression used to initialize the constant. For
example:

constant pattern : std_logic_vector := "11010101";

45
Types signed and unsigned

• Type std_logic_vector is not defined as a numeric


representation. It is simply an array of elements of
type std_logic. No arithmetic operators are defined
for it in package STD_LOGIC_1164.
• package NUMERIC_STD, defines two vector types
whose elements are type std_logic: The unsigned
and signed to represent unsigned and signed
numeric values.
type unsigned is array ( natural range <> ) of std_logic;

type signed is array ( natural range <> ) of std_logic;


46
Types signed and unsigned
• Type signed is interpreted as a signed binary number in 2’s
complement form. The leftmost element is the sign bit.
• Type unsigned is interpreted as an unsigned binary number
with the leftmost element as the most significant bit.
• To use either type unsigned or signed a design unit must be
preceded by the following context clause:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

signal m : unsigned := "1101";


signal s : unsigned (7 downto 0);
47
Interpretation of Unsigned and Signed Operators

• The VHDL arithmetic operators abs, *, /, mod, rem,


+, and – are overloaded in package
NUMERIC_STD for types unsigned and signed.
• For these overloaded operators the operands can
be:
• both unsigned, both signed, unsigned and natural, or
unsigned and integer.
• The relational operators are overloaded to handle
operands that :
• are both unsigned, both signed, unsigned and natural, or
unsigned and integer. 48
Conversion between Std_logic_vector, Unsigned,
and Signed
• Although types std_logic_vector, unsigned, and signed all
have elements that are type std_logic, they are different types.
• In VHDL these types are considered closely related.
• Type conversion between closely related types is
accomplished by simply using the name of the target type as if
it were a function. For example:
• if signal x is declared as type std_logic_vector and signal y is
declared as type unsigned, and they are of equal length

x <= y; -- illegal assignment, type conflict


y <= x: -- illegal assignment, type conflict

x <= std_logic_vector(y); -- valid assignment


y <= unsigned(x): -- valid assignment
49
Example

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
...
signal s1, s2, s3, s4, s5, s6: std_logic_vector(3 downto 0);
signal u1, u2, u3, u4, u6, u7: unsigned(3 downto 0);
signal sg: signed(3 downto 0);

50
Example Continue….
• Ok
u3 <= u2 + u1; --- ok, both operands unsigned
u4 <= u2 + 1; --- ok, operands unsigned and natural

• Wrong
u5 <= sg; -- type mismatch
u6 <= 5; -- type mismatch
• Fix
u5 <= unsigned(sg); -- type casting
u6 <= to_unsigned(5,4); -- conversion function

51
Example Continue….

• Wrong
u7 <= sg + u1; -- + undefined over the types
• Fix
u7 <= unsigned(sg) + u1; -- ok, but be careful
• Wrong
s3 <= u3; -- type mismatch
s4 <= 5; -- type mismatch
• Fix
s3 <= std_logic_vector(u3); -- type casting
s4 <= std_logic_vector(to_unsigned(5,4));
52
Example Continue….

• Wrong
s5 <= s2 + s1; + undefined over std_logic_vector
s6 <= s2 + 1; + undefined
• Fix
s5 <= std_logic_vector(unsigned(s2) + unsigned(s1));
s6 <= std_logic_vector(unsigned(s2) + 1);

53
Note

• Types std_logic_vector, unsigned, and signed are all


vectors whose elements are type std_logic.
• Signals of these types having n-elements are often
referred to as n-bit vectors.
• While this terminology is a misnomer, since the
elements of the vector are not actually type bit but
are instead type std_logic, it is commonly used.
• This terminology reflects the actuality of the
hardware being described.

54
Integer Type
• An integer type has values that are whole numbers in a
specified range.
• Type integer is declared in package STANDARD
• There are two predefined type integer subtypes: natural and
positive are defined in package STANDARD.
• Integer literals can be represented as decimal literals or based
literals
• A decimal literal representing an integer can be simply a sequence
of digits or exponential notation can be used.
100 or 1E2 or 1e2
• A based literal uses an explicitly specified base between 2 and 16.
10#100# or 2#1100100# or 2#0110_0100# or 16#64#
55
Synthesis of an Unconstrained Integer

• An unconstrained integer is synthesized as 32 bits.


For this reason, when used for synthesis, an integer
signal should always be constrained to the smallest
range of values required. A synthesizer will map
constrained integers to the minimum number of bits
required to represent the specified range to reduce
the amount of hardware synthesized.
entity compare_int is
port ( a,b: in integer range 0 to 15;
abstract type
equal: out boolean);
end compare_int;
56
Functions for Conversion to and from Type Integer

Example: If i is an integer and unsigned signal y has eight


elements, and signal x is std_logic_vector :

y <= to_unsigned(i,8);

x <= std_logic_vector(to_unsigned(i,8));
57
Homework#2

• Solve the following problems from the textbook


chapter2:
7, 16, 18, 21, 22, 24, 25, 26, 30,31

58
Finally!!

?
Any Question

59

You might also like