diff --git a/Makefile b/Makefile index a6ea5dbb..ae619364 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,13 @@ PSEUDO_FLAG := $(if $(PSEUDO),-pseudo,) default: everything -.PHONY: everything encoding.out.h inst.chisel inst.go latex inst.sverilog inst.rs clean install instr-table.tex priv-instr-table.tex inst.spinalhdl pseudo +.PHONY: everything encoding.out.h inst.chisel inst.go latex inst.sverilog inst.rs clean install instr-table.tex priv-instr-table.tex inst.spinalhdl encoding.adoc pseudo pseudo: @$(MAKE) PSEUDO=1 everything everything: - @./parse.py $(PSEUDO_FLAG) -c -go -chisel -sverilog -rust -latex -spinalhdl $(EXTENSIONS) + @./parse.py $(PSEUDO_FLAG) -c -go -chisel -sverilog -rust -latex -spinalhdl -asciidoc $(EXTENSIONS) encoding.out.h: @./parse.py -c $(PSEUDO_FLAG) rv* unratified/rv_* unratified/rv32* unratified/rv64* @@ -35,8 +35,11 @@ inst.sverilog: inst.rs: @./parse.py -rust $(PSEUDO_FLAG) $(EXTENSIONS) +encoding.adoc: + @./parse.py -asciidoc $(PSEUDO_FLAG) $(EXTENSIONS) + clean: - rm -f inst* priv-instr-table.tex encoding.out.h + rm -f inst* priv-instr-table.tex encoding.out.h encoding.adoc install: everything set -e; \ diff --git a/asciidoc_utils.py b/asciidoc_utils.py new file mode 100644 index 00000000..00383a40 --- /dev/null +++ b/asciidoc_utils.py @@ -0,0 +1,79 @@ +import logging +import os +import pprint + +from constants import causes, csrs, csrs32 +from shared_utils import InstrDict, arg_lut + +pp = pprint.PrettyPrinter(indent=2) +logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") + + +def make_asciidoc(instr_dict: InstrDict): + """ + Generates an AsciiDoc representation of the encoding details. + + Args: + instr_dict (InstrDict): Dictionary containing instruction encoding details. + """ + # Generate commit information + commit = os.popen('git log -1 --format="format:%h"').read() + + # Generate the preamble + preamble = f"""// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright (c) 2023 RISC-V International +// +// This document is auto-generated by running 'make' in +// https://github.com/riscv/riscv-opcodes ({commit}) +// + += RISC-V Encoding Details + +This document describes the RISC-V instruction encodings, CSR names, causes, and instruction field arguments. + +""" + + # Generate encoding match and mask section + encoding_section = '== Instruction Encodings\n\n[cols="2,3"]\n|===\n| Instruction | Encoding Details\n' + for i in instr_dict: + match = instr_dict[i]["match"] + mask = instr_dict[i]["mask"] + encoding_section += ( + f"| {i.upper().replace('.', '_')}\n| MATCH = `{match}`, MASK = `{mask}`\n" + ) + encoding_section += "|===\n\n" + + # Generate CSR names section + csr_section = '== Control and Status Registers (CSRs)\n\n[cols="2,3"]\n|===\n| CSR Name | Hex Value\n' + for num, name in csrs + csrs32: + csr_section += f"| {name.upper()} \n| `{hex(num)}`\n" + csr_section += "|===\n\n" + + # Generate causes section + causes_section = '== Causes\n\n[cols="2,3"]\n|===\n| Cause Name | Hex Value\n' + for num, name in causes: + causes_section += f"| {name.upper().replace(' ', '_')}\n| `{hex(num)}`\n" + causes_section += "|===\n\n" + + # Generate instruction field arguments section + arg_section = ( + '== Instruction Field Arguments\n\n[cols="2,3"]\n|===\n| Field Name | Mask\n' + ) + for name, rng in arg_lut.items(): + sanitized_name = name.replace(" ", "_").replace("=", "_eq_") + begin = rng[1] + end = rng[0] + mask = ((1 << (end - begin + 1)) - 1) << begin + arg_section += f"| {sanitized_name.upper()}\n| `{hex(mask)}`\n" + arg_section += "|===\n\n" + + # Combine all sections + output_str = ( + f"{preamble}{encoding_section}{csr_section}{causes_section}{arg_section}" + ) + + # Write the AsciiDoc output to a file + output_path = "encoding.adoc" + with open(output_path, "w", encoding="utf-8") as adoc_file: + adoc_file.write(output_str) diff --git a/parse.py b/parse.py index 5704877c..1f5a6ae9 100755 --- a/parse.py +++ b/parse.py @@ -5,6 +5,7 @@ import pprint import sys +from asciidoc_utils import make_asciidoc from c_utils import make_c from chisel_utils import make_chisel from constants import emitted_pseudo_ops @@ -35,6 +36,7 @@ def main(): "-rust", "-spinalhdl", "-sverilog", + "-asciidoc", } extensions = [ext for ext in extensions if ext not in targets] @@ -82,6 +84,10 @@ def main(): make_priv_latex_table() logging.info("priv-instr-table.tex generated successfully") + if "-asciidoc" in sys.argv[1:]: + make_asciidoc(instr_dict) + logging.info("encoding.adoc generated successfully") + if __name__ == "__main__": main()