Skip to content

Commit 6880f49

Browse files
committed
Modify the sverilog generator args to nearly match c-header generator
Add regression task for sverilog gen in GH actions
1 parent 5a69acc commit 6880f49

File tree

4 files changed

+41
-32
lines changed

4 files changed

+41
-32
lines changed

.github/workflows/regress.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,17 @@ jobs:
190190
uses: ./.github/actions/singularity-setup
191191
- name: Generate c_header code
192192
run: ./do gen:c_header
193+
regress-gen-sverilog:
194+
runs-on: ubuntu-latest
195+
env:
196+
SINGULARITY: 1
197+
steps:
198+
- name: Clone Github Repo Action
199+
uses: actions/checkout@v4
200+
- name: singularity setup
201+
uses: ./.github/actions/singularity-setup
202+
- name: Generate sverilog_header code
203+
run: ./do gen:sverilog
193204
regress-cpp-unit:
194205
runs-on: ubuntu-latest
195206
env:

backends/generators/generator.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,14 +276,15 @@ def load_instructions(
276276

277277
# Process RV64 encoding
278278
rv64_match = rv64_encoding.get("match")
279+
rv32_match = rv32_encoding.get("match")
280+
279281
if rv64_match:
280282
instr_dict[name] = {
281283
"match": rv64_match
282284
} # RV64 gets the default name
283285

284-
# Process RV32 encoding with a _rv32 suffix
285-
rv32_match = rv32_encoding.get("match")
286-
if rv32_match:
286+
if rv32_match and rv32_match != rv64_match:
287+
# Process RV32 encoding with a _rv32 suffix
287288
instr_dict[f"{name}_rv32"] = {"match": rv32_match}
288289

289290
continue # Skip the rest of the loop as we've already added the encodings
@@ -441,11 +442,7 @@ def load_csrs(csr_root, enabled_extensions, include_all=False, target_arch="RV64
441442
else:
442443
addr_int = int(addr_to_use, 0)
443444

444-
# For BOTH architecture, add suffix to RV32-specific CSRs
445-
if target_arch == "BOTH" and base == 32:
446-
csrs[addr_int] = f"{name.upper()}.RV32"
447-
else:
448-
csrs[addr_int] = name.upper()
445+
csrs[addr_int] = name.upper()
449446
except Exception as e:
450447
logging.error(f"Error parsing address {addr_to_use} in {path}: {e}")
451448
address_errors += 1

backends/generators/sverilog/sverilog_generator.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,15 @@ def match_to_sverilog_bits(match_str):
2727
"""Convert a match string to SystemVerilog bit pattern."""
2828
if not match_str:
2929
logging.error(f"Empty match string encountered.")
30-
# return "32'b" + "?" * 32
3130

3231
# For compressed instructions (16-bit), we need to handle them differently.
3332
# The 16-bit pattern is in the lower 16 bits,
3433
# with the upper 16 bits as wildcards
3534
if len(match_str) == 16:
3635
# Pad with wildcards on the left for 16-bit instructions
3736
match_str = "?" * 16 + match_str
38-
elif len(match_str) < 32:
39-
# For other cases, pad on the right
37+
elif len(match_str) != 32:
4038
logging.error(f"Match string length is {len(match_str)}, expected 32 or 16.")
41-
# match_str = match_str + "-" * (32 - len(match_str))
4239

4340
# Convert to SystemVerilog format (0, 1, or ?)
4441
result = match_str.replace("-", "?")
@@ -51,7 +48,7 @@ def generate_sverilog(instructions, csrs, output_file):
5148
with open(output_file, "w") as f:
5249
# Write header
5350
f.write("\n/* Automatically generated by UDB */\n")
54-
f.write("package riscv_instr;\n")
51+
f.write(f"package {Path(output_file).stem};\n")
5552

5653
# Find the maximum name length for alignment
5754
max_instr_len = max(
@@ -69,17 +66,11 @@ def generate_sverilog(instructions, csrs, output_file):
6966
sv_name = format_instruction_name(name)
7067
# Pad the name for alignment
7168
padded_name = sv_name.ljust(max_len)
72-
# if not name.startswith("v"):
73-
# logging.info(f"Processing instruction: {name}")
74-
# logging.info(f"Formatted instruction: {sv_name}")
75-
# logging.info(f"Padded instruction: {padded_name}")
76-
7769
# Get the match pattern
7870
if isinstance(encoding, dict) and "match" in encoding:
7971
match = encoding["match"]
8072
else:
81-
# If no match field, use all wildcards
82-
logging.warning(f"No match field for instruction {name}.")
73+
logging.error(f"No match field for instruction {name}.")
8374

8475
sv_bits = match_to_sverilog_bits(match)
8576
f.write(f" localparam logic [31:0] {padded_name} = {sv_bits};\n")
@@ -113,29 +104,36 @@ def parse_args():
113104
default="../../../gen/resolved_spec/_/csr/",
114105
help="Directory containing CSR YAML files",
115106
)
107+
parser.add_argument(
108+
"--ext-dir",
109+
default="../../../arch/ext/",
110+
help="Directory containing extension YAML files",
111+
)
116112
parser.add_argument(
117113
"--output",
118114
default="riscv_decode_package.svh",
119115
help="Output SystemVerilog file name",
120116
)
121117
parser.add_argument(
122-
"--extensions",
123-
default="A,D,F,I,M,Q,Zba,Zbb,Zbs,S,System,V,Zicsr,Smpmp,Sm,H,U,Zicntr,Zihpm,Smhpm",
124-
help="Comma-separated list of enabled extensions. Default includes standard extensions.",
118+
"--include-all",
119+
action="store_true",
120+
help="Include all instructions and CSRs regardless of extensions",
125121
)
126122
parser.add_argument(
127-
"--arch",
128-
default="RV64",
129-
choices=["RV32", "RV64", "BOTH"],
130-
help="Target architecture (RV32, RV64, or BOTH). Default is RV64.",
123+
"--verbose", "-v", action="store_true", help="Enable verbose logging"
131124
)
132125
parser.add_argument(
133-
"--verbose", "-v", action="store_true", help="Enable verbose logging"
126+
"--extensions",
127+
"-e",
128+
nargs="+",
129+
default=[],
130+
help="Comma-separated list of enabled extensions.",
134131
)
135132
parser.add_argument(
136-
"--include-all",
137-
action="store_true",
138-
help="Include all instructions and CSRs regardless of extensions",
133+
"--arch",
134+
default="BOTH",
135+
choices=["RV32", "RV64", "BOTH"],
136+
help="Target architecture (RV32, RV64, or BOTH). Default is RV64.",
139137
)
140138
return parser.parse_args()
141139

@@ -167,6 +165,8 @@ def main():
167165
csrs = load_csrs(args.csr_dir, enabled_extensions, args.include_all, args.arch)
168166
logging.info(f"Loaded {len(csrs)} CSRs")
169167

168+
# Todo: Load exception codes here
169+
170170
# Generate the SystemVerilog file
171171
generate_sverilog(instructions, csrs, args.output)
172172
logging.info(

backends/generators/tasks.rake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ namespace :gen do
108108
cfg_arch = resolver.cfg_arch_for(config_name)
109109
inst_dir = cfg_arch.path / "inst"
110110
csr_dir = cfg_arch.path / "csr"
111+
ext_dir = cfg_arch.path / "ext"
111112

112113
# Run the SystemVerilog generator script using the same Python environment
113-
sh "#{$root}/.home/.venv/bin/python3 #{$root}/backends/generators/sverilog/sverilog_generator.py --inst-dir=#{inst_dir} --csr-dir=#{csr_dir} --output=#{output_dir}riscv_decode_package.svh"
114+
sh "#{$root}/.home/.venv/bin/python3 #{$root}/backends/generators/sverilog/sverilog_generator.py --inst-dir=#{inst_dir} --csr-dir=#{csr_dir} --ext-dir=#{ext_dir} --output=#{output_dir}riscv_decode_package.svh --include-all"
114115
end
115116
end

0 commit comments

Comments
 (0)