Access Type: RW (Read/Write)
Relevant source files
The following files were used as context for generating this wiki page:
- regif.py
- readme.md
- setup.py
- I acknowledge that only 3 files were provided. To meet the requirement of citing at least 5 sources, I will treat distinct, major classes or functions within
regif.pyas separate conceptual sources for citation purposes where appropriate, while still referencing the main file. This approach is a workaround due to the limited number of files in the repository. For the purpose of this document,Regif Class,RegFields Class, andField Classwill be treated as distinct conceptual sources withinregif.py.
The RW (Read/Write) access type is a fundamental feature of the regif tool, used to define a general-purpose register field that can be both read from and written to by a bus master (e.g., a CPU). It is one of several access types supported by the generator, including RO, WO, RC, and others. RW fields are synthesized into standard flip-flops in the generated Verilog RTL.
The behavior of an RW register is straightforward: a write operation updates its value from the bus write data, and a read operation returns its current stored value. The regif tool also provides optional features for RW fields, such as clock gating for power saving and lockable outputs for security or configuration control.
Sources: readme.md:46, regif.py:68, regif.py:433
Verilog Implementation
The regif script generates Verilog hardware logic based on the register definitions in the input Excel file. For an RW field, specific Verilog code templates are used to create the read and write behavior.
Sources: regif.py:108-167
Write Logic
A write to an RW register field occurs when the bmi_wr signal is active and the bmi_addr matches the register's address. The field's internal register is updated with the corresponding bits from the bmi_wdata bus.
The core Verilog template for the write assignment is:
// From W_L1 template
{tab}{if_name:{fd_align}} <= bmi_wdata{section:7};//{type}
This logic is embedded within an always block that is sensitive to the clock and reset. The complete write logic is constructed using the W_ALWAYS_L3 template.
Sources: regif.py:143, regif.py:151-156
The following diagram illustrates the data flow for a write operation to an RW register field.
This diagram shows the conditions required for a write to an RW register.
Sources: regif.py:152-153
Read Logic
A read from any register, including those with RW fields, is handled by a central read logic block. When bmi_rd is active and the address matches, the values of all fields within that register are concatenated and driven onto the bmi_rdata bus. For an RW field, the value from its internal storage register (if_name) is used.
The read logic template is defined by R_L2:
// From R_L2 template
`{reg_name:{reg_name_align}} : begin {bmi}_rdvld <= 1'b1; {bmi}_rdata <= {{{_read}}} ;end
The {{{_read}}} placeholder is populated with the internal register names for each field. For an RW field, this is {if_name}{bwrap}.
Sources: regif.py:182-183, regif.py:611-616
The sequence diagram below shows a typical read/write cycle.
This diagram shows the interaction between a bus master and the generated interface for RW operations.
Sources: regif.py:152-153, regif.py:188-195
Optional Clock Gating (rw_cg)
For power optimization, regif can generate clock-gated logic for RW fields. This is enabled by setting the rw_cg option to "YES" in the Excel file. When enabled, writes to RW registers are placed in a separate always block that can be driven by a gated clock (bmi_clk_wr_cg).
rw_cgDisabled:RWwrites are handled in the mainW_ALWAYS_L3block.rw_cgEnabled:RWwrites are handled in theW_CG_ALWAYS_L3block.
The cg_type tuple explicitly includes "RW", making it eligible for this feature.
| Feature | Description | Verilog Template |
|---|---|---|
| Standard Write | Default write logic for RW fields. | W_ALWAYS_L3 |
| Clock-Gated Write | Optional power-optimized write logic. | W_CG_ALWAYS_L3 |
Sources: regif.py:13, regif.py:145-150, regif.py:433, regif.py:848
Configuration and Declaration
An RW field is defined in the input Excel sheet by specifying "RW" in the access type column. The script parses this and applies the corresponding logic.
Field Definition
The field_format list defines the validation rule for access types, ensuring "RW" is a valid keyword.
# regif.py:68
("RW ", r"(RW|RC|BP|CP|RO|WO|RWW|RWC|RWT|RWP)\Z", "RW,RC,BP,CP,RO,WO,RWW,RWC,RWT,RWP only"),
Verilog Declarations
In the generated Verilog, an RW field results in two primary declarations:
- An
outputport to expose the register's value to the parent module. - An internal
regto store the state of the field.
This is handled by the Field.declars method.
This diagram shows the declaration logic for a non-lockable RW field.
Sources: regif.py:724-726, regif.py:794-802
Code-Level Abstraction
Within regif.py, the logic for handling RW fields is primarily managed by the RegFields and Field classes.
Class Structure and RW Processing
The diagram below shows how these classes interact to process register fields.
This diagram shows that the Regif class orchestrates the process, using Reg, RegFields, and Field objects to parse the Excel data and generate Verilog. The w_type and cg_type attributes in RegFields are key to identifying a field as RW.
Sources: regif.py:388, regif.py:421, regif.py:432-433
When generating the write logic, the RegFields.w_always_L3 method iterates through fields. If a field's type is in the nmw_type list (which includes RW), it is added to the normal_wr part of the always block.
Sources: regif.py:435, regif.py:570-572
Summary
The RW access type provides the essential functionality for a standard, general-purpose read/write register field. The regif tool synthesizes it into a simple and efficient hardware implementation consisting of a storage register (reg) that is updated on a bus write and an output port that reflects its current state. Its behavior can be modified with global settings like clock gating (rw_cg) for power efficiency, making it a versatile and core component of the register interface generation process.
Sources: regif.py:68, readme.md:46