always @(posedge clk or negedge rstn) begin
if (!rstn) begin
// if negedge rstn occurs now , this case is reached. negedge rstn
// means rstn has just now transitioned to 0 and this case is reached when
// rstn == 0.
// if posedge clk occurs now while rstn is low, this case is reached
// as well and the clk transition is ignored -- the FF is held in
// reset.
q <= 1'b0; // q gets 0 when rstn goes low.
end else begin
// it is impossible to reach this point if negedge rstn happened now.
// likewise, it is impossible to reach this point if posedge clk
// happened now while rstn == 0.
// the only way to get here is for posedge clk to happen now while
// rstn == 1. so this is what happens on clock edges when the
// circuit is not reset.
q <= d; // q gets d on rising edge clk.
end
end
// if you want a falling edge clk sensitivity, use 'negedge clk'.
// if you want active high reset, use 'posedge rst' and 'if (rst) begin'.
//
// This is the one case where the synthesis tools make use of the
// sensitivity list to infer behavior in synthesis. normally the sensitivity
// list is ignored in synthesis. So don't try to get too creative with
// them. use the above pattern and always@(*).
// or use always_ff/always_comb if you have SystemVerilog.