2. Dataflow Style in VHDL
Concurrent Statement
In general, digital circuits are concurrent in nature (working in parallel or simultaneously). A change in the output of a concurrent circuit is directly influenced by a change in an input. Therefore, VHDL also adopts the concept of concurrency when processing the inputs and outputs of a circuit. A program in VHDL cannot be equated to software programming where instructions are executed sequentially. Instructions in VHDL are executed directly and simultaneously. However, with certain techniques, VHDL can also describe sequential circuits whose processes are executed in order.
A concurrent statement is a method used to describe the parallel operation of hardware in VHDL. There are four ways to describe a concurrent statement:
-
Concurrent signal assignment : This is the most common method used to describe a concurrent statement. The output of the circuit can change at any time when one of its inputs changes. Example description of a 3-input NAND and AND gate using concurrent signal assignment:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Entity defines the inputs and outputs (the "black box")
entity Logic_Gates is
port (
a, b, c : in STD_LOGIC; -- Three inputs
y_and : out STD_LOGIC; -- Output for the AND gate
y_nand : out STD_LOGIC -- Output for the NAND gate
);
end Logic_Gates;
-- Architecture describes what happens inside the box
architecture Behavioral of Logic_Gates is
begin
-- These two statements are CONCURRENT. They happen at the same time.
y_and <= a and b and c;
y_nand <= a nand b and c;
end Behavioral;
-
Conditional signal assignment : This method is used to describe a statement that has a single target signal but has more than one condition to evaluate. Example description of a 2-to-1 Mux using conditional signal assignment:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Entity for a 2-to-1 Multiplexer
entity Mux_2_to_1_Conditional is
port (
i0, i1 : in STD_LOGIC; -- The two data inputs
sel : in STD_LOGIC; -- The select line
y : out STD_LOGIC -- The single output
);
end Mux_2_to_1_Conditional;
-- Architecture using the "when/else" concurrent statement
architecture Behavioral of Mux_2_to_1_Conditional is
begin
-- The output 'y' gets the value of 'i0' WHEN 'sel' is '0',
-- ELSE it gets the value of 'i1'.
y <= i0 when sel = '0' else i1;
end Behavioral;
-
Selected signal assignment : This method differs from the conditional signal assignment method. In a selected signal assignment, the target is based on the evaluation of an expression. Example description of a 2-to-1 Mux with selected signal assignment:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Entity for a 2-to-1 Multiplexer
entity Mux_2_to_1_Selected is
port (
i0, i1 : in STD_LOGIC; -- The two data inputs
sel : in STD_LOGIC; -- The select line
y : out STD_LOGIC -- The single output
);
end Mux_2_to_1_Selected;
-- Architecture using the "with/select" concurrent statement
architecture Behavioral of Mux_2_to_1_Selected is
begin
-- WITH the value of 'sel', SELECT the output 'y'
with sel select
y <= i0 when '0', -- When sel is '0', y gets i0
i1 when '1', -- When sel is '1', y gets i1
'X' when others; -- For any other value (like 'U' or 'Z'), output 'X' (unknown)
end Behavioral;
-
Process Statement : A method that can be used to execute many instructions sequentially. This section will be discussed in more detail in module 4 regarding Sequential Circuit Design.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Entity for a 2-to-1 Multiplexer
entity Mux_2_to_1_Process is
port (
i0, i1 : in STD_LOGIC; -- The two data inputs
sel : in STD_LOGIC; -- The select line
y : out STD_LOGIC -- The single output
);
end Mux_2_to_1_Process;
architecture Behavioral of Mux_2_to_1_Process is
begin
-- This process block is sensitive to changes in i0, i1, or sel.
-- If any of them change, the code inside runs sequentially.
mux_process: process(i0, i1, sel)
begin
-- Inside a process, you use sequential statements like "if/then/else"
if sel = '0' then
y <= i0;
else
y <= i1;
end if;
end process mux_process;
end Behavioral;
Intermediate Signal
An intermediate signal has a function that is very similar to a signal declared in the entity. However, an intermediate signal is defined inside the architecture (before the begin
keyword). Intermediate signals are very useful when the circuit we are describing becomes more complex. This signal can also act as a buffer to store data that has been processed in a specific part of the overall architecture.
architecture Behavioral of Counter is
signal count_value : integer := 0; -- This is an example of an intermediate signal
begin
process (clk)
begin
if rising_edge(clk) then
count_value <= count_value + 1;
end if;
end process; -- ...
end Behavioral;
Multiple Bits Signal
With STD_LOGIC, we can represent the values '0' and '1' in the circuit we are describing (in the entity and architecture sections). In addition, we can also combine more than one bit into a single signal by using the STD_LOGIC_VECTOR signal type. This signal becomes a one-dimensional vector or array that represents data with a number of bits that can be set by the user.
entity Register is
Port (
data_in : in STD_LOGIC_VECTOR(7 downto 0); -- 8-bit Input
data_out : out STD_LOGIC_VECTOR(7 downto 0) -- 8-bit Output
);
end entity Register;
architecture Behavioral of Register is
signal internal_register : STD_LOGIC_VECTOR(7 downto 0); -- 8-bit signal
begin
process (clk)
begin
if rising_edge(clk) then
if (load = '1') then
internal_register <= data_in; -- Loading data into the register
else
data_out <= internal_register; -- Outputting data from the register
end if;
end if;
end process; -- ...
end Behavioral;
1.6 VHDL Architecture Models
In VHDL, there are several approaches to explaining or describing an architecture. Hardware can be described using these styles or models according to its needs and complexity. These approaches are divided into three types:
-
Data-flow style : The data-flow approach describes a circuit by showing the relationship between the inputs and outputs of the components in the VHDL language. Concurrent signal assignment, conditional signal assignment, and selected signal assignment are the statements used in the data-flow style.
-
Behavioral style : The behavioral style approach doesn't describe how the circuit is implemented when synthesized. Instead, the behavioral style models how the circuit's output reacts to its inputs. The main component of the behavioral style is the process statement.
-
Structural style : The structural style approach is essentially a method that supports the interconnection of black boxes or entities. This style enables modular design, allowing you to connect previously separate components into a single circuit or entity. The structural style is commonly used when a circuit becomes increasingly complex, as it simplifies the description process.