Skip to content

Commit

Permalink
Merge pull request #293 from Timmmm/user/timh/types
Browse files Browse the repository at this point in the history
Add static type hints
  • Loading branch information
aswaterman authored Oct 31, 2024
2 parents f73c2a4 + 284a5fa commit 699eb16
Show file tree
Hide file tree
Showing 17 changed files with 250 additions and 240 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install PyYAML
- name: Install Coverage
run: |
pip3 install -r requirements.txt
pip3 install coverage
- name: Run pre-commit
run: |
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install PyYAML
- name: Install Coverage
run: |
pip3 install -r requirements.txt
pip3 install coverage
- name: Test error outputs
run: coverage run -m unittest -b
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ priv-instr-table.tex
inst.rs
inst.spinalhdl
inst.sverilog
instr_dict.yaml
instr_dict.json

__pycache__/
13 changes: 4 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,8 @@ repos:
# rev: v3.3.1
# hooks:
# - id: pylint
# additional_dependencies:
# - "pyyaml==6.0.2"

# TODO: Enable this when types are added.
# - repo: https://github.com/RobertCraigie/pyright-python
# rev: v1.1.383
# hooks:
# - id: pyright
# additional_dependencies:
# - "pyyaml==6.0.2"
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.383
hooks:
- id: pyright
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ of extensions are being processed such that the *base-instruction* is not includ

The following artifacts can be generated using parse.py:

- instr\_dict.yaml : This is file generated always by parse.py and contains the
entire main dictionary `instr\_dict` in YAML format. Note, in this yaml the
*dots* in an instruction are replaced with *underscores*
- instr\_dict.json : This is always generated by parse.py and contains the
entire main dictionary `instr\_dict` in JSON format. Note, in this file the
*dots* in an instruction are replaced with *underscores*. In previous
versions of this project the generated file was instr\_dict.yaml. Note that
JSON is a subset of YAML so the file can still be read by any YAML parser.
- encoding.out.h : this is the header file that is used by tools like spike, pk, etc
- instr-table.tex : the latex table of instructions used in the riscv-unpriv spec
- priv-instr-table.tex : the latex table of instruction used in the riscv-priv spec
Expand All @@ -138,14 +140,6 @@ The following artifacts can be generated using parse.py:
- inst.spinalhdl : spinalhdl code to decode instructions
- inst.go : go code to decode instructions

Make sure you install the required python pre-requisites are installed by executing the following
command:

```
sudo apt-get install python-pip3
pip3 install -r requirements.txt
```

To generate all the above artifacts for all instructions currently checked in, simply run `make` from the root-directory. This should print the following log on the command-line:

