adds Debug tools
This commit is contained in:
parent
c365d4f822
commit
db0d125651
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
/build/
|
/build/
|
||||||
/Debug/
|
|
||||||
.settings
|
.settings
|
||||||
/.venv*
|
/.venv*
|
||||||
/Debug-PA/
|
/Debug-PA/
|
||||||
|
5
Debug/.gitignore
vendored
Normal file
5
Debug/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.log
|
||||||
|
*.dis
|
||||||
|
*.asm
|
||||||
|
*.ll
|
||||||
|
*tcc_*
|
154
Debug/create_reg_traces.py
Normal file
154
Debug/create_reg_traces.py
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def validate_elf_file(filepath: str) -> str:
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
raise argparse.ArgumentTypeError(f"{filepath} is not a valid file.")
|
||||||
|
|
||||||
|
# Use the 'file' command to check if it's an ELF file
|
||||||
|
result = subprocess.run(
|
||||||
|
["file", filepath], capture_output=True, text=True, check=False
|
||||||
|
)
|
||||||
|
if "ELF" not in result.stdout:
|
||||||
|
raise argparse.ArgumentTypeError(f"{filepath} is not a valid ELF file.")
|
||||||
|
|
||||||
|
return filepath
|
||||||
|
|
||||||
|
|
||||||
|
def run_test_and_move_output(elf_file: str, backend: str, isa: str = "tgc5c") -> None:
|
||||||
|
# Call 'test' with the specified backend mode
|
||||||
|
os.chdir(Path(__file__).parent.parent)
|
||||||
|
sim_path = "build/Debug/dbt-rise-tgc/tgc-sim"
|
||||||
|
run_command = [
|
||||||
|
sim_path,
|
||||||
|
"-f",
|
||||||
|
elf_file,
|
||||||
|
"--backend",
|
||||||
|
backend,
|
||||||
|
"--isa",
|
||||||
|
isa,
|
||||||
|
"-p",
|
||||||
|
"build/Debug/dbt-rise-plugins/pctrace/pctrace.so=dbt-rise-tgc/contrib/instr/TGC5C_instr.yaml",
|
||||||
|
"-i",
|
||||||
|
"10000",
|
||||||
|
]
|
||||||
|
print(f"Running: \n{' '.join(run_command)}")
|
||||||
|
try:
|
||||||
|
subprocess.run(run_command, check=False, timeout=10)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print("Execution timed out")
|
||||||
|
|
||||||
|
# Move the output.trc file
|
||||||
|
if os.path.exists("output.trc"):
|
||||||
|
shutil.move("output.trc", f"Debug/{backend}.trc")
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"output.trc does not exist after running with backend {backend}, so it cannot be renamed."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_shortened_diff_files(backend: str) -> None:
|
||||||
|
file1_path = "Debug/interp.trc"
|
||||||
|
file2_path = f"Debug/{backend}.trc"
|
||||||
|
|
||||||
|
def validate_file(filepath: str) -> str:
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
raise ValueError(f"{filepath} is not a valid file.")
|
||||||
|
return filepath
|
||||||
|
|
||||||
|
file1_path = validate_file(file1_path)
|
||||||
|
file2_path = validate_file(file2_path)
|
||||||
|
|
||||||
|
with open(file1_path, "r", encoding="utf8") as file1, open(
|
||||||
|
file2_path, "r", encoding="utf8"
|
||||||
|
) as file2:
|
||||||
|
lines1 = file1.readlines()
|
||||||
|
lines2 = file2.readlines()
|
||||||
|
|
||||||
|
diff_index = -1
|
||||||
|
for index, (line1, line2) in enumerate(zip(lines1, lines2)):
|
||||||
|
if line1 != line2:
|
||||||
|
diff_index = index
|
||||||
|
break
|
||||||
|
|
||||||
|
if diff_index == -1:
|
||||||
|
print("The files are identical.")
|
||||||
|
return
|
||||||
|
|
||||||
|
start_index = max(0, diff_index - 5)
|
||||||
|
end_index = min(len(lines1), diff_index + 6)
|
||||||
|
|
||||||
|
shortened_lines1 = lines1[start_index:end_index]
|
||||||
|
shortened_lines2 = lines2[start_index:end_index]
|
||||||
|
|
||||||
|
with open("Debug/short_interp.trc", "w", encoding="utf8") as short_file1:
|
||||||
|
short_file1.writelines(shortened_lines1)
|
||||||
|
|
||||||
|
with open(f"Debug/short_{backend}.trc", "w", encoding="utf8") as short_file2:
|
||||||
|
short_file2.writelines(shortened_lines2)
|
||||||
|
|
||||||
|
|
||||||
|
def create_disassembly(elf_file_path: str) -> None:
|
||||||
|
def validate_file(filepath: str) -> str:
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
raise ValueError(f"{filepath} is not a valid file.")
|
||||||
|
return filepath
|
||||||
|
|
||||||
|
elf_file_path = validate_file(elf_file_path)
|
||||||
|
|
||||||
|
output_file_path = "Debug/dut.dis"
|
||||||
|
with open(output_file_path, "w", encoding="utf8") as output_file:
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"riscv64-unknown-elf-objdump",
|
||||||
|
"-d",
|
||||||
|
"-Mnumeric",
|
||||||
|
"-Mno-aliases",
|
||||||
|
elf_file_path,
|
||||||
|
],
|
||||||
|
stdout=output_file,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main(args: argparse.Namespace) -> None:
|
||||||
|
elf_file = args.elf_file
|
||||||
|
backend = args.backend
|
||||||
|
isa = args.isa
|
||||||
|
|
||||||
|
# Set environment variable
|
||||||
|
os.environ["REGDUMP"] = "True"
|
||||||
|
|
||||||
|
# Run the tests and move the output files
|
||||||
|
run_test_and_move_output(elf_file, "interp", isa)
|
||||||
|
run_test_and_move_output(elf_file, backend, isa)
|
||||||
|
create_shortened_diff_files(backend)
|
||||||
|
create_disassembly(elf_file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Process an ELF file with a specified backend. Generates register traces for interp and the specified backend"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"elf_file", type=validate_elf_file, help="The ELF file to be processed."
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--backend",
|
||||||
|
type=str,
|
||||||
|
default="amsjit",
|
||||||
|
help="The backend to be used. Default is amsjit.",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--isa",
|
||||||
|
type=str,
|
||||||
|
default="tgc5c",
|
||||||
|
help="The isa to be used. Default 'tgc5c'",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
main(args=parser.parse_args())
|
43
Debug/offsets.txt
Normal file
43
Debug/offsets.txt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
X0 (zero) : 0 (0x00)
|
||||||
|
X1 (ra) : 4 (0x04)
|
||||||
|
X2 (sp) : 8 (0x08)
|
||||||
|
X3 (gp) : 12 (0x0c)
|
||||||
|
X4 (tp) : 16 (0x10)
|
||||||
|
X5 (t0) : 20 (0x14)
|
||||||
|
X6 (t1) : 24 (0x18)
|
||||||
|
X7 (t2) : 28 (0x1c)
|
||||||
|
X8 (s0/fp): 32 (0x20)
|
||||||
|
X9 (s1) : 36 (0x24)
|
||||||
|
X10 (a0) : 40 (0x28)
|
||||||
|
X11 (a1) : 44 (0x2c)
|
||||||
|
X12 (a2) : 48 (0x30)
|
||||||
|
X13 (a3) : 52 (0x34)
|
||||||
|
X14 (a4) : 56 (0x38)
|
||||||
|
X15 (a5) : 60 (0x3c)
|
||||||
|
X16 (a6) : 64 (0x40)
|
||||||
|
X17 (a7) : 68 (0x44)
|
||||||
|
X18 (s2) : 72 (0x48)
|
||||||
|
X19 (s3) : 76 (0x4c)
|
||||||
|
X20 (s4) : 80 (0x50)
|
||||||
|
X21 (s5) : 84 (0x54)
|
||||||
|
X22 (s6) : 88 (0x58)
|
||||||
|
X23 (s7) : 92 (0x5c)
|
||||||
|
X24 (s8) : 96 (0x60)
|
||||||
|
X25 (s9) : 100 (0x64)
|
||||||
|
X26 (s10) : 104 (0x68)
|
||||||
|
X27 (s11) : 108 (0x6c)
|
||||||
|
X28 (t3) : 112 (0x70)
|
||||||
|
X29 (t4) : 116 (0x74)
|
||||||
|
X30 (t5) : 120 (0x78)
|
||||||
|
X31 (t6) : 124 (0x7c)
|
||||||
|
PC : 128 (0x80)
|
||||||
|
NEXT_PC : 132 (0x84)
|
||||||
|
PRIV : 136 (0x88)
|
||||||
|
DPC : 137 (0x89)
|
||||||
|
trap_state : 141 (0x8d)
|
||||||
|
pending_trap : 145 (0x91)
|
||||||
|
icount : 149 (0x95)
|
||||||
|
cycle : 157 (0x9d)
|
||||||
|
instret : 165 (0xa5)
|
||||||
|
instruction : 173 (0xad)
|
||||||
|
last_branch : 177 (0xb1)
|
29
Debug/simplify_sail_trace.py
Normal file
29
Debug/simplify_sail_trace.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def simplify_trace(input_file, output_file):
|
||||||
|
with open(input_file, "r") as infile, open(output_file, "w") as outfile:
|
||||||
|
for line in infile:
|
||||||
|
# Enhanced regex to match the instruction number, mode, and PC
|
||||||
|
match = re.search(r"\[\d+\] \[[MI]\]: (0x[0-9A-Fa-f]+)", line)
|
||||||
|
if match:
|
||||||
|
pc = match.group(1).lower()
|
||||||
|
outfile.write(f"{pc}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Simplify a trace from an instruction set simulator."
|
||||||
|
)
|
||||||
|
parser.add_argument("input_file", type=str, help="The input trace file")
|
||||||
|
parser.add_argument(
|
||||||
|
"output_file", type=str, help="The output file for the simplified trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
simplify_trace(args.input_file, args.output_file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
26
Debug/simplify_tgc_trace.py
Normal file
26
Debug/simplify_tgc_trace.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
def simplify_trace(input_file, output_file):
|
||||||
|
with open(input_file, "r") as infile, open(output_file, "w") as outfile:
|
||||||
|
for line in infile:
|
||||||
|
# Split the line by the first comma and take the PC part
|
||||||
|
pc = line.split(",")[0].strip().lower()
|
||||||
|
outfile.write(f"{pc}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Simplify traces from instruction set simulators."
|
||||||
|
)
|
||||||
|
parser.add_argument("input_file", type=str, help="The input trace file")
|
||||||
|
parser.add_argument(
|
||||||
|
"output_file", type=str, help="The output file for the simplified trace"
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
simplify_trace(args.input_file, args.output_file)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user