Transcript Slide 1

Programming in
VHDL Using Processes
How Processes Run
A process is either in suspend mode or is running.
For a process to run, there has to be a change in any of the variables in
the sensitivity list of the process.
When a process is completed, it enters in suspend mode until the next
change in its sensitivity list.
If there is no sensitivity list, then the process will run forever.
These observations give us the execution model that follows.
An Execution Model for Processes
We describe the execution of a process as follows:
suspend process; -- in suspend mode
while (1)
-- continuously check
if (change in the sensitivity list or
there is no sensitivity list)
run process;
suspend process; -- when you have a wait command
end if
Serial and Parallel Execution
• Inside an architecture, we note that every time we call a process,
function, or a procedure, then all calls are processed in parallel.
• Internally though, in a process, function, or procedure, we have
serial execution; from the first to the second, to the third instruction
(just like “C”). A process, function, or a procedure can define subfunction(s) or sub-procedure(s); but we cannot have subprocesses.
• We need to be careful to avoid parallel changes to the same data. In
general, parallel programming rules apply here.
• Carefully check how the code gets mapped to the hardware!
Defining a Bus in VHDL
(Also exposes issues in Parallel Assignment)
Bus Definition Using VHDL (I/II)
-- In the following example, we make use of std_ulogic
-- to define buses.
library IEEE;
use IEEE.std_logic_1164.all; -- for the definition of std_ulogic, …
-- If Select_inp='0' then Bus_out <= A where Α, Β are 4-bit.
-- If Select_inp=‘1' then Bus_out <= B;
entity Bus_two_4_bit_inps is port (
Select_inp : in std_logic; -- chooses signals between Α(3:0) and B(3:0).
Α, Β
: in std_logic_vector (3 downto 0); -- input buses
Bus_out : out std_ulogic_vector (3 downto 0)); -- exit bus
end Bus_two_4_bit_inps;
Bus Definition Using VHDL (II/II)
architecture behavioral_two_4bit_bus of Bus_two_4_bit_inps is
begin
process (Select_inp, A) – change in A or Select_inp always runs the process.
begin
if Select_inp='0' -- select A
then
Bus_out <= To_stdULogicVector (A); -- Copy to the output
else
Bus_out <= (others => 'Z');
-- hi-Z value to the rest
end if;
end process;
process (Select_inp, B) -- change in B or Select_inp always runs the process.
begin
if Select_inp='1' -- select Β
then
Bus_out <= To_stdULogicVector (B); -- Copy to the output
else
Bus_out <= (others => 'Z');
-- hi-Z value for the rest
end if;
end process;
end behavioral_two_4bit_bus;
Bus Synthesis in VHDL
We note that Bus_out is affected by two process instructions.
Note that any change in Select_inp will force both process
instructions to run. Furthermore, they will both attempt to assign
a value to the output.
What will happen?
The final values for Bus_out will be determined by a call to the
function resolved, as we explain next.
Using a Function for Determining Values
in Parallel Execution
In the std_logic_1164 package, we define the type std_ulogic (standard unresolved
logic) as an enumerated data type:
TYPE std_ulogic IS ( 'U',
'X',
'0',
'1',
'Z',
'W',
'L',
'H',
'-'
);
-- Uninitialized
-- Forcing Unknown
-- Forcing 0
-- Forcing 1
-- High Impedance
-- Weak Unknown
-- Weak 0
-- Weak 1
-- Don't care
The following definition of std_logic defines the function resolved as the function
to use in case we have multiple instructions trying to assign a value to a variable
of type std_logic:
SUBTYPE std_logic IS resolved std_ulogic;
Definition of the resolved function
in the std_logic_1164 package (I/II)
TYPE stdlogic_table IS ARRAY (std_ulogic, std_ulogic) OF std_ulogic;
-------------------------------------------------------------------- resolution function
------------------------------------------------------------------CONSTANT resolution_table : stdlogic_table := (
----------------------------------------------------------| U X 0 1 Z W L H | |
---------------------------------------------------------( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U | <- unknown outputs.
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ),
-- | 0 | <- output=0 if both inputs are 0s ...
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ),
-- | 1 | <- output=1 if both inputs are 1s …
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' )
-- | - |
);
--
Definition of the resolved function
in the std_logic_1164 package (II/II)
FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS
VARIABLE result : std_ulogic := 'Z'; -- weakest state default
BEGIN
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and that
-- would conflict with the value of a single driver unresolved
-- signal.
IF (s'LENGTH = 1) THEN RETURN s(s'LOW);
ELSE
FOR i IN s'RANGE LOOP
result := resolution_table(result, s(i));
END LOOP;
END IF;
RETURN result;
END resolved;
The expression (s'LENGTH=1) checks if we have only one element in the array,
while s(s'LOW) returns the smallest value that we can assign to the signal.
For more information, see the discussion on attibutes.
If there are two or more attempts to assign a value, we use the resolution_table
in sequence …
Basic Problems
Analysis problems.
Problem 1. Give the logic diagram that describes the bus in our
previous example.
Problem 2. Compute the values of Bus_out for different input
combinations.
A Synthesis Problem.
Problem 3. Give the VHDL code for a bus with four input signals,
each with two bits.