Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/chipsalliance/uhdm

Universal Hardware Data Model. A complete modeling of the IEEE SystemVerilog Object Model with VPI Interface, Elaborator, Serialization, Visitor and Listener. Used as a compiled interchange format in between SystemVerilog tools. Compiles on Linux gcc, Windows msys2-gcc & msvc, OsX
https://github.com/chipsalliance/uhdm

ieee-standard listener serialization systemverilog vpi-api vpi-interface

Last synced: 1 day ago
JSON representation

Universal Hardware Data Model. A complete modeling of the IEEE SystemVerilog Object Model with VPI Interface, Elaborator, Serialization, Visitor and Listener. Used as a compiled interchange format in between SystemVerilog tools. Compiles on Linux gcc, Windows msys2-gcc & msvc, OsX

Awesome Lists containing this project

README

        

# Universal Hardware Data Model (UHDM)

![UHDM Overview](/images/UHDM.png)

![UHDM Roadmap](/images/UHDM_future.png)

# Presentation
* [WOSET 2020 Paper and Presentation](https://woset-workshop.github.io/WOSET2020.html#article-10)
* [UHDM Presentation](https://docs.google.com/presentation/d/1evu8aBWMFwi_UrK-DfWXowfsXM4Bp9knQuHV24lwkPc/edit#slide=id.p)

# Purpose

* Auto generate a concrete C++ implementation of the SystemVerilog (VHDL in future) Object Model following the IEEE standard object model
* Auto generate a standard VPI interface as a facade to the C++ model
* Auto generate a serialization/deserialization of the data model
* Auto generate a Visitor (Walker) function that exercise the entire VPI interface (used in uhdm-dump executable)
* Auto generate a C++ Listener Design Pattern that traverse the entire VPI data model (used in uhdm-listener executable)
* Auto generate an Elaborator that uniquifies nets, variables...
* The generated Object Model can, for a given design, be:
* Populated by parsers like [Surelog](https://github.com/alainmarcel/Surelog/) or [Verible](https://github.com/google/verible)
* Consumed by tools like Yosys or Verilator

# HowTo

```bash
* git clone https://github.com/alainmarcel/UHDM.git
* cd UHDM
* git submodule update --init --recursive
* make
```

# Features
* All SystemVerilog models are expressed in a Yaml type syntax (One file per Verilog Object Model)
* From this Yaml description, all the code (C++ headers, VPI Interface, Serialization) is automatically generated.
* Model inheritance and object/class grouping is supported (To follow the IEEE standard)
* Supports the concept of "design" on top of the IEEE standard to support partitioning and multi-language (SystemVerilog - VHDL)
* Any deviation/addition from the standard is cleary indicated by a uhdm prefix, IEEE standard API is either prefixed by vpi (Verilog) or vhpi (VHDL).

# Model Concepts
* The model is captured in .yaml files, one per object models detailed pages 976-1050 of the SystemVerilog 2017 IEEE standard.
* To match the standard, several concepts are observed in the model:
* obj_def: A leaf object specification (Object can be allocated and persisted)
* class_def: A virtual class specification (Class is used either with inheritance - extends:, or as composition of a - class_ref)
* property: Typically an int, bool, string property with a name and a vpi access type (ie: vpiModule) accessed by the vpi_get function
* obj_ref: A reference to one (accessed by vpi_handle) or many (accessed by vpi_iterate) leaf objects
* class_ref: A reference to one or many virtual class, actual objects returned will be of a leaf type
* extends: Class inheritance specified by the extends keyword
* group_def: Grouping of objects in a named or unnamed group (We actually give a representative name to unnamed groups)
* group_ref: A reference to one or many members of a group of objects
* Keywords used to capture the model in Yaml
* all of the above keywords (obj_def...group_ref),
* For each reference (obj_def, class_def, group_def) and property, the following sub fields:
* name: the name of the field (spaces accepted), verbatim from the standard
* vpi: the name of the VPI access type to access this object member (Has to match a defined value in vpi_user.h or sv_vpi_user.h)
* type: the formal type of the field:
* obj_ref
* class_ref
* group_ref
* int
* unsigned int
* bool
* string
* value (VPI s_vpi_value)
* delay (VPI s_vpi_delay)
* card: cardinality of the field
* 1
* any (0 or more)
* The Standard VPI Data Model is Fully Elaborated, in contrast:
* When created by Surelog, the UHDM/VPI Data Model is a Folded Model that we found most suitable for applications like Yosys and Verilator:
* The Instance tree contains the Design Hierarchy and Elaborated Nets/Ports with High conn and Low conn connections done.
* The module definitions contain the logic elements (non-elaborated, and only outside generate statements)
* Generate statements and underlying logic are only visible in the elaborated model (topModules)
* To get the complete picture of the design one has to use both views (Example in [`listener_elab_test.cpp`](tests/listener_elab_test.cpp))
* Applications where the UHDM data model is used as a precursor to another internal datastructure like a Synthesis or Simulator tool will prefer using the Folded Model.
* Nets, Ports, Variables in the flat module list (allModules) don't necessary have the correct data type as not enough elaboration steps were performed on them
* On the other hand, Nets, Ports, Variables have the correct type in the elaborated view (topModules)
* Lhs vs Rhs expression padding is not performed at this point (We welcome PR contributions)
* UHDM offers an optional Elaboration step that uniquifies nets, ports, variables and function by performing a deep cloning and ref_obj binding.
* See [`full_elab_test.cpp`](tests/full_elab_test.cpp) and [`uhdm-dump.cpp`](util/uhdm-dump.cpp)
* Applications where the UHDM data model is free standing and is the sole data structure for the design representation will prefer the Fully Elaborated Data Model, examples: Linters or Code Analyzers.
* At this point, UHDM does not offer:
* the full bit blasted model available in the commercial EDA applications (We welcome contributions).
* an expression evaluator that operates on the UHDM expression tree (We welcome contribuitons).
* [Issue 319](https://github.com/chipsalliance/UHDM/issues/319) discusses more on the topic of elaboration

# Model creation
* The model creation task consists in converting the Object Model diagrams into their Yaml representation and invoking the creation of the concrete
C++ classes, iterators, serialization code by invoking "make"
* [How to create the model (presentation)](https://docs.google.com/presentation/d/1SGpgeeWmxJ-1AU8EKABrTyKwcfHOe-pfK8yXArTKIz8/edit?usp=sharing)

# Actual Design creation
* The design creation task consists in invoking:
* the proper concrete object factory methods to get serializable objects
* populate the properties to the obtained objects
* assemble the model by creating legal object relations (compile time and runtime checking) following the IEEE standard
* invoking the serialization call
* Read [`module-port_test.cpp`](tests/module-port_test.cpp)

# Design Navigation
* After Deserialization of the persisted design (elaborated or not) (Read [`module-port_test.cpp`](tests/module-port_test.cpp))
* Client applications can elaborate optionally and use the VPI interface to navigate the Object Model and create their own internal data structures (Read [`tests/listener_elab_test.cpp`](tests/listener_elab_test.cpp))
* Or use the Visitor (More like a Walker)
* An example Visitor is auto-generated to print the content of the data model [`vpi_visitor.cpp`](templates/vpi_visitor.cpp)
* Or use the Listener Design Pattern
* Examples can be found in tests/vpi_listener.cpp or tests/uhdm_listener.cpp
* The listener enables client application development with minimum disruption while the data model evolves.
* An Custom Elaborator example code uses the Listener Design Pattern in [`listener_elab_test.cpp`](tests/listener_elab_test.cpp)
* A Full Elaboration example is demonstrated in [`full_elab_test.cpp`](tests/full_elab_test.cpp) and [`uhdm-dump.cpp`](util/uhdm-dump.cpp)
* The uhdm-dump [`uhdm-dump`](util/uhdm-dump.cpp) executable creates a human readable view of the UHDM serialized data model using the visitor [`visitor.cpp`](templates/vpi_visitor.cpp).
* An optional linter (Listener) that warns about non-Synthesizable constructs can be found here: [`SynthSubset.cpp`](templates/SynthSubset.cpp)
* An optional linter (Listener) that warns about diverse Verilog compliances post-elaboration can be found here: [`UhdmLint.cpp`](templates/UhdmLint.cpp)
* An optionnal expression evaluator can be found here: [`ExprEval.cpp`](templates/ExprEval.cpp)
* The Yosys-UHDM plugin code (most comprehensive open-source usage of UHDM) can be found here: https://github.com/chipsalliance/yosys-f4pga-plugins/tree/main/systemverilog-plugin
* The Verilator-UHDM plugin code can be found here: https://github.com/antmicro/verilator/blob/uhdm-verilator/src/UhdmAst.cpp

# Linking libuhdm.a to your application
* After instaling (`make install`), create your own executable (Read [`Makefile`](Makefile)) , ie:
* `$(CXX) -std=c++17 tests/test1.cpp -I/usr/local/include/uhdm -I/usr/local/include/uhdm/include /usr/local/lib/libuhdm.a /usr/local/lib/libcapnp.a /usr/local/lib/libkj.a -ldl -lutil -lm -lrt -lpthread -o test_inst`

# Generating uhdm databases
* Surelog generates natively UHDM databases (surelog.uhdm)
* Other parsers are welcome to generate UHDM databases

# Python API
* When uhdm is compiled as a shared library and the UHDM_WITH_PYTHON is set, it also builds a swig wrapper for python (`-DUHDM_WITH_PYTHON=ON` using `cmake` command, or `make release-shared UHDM_WITH_PYTHON=ON`, also make sure your python executable is built with shared libraries enabled: env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install -verbose 3.9.11). The python wrapper implements almost all the VPI getter API from systemVerilog. See chapter *38. VPI routine definitions* of Ieee1800-2017 for details.
* Find here a short example that assumes an existing database. It will print all module names existing in the first design :
```python
import uhdm

#build uhdm Serializer object
s = uhdm.Serializer()
#Read and uhdm database
data = s.Restore('surelog.uhdm')

#Your specific application
#Here create an iterator on all module in the first design
module_iterator = uhdm.vpi_iterate(uhdm.uhdmallModules,data[0])

#iterate on all module
while(True):
vpiObj_module = uhdm.vpi_scan(module_iterator)
if vpiObj_module is None:
break
#print the string pointed by vpiName attribut of vpiObj_module
print(uhdm.vpi_get_str(uhdm.vpiName,vpiObj_module))

```

# Useful links
* [Verilog_Object_Model.pdf](third_party/Verilog_Object_Model.pdf) - Object Model section of the IEEE_Std1800-2017_8299595.pdf (Practical for searches)
* [SystemVerilog 2017](http://ecee.colorado.edu/~mathys/ecen2350/IntelSoftware/pdf/IEEE_Std1800-2017_8299595.pdf) - System Verilog Standard
* [Surelog](https://github.com/chipsalliance/Surelog) - Surelog parser
* [Verible](https://github.com/chipsalliance/verible) - Verible linter
* [capnproto](https://capnproto.org/) - Cap'n Proto serialization