· UVM 1.2 Functional Verification of a Dual-Clock Asynchronous FIFO in SystemVerilog
This project implements a complete Universal Verification Methodology (UVM 1.2) testbench for a dual-clock asynchronous FIFO design. The FIFO uses separate, independent write and read clock domains and employs Gray-code pointer synchronization via two-flop synchronizers to safely cross clock domain boundaries — a classical technique described in Clifford Cummings' seminal paper on FIFO design.
The verification environment features a layered UVM architecture with independent write and read agents, a self-checking scoreboard, functional coverage collection, and a cross-domain transaction analyzer.
Dual_Clock_Asynchronous_FIFO_UVM/
├── Design/
│ └── dual_clock_async_fifo_design.v # RTL design (Verilog)
├── Output/
│ ├── Output.txt # Simulation log / transcript
│ └── Waveform.png # GTKWave / simulator waveform screenshot
├── References/
│ ├── Simulation_and_Synthesis_Tech... # Reference textbook/paper excerpt
│ ├── Template_FFVDD_Team_1.pptx # Project presentation slides
│ └── cummings1_final.pdf # Clifford Cummings FIFO paper (SNUG 2002)
├── Testbench/
│ └── dual_clock_async_fifo_testbench... # Full UVM testbench (SystemVerilog)
├── LICENSE # MIT License
└── README.md # This file
The RTL (dual_clock_async_fifo_design.v) is structured as five cooperating modules:
fifo1 (top)
├── fifomem — Dual-port synchronous-write / asynchronous-read memory array
├── wptr_full — Write pointer (binary + Gray), full flag generation
├── rptr_empty — Read pointer (binary + Gray), empty flag generation
├── sync_r2w — 2-FF synchronizer: read Gray pointer → write clock domain
└── sync_w2r — 2-FF synchronizer: write Gray pointer → read clock domain
| Parameter | Value | Description |
|---|---|---|
DSIZE |
8 bits | Data word width |
ASIZE |
4 bits | Address width |
| Depth | 16 entries | 2^ASIZE |
| Write clock | 100 MHz | Configurable |
| Read clock | 75 MHz | Configurable (intentionally asynchronous) |
| Pointer encoding | Gray code | CDC-safe; only one bit changes per increment |
| Full detection | MSB comparison | wgnext == {~wrptr2[MSBs], wrptr2[LSBs]} |
| Empty detection | Equality check | rgnext == rwptr2 |
The UVM testbench (Testbench/) implements the following class hierarchy:
fifo_uvm_base_test
└── fifo_normal_test
└── fifo_uvm_env
├── write_agent (UVM_ACTIVE)
│ ├── write_sequencer
│ ├── write_driver
│ └── write_monitor ──► analysis port
├── read_agent (UVM_ACTIVE)
│ ├── read_sequencer
│ ├── read_driver
│ └── read_monitor ──► analysis port
├── fifo_scoreboard ◄── write_monitor + read_monitor
├── fifo_coverage ◄── cross_domain_analyzer
└── cross_domain_analyzer ◄── write_monitor + read_monitor
| Component | Class | Role |
|---|---|---|
| Interface | fifo_if |
Bundles all DUT signals; provides generate_wrst / generate_rrst tasks |
| Write transaction | fifo_write_transaction |
Randomized wdata (boundary-weighted), winc (70% active) |
| Read transaction | fifo_read_transaction |
Randomized rinc (70% active), captures rdata |
| Combined transaction | fifo_combined_transaction |
Cross-domain tuple used by coverage |
| Write sequence | fifo_write_sequence |
Drives N write transactions with inter-transaction delays |
| Read sequence | fifo_read_sequence |
Drives N read transactions after a 50 ns head-start delay |
| Scoreboard | fifo_scoreboard |
Shadow queue checks every read against the expected write order; reports mismatches |
| Coverage | fifo_coverage |
Covergroup sampling data boundary values (0x00, 0xFF, mid-range), valid write/read events |
| Cross-domain analyzer | cross_domain_analyzer |
Pairs write and read monitor transactions into combined events for coverage |
| Config objects | write_agent_config, read_agent_config, fifo_uvm_env_config |
Parameterized via uvm_config_db |
| Field | Distribution |
|---|---|
wdata |
0x00 → 10%, 0xFF → 10%, 0x01–0xFE → 80% |
winc |
Assert → 70%, De-assert → 30% |
rinc |
Assert → 70%, De-assert → 30% |
The scoreboard maintains a shadow FIFO (expected_data[$]) in the write clock domain and checks reads in order:
- Write monitor pushes
wdataintoexpected_datawhenwinc && !wfull. - Read monitor pops the front of
expected_dataand compares it tordatawhenrinc && !rempty. - Any mismatch raises a UVM_ERROR; a clean run prints
*** TEST PASSED ***.
| Test | Class | Description |
|---|---|---|
| Normal Operation | fifo_normal_test |
Concurrent 32-write / 32-read sequences; fork–join; 75 MHz vs. 100 MHz clocks |
| Base (template) | fifo_uvm_base_test |
1 µs idle run; used as base class for derived tests |
| Reference | Description |
|---|---|
cummings1_final.pdf |
C. Cummings, Simulation and Synthesis Techniques for Asynchronous FIFO Design, SNUG San Jose 2002 — the canonical reference for Gray-code CDC FIFO architecture |
Simulation_and_Synthesis_Tech... |
Supporting simulation and synthesis methodology document |
Template_FFVDD_Team_1.pptx |
Course presentation slides for the FFVDD Elective Mini Project |
This project is licensed under the MIT License — see LICENSE for details.
Done as part of FFVDD (Formal and Functional Verification of Digital Designs) Elective Mini Project Assignment.