I am currently working through Pong Chu's FPGA Prototyping By System Verilog Examples, specifically on Chapter 4 which covers sequential circuits. In it, Chu describes the method where a sequential circuit has the sequential part and the combinational part. So far so good. As an example, he shows how a DFF with synchronous clear is coded up:
module d_ff_sync_clr_2seg
(
input logic clk,
input logic syn_clr,
input logic d,
output logic q
);
// signal declaration
logic r_reg, r_next;
// body
// D FF
always_ff @(posedge clk)
r_reg <= r_next;
// next-state logic
always_comb
if (syn_clr)
r_next = 1'b0;
else
r_next = d;
// output logic
assign q = r_reg;
endmodule
In the discussion, he states the syn_clr
signal is only checked at the rising edge of the clock. He also provides a different formatting style for the same circuit which I found clearer:
module d_ff_sync_clr_1seg
(
input logic clk,
input logic syn_clr,
input logic d,
output logic q
);
// body
always_ff @(posedge clk)
if (syn_clr)
q <= 1'b0;
else
q <= d;
endmodule
In the second example (d_ff_sync_clr_1seg), I can clearly see that yes, at the rising edge of the clock the always_ff block is activated and syn_clr is indeed sampled.
In the first (d_ff_sync_clr_2seg), longer example, the statement Chu makes that syn_clr is only checked at the rising edge of the clock isn't as clear. My thinking is that when syn_clr changes, the always_comb block is activated, and r_next is updated to be either 1'b0 or d. Then, at the rising edge of the clock, r_reg gets assigned the value of r_next, as it was set in the always_comb block. So indirectly it seems, syn_clr (or the results of checking syn_clr) is sampled at the rising edge of the clock. I don't see the connection between what is going on in the always_ff block which is just sensitive to the rising edge of the clock and the always_comb which will activate whenever syn_clr changes. How is syn_clr just sampled in at the rising edge of the clock, and hence is synchronous, if its in the always_comb block.
I understand that in an always_ff block the assignments are non-blocking and happen at the end of the block, but in this example there's only one assignment so OK.
At this point in the book Chu has mentioned FSMs and FSMDs but hasn't formally introduced those concepts in this chapter.
Perhaps I'm missing something else or my understanding of always blocks isn't as firm as I thought. Any clarification would be appreciated.
the statement Chu makes that
syn_clr
is only checked at the rising edge of the clock isn't as clear.
You are correct. That statement is imprecise. r_next
is sampled at the posedge of clk
, not syn_clr
.
The 2nd code example is the proper way to model a simple DFF with synchronous clear.
It is not clear why the author chose to show the 1st example at all.
My thinking is that when
syn_clr
changes, thealways_comb
block is activated
This is true, but the block is also activated when d
changes. More generally, the block is triggered on any change of any signal on the RHS of an assignment (that does not also appear on the LHS) within the block.