11. Build Your Own Plugin¶
This chapter will discuss about the nuances of the river_core framework and how to add more plugins or create customizations in the framework.
11.1. Plugin Development¶
To facilitate a plugin based approach, we use the Pluggy Framework. And to do all the low-level work (command generation, running commands) we use the Pytest Framework in combination with the Pluggy framework. It also is helpful as it provides with detailed HTML reports.
As explained in the Overview, the plugins are broadly classified into Generator, DUT (Device Under Test) and Reference Plugins.
To re-iterate the above things in short:
Generator plugins:
These plugins are wrappers around existing Random Code Generator tools that generate random ASM files for a design to run. Some of the common examples include:
AAPG
Torture
Microtesk
DUT plugins:
These Plugins help in running the above generated tests on a design and compiler that you want. Some of the common compiler plugins include:
Verilator
Questa
Cadence
Supported cores at the moment:
Chromite
Your design :)
Reference Plugins run the above generated tests on a golden standard. Some of the common examples include:
Spike
SAIL
11.1.1. Example Plugin Directory¶
11.1.1.1. Common Files¶
{name}_plugin.py
the main Python file that is loaded when the Plugin is loaded into RiVer Core.conftest.py
config file for the Pytest frameworkgen_framework.py
main file which will be containing the pytest parameters and commands to execute.README.md
README for the plugin__init__.py
Standard __init__ file for importing packages
11.1.1.2. Generator Plugins¶
Taking the example of the AAPG
plugin:
├── aapg_gen_config.yaml
├── aapg_plugin.py
├── conftest.py
├── gen_framework.py
├── README.md
├── __init__.py
└── templates
aapg_gen_config.yaml
contains the configuration specific to the AAPG plugin, config.yaml path and the command to run etc.templates
AAPG specific templates for generator YAMLs
11.1.1.3. Device Under Test Plugins¶
Taking an example of the Chromite Verilator
plugin:
├── boot
│ ├── boot.hex
│ ├── chromite.dtb
│ ├── chromite.dts
│ ├── config.chromite
│ └── Makefile
├── chromite_verilator_plugin.py
├── conftest.py
├── gen_framework.py
├── __init__.py
└── README.rst
boot
directory contains files related tocore
11.1.1.4. Reference Plugins¶
Taking an example of the Spike
plugin:
├── conftest.py
├── gen_framework.py
├── __init__.py
├── README.md
└── spike_plugin.py
11.1.2. Plugin API¶
This topic will explain some of the APIs defined for integrating different plugins into RiVer Core.
11.1.2.1. Generator Plugins¶
The generator plugin needs to have 3 different APIs that will be accessed by RiVer Core.
The activities of the plugins are divided into the below 3 categories.
11.1.2.2. DUT and Reference Plugins¶
The DUT plugins needs to have 4 different APIs that will be accessed by RiVer Core.
Reference plugin only needs to have the first 3,
merge
API is optional.
11.1.3. Things to consider while designing plugins¶
11.1.3.1. 1. Plugin naming¶
The class for the plugin has to be plugin_name + plugin. Keeping all the plugins in lowercase.
This is because the RiVer Core is designed to load all plugins in a similar format.
plugin_class = "{0}_plugin".format(suite)
class_to_call = getattr(generatorpm_module, plugin_class)
# TODO:DOC: Naming for class in plugin
generatorpm.register(class_to_call())
except FileNotFoundError as txt:
logger.error(suite + " not found at : " + path_to_module + ".\n" +
str(txt))
raise SystemExit
11.1.3.2. 2. Use pre_gen and init to load and get all values¶
Like the current plugins call and load the required config from the .ini and YAML files, you s should ideally be loading all the required configuration in the initial hooks of the plugins.