Skip to content

gopro-uvm-rtl-verification/PCIe-Gen3-Endpoint-Subsystem-Verification

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PCIe Gen3 Endpoint — Transaction-Layer Verification (UVM + DPI-C Reference Model)

1) Overview

This repository hosts a UVM-based verification environment for a PCIe Gen3 Endpoint focusing on Transaction Layer correctness. The testbench drives Memory Read/Write and Config Read/Write TLPs, checks completions, collects functional coverage, and uses a self-checking scoreboard that compares DUT TLP streams against a C++ reference model via DPI-C.

In addition to transaction checks, we include bring-up level modeling/checks for Link Training (LTSSM) sequencing and flow-control credits (counter/monitor based), sufficient to validate basic endpoint behavior under randomized traffic. Deeper PHY/elastic-buffer/EIEOS/TS ordering details are planned as extensions.

Key Capabilities (current)

  • UVM layered TB (env/agent/driver/monitor/scoreboard) + SystemVerilog interface & SVA for valid/ready timing and address stability.

  • DPI-C C++ transaction-layer reference model (“memory/config mirror”), consumed by the scoreboard:

    • MRd → CplD with strict tag/len/addr/payload matching.
    • MWr updates model memory; verified via write-then-read.
    • CfgRd/CfgWr minimal stubs (returns zero for CfgRd; ready to extend to full capability/BAR).
  • LTSSM bring-up: sequenced state progression (Detect→Polling→Configuration→L0) in stimulus; simple checks for entry to L0 and recovery hooks.

  • Flow-control credits: stimulus/monitor maintain posted/non-posted/completion credit counters; assertions for “no send w/o credit”; coverpoints track credit consumption/return under randomized traffic.

  • Functional coverage: request-type/length/address crosses; completion coverage (growing); tag-spray sequences for out-of-order stress.

  • Self-checking: automated pass/fail; waveform optional.

Nice-to-have / Extensions

  • Full Config Space model (capabilities, BAR sizing/probing) and MSI/MSI-X as posted writes.
  • ECRC & malformed-TLP injection and checks.
  • Deeper link/PHY modeling (elastic buffer, ordered sets, lane reversal, polarity inversion) if needed.

2) Repository Layout

rtl/                     # DUT (bring-up or real IP)
uvm/
  pcie_pkg.sv           # enums, seq_item, sequences, coverage, agent/env + scoreboard (MVP inline)
  pcie_if.sv            # interface + SVA (valid/ready, addr-stable, etc.)
  # pcie_scoreboard.sv  # (optional) split from pkg in later refactor
  # pcie_env.sv         # (optional) split from pkg in later refactor
dpi/
  pcie_ref_dpi_pkg.sv   # DPI import package (SV side)
  pcie_ref_model.cpp    # C++ transaction-layer reference model
tb/
  tb_top.sv             # clock/reset + run_test
filelist.f              # compile order (SV)
docs/
  figs/run_log.png
  figs/wave_mrd_cpld.png
scripts/
  run_questa.sh
  run_vcs.sh

3) Architecture (what runs where)

     +---------------------+              +-------------------+
     |  UVM Sequences      |              |   C++ Reference   |
     |  (random+directed)  |              |   Model (DPI-C)   |
     +----------+----------+              +---------+---------+
                |                                 ^
                v                                 |
        +-------+--------+                        |
        |  Driver        |                        |
        +-------+--------+                        |
                |   TLP_in                        |
                v                                 |
+---------------+---------------+                 |
|             DUT (Endpoint)    |                 |
+---------------+---------------+                 |
                ^   TLP_out                      |
        +-------+--------+               +-------+--------+
        |  Monitor_out   |---- tr_cpl -->|   Scoreboard   |
        +-------+--------+               +-------+--------+
                ^   TLP_in                      ^
        +-------+--------+                      |
        |  Monitor_in    |---- tr_req ---------+
        +----------------+
  • Monitor_in: forwards inbound requests to the scoreboard → scoreboard calls pcie_model_step_req(...) to advance the C++ model (update memory/config mirror, enqueue expected outputs).
  • Monitor_out: forwards DUT completions/posted writes to the scoreboard → scoreboard pops via pcie_model_pop_expected(...) and compares tag/len/payload/addr.
  • LTSSM & Credits: driver/stimulus include state-sequencing hooks; monitors track credit counters and assert no send without credit; coverpoints record credit consumption/return patterns.

