SystemVerilog/UVM verification project for an AXI4 slave memory controller.
This repository includes RTL, UVM agents, protocol monitors, a shadow-memory scoreboard, SVA protocol checks, functional coverage models, Python regression support, real Siemens Questa simulation logs, and a documented debug fix.
Current status: initial seed-1 regression completed on Siemens Questa 2025.2 through EDA Playground. Captured simulator logs are included under
logs/, and the dashboard reads real values fromreports/regression_results.json.
No UCDB coverage database or coverage-closure signoff is claimed.
- Built a modular UVM environment for an AXI4 slave memory controller.
- Implemented active master agent, passive slave monitor, scoreboard, coverage collector, and SVA checks.
- Ran seed-1 regression on Siemens Questa 2025.2 through EDA Playground.
- Completed final passing runs for
base_test,burst_write_test,burst_read_test, andrandom_stress_test. - Captured a real debug issue in
burst_read_test, fixed the master-driver timing, and preserved both failing and passing logs. - Verified 780 matching beats across 199 final read/write transactions with zero mismatches.
axi4_verification/
├── rtl/
│ └── axi4_slave_ctrl.sv
├── tb/
│ ├── interfaces/
│ │ └── axi4_if.sv
│ ├── uvm/
│ │ ├── axi4_pkg.sv
│ │ ├── axi4_seq_item.sv
│ │ ├── axi4_master_driver.sv
│ │ ├── axi4_slave_driver.sv
│ │ ├── axi4_monitor.sv
│ │ ├── axi4_scoreboard.sv
│ │ ├── axi4_coverage.sv
│ │ ├── axi4_master_agent.sv
│ │ ├── axi4_slave_agent.sv
│ │ ├── axi4_env.sv
│ │ └── axi4_sequences.sv
│ ├── tests/
│ │ ├── base_test.sv
│ │ ├── burst_write_test.sv
│ │ ├── burst_read_test.sv
│ │ └── random_stress_test.sv
│ └── top/
│ └── axi4_tb_top.sv
├── assertions/
│ └── axi4_assertions.sv
├── docs/
│ ├── debug_story_burst_read_seed1.md
│ ├── img1_uvm_hierarchy.png
│ └── img2_base_test_coverage_summary.png
├── logs/
│ ├── base_test_seed1_questa.log
│ ├── burst_write_test_seed1_questa.log
│ ├── burst_read_test_seed1_questa_FAIL.log
│ ├── burst_read_test_seed1_questa.log
│ └── random_stress_test_seed1_questa.log
├── reports/
│ ├── coverage_dashboard.html
│ ├── regression_results.json
│ └── regression_results.template.json
└── scripts/
└── run_regression.py
uvm_test_top
└── env
├── master_agent [ACTIVE]
│ ├── driver
│ ├── monitor
│ └── sequencer
├── slave_agent [PASSIVE when RTL DUT is used]
│ └── monitor
├── scoreboard
└── coverage_coll
The hierarchy was printed by the real print_topology() call during the seed-1 Questa runs.
Evidence:
logs/base_test_seed1_questa.logdocs/img1_uvm_hierarchy.png
| Feature | Detail |
|---|---|
| Protocol | AXI4 slave-style memory controller |
| Channels | AW, W, B, AR, R |
| Burst types | FIXED and INCR |
| Data width | 32-bit |
| Address width | 32-bit |
| ID width | 4-bit |
| Memory | Internal byte-addressable SRAM, 4 KB default |
| Implementation | Separate write-path and read-path FSMs |
| Component | Description |
|---|---|
axi4_master_agent |
Active agent that drives AXI4 transactions into the DUT |
axi4_slave_agent |
Passive observation agent when the RTL slave is instantiated |
axi4_monitor |
Captures read/write activity and publishes transactions through analysis ports |
axi4_scoreboard |
Shadow-memory model for read-after-write data checking |
axi4_coverage |
Functional coverage model for burst type, burst length, size, address range, response, and strobes |
axi4_assertions |
SVA protocol checks bound to the AXI4 interface |
run_regression.py |
Helper script for simulator command generation and log parsing |
| Test | Purpose |
|---|---|
base_test |
Smoke test using a basic write/read sequence |
burst_write_test |
Exercises incrementing write bursts and readback checking |
burst_read_test |
Exercises burst reads after memory initialization/write traffic |
random_stress_test |
Runs mixed constrained-random AXI4 traffic |
The initial seed-1 regression was run on Siemens Questa 2025.2 through EDA Playground. Logs are included under logs/.
| Test | Seed | Final Status | UVM Errors | UVM Fatals | Mismatched Beats | Log |
|---|---|---|---|---|---|---|
base_test |
1 | PASS | 0 | 0 | 0 | logs/base_test_seed1_questa.log |
burst_write_test |
1 | PASS | 0 | 0 | 0 | logs/burst_write_test_seed1_questa.log |
burst_read_test |
1 | PASS after debug fix | 0 | 0 | 0 | logs/burst_read_test_seed1_questa.log |
random_stress_test |
1 | PASS | 0 | 0 | 0 | logs/random_stress_test_seed1_questa.log |
The initial burst_read_test seed-1 run failed with a scoreboard mismatch at address 0x00000100. The failing log is preserved as:
logs/burst_read_test_seed1_questa_FAIL.log
The fix and rerun are documented in:
docs/debug_story_burst_read_seed1.md
The scoreboard uses a byte-addressable shadow memory model.
Write transactions update expected memory contents per byte lane. Read transactions compare observed RDATA against the expected shadow-memory value.
Write: shadow_mem[address + byte_lane] = WDATA byte when WSTRB lane is active
Read : compare RDATA byte lanes against shadow_mem[address + byte_lane]
Final passing regression totals:
| Metric | Count |
|---|---|
| Total write transactions | 88 |
| Total read transactions | 111 |
| Total read/write transactions | 199 |
| Matching beats | 780 |
| Mismatched beats | 0 |
Coverage is implemented in:
tb/uvm/axi4_coverage.sv
The following values were printed by real Questa simulation logs and copied into reports/regression_results.json.
These are functional covergroup summaries printed by the testbench. They are not a UCDB coverage-closure report.
| Test | Write CG | Read CG | Strobe CG | Status |
|---|---|---|---|---|
base_test |
38.7% | 42.4% | 14.3% | PASS |
burst_write_test |
49.4% | 54.9% | 14.3% | PASS |
burst_read_test |
53.6% | 71.5% | 14.3% | PASS after debug fix |
random_stress_test |
75.6% | 82.6% | 14.3% | PASS |
Strobe coverage remains low because seed 1 primarily exercises full-word writes. This is reported as-is and is not presented as coverage closure.
The first burst_read_test seed-1 run exposed a scoreboard mismatch during burst readback at address 0x00000100.
Root cause: the master driver was driving write data too close to the DUT sampling edge, creating race-prone behavior in the write channel.
Fix: updated the master-driver timing so write data is stable before the DUT samples it.
Verification: reran the same test and seed. The rerun passed with:
UVM_ERROR : 0
UVM_FATAL : 0
Mismatched beats: 0
*** TEST PASSED ***
Evidence:
- Failing log:
logs/burst_read_test_seed1_questa_FAIL.log - Passing log:
logs/burst_read_test_seed1_questa.log - Debug notes:
docs/debug_story_burst_read_seed1.md
The project includes assertion labels in:
assertions/axi4_assertions.sv
| Area | Example checks |
|---|---|
| AW channel | AWVALID, AWADDR, AWLEN, and AWBURST stability while waiting for AWREADY |
| W channel | WVALID, WDATA, WSTRB, and WLAST stability while waiting for WREADY |
| B channel | BVALID/BRESP stability and response ordering after a write address handshake |
| AR channel | ARVALID and ARADDR stability while waiting for ARREADY |
| R channel | RVALID, RDATA, and RLAST stability while waiting for RREADY |
| Reset | VALID signals low after reset release |
Open:
reports/coverage_dashboard.html
The dashboard loads real seed-1 simulation data from:
reports/regression_results.json
regression_results.template.json remains a schema example only.
This project requires a simulator with SystemVerilog/UVM support, such as Questa, VCS, or Xcelium.
Examples:
# Questa
python scripts/run_regression.py --sim questa --seed 1
# VCS
python scripts/run_regression.py --sim vcs --seed 1
# Xcelium
python scripts/run_regression.py --sim xcelium --seed 1Run a single test while debugging:
python scripts/run_regression.py --sim questa --tests base_test --seed 1After a successful run, the script writes generated results under reports/ and simulator logs under the configured log directory.
For published evidence, important simulator transcripts are copied into:
logs/
| Evidence | File |
|---|---|
| Base test log | logs/base_test_seed1_questa.log |
| Burst write log | logs/burst_write_test_seed1_questa.log |
| Initial burst read failing log | logs/burst_read_test_seed1_questa_FAIL.log |
| Fixed burst read passing log | logs/burst_read_test_seed1_questa.log |
| Random stress log | logs/random_stress_test_seed1_questa.log |
| Regression JSON | reports/regression_results.json |
| UVM hierarchy screenshot | docs/img1_uvm_hierarchy.png |
| Coverage/scoreboard screenshot | docs/img2_base_test_coverage_summary.png |
| Debug story | docs/debug_story_burst_read_seed1.md |
| Item | Status |
|---|---|
| RTL source | Present |
| UVM components | Present |
| Test classes | Present |
| SVA source | Present |
| Coverage model | Present |
| Regression script | Present |
| Real simulator transcripts | Included under logs/ |
| Real functional coverage summaries | Included in logs and reports/regression_results.json |
| Debugged simulator failure story | Included in docs/debug_story_burst_read_seed1.md |