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.