VHDL modeling styles:
VHDL can be written in three different
models. They are called
Data flow model
Behavioral model
Structural model
Before attempting
a VHDL program, one should know the steps involved in these modeling styles.
Data flow model:
In
this model, the input data simply flows into the output. That is, we will be
implementing the relation between input and output terminals directly.
Example:
(2 input and gate)
Library
IEEE;
Entity
and2 is
Port
(a, b: in bit;
C: out bit);
End and2;
Architecture
and2 of and2 is
Begin
c < = a and b;
end and2;
Here,
the output c is an ANDing of a and b. We are actually implementing the direct relation between inputs
and outputs. That is, c = a . b
Hence,
we need not write any complex conditional statements here in data flow model.
Simply implement the output expression. Here, we are implementing the code at a
very basic level i. e. circuit level or gate level.
Behavioral model:
Here,
in behavioral model, one needs to code the behavior of the system to be
designed. If we consider the same above example, the behavior is that, the
output should be one (1) whenever both the inputs are one (1).
Example:
Library
IEEE;
Entity
and2 is
Port
(a, b: in bit;
C: out bit);
End and2;
Architecture
and2 of and2 is
Begin
Process
(a, b)
begin
if (a=1 and b=1) then
c<='1';
else
c<='0';
c<='1';
else
c<='0';
end if;
end process;
end and2;
We
are implementing the LOGIC here. We are least bothered about the circuits that
can implement this logic. Hence, it is a system level or logic level modeling
style.
Structural modeling:
In
structural modeling of VHDL, the concept of components is used. In this model,
the system to be designed is considered as a combination of sub structures.
These sub structures are called components.
For example, a Half-Adder is a combination of a XOR gate and an AND gate. Hence, the components used for designing a half adder are:
For example, a Half-Adder is a combination of a XOR gate and an AND gate. Hence, the components used for designing a half adder are:
XOR gate
AND gate
VHDL Code for XOR gate:
library ieee;
use ieee.std_logic_1164.all;
entity XOR1 is
port (a, b: in std_logic;
c:
out std_logic);
end
XOR1;
architecture XOR1 of XOR1 is
begin
c <= a xor b;
end
XOR1;
VHDL Code for AND gate:
Library IEEE;
use ieee.std_logic_1164.all;
entity AND1 is
port
(a,
b: in std_logic;
c: out std_logic);
end
AND1;
architecture AND1 of AND1 is
begin
c <= a and b;
end
AND1;
VHDL Code for Half Adder:
library ieee;
use ieee.std_logic_1164.all;
entity half_add is
port
(a,
b: in std_logic;
sum, carry : out std_logic);
end half_add;
architecture half_add of half_add is
component XOR1 is
port (a, b: in std_logic;
c:
out std_logic);
end component XOR1;
component AND1 is
port (a, b: in std_logic;
c: out std_logic);
end component AND1;
begin
SUM1: XOR1 port map (a,
b, sum);
CARRY1: AND1 port map (a,
b, carry);
End
half_add;
Notice that the same input names a and b for
the ports of the XOR gate, for AND
gate and for half adder were used. This does not pose a problem in
VHDL since they refer to different levels. However, for readability, it may be
easier to use different names. Data type should be same for components and main
module.
VHDL Data Objects:
A data object is created by an object declaration and has a value and type associated with it. An object can be a Constant, Variable, and Signal. Signals can be considered wires
in a schematic that can have a current value and future values, and that are a
function of the signal assignment statements. On the other hand, Variables and
Constants are used to model the behavior of a circuit and are used in
processes, procedures and functions, similarly as they would be in a
programming language.
Data Objects are classified in to three types.
They are listed below:
- Constants
- Signals
- Variables
Constants:
Constant holds the value, which cannot be changed during the run
time. Constants generally used for easier readability. It can be used in
Package, Entity or in the Architecture. If it is used inside the package then
that constant will be used as global wherever the package is used across
several entities. If the constant used under the entity then the constant may
be used in different architectures. When the constant is used inside
architecture then it will be local to that architecture.
A
constant can have a single value of a given type and cannot be changed during
the simulation. A constant is declared as follows,
Constant name_of_constant : Data_Type : = initial value;
Where the initial value is optional. Constants
can be declared at the start of an architecture and can then be used anywhere
within the architecture. Constants declared within a process can only be used
inside that specific process.
Example:
Constant abc : time := 2 ns;
Constant DELAY1: time := 4 ns;
Constant R_TIME, F_TIME: time:= 1 ns;
Constant DATA_BUS16 : integer:= 16;
Signals:
Signals behave as wire to transport data; it interconnects the design through ports. Signals acts as the memory elements to store the data. It will store the values either '1' or '0'. Values to the signal is assigned in "<=" format.
Signals
are declared outside the process using the following statement:
signal
signal_names : Data_Type :=
initial value ;
Example:
signal
count: std_logic;
signal clk:
bit;
signal abc: integer :=0;
signal data_bus8: bit_vector (0 to 7);
signal xyz: integer range 0 to 10;
Signals are
updated when their signal assignment statement is executed, after a certain delay, as illustrated
below,
SUM1
<= (A xor B) after 2 ns;
If
no delay is specified, the signal will be updated after a delta delay. One can also specify
multiple waveforms using multiple events as illustrated below,
signal xyz : std_logic;
xyz <= ‘0’,
‘1’ after 5ns, ‘0’ after 10ns, ‘1’ after 20 ns;
If signals assigned inside clock, sensitivity
process assigned value will be available from the next clock cycle. If it is
assigned outside the process then the value will be assigned immediately.
Variables:
Variables are like signals but it doesn't have
any memory to store the value. Assigned value will be available on the same
time period without any delay. Values to the variable are assigned in
":=" format. Variables must be
declared inside a process.
The
variable declaration is as follows:
variable
variable_names : Data_Type := initial
value ;
Example:
variable abc: bit :=0;
variable xyz: Boolean
:=FALSE;
variable SUM: integer
range 0 to 100 :=16;
variable BIT12:
bit_vector (7 downto 0);
The variable SUM,
in the example above, is an integer that has a range from 0 to 100 with initial
value of 16 at the start of the simulation. The fourth example defines a bit
vector or 8 elements: BIT12 (7), BIT12 (6), … BIT12 (0).
A
variable can be updated using a variable assignment statement such as
Variable_name:=
expression;
As
soon as the expression is executed, the variable is updated without any delay.
Variables vs. Signals:
It
is important to understand the difference
between variables and signals, particularly how it relates to when their
value changes. A variable changes instantaneously when the variable assignment
is executed. On the other hand, a signal changes a delay after the assignment
expression is evaluated. If no delay is specified, the signal will change after
a delta delay. This has
important consequences for the updated values of variables and signals.
Example
using VARIABLE
|
Example
using SIGNAL
|
signal a, b, c, x, y : integer;
begin process (a, b, c) variable m, n : integer; begin m := a; n := b; y <= m + n; m :=c; x <= m + n; end process; |
signal a, b, c, x,
y : integer;
signal m, n: integer; begin process (a, b, c, m, n) begin m <=a; n <=b; y <= m + n; m <=c; x <= m + n; end process; |
Signal
values are assigned after the process execution only
the last signal assignment is carried out m <= a;
is overwritten by m <= c; the 2nd adder input is
connected to c.
The two
processes shown in the example implement different behavior as both outputs x
and y will be set to the result of b+c when signals are used instead of
variables. Please note that the intermediate signals have to add to the
sensitivity list, as they are read during process execution.
Comparison
between Signal and Variable:
Signal
is updated after a certain delay when its signal assignment statement is
executed. The variable is updated as soon as the statement is executed without
any delay.
Variables
take less memory while signals need more memory as they need more information
to allow for scheduling and signal attributes.
Signals
are declared in entity or architecture using “<=” symbol where as variables
are declared inside process or functions using “: =” symbol.
Signals
have attributes and variables do not have attributes.