Question

I'm new to VHDL. I understand that processes are executed concurrently. But I don't grasp the output of the following program:

-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

entity Ex2 is
end Ex2;

architecture behav of Ex2 is
 signal A : std_logic;
begin

 proc1 : process is
 begin
  wait for 20 ns;
  A <= '1';
  wait for 20 ns;
  A <= 'Z';
  wait for 20 ns;
  A <= '0';
 end process proc1;

 proc2 : process is

 begin
  wait for 10 ns;
  A <= '0';
 end process proc2;
end behav;

"A" has the follwing values over time:

  • 0 ns - 20 ns -> U
  • 20 ns - 30 ns -> X
  • 30 ns - 40 ns -> 1
  • 40 ns - 80 ns -> 0
  • 80 ns - 90 ns -> X

My imagination how the output should look like:

  • In proc2 "A" get 0 after 10ns. The process ends so "A" should be 0 after 10ns.
  • After 20ns both processes are resuming, both are writing "A" at the same time so X is okay.
  • After 30ns proc2 again writes 0 so "A" should become 0 but it is 1.
  • and so on
Était-ce utile?

La solution

Each process has a driver for A, and the result of driving from the two processes is generated by the resolution function for std_logic.

If you make separate versions of A from the two processes, called A_1 and A_2, and then drive the common A outside the processes with the code:

A <= A_1;
A <= A_2;

Then you can see the value driven from each of the processes in the figure below.

enter image description here

The resolution function then resolved the two sources A_1 and A_2 that drives A based on the table below:

    U X 0 1 Z W L H -
    -----------------
U | U U U U U U U U U  
X | U X X X X X X X X    
0 | U X 0 X 0 0 0 0 X
1 | U X X 1 1 1 1 1 X
Z | U X 0 1 Z W L H X
W | U X 0 1 W W W W X
L | U X 0 1 L W L W X
H | U X 0 1 H W W H X
- | U X X X X X X X X

The initial values driven from start of simulation and until first explicit assign in the process is 'U' (Uninitialized).

So for example, the reason that A is not '0' after 10 ns, is that the value driven to A from proc1 is 'U', and the resolution table above shows that ('U', '0') results in 'U'.

Autres conseils

Each process has it's own driver for A. The effective value of A is the resolved value of both drivers. The processes are concurrent to each other, it's like taking two different ICs and connecting a pin on both to the same net (named A in this case).

The resolution function for std_logic is found in package std_logic_1164 in library ieee.

Values to be resolved are taken two at a time and input to a resolution table:

-------------------------------------------------------------------
-- 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 |
        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
        ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
        ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
        ( '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' )  -- | - |
    );

The intersection of the horizontal and vertical values shown is the resolved values.

If A hadn't been declared with a resolved base type you would have gotten an error message complaining about that instead of resolved values.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top