0% found this document useful (0 votes)
88 views78 pages

Introduction of VHDL: Shomal University Fall 2010

This document provides an introduction to VHDL, including: - VHDL and Verilog are the two major HDLs, with VHDL being standardized in 1987, 1993, 2002, and 2006. - VHDL uses an object-oriented, verbose syntax similar to ADA, while Verilog uses a more concise syntax like C. - Key VHDL constructs include entities, architectures, processes, and packages, which are used to break designs into multiple files.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
88 views78 pages

Introduction of VHDL: Shomal University Fall 2010

This document provides an introduction to VHDL, including: - VHDL and Verilog are the two major HDLs, with VHDL being standardized in 1987, 1993, 2002, and 2006. - VHDL uses an object-oriented, verbose syntax similar to ADA, while Verilog uses a more concise syntax like C. - Key VHDL constructs include entities, architectures, processes, and packages, which are used to break designs into multiple files.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 78

In the name of God

Introduction of VHDL

Shomal University
Fall 2010

Rahim Soleymanpour
Introduction
Two major HDLs:
VHDL
standardized by IEEE in 1987,1993, 2002,2006
object-oriented, very widely used
Has Verbose syntax like ADA
Verilog
standardized by IEEE in 1995, 2001, 2005
has concise syntax like C
Introduction
VHDL example :
-- An N-bit multiplier
entity MULTIPLY is
port (
a, b : in bit_vector( 7 downto 0 );
z : out bit_vector( 15 downto 0 )
);
end entity;
architecture rtl of MULTIPLY is
begin
z <= a * b;
end rtl;
Introduction

Verilog Example:
// An N-bit multiplier
module MULTIPLY (a,b,z);
input [7:0] a,b;
output [15:0] z;
assign z = a * b;
endmodule
VHDL Design Flow
VHDL Constructs
Entity definition
Architecture definition
Configuration
Process
Subprogram
Package
A VHDL design can be broken into multiple files.
Each file contains entity and architecture
definitions, or packages.
Design Entity
A component or a system to be designed is a VHDL
design entity
VHDL divides entities into two parts:
External (interface): how it connects to other
components
Internal (architecture): how it behaves and how it is
implemented
Behavioral
Structural
Hybrid
Entity definition
To define an entity
First an entity declaration is given. This
specifies one or more input, output, or input-output
ports that are wired to neighboring
entities.
Then one or more architecture definition(s) is
given. This determines how the entity functions
and how it is implemented.
Example
Two input NAND gate
entity NAND2 is
port ( a : in bit;
b : in bit;
z : out bit );
end entity;
-- A dataflow description
architecture dataflow of NAND2 is
begin
z <= not (a and b);
end dataflow;
Example
-- A behavioral description
architecture behavioral of NAND2 is
begin
process(a,b)
begin
if a=1 and b=1 then
z <= 0;
else
z <= 1;
end process;
end behavioral;
Entities and Architectures
ENTITY entity_name IS
input and output ports
END ENTITY entity_name;

ARCHITECTURE identifier OF entity_name IS


