Validation Checks
Relevant source files
The following files were used as context for generating this wiki page:The regif tool incorporates a comprehensive, multi-stage validation system to ensure the integrity and correctness of the input Excel register definition file. This system is a critical feature, designed to "never generate broken verilog" by catching configuration, format, and logical errors before any RTL code is produced. The checks are executed automatically when the script is run and will terminate the process with descriptive error messages if any validation fails.
The validation process is divided into three main phases: prerequisite library checks, static checks on the raw Excel data, and dynamic checks that validate the relationships and logic between different register fields. A successful pass through all validation stages is required before the tool proceeds to Verilog and documentation generation.
Overall Validation Flow
The validation process is initiated within the Regif class constructor and proceeds through several sequential steps. The script will exit if any check fails, preventing the generation of faulty output.
This diagram illustrates the high-level validation and generation flow.
Sources: regif.py:1239-1262, readme.md:15
Prerequisite Checks
Before any processing of the Excel file, regif verifies that all required Python libraries are installed.
Library Dependency Check
The checklib() function is called at the very beginning of the script's execution. It attempts to import xlrd (for reading .xls files) and docx (from python-docx for creating .docx files). If either import fails, it prints an error message instructing the user how to install the missing package and exits.
Sources: regif.py:20-31, setup.py:24-27
Static Validation
Static validation occurs immediately after the Excel file is read. These checks focus on format compliance, syntax, and uniqueness constraints for individual cells, without considering the relationships between different fields. This phase is orchestrated by the _static_check method in the Regif class.
Sources: regif.py:1270-1279
Header Configuration Checks
The title_check function validates the global configuration parameters located in the header of the Excel sheet. It uses regular expressions to ensure that values like module name and bus widths are correctly formatted.
| Cell | Parameter | Regex Pattern | Example |
|---|---|---|---|
| C2 | moudle | [a-zA-Z]\w* | my_module |
| F4 | addr_wdith | `([2-9]\Z | [1-9]\d{1,2}\Z)` |
| F5 | data_width | `([4-9]\Z | [1-9]\d{1,2}\Z)` |
| F7 | reg_pre | `"[a-zA-Z_]\w*"\Z | ""\Z` |
Sources: regif.py:81-86, regif.py:1200-1206
Register and Field Format Checks
The static_check function iterates through every register and field defined in the Excel sheet. It performs two main types of validation:
- Format Checking: Each relevant cell is matched against a predefined regular expression to enforce correct syntax.
- Uniqueness Checking: It ensures that all register names and register addresses are unique within the specification. It also checks for unique field names (excluding "RESERVED").
If any of these checks fail, a detailed error message indicating the exact position (line and column) and the nature of the error is reported.
Register Format (reg_format)
This table details the validation rules applied to each register definition row.
| Column | Parameter | Regex Pattern | Suggested Format |
|---|---|---|---|
| A | offset | 0x[\da-fA-F]+\Z | "0x001C" |
| B | regname | [a-zA-Z]\w*\Z | "M_DMA_CFG" |
| C | reg_des | .* | some description is better |
| D | width | [1-9]\d{1,2}\Z | 1~999 |
Sources: regif.py:60-65, regif.py:1171-1198
Field Format (field_format)
This table details the validation rules applied to each field within a register.
| Column | Parameter | Regex Pattern | Suggested Format |
|---|---|---|---|
| E | section | `[(\d+ | \d+:\d+)]\Z` |
| F | fd_name | [a-zA-Z]\w*\Z | must be one word |
| G | RW | `(RW | RC |
| H | reset | `(\d+'(h | H)[\da-fA-F]+\Z |
| I | wprotect | `BITWISE | bitwise |
| J | locksig | `[a-zA-Z]\w*\Z | \A\Z` |
| K | fd_des | .* | (any string) |
| L | other | .* | (any string) |
Sources: regif.py:67-75, regif.py:1171-1198
Dynamic Validation
After static checks pass and register/field objects are created, dynamic validation is performed. These checks analyze the relationships between fields and the logical consistency of the entire register map. This phase is orchestrated by the _dynamic_check method, which calls the dynamic_check method on each register object.
Sources: regif.py:1281-1291
The flow of dynamic checks within a register is as follows:
Sources: regif.py:460-463
Bit Section Continuity
The _section_continue_check method ensures that the bit sections defined for all fields within a single register are valid and form a contiguous block. It checks for three conditions:
- The first field's bit section must start at bit
0. - The last field's bit section must end at
data_width - 1. - There must be no gaps or overlaps between the bit sections of adjacent fields.
Sources: regif.py:465-483
Protection Logic Check
The _protect_check method validates the configuration of write-protection fields (CP - Condition Protection, BP - Bitwise Protection).
- It ensures that if a field specifies a
wprotectsection, a correspondingCPorBPfield exists at that section. - For
BP(Bitwise Protection), it verifies that the bit width of the protected field matches the bit width of theBPfield. - It confirms that
CPandBPfields themselves do not have awprotectvalue, as they cannot be protected by other fields.
Sources: regif.py:485-504
Reset Value Check
The rst_val_check method within the Field class validates the reset value of each field.
- It checks that the width specified in the reset value (e.g., the
12in12'hFFF) matches the bit width of the field's section. - It verifies that the numerical value of the reset (e.g.,
0xFFF) does not exceed the maximum possible value for the field's bit width.
# Snippet from rst_val_check
def rst_val_check(self):
msg = ""
if self.bits_width != int(self.rstval.split("'")[0]):
msg += "Error:The reg '{{reg_name:{{reg_align}}}}' field {name:10} width '{bits_width}' don't macth it reset value '{rstval}' \n".format(
**self.__dict__)
# ...
max_val = 2 ** int(self.bits_width)
# ...
if rel_val > (max_val - 1):
msg += "Error:The reg '{{reg_name:{{reg_align}}}}' field {name:10} reset value {rstval} exceed {section} supported max value' \n".format(
**self.__dict__)
return msg
Sources: regif.py:1010-1033
Group Size Check
The groupSize function is a specialized check for the "Read Group" feature. If a group size is specified in the Excel header (cell K5), this function ensures the value is a power of 2. If the value is not a power of 2, the script prints an error and exits immediately, as this would lead to incorrect read logic generation.
Sources: regif.py:1218-1227
Conclusion
The validation system in regif is a foundational component that guarantees the quality and correctness of the generated hardware description code. By catching a wide array of potential errors—from simple formatting mistakes to complex logical inconsistencies—at an early stage, it saves significant time in debugging and verification. The clear separation between static and dynamic checks allows for a structured and thorough analysis of the user's register specification, reinforcing the tool's reliability.