```
Expand Down Expand Up @@ -220,6 +214,6 @@ DEBUG:: Processing line: bne bimm12hi rs1 rs2 bimm12lo 14..12=1 6..2=0x
## How do I find where an instruction is defined?

You can use `grep "^\s*<instr-name>" rv* unratified/rv*` OR run `make` and open
`instr_dict.yaml` and search of the instruction you are looking for. Within that
instruction the `extension` field will indicate which file the instruction was
picked from.
`instr_dict.json` and search for the instruction you are looking for. Within
that instruction the `extension` field will indicate which file the
instruction was picked from.
2 changes: 1 addition & 1 deletion c_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s")


def make_c(instr_dict):
def make_c(instr_dict: InstrDict):
mask_match_str = ""
declare_insn_str = ""
for i in instr_dict:
Expand Down
4 changes: 2 additions & 2 deletions chisel_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s")


def make_chisel(instr_dict, spinal_hdl=False):
def make_chisel(instr_dict: InstrDict, spinal_hdl: bool = False):

chisel_names = ""
cause_names_str = ""
Expand All @@ -31,7 +31,7 @@ def make_chisel(instr_dict, spinal_hdl=False):
elif "rv_" in e:
e_format = e.replace("rv_", "").upper()
else:
e_format = e.upper
e_format = e.upper()
chisel_names += f' val {e_format+"Type"} = Map(\n'
for instr in e_instrs:
tmp_instr_name = '"' + instr.upper().replace(".", "_") + '"'
Expand Down
218 changes: 96 additions & 122 deletions constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import csv
import re

# TODO: The constants in this file should be in all caps.
overlapping_extensions = {
"rv_zcmt": {"rv_c_d"},
"rv_zcmp": {"rv_c_d"},
Expand All @@ -21,29 +22,29 @@

# regex to find <msb>..<lsb>=<val> patterns in instruction
fixed_ranges = re.compile(
"\s*(?P<msb>\d+.?)\.\.(?P<lsb>\d+.?)\s*=\s*(?P<val>\d[\w]*)[\s$]*", re.M
r"\s*(?P<msb>\d+.?)\.\.(?P<lsb>\d+.?)\s*=\s*(?P<val>\d[\w]*)[\s$]*", re.M
)

# regex to find <lsb>=<val> patterns in instructions
# single_fixed = re.compile('\s+(?P<lsb>\d+)=(?P<value>[\w\d]*)[\s$]*', re.M)
single_fixed = re.compile("(?:^|[\s])(?P<lsb>\d+)=(?P<value>[\w]*)((?=\s|$))", re.M)
single_fixed = re.compile(r"(?:^|[\s])(?P<lsb>\d+)=(?P<value>[\w]*)((?=\s|$))", re.M)

# regex to find the overloading condition variable
var_regex = re.compile("(?P<var>[a-zA-Z][\w\d]*)\s*=\s*.*?[\s$]*", re.M)
var_regex = re.compile(r"(?P<var>[a-zA-Z][\w\d]*)\s*=\s*.*?[\s$]*", re.M)

# regex for pseudo op instructions returns the dependent filename, dependent
# instruction, the pseudo op name and the encoding string
pseudo_regex = re.compile(
"^\$pseudo_op\s+(?P<filename>rv[\d]*_[\w].*)::\s*(?P<orig_inst>.*?)\s+(?P<pseudo_inst>.*?)\s+(?P<overload>.*)$",
r"^\$pseudo_op\s+(?P<filename>rv[\d]*_[\w].*)::\s*(?P<orig_inst>.*?)\s+(?P<pseudo_inst>.*?)\s+(?P<overload>.*)$",
re.M,
)

imported_regex = re.compile(
"^\s*\$import\s*(?P<extension>.*)\s*::\s*(?P<instruction>.*)", re.M
r"^\s*\$import\s*(?P<extension>.*)\s*::\s*(?P<instruction>.*)", re.M
)


def read_csv(filename):
def read_csv(filename: str):
"""
Reads a CSV file and returns a list of tuples.
Each tuple contains an integer value (from the first column) and a string (from the second column).
Expand Down Expand Up @@ -79,126 +80,99 @@ def read_csv(filename):

# dictionary containing the mapping of the argument to the what the fields in
# the latex table should be
latex_mapping = {}
latex_mapping["imm12"] = "imm[11:0]"
latex_mapping["rs1"] = "rs1"
latex_mapping["rs2"] = "rs2"
latex_mapping["rd"] = "rd"
latex_mapping["imm20"] = "imm[31:12]"
latex_mapping["bimm12hi"] = "imm[12$\\vert$10:5]"
latex_mapping["bimm12lo"] = "imm[4:1$\\vert$11]"
latex_mapping["imm12hi"] = "imm[11:5]"
latex_mapping["imm12lo"] = "imm[4:0]"
latex_mapping["jimm20"] = "imm[20$\\vert$10:1$\\vert$11$\\vert$19:12]"
latex_mapping["zimm"] = "uimm"
latex_mapping["shamtw"] = "shamt"
latex_mapping["shamtd"] = "shamt"
latex_mapping["shamtq"] = "shamt"
latex_mapping["rd_p"] = "rd\\,$'$"
latex_mapping["rs1_p"] = "rs1\\,$'$"
latex_mapping["rs2_p"] = "rs2\\,$'$"
latex_mapping["rd_rs1_n0"] = "rd/rs$\\neq$0"
latex_mapping["rd_rs1_p"] = "rs1\\,$'$/rs2\\,$'$"
latex_mapping["c_rs2"] = "rs2"
latex_mapping["c_rs2_n0"] = "rs2$\\neq$0"
latex_mapping["rd_n0"] = "rd$\\neq$0"
latex_mapping["rs1_n0"] = "rs1$\\neq$0"
latex_mapping["c_rs1_n0"] = "rs1$\\neq$0"
latex_mapping["rd_rs1"] = "rd/rs1"
latex_mapping["zimm6hi"] = "uimm[5]"
latex_mapping["zimm6lo"] = "uimm[4:0]"
latex_mapping["c_nzuimm10"] = "nzuimm[5:4$\\vert$9:6$\\vert$2$\\vert$3]"
latex_mapping["c_uimm7lo"] = "uimm[2$\\vert$6]"
latex_mapping["c_uimm7hi"] = "uimm[5:3]"
latex_mapping["c_uimm8lo"] = "uimm[7:6]"
latex_mapping["c_uimm8hi"] = "uimm[5:3]"
latex_mapping["c_uimm9lo"] = "uimm[7:6]"
latex_mapping["c_uimm9hi"] = "uimm[5:4$\\vert$8]"
latex_mapping["c_nzimm6lo"] = "nzimm[4:0]"
latex_mapping["c_nzimm6hi"] = "nzimm[5]"
latex_mapping["c_imm6lo"] = "imm[4:0]"
latex_mapping["c_imm6hi"] = "imm[5]"
latex_mapping["c_nzimm10hi"] = "nzimm[9]"
latex_mapping["c_nzimm10lo"] = "nzimm[4$\\vert$6$\\vert$8:7$\\vert$5]"
latex_mapping["c_nzimm18hi"] = "nzimm[17]"
latex_mapping["c_nzimm18lo"] = "nzimm[16:12]"
latex_mapping["c_imm12"] = (
"imm[11$\\vert$4$\\vert$9:8$\\vert$10$\\vert$6$\\vert$7$\\vert$3:1$\\vert$5]"
)
latex_mapping["c_bimm9lo"] = "imm[7:6$\\vert$2:1$\\vert$5]"
latex_mapping["c_bimm9hi"] = "imm[8$\\vert$4:3]"
latex_mapping["c_nzuimm5"] = "nzuimm[4:0]"
latex_mapping["c_nzuimm6lo"] = "nzuimm[4:0]"
latex_mapping["c_nzuimm6hi"] = "nzuimm[5]"
latex_mapping["c_uimm8splo"] = "uimm[4:2$\\vert$7:6]"
latex_mapping["c_uimm8sphi"] = "uimm[5]"
latex_mapping["c_uimm8sp_s"] = "uimm[5:2$\\vert$7:6]"
latex_mapping["c_uimm10splo"] = "uimm[4$\\vert$9:6]"
latex_mapping["c_uimm10sphi"] = "uimm[5]"
latex_mapping["c_uimm9splo"] = "uimm[4:3$\\vert$8:6]"
latex_mapping["c_uimm9sphi"] = "uimm[5]"
latex_mapping["c_uimm10sp_s"] = "uimm[5:4$\\vert$9:6]"
latex_mapping["c_uimm9sp_s"] = "uimm[5:3$\\vert$8:6]"
latex_mapping = {
"imm12": "imm[11:0]",
"rs1": "rs1",
"rs2": "rs2",
"rd": "rd",
"imm20": "imm[31:12]",
"bimm12hi": "imm[12$\\vert$10:5]",
"bimm12lo": "imm[4:1$\\vert$11]",
"imm12hi": "imm[11:5]",
"imm12lo": "imm[4:0]",
"jimm20": "imm[20$\\vert$10:1$\\vert$11$\\vert$19:12]",
"zimm": "uimm",
"shamtw": "shamt",
"shamtd": "shamt",
"shamtq": "shamt",
"rd_p": "rd\\,$'$",
"rs1_p": "rs1\\,$'$",
"rs2_p": "rs2\\,$'$",
"rd_rs1_n0": "rd/rs$\\neq$0",
"rd_rs1_p": "rs1\\,$'$/rs2\\,$'$",
"c_rs2": "rs2",
"c_rs2_n0": "rs2$\\neq$0",
"rd_n0": "rd$\\neq$0",
"rs1_n0": "rs1$\\neq$0",
"c_rs1_n0": "rs1$\\neq$0",
"rd_rs1": "rd/rs1",
"zimm6hi": "uimm[5]",
"zimm6lo": "uimm[4:0]",
"c_nzuimm10": "nzuimm[5:4$\\vert$9:6$\\vert$2$\\vert$3]",
"c_uimm7lo": "uimm[2$\\vert$6]",
"c_uimm7hi": "uimm[5:3]",
"c_uimm8lo": "uimm[7:6]",
"c_uimm8hi": "uimm[5:3]",
"c_uimm9lo": "uimm[7:6]",
"c_uimm9hi": "uimm[5:4$\\vert$8]",
"c_nzimm6lo": "nzimm[4:0]",
"c_nzimm6hi": "nzimm[5]",
"c_imm6lo": "imm[4:0]",
"c_imm6hi": "imm[5]",
"c_nzimm10hi": "nzimm[9]",
"c_nzimm10lo": "nzimm[4$\\vert$6$\\vert$8:7$\\vert$5]",
"c_nzimm18hi": "nzimm[17]",
"c_nzimm18lo": "nzimm[16:12]",
"c_imm12": "imm[11$\\vert$4$\\vert$9:8$\\vert$10$\\vert$6$\\vert$7$\\vert$3:1$\\vert$5]",
"c_bimm9lo": "imm[7:6$\\vert$2:1$\\vert$5]",
"c_bimm9hi": "imm[8$\\vert$4:3]",
"c_nzuimm5": "nzuimm[4:0]",
"c_nzuimm6lo": "nzuimm[4:0]",
"c_nzuimm6hi": "nzuimm[5]",
"c_uimm8splo": "uimm[4:2$\\vert$7:6]",
"c_uimm8sphi": "uimm[5]",
"c_uimm8sp_s": "uimm[5:2$\\vert$7:6]",
"c_uimm10splo": "uimm[4$\\vert$9:6]",
"c_uimm10sphi": "uimm[5]",
"c_uimm9splo": "uimm[4:3$\\vert$8:6]",
"c_uimm9sphi": "uimm[5]",
"c_uimm10sp_s": "uimm[5:4$\\vert$9:6]",
"c_uimm9sp_s": "uimm[5:3$\\vert$8:6]",
}

# created a dummy instruction-dictionary like dictionary for all the instruction
# types so that the same logic can be used to create their tables
latex_inst_type = {}
latex_inst_type["R-type"] = {}
latex_inst_type["R-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"rs2",
"funct7",
]
latex_inst_type["R4-type"] = {}
latex_inst_type["R4-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"rs2",
"funct2",
"rs3",
]
latex_inst_type["I-type"] = {}
latex_inst_type["I-type"]["variable_fields"] = [
"opcode",
"rd",
"funct3",
"rs1",
"imm12",
]
latex_inst_type["S-type"] = {}
latex_inst_type["S-type"]["variable_fields"] = [
"opcode",
"imm12lo",
"funct3",
"rs1",
"rs2",
"imm12hi",
]
latex_inst_type["B-type"] = {}
latex_inst_type["B-type"]["variable_fields"] = [
"opcode",
"bimm12lo",
"funct3",
"rs1",
"rs2",
"bimm12hi",
latex_inst_type = {
"R-type": {
"variable_fields": ["opcode", "rd", "funct3", "rs1", "rs2", "funct7"],
},
"R4-type": {
"variable_fields": ["opcode", "rd", "funct3", "rs1", "rs2", "funct2", "rs3"],
},
"I-type": {
"variable_fields": ["opcode", "rd", "funct3", "rs1", "imm12"],
},
"S-type": {
"variable_fields": ["opcode", "imm12lo", "funct3", "rs1", "rs2", "imm12hi"],
},
"B-type": {
"variable_fields": ["opcode", "bimm12lo", "funct3", "rs1", "rs2", "bimm12hi"],
},
"U-type": {
"variable_fields": ["opcode", "rd", "imm20"],
},
"J-type": {
"variable_fields": ["opcode", "rd", "jimm20"],
},
}
latex_fixed_fields = [
(31, 25),
(24, 20),
(19, 15),
(14, 12),
(11, 7),
(6, 0),
]
latex_inst_type["U-type"] = {}
latex_inst_type["U-type"]["variable_fields"] = ["opcode", "rd", "imm20"]
latex_inst_type["J-type"] = {}
latex_inst_type["J-type"]["variable_fields"] = ["opcode", "rd", "jimm20"]
latex_fixed_fields = []
latex_fixed_fields.append((31, 25))
latex_fixed_fields.append((24, 20))
latex_fixed_fields.append((19, 15))
latex_fixed_fields.append((14, 12))
latex_fixed_fields.append((11, 7))
latex_fixed_fields.append((6, 0))

# Pseudo-ops present in the generated encodings.
# By default pseudo-ops are not listed as they are considered aliases
Expand Down
2 changes: 1 addition & 1 deletion go_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s")


def make_go(instr_dict):
def make_go(instr_dict: InstrDict):

args = " ".join(sys.argv)
prelude = f"""// Code generated by {args}; DO NOT EDIT."""
Expand Down
Loading

0 comments on commit 699eb16

Please sign in to comment.