Skip to content

VHDL · Chapter 3.2 · Signals & Hardware Behavior

Signal Assignment in VHDL

Signal assignment looks like storing a value, but it is really scheduling one. Assigning a signal projects a transaction onto that signal's driver, and the signal only takes the new value after a delta delay, or after an explicit delay if you add one. Two consequences follow that trip up newcomers and explain a great deal of real RTL. Inside a process, if you assign the same signal twice, the last assignment wins, and a concurrent assignment outside a process is simply a driver that is always re-evaluated. This lesson builds the driver-and-schedule model, contrasts signal assignment with the immediate update of a variable or constant, and shows how last-assignment-wins, default assignments, and multiple drivers all fall out of one idea.

Foundation15 min readVHDLSignal AssignmentDriversDelta Cyclenumeric_stdRTL

1. Intuition — assignment projects a transaction onto a driver

A signal does not hold a value the way a variable does. Behind every signal is a driver, and s <= value places a transaction — "become this value at this (future) time" — onto that driver. With no explicit delay the time is the next delta cycle; with after t (lesson 2.13) it is t later. The signal's actual value is whatever its driver projects once that time arrives.

assignment_is_scheduling.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
s <= a;            -- schedule s := a for the next delta cycle
s <= a after 2 ns; -- schedule s := a for 2 ns from now (simulation modelling)

Holding "assignment = schedule a transaction on a driver" in mind is what makes the rest of this lesson — and multiple drivers, and the delta model — coherent rather than a list of special cases.

2. Inside a process — last assignment wins

A process executes top to bottom, but signal updates are not applied until it suspends. So if a process assigns the same signal more than once, every assignment targets the same delta update, and the last one executed overwrites the earlier ones. Only the final value is ever scheduled:

last_assignment_wins.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
process (sel, a, b)
begin
  y <= a;          -- scheduled...
  if sel = '1' then
    y <= b;        -- ...overwritten: if sel='1', the final scheduled value is b
  end if;
end process;
-- Net effect: y = b when sel='1', else y = a. The first 'y <= a' acts as a DEFAULT.

This is not a bug — it is the single most useful idiom in combinational VHDL: assign a default first, then override conditionally. Because the default always runs, every path assigns y, which (as a later lesson details) is exactly how you avoid an unintended latch.

3. The driver and the delta update, drawn

signal assignment projecting a transaction onto a driver, applied at the delta cyclescheduleon suspendupdates <= valueproject transactiondriverholds the pending value(last write wins)delta cycleapply scheduled valuesignal snew value visible after Δ12
Signal assignment does not write the signal directly. The '<=' projects a transaction onto the signal's driver; when the process suspends, the driver's scheduled value is applied in the next delta cycle and becomes the signal's new value. Inside one process, repeated assignments overwrite the same pending transaction, so only the last survives to the delta update — last-assignment-wins. A concurrent assignment is the same picture with a driver that re-evaluates whenever its inputs change.

4. The update over time — and last-wins on the waveform

The delta update means a signal assigned in a process changes after the triggering event, not during it, and only the final assignment of the step is what you see:

Default-then-override: y is assigned twice; only the last (sel-dependent) value appears

8 cycles
Default-then-override: y is assigned twice; only the last (sel-dependent) value appearssel=1: 'y<=a' then 'y<=b' → last wins, y=b=9sel=1: 'y<=a' then 'y<…sel=0: override skipped → y keeps default a=5sel=0: override skippe…sel00110011a55555555b99999999y55995599t0t1t2t3t4t5t6t7
y is assigned the default a, then conditionally overridden with b. Because both assignments schedule the same delta update, the last one executed determines y. When sel=1 the override runs (y=9); when sel=0 only the default runs (y=5). The signal settles to its final scheduled value each evaluation.

5. Concurrent assignment — a driver that is always live

Outside a process, a concurrent signal assignment is a driver that re-evaluates whenever any input changes — a continuously-active piece of combinational hardware:

concurrent_assignment.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- These run continuously and concurrently; order between them does not matter.
sum   <= std_logic_vector(unsigned(a) + unsigned(b));   -- numeric_std arithmetic
y     <= a when sel = '1' else b;                       -- conditional driver (a mux)
parity <= xor a;                                         -- reduction (VHDL-2008)

Each line is its own driver on its own signal. There is no top-to-bottom execution between them: they all evaluate in parallel, exactly like the gates they describe. (Assigning the same signal from two concurrent statements creates two drivers — see Section 6.)

6. Debugging example — two drivers on one signal

Last-assignment-wins applies within one process. Assign the same signal from two places (two processes, or two concurrent statements) and you create two drivers, which do not overwrite — they are resolved (lesson 2.5):

the accidental multiple driver
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- Two concurrent drivers on bus_o:
bus_o <= x"AA";        -- driver 1
bus_o <= data when en = '1' else (others => 'Z');   -- driver 2
-- With std_logic, the resolution function combines them: driver 1 forces AA while
-- driver 2 drives data → the two FIGHT and you get 'X' on the conflicting bits.
-- With std_ulogic (unresolved), the second driver is an elaboration ERROR.

The symptom is 'X' on a bus you "only assigned once" — but you assigned it from two drivers. The fix is to ensure a signal has a single driver unless you intend a resolved multi-driver bus (tristate), in which case exactly one driver should be active ('Z' elsewhere) at any time. This is why last-assignment-wins (one driver, intentional override) and resolution (multiple drivers, combined) are different mechanisms you must not confuse.

7. Common mistakes & what to watch for

  • Expecting intermediate in-process assignments to take effect. Only the last assignment to a signal in a process step is scheduled; use a variable if you need each step's value.
  • Confusing <= and :=. <= schedules a signal; := updates a variable/constant immediately. They are not interchangeable.
  • Creating accidental multiple drivers. Assigning one signal from two processes/concurrent statements builds two drivers that resolve (to 'X' on conflict), not overwrite.
  • Forgetting the default assignment. In a combinational process, skipping the default-first idiom leaves some path unassigned and infers a latch.
  • Using after to create real timing. In synthesizable logic after is ignored (lesson 2.13); timing comes from clocked registers, not assignment delays.

8. Engineering insight

One model — assignment projects a transaction onto a driver, applied at the delta cycle — explains the behaviours that otherwise look like unrelated rules. Last-assignment-wins is one driver receiving several writes before it updates. The default-then-override idiom is that same behaviour put to work to guarantee full assignment. Concurrent statements are drivers that re-evaluate continuously. Multiple drivers are several drivers on one net, resolved by strength. Once you see signal assignment as scheduling onto drivers rather than storing values, RTL behaviour — combinational vs registered, single vs multi-driver, immediate vs delayed — reads as one consistent system.

9. Summary & next step

Signal assignment (<=) schedules a transaction onto a signal's driver, applied after a delta delay. Inside a process the last assignment to a signal wins, which powers the default-then-override idiom; outside a process, concurrent assignments are always-live drivers. Assigning one signal from two places creates multiple drivers that resolve (not overwrite), and := (variables) is a separate, immediate mechanism.

You can now reason about how a signal takes its value. The module continues by pinning down the remaining signal mechanics — declaring signals and their scope, then the delta cycle and multiple drivers in full — building toward processes and the combinational and sequential logic they describe.