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

Enables and Loads

Most registers spend most cycles holding still. A UART’s shift register only shifts when a bit has arrived; an accumulator only adds when told to. Verilog has a pattern for that, and it is one you have already seen.

The pattern

always @(posedge clk) begin
    if (en)
        q <= d;
    // en low: q holds
end

No else, and in a clocked block that is correct: holding is what a flip-flop does. It is not a latch. Most library and FPGA flip-flops have a clock-enable pin, and the synthesiser wires en to it rather than building a mux in front of D, which is smaller and uses less power.

Reset first

With both a reset and an enable, reset wins:

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        q <= 1'b0;
    else if (en)
        q <= d;
end

Reset, then enable. A register that could load data on the cycle it is being cleared is a bug waiting for its moment.

Load

A parallel-load register is the enable pattern with a name that says what the enable means:

always @(posedge clk) begin
    if (load)
        data_reg <= data_in;
end

Clear is not reset

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        q <= 1'b0;      // reset: power-up or an external event
    else if (clear)
        q <= 1'b0;      // clear: the design's own command during operation
    else if (en)
        q <= d;
end

Same destination, different roles. Reset establishes a known state once. Clear is a state machine zeroing a counter mid-run. Keep the order: reset, clear, enable.

Do not gate the clock

assign gated_clk = clk & en;    // do not

It looks like it should work. It is an AND gate in a clock path, and section 2.4 explained what that does: if en changes while the clock is high, the gate makes a runt pulse that every downstream flip-flop takes as an edge, and static timing analysis, which assumes clocks are clean, cannot see it. Write the enable in the D-input logic as above. When power matters, the synthesis tool recognises the pattern and inserts an integrated clock-gating cell, the latch-and-AND cell built for the job, and that is the only gated clock that should exist in a design.

Practice Exercise

A 4-bit accumulator that adds data_in to its total when acc_en is high, clears when clear is high, and otherwise holds. Write it with a self-checking testbench.

Solution
`timescale 1ns / 1ps
`default_nettype none

module accumulator (
    input  wire       clk, rst_n,
    input  wire       clear, acc_en,
    input  wire [3:0] data_in,
    output reg  [3:0] acc
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)      acc <= 4'b0000;
        else if (clear)  acc <= 4'b0000;
        else if (acc_en) acc <= acc + data_in;
    end
endmodule

module tb_accumulator;
    reg        clk = 0, rst_n, clear, acc_en;
    reg  [3:0] data_in;
    wire [3:0] acc;

    accumulator dut (.clk(clk), .rst_n(rst_n), .clear(clear), .acc_en(acc_en), .data_in(data_in), .acc(acc));

    always #5 clk = ~clk;

    initial begin
        $dumpfile("tb.vcd");
        $dumpvars(0, tb_accumulator);

        rst_n = 0; clear = 0; acc_en = 0; data_in = 0;
        @(negedge clk); rst_n = 1;

        @(negedge clk);
        if (acc !== 4'd0) $display("FAIL: expected hold at 0, got %0d", acc);

        acc_en = 1; data_in = 4'd3; @(negedge clk);
        data_in = 4'd2; @(negedge clk);
        if (acc !== 4'd5) $display("FAIL: expected 5, got %0d", acc);
        else              $display("PASS: acc=%0d after 3+2", acc);

        clear = 1; @(negedge clk);          // clear with acc_en still high
        if (acc !== 4'd0) $display("FAIL: expected 0 after clear, got %0d", acc);
        else              $display("PASS: cleared");

        $finish;
    end
endmodule

The test that matters is the last one: with clear and acc_en both high, clear wins, as the order of the else ifs says.

The next article is a catalogue: six register shapes, counters, shift registers and an accumulator, that make up most of the sequential logic in any design.

โ† Reset Register Patterns โ†’