Outputs
Axion-HDL generates multiple output formats from a single input definition. This section describes each output type in detail.
Output Summary
Output |
File Pattern |
Description |
|---|---|---|
VHDL Module |
|
AXI4-Lite slave entity |
SystemVerilog |
|
AXI4-Lite slave module with structs |
C Header |
|
Register macros and addresses |
Markdown |
|
Human-readable documentation |
HTML |
|
Styled web documentation |
XML |
|
IP-XACT compatible register map |
YAML |
|
Re-importable YAML definition |
JSON |
|
Machine-readable JSON format |
Address Map |
|
Instance address space overview (requires |
VHDL Register Module
File: <module>_axion_reg.vhd
A fully compliant AXI4-Lite slave module with the following features:
Entity Structure
entity spi_master_axion_reg is
generic (
BASE_ADDR : std_logic_vector(31 downto 0) := x"00000000"
);
port (
-- AXI4-Lite Interface
axi_aclk : in std_logic;
axi_aresetn : in std_logic;
-- AXI Write Address Channel
axi_awaddr : in std_logic_vector(31 downto 0);
axi_awvalid : in std_logic;
axi_awready : out std_logic;
-- AXI Write Data Channel
axi_wdata : in std_logic_vector(31 downto 0);
axi_wstrb : in std_logic_vector(3 downto 0);
axi_wvalid : in std_logic;
axi_wready : out std_logic;
-- AXI Write Response Channel
axi_bresp : out std_logic_vector(1 downto 0);
axi_bvalid : out std_logic;
axi_bready : in std_logic;
-- AXI Read Address Channel
axi_araddr : in std_logic_vector(31 downto 0);
axi_arvalid : in std_logic;
axi_arready : out std_logic;
-- AXI Read Data Channel
axi_rdata : out std_logic_vector(31 downto 0);
axi_rresp : out std_logic_vector(1 downto 0);
axi_rvalid : out std_logic;
axi_rready : in std_logic;
-- Module Clock (for CDC, when enabled)
module_clk : in std_logic;
-- Register Signals
control_reg : out std_logic_vector(31 downto 0);
control_reg_wr_strobe : out std_logic;
status_reg : in std_logic_vector(31 downto 0);
status_reg_rd_strobe : out std_logic;
-- ... additional signals ...
);
end entity;
Features
Feature |
Description |
|---|---|
Full AXI4-Lite Compliance |
Proper handshaking, response codes (OKAY, SLVERR) |
State Machine |
Handles independent address/data phases per AXI-LITE-005 |
Byte-Level Writes |
|
Clock Domain Crossing |
Optional multi-stage synchronizers |
Access Control |
Proper RO/WO/RW behavior with error responses |
Strobe Generation |
Single-cycle read/write strobe outputs |
Default Values |
Register initialization on reset |
Address Decoding |
Automatic offset-based routing |
Port Directions by Access Mode
Access |
Register Port |
Direction |
Strobe Ports |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Typed AXI Ports (axion_common_pkg)
By default, AXI4-Lite signals are exposed as individual flat ports. When the use_axion_types option is enabled, the 19 flat AXI signals are replaced by two typed record ports from axion-common:
use work.axion_common_pkg.all;
entity spi_master_axion_reg is
generic (
BASE_ADDR : std_logic_vector(31 downto 0) := x"00000000"
);
port (
axi_aclk : in std_logic;
axi_aresetn : in std_logic;
-- AXI4-Lite typed record ports (axion_common_pkg)
axi_m2s : in t_axi_lite_m2s; -- master-to-slave signals
axi_s2m : out t_axi_lite_s2m; -- slave-to-master signals
-- Register Signals
control_reg : out std_logic_vector(31 downto 0);
-- ...
);
end entity;
The architecture body uses intermediate signals for every AXI channel signal. The record ports are automatically unpacked/packed via concurrent signal assignments — the internal state machine is unchanged.
Enable per module (YAML):
module: spi_master
base_addr: "0x00000000"
config:
use_axion_types: true
registers:
- name: control
access: RW
Enable globally (CLI):
axion-hdl -s regs.yaml -o output/ --vhdl --use-axion-types
Note:
axion_common_pkgmust be compiled into theworklibrary before this module can be elaborated. See axion-common for the package source.
SystemVerilog Register Module
File: <module>_axion_reg.sv
A modern SystemVerilog AXI4-Lite slave module optimized for verification and integration.
Module Structure
module sensor_controller_axion_reg #(
parameter int ADDR_WIDTH = 32,
parameter int DATA_WIDTH = 32
) (
// AXI4-Lite Interface
input logic axi_aclk,
input logic axi_aresetn,
// ... AXI channels ...
// Module Clock (CDC enabled)
input logic module_clk,
// Register Interface using Packed Structs
output ctrl_reg_t control_reg,
input logic [31:0] status_reg
);
Key Features
Feature |
Description |
|---|---|
Packed Structs |
Generates |
Wide Registers |
Automatically maps registers >32 bits to multiple address offsets. |
Reset Values |
Initializes registers to defined defaults (hex/dec) upon reset. |
Lint Clean |
Passes |
CDC Support |
Built-in synchronization for both Read-Only and Read-Write registers across clock domains. |
Typed AXI Ports (axion_common_pkg)
When use_axion_types is enabled, the 19 flat AXI signals are replaced by two typed struct ports from axion_common_pkg:
import axion_common_pkg::*;
module spi_master_axion_reg #(
parameter int ADDR_WIDTH = 32,
parameter int DATA_WIDTH = 32
) (
// AXI4-Lite Interface (typed record ports from axion_common_pkg)
input logic axi_aclk,
input logic axi_aresetn,
input t_axi_lite_m2s axi_m2s,
output t_axi_lite_s2m axi_s2m,
// Register Interface
output logic [31:0] control_reg
);
Intermediate logic signals bridge the record ports to the existing state machine logic. The state machine itself is unchanged.
Enable per module (YAML):
config:
use_axion_types: true
Enable globally (CLI):
axion-hdl -s regs.yaml -o output/ --sv --use-axion-types
C Header File
File: <module>_regs.h
A C header providing register definitions for embedded software development.
Contents
/**
* @file spi_master_regs.h
* @brief Register definitions for spi_master module
* @note Generated by Axion HDL - Do not edit manually
*/
#ifndef SPI_MASTER_REGS_H
#define SPI_MASTER_REGS_H
#include <stdint.h>
/* Module Base Address */
#define SPI_MASTER_BASE_ADDR 0x00000000
/* Register Address Offsets (relative to base) */
#define SPI_MASTER_CONTROL_REG_OFFSET 0x00 /* SPI control */
#define SPI_MASTER_STATUS_REG_OFFSET 0x04 /* SPI status */
#define SPI_MASTER_TX_DATA_REG_OFFSET 0x08 /* Transmit data buffer */
#define SPI_MASTER_RX_DATA_REG_OFFSET 0x0C /* Receive data buffer */
/* Absolute Register Addresses */
#define SPI_MASTER_CONTROL_REG_ADDR 0x00
#define SPI_MASTER_STATUS_REG_ADDR 0x04
#define SPI_MASTER_TX_DATA_REG_ADDR 0x08
#define SPI_MASTER_RX_DATA_REG_ADDR 0x0C
/* Bit Field Helper Macros */
#define GET_FIELD(val, mask, shift) (((val) & (mask)) >> (shift))
#define SET_FIELD(val, mask, shift, new_val) (((val) & ~(mask)) | (((new_val) << (shift)) & (mask)))
/* Read Macros */
#define SPI_MASTER_READ_CONTROL_REG() \
(*((volatile uint32_t*)(SPI_MASTER_BASE_ADDR + SPI_MASTER_CONTROL_REG_OFFSET)))
#define SPI_MASTER_READ_STATUS_REG() \
(*((volatile uint32_t*)(SPI_MASTER_BASE_ADDR + SPI_MASTER_STATUS_REG_OFFSET)))
/* Write Macros */
#define SPI_MASTER_WRITE_CONTROL_REG(val) \
(*((volatile uint32_t*)(SPI_MASTER_BASE_ADDR + SPI_MASTER_CONTROL_REG_OFFSET)) = (val))
#define SPI_MASTER_WRITE_TX_DATA_REG(val) \
(*((volatile uint32_t*)(SPI_MASTER_BASE_ADDR + SPI_MASTER_TX_DATA_REG_OFFSET)) = (val))
#endif /* SPI_MASTER_REGS_H */
Macro Naming Convention
All macros use the pattern <MODULE>_<REGISTER>_<SUFFIX>:
Suffix |
Description |
Example |
|---|---|---|
|
Offset from base address |
|
|
Absolute address |
|
|
Read accessor macro |
|
|
Write accessor macro |
|
Documentation Outputs
Markdown (register_map.md)
Human-readable documentation with:
Module overview (name, base address, CDC status)
Register table with all fields
Address mapping
Descriptions
HTML (<module>.html, index.html)
Styled web documentation featuring:
Navigation index across all modules
Sortable register tables
Embedded CSS (no external dependencies)
Responsive design
Per-module detail pages
Re-exportable Formats
These outputs can be used as inputs to Axion-HDL, enabling round-trip workflows.
YAML Output (<module>_regs.yaml)
module: spi_master
base_addr: '0x0000'
config:
cdc_en: true
cdc_stage: 2
registers:
- name: control_reg
addr: '0x00'
access: RW
width: 32
w_strobe: true
description: 'SPI control: bit0=start, bits[15:8]=clk_div'
- name: status_reg
addr: '0x04'
access: RO
width: 32
r_strobe: true
description: 'SPI status: bit0=busy, bit1=done, bit2=error'
JSON Output (<module>_regs.json)
{
"module": "spi_master",
"base_addr": "0x0000",
"config": {
"cdc_en": true,
"cdc_stage": 2
},
"registers": [
{
"name": "control_reg",
"addr": "0x00",
"access": "RW",
"width": 32,
"w_strobe": true,
"description": "SPI control: bit0=start, bits[15:8]=clk_div"
}
]
}
XML Output (<module>_regs.xml)
IP-XACT compatible format for EDA tool integration:
<?xml version="1.0" encoding="UTF-8"?>
<register_map module="spi_master" base_addr="0x0000">
<config cdc_en="true" cdc_stage="2"/>
<register name="control_reg" addr="0x00" access="RW" width="32"
w_strobe="true" description="SPI control"/>
<register name="status_reg" addr="0x04" access="RO" width="32"
r_strobe="true" description="SPI status"/>
</register_map>
Python Register Model (<module>_regs.py)
An importable Python file that contains the register space as a live, simulation-ready Python object. No re-parsing of YAML/VHDL sources is required — import the generated file directly in your golden model.
# my_module_regs.py — generated by axion-hdl --python
# DO NOT EDIT — regenerate with: axion-hdl --python
from axion_hdl.register_model import RegisterSpaceModel
_MODULE_DICT = { ... } # register definitions frozen at generation time
MY_MODULE = RegisterSpaceModel.from_module_dict(_MODULE_DICT)
Usage in a golden model:
from my_module_regs import MY_MODULE
# AXI4-Lite bus simulation — use absolute addresses (base + offset)
base = MY_MODULE.base_address
MY_MODULE.write(base + 0x0000, 0x1)
val = MY_MODULE.read(base + 0x0000)
# Named register access
MY_MODULE.control.value = 0x42
print(MY_MODULE.status.ready.enum_name) # 'READY'
# Strobe callback
def on_write(name, val):
print(f"{name} written: 0x{val:08X}")
MY_MODULE.on_write('control', on_write)
# Full register dump
print(MY_MODULE.dump())
Access mode semantics:
Mode |
|
|
|---|---|---|
|
Returns current value |
Updates value |
|
Returns current value |
Raises |
|
Returns |
Updates value |
Use .raw_value on any register to inspect the internal state regardless of access mode —
useful for golden model verification.
Generation Control
CLI Flags
Flag |
Output |
Default |
|---|---|---|
|
VHDL register module |
Disabled |
|
C header file |
Disabled |
|
Documentation (default: Markdown) |
Disabled |
|
Documentation format: |
|
|
XML register map |
Disabled |
|
YAML register map |
Disabled |
|
JSON register map |
Disabled |
|
Python register model |
Disabled |
|
All output formats |
Disabled |
Example Commands
# Generate only VHDL
axion-hdl -s input.yaml -o output --vhdl
# Generate VHDL and C headers
axion-hdl -s input.yaml -o output --vhdl --c-header
# Generate all formats
axion-hdl -s input.yaml -o output --all
# Generate documentation in HTML format
axion-hdl -s input.yaml -o output --doc --doc-format html
Output Directory Structure
After running axion-hdl -s sources/ -o output/ --all:
output/
├── index.html # Navigation page
├── register_map.md # Combined Markdown docs
├── module1_axion_reg.vhd # VHDL module
├── module1_regs.h # C header
├── module1_regs.xml # XML export
├── module1_regs.yaml # YAML export
├── module1_regs.json # JSON export
├── module1.html # HTML detail page
├── module2_axion_reg.vhd
├── module2_regs.h
├── module2_regs.xml
├── module2_regs.yaml
├── module2_regs.json
├── module2.html
└── ...
Integration Examples
Vivado IP Integrator
Generate VHDL output
Add
<module>_axion_reg.vhdto your projectInstantiate in your top-level design
Connect AXI4-Lite interface to your bus
Embedded C Development
Generate C header output
Include
<module>_regs.hin your firmwareUse provided read/write macros
Optionally redefine
BASE_ADDRfor your memory map
Documentation Workflow
Generate HTML/Markdown outputs
Publish to documentation server or include in project wiki
Re-export YAML/JSON for version control tracking
Enumerated Values in Outputs
Docs (Markdown/HTML/PDF)
When a packed register field has enum_values, the field table includes an “Enum Values” column:
Field |
Bits |
Type |
Access |
Default |
Description |
Enum Values |
|---|---|---|---|---|---|---|
|
[1:0] |
[1:0] |
RW |
0x0 |
Status |
0:IDLE, 1:WAITING, 3:READY |
C Header
Enum macros are generated after the field mask/shift definitions:
/* status enumerated values */
#define MYMOD_STATUS_REG_STATUS_IDLE 0x0
#define MYMOD_STATUS_REG_STATUS_WAITING 0x1
#define MYMOD_STATUS_REG_STATUS_READY 0x3
YAML / JSON Export
enum_values is included in the field entry with string keys:
fields:
- name: status
bit_offset: 0
width: 2
enum_values:
"0": IDLE
"1": WAITING
"3": READY
XML (SPIRIT) Export
<spirit:enumeratedValues> is emitted inside each field element with enum values.
VHDL Package (*_regs_pkg.vhd)
Generated when any field has enum_values:
package mymod_regs_pkg is
-- status_reg.status enumerated values
constant C_STATUS_REG_STATUS_IDLE : std_logic_vector(1 downto 0) := "00";
constant C_STATUS_REG_STATUS_WAITING : std_logic_vector(1 downto 0) := "01";
constant C_STATUS_REG_STATUS_READY : std_logic_vector(1 downto 0) := "11";
end package mymod_regs_pkg;
SystemVerilog Package (*_regs_pkg.sv)
Generated when any field has enum_values:
package mymod_regs_pkg;
typedef enum logic [1:0] {
IDLE = 2'b00,
WAITING = 2'b01,
READY = 2'b11
} t_status_reg_status_e;
endpackage // mymod_regs_pkg
Address Map Report (Hierarchy Mode)
File: address_map.html
Generated when: --hier <file> is provided.
A styled HTML report showing all module instances with their assigned address ranges. Useful for reviewing the full design address space at a glance.
Table Columns
Column |
Description |
|---|---|
Instance Name |
The instance identifier from the hierarchy file (or module name for single-instance modules) |
Module |
The source module name |
Base Address |
The base address assigned in the hierarchy file |
End Address |
Base address + register space size − 1 |
Size |
Total register space size (bytes) |
Example
Instance Name Module Base Address End Address Size
spi_master_0 spi_master 0x00020000 0x0002000F 16 B
spi_master_1 spi_master 0x00021000 0x0002100F 16 B
uart_ctrl_0 uart_ctrl 0x00030000 0x0003001F 32 B
The rows are sorted by base address.