Skip to content

VHDL · Chapter 7.2 · Sequential Logic Design

Detecting the Clock Edge

A register exists because something happens on a clock edge, a transition rather than a level. In VHDL you express that with the rising-edge and falling-edge functions, which are true only at the instant the clock changes from 0 to 1 or from 1 to 0. That edge is precisely what makes synthesis infer a flip-flop instead of combinational logic or a latch. This lesson covers the edge-detection functions, why the rising-edge function is the modern form preferred over the older clock-event-and-equals-one style because it is metavalue-safe and states intent clearly, how to choose rising versus falling, and why a clocked process keys on exactly one edge of one clock. Getting this right is the foundation of every synchronous circuit you will design.

Foundation13 min readVHDLClock Edgerising_edgeFlip-FlopSynchronousRTL

1. Engineering intuition — capture on a transition, not a level

A flip-flop samples its input at the moment the clock transitions, then holds that value until the next transition. The key word is moment: it is the edge that matters, not whether the clock is high or low. A level-sensitive element (transparent while high) is a latch; an edge-sensitive element (captures at the transition) is a flip-flop. So detecting the clock edge — the 0-to-1 transition — is exactly what tells VHDL "build a flip-flop here," and it is the single ingredient that turns a process from combinational into sequential.

2. Formal explanation — rising_edge and why it is preferred

edge_detection.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- MODERN, preferred: a function from std_logic_1164, true only on the 0→1 transition.
if rising_edge(clk) then   ...   end if;
if falling_edge(clk) then  ...   end if;   -- the 1→0 transition
 
-- OLDER form (still seen): clk changed AND its new value is '1'.
if clk'event and clk = '1' then  ...  end if;   -- equivalent intent, but less safe

rising_edge(clk) is a function (from std_logic_1164) that returns true only for a genuine 0-to-1 transition of a std_logic clock. It is preferred over clk'event and clk = '1' because it is metavalue-safe (it correctly ignores transitions involving 'U'/'X'/'Z', which the naive form can misread) and it states intent plainly. Use rising_edge/falling_edge; reserve the clk'event form for legacy code you are reading, not writing.

3. Production RTL — the edge makes the register

edge_makes_register.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all;
-- The rising_edge guard is what infers a flip-flop for q.
ff : process (clk)
begin
  if rising_edge(clk) then     -- edge → register
    q <= d;
  end if;
end process;
 
-- Without the edge guard, the same assignment is combinational / a latch — NOT a register.
-- y <= d;   -- combinational wire, no storage

What hardware does this become? With the rising_edge(clk) guard, q is a flip-flop that captures d on each rising edge. Remove the guard and there is no flip-flop — just a wire (or a latch if the assignment is conditional and incomplete). The edge detection is the difference between a register and no register.

4. Hardware interpretation — edge vs level

rising edge infers a flip-flop while a level test infers a latchinfersinfersrising_edge(clk)true only at 0→1 transitionedge-triggeredflip-flopcaptures at the edge, holdslevel test (clk='1')true for the whole highphasetransparent latchfollows input while high12
Edge versus level sensitivity. rising_edge(clk) is true only at the instant the clock transitions 0 to 1 — an edge — which infers an edge-triggered flip-flop that samples its input at that instant and holds otherwise. A level test (clk = '1') would be transparent for the whole high phase — a latch. Modern synchronous design uses one clock edge (usually rising) to clock all flip-flops, so they capture together; this is what makes timing analysis tractable.

5. Simulation interpretation — capture only at the edge

rising_edge(clk): d is sampled only at the rising edges

8 cycles
rising_edge(clk): d is sampled only at the rising edgesrising edge → q samples d (=3) at that instantrising edge → q sample…d changes between edges → IGNORED until the next edged changes between edge…next rising edge → q samples the d present then (=5)next rising edge → q s…clkd33955288q03355558t0t1t2t3t4t5t6t7
q captures d only at the rising edges; changes of d between edges have no effect — the flip-flop samples at the transition and holds. Notice q at edge 3 takes the value d held at that edge, not the value d briefly had in between. Edge-only capture is the defining behaviour rising_edge gives you.

6. Debugging example — clk'event misread, or a level used

Expected: an edge-triggered register. Observed: a metavalue glitch at time zero produces a spurious clock (with the clk'event form), or a latch appears (with a level test). Root cause: clk'event and clk = '1' can react to transitions out of 'U'/'X' that are not real rising edges; a plain clk = '1' level test is not an edge at all and infers a latch. Fix: use rising_edge(clk), which is true only for a clean 0-to-1 transition. Engineering takeaway: for clocked logic always use rising_edge/falling_edge — they are edge-correct and metavalue-safe, unlike level tests or the naive event form.

use_rising_edge.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- RISKY: reacts to spurious transitions from 'U'/'X' at startup; or (level) infers a latch.
-- if clk'event and clk = '1' then ... ;     -- prefer rising_edge
-- if clk = '1' then q <= d; end if;          -- LEVEL → latch, not a flip-flop
-- CORRECT: clean, metavalue-safe edge detection.
if rising_edge(clk) then q <= d; end if;

7. Common mistakes & what to watch for

  • Using a level test for a register. clk = '1' is level-sensitive → a latch. Use rising_edge(clk) for an edge-triggered flip-flop.
  • Preferring clk'event and clk = '1'. It is older and not metavalue-safe; rising_edge is the modern, robust choice.
  • Detecting both edges in one process. A clocked process keys on one edge of one clock; dual-edge logic is special and rarely portable.
  • Mixing clock domains. One clock per clocked process; crossing domains needs synchronisers (later).
  • Putting combinational logic under the edge guard unnecessarily. Anything inside rising_edge becomes registered; keep purely combinational logic outside.

8. Engineering insight & continuity

Edge detection is the hinge of sequential design: rising_edge(clk) is what converts a process into a flip-flop, because flip-flops are defined by capturing at a transition, not a level. Make rising_edge/falling_edge your reflex — they are correct, safe, and self-documenting — and reserve a single edge of a single clock per clocked process so all your registers update together in one timing domain. With the edge understood, the next lesson builds the element it creates: The D Flip-Flop — the atom of all stateful hardware — followed by Registers (D flip-flops in parallel) and the enables, counters, and shift registers that compose them.