Understanding SystemRDL: Comprehensive Tutorial with Examples
SystemRDL (Register Description Language). SystemRDL is a language used for describing the register maps of digital systems, particularly in the context of hardware design. It allows designers to define the structure and behavior of registers within a hardware design, including their fields, access policies, and associated documentation.
SystemRDL is commonly used in the design and verification of complex digital systems, such as integrated circuits (ICs), system-on-chip (SoC) designs, and other types of hardware where registers play a critical role in controlling and interfacing with the system.
Designers typically use SystemRDL to create register maps that describe the registers and their characteristics, which can then be used by various tools in the design flow, including synthesis, simulation, verification, and documentation generation tools.
Overall, SystemRDL helps improve the efficiency and consistency of register definition and management within complex digital designs, making it a valuable tool in the hardware design process.
This article will discuss several key SystemRDL constructs, accompanied by illustrative examples.
Register Definition:
Register definition is the core component of SystemRDL. It defines the properties and behavior of registers within a hardware design.
reg r1 { regwidth = 32; field f1 { hw = rw; sw = rw; }; f1 field1[31:0] = 31’b0; }; r1 reg1[3] @0x100;
Fields:
Fields within registers define individual bit-level properties such as their access permissions, descriptions, and reset values.
addrmap top{ lsb0; reg{ field {} A[3]= 3’b110; field {} B[15:8]; } regA; };
External Registers
It is possible to have a register to be implemented by the user outside the generated RTL. To indicate such a register the “external” keyword is used in front of the instantiation.
reg reg1 { field { hw=w; sw=rw; } field1; }; addrmap foo { external reg1 reg1; };
Memory:
A memory is an array of storage consisting of a number of entries of a given bit width. The
physical memory implementation is technology dependent and memories shall be external.
mem fixed_mem #(longint unsigned word_size = 32, longint unsigned memory_size = word_size * 4096) { mementries = memory_size/word_size ; memwidth = word_size ; } ;
Register File Component
A register file is as a logical grouping of one or more register and register file instances.The only difference between the register file component (regfile) and the addrmap component is an addrmap defines an RTL implementation boundary where the regfile does not.
regfile fifo_rfile { reg {field {} a;} a; reg {field {} a;} b; }; regfile top_regfile { external fifo_rfile fifo_a; external fifo_rfile fifo_b[64]; sharedextbus; }; addrmap top{ top_regfile top_regfile; };
Addrmap
An address component map (addrmap) is the basic building block that contains registers, register files, memories, and/or other address maps and assigns a virtual address or final addresses. Specifies RTL module boundary
addrmap top{ reg reg1 { field { } fld1[31:20]; field { } fld2[7:5]; }; reg reg2 { field { } fld1[32]; }; reg1 reg1 @0x0; external reg2 reg2 @0x4; };
Signals
“Signals” creates ports, at the block or chip level, and connect certain internal design signals to the external world. User can choose what gets connected to these signals and where these signals are used in the generated RTL using properties
addrmap top { signal{activelow;async;field_reset;} pci_soft_reset; signal{async;activelow;cpuif_reset;} pci_hard_reset; reg PCIE_REG_BIST { regwidth = 8; field { hw = rw; sw = r; fieldwidth = 4; } cplCode [3:0]; field { hw = rw; sw = rw; fieldwidth = 1; resetsignal = pci_hard_reset; } capable [7:7]=0; }; PCIE_REG_BIST PCIE_REG_BIST @0x0; };
Addressing:
SystemRDL allows specifying the address of registers within the address map of the system.
reg control @ 0x100 { // Fields definition here }
Register Arrays:
Register arrays allow defining multiple registers with similar properties in a concise manner.
reg [7:0] data[3] { // Fields definition here }
Enums:
Enums are used to define sets of symbolic constants that can be used to represent specific values.
enum { MODE_A, MODE_B, MODE_C } mode_enum;
User-defined Datatypes:
SystemRDL allows defining custom datatypes to represent complex data structures within registers.
typedef struct { bit [7:0] value; bit [2:0] status; } custom_type;
Defining component parameters
All definitive component types, except enumerations and constraints, may be parametrized using Verilog-style parameters.
reg myReg #(longint unsigned SIZE =32){ regwidth = SIZE; field { } data[SIZE – 1]; }; addrmap myAmap { myReg reg32; myReg reg32_arr[8]; myReg #(.SIZE(16)) reg16; myReg #(.SIZE(8)) reg8; };
Summary
This article discussed a few important constructs in SystemRDL. The language provides a rich set of features for describing registers and their associated properties, making it powerful when used with tools like IDesignSpec for hardware design and verification.