4) DPI-C API (SV ↔ C++)

SV package: dpi/pcie_ref_dpi_pkg.sv

typedef chandle pcie_model_t; // C++ void*

// lifecycle
import "DPI-C" context function pcie_model_t pcie_model_init();
import "DPI-C" context function void         pcie_model_free(pcie_model_t);
import "DPI-C" context function void         pcie_model_reset(pcie_model_t);

// feed inbound requests (MRd/MWr/Cfg*)
import "DPI-C" context function void pcie_model_step_req(
  pcie_model_t  ctx, int tlp_type, longint unsigned addr, int len_dw, int tag,
  byte unsigned payload[], int payload_nbytes, int byte_en_first, int byte_en_last
);

// pop one expected output (1=CplD, 2=MWr/MSI; 0=Cpl)
import "DPI-C" context function int pcie_model_pop_expected(
  pcie_model_t  ctx, output int kind, output longint unsigned addr,
  output int len_dw, output int tag,
  output byte unsigned payload[], input int payload_capacity, output int payload_nbytes
);

// optional: peek model memory for debug/side checks
import "DPI-C" context function int pcie_model_peek_mem(
  pcie_model_t ctx, longint unsigned addr, output byte unsigned data_out[], int nbytes
);

C++ side: dpi/pcie_ref_model.cpp maintains a 64KB memory mirror and an expected-TLP queue.

  • MRd → enqueue CplD with payload from mirror.
  • MWr → write mirror (no immediate expected).
  • CfgRd/CfgWr → stubs (extendable to true capability/BAR model).
  • Endianness: little-endian payload packing; len_dw in DW, addr in bytes.

5) Scoreboard Glue (essentials)

In pcie_scoreboard.sv:

  • build_phase: m_ctx = pcie_model_init(); m_tmp_buf = new[4096];
  • final_phase: pcie_model_free(m_ctx);
  • write_req(tr): converts pcie_seq_item to DPI args; calls pcie_model_step_req(...).
  • write_cpl(c): pcie_model_pop_expected(...) → strict compare: tag/len/payload (+ addr if present).
  • Legacy tag2addr map kept for debug prints; assertions guard protocol mistakes.

6) Interface-level SVA

  • Valid-hold until Ready (both request & completion channels).
  • Address stable while valid && !ready.
  • Latency/existence of CplD after MRd (optional bounded property).
  • Compile-time guards for fault injection (drop valid, corrupt data) to demonstrate assertion firing & coverage.

7) Sequences

  • pcie_smoke_seq: minimal MWr → MRd → CfgRd sanity.
  • pcie_cov_seq: length buckets (small/medium/large), address buckets (BAR0 window), write-then-read side-effect check.
  • pcie_cpl_tag_spray_seq: stresses tags (out-of-order completions matched by tag).
  • LTSSM bring-up seq: scripted Detect→Polling→Configuration→L0 (for endpoint bring-up).
  • Credit stress seq: randomized non-posted/posted/CPL mixes to exercise credit counters.

8) Coverage

  • REQ_CG: type × length × address cross (per-instance).
  • CPL_CG: completion presence/type × length; tag distribution; out-of-order tolerated per tag rules.
  • Credit_CG: bins for credit consumption, depletion, and return under randomized mixes. Typical interim prints observed during bring-up (example):
uvm_test_top.env.cov [COV] REQ_CG=~94% | CPL_CG=growing | CREDIT_CG=exercised (no-send-without-credit holds)

9) Build & Run

(A) Questa/ModelSim (Linux / EDA Playground)

filelist.f (order matters):

+incdir+.
+incdir+rtl +incdir+uvm +incdir+dpi +incdir+tb
dpi/pcie_ref_dpi_pkg.sv
uvm/pcie_pkg.sv
uvm/pcie_if.sv
# uvm/pcie_scoreboard.sv  # (if split later)
rtl/dut.sv
# uvm/pcie_env.sv         # (if split later)
tb/tb_top.sv

Commands:

# compile SV
vlog -sv -f filelist.f

# build DPI library (Linux)
g++ -fPIC -shared -O2 -I$QUESTA_HOME/include -o pcie_ref.so dpi/pcie_ref_model.cpp