declarative part
BEGIN
statement part
END ARCHITECTURE identifier;
VHDL Alphabet
VHDL alphabet consists of all of the characters in
the ISO eight-bit character set.
The first 128 characters in the ISO set are the
ASCII characters.
VHDL is not case-sensitive.
Two consecutive dashes (--) start a VHDL
comment. The comment extends to the end of
current line.
VHDL Identifiers
VHDL identifiers:
Must start with an alphabetic letter,
May only contain uppercase and lowercase letter,
digits, and underscore ( _ ),
May not end with an underscore character,
May not contain two consecutive underscore
Characters,
Can be arbitrarily long.
VHDL Keywords
Special Symbols
Single symbols:
&()*+-,./:;<=>|
Double symbols:
=> ** := <= /= >= <>
Digits:
0123456789ABCDEFabcdef
Numbers
Integers
E.g. 23, 46E5, 1E+12, 19e5
In other bases: 2#11101011#, 16#D4F1#, 8#2347#
Reals
E.g. 23.1, 2.0, 1.23E9, 98.6e-3
In other bases: 2#0.100#, 8#0.4#, 12#0.6#
To aid readability, underscore can be used
between digits
2#0101_1110#, 16#4f23_10e2_fe00_cb00#, 250_300
Characters & Strings
A character literal is enclosed in single quotes
E.g. a, W, q
A string is enclosed in double quotes. It can
contain any number of characters except the
newline character.
Example: This is a sample string.
Example: Another string with & !, and % 0111zz
Bit strings are enclosed in double quotes
Example: b0110, B111001, O425, XFE21,
xd24c0
Data Types
VHDL is a strongly typed language. You must
assign a data type to all ports, signals, variables, and
constants.
Four classes of data types
1. Scalar types (integer, real, time, )
2. Composite types (array, record, )
3. File types (binary file, ascii file)
4. Access types
Scalar Types
Integers (at least 32 bits signed)
Permissible operations: + - * / mod rem abs **
Floating point numbers (32 bits at least)
Permissible operations: + - * / abs **
Physical units
1) Type time is predefined in VHDL.
E.g. 20 fs, 34 ps, 10 ns, 21 us, 320 ms, 2 sec, 12 min, 3 hr
2) Other physical types can also be defined.
Enumeration types
Predefined: bit (0,1), character, boolean (false,true)
Users can define other enumeration types.
Arrays
An array is an ordered collection of elements of
the same type.
Two types of array can be defined
Constrained arrays
Type word is array (0 to 15) of bit;
Type byte is array (7 downto 0) of bit;
Type ram is array (0 to 16#FFFF#) of byte;
Type int_array is array (1 to 100) of integer;
Unconstrained arrays
Type bit_vector is array (natural range <>) of bit;
Type string is array (positive range <>) of character;
Type std_ulogic_vector is array (natural range <>) of std_ulogic;
Array Elements & Slices
Example:
Variable B : bit_vector(7 downto 0);
Array Operations
Shift, rotate and concatenate examples:
Expressions
An expression is a formula that specifies how to
compute a value.
Example (D**3) + ((A*B) mod 2)
VHDL operators
VHDL Operators

Boolean NOT AND OR NAND NOR XOR XNOR


Operators

Comparison = /= < <= > >=


Operators

Arithmetic + - ABS MOD REM * / **


Operators

Concat. &
Operators
Logic value system

Value Representing
'U' Uninitialized
'X' Forcing Unknown
'0' Forcing 0
'1' Forcing 1
'Z' High Impedance
'W' Weak Unknown
'L' Weak 0
'H' Weak 1
'-' Dont care
Example
Entity:
ENTITY aCircuit IS
PORT (a, b : IN BIT;
c : INOUT BIT;
av, bv : IN BIT_VECTOR (7 DOWNTO 0);
cv : INOUT BIT_VECTOR (7 DOWNTO 0);
w : OUT BIT;
wv : OUT BIT_VECTOR (7 DOWNTO 0));
END ENTITY aCircuit;
Example
ARCHITECTURE four_assignments OF aCircuit IS
SIGNAL d : BIT;
SIGNAL iv, jv, kv : BIT_VECTOR (7 DOWNTO 0);
BEGIN
iv <= av AND cv;
jv <= bv AND cv;
kv <= av NOR bv;
wv <= iv XOR jv WHEN c = 1 ELSE iv NAND kv;
END ARCHITECTURE four_assignments;
Example
ARCHITECTURE indexing_slicing OF aCircuit IS
SIGNAL d : BIT;
SIGNAL dv : BIT_VECTOR (7 DOWNTO 0);
BEGIN
wv (3 DOWNTO 0) <= av (7 DOWNTO 4) AND cv (7
DOWNTO 4);
w <= cv (4);
cv (7) <= av (0);
END ARCHITECTURE indexing_slicing;
Example
-- xor example
ENTITY xor2 IS
PORT (i1, i2: IN std_logic; o1: OUT
std_logic);
END ENTITY xor2;
--
ARCHITECTURE expression OF xor2 IS
BEGIN
o1 <= i1 XOR i2 AFTER 3 NS;
END ARCHITECTURE expression
Example
-- full adder Example
ENTITY full_adder IS
PORT (a, b, cin : IN std_logic;
sum, cout : OUT std_logic);
END ENTITY full_adder;
--
ARCHITECTURE expression OF full_adder IS
BEGIN
sum <= a XOR b XOR cin AFTER 0.3 NS;
cout <= (a AND b) OR (a AND cin) OR (b AND
cin) AFTER 0.2 NS;
END ARCHITECTURE expression;
Modeling Concurrency
Delay and concurrency is inherent in any real circuit and must be
simulated.
Event-driven simulation method is used.
Example Simulation
VHDL Statements
VHDL has two kinds of statements:
Sequential statements: they are executed one after
another, like C or Pascal
Signal and variable assignments, flow control constructs (if,
case, while, loop, ), subprogram call, wait
Concurrent statements: all are executed at the
same time.
Processes, block statements, component instantiations,
generate statements, concurrent assignments and concurrent
procedures
Syntax
Entity:
entity entity_name is
[ generic (generic_declarations); ]
[ port (port_declarations); ]
end [entity] [entity_name];
Generic:
generic ( [constant_name : type [:=value] ]
{ ; constant_name : type [:=value] } );
Port:
port ( [ port_name : port_mode type
{ ; port_name : port_mode type } ] );
Syntax
Port Modes:
In : port can only be read
Out : port can only be assigned
Inout : Can be read and assigned a value. The value read is
not the assigned value.
Buffer : Similar to out, but can be read
Example
entity adder is
generic ( N: integer :=8 );
port ( x, y : in bit_vector(N-1 downto 0);
sum : out bit _vector(N downto 0) );
end entity adder;
Syntax
Architecture
architecture architecture_name of entity_name is
{ declarative_item }
begin
{ concurrent_statement }
end [architecture_name];
A declarative item can be any of these:
Use clause
Subprogram declaration and body
Type or subtype declaration
Constant declaration
Signal declaration
Component declaration
Example
architecture dataflow of adder is
begin
process(x,y)
begin
sum <= x + y;
end process;
end dataflow;
Syntax
Process
[label:] process [( sensitivity_list )]
{ process_declarative_item }
begin
{ sequential_statement }
end process;
The sensitivity list is a list of signals read by the process.
The process declarative items can include:
Use clause
Subprogram declaration and body
Variable and constant declaration
Type and subtype declaration
Signals
Signals carry information among processes and
components in an architecture.
Signal declaration syntax
signal signal_name : signal_type [:=expression];
signal address : bit_vector(31 downto 0);
signal mem_read : bit := 0;
Signal assignment syntax
[Label:] signal_name <= value [after time_expression]
{, value [after time_expression]};
address <= x18FE5900 after 20 ns;
mem_read <= 1 after 25 ns, 0 after 50 ns, 1 after
110 ns;
data_reg <= 1101_0010;
Wait Statement
Wait causes a process to wait for an event
Syntax
wait [on signal_name {,signal_name}];
wait [until boolean_expression];
wait [for time_expression];
Example
wait on a,b;
wait until Q=1;
wait until clk=1 and clkevent;
wait for 100 us;
wait;
Wait in Process
If Statement
Syntax
[label]:
if boolean_expression then
{sequential_statement}
elsif boolean_expression then
{sequential_statement}
[else
{sequential_statement} ]
end if [lable];
Example
--Check_opcode:
If opcode = 0101 then
data_reg <= rega;
elsif opcode = 0011 then
data_reg <= regb;
else
data_reg <= regc;
flag <= 1;
End if;
Case Statement
Syntax:
[Label:]
case expression is
{ when choice => {sequential_statement} }
end case [label];
Example
Mux: case sel is
when 00 =>
oreg <= ireg1 after 10 ns;
when 01 =>
oreg <= ireg2 after 10 ns;
when 10 =>
oreg <= ireg3 after 10 ns;
when 11 =>
oreg <= ireg4 after 10 ns;
end case;
Loop, While & For Statement
Syntax
[label:] loop
{sequential_statement}
end loop [label];
Syntax
[label:] while condition loop
{sequential_statement}
end loop [label];
Syntax
[label:] for identifier in discrete_range loop
{sequential_statement}
end loop [label];
Example
Next, Exit, Null
Syntax
[label:] next [when boolean_expression];
[label:] exit [when boolean_expression];
[label:] null;
Example
Concurrent Signal Assignments
Conditional signal assignment
[label:] Signal_name <= { value when
boolean_expression else }
value [when boolean_expression];
Selected signal assignment
[label:] with expression select
signal_name <= { value when choices}
value when choices;
Example
Zmux: z <= d0 when sel1=0 and sel2=0 else
d1 when sel1=0 and sel2=1 else
d2 when sel1=1 and sel2=0 else
d3;
------------------------------------------------
Zmux: with sel select
z <= d0 when 00,
d1 when 01,
d2 when 10,
d3 when others;
Subprograms
Procedures
Generalize a statement
Encapsulate a collection of sequential statements that are
executed for their effect
Functions
Generalize an expression
Encapsulate a collection of sequential statements that compute
a result
Procedure
Syntax
procedure identifier [ ( parameter_list ) ] is
{ declarations }
begin
{ sequential statements }
end [procedure];
Syntax of parameter list
[constant|variable|signal] identifier {, } : [mode] type
:= static_expression] {; }
Modes: in | out | inout
Defaults: in is constant, out and inout are variables
Example
PROCEDURE consecutive_data
(SIGNAL target : OUT BIT_VECTOR;
CONSTANT ti : TIME; CONSTANT n : INTEGER)
IS
VARIABLE data : BIT_VECTOR (target'RANGE);
VARIABLE sum, carry : BIT;
BEGIN
FOR i IN 1 TO n LOOP
carry := '1';
FOR j IN data'REVERSE_RANGE LOOP
sum := data (j) XOR carry;
carry := data (j) AND carry;
data (j) := sum;
END LOOP;
target <= TRANSPORT data AFTER ti * i;
END LOOP;
END PROCEDURE consecutive_data;
Example
ARCHITECTURE procedural OF multiplexer8_tester IS
PROCEDURE consecutive_data
(SIGNAL target : OUT BIT_VECTOR;
CONSTANT ti : TIME; CONSTANT n : INTEGER)
IS .
.
END PROCEDURE consecutive_data;
SIGNAL a, b, w2 : BIT_VECTOR (7 DOWNTO 0);
SIGNAL s : BIT;
SIGNAL sel : BIT_VECTOR (0 TO 0);
BEGIN
UUT2: ENTITY WORK.multiplexer8 (direct)
PORT MAP (a, b, s, w2);
consecutive_data (a, 123 NS, 6);
consecutive_data (b, 79 NS, 6);
consecutive_data (sel, 119 NS, 8);
s <= sel(0);
END ARCHITECTURE procedural;
Nesting Procedure
PROCEDURE inc (VARIABLE invec : INOUT BIT_VECTOR) IS
VARIABLE sum, carry : BIT;
BEGIN
carry := '1';
FOR j IN invec'REVERSE_RANGE LOOP
sum := invec (j) XOR carry;
carry := invec (j) AND carry;
invec (j) := sum;
END LOOP;
END PROCEDURE inc;
--
PROCEDURE consecutive_data
(SIGNAL target : OUT BIT_VECTOR;
CONSTANT ti : TIME; CONSTANT n : INTEGER) IS
VARIABLE data : BIT_VECTOR (target'RANGE);
BEGIN
FOR i IN 1 TO n LOOP
inc (data);
target <= TRANSPORT data AFTER ti * i;
END LOOP;
END PROCEDURE consecutive_data;
Functions
Syntax
[pure|impure] function identifier [ (
parameter_list ) ]
return type_name is
{ declarations }
begin
{ sequential statements }
end [function] [identifier];
Mode of parameters is restricted to in.
Example
function limit ( value, min, max : integer ) return
integer is
begin
if value > max then
return max;
elsif value < min then
return min;
else
return value;
end if;
end function;
Example
ARCHITECTURE functional OF multiplexer IS
FUNCTION mux (databits : BIT_VECTOR; . . .
.
.
.
END FUNCTION mux;

SIGNAL sel : BIT_VECTOR (0 DOWNTO 0);


BEGIN
sel(0) <= s;
w <= mux ((a,b), sel) AFTER 8 NS;
END ARCHITECTURE functional;
Nesting Function
FUNCTION int (invec : BIT_VECTOR) RETURN INTEGER IS
VARIABLE tmp : INTEGER := 0;
BEGIN
FOR i IN invec'LENGTH - 1 DOWNTO 0 LOOP
IF invec (i) = '1' THEN
tmp := tmp + 2**i;
END IF;
END LOOP;
RETURN tmp;
END FUNCTION int;
FUNCTION mux (databits : BIT_VECTOR; sel : BIT_VECTOR)
RETURN BIT IS
BEGIN
RETURN databits (int(sel));
END FUNCTION mux;
Function Overloading
We can define two distinct subprograms with the
same name but with different number or types of
formal parameters.
Example
procedure increment ( a: inout integer; n: integer ) is
procedure increment ( a: inout bit_vector; n: integer ) is
procedure increment ( a: inout bit_vector; n: bit_vector ) is
Operator Overloading
VHDL allows to define functions using the
operator symbols as names.
Look in std_logic_1164 package for examples.
Example
function + ( a, b : in bit_vector ) return
bit_vector is.
begin.
.
end function;
Visibility of Declarations
Architectures, processes, and subprograms are divided into
two parts: a declarative part and a body.

A name declared in declarative part is visible from the end


of the declaration itself down to the end of corresponding
body part.

Subprogram nesting is possible and any item declared within


an outer procedure before declaration of a nested procedure
can be referred to inside the nested procedure.
instantiation
Syntax (entity declaration)
entity identifier is
generic ( parameter_list )
port ( interface_list );
end [entity][identifier];
Syntax (entity instantiation)
Label: entity_name [ architecture_identifier ]
[ generic map ( generic_association_list ) ]
[ port map ( port_ association_list ) ];
Direct instantiate
Declaration
entity or_reduce is
generic ( n : positive; tpd : time );
port ( a : in bit_vector(n downto 1); z : out bit );
end entity;
Instantiation
U1: entity or_reduce
generic map ( n => 12, tpd => 5 ns );
port map ( a => a1 , z => z1 );
U2: entity or_reduce
generic map ( tpd => 15 ns, n => 32 );
port map ( a => a2, z => z2 );
U3: entity or_reduce
generic map ( 16, 15 ns ); port map ( a => a2, z => z2 );
Direct instantiate
Declaration
entity or_reduce is
generic ( n : positive:= 8; tpd : time:= 5 ns );
port ( a : in bit_vector (n downto 1); z : out bit );
end entity;
Instantiation
U1: entity or_reduce
generic map ( tpd => 5 ns );
port map ( a => a1 , z => z1 );
U2: entity or_reduce
generic map ( n => 32 );
port map ( a => a2, z => z2 );
U3: entity or_reduce
generic map ( open, 5 ns ); port map ( a => a1 , z => z1 );
Component Instantiation
A component can be declared in a package or in the
declaration part of an architecture.
A component can be instantiated in an architecture.
Syntax
Instantiation_label: [component] component_name
[ generic map ( generic_association_list ) ]
[ port map ( port_association_list ) ];
Example
ARCHITECTURE gates OF multiplexer IS
COMPONENT n1
PORT (i1: IN BIT; y: OUT BIT);
END COMPONENT;
COMPONENT n2
PORT (i1, i2: IN BIT; y: OUT BIT);
END COMPONENT;
FOR ALL : n1 USE ENTITY WORK.inv (delay1);
FOR ALL : n2 USE ENTITY WORK.nand2 (delay1);
SIGNAL sbar, asel, bsel : BIT;
BEGIN
U1: n1 PORT MAP (s, sbar);
U2: n2 PORT MAP (a, sbar, asel);
U3: n2 PORT MAP (b, s, bsel);
U4: n2 PORT MAP (asel, bsel, w);
END ARCHITECTURE gates;
Signal and Variable
Writing Testbenches
ENTITY detector110_tester IS END ENTITY;
--
ARCHITECTURE timed OF detector110_tester IS
SIGNAL aa, clock, rst, ww : std_logic := '0';
BEGIN
UUT1: ENTITY WORK.detector110 (procedural)
PORT MAP (aa, clock, rst, ww);
rst <= '1' AFTER 31 NS, '0' AFTER 54 NS;
clock <= NOT clock AFTER 7 NS WHEN NOW<=165 NS ELSE '0';
PROCESS BEGIN
WAIT FOR 23 NS; aa <= '1';
WAIT FOR 21 NS; aa <= '0';
WAIT FOR 19 NS; aa <= '1';
WAIT FOR 31 NS; aa <= '0';
WAIT;
END PROCESS;
PROCESS (ww) BEGIN
REPORT "Signal w changed to:"& std_logic'IMAGE(ww)&
" at " & TIME'IMAGE(NOW)
SEVERITY NOTE;
END PROCESS;
END ARCHITECTURE timed;
Writing Testbenches
Enumeration Type for Multi-Value Logic
TYPE std_logic IS
(U,X,0,1,Z,W,L,H,-);

TYPE v4l IS (X,0,1,Z);


Array Declarations
TYPE v4l_byte IS ARRAY (7 DOWNTO 0) of v4l;
TYPE v4l_word IS ARRAY (15 DOWNTO 0) of v4l;
TYPE v4l_4by8 IS ARRAY (3 DOWNTO 0, 0 TO 7) of v4l;
TYPE v4l_1kbyte IS ARRAY (0 to 1023) OF v4l_byte;
TYPE v4l_8cube IS ARRAY (0 TO 7, 0 TO 7, 0 TO 7) of v4l;
Array Declarations
ARCHITECTURE assign OF array_test IS
SIGNAL s : v4l;
SIGNAL s_byte : v4l_byte;
SIGNAL s_word : v4l_word;
SIGNAL s_4by8 : v4l_4by8;
SIGNAL s_1kbyte : v4l_1kbyte;
SIGNAL s_8cube : v4l_8cube;
BEGIN
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
END ARCHITECTURE assign;
Array Declarations
BEGIN
SA1: s_byte <= v4l_byte ( s_word (11 DOWNTO 4) );
SA2: s <= s_4by8 (0, 7);
SA3: s_byte <= s_1kbyte (27);
SA4: s <= s_1kbyte (23)(3);
SA5: s_byte <= s_byte (0) & s_byte (7 DOWNTO 1);
SA6: s_byte (7 DOWNTO 4) <=
s_byte(2) & s_byte(3) & s_byte(4) & s_byte(5);
SA7: s_byte (7 DOWNTO 4) <=
(s_byte(2), s_byte(3), s_byte(4), s_byte(5));
SA8: (s_byte(0), s_byte(1), s_byte(2), s_byte(3))
<= s_byte (5 DOWNTO 2);
END ARCHITECTURE assign;
Initializing Multidimensional Arrays
SIGNAL s_4by8 : v4l_4by8 :=
(
( 0, 0, 1, 1, Z, Z, X, X ),
( X, X, 0, 0, 1, 1, Z, Z ),
( Z, Z, X, X, 0, 0, 1, 1 ),
( 1, 1, Z, Z, X, X, 0, 0 )
);
SIGNAL s_4by8 : v4l_4by8 := (OTHERS => 11000000);
SIGNAL s_4by8 : v4l_4by8 := (OTHERS => (OTHERS =>
Z));
SIGNAL s_4by8 : v4l_4by8 :=(OTHERS => (0 TO 1 =>
1, OTHERS =>0));
Unconstrained Arrays
ARCHITECTURE behavioral OF vlog_ram IS
TYPE mem IS ARRAY
(NATURAL RANGE <>, NATURAL RANGE <>) of v4l;
BEGIN
PROCESS
CONSTANT memsize : INTEGER := 2**addressLENGTH;
VARIABLE memory : mem (0 TO memsize-1,
datainRANGE);
BEGIN
id: IF oprEVENT THEN
IF opr=TRUE THEN
init_mem (memory, "memdata.dat");
ELSE
dump_mem (memory, "memdump.dat");
END IF;
END IF;

You might also like