Core Concepts in Digital IC Design and Verification
ASIC vs. FPGA Architecture and Flow
Application Specific Integrated Circuits (ASIC) are custom-designed for a specific application. The design involves creating masks for manufacturing, resulting in high non-recurring engineering (NRE) costs but low unit costs for high volumes. ASICs offer superior performance, power efficiency, and area optimization compared to programmable logic. Once fabricated, the logic is fixed.
Field Programmable Gate Arrays (FPGA) consist of configurable logic blocks (CLBs), programmable interconnects, and dedicated hardware resources like DSP blocks and RAM. They offer reprogrammability, enabling rapid prototyping and lower time-to-market. However, they have higher unit costs and higher power consumption due to the overhead of programmable routing.
Development Flow:
- FPGA: Design Entry (HDL) -> Simulation -> Synthesis (Map to LUTs/FFs) -> Place & Route -> Bitstream Generation.
- ASIC: Specification -> RTL Design -> Functional Verification -> Synthesis (to Standard Cells) -> Floorplanning -> Place & Route -> Clock Tree Synthesis (CTS) -> Timing Closure -> Physical Verification (DRC/LVS) -> GDSII Tape-out.
Timing Analysis and Constraints
Static Timing Analysis (STA) verifies the timing of a digital design without requiring simulation vectors. It analyzes all possible paths to ensure setup and hold times are met across all process, voltage, and temperature (PVT) corners.
Setup Time ($T_{setup}$): The minimum time data must be stable before the clock edge.
Hold Time ($T_{hold}$): The minimum time data must remain stable after the clock edge.
Setup Violation Fix: Reduce logic delay between flip-flops or increase the clock period.
Hold Violation Fix: Insert delay buffers into the data path to slow down fast signals.
Clock Skew and Jitter
Clock Skew: The difference in arrival time of the clock signal at different registers. Positive skew can help setup times but hurts hold times; negative skew does the opposite.
Clock Jitter: The deviation of the clock edge from its ideal position in time. It reduces the effective clock period available for logic propagation.
Metastability
When a signal changes asynchronously near the clock edge, the flip-flop output may enter a metastable state (a voltage between logic levels), potentially propagating errors through the system. To mitigate this, a synchronizer chain (typically two flip-flops in series) is used.
// Two-flop synchronizer for asynchronous signal
module sync_2ff (
input wire clk,
input wire rst_n,
input wire async_in,
output wire sync_out
);
reg [1:0] sync_reg;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
sync_reg <= 2'b00;
end else begin
sync_reg <= {sync_reg[0], async_in}; // Shift register
end
end
assign sync_out = sync_reg[1];
endmodule
Hardware Description Languages (HDL)
Verilog Operator Precedence
Understanding operator precedence is crucial for correct logic synthesis:
- Unary Logical/Bitwise (!, ~)
- Multiplication, Division, Modulus (*, /, %)
- Addition, Subtraction (+, -)
- Shift (<<, >>)
- Relational (<, <=, >, >=)
- Equality (==, !=, ===, !==)
- Bitwise AND (&)
- Bitwise XOR (^, ^~)
- Bitwise OR (|)
- Logical AND (&&)
- Logical OR (||)
- Conditional (? :)
Latch vs. Flip-Flop
D-Latch: Level-sensitive. The output follows input ($Q=D$) when the enable is high. Inferred if code uses incomplete assignments in an `always` block triggered by a level.
D Flip-Flop: Edge-sensitive. Output samples input only on a clock edge (rising or falling).
// D Flip-Flop with Asynchronous Reset
module dff (
input wire clk,
input wire rst_n,
input wire d,
output reg q
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
endmodule
Reset Strategies
Synchronous Reset: Reset logic is sampled only at the clock edge. It is immune to glitches but requires the clock to be running.
Asynchronous Reset: Reset takes effect immediately upon assertion, regardless of the clock. However, de-asserting asynchronously can cause metastability if it occurs near a clock edge. The best practice is Asynchronous Assertion, Synchronous De-assertion (Reset Bridge).
module reset_bridge (
input wire clk,
input wire ext_rst_n, // External asynchronous reset
output wire sys_rst_n // Synchronized reset for system
);
reg r1, r2;
always_ff @(posedge clk or negedge ext_rst_n) begin
if (!ext_rst_n) begin
r1 <= 1'b0;
r2 <= 1'b0;
end else begin
r1 <= 1'b1;
r2 <= r1; // Synchronize release
end
end
assign sys_rst_n = r2;
endmodule
Finite State Machines (FSM)
FSMs are categorized into Moore (output depends only on state) and Mealy (output depends on state and inputs). A robust coding style is the Three-Block (or three-process) style:
- State Register: Sequential logic for state transitions.
- Next State Logic: Combinational logic determining the next state based on current state and inputs.
- Output Logic: Combinational (Mealy) or Registered (Moore) logic for outputs.
typedef enum logic [1:0] { IDLE, RUN, DONE } state_t;
module fsm (
input wire clk,
input wire rst_n,
input wire start,
input wire done_flag,
output reg active
);
state_t curr_state, next_state;
// 1. State Register
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) curr_state <= IDLE;
else curr_state <= next_state;
end
// 2. Next State Logic
always_comb begin
next_state = curr_state; // Default assignment to prevent latches
case (curr_state)
IDLE: if (start) next_state = RUN;
RUN: if (done_flag) next_state = DONE;
DONE: next_state = IDLE;
endcase
end
// 3. Output Logic (Registered/Moore)
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) active <= 1'b0;
else begin
case (curr_state)
RUN: active <= 1'b1;
default: active <= 1'b0;
endcase
end
end
endmodule
Memory and Data Structures
First-In-First-Out (FIFO) Buffers
FIFOs are used for data buffering, especially across Clock Domain Crossing (CDC). Asynchronous FIFOs use Gray code counters for read and write pointers to prevent metastability when synchronizing pointers across clock domains. Gray code ensures only one bit changes between consecutive values.
// Binary to Gray Code Conversion
function automatic logic [ADDR_WIDTH-1:0] bin2gray(
input logic [ADDR_WIDTH-1:0] binary
);
return binary ^ (binary >> 1);
endfunction
// Gray to Binary Code Conversion
function automatic logic [ADDR_WIDTH-1:0] gray2bin(
input logic [ADDR_WIDTH-1:0] gray
);
logic [ADDR_WIDTH-1:0] binary;
binary[ADDR_WIDTH-1] = gray[ADDR_WIDTH-1];
for (int i = ADDR_WIDTH-2; i >= 0; i--) begin
binary[i] = binary[i+1] ^ gray[i];
end
return binary;
endfunction
Synchronous vs. Asynchronous Reset
Modern design flows often prefer synchronous resets for timing analysis simplicity, or specific asynchronous reset bridges for reliability. General-purpose inputs should be synchronized before use in the logic clock domain.
Design for Testability (DFT)
To verify manufacturing defects, DFT techniques are inserted into the design.
- Scan Chains: Flip-flops are replaced with scan flops (multiplexed inputs). In test mode, they connect to form a long shift register, allowing external testers to shift in test patterns and shift out results.
- Boundary Scan (JTAG): Tests interconnects between chips without physical probes.
- ATPG: Automatic Test Pattern Generation tools create vectors to detect stuck-at faults.
Verification and UVM
Universal Verification Methodology (UVM) provides a standard methodology for SystemVerilog-based verification.
- Scoreboarding: Predicts expected output to compare with DUT output.
- Functional Coverage: Measures which features or scenarios have been exercised.
- Code Coverage: Measures lines, branches, and conditions executed in the RTL.
- Inheritance and Polymorphism: Used to create reusable testbench components (drivers, monitors, scoreboards).
EDA Tools and Protocols
Common Tools:
- Synthesis: Design Compiler (Synopsys), Genus (Cadence).
- Simulation: VCS (Synopsys), Xcelium (Cadence), ModelSim/Questa (Mentor).
- STA: PrimeTime (Synopsys), Tempus (Cadence).
- P&R: Innovus (Cadence), ICC2 (Synopsys).
Standard Protocols: AMBA (AHB, AXI, APB), PCIe, USB, I2C, SPI, DDR, Ethernet.