Convert Excel register specifications to PyUVM RAL models via SystemRDL
Project description
excel2pyral Converter
A comprehensive tool for converting Excel register specifications into Python PyUVM Register Abstraction Layer (RAL) models via SystemRDL intermediate representation.
โ ๏ธ Note:
excel2pyral is currently under active development. Features and interfaces may change, and some functionalities might be incomplete or unstable.
Please use it carefully and report any issues or feedback to help improve the project. ๐
๐ Features
- Excel to PyUVM RAL: Convert Excel register specs directly to Python PyUVM RAL models
- SystemRDL Generation: Generate standalone SystemRDL files from Excel specifications
- Built-in GUI Editor: Interactive Excel editor for viewing and modifying register specifications
- Proper UVM Structure: Generates hierarchical RAL models matching industry standards
- SystemRDL Integration: Uses SystemRDL as intermediate representation for accuracy
- Built-in Validation: Automatic validation through SystemRDL compiler ensures correctness of register descriptions
- Submodule Support: Handles complex hierarchical designs with multiple IP blocks
- Field-Level Detail: Supports register fields with access types, reset values, descriptions
- Debug Support: Comprehensive logging and intermediate file preservation options
- Flexible Output: Choose between PyUVM RAL generation or standalone SystemRDL output
๐ Project Structure
excel2pyral/ # Root project directory
โโโ README.md # This file
โโโ requirements.txt # required python package list
โโโ pyproject.toml # Build system and configuration for your Python project
โโโ excel2pyral/ # Main Python package
โ โโโ __init__.py # Package initialization
โ โโโ excel_importer.py # Excel to SystemRDL converter
โ โโโ systemrdl_compiler.py # SystemRDL compiler wrapper
โ โโโ pyuvm_generator.py # PyUVM RAL generator
โ โโโ main.py # Main converter logic
โโโ docs/ # Documentation
| โโโ README_api.md # README file for API
โโโ examples/ # Example files
| โโโ mychip.xlsx # Simple example input Excel file
| โโโ mychip.rdl # Generated SystemRDL file for mychip
| โโโ mychip_ral.py # Generated PyUVM RAL model for mychip
| โโโ PROJECT_TEST.xlsx # Complex example with multiple modules
| โโโ PROJECT_TEST.rdl # Generated SystemRDL for complex example
| โโโ PROJECT_TEST_ral.py # Generated PyUVM RAL for complex example
โโโ setup.py # Package installation
๐ Table of Contents
- Features
- Project Structure
- Available Commands
- Installation
- Command Line Options
- Excel File Format
- Quick Start
- Python API
- Generated PyUVM Structure
- Best Practices
- Troubleshooting
- Contributing
- License
- Acknowledgments
๏ฟฝ Available Commands
The package provides two main commands:
1. pyral Command
Converts Excel register specifications to PyUVM RAL models with optional SystemRDL generation.
# Basic conversion to PyUVM RAL
pyral registers.xlsx
# Edit Excel file in GUI editor
pyral registers.xlsx --edit
pyral registers.xlsx -e
# Keep intermediate SystemRDL file
pyral registers.xlsx --keep-rdl
# Specify custom names
pyral registers.xlsx --top-name chip_top --package-name chip_ral_pkg
# Custom output directory and keep SystemRDL
pyral chip_spec.xlsx --output results/ --keep-rdl
# Custom sheet names
pyral design.xlsx --submodule-sheet "Modules" --default-sheet "Properties"
# Use enhanced classes with custom package name
pyral my_chip.xlsx --package-name custom_ral --enhanced-classes
2. genrdl Command
Generates only the SystemRDL file from Excel specifications.
# Basic SystemRDL generation
genrdl registers.xlsx
# Edit Excel file in GUI editor
genrdl registers.xlsx --edit
genrdl registers.xlsx -e
# Custom output directory
genrdl registers.xlsx -o output/
# Custom top-level name
genrdl registers.xlsx --top-name chip_top
# Verbose output
genrdl registers.xlsx -v
๏ฟฝ๐ง Installation
Prerequisites
# Required dependencies
pip install systemrdl-compiler
pip install pyuvm
pip install pandas
pip install openpyxl
Install Package
# Clone the repository
git clone https://github.com/SanCodex/excel2pyral.git
cd excel2pyral
# Install in development mode
pip install -e .
๐ฏ Command Line Options
pyral Command
usage: pyral [-h] [--version] [-o OUTPUT] [-r] [-t TOP_NAME] [--package-name PACKAGE_NAME]
[--submodule-sheet SUBMODULE_SHEET] [--default-sheet DEFAULT_SHEET] [-e] [-v] [-q]
excel_file
Convert Excel register specifications to PyUVM RAL models
genrdl Command
usage: genrdl [-h] [--version] [-o OUTPUT] [-t TOP_NAME] [--submodule-sheet SUBMODULE_SHEET]
[--default-sheet DEFAULT_SHEET] [-e] [-v] [-q]
excel_file
Convert Excel register specifications to SystemRDL
Common Options for Both Commands
| Option | Description | Default |
|---|---|---|
-e, --edit |
Open Excel file in GUI editor before conversion | False |
-o, --output |
Output directory | output |
-t, --top-name |
Override top-level addrmap name | From filename |
--submodule-sheet |
Name of submodule hierarchy sheet | Submodules |
--default-sheet |
Name of default properties sheet | default |
-v, --verbose |
Enable verbose output | False |
-q, --quiet |
Suppress all output except errors | False |
Additional Options for pyral Command
| Option | Description | Default |
|---|---|---|
-r, --keep-rdl |
Keep intermediate SystemRDL file | False |
--package-name |
Name for UVM package | {top_name}_ral |
--enhanced-classes |
Use enhanced PyUVM classes | True |
โก Quick Start
Excel GUI Editor
Both pyral and genrdl commands include a built-in GUI editor for Excel files. This feature allows you to:
- View and edit Excel register specifications in a user-friendly interface
- Quickly modify register definitions, offsets, and field properties
- Validate your changes before conversion
- Save changes directly to the Excel file
Using the Excel Editor:
# Edit Excel file in GUI editor
pyral registers.xlsx --edit
# Edit Excel file in GUI editor
genrdl registers.xlsx -e
# Short form works with both commands
pyral chip_spec.xlsx -e
genrdl design.xlsx -e
Features:
- Browse all sheets in your Excel file
- Select and view register definitions
- Edit cell values directly in the GUI
- Save changes and close to proceed with conversion
- Cancel to abort without conversion
Note: The editor opens in a Tkinter GUI window, so ensure you have a display available. After closing the editor:
- If you saved changes, conversion proceeds with the updated file
- If you cancelled or closed without saving, the conversion is aborted
๐ Excel File Format
Required Sheets
1. "Submodules" Sheet (Required for hierarchical designs)
Defines the top-level module hierarchy:
| Column | Description | Example |
|---|---|---|
| Submodule Name | Name of the module type/class | GPIO, UART, SPI |
| Instances | Unique instance name | gpio0, uart_primary |
| Base Addresses | Hexadecimal base address | 0x1000, 0x2000 |
2. Module Type Sheets (One per module type)
Define registers and fields for each module type:
| Column | Description | Example |
|---|---|---|
| Register Name | Name of the register | CONTROL_REG |
| Offset | Offset within module | 0x0, 0x4 |
| Width | Register Width | 32, 64 |
| Reset Value | Reset value (hex/decimal) | 0, 0x5A |
| Field Name | Name of the register field | ENABLE, MODE |
| Field Bits | Field bit positions | [0:0], [7:4] |
| Field Descripton | Description of field bits | Start txn UART |
| SW Access | Access type | rw |
| HW Access | Hardware access | r |
| Behaviour | SystemRDL field property | onwrite=woclr, onwrite=woset |
3. "default" Sheet (Optional)
Global default properties:
| Property | Value | Description |
|---|---|---|
| regwidth | 32 | Default register width |
| accesswidth | 32 | Default access width |
| addressing | regalign | Address alignment |
Column Value Inheritance
When a register has multiple fields, you can leave certain column values empty and they will be inherited from the previous row. This applies to:
- Register Name
- Offset
- Width
- Reset Value
For example, in the UART sheet below, the second field 'START' of RESET_REG inherits the register properties from the first row. This reduces redundancy and makes the spreadsheet more maintainable.
Column Descriptions
Required Columns:
Register Name: Name of the registerOffset: Register offset address (hex format: 0x...)Field Name: Name of the register fieldField Bits: Bit range in format [msb:lsb], [bit], or width number
Optional Columns:
Field Description: Description of the field's functionalitySW Access: Software access permissions (e.g., rw, r, w, rw1c)HW Access: Hardware access permissions (e.g., r, w, rw)Reset Value: Field reset value (hex format)Behaviour: Additional field behaviors using SystemRDL property assignments. Examples:onwrite=woclr- Write one to clear behavioronwrite=woset- Write one to set behavior
Field Bits Format Support:
- Range format:
[7:0]- 8-bit field from bit 7 to 0 - Single bit:
[3]- Single bit field at position 3 - Width only:
8- 8-bit field (position auto-assigned)
Access Permission Values:
-
Software (SW) Access:
rw: Read-Writer: Read-onlyw: Write-onlyrw1c: Read-Write 1 to Clear- Other standard SystemRDL access types
-
Hardware (HW) Access:
r: Read-onlyw: Write-onlyrw: Read-Write- Other standard SystemRDL access types
1. Prepare Your Excel File
Create an Excel file with register specifications:
Sheet: "Submodules"
| Submodule Name | Instances | Base Addresses |
|---|---|---|
| GPIO | gpio0,gpio1 | 0x1000,0x1100 |
| UART | uart0,uart1 | 0x2000,0x3000 |
Sheet: "default" (Optional)
| SW Access | HW Access | Access Width | Reg Width |
|---|---|---|---|
| rw | r | 32 | 32 |
The default sheet provides global default values that apply to all registers unless overridden.
Sheet: "GPIO"
| Register Name | Offset | Width | Reset Value | Field Name | Field Bits | Field Description | SW Access | HW Access | Behaviour |
|---|---|---|---|---|---|---|---|---|---|
| CTRL_REG | 0x0 | 32 | 0x0 | ENABLE | [0:0] | Enable GPIO | rw | r | onwrite=woclr |
| MODE | [3:1] | Mode Select | rw | r | onwrite=woclr | ||||
| STATUS_REG | 0x4 | 32 | 0x0 | INT_STATUS | [0:0] | Interrupt Status | rw1c | r | onwrite=woclr |
Sheet: "UART"
| Register Name | Offset | Width | Reset Value | Field Name | Field Bits | Field Description | SW Access | HW Access | Behaviour |
|---|---|---|---|---|---|---|---|---|---|
| RESET_REG | 0x8 | 32 | 0x0 | PAUSE | [0:0] | Pause txn UART | rw | r | onwrite=woclr |
| START | [3:1] | Start txn UART | rw | r | |||||
| STOP_REG | 0x16 | 32 | 0x0 | END | [0:0] | Stop txn UART | rw | r | onwrite=woclr |
2. Automatic SystemRDL Validation
One of the key features of excel2pyral is its built-in validation through the SystemRDL compiler. Both pyral and genrdl commands perform this validation automatically. During conversion, your register descriptions go through rigorous validation:
For pyral command:
Excel File โ SystemRDL Generation โ SystemRDL Compiler Validation โ PyUVM RAL
For genrdl command:
Excel File โ SystemRDL Generation โ SystemRDL Compiler Validation โ Final SystemRDL
The SystemRDL compiler validates:
- โ Register and field bit ranges
- โ Access permission combinations
- โ Address overlaps and conflicts
- โ Field property assignments
- โ Structural relationships
- โ SystemRDL syntax compliance
When the SystemRDL compiler finds issues:
- Compilation stops immediately
- Detailed error messages are provided to help fix your Excel file
- For
pyralcommand:- With
--keep-rdl, the intermediate SystemRDL file is preserved in the output directory for debugging - No PyUVM RAL model is generated until all validation errors are fixed
- With
- For
genrdlcommand:- The SystemRDL file is written to the output directory (e.g.,
mychip.rdl) - If validation fails, this file is preserved with the invalid content for debugging
- You can fix the Excel file and run the command again to generate a correct SystemRDL file
- The SystemRDL file is written to the output directory (e.g.,
To debug validation issues:
# Using pyral command with verbose output
pyral registers.xlsx --keep-rdl --verbose
# Using genrdl command with verbose output
genrdl registers.xlsx --verbose
# If compilation fails, examine the generated SystemRDL:
cat output/registers.rdl # Look for where compilation stopped
3. Run Conversion
Using pyral (Generate PyUVM RAL)
# Generate PyUVM RAL model
pyral mychip.xlsx --keep-rdl
# With custom options
pyral mychip.xlsx --output custom_output/ --top-name chip_top --package-name chip_pkg
Using genrdl (Generate SystemRDL Only)
# Generate SystemRDL file
genrdl mychip.xlsx
# With custom options
genrdl mychip.xlsx -o rdl_output/ --top-name chip_top --verbose
4. Use Generated PyUVM RAL
# Import the generated RAL model
from output.mychip_ral import build_ral_model
# Build the RAL model in your test class
class MyTest(uvm_test):
def __init__(self, name, parent):
super().__init__(name, parent)
self.ral = build_ral_model()
async def run_phase(self, phase):
# Access registers through proper hierarchy
await self.ral.gpio0.CRTL_REG.write(0x5)
data = await self.ral.uart0.RESET_REG.read()
# Access individual fields
await self.ral.gpio0.CRTL_REG.ENABLE.write(1)
enable_val = await self.ral.gpio0.CRTL_REG.ENABLE.read()
# Use with sequences
reg_seq = uvm_reg_sequence.type_id.create("reg_seq")
reg_seq.model = self.ral
await reg_seq.start(None)
๐ Python API
ExcelToPyRALConverter Class
Main class that orchestrates the Excel โ SystemRDL โ PyUVM pipeline:
from excel2pyral import ExcelToPyRALConverter
# Initialize converter
converter = ExcelToPyRALConverter()
# Convert with all options
result = converter.convert(
excel_file="registers.xlsx", # Input Excel file
output="output", # Output directory
top_name="my_chip", # Top-level module name
package_name="my_chip_ral", # Generated package name
submodule_sheet="Submodules", # Name of submodule hierarchy sheet
default_sheet="default", # Name of default properties sheet
keep_rdl=True, # Keep intermediate SystemRDL
use_enhanced_classes=True # Enable enhanced features
)
# Returns a dictionary with file paths
print(f"Generated PyUVM RAL: {result['pyuvm_file']}")
print(f"Generated SystemRDL: {result['systemrdl_file']}") # If keep_rdl=True
ExcelToSystemRDLImporter Class
For generating SystemRDL files only:
from excel2pyral import ExcelToSystemRDLImporter
# Initialize importer
importer = ExcelToSystemRDLImporter()
# Generate SystemRDL content
systemrdl_content = importer.excel_to_systemrdl(
excel_file="mychip.xlsx",
top_name="chip_top",
submodule_sheet="Submodules", # Optional
default_sheet="default" # Optional
)
# Write to file
with open("output/chip.rdl", "w") as f:
f.write(systemrdl_content)
Individual Components
# Use individual components
from excel2pyral import (
ExcelToSystemRDLImporter,
SystemRDLCompiler,
PyUVMRALGenerator
)
# Step 1: Excel to SystemRDL
excel_importer = ExcelToSystemRDLImporter()
systemrdl_content = excel_importer.excel_to_systemrdl(
excel_file="registers.xlsx",
top_name="my_chip"
)
# Step 2: Compile SystemRDL
rdl_compiler = SystemRDLCompiler()
compiled_root = rdl_compiler.compile_string(systemrdl_content)
# Step 3: Generate PyUVM RAL
ral_generator = PyUVMRALGenerator()
ral_generator.generate(
root_node=compiled_root,
output_file="my_chip_ral.py"
)
๐๏ธ Generated PyUVM Structure
The generated PyUVM RAL follows proper UVM hierarchical structure:
Type-Based Register Classes
class GpioCrtlReg(uvm_reg):
"""Register: GPIO::CRTL_REG"""
def __init__(self, name="CRTL_REG"):
super().__init__(name, 32, has_coverage=uvm_cvr_t.UVM_CVR_ALL)
# Fields
self.ENABLE = uvm_reg_field.type_id.create("ENABLE")
self.MODE = uvm_reg_field.type_id.create("MODE")
Type-Based Block Classes
class GPIO(uvm_reg_block):
"""Register Block: GPIO"""
def __init__(self, name="GPIO"):
super().__init__(name, has_coverage=uvm_cvr_t.UVM_CVR_ALL)
# Register instances
self.CRTL_REG = GpioCrtlReg.type_id.create("CRTL_REG")
self.STATUS_REG = GpioStatusReg.type_id.create("STATUS_REG")
def build_phase(self, phase):
# Create register map and add registers
self.default_map = uvm_reg_map.type_id.create("default_map")
self.default_map.add_reg(self.CRTL_REG, 0x0, "RW")
self.default_map.add_reg(self.STATUS_REG, 0x4, "RW")
Top-Level Class with Sub-Block Instances
class Mychip(uvm_reg_block):
"""Top-level register block: mychip"""
def __init__(self, name="mychip"):
super().__init__(name, has_coverage=uvm_cvr_t.UVM_CVR_ALL)
# Sub-block instances (like SystemVerilog UVM)
self.gpio0 = GPIO.type_id.create("gpio0")
self.gpio1 = GPIO.type_id.create("gpio1")
self.uart0 = UART.type_id.create("uart0")
self.uart1 = UART.type_id.create("uart1")
def build_phase(self, phase):
# Add submaps at proper addresses (like add_submap)
self.default_map.add_submap(self.gpio0.default_map, 0x1000)
self.default_map.add_submap(self.gpio1.default_map, 0x1100)
self.default_map.add_submap(self.uart0.default_map, 0x2000)
self.default_map.add_submap(self.uart1.default_map, 0x3000)
Enhanced PyUVM Classes
Enable enhanced PyUVM classes for additional features:
converter.convert(
excel_file="registers.xlsx",
use_enhanced_classes=True # Enables coverage, callbacks, etc.
)
Best Practices
Excel File Organization
- Use consistent naming: Keep module, register, and field names consistent
- Group related functionality: Put similar registers together
- Document thoroughly: Use description fields extensively
- Validate addresses: Ensure no overlapping address ranges
- Standard bit ranges: Use standard field sizes where possible
Module Design
- Logical grouping: Group related registers in the same module
- Address alignment: Align register addresses to natural boundaries
- Reserved fields: Include reserved fields for future expansion
PyUVM Integration
- Register model early: Create RAL model during build phase
- Use callbacks: Implement register callbacks for monitoring
- Enable coverage: Turn on register coverage for verification
- Sequence integration: Use with standard UVM register sequences
Development Workflow
- Start simple: Begin with basic register definitions
- Test incrementally: Test after each module addition
- Use version control: Track changes to Excel files
- Keep intermediate files: Use
--keep-rdlfor debugging - Validate generated code: Review generated PyUVM RAL model
๐ Troubleshooting
Common Issues
"Walker did not find any top-level addrmap block"
Cause: Missing or incorrectly formatted Submodules sheet Solution:
- Ensure Submodules sheet exists
- Check column names match exactly: "Module Type", "Instance Name", "Base Address", "Description"
- Verify sheet name is exactly "Submodules"
"SystemRDL compilation failed"
Cause: Invalid register/field definitions caught by SystemRDL compiler validation Solution: The SystemRDL compiler automatically validates your register descriptions and will catch issues such as:
- Invalid bit ranges: Ensures
[MSB:LSB]format is correct and MSB >= LSB - Unsupported access types: Validates that access types (RW, RO, WO, etc.) are legal
- Address conflicts: Detects overlapping register addresses
- Invalid field properties: Validates SystemRDL property assignments
- Structural issues: Checks for proper register and field relationships
To debug:
- Use
--keep-rdl --verboseto inspect the generated SystemRDL file - Review the SystemRDL compiler error messages for specific validation issues
- Fix the corresponding entries in your Excel file
"No registers found in design"
Cause: Module type sheets missing or incorrectly named Solution:
- Ensure each Module Type in Submodules sheet has corresponding sheet
- Check sheet names match Module Type exactly (case-sensitive)
- Verify register definitions have all required columns
Import errors in generated PyUVM
Cause: PyUVM not installed or wrong version Solution:
- Install PyUVM:
pip install pyuvm - Check Python environment is correct
- Verify all dependencies are installed
Debug Mode
Enable detailed debugging:
pyral registers.xlsx --keep-rdl --verbose
This provides:
- Step-by-step conversion progress
- Intermediate SystemRDL file for inspection
- Detailed error messages with context
- Generated file locations and sizes
Validation Checklist
Before conversion, verify your Excel file:
- Submodules sheet exists with correct column names
- All module types have corresponding sheets
- Register definitions have all required columns
- Bit ranges are in correct format
[MSB:LSB] - Access types are valid (RW, RO, WO, etc.)
- Addresses are in hexadecimal format
- No overlapping address ranges
- Field names are valid identifiers
- Reset values are properly formatted
Pre-Conversion Validation
Before running the conversion, manually verify your Excel file structure and content using the Validation Checklist above.
๐ค Contributing
Development Setup
git clone https://github.com/SanCodex/excel2pyral.git
cd excel2pyral
# Create virtual environment
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\\Scripts\\activate # Windows
# Install development dependencies
pip install -r requirements-dev.txt
pip install -e .
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- SystemRDL Compiler for SystemRDL support
- PyUVM for Python UVM framework
- PeakRDL ecosystem for inspiration
โญ If this project helped you, please consider giving it a star on GitHub!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file excel2pyral-1.2.1.tar.gz.
File metadata
- Download URL: excel2pyral-1.2.1.tar.gz
- Upload date:
- Size: 130.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ee3f9fae8a3fe6d0ea7abeabca2d9512a1df01a023a030ac70fc97d91d0c279
|
|
| MD5 |
c38ed65a72b972b7ea0da047b4bb69f6
|
|
| BLAKE2b-256 |
cc1ffd3d6f0d6132e4d62673022297c6d24b17c5bf537f2e349fce42847dcdc9
|
File details
Details for the file excel2pyral-1.2.1-py3-none-any.whl.
File metadata
- Download URL: excel2pyral-1.2.1-py3-none-any.whl
- Upload date:
- Size: 125.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1031c9b515dd9761930be4693cbcc350337b0e16062792b9d59d748c598300f6
|
|
| MD5 |
263463a97ddbe7509febc48d40806c3f
|
|
| BLAKE2b-256 |
90f02b3d77d1196796f6ecb077d7ba3d4c2208e8062e2a124a0f625db8cc8def
|