# simulate (must load the library)
vsim -c -sv_lib pcie_ref work.tb_top -do "run -all; quit"

EDA Playground:

  • Put pcie_ref_model.cpp under C/C++ Sources; set Library name = pcie_ref.
  • Put pcie_ref_dpi_pkg.sv in Design files before scoreboard.
  • Run Options: -sv_lib pcie_ref -voptargs=+acc=npr
  • Transcript should show: Loading svlib 'pcie_ref'.

(B) VCS (Linux)

vlogan -full64 -sverilog +incdir+. -f filelist.f
g++ -fPIC -shared -O2 -I$VCS_HOME/include -o pcie_ref.so dpi/pcie_ref_model.cpp
vcs -full64 -R -sv_lib pcie_ref work.tb_top

10) Expected Output (proof of success)

Transcript snippets to keep in the repo:

# Loading svlib 'pcie_ref'
UVM_INFO @...: uvm_test_top.env.sb [SB] CplD matched OK tag=5 addr=0x00000100 data=0xA5A50001
UVM_INFO @...: uvm_test_top.env.credit [CREDIT] np_credit=... p_credit=... cpl_credit=...
UVM_INFO [UVM/REPORT/SUMMARY] --- Report summary --- Errors: 0 ...

Negative test example (fault injection):

UVM_ERROR @...: uvm_test_top.ifc.sva [SVA] addr_must_stable violated under valid && !ready
UVM_ERROR @...: uvm_test_top.env.sb   [SB] CplD data mismatch @idx=0 exp=DE AD BE EF got=BA AD F0 0D tag=7 addr=0x10

Waveforms: add IF/DUT signals as usual. Optionally wave scoreboard counters: sb_matches, sb_mismatches, exp_qdepth, np_credit, p_credit, cpl_credit.


11) Assumptions & Limits

  • Transaction layer is the primary scope.
  • LTSSM/Credit: implemented at bring-up/verification level (state sequencing + credit counters + assertions). Deep PHY modeling (ordered sets, lane mapping, SKP/elastic buffer) is deferred unless required by the DUT.
  • Tag width aligned to sequence config (6–8 bits typical).
  • Little-endian payload packing; current BE handling is relaxed (0xF/0xF), can be tightened.

12) Roadmap

  • Full Config Space & BAR decode in the model; MSI/MSI-X as posted writes with address/data checks.
  • ECRC/malformed-TLP injections with protocol assertions & coverage.
  • Enhanced credit checks (VCs, per-class throttling), scoreboard correlation with DUT credit interfaces if exposed.
  • Regression scripts + coverage dashboards (HTML) & CI.

13) What to commit as “Proof Pack”

  • Transcript lines showing Loading svlib 'pcie_ref' and at least one “CplD matched OK …”.
  • One EPWave screenshot: MRd @0x100 → matching CplD (highlight tag/addr/len/payload).
  • File tree + the exact run commands (or a Makefile/script).
  • (Optional) A block diagram (PNG) of the monitor→DPI→scoreboard flow.

14) License

MIT (or your choice)


Appendix A — DPI Notes (why chandle/void*, why context)

  • chandle(SV) ↔ void*(C++): pass an opaque pointer to the model object across the DPI boundary.
  • context: allows the imported function to call back SV DPI services and access SV context safely across sim phases.
  • Arrays: SV byte[] maps to C++ uint8_t* with open-array handles; prefer explicit nbytes.

Appendix B — Debugging Checklist

  • Failed to open -sv_lib pcie_ref → library name mismatch or library not built in C/C++ panel.
  • Package not defined → compile order wrong; build pcie_ref_dpi_pkg.sv before scoreboard.
  • Tons of mismatches with got=0 from pop_expectedstep_req not being called (connect Monitor_in) or timing/OOO window too tight.

Figure 1 — Transcript excerpt (self-checking scoreboard active) Shows multiple CPL matched … lines, MSI hit, coverage summary, and Errors: 0. image

Figure 2 — EPWave snapshot: MRd → CplD match (tag-based OOO allowed) Highlighted signals: req_valid/ready, req_type/len/tag/addr/data and cpl_valid/ready/status/tag/data. The MRd to addr=0x10 with tag=0x3d is followed by a CplD carrying the expected payload; tags align. image

About

UVM + DPI-C reference model for PCIe Gen3 endpoint (transaction layer)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published