A D flip-flop captures D on a clock edge and holds Q until the next capture. Nearly all synthesizable “memory” in FPGA/ASIC RTL is built from FFs (or inferred RAM).
Basic forms
Plain register:
always_ff @(posedge clk) q <= d;
Async reset (active-low):
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) q <= 1'b0;
else q <= d;
end
Clock enable:
always_ff @(posedge clk) begin
if (en) q <= d;
end
Enable is preferred over gating the clock in the fabric — gated clocks need special cells / care.
Reset flavors
| Style | Sensitivity | Use when |
|---|---|---|
| Async assert | or negedge rst_n |
Fast, global reset trees |
| Sync only | posedge clk only |
Simpler timing; reset is a data input |
| Async assert / sync deassert | Hybrid at chip level | Avoid recovery issues on reset release |
See Reset strategy for project-level choices.
Inferring vs instantiating
Write behavioral always_ff and let synthesis infer FFs. Instantiate primitives only when you need a specific cell (ECC FF, technology macro).
Common bugs
- Using
=(blocking) inalways_fffor state → simulation/synth mismatch risk. - Forgetting reset branch for some bits → X or random power-on in sim.
- Sampling async inputs without synchronizers → CDC failures.