Flip-Flops, Clocks & Resets
always @(posedge clk), non-blocking assignment, and the real difference between synchronous and asynchronous reset.
A flip-flop stores one bit and updates it only at a clock edge. Everything that remembers anything in a synchronous design — registers, counters, state machines — is built from flip-flops sharing a clock. In Verilog, a flip-flop is any reg assigned inside always @(posedge clk).
Timing in one paragraph
always @(posedge clk or posedge rst) if (rst) q <= 0; else if (en) q <= d; else q <= q; // unnecessary always @(posedge clk or posedge rst) if (rst) q <= 1'b0; else if (en) q <= d;
In a clocked block, an unassigned reg simply keeps its value: that is what a flip-flop does. No latch is created, and q <= q adds nothing.
always @(posedge clk or rst) // level, not edge always @(posedge clk or posedge rst)
For an asynchronous reset, the sensitivity list needs an edge on the reset too. Mixing an edge and a level in the same list is not synthesizable.
What are setup and hold time?
Setup time: how long before the clock edge the D input must be stable. Hold time: how long after the edge it must stay stable. Violating either can make the flip-flop capture the wrong value or go metastable.
What determines the maximum clock frequency of a design?
The critical path: the slowest path of combinational logic between two flip-flops (plus the flip-flop's clock-to-Q delay and setup time). The clock period cannot be shorter than that.
Why must an asynchronous reset be released synchronously?
If reset de-asserts close to a clock edge, different flip-flops may see it in different cycles (or go metastable), so the design leaves reset in an inconsistent state. A reset synchronizer releases it cleanly on a clock edge.