Skip to content

Commit 8ca1d36

Browse files
committed
Various updates from model and dynamic stages
Select Variant for code highlighting and handle unknown instructions. Stages are now dynamic depending on the trace (such as ibex).
1 parent 9ee3f2e commit 8ca1d36

File tree

2 files changed

+35
-25
lines changed

2 files changed

+35
-25
lines changed

pipelineviewer/ibex.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
from attrdict import AttrDict
55

66
class PipelineIbex(Pipeline):
7-
stages = ["IF", "IDEX"]
8-
event_name = {"IF": 0, "IDEX": 1,
9-
"IDEX_MULTCYCLE_START": 2, "IDEX_MULTCYCLE_END": 3}
7+
event_name = {"IF": 0, "IDEX": 1, "WB": 2, "DONE": 3}
108

119
def __init__(self, tracepath):
1210
log = {}
1311

12+
self.hasWritebackStage = False
13+
1414
self.ctf_reader = CTFReader(tracepath)
1515
for event in self.ctf_reader.get_events():
1616
id = 0
@@ -31,14 +31,20 @@ def __init__(self, tracepath):
3131
if "insn_type" in keys:
3232
insn_type = str(event["insn_type"])
3333
log[event["insn_id"]] = AttrDict(
34-
{"pc": pc, "insn_type": insn_type, "insn": insn, "mode": riscv_priv_modes[event["mode"]], "IF": timestamp, "IDEX": None, "end": None})
34+
{"pc": pc, "insn_type": insn_type, "insn": insn, "mode": riscv_priv_modes[event["mode"]], "IF": timestamp, "IDEX": None, "WB": None, "end": None})
3535

3636
elif id_str == "IDEX":
37+
# single cycle idex in the standard pipeline
3738
log[event["insn_id"]]["IDEX"] = event["timestamp"]
38-
log[event["insn_id"]]["end"] = event["timestamp"]
39-
elif id_str == "IDEX_MULTCYCLE_START":
40-
log[event["insn_id"]]["IDEX"] = event["timestamp"]
41-
elif id_str == "IDEX_MULTCYCLE_END":
39+
elif id_str == "WB":
40+
# idex starts in the pipeline with
41+
log[event["insn_id"]]["WB"] = event["timestamp"]
42+
self.hasWritebackStage = True
43+
elif id_str == "DONE":
44+
# idex starts in the pipeline with
4245
log[event["insn_id"]]["end"] = event["timestamp"]
4346

4447
self.log = log
48+
49+
def get_stages(self):
50+
return ["IF", "IDEX", "WB"] if self.hasWritebackStage else ["IF", "IDEX"]

pipelineviewer/main.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from riscvmodel.code import decode
1111
from riscvmodel.model import Model
12-
from riscvmodel.variant import RV32I
12+
from riscvmodel.variant import RV32I, RV32IM, Variant
1313
import pygments
1414
import pygments.lexers
1515
import pygments.formatters
@@ -46,9 +46,11 @@ def render(pipeline, args):
4646

4747
model = Model(RV32I) if "e" in args.format else None
4848

49+
stages = pipeline.get_stages()
50+
4951
header_legend = []
5052
length = 0 # need to keep track separately
51-
for s in pipeline.stages:
53+
for s in stages:
5254
leg = colorama.Style.BRIGHT + \
5355
display[s].fore + display[s].back + \
5456
display[s].char + colorama.Style.RESET_ALL
@@ -57,7 +59,7 @@ def render(pipeline, args):
5759
length += 2+len(display[s].legend)
5860
header_legend.append(leg)
5961
header_legend = " ".join(header_legend)
60-
print(header_legend)
62+
args.outfile.write(header_legend)
6163

6264
col_width = {'m': 1, 'r': 8, 't': 17, 'p': 16, 'i': 20, 'e': 40 }
6365

@@ -96,20 +98,20 @@ def render(pipeline, args):
9698
in_snip = False
9799
line = list("." * args.width)
98100

99-
for s in range(len(pipeline.stages)):
100-
stage = pipeline.stages[s]
101+
for s in range(len(stages)):
102+
stage = stages[s]
101103
if stage in i and i[stage] is not None:
102104
line[i[stage] % args.width] = display[stage].fore + \
103105
display[stage].back + display[stage].char + \
104106
colorama.Style.RESET_ALL
105107
next = s + 1
106-
if next >= len(pipeline.stages) and "end" in i and i["end"] is not None:
108+
if next >= len(stages) and "end" in i and i["end"] is not None:
107109
for x in range(i[stage] + 1, i["end"]+1):
108110
line[x % args.width] = display[stage].fore + \
109111
display[stage].back + "=" + \
110112
colorama.Style.RESET_ALL
111113
continue
112-
next = pipeline.stages[next]
114+
next = stages[next]
113115
if next in i and i[next] is not None:
114116
for x in range(i[stage] + 1, i[next]):
115117
line[x % args.width] = display[stage].fore + \
@@ -129,32 +131,34 @@ def render(pipeline, args):
129131
elif c == "r":
130132
if "end" in i and i["end"]:
131133
count_retired += 1
132-
elif "RE" in pipeline.stages:
134+
elif "RE" in stages:
133135
if i.RE is not None:
134136
count_retired += 1
135-
elif "C" in pipeline.stages:
137+
elif "C" in stages:
136138
if i.C is not None:
137139
count_retired += 1
138140
line += "{:8}".format(count_retired)
139141
width = 8
140142
elif c == "t":
141-
if pipeline.stages[-1] in i and i[pipeline.stages[-1]]:
142-
line += "{:8}-{:8}".format(i[pipeline.stages[0]],
143-
i[pipeline.stages[-1]])
143+
if stages[-1] in i and i[stages[-1]]:
144+
line += "{:8}-{:8}".format(i[stages[0]],
145+
i[stages[-1]])
144146
else:
145-
line += "{:8}---------".format(i[pipeline.stages[0]])
147+
line += "{:8}---------".format(i[stages[0]])
146148
width = 17
147149
elif c == "p":
148150
line += "{:016x}".format(i.pc)
149151
width = 16
150152
elif c == "i" and i.insn:
151-
insn = str(decode(int(i.insn)))
152-
line += pygments.highlight(insn, pygments.lexers.GasLexer(
153-
), pygments.formatters.TerminalFormatter()).strip()
153+
try:
154+
insn = str(decode(int(i.insn), Variant("RV32IMZifencei_Zicsr")))
155+
except:
156+
insn = str(i.insn)
157+
line += pygments.highlight(insn, pygments.lexers.GasLexer(), pygments.formatters.TerminalFormatter()).strip()
154158
width = len(insn)
155159
elif c == "e":
156160
line += colorama.Style.DIM
157-
insn = decode(int(i.insn))
161+
insn = decode(int(i.insn), Variant("RV32IMZifencei_Zicsr"))
158162
inops = insn.inopstr(model)
159163
if len(inops) > 0:
160164
line += "[i] " + inops

0 commit comments

Comments
 (0)