Library / SDK
pyuvm/pyuvm avatar
pyuvm/pyuvm

pyuvm: the UVM written in Python on top of cocotb

The UVM written in Python

571 stars112 forksPythonNOASSERTION

At a glance

What is it?
pyuvm implements the IEEE 1800.2 Universal Verification Methodology in Python rather than SystemVerilog, using cocotb to drive simulators, and covers the sections of the standard that verification engineers actually use: base classes, reporting, factories, phasing, TLM, components, sequences and the register access layer. The register layer is where the gaps are, and the README says so.
Who is it for?
pyuvm suits a verification team that wants the UVM's structure without SystemVerilog, particularly one already using cocotb or moving to a Python-based flow, since the same library gives you a factory, a component hierarchy and a scoreboard with no macro layer in the way.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why a Python UVM exists at all

The README opens with the case for the UVM itself. The Universal Verification Methodology is the dominant RTL verification network across the IC industry, and it is popular because it allows engineers to reuse testbench components across testbenches, and because it provides a standardized testbench structure that lets engineers understand existing testbenches as they move across projects, companies and industries. There is even a hiring argument attached: if you apply for a job as a verification engineer, the hiring team likely uses the UVM and will test your UVM knowledge. Then comes the observation that makes the Python version possible. While the industry defined the 1800.2 standard in terms of SystemVerilog, there is little in the standard that requires the UVM library to be implemented in SystemVerilog, because it could be implemented in any language with sufficient object-oriented support, for example Python. The standard is IEEE 1800.2, defined in the IEEE Standard for Universal Verification Methodology Language Reference Manual, and the argument is that the pattern, not the language, is the valuable part.

Python's object model is the point, not a workaround

The README is explicit about why Python suits the task better than SystemVerilog. It is easier to write UVM code in Python because Python does not have strict typing and does not require parameterized classes, and Python supports important object-oriented programming concepts such as multiple inheritance that are missing in SystemVerilog. That is a real difference in expressiveness rather than a matter of taste, and it changes what the library can offer. The standard's factory mechanism, which relies on macros in SystemVerilog, becomes ordinary Python class registration, so the factory supports any class extended from uvm_void. Phasing, the mechanism that decides when a sequence, driver and scoreboard take part in a phase, is described in the standard as two systems, a basic one everyone uses and a complicated custom one almost nobody uses, and pyuvm implements only the basic one, with the note that you can extend phasing using Python object-oriented techniques instead of a macro system. The library also simplifies uvm_config_db into a Python-friendly Config class, and refactors the sequencer functionality into a simpler implementation of the UVM sequence functionality.

What the standard sections table actually says

The README includes a section-by-section table of IEEE 1800.2 coverage, and it is the most honest part of the documentation because it names what is missing. Section 5, base classes such as uvm_void and uvm_object, is implemented. Section 6, reporting classes, uses the logging package as the reporting backend and provides optional SV-UVM-style reporting APIs, verbosity filtering, report IDs, severity counts and summaries. Section 8, factory classes, implements all the UVM factory functionality without the macros needed in SystemVerilog. Section 9, phasing, is the basic implementation described above. Section 12, UVM TLM interfaces, is fully implemented, which is the Transaction Level Modeling system. Section 13 covers uvm_component with hierarchy, the uvm_root singleton and the run_test() task. Sections 14 and 15 cover sequences, sequencer and sequence_item, and the README calls out a simpler implementation of the sequence functionality. Section 17, the UVM register enum, implements the basic enum types in the register access layer.

The register access layer is where the gaps are

Sections 18 to 27 cover the register access layer, and the README's wording here is a mix of done, partial and not implemented. Section 18, the register block, is implemented. Section 19, the register field, implements fields as defined in IEEE 1800.2 but still lacks functionalities such as atomic Backdoor access, field byte access and single field access during a read or write operation. Section 20, the main register class, is implemented but is still missing Backdoor and the used Backdoor leveraged from cocotb force, with byte access and single field access yet to be implemented. Section 21, the register map, has the main class but the README says it should be refactored to guarantee simplicity and backdoor access, with the extension class in read and write to be implemented. Section 22, UVM memory, is marked Not Implemented. The remaining sections are narrower: a register item used across multiple classes, a register include file to be merged with section 17, the main register adapter, the main register predictor which should be disabled if auto_prediction is not set, and a main register package which should behave similarly to uvm_reg_pkg if included.

Installing pyuvm and running the first object

Installation is a single pip command, and the README notes that this will also install cocotb as a requirement for pyuvm:

bash
% pip install pyuvm

The smoke test runs in an interactive interpreter:

bash
% python
>>> from pyuvm import *
>>> my_object = uvm_object("my_object")
>>> type(my_object)
<class 's05_base_classes.uvm_object'>
>>> print("object name:", my_object.get_name())
object name: my_object

The output is worth pausing on, because it shows the library's structure directly. The class of the object is reported as s05_base_classes.uvm_object, so the module names follow the standard's section numbering, and that mapping from the 1800.2 table to the source tree is how a user navigates the code. The package manifest makes the same structure explicit with a package-dir of src and a packages.find limited to pyuvm. The declared requirement is cocotb>=1.6.0,<3.0, and requires-python is 3.9 or later, with the docs dependency group requiring 3.11.

Running the TinyALU example under a simulator

For development from a clone, the README gives three commands:

bash
% git clone https://github.com/pyuvm/pyuvm.git
% cd pyuvm
% pip install -e .

