Excel Template: 'reg' Sheet
Relevant source files
The following files were used as context for generating this wiki page:The regif tool uses a single Microsoft Excel (.xls) file as its primary input for generating Verilog register interface modules and corresponding documentation. The structure and content of the first sheet in this Excel workbook define the entire register map, from global module properties to individual bit-field behaviors. The script parses this sheet to create a hierarchical representation of the registers, performs extensive validation, and then generates the output files.
This single-source-of-truth approach ensures that the hardware implementation, its configuration, and its documentation are always synchronized. The tool is invoked via the command line, passing the path to the Excel file.
Sources: readme.md:16-18, 40-42, regif.py:1290-1303
File Parsing and Processing
The regif script relies on the xlrd Python library to read the .xls file. It processes only the first sheet by index (sheet 0). The core logic for parsing is encapsulated within the Regif class, which reads global settings, extracts register and field data, and orchestrates validation and generation steps.
Sources: setup.py:24, regif.py:33, 1300
The following diagram illustrates the high-level data flow when the tool is executed.
Global Configuration Section
The top-left area of the sheet is reserved for global configuration parameters that apply to the entire module. These values are read during the initialization of the Regif object and are validated against predefined regular expressions.
Sources: regif.py:81-86, 1174-1193
| Parameter | Cell Location | Description | Source |
|---|---|---|---|
| Module Name | C2 | The base name for the generated Verilog module (e.g., my_module). | regif.py:82, 1176 |
| Address Width | F4 | The width of the bmi_addr bus. | regif.py:83, 1177 |
| Data Width | F6 | The width of the bmi_wdata and bmi_rdata buses. | regif.py:84, 1179 |
| Register Prefix | F7 | A string prefix (e.g., "if_") added to internal register and field signal names. | regif.py:85, 1180 |
| Clock Gating | K4 | If set to "YES", enables clock gating logic for RW, RWT, and WO type registers to save power. | regif.py:1178 |
| Group Size | K5 | Groups registers for read logic generation to reduce combinational delay. The value must be a power of 2. | regif.py:1181, 1162-1171 |
| Sync Mode | B6 | If set to anything other than "SYNC", enables clock-domain-crossing (CDC) logic for RC and RWC fields. | regif.py:1188 |
| Reset Macro | K6 | If set to "YES", uses a generic Verilog reset macro (ctrl_always_ff_begin) instead of a hardcoded always block header. | regif.py:1191-1192, 260-272 |
Register and Field Layout
The main body of the sheet, starting from row 10, defines the registers and their constituent bit-fields. The extract_regs function parses these rows sequentially.
- A row with a non-empty offset (Column A) defines a new register.
- Subsequent rows with an empty offset column are treated as fields belonging to the most recently defined register.
Sources: regif.py:1195-1206
Register Definition Columns
These columns are used to define a register block.
| Column | Header | Description | Validation Regex | Source |
|---|---|---|---|---|
| A | offset | The register's address offset in hexadecimal format (e.g., 0x0004). | 0x[\da-fA-F]+\Z | regif.py:53 |
| B | regname | The unique name of the register (e.g., M_DMA_CFG). | [a-zA-Z]\w*\Z | regif.py:54 |
| C | reg_des | A description of the register's purpose. Special keywords like RTL_FREE or FIFO_IF can be included here to alter generation. | .* | regif.py:55, 354-355 |
| D | width | The width of the register. This is checked but the global data_width is primarily used. | [1-9]\d{1,2}\Z | regif.py:56 |
Field Definition Columns
These columns define the bit-fields within a register.
| Column | Header | Description | Validation Regex | Source |
|---|---|---|---|---|
| E | section | Bit position(s) of the field, e.g., [0] for a single bit or [15:7] for a multi-bit field. | `[(\d+ | \d+:\d+)]\Z` |
| F | fd_name | The name of the field. The name RESERVED is special and generates no logic, just space in the register map. | [a-zA-Z]\w*\Z | regif.py:61, 560 |
| G | RW | The access type of the field, which determines its hardware behavior. See the Access Types table below. | (RW|RC|BP|CP|RO|WO|RWW|RWC|RWT|RWP)\Z | regif.py:62 |
| H | reset | The reset value of the field, specified with bit-width and base, e.g., 1'b0, 8'hFF, 4'd10. | (\d+'(h|H)[\da-fA-F]+\Z|\d+'(d|D)\d+\Z|\d+'(b|B)[01]+\Z|0\Z) | regif.py:63 |
| I | wprotect | Defines a write-protection scheme. Can be a bit section [x:y], BITWISE, or empty. Used by CP and BP fields. | BITWISE|bitwise|\[(\d+|\d+\:\d+)\]\Z|\A\Z | regif.py:64 |
| J | locksig | An external signal name that, when asserted, locks this field from being written. | [a-zA-Z]\w*\Z|\A\Z | regif.py:65 |
| K | fd_des | A text description of the field's purpose. | .* | regif.py:66 |
| L | other | Reserved for future use. | .* | regif.py:67 |
Access Types
The access type specified in the RW column (Column G) is critical as it dictates the generated Verilog logic for each field.
| Type | Name | Description | Source |
|---|---|---|---|
RO | Read Only | The field can only be read by the bus. Its value is driven from a corresponding Verilog input port. | readme.md:46, regif.py:62 |
WO | Write Only | The field can only be written by the bus. Its value is driven to a corresponding Verilog output port. | readme.md:48, regif.py:62 |
RW | Read/Write | A standard software-controllable register field that can be both read and written by the bus. | readme.md:50, regif.py:62 |
RC | Read, Clear on HW event | Readable by the bus. A hardware event signal (<field_name>_hw_set) clears the field to 1'b1. A bus write of '1' clears it to 0. | readme.md:52, regif.py:62, 142-148 |
RWC | Read/Write, Clear on HW event | Writable by the bus. A hardware event signal (<field_name>_hw_clc) clears the field to its defined reset value. | regif.py:62, 175-178 |
RWT | Read/Write, Toggle on Write | A readable field where writing a '1' to a bit position toggles its current value. Writing '0' has no effect. | readme.md:58, regif.py:62, 169-170 |
RWP | Read/Write, Protected | A field that can be read by the bus, but bus writes are ignored. It can be cleared to its reset value by hardware. | readme.md:60, regif.py:62 |
RWW | Read/Write, HW Settable | Writable by the bus. It can also be set to a specific value by hardware signals (<field_name>_hw_set and <field_name>_hw_setval). | regif.py:62, 173-174 |
BP | Bitwise Protection | A field that controls write access to another field on a bit-by-bit basis. It is not a storage element itself. | readme.md:56, regif.py:62, 617-624 |
CP | Condition Protection | A field whose value is compared against a condition. If the condition is met, a write to a protected field is allowed. | readme.md:54, regif.py:62, 625-631 |
Internal Data Structures
After parsing, the flat data from the Excel sheet is organized into a hierarchy of Python objects. This structure facilitates validation and code generation.
The diagram below shows the relationship between the main classes used for this internal representation.
Sources: regif.py:350, 410, 458, 1172
Summary
The Excel template is the cornerstone of the regif workflow, providing a user-friendly yet powerful method for defining a complete register interface. Its structured format, combined with the script's rigorous validation, ensures the generation of correct-by-construction Verilog RTL. By using this single file to generate both the hardware and the documentation, regif eliminates inconsistencies and simplifies the design and verification process for register-based modules.
Sources: readme.md:16-22, regif.py:1290-1309