Variables vs. Signals in VHDL

Variables and Signals in VHDL appears to be very similar. They can both be used to hold any type of data assigned to them. The most obvious difference is that variables use the := assignment symbol whereas signals use the assignment symbol. However the differences are more significant than this and must be clearly understood to know when to use which one. If you need a refresher, try this page about VHDL variables.

Signals vs. Variables:

The most important thing to understand (and the largest source of confusion) is that variables immediately take the value of their assignment, whereas signals depend on if the signal is used in combinational or sequential code. In combinational code, signals immediately take the value of their assignment. In sequential code, signals are used to create flip-flops, which inherently do not immediately take the value of their assignment. They take one clock cycle. In general, I would recommend that beginners avoid using variables. They can cause a lot of confusion and often are hard to synthesize by the tools.

The example below demonstrates how signals behave differently than variables. Notice that r_Count and v_Count appear to be the same, but they actually behave very differently.

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity variable_vs_signal is port ( i_clk : in std_logic; o_var_done : out std_logic; o_sig_done : out std_logic ); end variable_vs_signal; architecture rtl of variable_vs_signal is signal r_Var_Done : std_logic := '0'; signal r_Count : natural range 0 to 6 := 0; signal r_Sig_Done : std_logic := '0'; begin VAR_VS_SIG : process (i_clk) variable v_Count : natural range 0 to 5 := 0; begin if rising_edge(i_clk) then v_Count := v_Count + 1; -- Variable r_Count 

Testbench:

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity variable_vs_signal_tb is end variable_vs_signal_tb; architecture behave of variable_vs_signal_tb is constant c_CLK_PERIOD : time := 10 ns; signal r_Clock : std_logic := '0'; signal w_Var_Done : std_logic; signal w_Sig_Done : std_logic; component variable_vs_signal is port ( i_clk : in std_logic; o_var_done : out std_logic; o_sig_done : out std_logic ); end component variable_vs_signal; begin r_Clock r_Clock, o_var_done => w_Var_Done, o_sig_done => w_Sig_Done ); end behave;

Variables vs. Signals Testbench Waveform

Variables can be a bit tricky to display in simulation. If you are using Modelsim, read more about how to see your variables in Modelsim’s waveform window. Look carefully at the waveform above. Do you see how o_var_done pulses every 5th clock cycle, but o_sig_done pulses every 6th clock cycle? Using signals and variables to store data generates very different behavior. Make sure you clearly understand what you code will be generating and make sure that you simulate your code to check that behaves like you want!