RTL Refactoring Policy
Refactoring Decision Criteria
- Module >500 lines: consider splitting
- 3+ modules share similar code: extract common module
- Naming inconsistency flagged by rtl-critic: rename pass
- Missing parameterization: add parameters for magic numbers
- Refactoring is selective — not all modules need it
Naming Convention Audit Rules
Refactoring plans MUST include naming convention audit:
- Ports:
i_/o_/io_prefix (NOT suffix_i/_o) — flag violations for correction - Clocks:
clk(single domain) or{domain}_clk(multiple domains) — flagclk_i,clk_sys - Resets:
rst_n(single domain) or{domain}_rst_n(multiple domains) — flagrst_ni - Instances:
u_prefix — flag missing prefix - Generates:
gen_prefix — flag missing prefix logiconly — flag anyreg/wireusage
Common refactoring patterns:
data_i->i_data,valid_o->o_valid(suffix to prefix)clk_i->clkorsys_clk(suffix clock to conformant name)rst_ni->rst_norsys_rst_n(suffix reset to conformant name)fifo_inst->u_fifo(missing instance prefix)reg [7:0] data->logic [7:0] data(reg to logic)
When renaming ports, prefer sv-renamer (https://github.com/babyworm/sv-renamer) when installed:
# Dry-run preview
sv_renamer.py --dir rtl/ --recursive --prefix i_ --dry-run --report json
# Apply + verify equivalence
sv_renamer.py --dir rtl/ --recursive --prefix i_
sv_semantic_diff.py --before original/ --after rtl/ # formal equivalence check
If sv-renamer is not installed, use Grep to find ALL instantiation sites across the codebase and update them in the same task.
Equivalence Proof Policy
- Cosmetic/style-only cleanup: lint + smoke simulation sufficient
- Any change touching combinational/sequential logic, reset, clock enable, or constraints intent: invoke equivalence-checker (RTL-vs-RTL) before completion
- Formal equivalence via SymbiYosys (requires sv2v conversion first):
sv2v rtl/{module}/*.sv -o rtl/{module}/{module}_v2v.v cd formal/ && sby -f {module}.sby # .sby must reference _v2v.v, not .sv
Escalation & Stop Conditions
- Equivalence check fails → revert to original, report diff to user
- Refactoring plan conflicts with uarch spec → pause, flag to user
- For large module splits, update all instantiation sites in the same task to maintain consistency
Final Checklist
- All changed files pass lint (verilator --lint-only -Wall + slang --lint-only)
- Equivalence verified (formal or smoke sim)
- No instantiation sites broken
- Refactoring plan followed exactly
- All port names use
i_/o_/io_prefix (NOT suffix_i/_o) - All clocks:
clkor{domain}_clk— NOTclk_i - All resets:
rst_nor{domain}_rst_n— NOTrst_ni - All instances:
u_prefix, generates:gen_prefix - No
reg/wirekeywords —logiconly