x Getting Initializations to Work Properly


Question: I’ve got a call to a conversion function to convert a Std_logic_vector to an Integer. I then use the integer to pick a value out of a register file array.

type RegType is array (15 downto 0) of Std_logic_vector(7 downto 0);
...
entity Dblock1 is
  port (A: in Std_logic_vector(3 downto 0) := "0000";
        Reg: in RegType;
        ...
Word <= Reg(To_integer(A));

The problem is that the value of the vector A at time 0 is "UUUU", so the To_integer conversion returns -2147483647, which underflows the array range (15 downto 0). I want to force the value of A at time 0 to be "0000" to avoid the underflow, but the simulator seems to ignore the initial value shown above for the port. I've also tried initializing the signal connected to the port, as shown below, but this has no effect either!

signal A: Std_logic_vector(3 downto 0) := "0000";
...
B1: Dblock1 port map (A, ...);

As an experiment, I've tried forcing a value on A at time zero with a signal assignment, but the signal is still initially "UUUU".

My VHDL code compiles OK. I am using the syntax shown in the text books. Why does the simulator ignore the initial values? How can I initialize the signal?

Answer: As you have discovered, you have to be very careful when initializing signals, and it can be very frustrating until you know the trick!

Well, there is a trick! Let's illustrate it with an example:

entity Comp is
  port (A: in  Integer := 5;
        F: out Integer := 1);
end;

architecture A1 of Comp is
begin
  F <= A;
end;

entity Top is
end;

architecture A1 of Top is
  component Comp
    port (A: in  Integer := 4;
          F: out Integer := 2);
  end component;
  signal P, Q: Integer := 3;
begin
  C1: Comp port map (open, P);
  C2: Comp port map (P, Q);
end;

Here we have initialized the signal (P) connecting the two instances of Comp in no fewer than 5 different places to 5 different values. So, which value will win, or will they all be ignored, or will they be in conflict? The answer is that at the start of simulation, the signal P will be initialized to the value 1, the initial value of the out port. The other 4 initial values will have no visible effect at all.

To understand why this is, we have to think a bit deeper about what is going on behind the scenes when the VHDL source code gets compiled. So here goes...

Every VHDL signal has none, one or several VHDL drivers. Drivers are not the easiest VHDL concept to understand, because they are invisible! You have to imagine them! The VHDL compiler creates a driver whenever a signal is assigned within a process, just one driver for each process-signal pair. (For VHDL gurus: the same is true for any concurrent statement that is defined by an equivalent process.)

Drivers are an important VHDL concept, and help explain several VHDL phenomena including bus resolution, event sequencing, and in this case, initialization. Drivers are important for initialization, because in effect it is the driver which actually determines the value of a signal. If you want to set an initial value on a signal, you must set the initial value of the driver of that signal, which means writing the initial value in the same region of the VHDL code as the driver.

In our example, the driver for the signal in question comes from the concurrent signal assignment (F <= A:) to the output port F of instance C1 of component/entity Comp, so it is the initial value on the out port which matters. During the initialization phase of simulation (immediately before time zero), the driver is initialized to the value 1, and that value is then propagated along the signal and through the ports, overwriting the initial values of the other signal segments connected to the same electrical net.

In conclusion, to initialize a signal, you must hunt down the place in the VHDL source code where the signal is ultimately assigned, and insert the initial value into the signal (or port) declaration at that level. Initial values elsewhere on the net are allowed in the syntax, but have no effect on the value of the signal.

There is one situation where initial values on input ports become relevant, and that is when the input port is unconnected. This happens in the case of port A on instance C1 of Comp shown above. Within instance C1 of Comp, port A will be initialized to the value 4, the default value from the component. The default value (5) of the input port of the entity Comp is once again irrelevant.

Just to emphasise the point, let's look at one final situation. Suppose we change the declaration of entity Comp to read as follows, but leave the rest of the example the same:

entity Comp is
  port (A: in  Integer := 5;
        F: out Integer);
end;

We've removed the default value from the output port F of the entity. What will be the initial value on the input port A of instance C2 now? The answer is Integer'Left (or -2147483647). The initial value of the signal in the part of the VHDL text containing the driver still wins. In this case there is no explicit initial value, so the initial value defaults to the leftmost value of the type of the signal. The explicit initial values on the other parts of the signal are once again ignored and are overwritten by the initial value of the driver.


xDoulos Training Courses
xVHDL FAQ
author iconBack to “Your VHDL Problems Answered” Index


river sceneDoulos Home Page

Copyright 1995-1996 Doulos
This page was last updated 24th July 1996.

mail iconWe welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk