In the previous tutorial we learned how to declare a variable in a process. Variables are good for creating algorithms within a process, but they are not accessible to the outside world. If a scope of a variable is only within a single process, how can it interact with any other logic? The solution for this is a signal.

Signals are declared between the architecture <architecture_name> of <entity_name> is line and the begin statements in the VHDL file. This is called the declarative part of the architecture.

This blog post is part of the Basic VHDL Tutorials series.

The syntax for declaring a signal is:
signal <name> : <type>;

A signal may optionally be declared with an initial value:
signal <name> : <type> := <initial_value>;

Exercise

In this video tutorial we learn how to declare a signal. We will also learn the main difference between a variable and a signal:

The final code we created in this tutorial:

entity T06_SignalTb is
end entity;

architecture sim of T06_SignalTb is

    signal MySignal : integer := 0;

begin

    process is
        variable MyVariable : integer := 0;
    begin

        report "*** Process begin ***";

        MyVariable := MyVariable + 1;
        MySignal   <= MySignal + 1;

        report "MyVariable=" & integer'image(MyVariable) &
            ", MySignal=" & integer'image(MySignal);

        MyVariable := MyVariable + 1;
        MySignal   <= MySignal + 1;

        report "MyVariable=" & integer'image(MyVariable) &
            ", MySignal=" & integer'image(MySignal);

        wait for 10 ns;

        report "MyVariable=" & integer'image(MyVariable) &
            ", MySignal=" & integer'image(MySignal);

    end process;

end architecture;

The output to the simulator console when we pressed the run button in ModelSim:

VSIM 2> run
# ** Note: *** Process begin ***
#    Time: 0 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=1, MySignal=0
#    Time: 0 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=2, MySignal=0
#    Time: 0 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=2, MySignal=1
#    Time: 10 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: *** Process begin ***
#    Time: 10 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=3, MySignal=1
#    Time: 10 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=4, MySignal=1
#    Time: 10 ns  Iteration: 0  Instance: /t06_signaltb
# ** Note: MyVariable=4, MySignal=2
#    Time: 20 ns  Iteration: 0  Instance: /t06_signaltb
...

Get exclusive access to exercises and answers!

Analysis

We created a signal and a variable with the same initial value of 0. In our process we treated them in the exact same way, yet the printouts reveal that they behaved differently. First we saw that the assignment to a variable and a signal has a different notation in VHDL. Variable assignment uses the := operator while signal assignment uses the <= operator.

MyVariable behaves as one would expect a variable to behave. In the first iteration of the loop it is incremented to 1, and then to 2. The last printout from the first iteration shows that its value is still 2, as we would expect.

MySignal behaves slightly different. The first +1 increment doesn’t seem to have any effect. The printout reveals that its value is still 0, the initial value. The same is true after the second +1 increment. Now the value of MyVariable is 2, but the value of MySignal is still 0. After wait for 10 ns; the third printout shows that the value of MySignal is now 1. The subsequent printouts follow this pattern as well.

What is this sorcery? I will give you a clue, the wait for 10 ns; has something to do with it. Signals are only updated when a process is paused. Our process pauses only one place, at wait for 10 ns;. Therefore, the signal value changes only every time this line is hit. The 10 nanoseconds is an arbitrary value, it could be anything, even 0 nanoseconds. Try it!

Another important observation is that event though the signal was incremented twice before the wait, its value only incremented once. This is because when assigning to a signal in a process, the last assignment “wins”. The <= operator only schedules a new value onto the signal, it doesn’t change until the wait. Therefore, at the second increment of MySignal, 1 is added to its old value. When it is incremented again, the first increment is completely lost.

Takeaway

  • A variable can be used within one process while signals have a broader scope
  • Variable assignment is effective immediately while signals are updated only when a process pauses
  • If a signal is assigned to several times without a wait, the last assignment “wins”

Go to the next tutorial »

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.