The example itself is TinyALU, a tiny ALU with four operations, ADD, AND, NOT and MUL, with a Verilog version and also a VHDL version. cocotb uses a Makefile to run the simulation, and the file in examples/TinyALU sets the simulator, the sources, the module and the toplevel, along with the HDL time unit and precision:

makefile
CWD=$(shell pwd)
COCOTB_REDUCED_LOG_FMT = True
SIM ?= icarus
VERILOG_SOURCES =$(CWD)/hdl/verilog/tinyalu.sv
MODULE := testbench
TOPLEVEL=tinyalu
TOPLEVEL_LANG=verilog
COCOTB_HDL_TIMEUNIT=1us
COCOTB_HDL_TIMEPRECISION=1us
include $(shell cocotb-config --makefiles)/Makefile.sim

You change the SIM variable to match your simulator, with the simulator definitions living in cocotb's makefile.$(SIM), and then run the simulation from the example directory:

bash
% cd <path>/pyuvm/examples/TinyALU
% make sim

cocotb prints a lot of messages, and in the middle of them you see the UVM messages, one for each command with randomized operands, so the scoreboard output is the visible proof that the library is driving the design.

How the test suite is organised

The Makefile at the repository root shows how the library tests itself, and the directory names mirror the standard's section numbers. The default simulator variables are VERILOG_SIM ?= icarus and VHDL_SIM ?= ghdl, so both language flows are exercised. The root of the repository is put on PYTHONPATH, with a comment that this is so any test or testbench can pull code from another directory as a namespace package, for example from examples.TinyALU.testbench import .... There are separate targets for the plain pytest suite and for the cocotb suites, and the cocotb ones are broken out per standard section, with targets for t05_base_classes, t08_factories, t09_phasing, t12_tlm, t13_components and config_db, alongside a queue and a decorator target. Coverage is opt-in through a COVERAGE variable, which switches the test command to run under coverage with the COCOTB_USER_COVERAGE variable set, and the repository also carries a checkclean.mk and a combine_results.py, which is how the per-section results are merged.

Licence, releases and where the project stands

There is an inconsistency in the licensing metadata that is worth resolving before you depend on it. GitHub classifies the repository licence as Other, a custom licence the platform cannot map to a known identifier, and the README does not discuss the licence at all, while the pyproject.toml declares license = "Apache-2.0" with license-files = ["LICENSE"] and the project URLs point at the GitHub repository. The LICENSE file at the root is the authoritative text, and the discrepancy between the platform classification and the packaging metadata is the kind of thing that only a human check settles. The release history shows steady work, with 5.0.0 on 2026-08-31, 4.0.1 on 2025-10-18 fixing the @pyuvm.test() decorator and adding cocotb 2.0 support, and 4.0.0 on 2025-10-14 for cocotb 2.0 support, with the last push to the repository on 2026-10-20. The repository layout is a src/ layout with a tests/ directory, an examples/ directory, a docs/ directory, a manual_rst/ directory, a Makefile, a pyproject.toml, a uv.lock, a VERSION file and a .pre-commit-config.yaml, and the author is listed as Ray Salemi.

Editorial conclusion

pyuvm suits a verification team that wants the UVM's structure without SystemVerilog, particularly one already using cocotb or moving to a Python-based flow, since the same library gives you a factory, a component hierarchy and a scoreboard with no macro layer in the way. It is the wrong tool for a project that needs the register access layer complete, because the README records unimplemented and unfinished sections there, including memory, and for a team that wants to reuse a mature SystemVerilog UVM library unchanged. Verify first which standard sections your testbenches need, since the coverage table is in the README and it is explicit about what is missing, and note that the project describes itself as a clean implementation of 1800.2 with cocotb as the simulator layer, and that the newest release is 5.0.0 from 2026-08-31 with the last push on 2026-10-20.

Frequently asked questions

What is pyuvm and what standard does it implement?

It is the Universal Verification Methodology implemented in Python instead of SystemVerilog, and it is a clean implementation of IEEE 1800.2, the standard the industry defines in terms of SystemVerilog but which does not require the library itself to be written in that language.

Which simulator does pyuvm use?

It uses cocotb to interact with simulators and schedule simulation events, with cocotb>=1.6.0,<3.0 as the declared dependency. Installing pyuvm with pip also installs cocotb, and the TinyALU example uses Icarus by default with the SIM variable changed to match your simulator.

Which parts of the UVM register access layer are missing?

The README states that UVM memory is not implemented, that register fields still lack atomic Backdoor access, field byte access and single field access, that the main register class is missing Backdoor and the used Backdoor leveraged from cocotb force, and that the register map should be refactored to guarantee simplicity and backdoor access.

How do I run the TinyALU example?

Clone the repository, install it with pip install -e ., then change into the examples/TinyALU directory and run make sim. cocotb prints many messages, with the UVM scoreboard output in the middle showing one PASSED line for each of the four ALU operations with randomized operands.

Why use Python rather than SystemVerilog for UVM?

The README argues that Python does not have strict typing, does not require parameterized classes, and supports multiple inheritance, which is missing in SystemVerilog. It also means the factory can support any class extended from uvm_void without the macros SystemVerilog needs, and phasing can be extended with ordinary object-oriented techniques.

Official sources

  1. Issues
  2. pyuvm/pyuvm on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pyuvm-pyuvm.svg)](https://hysenlabs.com/projects/pyuvm-pyuvm)

Was this useful?