Upload
nguyendang
View
226
Download
4
Embed Size (px)
Citation preview
Digital Design with VHDL
By Benjamin Abramov
All rights reserved to Abramov B. 2
Course Topics
n Preface ………………………..…………….2
n Topic one ……………………………………32
n Topic two …………………….....................119
n Topic three…………………………………..206
n Topic four ……………………………………315
All rights reserved to Abramov B. 4
Preface
Very High Speed
Hardware
Description
Language
is a language for describing digital electronic
systems.
It was subsequently developed further under the
auspices of the Institute of Electrical and
Electronic Engineers à IEEE and adopted in
the form of the IEEE standard 1076.
All rights reserved to Abramov B. 5
HDL family
VHDL Verilog
AHDL
Abel
System C
System Verilog
All rights reserved to Abramov B. 6
VHDL History
nThe American Department Of Defense (DOD) signs a
development contract with IBM, TI & Intermatics for a standard
HDL.
n1987 – The IEEE-1076-87 VHDL Standard is signed.
n1988 – The first simulation programs in VHDL go out to market.
n1990 – The Israeli Ministry Of Defense initiates projects using
VHDL in some military companies.
n1995 – VITAL’95 standard is signed to include detailed timing
data in VHDL models.
All rights reserved to Abramov B. 9
VHDL standards
Standard VHDL Language Reference Manual in 1987.
This first standard version of the language is often
referred to as VHDL-87.
Like all IEEE standards, the VHDL standard is subject to
review every five years.
Next version of the language, giving us VHDL-93.
A seconds round of revision of the standard was started in
1998.
That process was completed in 2001.
The current version of the language VHDL-2001.
All rights reserved to Abramov B. 20
Simulator : functional testing. Provides a waveform diagram.
The designer has to check whether the design indeed behaves as it
is supposed to.
Synthesizer: provides a “net list” – design block diagram from the highest
level (the whole design as one block) to the lowest level (single logic gates).
Fitter: software tool that is used to configure a programmable chip according
to special design. The received result will be a chip that we designed.
VHDL Design Tools
All rights reserved to Abramov B. 27
Lexical Elements
Identifiers.
Identifiers are used to name items in a VHDL model.
A basic identifier
• May only contain alphabetic letters ( ‘A’ to ‘Z’ and ‘a’ to ‘z’),
decimal digits ( ‘0’ to ‘9’ ) and the underline character (‘_’)
• Must start with an alphabetic character
• May not include two successive underline characters.
All rights reserved to Abramov B. 28
Lexical Elements (cont)
Valid identifiers example.
Count_enable;
Shift_reg_8bit;
Invalid identifiers example.
8bit_shift_reg; -- start with digit
count__enable; -- two successive underlines
All rights reserved to Abramov B. 29
Lexical Elements (cont)
Special symbols:
VHDL uses a number of special symbols to denote operators,
to delimit parts of language constructs and as punctuation.
One character symbols:
“ # & ‘ ( ) * + - , . / : ; < = > [ ] |
Two characters symbols must be typed next to each other,
with no intervening space.
=> ** := /= >= <= <>
VHDL is non case sensitive language!
“a” and “A”, “deCOdeR” and “DEcoder” are the same names.
All rights reserved to Abramov B. 30
Lexical Elements (cont)
Comments:
A comments can be added to a line by writing two dashes together,
followed by the comment text.
For example:
-- this is example of comment
All rights reserved to Abramov B. 31
Lexical Elements (cont)Reserved words:
abs disconnected label package sla
access downto library port sll
after else linkage postponed sra
alias elsif literal procedure srl
all end loop process subtype
and entity map protected then
architecture exit mod pure to
array file nand range transport
assert for new record type
attribute function next register unaffected
begin generate nor reject units
block generic not rem until
body group null report use
buffer guarded of return variable
bus if on rol wait
case impure open ror when
component in or select while
configuration inertial others severity with
constant inout out shared xnor
is signal xor
All rights reserved to Abramov B. 32
Meta-comments
The meta-comments,
-- RTL_SYNTHESIS OFF
and
-- RTL_SYNTHESIS ON
cause the synthesis tool ignore the code between them.
All rights reserved to Abramov B. 33
Topic One
n Entity …………………………..33
n Port …………………………..35
n Port mode …………………….37
n Basic types ……………………45
n Architecture ………………….. 64
n Signals & Components ………71
n Test Bench……………………..110
All rights reserved to Abramov B. 34
Entity
The first basic building block in VHDL is entity.
üEntity describes the boundaries of the logic block.
üThe entity part provides system interface specification.
All rights reserved to Abramov B. 35
Entity (cont)
Entities in VHDL can describe different complexity leveled systems:
•Gates
•Discrete components (multiplexor,decoder …).
•Complex digital designs as controllers and processors
(DMAC, Pentium IV, 68000).
•A full system (PCI card, motherboard, …).
•Each of these will be described by their outer world interface:
AND
GATEMUX
4-1
X
yz
In 0
In 1
In2
In3
s1s0
All rights reserved to Abramov B. 36
Entity (cont)
The entity part is generally comprised of two elements:
• Parameters of the system as seen from the outside
(such the bus width or maximum clock frequency) - generics
• Connections that are transferring information
to and from the system (system’s inputs and outputs) - ports
Entity Parameters
Connections
All rights reserved to Abramov B. 37
Its ports and its generics are declared within the entity .
Syntax:
entity entity_name is
generic(generic_list);
port(port_list);
end entity entity_name;
Entity (cont)
optionally
optionally
All rights reserved to Abramov B. 38
Entity (cont)
Frequency
DividerFreq_InFreq_Out
Sel(1:0)
Rst
The port list must:
ü define name,
ü mode (i.e. direction)
ü and type
of each port of the entity.
All rights reserved to Abramov B. 39
Entity (cont)
We call the module frequency_divider entity,
and the inputs and outputs are ports.
entity frequency_divider is
port (
rst : in bit;
sel : in bit_vector(1 downto 0);
freq_in : in bit;
freq_out : out bit
);
end entity frequency_divider;
All rights reserved to Abramov B. 40
Entity (cont)
Port mode and read/write status
Mode Read Write
in yes no
out no yes
inout yes yes
buffer yes yes
All rights reserved to Abramov B. 41
Entity (cont)
A buffer mode port behaves in the similar way to an inout mode port,
in that the port can be both read and
assigned in the entity or block.
The source of a buffer port determines the driving
value of the port in the normal way.
However, when the port is read,
the value read is the driving value.
All rights reserved to Abramov B. 42
Entity (cont)
entity any_block is
port(
a : in bit;
b : in bit;
c : in bit;
d : in bit;
f : in bit;
e : out bit;
out_sig : buffer bit
);
end entity any_block;
All rights reserved to Abramov B. 43
Entity (cont)
buffer port mode example
Transmit out
Return for
“reuse”
A
logic
B
logic
All rights reserved to Abramov B. 44
Entity (cont)
inout port mode example
Inout port
always should
be
controlled!!!
All rights reserved to Abramov B. 46
Basic Types
Three basic predefined types :
Bit
Boolean
Integer
All rights reserved to Abramov B. 47
Boolean
One of the most important predefined enumeration type in VHDL
is boolean type. It is defined as:
type boolean is (false,true);
All rights reserved to Abramov B. 48
Boolean (cont)
The relational operators equality (“=”) and inequality (“/=”) can be
applied to operands of any types, including the composite types.
For example:
10=10;
“010”=”010”;
3 ns = 3 ns;
all yield the value true
All rights reserved to Abramov B. 49
Boolean (cont)
As well these operators can be applied to expressions
123=234;
‘a’/=’a’;
yield the value false.
All rights reserved to Abramov B. 50
Boolean (cont)
• The relational operators less-than (“<”),
less-than or equal-to (“<=”),
greater-than (”>”),
greater-than or equal-to (“>=”),
can only be applied to values of types that are ordered,
including all of the scalar types.
• As with the equality and inequality operators, the operands must be
of the same type, and result is a Boolean value.
All rights reserved to Abramov B. 51
Boolean (cont)
The logical operators
• and
• or
• nand
• nor
• xor
• xnor
• not
take operands that must be Boolean values,
the returned value Boolean .
All rights reserved to Abramov B. 52
Bit
Since VHDL is used to model digital systems,
it is useful to have a data type to represent bit values.
The predefined enumeration type bit serves this purpose.
It is defined as
type bit is (‘0’,’1’);
All rights reserved to Abramov B. 53
Bit (cont)
The logical operators for Boolean values can also be applied to values of type
bit, and they produce result of type bit.
The ‘0’ corresponds to false, and ‘1’ to true.
‘0’ and ‘1’ = ‘0’;
‘1’ or ‘0’ = ‘1’;
The operands must still be of the same type .
All rights reserved to Abramov B. 54
Bit (cont)
The difference between types Boolean and bit is that values are used to model
abstract conditions, whereas bit value is used to model hardware logic level.
Thus, ‘0’ represents a low logic level
and ‘1’ represent a high logic level.
Note: Logical values for object of the type bit
must be written in quotes
my_bit<=‘1’;
All rights reserved to Abramov B. 55
Bit Vector
The bit_vector type is predefines as standard one-dimensional array
type with each element being of type bit.
The bit_vector type is an unconstrained vector of elements of the
bit type.
The size of a particular vector is specified during its declaration.
The way the vector elements are indexed depends on the defined
range, and can be either ascending or descending .
All rights reserved to Abramov B. 56
Bit Vector (cont)Little endian: (high downto low) where high>=low
my_vector : bit_vector(7 downto 0);
Defined bus of 8 bit width and bit with index 7 is MSB
bit with index 0 is LSB (descending range).
Big endian: (low to high) where high>=low
your_vector : bit_vector(0 to 7);
Defined bus of 8 bit width and bit with index 7 is LSB
bit with index 7 is LSB (ascending range).
Note! The first bit and last bit index numbers define the
number of bits in the vector (i.e. high - low + 1).
Little endian form is preferred!!!
All rights reserved to Abramov B. 57
Bit Vector (cont)
If bit number 7 is msb, then its is declared in VHDL as
bit_vector(7 downto 0) and the decimal value of the register is 188.
If bit number 0 is msb, then its is declared in VHDL as
bit_vector(0 to 7) and the decimal value of the register is 61.
msb register lsb
1 0 1 1 1 1 0 0
All rights reserved to Abramov B. 58
Bit Vector (cont)
Assignment to an object of bit_vector type can be
performed using single element of array (by index),
concatenation, aggregates, slices or any combination of
them.
Logical value for objects of bit_vector type must be
written in double quotes.
my_bit_vector <= “1001”;
All rights reserved to Abramov B. 59
Bit Vector (cont)
A slice is a part of a vector accessed by a range clause
n vec(high downto low) or vec(low to high)
n indexes cannot go out of bounds of original
declaration
n range direction must be the same as the original
vector
n a single index is use to access a single bit e.g.
vec(4);
All rights reserved to Abramov B. 60
Integer
In VHDL, integer type used for the whole numbers.
An example of an integer type is the predefined type
integer, which includes all whole numbers re-presentable
on a particular host computer.
integer from (- (2**31) + 1) to ((2 **31) –1).
All rights reserved to Abramov B. 61
Integer (cont)
Each integer in VHDL represented by synthesizer like bus.
my_int : integer range 15 downto 0; -- declared range 4 bit;
my_int : integer range 10 downto 0; -- declared range 4 bit !!!
When integer range not declared, then by default the range is 32 bit.
port(
my_int : in integer ; -- range 32 bit
);
All rights reserved to Abramov B. 62
Integer (cont)
An integer type can be defined either in ascending or descending range.
my_int : integer range 15 downto 0; -- descending range 4 bit;
my_int : integer range 0 to 15; -- ascending range 4 bit
The operations that can be performed on values of integer types include the
familiar arithmetic operations.
It is an error to assign to an integer object a value,
which is from outside its range!
All rights reserved to Abramov B. 63
Integer (cont)
Subtypes natural and positive are predefined subtypes of integer.
natural >= 0;
positive >= 1;
subtype natural is integer range 0 to integer’high;
subtype positive is integer range 1 to integer’high;
All rights reserved to Abramov B. 64
Integer (cont)
Use Integers with Care !!!
• Synthesis tools create a 32-bit wide resources for unconstrained integers
• Do not use unconstrained integers for synthesis
signal Y_int, A_int, B_int : integer ;
Y_int <= A_int + B_int ;
• Specify a range with integers
signal A_int, B_int: integer range -8 to 7;
signal Y_int : integer range -16 to 15 ;
Y_int <= A_int + B_int ;
• Recommendation: Use integers only as constants or literals
Y_uv <= A_uv + 17 ;
All rights reserved to Abramov B. 65
Architecture
All rights reserved to Abramov B. 66
Architecture (cont)
The secondary unit in the library is architecture.
Syntax:
architecture arc_entity_name of entity_name is
architecture declaration area
begin
concurrent statements
end architecture arc_entity_name;
All rights reserved to Abramov B. 67
Architecture (cont)
Declarations may typically be any of the following:
üComponent
üType,
üSubtype,
üConstant,
üSignal,
üAttribute,
üFunction,
üProcedure,
üFile.
All rights reserved to Abramov B. 68
Architecture (cont)
architecture arc_entity_name of entity_name is
component component_name is
generic(generic_list);
port (port_list);
end component component_name ;
type some_type;
subtype subtype_name is base_type range range_constrain;
constant constant_name : type :=value;
signal signal_name : type;
attribute middle : integer;
attribute middle of signal_name: signal is signal_name'length/2;
alias my_alias : std_logic_vector(7 downto 0) is my_bus(31 downto 24);
begin
All rights reserved to Abramov B. 69
Architecture (cont)Ø Items declared in the architecture are visible in any
process or block within it.
ØAn architecture can contain mix of component instances,
processes or other concurrent statements.
ØAn entity can have one or more architectures.
(Which one is used depends on the configuration)
ØAn architecture cannot be analyzed unless the entity it refers to
exists in the same design library.
Ø The architecture contents starts after the begin statement.
This is called the dataflow environment.
ØAll statements in the dataflow environment are executed concurrently !!!
ØAssignment of a value to a port (signal) is done with the <=.
All rights reserved to Abramov B. 70
Architecture (cont)
architecture arc_parity_check of parity_check is
begin
parity_bit <= ((din(7) xor din(6)) xor (din(5) xor din(4))) xor
((din(3) xor din(2)) xor (din(1) xor din(0)));
end architecture arc_ parity_check;
All rights reserved to Abramov B. 71
Architecture (cont)
As a result of the above description we will receive the following hardware:
All rights reserved to Abramov B. 72
Signal
signal
•If we need a wire to transport data from one element of the design to another,
we call it signal.
Signals are declared at the architecture before BEGIN.
Declaration example:
SIGNAL my_signal: BIT;
All rights reserved to Abramov B. 73
Signal (cont)
n Signals are the primary object describing a hardware
system and are equivalent to “wires”.
n Represent communication channels among concurrent
statements of system’s specification.
n Signals and associated mechanisms of VHDL
( signal assignment statements, resolution function,
delays, etc.) are used to model inherent hardware
features such as concurrency, inertial characters of
signal propagation, buses with multiple driving
sources, etc.
All rights reserved to Abramov B. 74
Signal (cont)
Each signal has a history of values and may have multiple drivers,
each of which has a current value and projected future values.
Signal can be explicitly declared in the declarative part of:
● Package declaration; signals declared in a package are
visible in all design entity’s using the package.
● Architecture: signal is visible inside the architecture only.
● Block: the scope of such signals is limited to the block itself;
● Subprogram (function and procedure);
All rights reserved to Abramov B. 75
Signal (cont)
The signals can be classified as either internal or external.
External signals are signals that connect the system to the
outside world, they form the system’s interface (ports).
Internal signals, which are not visible from the outside, are
completely embedded inside the system and are part of its
internal architecture, providing signals between internal
circuits.
All rights reserved to Abramov B. 78
Signal (cont)
All rights reserved to Abramov B. 79
Signal (cont)
The architecture within signal declaration:
architecture arc_full_adder of full_adder is
-- signal declaration
signal sig1 : bit;
signal sig2 : bit;
signal sig3 : bit;
begin
s<= a xor b xor ci;
co<= sig1 or sig2 or sig3 ;
-- signal assignment
sig1<= a and b;
sig2<= a and ci;
sig3<= b and ci;
end architecture arc_full_adder;
All rights reserved to Abramov B. 83
Constant
Used to holding a value that can not be changed
during design description.
• Constants value is assigned during declaration
• Used for readability and modification reasons.
Syntax:
constant constant_name : type :=value;
All rights reserved to Abramov B. 84
Constant (cont)
constant byte_width : integer:=8;
constant num_of_bytes : integer:=4;
constant num_of_bits : integer:= num_of_bytes * bus_width;
signal my_dword : bit_vector( (num_of_bits – 1) downto 0);
signal my_bus : bit_vector( (byte_width –1) downto 0);
signal my_sig : bit_vector(15 downto 0);
constant all_ones : bit_vector( 15 downto 0):=x”ffff”;
constant VCC : bit:=‘1’;
constant GND : bit:=‘0’;
-----------------------------------------------------------------------------------
my_sig <= all_ones; -- the constant used to set of default value
All rights reserved to Abramov B. 91
Component
Components:
üPreviously coded, simulated, synthesized and placed in design library
Structural VHDL:
üPossibility of creating hierarchical designs built from a set of
interconnected components.
Design refinement :
üSimplification of debugging process
üThe smaller, less complex circuit, the easier debugging process
Component representation:
üIn terms of other, smaller components (structural VHDL)
üLogic expressions
üUsing behavioural VHDL (mixed style coding)
All rights reserved to Abramov B. 92
Component (cont)
Structural VHDL:
üEntity implementation by specifying its composition from subsystems
üStructural architectural body – system composed only of interconnected subsystems
üElements of structural architecture:
1. Signal declaration
2. Component declaration - specification of external interface to component
in terms of generic constants and ports.
Component declaration uses the same name of component as entity of
the component module.
The same port declaration as module entity declared as component.
3. Component instantiation – specifies usage of module in design
All rights reserved to Abramov B. 93
Hierarchical Project (cont)
The port list must define the name, the mode,
and the type of each port on the component.
component half_adder is
port(
a : in std_logic;
b : in std_logic;
s : out std_logic;
co: out std_logic
);
end component half_adder ;
All rights reserved to Abramov B. 94
Hierarchical Project (cont)
A component declaration doest not define
the entity-architecture pair to be bound to each instance,
or even the ports on the entity.
In an architecture , components must be declared before the
begin statement:
All rights reserved to Abramov B. 95
Hierarchical Project (cont)
architecture arc_hierarchy_design of hierarchy_design is
-- signals and others resources of architecture
component half_adder is
port(
a : in bit
b : in bit;
s : out std_logic;
co: out std_logic
);
end component half_adder ;
begin
--the architecture contents
end architecture arc_ hierarchy_design;
All rights reserved to Abramov B. 96
Hierarchical Project (cont)
All rights reserved to Abramov B. 97
Hierarchical Project (cont)
entity half_adder is
port(
a : in std_logic;
b : in std_logic;
s : out std_logic;
co: out std_logic
);
end entity half_adder;
architecture arc_half_adder of half_adder is
begin
s<= a xor b;
co<= a and b;
end architecture arc_half_adder;
All rights reserved to Abramov B. 98
Hierarchical Project (cont)
entity full_adder is
port(
a : in std_logic;
b : in std_logic;
ci: in std_logic;
s : out std_logic;
co: out std_logic
);
end entity full_adder;
All rights reserved to Abramov B. 99
Hierarchical Project (cont)
architecture arc_full_adder of full_adder is
component half_adder is
port(
a : in std_logic;
b : in std_logic;
s : out std_logic;
co: out std_logic
);
end component half_adder ;
signal co1,co2 : std_logic;
signal a_xor_b : std_logic;
All rights reserved to Abramov B. 100
Hierarchical Project (cont)begin
u1: half_adder -- instantiation by name
port map(
a => a,
b => b,
s => a_xor_b,
co => co1);
u2: half_adder -- instantiation by name
port map(
a => a_xor_b,
b => ci,
s => s,
co => co2);
co<= co1 or c02;
end architecture arc_full_adder;
All rights reserved to Abramov B. 101
Hierarchical Project (cont)Rules:
n The instance label is compulsory.
n The component name must match the relevant component
declaration.
n The association list defines which local signals connect to
which component ports.
n The instantiation by name, where ports are explicitly
referenced and order is not important through it’s preferred.
n The instantiation by name are the pairs of signals where each
pair consists of two parts:
u The left part of the expression serve as name of port of the
relevant component
u The right part of the expression serves as name of connected
signal (or port of other component)
All rights reserved to Abramov B. 102
Hierarchical Project (cont)
The alternative is named association – instantiation by position.
The signals are connected up in the order in which the port
were declared.
For example :
u2: half_adder
port map ( a_xor_b, ci , s, co2);
This way of describe is more compact, but not readably.
All rights reserved to Abramov B. 103
Hierarchical Project (cont)
Output Port may be left unconnected using the
keyword open:
u2: half_adder
port map ( a_xor_b, ci , s, open);
All rights reserved to Abramov B. 104
Hierarchical Project (cont)
In VHDL-93 standard, an entity-architecture pair may be directly instantiated, i.e.
component need not declared. This is more compact, but not readably.
architecture arc_full_adder of full_adder is
signal co1,co2 : std_logic;
signal a_xor_b : std_logic;
begin
u1: entity work.half_adder(arc_1)
port map(a,b,a_xor_b,co1);
u2: entity work.half_adder(arc_2)
port map(a_xor_b,ci,s,co2);
co<= co1 or c02;
end architecture arc_full_adder;
All rights reserved to Abramov B. 105
Self Work
architecture arc_ripple_adder4 of ripple_adder4 is
-- component declaration comes here
signal c : bit_vector(2 downto 0);
begin
fa0: fa
port map (a_in => a(0),b_in=>b(0),c_in=>c_in_r, c_out=>c(0),s_out=>s(0));
fa1: fa ……………………
component fa is
port ( a_in : in bit;
b_in : in bit;
c_in : in bit;
c_out : out bit;
s_out : out bit);
end component fa;
All rights reserved to Abramov B. 114
Typical VHDL file structure
Library's and packages declaration
Entity declaration
Architecture
Configuration
All rights reserved to Abramov B. 115
Topic Two
n Data Assignment ………………120
n Scalar types…………………….133
n String ……………………………141
n User defined types……………..142
n Resolved types………………....147
n Subtypes………………………..166
n Type conversions………………171
n Expressions and Operators…...176
All rights reserved to Abramov B. 116
Data Assignment
ü For assignment VHDL uses the combination of symbols <=
ü An assignment to a port defines a driver to that port.
ü A standard port has only one source (driver).
ü Assignment can’t be done between different types!
All rights reserved to Abramov B. 117
Data Assignment (cont)
Examples:
my_sig,any_sig : bit;
my_int : integer range 15 downto 0;
my_boolean : boolean;
my_bus , any_bus : bit_vector(15 downto 0);
------------------------------------------------------------
my_sig<=’1’;
any_sig<=my_sig; -- any_sig=’1’
my_int<=12;
my_int<= 30; --wrong, to large value, over the range
my_boolean<=true;
my_bus<= ”0000000000000000”;
my_bus(15 downto 8)<= x”ff”; -- now my_bus is “1111111100000000”;
my_bus(0)<=my_sig; -- now my_bus is “1111111100000001”;
any_bus<=my_bus;
All rights reserved to Abramov B. 118
Data Assignment (cont)
For bus assignment VHDL supports two different forms of assignment:
aggregate and concatenation.
Aggregate is a grouping of values in order to form an array.
signal a,b,c,d : bit;
nibble : bit_vector(3 downto 0);
a<=’1’;
b<=’0’;
c<=’1’;
d<=’0’;
All rights reserved to Abramov B. 119
Data Assignment (cont)
nibble<=(a,b,c,d); -- nibble=”1010”;
Equivalent assignment is :
nibble(3)<=a;
nibble(2)<=b;
nibble(1)<=c;
nibble(0)<=d;
All rights reserved to Abramov B. 120
Data Assignment (cont)
Aggregate
Positional associationNamed association
All rights reserved to Abramov B. 121
Data Assignment (cont)
Positional association – where the values are associated with
elements from left to right.
nibble<=(‘0’,’1’,’0’,’1’); -- direct assignment in positional association.
--nibble=”0101”
Named association – where elements are explicitly referenced
and order is not important.
nibble<=(2=>a,1=> b,0=>d,3=>c); -- nibble=”1100”
All rights reserved to Abramov B. 122
Data Assignment (cont)
With positional association , elements may be grouped together
using the | (pipe) symbol or a range.
The keywords others may be used to refer to all elements.
nibble<= (3|2 =>’1’, others=> ‘0’); -- nibble =”1100”;
nibble <=(3 downto 1 =>’0’,0=>’1’); -- nibble =”0001”;
nibble<=(others=>’0’); --nibble=”0000”;
All rights reserved to Abramov B. 123
Data Assignment (cont)
Another kind of aggregate is grouped assignment, i.e. assigning value to a
number of elements of the same type:
signal a,b,c,d : bit;
(a,b,c,d)<= bit_vector’(x”5”);
Equivalent assignment is :
a<=‘0’;
b<=‘1’;
c<=‘0’;
d<=‘1’;
All rights reserved to Abramov B. 124
Data Assignment (cont)
Aggregate example:
signal A : bit_vector(7 downto 0);
signal Asel: bit;
We want to build the following circuit:
The elegant deciding of this task by using aggregate looks so:
signal Asel_vector: bit_vector(7 downto 0);
………
Asel_vector<=(others=>Asel);
T<=A and Asel_vector;
All rights reserved to Abramov B. 125
Data Assignment (cont)
Concatenation
The concatenation operator (denoted as &) composes two one-
dimensional arrays into one larger array of the same type.
my_bus : bit_vector(7 downto 0);
nibble <=a & b & c & d; -- nibble=”1010”;
my_bus<= nibble(2 downto 1) & nibble(0) & nibble(3) & “0010”;
All rights reserved to Abramov B. 126
Data Assignment (cont)
Constant valuesmy_bus : bit_vector(7 downto 0);
your_bus : bit_vector(5 downto 0);
my_bus<= “01011100”; --binary value by default
your_bus<=b”010111”; -- explicit binary value
my_bus<=“0111_0101”; --binary value with nibble separator
your_bus<=o”67”; --octal base of value presentation
my_bus<=x”a5”; -- hexadecimal base
üBe Careful!
b”0” -- 1 bit with value 0
o”0” -- 3 bits with value 0, same as B”000”
x”0” -- 4 bits with value 0, same as B”0000”
b”0” ≠ o”0” ≠ x”0”
All rights reserved to Abramov B. 128
Self WorkWrite entity and architecture for the following design using signals.
Use a. concatenation
b. aggregate
For constructing out_bus port.
In_bus
Out_bus
a
b
y
Smart_box
sig1
sig2
sig3
sig4
sig5
sig6
(0)
(1)
(2)
(2)
(1)
(0)
All rights reserved to Abramov B. 129
Scalar types
Next scalar type (integer type is first) is floating point type .
A floating point type is approximation to the set
of real numbers in a specified range.
The precision of the approximation is not defined by the VHDL
language standard, however it must be at least six decimal digits.
The values may be within the range from -1E38 to +1E38.
All rights reserved to Abramov B. 130
Scalar types (cont)
A floating point type is declared using the syntax:
floating_type_definition := range_constraint
Some examples are:
type signal_level is range -10.00 to +10.00;
type probability is range 0.0 to 1.0;
All rights reserved to Abramov B. 131
Scalar types (cont)
There is a predefined floating point type called real.
The range of this type is implementation defined, though it
is guaranteed that its value is within -1E38 to +1E38 range.
Note: This type is not supported by synthesis tools.
All rights reserved to Abramov B. 132
Scalar types (cont)
The predefined physical type time is very important in VHDL,
as it used extensively to specify delay.
Its definition is implementation defined
type time is range –(2**31) to (2**31)
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hr = 60 min;
end units;
All rights reserved to Abramov B. 133
Scalar types (cont)VHDL provides a predefined function now that returns the current simulation time.
pure function now return delay_length;
delay_length is predefined subtype of the physical type time,
constrained to non-negative time value.
The time type is not supported by synthesis tools.
It is used in test_benches and modeling.
For example:
if ( now < 100 ns) then
wait for (100 ns – now);
do something
end if;
All rights reserved to Abramov B. 134
Scalar types (cont)
The character data type enumerates the ASCII character set.
Nonprinting characters are represented by a three-letter name,
such as NUL for the null character.
Printable characters are represented by themselves,
in single quotation marks, as follows:
CHARACTER_VAR: character;
. . .
CHARACTER_VAR <= ’A’;
All rights reserved to Abramov B. 135
Scalar types (cont)
type character is ( NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, HT, LF, VT, FF, CR, SO, SI, DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FSP, GSP, RSP, USP, ' ', '!', '"', '#', '$', '%', '&', ''', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', DEL);
All rights reserved to Abramov B. 136
Scalar types (cont)
Type character is an example of an enumeration type containing
a mixture of identifiers and characters.
Also, the characters '0' and '1' are members of both bit and
character types.
When '0' or '1' occur in a program, the context will be used to
determine which type is being used.
All rights reserved to Abramov B. 137
String
The string data type is an unconstrained array of characters.
string value is enclosed in double quotation marks as follows:
signal header: string(1 to 10);
header <= ”start_time”;
The string index always starts from 1 and should be ascending only!!!
All rights reserved to Abramov B. 138
User defined types
The next type of VHDL is the user defined enumeration type.
type my_type is (idle,st_start,st_1,st_2);
This type is very useful to encoding state machine description .
idle
St_start
St_1
St_2
All rights reserved to Abramov B. 139
User defined types (cont)
Enumeration (literal values enumerated in a list)
Example :
type octal_digit is (‘0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’);
signal curr_digit : octal_digit;
………….
…………
curr_digit <= ‘2’;
All rights reserved to Abramov B. 140
User defined types (cont)
Different enumeration types may include the same identifier as a literal
(overloading).
To illustrate this, consider the following declarations:
type level is (unknown,low,medium,high);
type temperature_level is (dangerously_high,high,ok);
signal logic_level : level;
signal temp_level : temperature_level;
…………
logic_level<=high;
temp_level<=high;
Note: logic_level /= temperature_level !!! These are different types!!!
All rights reserved to Abramov B. 141
User defined types (cont)
logic_level<=high;
temperature_level<=high;
Solution for this problem is qualified expression.
We can distinguish between the common literal values by writing:
logic_level<=level’(high);
All rights reserved to Abramov B. 142
User defined types (cont)
The hardware implementation of the above types is bus.
Width of bus depends on encoding style.
For example :
type my_type is (idle,st_start,st_1,st_2);
State
name
Encoding style
Binary Gray One_Hot
idle “00” “00” “0001”
St_start “01” “01” “0010”
St_1 “10” “11” “0100”
St_2 “11” “10” “1000”
All rights reserved to Abramov B. 155
Resolved type (cont)
STD_LOGIC and STD_ULOGIC can be assigned to each other:
sl : std_logic;
sul : std_ulogic;
sl<=sul; --correct;
sul<=sl; --correct;
STD_LOGIC_VECTOR and STD_ULOGIC_VECTOR
can not be assigned to each other:
slv : std_logic_vector(7 downto 0);
sulv : std_ulogic_vector(7 downto 0);
slv<=sulv; --wrong;
sulv<=slv; --wrong;
All rights reserved to Abramov B. 156
Resolved type (cont)
The package STD_LOGIC_ARITH defines two new data types,
Both arrays of STD_LOGIC:
UNSIGNED => Positive only
SIGNED => Positive and Negative ( twos compliment)
All rights reserved to Abramov B. 157
Resolved type (cont)
STD_LOGIC_ARITH containing arithmetic and logical operators for
combinations of vectors and integers, along with useful function
for converting between them using overloading.
The STD_LOGIC_ARITH package do not contain arithmetic operation
For std_logic_vectors and std_ulogic_vectors !
Only for signed and unsigned types.
All rights reserved to Abramov B. 158
Resolved type (cont)
A : std_logic_vector(3 downto 0);
B : unsigned(3 downto 0);
b<=a + 7; -- wrong
b<=unsigned(a) + 7; -- correct
Casting a into an unsigned vector enable the adding operation.
All rights reserved to Abramov B. 159
Resolved type (cont)
STD_LOGIC_SIGNED and STD_LOGIC_UNSIGNED
Includes a set of signed/unsigned arithmetic and conversion function for
std_logic_vectors.
These 2 packages are automatically performing casting into unsigned or signed types.
Only one package STD_LOGIC_SIGNED or STD_LOGIC_UNSIGNED
May be used for a specific design!
•Designs that have only positive vectors will use the std_logic_unsigned package.
•Designs that have positive and negative vectors will use the std_logic_signed package.
All rights reserved to Abramov B. 160
Resolved type (cont)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity comp is
port (a,b : in std_logic_vector(7 downto 0);
comp_out : out boolean);
end entity comp;
architecture arc_comp of comp is
begin
comp_out <= (a>b);
end architecture arc_comp
where:
a=x”07”
b=x”82”
comp_out is false
All rights reserved to Abramov B. 161
Resolved type (cont)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity comp is
port (a,b : in std_logic_vector(7 downto 0);
comp_out : out boolean);
end entity comp;
architecture arc_comp of comp is
begin
comp_out <= (a>b);
end architecture arc_comp;
where:
a=x”07”
b=x”82”
comp_out is true
All rights reserved to Abramov B. 162
Subtypes
Subtype – defines a new type contains parts of the values of a previously
defined type.
subtype subtype_name is base_type range range_constraint;
Example ( user-defined subtypes):
subtype nibble is std_logic_vector( 3 downto 0);
subtype byte is std_logic_vector(7 downto 0);
All rights reserved to Abramov B. 163
Subtypes (cont)A subtype object can be assigned to its base type object:
subtype byte is std_logic_vector(7 downto 0);
subtype short is integer range (2**16 –1) downto 0;
signal my_byte : byte;
signal new_byte : std_logic_vector(7 downto 0);
signal new_word : std_logic_vector(15 downto 0);
signal my_natural : natural;
signal my_int : integer;
my_byte<= x”ff”;
new_byte<= my_byte;
new_word<= my_byte & my_byte; -- concatenation
my_int<= my_natural;
my_natural<=my_int ; -- WRONG
All rights reserved to Abramov B. 164
Subtypes (cont)
subtype two_bits is std_logic_vector(1 downto 0);
signal a,b : std_logic;
signal ab : std_logic_vector(1 downto 0);
………………………….
…………………………
ab<=two_bits’(a & b);
All rights reserved to Abramov B. 165
Subtypes (cont)
subtype large_word is std_logic_vector(127 downto 0);
signal my_word : large_word;
begin
…………………………
empty_flag<=my_word=large_word’(others=>’0’);
All rights reserved to Abramov B. 166
Subtypes (cont)Pre-defined subtypes:
subtype natural is integer range 0 to integer’high;-- ( 0 to MAX_INTEGER)
subtype positive is integer range 1 to integer’high;-- ( 1 to MAX_INTEGER)
subtype delay_lengt is time range 0 fs to time’high;
For modeling and
simulations only !!!
All rights reserved to Abramov B. 167
Type conversions
Type conversions change an expression’s type.
The syntax of a type conversion is
type_name( expression)
The expression must evaluate to a value of a type that is
convertible into type type_name .
• Type conversions can convert between integer types or
between similar array types.
• Two array types are similar if they have the same length and
have convertible or identical element types.
All rights reserved to Abramov B. 168
Type conversions (cont)
•Type conversions can convert between integer types or
between similar array types.
• Two array types are similar if they have the same length
and have convertible or identical element types.
• Enumerated types are not convertible.
All rights reserved to Abramov B. 172
Expressions in VHDL are much like expressions in other programming languages.
An expression is a formula combining primaries with operators.
Primaries include:
• names of objects
• literals,
• function calls
• parenthesized expressions.
Expressions and Operators
All rights reserved to Abramov B. 173
• and
• or
• nand
• nor
• xor
• xnor
• not
The above logical operators operate on values of types bit, boolean, std_ulogic,
std_logic and also on one-dimensional arrays of these types.
For array operands, the operation is applied between corresponding elements of each
array, yielding an array of the same length as the result.
Expressions and Operators
All rights reserved to Abramov B. 174
s<= a xor b xor ci;
co<= (a and b) or (a and ci) or (a and ci);
The result of this description:
Expressions and Operators
All rights reserved to Abramov B. 175
Problem:
Describe the 3 input NAND logic gate.
D<= A nand B nand C; -- Syntax wrong !!!
This is not logic gate NAND –3
D<= not (A and B and C); -- Correct
Expressions and Operators
All rights reserved to Abramov B. 176
Hierarchy with parentheses:
parity_bit <= ((din(7) xor din(6)) xor (din(5) xor din(4))) xor
((din(3) xor din(2)) xor (din(1) xor din(0)));
Expressions and Operators
All rights reserved to Abramov B. 177
As your known, the logical operators of VHDL has binary operators:
What is happening at this circuit ?
S<= A or B or (not B);
If this function is degrades to constant, or the compiler builds it?
Expressions and Operators
All rights reserved to Abramov B. 178
Simple Arithmetic Expression
Z <= A + B + C + D;
The parser performs each addition in order,
as though parentheses were placed within the
expression as follows:
Z <= ((A + B) + C) + D;
Expressions and Operators
All rights reserved to Abramov B. 179
The compiler constructs the expression tree
Expressions and Operators
All rights reserved to Abramov B. 180
If the arrival times of all the signals are the same,
the length of the critical path of the expression equals three
adder delays.
The critical path delay can be reduced to two adder delays if
you insert parentheses as follows:
Z <= (A + B) + (C + D);
Expressions and Operators
All rights reserved to Abramov B. 181
Balanced Adder Tree (Same Arrival Times for All Signals)
Expressions and Operators
All rights reserved to Abramov B. 182
The relational operators :
• =
• /=
• <
• <=
• >
• >=
must have both operands of the same type, and yield boolean results.
The equality operators (= and /=) can have operands of any type.
For composite types, two values are equal if all of their corresponding
elements are equal.
The remaining operators must have operands which are scalar types or
one-dimensional arrays of discrete types.
Expressions and Operators
All rights reserved to Abramov B. 183
The sign operators (+ and -)
and the addition (+)
and subtraction (-) operators
have their usual meaning on numeric operands.
The concatenation operator (&) operates on one-dimensional arrays
to form a new array with the contents of the right operand following
the contents of the left operand.
It can also concatenate a single new element to an array,
or two individual elements to form an array.
The concatenation operator is most commonly used with strings.
Expressions and Operators
All rights reserved to Abramov B. 184
entity adder is
port(
a : in integer range 31 downto 0;
b : in integer range 31 downto 0;
c : out integer range 63 downto 0
);
end entity adder;
architecture arc_adder of adder is
begin
c<= a + b;
end architecture arc_adder;
Expressions and Operators
All rights reserved to Abramov B. 185
entity bus_conc is
port(
a : in std_logic_vector (7 downto 0);
b : in std_logic_vector (7 downto 0);
c : out std_logic_vector (15 downto 0)
);
end entity bus_conc ;
architecture arc_ bus_conc of bus_conc is
begin
c<= a & b;
end architecture bus_conc ;
Expressions and Operators
All rights reserved to Abramov B. 186
The absolute value (abs) operator works on any numeric type.entity alarm is
port(
temp_level : in integer;
critical _level : in integer;
alarm_sig : out boolean
);
end entity alarm;
architecture arc_ alarm of alarm is
begin
-- the temperature should be in the range from –critical_level to +critical_level
alarm_sig <= ( (abs temp_level) >= critical_level);
end architecture arc_ alarm;
Expressions and Operators
All rights reserved to Abramov B. 187
The multiplication (*) and division (/) operators
work on integer, floating point and physical types
(time for example).
Be careful !!!
The multiplication and division operations are source
of hardware overhead.
The synthesis tools supports division operation only
for constants (one from two operands).
Expressions and Operators
All rights reserved to Abramov B. 188
Expressions and Operators
The modulus (mod) and remainder (rem) operators only
work on integer types.
The exponentiation (**) operator can have an integer or
floating point left operand, but must have an integer right
operand.
A negative right operand is only allowed if the left
operand is a floating point number.
All rights reserved to Abramov B. 189
A mod B = A – B * N (in which N is an integer)
ü the sign of (A mod B) is the same as the sign of B
ü abs (A mod B) < abs (B)
c<= (c + 1) mod 16 ; -- c would never be more then 15
6 mod 4 -- 2
4 mod 6 -- 4
6 mod (-4) -- -2
(-6) mod 4 -- 2
For synthesis the modulo operator supports when
the right operand is 2**n
Expressions and Operators
All rights reserved to Abramov B. 190
The remainder operation is defined such that the relation:
a=(a/b)*b + (a rem b) or (a rem b) = a – (a/b)*b and
abs (a rem b) < abs (b),
The result of the rem operator has the sign of its first operand ,
while the result of the mod operators has the sign of the second operand.
6 rem 4 -- 2
4 rem 6 -- 4
6 rem (-4) -- 2
(-6) rem 4 -- -2
For synthesis the remainder operator supports when
the right operand is 2**n
Expressions and Operators
All rights reserved to Abramov B. 191
Typical using of power operator by integer range declaration
entity mul is
port(
a : in integer range ((2**8) – 1) downto 0;
b : in integer range ((2**8) – 1) downto 0;
res : out integer range ((2**16) – 1) downto 0
);
end entity mul;
architecture arc_mul of mul is
begin
res<= a * b;
end architecture arc_mul;
Expressions and Operators
All rights reserved to Abramov B. 192
Highest precedence: ** abs not
* / mod rem
+ (sign) - (sign)
+ - &
= /= < <= > >=
Lowest precedence: and or nand nor xor
Expressions and Operators
All rights reserved to Abramov B. 193
VHDL-93 has a wide set of shift operators. The table bellow list the shift operators.
Name Operation
sll Shift left logical
srl Shift right logical
sla Shift left arithmetic
sra Shift right arithmetic
rol Rotate left logical
ror Rotate right logical
Expressions and Operators
All rights reserved to Abramov B. 194
The shift operators are defined for the one-dimensional
array with the elements of type bit .
For the shift operator an array is the left operant L
and the integer is the right operand R.
The right operand R represents the number of position the left operant L
should be shifted.
As the result of shifting, the value of the same type as the left operand is returned.
Expressions and Operators
All rights reserved to Abramov B. 195
signal source : bit_vector(3 downto 0);
signal dest : bit_vector(3 downto 0);
……………
source<=”1011”;
dest<= source sll 1; -- dest=”0110” the ‘0’ is inserted
dest<= source srl 1; -- dest=”0101”
dest<= source sll 3; -- dest=”1000”
dest<= source sll –3; -- dest<= source srl 3 ( “0001”)
dest<= source sla 1; -- dest=”0111” the ‘1’ is inserted
dest<= source sra 1; -- dest=”1101”
dest<= source rol 1; --dest=”0111”
dest<= source ror 1; -- dest=”1101”
Expressions and Operators
All rights reserved to Abramov B. 196
The shift operators are defined for one-dimensional
array with the elements of type bit (bit_vector)
However it also can be used for std_logic_vector, but only
along with type conversion function.
signal source : std_logic_vector(3 downto 0);
signal dest : std_logic_vector(3 downto 0);
……………
dest<= to_stdlogicvector(to_bitvector(source) sll 2);
Expressions and Operators
All rights reserved to Abramov B. 197
Sources and target sizes:
Expressions and Operators
All rights reserved to Abramov B. 198
As we saw VHDL strictly demands conformity of the size of operands.
This excessive severity can sometimes be an obstacle, for example at
realization of addition operation .
As is known at addition the size of result on one bit is more than the size of
biggest from operands.
How it is possible to overcome this contradiction?
One of possible variants :
signal a, b : std_logic_vector(n downto 0);
signal sum : std_logic_vector((n+1) downto 0);
sum<=(‘0’ & a) + (‘0’ & b);
Expressions and Operators
All rights reserved to Abramov B. 199
Expressions and Operators Problem : perform the next operation -> A + B + cin
Where A and B is two buses of 8 bit width and cin is carry input bit.
Solution:
signal temp_a, temp_b, temp_sum : std_logic_vector(9 downto 0);
signal sum : std_logic_vector(8 downto 0);
temp_a <= ‘0’ & a & ‘1’; temp_b <= ‘0’ & b & cin;
temp_sum <= temp_a + temp_b; sum <= temp_sum(9 downto 1);
a7 a6 a5 a4 a3 a2 a1 a00 1
b7 b6 b5 b4 b3 b2 b1 b00 cin
Where each node of the scheme is relevant bit of temp_sum
All rights reserved to Abramov B. 200
Self Work
Describe mux 2x1 on gate level according to followed scheme:
All rights reserved to Abramov B. 202
Topic Three
n Process…………………….207
n Wait statements …………..217
n Combinatorial Process……225
n Synchronous Process…….239
n Sequential Statements……255
n NULL Statements………….301
n Processes Guidelines …….303
n Behavioral Description…….307
n Wait statements ……..…….314
All rights reserved to Abramov B. 203
Processes
All rights reserved to Abramov B. 204
Processes
Process – a behavioral region in the
architecture were statements are
executed in sequence!!!
All rights reserved to Abramov B. 205
Processes
The process interpretation is different for
simulation tools and synthesis tools!!!
All rights reserved to Abramov B. 206
Processes
Syntax of process declaration:
label: process ( sensitivity list) is
--declaration of process resources
begin
sequential statements;
end process label;
All rights reserved to Abramov B. 207
Processes (cont)
The process declarative part defines local items for the
process and may contain declaration of:
• subprograms
• types
• subtypes
• constants
• variables
• files
• aliases
• use clauses
• groups
All rights reserved to Abramov B. 208
Processes (cont)
All rights reserved to Abramov B. 209
Processes (cont)
Asynchronous processes:
describe a combinatorial logic hardware
(muxes,decoders,encoders,arithmetic devices).
Synchronous processes:
describe a “clocked” logic
(FF,registers,shift registers,counters).
All rights reserved to Abramov B. 210
Processes (cont)
A process declaration may content optional sensitivity list.
The list contains identifiers of signals to which the process is sensitive.
A change of a value of any those signals causes the suspended
process to resume.
üSensitivity list and explicit wait statements may not be specified in the same process.
üThe process description style with sensitivity list is preferable for synthesis.
All rights reserved to Abramov B. 211
Processes (cont)
All rights reserved to Abramov B. 212
Processes (cont)
Process activation and suspension may be controlled via the
wait statement:
process
begin
warning_level<= ( curr_value=critical_value);
wait on curr_value,critical_value;
end process;
All rights reserved to Abramov B. 213
Wait statements
The wait statement is a statement that causes suspension
of a process or a procedure.
Syntax:
wait;
wait on signal_list;
wait until condition;
wait for n time_units;
All rights reserved to Abramov B. 214
Wait statements (cont)
The wait statement suspends the execution of the process or procedure
in which it is specified.
Resuming the process or procedure depends on meting the condition(s)
specified in the wait statement.
There are three types of conditions supported with wait statements:
sensitivity clause, condition clause, and timeout clause.
The most often used is the sensitivity clause.
A sensitivity list defines a set of signals to which the process is sensitive
and causes the process to resume.
Example:
signal S1, S2 : std_logic;
process
begin
…………
wait on S1, S2;
end process;
All rights reserved to Abramov B. 215
Wait statements (cont)
If a process does not contain a sensitivity list, then an implicit sensitivity
list is assumed, one which contains all the signals that are present in that condition.
If a process is resumed but no condition is met, then the process will not execute any
other statements.
wait until enable = '1';
this is equivalent to:
loop
wait on enable;
exit when enable = '1';
end loop;
All rights reserved to Abramov B. 216
Wait statements (cont)
The second type of a condition supported with the wait statement
is the condition clause.
A process is resumed when the logical condition turns true due to a change
of any signal listed in the condition .
The timeout clause defines the maximum time interval during which the
process is not active.
When the time elapses, the process is automatically resumed .
Example :
wait for 50 ns;
A process containing this statement will be suspended for 50 ns.
All rights reserved to Abramov B. 217
Wait statements (cont)
A single wait statement can have several different conditions.
In such a case the process will be resumed when all the
conditions are met.
Example :
process
begin
wait on a, b until clk = '1';
. . .
end process;
The process is resumed after a change on either a orb signal,
but only when the value of the signal clk is equal to '1'.
All rights reserved to Abramov B. 218
Wait statements (cont)
process
begin
wait until a /= b for 4 us;
. . .
end process;
The process is resumed when 4 us delay is ended, or after a
change of either a or b signal, when a is not equal to b.
All rights reserved to Abramov B. 219
Wait statements (cont) The syntax of the wait statement allows to use it without any conditions.
Such a statement is equivalent to wait until true,
which suspends a process forever and will never resume.
While in simulation of normal models this is a disadvantage,
this particular feature of a wait statement is widely used in testbenches.
The followed example shows an example of a testbench section.
process is
begin
G0 <= '0' ;
wait for 100 ns;
wait until clk’event and clk=’1’;
G0 <= '1' ;
wait until clk’event and clk=’1’;
G0 <= '0' ;
wait;
end process ;
All rights reserved to Abramov B. 220
Wait statements (cont)
Important notes:
n The wait statement can be located anywhere between begin
and end process.
n A process with a sensitivity list may not contain any wait
statements.
All rights reserved to Abramov B. 221
Processes (cont)
process ( curr_value, critical_value ) is
begin
warning_level<=(curr_value=critical_value);
end process;
Process activation and suspension may be controlled via the
wait statement or alternatively by sensitivity list
process
begin
warning_level<= ( curr_value=critical_value);
wait on curr_value,critical_value;
end process;
All rights reserved to Abramov B. 222
Processes (cont)
Processes rules:
Ø statements are executed sequentially
Ø execution time is zero !!!
Ø all signals within – updated at its end
All rights reserved to Abramov B. 223
Processes (cont)
architecture arc_sample of sample is
begin
P1: process (Rst, Clk)
begin
. . .
end process P1;
P2: process (Rst, Clk)
begin
. . .
end process P2;
end architecture arc_sample;
sequential
sequential
concurrent
All rights reserved to Abramov B. 224
Processes (cont)architecture arc_test of test is
begin
sig<= a and b;
sig<=c and d; -- wrong ! unresolved contention
end architecture arc_test;
All rights reserved to Abramov B. 225
Processes (cont)
Acceptable VHDL code!
architecture arc_test of test is
begin
and_gate:process(a,b,c,d) is
begin
sig<= a and b;
sig<=c and d;
end process and_gate;
end architecture arc_test;
All rights reserved to Abramov B. 226
Processes (cont)
Decoder behavioral with multiple assignment
signal din : std_logic_vector( n downto 0);
signal dout: std_logic_vector(((2**din’length)-1) downto 0);
begin
decoder : process (din) is
begin
dout <= (others => ‘0’);
dout (conv_integer (din)) <= ‘1’;
end process decoder ;
All rights reserved to Abramov B. 227
Processes (cont)§ Don’t use the signal that driven by combinatorial
process, for reading inside of this process.
process (a, b, c) is
begin
temp<= a xor b;
s<= temp xor c;
end process ;
If temp is used inside of
the process, then temp
should be included into
sensitivity list, but if temp
is signal from sensitivity
list, it feeds itself !??
process (a, b) is
begin
temp<= a xor b;
end process ;
process (temp, c) is
begin
s<= temp xor c;
end process ;
All rights reserved to Abramov B. 228
Processes (cont)
A combinatorial processes , aka asynchronous processes must have a
sensitivity list containing all the signals which it reads ( inputs),
and must always update the signals which it assigns ( outputs).
A missing signal in the sensitivity list can lead to a transparent latch!
All rights reserved to Abramov B. 229
Processes (cont)
architecture arc_and_gate of and_gate is
begin
process (d) is
begin
sig<= c and d;
end process;
end architecture arc_and_gate;
Signal c is not included into sensitivity list, therefore the process does
not respond when c changes its value.
So what get is the following circuit:
All rights reserved to Abramov B. 231
Processes (cont)
Another kind of uncompleted sensitivity list is when output values
are not included into sensitivity list.
process(a,b) is
begin
if(a=b) then
Sig<=c;
else
Sig<=d;
end if;
end process;
All rights reserved to Abramov B. 232
Processes (cont)
We expect to receive the following:
All rights reserved to Abramov B. 233
Processes (cont)
But real results look like this:
All rights reserved to Abramov B. 234
Processes (cont)
Most commons mistakes in asynchronous processes:
n Uncompleted sensitivity list.
n Redundant signals included into sensitivity list.
n Redundant logic is described.
All rights reserved to Abramov B. 235
Processes (cont)
Synchronous process – current output is sequenced by a clock
(rising edge or falling edge) and depends on past inputs as well as
current inputs.
This has a memory (flip-flops, registers, counters, shift registers, state
machines).
ü Sensitivity list include only clock and asynchronous reset/preset
üAll the logic must be assigned after clock edge ( rising or falling)
All rights reserved to Abramov B. 236
Processes (cont)
Clock change detecting:
by event predefined attribute:
clk’event and clk=‘1’ -- rise detect
clk’event and clk=‘0’ -- fall detect
by library functions:
rising_edge(arg : std_logic) return boolean
falling_edge(arg : std_logic) return boolean
At simulation with type std_logic use of functions
rising_edge and falling_edge is more preferable.
All rights reserved to Abramov B. 240
Processes (cont)
DFF with asynchronous reset (active high);
entity dff is
port( clk: in std_logic;
rst : in std_logic;
d : in std_logic;
q : out std_logic
);
end entity dff;
All rights reserved to Abramov B. 241
Processes (cont)architecture arc_dff of dff is
begin
process(clk,rst) is
begin
if (rst= ‘1’) then
q<=’0’;
elsif rising_edge(clk) then
q<=d;
end if;
end process;
end architecture arc_dff;
All rights reserved to Abramov B. 242
Processes (cont)DFF with synchronous reset (active high)
process (clk) is -- only clock signal should be declared in the sensitivity list
begin
if rising_edge(clk) then
if (rst= ‘1’) then
q<=’0’;
else
q<=d;
end if;
end if;
end process;
All rights reserved to Abramov B. 243
Processes (cont)
set_rst_dff:process(clk,set,rst) is
begin
if (rst= ‘0’) then
q<=’0’;
elsif (set=’0’) then
q<=’1’;
elsif rising_edge(clk) then
q<=d;
end if;
end process set_rst_dff;
All rights reserved to Abramov B. 244
Processes (cont)
The typical errors of synchronous processes:
n Using different signals as clock instead of the global clock
n Both set and reset assigned to the same signal and can be active at the same time.
n Signal do not have a reset value.
n Two edges of clock are used in the process.
n Gated clock is created.
n More then one clock is used in a process.
All rights reserved to Abramov B. 245
FF coding rules
All rights reserved to Abramov B. 250
Mixed Synchronous and Asynchronous processes
bad_style: process (clk, rst, ld, load_val) is
begin
if (rst=‘0’) then
cnt <= 0;
elsif rising_edge(clk) then
cnt <= cnt + 1;
elsif (ld=‘1’) then
cnt <= load_val;
end if;
end process bad_style;
Legal VHDL but
non-deterministic
synthesis result !!!
FF coding rules
All rights reserved to Abramov B. 251
Asynchronous load in synchronous process
dangerous_style: process (clk, ld) is
begin
if (ld=‘0’) then
cnt <= load_val;
elsif rising_edge (clk) then
cnt <= cnt + 1;
end if;
end process dangerous_style;
Legal VHDL when load_val is
constants value .
Otherwise non-deterministic
synthesis result !!!
FF coding rules
All rights reserved to Abramov B. 254
process (clk) is
……………………………………
if rising_edge (clk) and (en=’1’) then
--Signal assignment
clk_internal <= clk and en;
process (clk_internal) is
………………………
if risind_edge (clk_internal) then
--Signal assignment
•Gated clocks are more
complicated then this
•Gated clock is the source
of clock skew
•Avoid them !!!
FF coding rules
All rights reserved to Abramov B. 255
The correct description:
if rising_edge (clk) then
if (en = ’1’) then
-- signal assignment
FF coding rules
All rights reserved to Abramov B. 256
Is the following a register or a latch?
reg_or_latch_proc : process (clk) is
begin
if (clk=‘1’) then
q<=d;
end if;
end process reg_or_latch_proc;
FF coding rules
All rights reserved to Abramov B. 257
üCannot be a latch since it has an incomplete sensitivity list
üCannot be a register since has no clock edge specification
Resolution :
Synthesis tool should produce an error and not produce any results
FF coding rules
All rights reserved to Abramov B. 258
Self Work
Describe the binary counter according to the above-stated circuit.
All rights reserved to Abramov B. 259
Describe the binary up/down counter according to the above-stated circuit.
The half adder-subtractor
Self Work
All rights reserved to Abramov B. 260
Sequential Statements
All rights reserved to Abramov B. 261
Sequential Statements (cont)
The if statement allows selection of statements to execute
depending on one or more conditions.
Tests the condition and executes a set of statements
depending on the result.
If statement generate priority.
The syntax is:
if_statement ::=
if condition then
sequence_of_statements
{ elsif condition then
sequence_of_statements }
[ else
sequence_of_statements ]
end if ;
All rights reserved to Abramov B. 262
Sequential Statements (cont)
The conditions are expressions resulting in boolean values.
The conditions are evaluated successively until one found that
yields the value true.
In that case the corresponding statement list is executed.
Otherwise, if the else clause is present, its statement list is
executed.
The elsif and else clauses are optional.
All rights reserved to Abramov B. 263
Sequential Statements (cont)
Rules:
Ø Only one of the branches is executed.
Ø The order is important – the first true condition causes
Ø the sequential statements after it to be executed.
Ø The rest are ignored.
Ø The first condition gets the highest priority.
All rights reserved to Abramov B. 264
Sequential Statements (cont)
process(a,b,c,d) is
begin
if (a=’1’) then
res<=c;
elsif(b=’1’) then
res<=d;
else
res<=’0’;
end if;
end process;
.
All rights reserved to Abramov B. 265
Sequential Statements (cont)
If a equals ‘1’ only first branch will execute due
to the priority structure.
All rights reserved to Abramov B. 266
Sequential Statements (cont)The if statements not always create the structures with priority.
process(a,b,c,d,sel) is
begin
if (sel=”00”) then
dout<=a;
elsif (sel=”01”) then
dout <=b;
elsif (sel=”10”) then
dout <=c;
else
dout <=d;
end if;
end process;
All rights reserved to Abramov B. 267
Sequential Statements (cont)
All rights reserved to Abramov B. 268
Sequential Statements (cont)
Using an if statement without an else clause in a combinatorial
process can result in latches being inferred, unless all signals driven
by the process are given unconditional default assignment.
Example:
process(a,b) is
begin
if (a=’1’) then
x<=b;
end if;
end process;
Created D-latch
with enable (a).
All rights reserved to Abramov B. 269
Sequential Statements (cont)
The completed if statement presented below, describes mux.
process(a,b) is
begin
if (a=’1’) then
x<=b;
else
x<=’0’;
end if;
end process;
All rights reserved to Abramov B. 270
Sequential Statements (cont)
Same result gives the default assignment:
process(a,b) is
begin
x<=’0’; -- default assignment latches prevented
if (a=’1’) then
x<=b;
end if;
end process;
All rights reserved to Abramov B. 271
Sequential Statements (cont)
process(…,….) is
begin
some statement …………………………………..
………………
if (cond1) then
sig1<=a;
……….
if(cond2) then
sig2<=b;
……….
end process;
Parallel IF
sequential
sequential
parallel
sequential
Different
signals !!!!!!
All rights reserved to Abramov B. 273
Sequential Statements (cont)
The case statement allows selection of statements
to execute depending on the value of a selection expression.
The syntax is:
case_statement ::=
case expression is
case_statement_alternative
{ case_statement_alternative }
end case ;
All rights reserved to Abramov B. 274
Sequential Statements (cont)
case_statement_alternative ::=
when choices =>
sequence_of_statements
choices ::= choice { | choice }
choice ::=
simple_expression
| discrete_range
| element_simple_name
| others
All rights reserved to Abramov B. 275
Sequential Statements (cont)
The selection expression must result in either a discrete type,
or a one-dimensional array of characters.
The alternative whose choice list includes the value of the
expression is selected and the statement list executed.
Note :that all the choices must be distinct, that is, no value may
be duplicated.
Furthermore, all values must be represented in the choice lists,
or the special choice others must be included as the last
alternative. If no choice list includes the value of the expression,
the others alternative is selected.
If the expression results in an array, then the choices may be
strings or bit strings.
All rights reserved to Abramov B. 276
Sequential Statements (cont)
multiplexor: case sel is
when “00” => dout<=a;
when “01”=> dout <=b;
when “10” => dout <=c;
when “11” => dout <=d;
end case multiplexor;
All possible choices must be included, unless the
others clause is used as the last choice.
All rights reserved to Abramov B. 277
Sequential Statements (cont)
Multiplexor with others clause:
multiplexor: case sel is
when “00” => dout<=a;
when “01” => dout <=b;
when “10” => dout <=c;
when others => dout <=d;
end case multiplexor;
All rights reserved to Abramov B. 278
Sequential Statements (cont)
A range or selection may be specified as a choice:
case sel is
when 0 => y<=a;
when 1 to 4 => y<=b;
when 5|7|9 => y<=c;
when others => y<=d;
end case;
All rights reserved to Abramov B. 279
Sequential Statements (cont)
A range may not be used with a vector type:
case sel is
when “000” => y<=a;
when “001” to “100” => y<=b; -- wrong! The sel is vector
when “101”|”110” => y<=c; -- correct
when others => y<=d;
end case;
All rights reserved to Abramov B. 280
Sequential Statements (cont)
Choice may not overlap :
case sel is
when 0 => y<=a;
when 1 to 4 => y<=b;
when 3|5|7|9 => y<=c; -- error, 3 included
-- into previous choice
when others => y<=d;
end case;
All rights reserved to Abramov B. 281
Sequential Statements (cont)
If many conditional clauses have to be performed on the same
selection signal, a case statement is a better solution than the if-
then-else construct.
The case statement with repeated assignments to a target signal,
it will synthesize to a large multiplexor with logic on the select
inputs to evaluate the conditions for the different choices in the
case statement branches.
No priority will be inferred from the order of the branches.
All rights reserved to Abramov B. 282
Sequential Statements (cont)
Hardware within priority: Hardware without priority:
if (a=‘1’) then ab<=a & b;
dout<=c; case ab is
elsif (b=‘1’) then when “10”|”11” => dout<=c;
dout<=d; when “01” => dout<=d;
else when others => dout<=e;
dout<=e; end case;
end if;
All rights reserved to Abramov B. 283
Sequential Statements (cont)
The case statement may be used with multiple targets,
embedded if statements and nested case statement.
Example of mixed case/if process with multiple targets.
arbiter: process(addr,power_up,valid) is
begin
bios <='0';
flash <='0';
sram <='0';
eeprom <='0'; -- preventing transparent latches
-- with default assignment
All rights reserved to Abramov B. 284
Sequential Statements (cont)
if (valid = '1') then
case addr is
when 0 to 5000 =>
if (power_up = '1') then
bios<='1';
else
flash<='1';
end if;
when 5001 to 8000 =>
sram<='1';
when 8001 to 9000 =>
eeprom<='1';
when others =>
flash<='1';
end case;
end if;
end process arbiter;
All rights reserved to Abramov B. 285
Sequential Statements (cont)
All rights reserved to Abramov B. 286
Sequential Statements (cont)
The case statement can only be used in a sequential environment.
In the dataflow environment, the selected signal assignment
statement has the equivalent behavior:
signal output_signal, sel, x, y, z : std_logic_vector (3 downto 0) ;
....
with sel select
output_signal <= x when "0010",
y when "0100",
z when "1000",
x and y and z when "1010" | "1100"|"0110",
"0000" when others ;
All rights reserved to Abramov B. 287
Sequential Statements (cont)
The rules are the same as for the case statement:
• all possible choices must be include, unless the others
clause is used as the last choice.
• a range or a selection may be specified as a choice.
• choices may not overlap.
• there is not implied priority to the choices.
A selected signal assignment will usually result in combinatorial
logic being generated.
All rights reserved to Abramov B. 288
Sequential Statements (cont)
Select statement and qualified expression:
entity full_adder is
port ( a,b,cin : in bit;
s,cout : out bit);
end entity full_adder;
architecture truth_table of full_adder is
begin
with bit_vector’(a,b,cin) select
(s,cout)<= bit_vector’(“00”) when “000”,
bit_vector’(“10”) when “001”,
bit_vector’(“10”) when “010”,
bit_vector’(“01”) when “011”,
bit_vector’(“10”) when “100”,
bit_vector’(“01”) when “101”,
bit_vector’(“01”) when “110”,
bit_vector’(“11”) when others;
end architecture truth_table;
All rights reserved to Abramov B. 289
Sequential Statements (cont)
The same functionality in the dataflow environment is
accomplished with the use of the conditional signal assignment
statement:
signal a : integer ;
signal output_signal, x, y, z : bit_vector (3 downto 0) ;
....
output_signal <= x when (a=1) else y when (a=2) else
z when (a=3) else "0000" ;
All rights reserved to Abramov B. 290
Sequential Statements (cont)
signal a ,b: std_logic ;
signal output_signal, x, y : std_logic _vector (3 downto 0) ;
....
output_signal <= x when (a=‘1’) else y when (b=‘1’) else x"0" ;
The first condition gets the highest priority.
All rights reserved to Abramov B. 291
Sequential Statements (cont)
•Conditions may overlap, as for the if statement.
• The expression corresponding to the first “true”
condition is assigned.
• There must be a final unconditional else expression:
y<= a when (x=5); -- wrong
All rights reserved to Abramov B. 292
Sequential Statements (cont)
Conditional signal assignment may be used to define tri-state buffers:
bi_dir_port <= inner_out when (output_en=’1’) else ‘Z’;
If a signal is conditionally assigned to itself,
latches may be inferred.
All rights reserved to Abramov B. 293
Sequential Statements (cont)entity mux is
port (din : in std_logic_vector(3 downto 0);
sel : in std_logic_vector(1 downto 0);
dout: out std_logic);
end entity mux;
architecture arc_mux of mux is
signal decoded : std_logic_vector(3 downto 0);
begin
decoder_2_to_4: process(sel) is
begin
decoded<=x"0";
decoded(conv_integer(sel))<='1';
end process decoder_2_to_4;
dout<=din(0) when (decoded=x"1") else 'Z’;
dout<=din(1) when (decoded=x"2") else 'Z’;
dout<=din(2) when (decoded=x"4") else 'Z’;
dout<=din(3) when (decoded=x"8") else 'Z’;
end architecture arc_mux;
All rights reserved to Abramov B. 294
Sequential Statements (cont)
All rights reserved to Abramov B. 295
Sequential Statements (cont)entity mux is
port (din : in std_logic_vector(3 downto 0);
sel : in std_logic_vector(1 downto 0);
dout: out std_logic);
end entity mux;
architecture mux of mux is
signal decoded : std_logic_vector(3 downto 0);
begin
decoder_2_to_4: process(sel) is
begin
decoded<=x"0";
decoded(conv_integer(sel))<='1';
end process decoder_2_to_4;
dout<=din(0) when (decoded(0)=‘1’) else 'Z’; --optimized description
dout<=din(1) when (decoded(1)=‘1’) else 'Z’; --without comparators
dout<=din(2) when (decoded(2)=‘1’) else 'Z’;
dout<=din(3) when (decoded(3)=‘1’) else 'Z’;
end architecture mux;
All rights reserved to Abramov B. 296
Sequential Statements (cont)
All rights reserved to Abramov B. 297
NULL Statements
The null statement perform no action.
It may be used to explicitly show that no action is required in certain cases.
It is most often used in case statements,
where all possible values of the selection expression must be listed as choices,
but for some choices no action is required.
For example:
case controller_command is
when forward =>
engage_motor_forward;
when reverse =>
engage_motor_reverse;
when idle => null;
end case;
All rights reserved to Abramov B. 299
Processes Guidelines
• Not assigning a signal during an iteration through a process infers a latch.
An incomplete CASE statement:process(present_state) isbegin
next_state <= s0;out_sig <= '0';case present_state iswhen s0 =>
next_state <= s1;out_sig <= '1';
when s1 => next_state <= s2;
when s2 => next_state <= s0;
end case;end process;
Default value covers
missing assignment
on any case conditions
Missing signal
assignment for out_sig
All rights reserved to Abramov B. 300
Processes Guidelines
• If … Then else statements can also be
incomplete
An incomplete IF statement:
process (a,b,c,d) is
begin
if (a = '1') then
out_sig <= c;
elsif (b ='1') then
out_sig <= d;
end if;
end process;
In the example above a latch is required to hold the value
when a = b = '0'
All rights reserved to Abramov B. 301
Processes Guidelines
• The reset condition must assign all signals!
process(clk,n_reset) is
begin
if (n_reset = '0') then
last <= 0;
elsif rising_edge(clk) then
last <= curr;
curr <= curr + 1;
end if;
end process;
In the above example curr is not given a value during reset.
Therefore its value must be retained
All rights reserved to Abramov B. 302
Processes Guidelines
• Reset condition can not assign combinatorial signals!
process (clk,n_reset) is
begin
if (n_reset = '0') then
smp_b <= '0';
smp_a <= '0';
elsif rising_edge(clk) then
smp_a <= a;
end if;
end process;
smp_b <= b;
c <= smp_a XOR smp_b;
In the above example smp_b is assigned from 2 sources.
All rights reserved to Abramov B. 303
Behavioral DescriptionThe highest level of abstraction supported in VHDL is called the
behavioral level.
When creating a behavioral description of a circuit,you will
describe your circuit in the terms of its operation over time.
The concept of time is the critical distinction between behavioral
description of circuits and gate-level descriptions.
In behavioral description,the concept of time may be an ordering
of operations that are expressed sequentially (such as in functional
description of flip-flop)
Further you can find examples of two levels of behavioral
abstraction of counter description:
u flip-flops and logic level
u highest – registers abstraction.
All rights reserved to Abramov B. 304
What does “the system behavior” mean?
The main purpose of any electronic system or device is to transform
input data into output results.
This kind of activity is called “behavior” or “functionality” of the
system and system specification describes input data are transformed
(through processes and signals) into output results.
Behavioral Description (cont)
All rights reserved to Abramov B. 305
Process
Process
Process
Process
Ports
Signals
Events
Behavioral Description (cont)
All rights reserved to Abramov B. 306
Behavioral Description (cont)count_4bit:process(clk,rst) is
begin
if (rst=‘1’) then
q<= (others=> ‘0’);
elsif rising_edge(clk) then
q<= q + 1;
end if;
end process count_4bit;
count_4bit:process(clk,rst) is
begin
if (rst=‘1’) then
q<= (others=> ‘0’);
elsif rising_edge(clk) then
q(0)<= not q(0);
if (q(0)=‘1’) then
q(1)<=not q(1);
end if;
if ((q(0) and q(1))=‘1’) then
q(2)<= not q(2);
end if;
if ((q(0) and q(1) and q(2))=‘1’) then
q(3)<= not q(3);
end if;
end if;
end process count_4bit;
All rights reserved to Abramov B. 307
shift_reg:process(clk,rst) is
begin
if (rst=‘1’) then
q<=(others =>’0’);
elsif rising_edge(clk) then
q(0)<=sin;
q(1)<= q(0);
q(2)<= q(1);
q(3)<= q(2);
end if;
end process shift_reg;
Behavioral Description (cont)shift_reg:process(clk,rst) is
begin
if (rst=‘1’) then
q<= (others=>’0’);
elsif rising_edge(clk) then
q<= q(2 downto 0) & sin;
end if;
end process shift_reg;
All rights reserved to Abramov B. 309
Behavioral vs. Structural
entity mux is
port
(
a, b, c, d : in bit;
s0, s1 : in bit;
x : out bit
);
end entity mux;
All rights reserved to Abramov B. 310
Behavioral vs. Structuralarchitecture structural_mux of mux is
signal s0_inv, s1_inv, x1, x2, x3, x4 : bit;
component and3gate is
port ( a, b, c: in bit; d: out bit);
end component and3gate;
component inverter is
port ( in1: in bit; x: out bit);
end component inverter;
component or4gate is
port ( a, b, c, d : in bit; x: out bit);
end component or4gate;
begin
u1: inverter port map (s0, s0_inv);
u2: inverter port map (s1, s1_inv);
u3: and3gate port map (a, s0_inv, s1_inv, x1);
u4: and3gate port map (b, s0, s1_inv, x2);
u5: and3gate port map (c, s0_inv, s1, x3);
u6: and3gate port map (d, s0, s1, x4);
u7: or4gate port map (a, b, c, d, x);
end architecture structural_mux;
architecture arc_mux of mux is
process(a,b,c,d,s0,s1) is
variable sel : bit_vector(1 downto 0);
begin
sel:= s1 & s0;
case sel is
when “00” => x<=a;
when “01” => x<=b;
when “01” => x<=c;
when others => x<=d;
end case;
end process;
end architecture arc_mux;