# Processes and rising_edge

*Describing logic that remembers*

A VHDL process is a block of statements that re-evaluates when a signal in its sensitivity list changes, and the pattern 'if rising_edge(clk)' inside it describes edge-triggered sequential logic, synthesising to a D flip-flop or register.

Group: HDL
URL: https://digiwleea.wleeaf.dev/learn/vhdl-process/

A [concurrent assignment](https://digiwleea.wleeaf.dev/learn/vhdl-concurrent/) describes combinational logic: output follows input, no memory. But a computer must **remember**, and from the [D flip-flop](https://digiwleea.wleeaf.dev/learn/dff/) you know memory comes from capturing a value on the clock edge. VHDL describes that with a **process** and the `rising_edge` test. This is how you write anything sequential: registers, counters, the accumulator of your CPU.

## What a process is

A **process** is a block (`process ... begin ... end process`) that wakes up and re-evaluates whenever a signal in its **sensitivity list** (the names in `process(clk)`) changes. Inside the process, statements read top to bottom like software, which is why processes feel familiar, but the process as a whole is still one piece of hardware. For a clocked storage element, the only signal we care about is the clock, so the list is just `process(clk)`.

## rising_edge: capturing on the clock

Inside the process, `if rising_edge(clk) then ... end if;` is the magic phrase. `rising_edge(clk)` is true only at the instant `clk` goes from `'0'` to `'1'`, the **rising edge**, exactly the one moment a [D flip-flop](https://digiwleea.wleeaf.dev/learn/dff/) samples. Any signal assigned inside that `if` is captured at the edge and held until the next one. This single pattern is the universal template for edge-triggered storage; synthesis turns it into actual flip-flops.

```vhdl
library ieee;
use ieee.std_logic_1164.all;

entity dff is
  port (
    clk : in std_logic;
    D : in std_logic;
    Q : out std_logic
  );
end entity;

architecture rtl of dff is
  signal q_r : std_logic := '0';
begin
  process(clk)
  begin
    if rising_edge(clk) then
      q_r <= D;
    end if;
  end process;
  Q <= q_r;
end architecture;
```

_A D flip-flop as a clocked process. The internal signal q_r is the stored bit; it captures D on each rising edge and is then assigned out to the port Q. This is a template skeleton: digiwleea generates the entity and the process shell, and the body (q_r <= D) is the logic you fill in._

Read the architecture as hardware. The internal [signal](https://digiwleea.wleeaf.dev/learn/vhdl-signals/) `q_r` is the flip-flop's stored bit (initialised to `'0'`). The process says: on every rising clock edge, load `q_r` with whatever `D` is at that instant. Outside the process, the concurrent line `Q <= q_r` wires the stored bit to the output port continuously. That mix is normal: the process is the sequential part, the final assignment is plain combinational wiring.

> **TIP:** Why assign to an internal `q_r` and then to `Q`, instead of straight to `Q`? Because in classic VHDL an `out` port cannot be read back, and a flip-flop's next value sometimes depends on its current one (a counter does `q_r <= q_r + 1`). Keeping the state in a readable internal signal, then driving the port from it, is the standard, safe pattern. It mirrors the [register bit](https://digiwleea.wleeaf.dev/learn/regbit/) holding its own value.

## Why the if has no else

Notice there is no `else`. When `clk` is **not** rising, the `if` simply does not fire, so `q_r` keeps its old value, it **remembers**. In a process, a signal that is not reassigned holds its previous value, and that held value is exactly what makes it storage. An `else` branch here would describe combinational logic instead and break the flip-flop.

> **WARN:** The classic beginner trap: writing `if rising_edge(clk) then ... else ... end if;` or testing a level (`if clk = '1'`) instead of the edge. A level test describes a transparent **latch** (the [D latch](https://digiwleea.wleeaf.dev/learn/dlatch/) problem you already saw), not an edge-triggered flip-flop, and adding an `else` to a clocked process tends to create unintended latches the synthesis tool will warn about. For a register, use `rising_edge(clk)` with no `else`, and let the no-fire case hold state.

> **KEY:** Why this matters: `if rising_edge(clk)` is the single most-used pattern in real VHDL, because every register, counter, and state machine in a synchronous design is built on it. The [register](https://digiwleea.wleeaf.dev/learn/regbit/), the program counter ([counter](https://digiwleea.wleeaf.dev/learn/counter/)), and the instruction register of your CPU are all this template, widened to many bits. Master it and you can describe any sequential circuit you built by hand.

_Circuit diagram: The flip-flop the process describes. Open it in the lab and pulse the clock: Q captures D only on the rising edge, the hardware behind if rising_edge(clk)._

**Q (Try it):** Inside `if rising_edge(clk) then q_r <= D; end if;`, suppose `clk` is currently high and steady (no new edge) while `D` flips from `0` to `1`. Does `q_r` change? Why?

**A:** No, `q_r` does **not** change. `rising_edge(clk)` is true only at the `0`-to-`1` transition, so with `clk` already high and steady the `if` never fires; `q_r` holds its captured value. Changing `D` between edges is ignored, which is exactly the edge-triggered behavior of a D flip-flop (one update per rising edge, glitches on `D` in between are invisible).

### FAQ

**Q:** What is a process in VHDL?

**A:** A process is a block of statements that re-evaluates whenever a signal in its sensitivity list changes. Statements inside read top to bottom, but the process as a whole is one piece of hardware. It is how VHDL describes sequential (clocked) logic, as opposed to concurrent assignments which describe combinational logic.

**Q:** What does rising_edge(clk) do in VHDL?

**A:** rising_edge(clk) is true only at the instant the clock goes from '0' to '1'. Used as 'if rising_edge(clk) then ...', it captures the assigned signals at that edge and holds them until the next rising edge, which is exactly a D flip-flop's behavior. Synthesis turns the pattern into real flip-flops.

**Q:** Why is there no else in a clocked VHDL process?

**A:** When the clock is not rising, the if simply does not fire, so the signal keeps its previous value, which is what makes it storage. Adding an else would describe combinational logic and can create unintended latches, so a register uses 'if rising_edge(clk)' with no else.

**Q:** How do you describe a D flip-flop in VHDL?

**A:** Put 'if rising_edge(clk) then q_r <= D; end if;' inside a process(clk), keep the state in an internal signal q_r, and drive the output port from it with a concurrent 'Q <= q_r'. That is the standard, synthesisable D flip-flop template.
