Skip to content
VLSI Mentor

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 latchrising_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 highinfersinfers12
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 samples d(=3) at that instantd changes between edges → IGNORED until the next edged changes between edges →IGNORED until the next edgenext rising edge → q samples the d present then (=5)next rising edge → qsamples the d present then(=5)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.

Standards & specifications

Governing standard
IEEE Std 1076 (VHDL)(opens IEEE in a new tab)

Defines the VHDL language — types, the simulation cycle, and the semantics a conforming analyser and simulator must implement. Synthesis restrictions and vendor coding rules are tool behaviour, not language rules.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of VHDL Sequential Logic — Registers, Counters & State Machines.