Module 5: Behavioral Verilog for Synthesis ยท 5.5 Modeling Flip-Flops and Registers

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.

Logic between registers
Figure 1: Combinational logic between one edge and the next

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.

Flip-flop timing
Figure 2: Setup, hold and clock-to-Q on the inferred flip-flop

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.

โ† generate for and Procedural for Reset โ†’