Generator

Generator is used for generating ModuleInstance and HDL code. There can be a Generator for each Interconnect and for each Backend.

Each Generator needs to implement the generate() method that will generate interconnect code specific for used backend.

generate(self, interconnect: _IT, module_instance: ModuleInstance) -> _T:
  pass

_IT is bound to Interconnect and is set by interconnect-specific implementation (e.g. WishboneRRSystemVerilogGenerator).
_T isn’t bound and is set by backend-specific implementation (e.g. SystemVerilogGenerator).

Note

Backend-specific generators inheritance from Generator (e.g. SystemVerilogGenerator).
Interconnect-specific generators inheritance from backend-specific (e.g. WishboneRRSystemVerilogGenerator).

Generated HDL code need to follow naming convention, for ports it is set by get_name(), and for Module by default it is interconnect_{interconnect.name}. add_module_instance_to_design() is used to create ModuleInstance and add it to Design, it can be overridden when generated HDL code needs it.

Important

clk and rst ports are always generated by default, if generate() method don’t create these ports it is needed to override add_module_instance_to_design() to change that behavior.

Backend-specific implementation can introduce new methods that the interconnect-specific class can implement or use. Each backends need to have its own lookup list that contains Interconnect and is mapped to Generator

How to implement a Generator

Based on example of WishboneRRSystemVerilogGenerator, a new SystemVerilog-based generator can be implemented as follows. Create subclass of SystemVerilogGenerator and implement generate(). It needs to return generated System Verilog code, the code needs to have same ports as generated ModuleInstance. To make name generation less prone to errors use get_name() in implementation of generate() or override get_name() with your naming convention.

Lookup maps

SystemVerilogBackend uses verilog_generators_map as lookup map.

API Reference

class Generator
add_module_instance_to_design(interconnect: _IT) ModuleInstance

Returns generated ModuleInstance based on Interconnect, generated ModuleInsance always has rst and clk, ModuleInstance also has additional ports and interfaces based on what bus is used with managers and subordinates. ModuleInstance`s of subordinates and managers are connected to generated `ModuleInsatnce

Parameters:
interconnect: _IT

Interconnect to represent as ModuleInstance

abstract generate(interconnect: _IT, module_instance: ModuleInstance) _T

Returns generated HDL code wrapped in class specific for backend

Parameters:
interconnect: _IT

HDL code is generated based on this Interconnect

module_instance: ModuleInstance

generated based on Interconnect, it don’t need to be used for generation, but can be helpful

get_name(referenced_interface: ReferencedInterface, signal: InterfaceSignal) str

Returns name for InterfaceSignal, generated backend specific code need to have same naming convention

Parameters:
referenced_interface: ReferencedInterface

InterfaceInstance containing this InterfaceSignal

signal: InterfaceSignal

Signal to give name

class SystemVerilogGenerator

It is System Verilog specific generator, it’s empty and need subclass for each Interconnect that SV backend need to support

class WishboneRRSystemVerilogGenerator
add_module_instance_to_design(interconnect: WishboneInterconnect) ModuleInstance

Returns generated ModuleInstance based on Interconnect, generated ModuleInstance always has rst and clk, ModuleInstance also has additional ports and interfaces based on what bus is used with managers and subordinates. ModuleInstance`s of subordinates and managers are connected to generated `ModuleInstance

Parameters:
interconnect: WishboneInterconnect

Interconnect to represent as ModuleInstance

generate(interconnect: WishboneInterconnect, module_instance: ModuleInstance) SVFile

Returns generated HDL code wrapped in class specific for backend

Parameters:
interconnect: WishboneInterconnect

HDL code is generated based on this Interconnect

module_instance: ModuleInstance

generated based on Interconnect, it don’t need to be used for generation, but can be helpful

get_name(referenced_interface: ReferencedInterface, signal: InterfaceSignal) str

Returns name for InterfaceSignal, generated backend specific code need to have same naming convention

Parameters:
referenced_interface: ReferencedInterface

InterfaceInstance containing this InterfaceSignal

signal: InterfaceSignal

Signal to give name

verilog_generators_map : dict[type[Interconnect], type[SystemVerilogGenerator[Any]]]

Used by SV backend to get correct generator. All implementations of Generator for SV backend need to be present in this map.


Last update: 2025-09-04