Circuits with memory - the building blocks of registers
| Combinational | Sequential |
|---|---|
| No memory | Has memory (storage) |
| Output = f(inputs) | Output = f(inputs + state) |
| No clock needed | Usually clocked |
| MUX, Adder, Decoder | Flip-flop, Counter, FSM |
Both store 1 bit, but behave differently:
| Latch | Flip-Flop |
|---|---|
| Level-sensitive | Edge-sensitive |
| Transparent when enabled | Samples only on clock edge |
| Simpler, less area | More predictable timing |
| Avoid in synchronous design | Preferred for synchronous design |
Set-Reset latch. Basic memory element.
Data latch. Avoids invalid state of SR latch.
// D Latch (avoid in synchronous designs!)
module d_latch (
input d, en,
output reg q
);
always @(*) begin
if (en)
q = d; // Transparent when enabled
end
endmodule
The most important sequential element!
Samples D input only at the rising (or falling) edge of clock.
// D Flip-Flop (preferred!)
module dff (
input clk,
input d,
output reg q
);
always @(posedge clk) begin
q <= d; // Sample D at rising edge only
end
endmodule
// With async reset
module dff_reset (
input clk,
input rst_n, // Active-low reset
input d,
output reg q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0; // Async reset
else
q <= d;
end
endmodule
Like SR, but J=K=1 toggles output (no invalid state).
Toggle flip-flop. Toggles on every clock when T=1.
// T Flip-Flop
module tff (
input clk, rst_n,
input t,
output reg q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else if (t)
q <= ~q; // Toggle
end
endmodule
Multiple flip-flops grouped together. Stores multi-bit data.
// 8-bit Register
module register8 (
input clk, rst_n,
input load,
input [7:0] d,
output reg [7:0] q
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 8'b0;
else if (load)
q <= d;
end
endmodule
Data shifts through flip-flops on each clock.
// 8-bit Shift Register
module shift_reg (
input clk, rst_n,
input serial_in,
output serial_out,
output reg [7:0] parallel_out
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
parallel_out <= 8'b0;
else
parallel_out <= {parallel_out[6:0], serial_in}; // Shift left
end
assign serial_out = parallel_out[7]; // MSB out
endmodule
Counts up or down on each clock.
// 4-bit Up Counter
module counter4 (
input clk, rst_n,
input enable,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'b0;
else if (enable)
count <= count + 1;
end
endmodule
// Up/Down Counter
module updown_counter (
input clk, rst_n,
input enable, up,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'b0;
else if (enable) begin
if (up)
count <= count + 1;
else
count <= count - 1;
end
end
endmodule
Detect rising or falling edge of a signal.
// Rising Edge Detector
module edge_detect (
input clk, rst_n,
input signal,
output rise,
output fall
);
reg signal_d; // Delayed version
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
signal_d <= 1'b0;
else
signal_d <= signal;
end
assign rise = signal & ~signal_d; // Was 0, now 1
assign fall = ~signal & signal_d; // Was 1, now 0
endmodule
| Element | Behavior | Use Case |
|---|---|---|
| Latch | Level-sensitive | Avoid if possible |
| D FF | Edge-sensitive | Standard storage |
| Register | Multi-bit storage | Data holding |
| Shift Reg | Serial ↔ Parallel | Serial comm |
| Counter | Count up/down | Timing, addressing |