Skip to content

Commit

Permalink
util: Get rid of spike-dasm in favor of llvm-mc
Browse files Browse the repository at this point in the history
  • Loading branch information
fischeti committed Aug 26, 2024
1 parent 198e990 commit 0147f40
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
8 changes: 0 additions & 8 deletions iis-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,3 @@ rm -rf tmp

# Install local packages in editable mode.
pip install -e .

# Install spike-dasm
mkdir tools/
cd tools/
wget https://raw.githubusercontent.com/pulp-platform/riscv-isa-sim/snitch/iis-install-spike-dasm.sh
chmod +x iis-install-spike-dasm.sh && ./iis-install-spike-dasm.sh && rm iis-install-spike-dasm.sh
cd -
export PATH=$(pwd)/tools:$PATH
3 changes: 1 addition & 2 deletions target/common/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ VERILATOR_SEPP ?=

# External executables
BENDER ?= bender
DASM ?= spike-dasm
VLT ?= $(VERILATOR_SEPP) verilator
VCS ?= $(VCS_SEPP) vcs
VERIBLE_FMT ?= verible-verilog-format
Expand Down Expand Up @@ -228,7 +227,7 @@ clean-visual-trace:
rm -f $(VISUAL_TRACE)

$(addprefix $(LOGS_DIR)/,trace_hart_%.txt hart_%_perf.json dma_%_perf.json): $(LOGS_DIR)/trace_hart_%.dasm $(GENTRACE_PY)
$(DASM) < $< | $(GENTRACE_PY) --permissive --dma-trace $(SIM_DIR)/dma_trace_$*_00000.log --dump-hart-perf $(LOGS_DIR)/hart_$*_perf.json --dump-dma-perf $(LOGS_DIR)/dma_$*_perf.json -o $(LOGS_DIR)/trace_hart_$*.txt
$(GENTRACE_PY) < $< --permissive --dma-trace $(SIM_DIR)/dma_trace_$*_00000.log --dump-hart-perf $(LOGS_DIR)/hart_$*_perf.json --dump-dma-perf $(LOGS_DIR)/dma_$*_perf.json -o $(LOGS_DIR)/trace_hart_$*.txt

# Generate source-code interleaved traces for all harts. Reads the binary from
# the logs/.rtlbinary file that is written at start of simulation in the vsim script
Expand Down
66 changes: 60 additions & 6 deletions util/trace/gen_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,23 @@
import sys
import re
import argparse
import subprocess
import json
import ast
from ctypes import c_int32, c_uint32
from collections import deque, defaultdict
from pathlib import Path
import traceback
from itertools import tee, islice, chain
from functools import lru_cache

EXTRA_WB_WARN = 'WARNING: {} transactions still in flight for {}.'

GENERAL_WARN = """WARNING: Inconsistent final state; performance metrics
may be inaccurate. Is this trace complete?\n"""

DASM_IN_REGEX = r'DASM\(([0-9a-fA-F]+)\)'

TRACE_IN_REGEX = r'(\d+)\s+(\d+)\s+(\d+)\s+(0x[0-9A-Fa-fz]+)\s+([^#;]*)(\s*#;\s*(.*))?'

TRACE_OUT_FMT = '{:>8} {:>8} {:>8} {:>10} {:<30}'
Expand Down Expand Up @@ -351,6 +355,25 @@ def load_opcodes():
_cached_opcodes[insn_name] = vec_params


@lru_cache
def disasm_inst(hex_inst, mc_exec="llvm-mc", mc_flags="-mcpu=snitch"):
"""Disassemble a single RISC-V instruction using llvm-mc."""
# Reverse the endianness of the hex instruction
inst_fmt = " ".join(
[f"0x{hex_inst[i:i+2]}" for i in range(0, len(hex_inst), 2)][::-1]
)

# Use llvm-mc to disassemble the binary instruction
result = subprocess.run(
f"echo {inst_fmt} | {mc_exec} -disassemble {mc_flags}",
shell=True,
capture_output=True,
)

# Extract disassembled instruction from llvm-mc output
return result.stdout.decode().splitlines()[-1].strip()


def flt_op_vlen(insn: str, op_type: str) -> int:
"""Get the vector length of a floating-point instruction operand.
Expand Down Expand Up @@ -883,6 +906,8 @@ def annotate_insn(
fseq_info:
dict, # Info on the sequencer to properly map tunneled instruction PCs
perf_metrics: list, # A list performance metric dicts
mc_exec: str, # Path to the llvm-mc executable
mc_flags: str, # Flags to pass to the llvm-mc executable
dupl_time_info:
bool = True, # Show sim time and cycle again if same as previous line?
last_time_info:
Expand All @@ -894,7 +919,14 @@ def annotate_insn(
dma_trans: list = []
) -> (str, tuple, bool
): # Return time info, whether trace line contains no info, and fseq_len
match = re.search(TRACE_IN_REGEX, line.strip('\n'))

# Disassemble instruction
line = re.sub(
DASM_IN_REGEX,
disasm_inst(re.findall(DASM_IN_REGEX, line)[0], mc_exec, mc_flags),
line,
)
match = re.search(TRACE_IN_REGEX, line.strip("\n"))
if match is None:
raise ValueError('Not a valid trace line:\n{}'.format(line))
time_str, cycle_str, priv_lvl, pc_str, insn, _, extras_str = match.groups()
Expand Down Expand Up @@ -1057,7 +1089,7 @@ def main():
# Argument parsing and iterator creation
parser = argparse.ArgumentParser()
parser.add_argument(
'infile',
'--infile',
metavar='infile.dasm',
nargs='?',
type=argparse.FileType('r'),
Expand Down Expand Up @@ -1104,6 +1136,16 @@ def main():
'--dump-dma-perf',
help='Dump DMA performance metrics as json text.'
)
parser.add_argument(
'--llvm-mc-exec',
default='llvm-mc',
help='Path to the llvm-mc executable'
)
parser.add_argument(
'--llvm-mc-flags',
default='-mcpu=snitch',
help='Flags to pass to the llvm-mc executable'
)

args = parser.parse_args()
line_iter = iter(args.infile.readline, b'')
Expand All @@ -1130,9 +1172,21 @@ def main():
if line:
try:
ann_insn, time_info, empty = annotate_insn(
line, gpr_wb_info, fpr_wb_info, fseq_info, perf_metrics, False,
time_info, args.offl, not args.saddr, args.permissive, dma_trans)
if perf_metrics[0]['start'] is None:
line,
gpr_wb_info,
fpr_wb_info,
fseq_info,
perf_metrics,
args.llvm_mc_exec,
args.llvm_mc_flags,
False,
time_info,
args.offl,
not args.saddr,
args.permissive,
dma_trans,
)
if perf_metrics[0]["start"] is None:
perf_metrics[0]['tstart'] = time_info[0] / 1000
perf_metrics[0]['start'] = time_info[1]
if not empty:
Expand All @@ -1142,7 +1196,7 @@ def main():
if not nextl:
message += 'last line. Did the simulation terminate?'
else:
message += 'line {lineno}.'
message += f'line {lineno}.'
print(traceback.format_exc(), file=sys.stderr)
print(message, file=sys.stderr)
return 1
Expand Down

0 comments on commit 0147f40

Please sign in to comment.