Flip-Flops and Registers
Master the D flip-flop as the fundamental storage element: FDRE/FDSE/FDPE/FDCE primitives, setup/hold timing, metastability, clock enable, synchronous reset, pipelining, and clock domain crossing.
The D Flip-Flop — FPGA's Memory Atom
A D flip-flop stores one bit of state. On the active clock edge (rising by default), the value at input D is captured and appears at output Q. Between clock edges, Q holds its value regardless of what D does. This is the fundamental storage element of all synchronous digital design — every counter, register, state machine, and pipeline stage is built from flip-flops.
In Xilinx 7-series FPGAs, each Slice contains 8 flip-flops (4 LUTs
× 2 FFs per LUT). The standard FF primitive is
FDRE
— Flip-Flop D with synchronous Reset and Clock Enable.
Xilinx FF Primitives
The FDRE primitive inputs/outputs:
// FDRE — Flip-Flop D, synchronous Reset, positive Edge, Clock Enable FDRE #(.INIT(1'b0)) ff_inst ( .D(d_in), // Data input .C(clk), // Clock input (positive edge) .CE(ce), // Clock Enable — FF updates ONLY when CE=1 .R(rst), // Synchronous reset — clears Q when R=1 at clock edge .Q(q_out) // Data output ); // Inferred in Verilog (synthesis maps to FDRE automatically): always @(posedge clk) begin if (rst) q <= 1'b0; // Synchronous reset else if (ce) q <= d; // Clock enable gates the update end
| Primitive | Reset/Set Type | Polarity | Reset Pin | When to Use |
|---|---|---|---|---|
| FDRE | Synchronous Reset | Positive edge | R (active high, sync) | Default choice — synchronous, timing-friendly |
| FDSE | Synchronous Set | Positive edge | S (active high, sync) | When you need to set FF to 1 synchronously |
| FDPE | Asynchronous Preset | Positive edge | PRE (active high, async) | Power-on preset — avoid in logic, use only at boundaries |
| FDCE | Asynchronous Clear | Positive edge | CLR (active high, async) | Power-on clear — avoid in logic, use only at boundaries |
always @(posedge clk && en) is
wrong and creates glitches. The correct approach is clock enable:
if (ce) q <= d; — this uses the CE
pin on the FDRE primitive, which is timed and glitch-free. Gating clocks causes
massive skew and timing closure failures.
Timing Parameters
Three fundamental timing parameters govern flip-flop behavior:
- Setup time (Tsu): Data at D must be stable for this time before the clock edge. Violation causes metastability.
- Hold time (Th): Data at D must be stable for this time after the clock edge. Even 0ps for most 7-series FFs — but routing delays must satisfy this.
- Clock-to-Q delay (Tcq): Time from clock edge to when Q output becomes valid. Typically 200–500ps in 7-series.
| Speed Grade | Tsu (Setup) | Th (Hold) | Tcq (Clock-to-Q) | Max Fabric Freq |
|---|---|---|---|---|
| Artix-7 -1 (slowest) | ~50 ps | 0 ps | ~450 ps | ~450 MHz |
| Artix-7 -2 | ~45 ps | 0 ps | ~380 ps | ~550 MHz |
| Artix-7 -3 (fastest) | ~40 ps | 0 ps | ~330 ps | ~630 MHz |
| Kintex-7 -1 | ~40 ps | 0 ps | ~280 ps | ~600 MHz |
| UltraScale+ -1 | ~25 ps | 0 ps | ~200 ps | ~891 MHz |
Timing Path and Slack
A timing path connects source FF output → combinational logic → destination FF input. The timing budget equation:
Slack = Clock Period - (Tcq + Tlogic + Trouting + Tsu) Example (100 MHz clock, 10ns period): Clock period = 10.000 ns Tcq = 0.450 ns (source FF clock-to-Q) Tlogic = 1.200 ns (LUT + carry delays) Trouting = 0.800 ns (routing delay between LUTs) Tsu = 0.050 ns (destination FF setup time) ───────────────────────────── Slack = 10.000 - (0.450 + 1.200 + 0.800 + 0.050) = +7.500 ns (PASSING)
Metastability
If the D input changes during the setup or hold window (the forbidden zone around the clock edge), the flip-flop enters a metastable state. In metastability, the FF's internal feedback loop is unresolved — the output oscillates between 0 and 1 for an unpredictable time before settling to a random value. This causes:
- Random bit errors in the captured data
- Potential for the metastable output to propagate and corrupt downstream logic
- MTBF (Mean Time Between Failure) that depends on clock frequency and data frequency
Metastability cannot be eliminated — it can only be made statistically improbable by giving the FF time to resolve before the output is used.
Synchronous vs Asynchronous Reset
| Property | Synchronous Reset (FDRE) | Asynchronous Reset (FDCE) |
|---|---|---|
| When reset takes effect | Only on clock edge | Immediately, independent of clock |
| Timing analysis | Fully timed by STA tool | Reset path unconstrained — risky |
| Recommended for FPGA? | Yes — strongly preferred | Avoid in fabric logic |
| Resource usage | Uses R pin of FDRE | Uses CLR pin of FDCE |
| Reset assertion | Clean — only transitions on clock | Can cause glitches if reset has noise |
| Reset removal | Automatic — timed by STA | MUST de-assert synchronously (2-FF synchronizer) |
A: Metastability occurs when a flip-flop's setup or hold time is violated, leaving it in an indeterminate output state for an unpredictable duration. Prevent it at clock domain crossings with a 2-FF synchronizer: pass the signal through two back-to-back FFs in the destination clock domain. The first FF may go metastable; the second FF receives a resolved signal. The MTBF becomes astronomically large with proper synchronizer design.
Interactive Timing Diagram
Pipelining for Timing Closure
Pipelining inserts registers between combinational stages to shorten the critical path and increase maximum clock frequency:
// Without pipeline — one long path, lower Fmax assign result = (a * b) + (c * d) + (e * f); // 3 multipliers in series // With 2-stage pipeline — shorter paths, higher Fmax, 2-cycle latency always @(posedge clk) begin pipe1 <= (a * b) + (c * d); // Stage 1 register e_r <= e; f_r <= f; // Register through-paths end always @(posedge clk) begin result <= pipe1 + (e_r * f_r); // Stage 2 register end
Double-Data-Rate (DDR) Flip-Flops
Dedicated IO flip-flops in FPGA IOBs can capture data on both the rising and falling clock edges. This doubles the effective data rate for the same clock frequency. DDR FFs are used for:
- DDR3/DDR4 memory interfaces (data and strobe signals)
- High-speed serial deserializers (LVDS, differential pairs)
- Double-speed clock outputs
These are instantiated via IDDR and ODDR primitives, not synthesized from RTL. They live in the IOB (IO Block), not in the fabric slice.
always @(a) if (en) q = a; creates a
LATCH, not a flip-flop. Latches are transparent when enable is high — they have no
clock, making them nightmares for FPGA timing analysis. Always use
always @(posedge clk) for synchronous
designs. If Vivado warns "inferred latch," find the combinational always block
missing an else branch.
Knowledge Check
- Fast Data Register Element
- Flip-Flop D with synchronous Reset and clock Enable, positive edge
- Flip-Flop Dual Reset Enable
- Frequency-Division Register Element
- The flip-flop resets to 0
- The clock edge is skipped
- Metastability — the output is undefined for an unpredictable time
- The flip-flop captures the previous value correctly
- Resets its output to 0
- Holds its previous Q value — ignores new data at D
- Stops the clock internally
- Enters a high-impedance state
- Asynchronous reset (FDCE/FDPE) — fastest response
- Synchronous reset (FDRE) — timed by STA, glitch-free
- No reset — initialize via INIT attribute only
- Both async and sync on the same FF simultaneously
- The time required for the clock to reach the FF from the global buffer
- The propagation delay from clock edge to when the Q output becomes valid
- The setup time requirement at the clock input
- The time between two consecutive clock edges
- Doubling the data rate of a flip-flop
- Implementing a 2-bit shift register
- Safely crossing a single-bit signal between two asynchronous clock domains
- Creating a 2-cycle pipeline stage
Practical Exercise
Timing Analysis
(a) Your design has a combinational path with 1ns of logic delay and 0.5ns of routing delay. The clock period is 2ns. Given Tcq = 0.3ns and Tsu = 0.1ns, calculate the timing slack. Does the path pass or fail?
(b) If the path fails by 0.2ns, name three ways to fix it (think: architecture, constraints, placement).
(c) Write a Verilog module with synchronous active-high reset and clock enable. After synthesis in Vivado, open the schematic (F4) and verify the FF primitive shown is FDRE. Check the primitive properties panel.
(d) Write a 2-FF synchronizer in Verilog. Add the attribute
(*ASYNC_REG="TRUE"*)
to both FFs. After synthesis, confirm Vivado places them in the same Slice (check
the Implemented Design → Device view).