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 27, 2024
1 parent 198e990 commit e61556b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 15 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
5 changes: 3 additions & 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 All @@ -30,6 +29,7 @@ VSIM ?= $(QUESTA_SEPP) vsim
VOPT ?= $(QUESTA_SEPP) vopt
VLOG ?= $(QUESTA_SEPP) vlog
VLIB ?= $(QUESTA_SEPP) vlib
RISCV_MC ?= $(LLVM_BINROOT)/llvm-mc
ADDR2LINE ?= $(LLVM_BINROOT)/llvm-addr2line

# Internal executables
Expand Down Expand Up @@ -93,6 +93,7 @@ VLT_FLAGS += --threads $(VLT_NUM_THREADS)
VLT_CFLAGS += -std=c++20 -pthread
VLT_CFLAGS += -I $(VLT_ROOT)/include -I $(VLT_ROOT)/include/vltstd -I $(VLT_FESVR)/include -I $(TB_DIR) -I ${MKFILE_DIR}test

RISCV_MC_FLAGS ?= -disassemble -mcpu=snitch
ANNOTATE_FLAGS ?= -q --keep-time --addr2line=$(ADDR2LINE)
LAYOUT_EVENTS_FLAGS ?= --cfg=$(CFG)

Expand Down Expand Up @@ -228,7 +229,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) $< --mc-exec $(RISCV_MC) --mc-flags "$(RISCV_MC_FLAGS)" --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: 61 additions & 5 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="-disassemble -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} {mc_flags}",
shell=True,
capture_output=True,
)

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


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,16 @@ 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
match = re.search(DASM_IN_REGEX, line)
if match is not None:
line = re.sub(
DASM_IN_REGEX,
disasm_inst(match.groups()[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 @@ -1104,6 +1138,16 @@ def main():
'--dump-dma-perf',
help='Dump DMA performance metrics as json text.'
)
parser.add_argument(
'--mc-exec',
default='llvm-mc',
help='Path to the llvm-mc executable'
)
parser.add_argument(
'--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 +1174,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.mc_exec,
args.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 +1198,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 e61556b

Please sign in to comment.