Compare VHDL signals, variables, and constants, including declaration scope, update timing, synthesis behavior, and when to use each one.
Signals, variables and constants pass values in different ways. Their choice describes model behavior; the resulting hardware depends on how they are assigned.
Property
Signal
Variable
Constant
Common use
Block connection or port
Local calculation
Fixed parameter
Assignment
Scheduled update
Immediate update
None after elaboration
Visibility
Depends on declaration region
Depends on declaration region
Depends on declaration region
Synthesis
Logic or storage, depending on code
Logic or storage, depending on code
Constant value
Connect blocks with signals
A signal passes values between concurrent blocks. It may represent a combinational connection or a stored value:
architecture rtl of example is -- Declaration in the architecture area signal w_intermediate : std_logic; signal r_counter : unsigned(7 downto 0) := (others => '0');begin -- Signal assignments are deferred w_intermediate <= i_a AND i_b; o_result <= w_intermediate OR i_c;end architecture rtl;
A signal assignment schedules an update. Without an explicit delay, the update occurs in a later simulator step, a delta-cycle. The simulator applies scheduled values and reevaluates affected blocks without advancing displayed time.
process(i_clk)begin if rising_edge(i_clk) then r_a <= '1'; r_b <= r_a; -- r_b receives the OLD value of r_a! -- r_a and r_b are both updated after the process end if;end process;
Here, r_b reads the old value of r_a. Both registers update after process execution, so r_b follows r_a one clock cycle later. Delta cycles explain simulation ordering; clock edges determine hardware storage.
Calculate locally with variables
Assignment with := immediately changes the variable for subsequent process or subprogram statements:
This difference changes which value the next calculation uses:
process(i_clk) variable v_x : std_logic;begin if rising_edge(i_clk) then -- With variable (immediate update) v_x := i_data; -- v_x takes i_data immediately o_y <= v_x; -- o_y = i_data (synchronous, same cycle) -- With signal (deferred) -- w_x <= i_data; -- o_y <= w_x; -- o_y = old value of w_x! end if;end process;
A variable is useful for intermediate results. It does not inherently require a register: its use may describe combinational logic or storage. Signals communicate between processes and through ports.
Fix parameters with constants
A constant retains the value determined during its elaboration. It may depend on generic parameters: