Sequential Logic and the Clock
Flip-flops, posedge clk, and resets
Combinational logic has no memory. Real chips need memory - something that remembers a value from one moment to the next. That something is the flip-flop, and it is driven by the clock.
What the clock is
The clock is a signal that ticks up and down, over and over, like a heartbeat: 0,1,0,1,0,1. A flip-flop only changes its stored value at the exact instant the clock goes from 0 to 1. That instant is called the rising edge, or posedge.
Between ticks, the flip-flop holds its value no matter what its input does. It only "takes a photo" of its input at each rising edge. This is what gives hardware memory and order.
A single flip-flop
// D flip-flop: on each clock rising edge, q copies d
module dff (
input wire clk,
input wire d,
output reg q
);
always @(posedge clk) begin
q <= d; // note the <= arrow (non-blocking)
end
endmodule- always @(posedge clk) - "every time the clock rises, run this."
- q <= d - capture d into q at that edge. Between edges, q keeps its value.
- q must be reg, because it holds state.
Adding a reset
When a chip powers on, flip-flops hold garbage (x). A reset forces them to a known starting value. This is a synchronous reset - it happens on the clock edge.
module counter (
input wire clk,
input wire rst, // active high reset
output reg [3:0] count
);
always @(posedge clk) begin
if (rst)
count <= 4'd0; // go to a known value
else
count <= count + 1'b1; // otherwise count up
end
endmoduleInside a clocked always @(posedge clk) block, always use the non-blocking arrow <=. This makes every flip-flop sample its input at the same instant, which is exactly how real hardware behaves. Use blocking = only in combinational always @(*) blocks. Memorize this pair and you avoid a whole class of bugs.
count + 1 will wrap from 15 back to 0 in a 4-bit counter, because 4 bits cannot hold 16. That is normal hardware behavior, not a bug - but be aware of it when you size your signals.