vhdltest-bench

Signals become undefined even though signal assignment is executed inside a VHDL process


Say I have this VHDL code-snippet, present in the architecture of an entity

p1 : process(resetn)
begin 
   if resetn'event and resetn = '0' then
      A <= '0';
      B <= '0';
   end if;
end process

And I have another process

p2 : process(clk)
begin
   if clk'event and clk = '1' then
      if some_expression then
         A <= '1';
      elsif some_other_expression then
         B <= '1';
      end if;
   end if;
end process

And the signals A and B are defined as follows:

signal A :  std_logic;
signal B :  std_logic;

What I'm seeing is that at the start of the simulation, my testbench is driving resetn from 1-> 0 -> 1 again (after certain ns)

However, these signals A and B are not assigned the value of '0' and remain 'U' that too throughout the simulation (despite me ensuring that some_expression and some_other_expression both are hit)

Any idea why?


Solution

  • In case anyone else comes across this, let me explain what's going on here. Both processes are driving the signal. Drivers are determined at compile time not runtime and exist for any signal that has a signal assignment statement anywhere in the process (I'm pretty sure even inside an if false would count). Here's the relevant part of the spec:

    Every signal assignment statement in a process statement defines a set of drivers for certain scalar signals. There is a single driver for a given scalar signal S in a process statement, provided that there is at least one signal assignment statement in that process statement and that the longest static prefix of the target signal of that signal assignment statement denotes S or denotes a composite signal of which S is a subelement. Each such signal assignment statement is said to be associated with that driver. Execution of a signal assignment statement affects only the associated driver(s).

    There's some other bits in there that get tricky too, technically there's a driver any time the static prefix of the signal assignment contains the signal. This can be troublesome if you have for instance some_signal_array(i).a <= '0'; where you have an array of records. Now the entire array and all members of the record have drivers (e.g. b, c, d, whatever else is in the record) not just the a value.

    The way you need to think of this is that each process provides a driver to the signal, then they all get resolved by way of the resolution function. So your first process is driving them with '0' (at least once it's been reset), but your second process is driving them with 'U' as it hasn't set them yet. 'U' always resolves to 'U' (doesn't matter what the other signal is), hence why you get 'U'.

    There are shared variables, but I don't think I've ever seen them used, not quite sure other than it's just not a paradigm that gets used much.