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

<module>_axion_reg.vhd

AXI4-Lite slave entity

SystemVerilog

<module>_axion_reg.sv

AXI4-Lite slave module with structs

C Header

<module>_regs.h

Register macros and addresses

Markdown

register_map.md

Human-readable documentation

HTML

<module>.html, index.html

Styled web documentation

XML

<module>_regs.xml

IP-XACT compatible register map

YAML

<module>_regs.yaml

Re-importable YAML definition

JSON

<module>_regs.json

Machine-readable JSON format

Address Map

address_map.html

Instance address space overview (requires --hier)


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

wstrb support for partial register updates

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

RO

signal_name

in

_rd_strobe : out

WO

signal_name

out

_wr_strobe : out

RW

signal_name

out

_rd_strobe, _wr_strobe : out

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_pkg must be compiled into the work library 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 typedef struct packed for registers with subfields, enabling clean access (e.g., ctrl.enable).

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 verilator --lint-only -Wall validation.

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

Offset from base address

SPI_MASTER_STATUS_REG_OFFSET

_ADDR

Absolute address

SPI_MASTER_STATUS_REG_ADDR

READ_<REG>()

Read accessor macro

SPI_MASTER_READ_STATUS_REG()

WRITE_<REG>(val)

Write accessor macro

SPI_MASTER_WRITE_CONTROL_REG(val)


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

.read()

.write()

RW

Returns current value

Updates value

RO

Returns current value

Raises ReadOnlyError

WO

Returns 0 (bus semantics)

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

VHDL register module

Disabled

--c-header

C header file

Disabled

--doc

Documentation (default: Markdown)

Disabled

--doc-format FORMAT

Documentation format: md, html, pdf

md

--xml

XML register map

Disabled

--yaml

YAML register map

Disabled

--json

JSON register map

Disabled

--python, --py

Python register model

Disabled

--all

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

  1. Generate VHDL output

  2. Add <module>_axion_reg.vhd to your project

  3. Instantiate in your top-level design

  4. Connect AXI4-Lite interface to your bus

Embedded C Development

  1. Generate C header output

  2. Include <module>_regs.h in your firmware

  3. Use provided read/write macros

  4. Optionally redefine BASE_ADDR for your memory map

Documentation Workflow

  1. Generate HTML/Markdown outputs

  2. Publish to documentation server or include in project wiki

  3. 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

status

[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.