Inferring Flip-Flops
Sections 5.2 to 5.4 were about combinational logic in always blocks. This section is about the other kind. How much Verilog does it take to describe a physical D flip-flop? Three lines:
always @(posedge clk) begin
q <= d;
end
No gates, no library, no cell name, and a synthesiser places a flip-flop for it every time. This article is about why.
The edge is the whole trick
A combinational block runs whenever any input changes and must drive every output on every path. A clocked block differs in one thing: its sensitivity list is an edge, posedge clk, not a level. That is what tells the synthesiser it is describing a register. The block runs only at the instant the clock rises, whatever d holds then is captured into q, and between edges nothing happens: q sits there, as a flip-flop does between clock pulses. The <= makes the simulator apply the update after everything else in that time step has settled, which is what a real flip-flop’s clock-to-Q delay does, and section 5.1 was about that.
The other edge
always @(negedge clk) begin
q <= d;
end
Same rule, falling edge. Double-data-rate interfaces sample on both edges; almost everything else uses posedge, and mixing edges without a reason confuses every reader.
Several flip-flops in one block
always @(posedge clk) begin
a_reg <= a_in;
b_reg <= b_in ^ a_in;
count <= count + 1;
end
Read this as three flip-flops on one clock, not one flip-flop doing three things. a_reg captures a_in; b_reg captures an XOR computed before the edge; count captures its own value plus one, an adder feeding back into its register. Three flip-flops, an XOR gate and an incrementer.
Between the edges
The value a flip-flop captures is whatever the combinational logic on its D input settled to during the previous period (Figure 1). Every register sits at the edge of a cloud of gates that computes its next value from the previous cycle’s outputs. That is the whole picture of synchronous design, and it is the structure of the pipelines later in this section.
Timing still applies
Setup, hold and clock-to-Q from section 3.1 have not gone anywhere (Figure 2). The device is the same whether you drew it or wrote it. Writing q <= d is a promise that the logic feeding d settles before the setup window on every edge for the life of the chip, and static timing analysis, in Module 8, checks whether you kept it.
Checking in Yosys
Do not take the pattern on trust; look:
$ yosys -p "read_verilog dff.v; synth; stat"
...
Number of cells: 1
$_DFF_P_ 1
$_DFF_P_ is Yosys’s name for a positive-edge D flip-flop, with D, C and Q mapped to d, clk and q. Replace stat with show and you get it drawn.
q <= d in a clocked block is not an instruction that runs once. It declares a device that will sample, hold and drive on every edge for as long as the chip has power.
Practice Exercise
Draw the circuit this block describes, then check it with Yosys.
always @(posedge clk) begin
sum_reg <= a + b;
max_reg <= (a > b) ? a : b;
tick <= ~tick;
end
Solution
Three registers, each with a little logic in front of it. sum_reg has an adder on a and b. max_reg has a comparator driving a mux between a and b. tick has an inverter from its own output back to its input, which is a toggle flip-flop: it flips every edge with no input at all. Yosys reports three flip-flops plus the adder, comparator, mux and inverter.
Every one of those flip-flops powers up holding something nobody chose. The next article is about reset, and the argument over how to wire it.