The foundation you need before diving into DFT
This is the most fundamental concept in digital design.
No memory. Output depends only on current inputs.
Examples: Adders, MUX, Decoders, ALU
// 2:1 MUX - Pure combinational
module mux2to1 (
input a, b, sel,
output y
);
assign y = sel ? b : a;
endmodule
Has memory (flip-flops). Output depends on inputs AND previous state.
Examples: Counters, FSMs, Registers, Shift Registers
// Counter - Sequential (has memory)
module counter4 (
input clk, rst_n, en,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'b0;
else if (en)
count <= count + 1;
end
endmodule
This is critical for DFT - most scan failures relate to timing!
Data must be stable BEFORE the clock edge.
Setup Violation: Data arrives too late → FF captures wrong value.
Data must stay stable AFTER the clock edge.
Hold Violation: Data changes too fast → FF captures garbage.
Setup Check:
Tclk_to_q + Tcomb + Tsetup < Clock_Period
Hold Check:
Tclk_to_q + Tcomb > Thold
When setup/hold is violated, the flip-flop enters an undefined state.
Two or three flip-flops in series. Each stage reduces metastability probability exponentially.
When signals move between different clock domains:
| Method | Use Case |
|---|---|
| 2-FF Synchronizer | Single-bit signals |
| Gray-coded FIFO | Multi-bit data |
| Handshake Protocol | Control signals |
| MUX Recirculation | Synchronized data |
Sequential circuits that move through defined states.
module fsm (
input clk, rst_n,
input start, done,
output reg busy, complete
);
// State encoding
localparam IDLE = 2'b00;
localparam RUNNING = 2'b01;
localparam FINISH = 2'b10;
reg [1:0] state, next_state;
// State register (sequential)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end
// Next state logic (combinational)
always @(*) begin
next_state = state; // Default: stay
case (state)
IDLE: if (start) next_state = RUNNING;
RUNNING: if (done) next_state = FINISH;
FINISH: next_state = IDLE;
endcase
end
// Output logic
assign busy = (state == RUNNING);
assign complete = (state == FINISH);
endmodule