-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_definitions.py
More file actions
130 lines (103 loc) · 3.1 KB
/
generate_definitions.py
File metadata and controls
130 lines (103 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import math
pipelines = ["xarith", "xlogic", "xshift", "xmultl", "xmulth", "xdiv"]
xarith_ops = ["add", "slt", "cmp", "branch", "jal", "jalr"]
xlogic_ops = ["and", "or", "xor", "shf", "sla", "clz", "ctz", "pop"]
ahb_htrans = ["idle", "busy", "nonseq", "seq"]
rvfi_metadata = {
"valid": 1,
"order": 64,
"insn": 32,
"trap": 1,
"halt": 1,
"intr": 1,
"mode": 2,
"ixl": 2
}
rvfi_pc = {
"pc_rdata": 64,
"pc_wdata": 64,
}
rvfi_reg = {
"rs1_addr": 5,
"rs2_addr": 5,
"rs1_rdata": 64,
"rs2_rdata": 64,
"rd_addr": 5,
"rd_wdata": 64,
}
bits = lambda n: math.ceil(math.log2(n))
def iota(n):
b = bits(n)
for i in range(n):
yield f"{b}'h{i:x}"
def enum(prefix, l):
width = max(len(s) for s in l)
for name, value in zip(l, iota(len(l))):
name = name.ljust(width)
name = f"{prefix}_{name}".upper()
yield name, value
def rvfi_ports(type, prefix, ports):
for name, length in ports.items():
slice = ""
if length > 1: slice = f"[{str(length - 1).rjust(2)}:0]"
slice = slice.ljust(6)
yield f"{type} {slice} {prefix}_{name}"
rvfi_inputs = lambda ports: rvfi_ports("input wire", "if", ports)
rvfi_regs = lambda ports: rvfi_ports("reg ", "rf", ports)
rvfi_outputs = lambda ports: rvfi_ports("output wire", "of", ports)
def rvfi_defines(name, ports):
s = ""
s += f"`define RVFI_{name.upper()}_INPUTS(i) \\\n"
for i, line in enumerate(rvfi_inputs(ports)):
s += f"\t{line}``i"
if i < len(ports) - 1:
s += ", \\"
s += "\n"
s += "\n"
s += f"`define RVFI_{name.upper()}_REGS(i) \\\n"
for i, line in enumerate(rvfi_regs(ports)):
s += f"\t{line}``i"
if i < len(ports) - 1:
s += ", \\"
s += "\n"
s += "\n"
s += f"`define RVFI_{name.upper()}_OUTPUTS(i) \\\n"
for i, line in enumerate(rvfi_outputs(ports)):
s += f"\t{line}``i"
if i < len(ports) - 1:
s += ", \\"
s += "\n"
s += "\n"
return s
def main():
s = ""
s += "// This file is autogenerated, do not edit.\n"
s += "// Instead modify generate_definitions.py\n"
s += "\n"
s += "`ifndef WARP_DEFINES\n"
s += "`define WARP_DEFINES\n"
s += "\n"
for name, value in enum("pipeline", pipelines):
s += f"`define {name} {value}\n"
s += "\n"
for name, value in enum("xarith_op", xarith_ops):
s += f"`define {name} {value}\n"
s += "\n"
for name, value in enum("xlogic_op", xlogic_ops):
s += f"`define {name} {value}\n"
s += "\n"
for name, value in enum("ahb_htrans", ahb_htrans):
s += f"`define {name} {value}\n"
s += "\n"
s += rvfi_defines("metadata", rvfi_metadata)
s += rvfi_defines("pc", rvfi_pc)
# s += rvfi_defines("reg_addr", rvfi_reg_addr)
# s += rvfi_defines("reg_rdata", rvfi_reg_rdata)
s += rvfi_defines("reg", rvfi_reg)
# misc hardcoded defines
s += "`define CANONICAL_NOP 32'h00000013\n"
s += "\n"
s += "`endif /* WARP_DEFINES */\n"
print(s, end="")
if __name__ == "__main__":
main()