Skip to content

Commit ed8ff26

Browse files
committedSep 16, 2020
Convert code to be PEP8 compliant
1 parent b740af3 commit ed8ff26

10 files changed

+2718
-2535
lines changed
 

‎cov.py

+283-258
Large diffs are not rendered by default.

‎run.py

+998-923
Large diffs are not rendered by default.

‎scripts/gen_csr_test.py

+301-266
Large diffs are not rendered by default.

‎scripts/instr_trace_compare.py

+235-224
Large diffs are not rendered by default.

‎scripts/lib.py

+360-346
Large diffs are not rendered by default.

‎scripts/ovpsim_log_to_trace_csv.py

+169-159
Original file line numberDiff line numberDiff line change
@@ -27,186 +27,196 @@
2727
from riscv_trace_csv import *
2828

2929
INSTR_RE = re.compile(r"riscvOVPsim.*, 0x(?P<addr>.*?)(?P<section>\(.*\): ?)" \
30-
"(?P<mode>[A-Za-z]*?)\s+(?P<bin>[a-f0-9]*?)\s+(?P<instr_str>.*?)$")
30+
"(?P<mode>[A-Za-z]*?)\s+(?P<bin>[a-f0-9]*?)\s+(?P<instr_str>.*?)$")
3131
RD_RE = re.compile(r" (?P<r>[a-z]*[0-9]{0,2}?) (?P<pre>[a-f0-9]+?)" \
32-
" -> (?P<val>[a-f0-9]+?)$")
33-
BASE_RE = re.compile(r"(?P<rd>[a-z0-9]+?),(?P<imm>[\-0-9]*?)\((?P<rs1>[a-z0-9]+?)\)")
32+
" -> (?P<val>[a-f0-9]+?)$")
33+
BASE_RE = re.compile(
34+
r"(?P<rd>[a-z0-9]+?),(?P<imm>[\-0-9]*?)\((?P<rs1>[a-z0-9]+?)\)")
35+
3436

3537
def convert_mode(pri, line, stop_on_first_error=False):
36-
""" OVPsim uses text string, convert to numeric """
37-
if "Machine" in pri: return str(3)
38-
if "Supervisor" in pri: return str(1)
39-
if "User" in pri: return str(0)
40-
logging.error("convert_mode = UNKNOWN PRIV MODE [%s]: %s" % (pri, line))
41-
if stop_on_first_error:
42-
sys.exit(RET_FATAL)
38+
""" OVPsim uses text string, convert to numeric """
39+
if "Machine" in pri:
40+
return str(3)
41+
if "Supervisor" in pri:
42+
return str(1)
43+
if "User" in pri:
44+
return str(0)
45+
logging.error("convert_mode = UNKNOWN PRIV MODE [{}]: {}".format(pri, line))
46+
if stop_on_first_error:
47+
sys.exit(RET_FATAL)
48+
4349

4450
def is_csr(r):
45-
""" see if r is a csr """
46-
if len(r) > 4:
47-
return True
48-
elif r[0] in ["m", "u", "d"]:
49-
return True
50-
elif r in ["frm", "fcsr", "vl", "satp"]:
51-
return True
52-
else:
53-
return False
51+
""" see if r is a csr """
52+
if len(r) > 4:
53+
return True
54+
elif r[0] in ["m", "u", "d"]:
55+
return True
56+
elif r in ["frm", "fcsr", "vl", "satp"]:
57+
return True
58+
else:
59+
return False
60+
5461

5562
def process_ovpsim_sim_log(ovpsim_log, csv,
56-
stop_on_first_error = 0,
57-
dont_truncate_after_first_ecall = 0,
58-
full_trace = True):
59-
"""Process OVPsim simulation log.
60-
61-
Extract instruction and affected register information from ovpsim simulation
62-
log and save to a list.
63-
"""
64-
logging.info("Processing ovpsim log : %s" % ovpsim_log)
65-
66-
# Remove the header part of ovpsim log
67-
cmd = ("sed -i '/Info 1:/,$!d' %s" % ovpsim_log)
68-
os.system(cmd)
69-
# Remove all instructions after end of trace data (end of program excecution)
70-
if dont_truncate_after_first_ecall:
71-
cmd = ("sed -i '/^Info --/q' %s" % ovpsim_log)
72-
logging.info("Dont truncate logfile after first ecall: %s", ovpsim_log)
73-
else:
74-
cmd = ("sed -i '/ecall/q' %s" % ovpsim_log)
75-
os.system(cmd)
76-
77-
instr_cnt = 0
78-
with open(ovpsim_log, "r") as f, open(csv, "w") as csv_fd:
79-
trace_csv = RiscvInstructionTraceCsv(csv_fd)
80-
trace_csv.start_new_trace()
81-
prev_trace = 0
82-
for line in f:
83-
# Extract instruction infromation
84-
m = INSTR_RE.search(line)
85-
if m:
86-
if prev_trace: # write out the previous one when find next one
87-
trace_csv.write_trace_entry(prev_trace)
88-
instr_cnt += 1
89-
prev_trace = 0
90-
prev_trace = RiscvInstructionTraceEntry()
91-
prev_trace.instr_str = m.group("instr_str")
92-
prev_trace.pc = m.group("addr")
93-
prev_trace.mode = convert_mode(m.group("mode"), line)
94-
prev_trace.binary = m.group("bin")
95-
if full_trace:
96-
prev_trace.instr = prev_trace.instr_str.split(" ")[0]
97-
prev_trace.operand = prev_trace.instr_str[len(prev_trace.instr):]
98-
prev_trace.operand = prev_trace.operand.replace(" ", "")
99-
process_trace(prev_trace)
100-
continue
101-
# Extract register change value information
102-
c = RD_RE.search(line)
103-
if c:
104-
if is_csr(c.group("r")):
105-
prev_trace.csr.append(c.group("r") + ":" + c.group("val"))
106-
else:
107-
prev_trace.gpr.append(c.group("r") + ":" + c.group("val"))
108-
logging.info("Processed instruction count : %d " % instr_cnt)
109-
if instr_cnt == 0:
110-
logging.error ("No Instructions in logfile: %s" % ovpsim_log)
111-
sys.exit(RET_FATAL)
112-
logging.info("CSV saved to : %s" % csv)
63+
stop_on_first_error=0,
64+
dont_truncate_after_first_ecall=0,
65+
full_trace=True):
66+
"""Process OVPsim simulation log.
67+
68+
Extract instruction and affected register information from ovpsim simulation
69+
log and save to a list.
70+
"""
71+
logging.info("Processing ovpsim log : {}".format(ovpsim_log))
72+
73+
# Remove the header part of ovpsim log
74+
cmd = ("sed -i '/Info 1:/,$!d' {}".format(ovpsim_log))
75+
os.system(cmd)
76+
# Remove all instructions after end of trace data (end of program excecution)
77+
if dont_truncate_after_first_ecall:
78+
cmd = ("sed -i '/^Info --/q' {}".format(ovpsim_log))
79+
logging.info("Dont truncate logfile after first ecall: {}".format(ovpsim_log))
80+
else:
81+
cmd = ("sed -i '/ecall/q' {}".format(ovpsim_log))
82+
os.system(cmd)
83+
84+
instr_cnt = 0
85+
with open(ovpsim_log, "r") as f, open(csv, "w") as csv_fd:
86+
trace_csv = RiscvInstructionTraceCsv(csv_fd)
87+
trace_csv.start_new_trace()
88+
prev_trace = 0
89+
for line in f:
90+
# Extract instruction infromation
91+
m = INSTR_RE.search(line)
92+
if m:
93+
if prev_trace: # write out the previous one when find next one
94+
trace_csv.write_trace_entry(prev_trace)
95+
instr_cnt += 1
96+
prev_trace = 0
97+
prev_trace = RiscvInstructionTraceEntry()
98+
prev_trace.instr_str = m.group("instr_str")
99+
prev_trace.pc = m.group("addr")
100+
prev_trace.mode = convert_mode(m.group("mode"), line)
101+
prev_trace.binary = m.group("bin")
102+
if full_trace:
103+
prev_trace.instr = prev_trace.instr_str.split(" ")[0]
104+
prev_trace.operand = prev_trace.instr_str[
105+
len(prev_trace.instr):]
106+
prev_trace.operand = prev_trace.operand.replace(" ", "")
107+
process_trace(prev_trace)
108+
continue
109+
# Extract register change value information
110+
c = RD_RE.search(line)
111+
if c:
112+
if is_csr(c.group("r")):
113+
prev_trace.csr.append(c.group("r") + ":" + c.group("val"))
114+
else:
115+
prev_trace.gpr.append(c.group("r") + ":" + c.group("val"))
116+
logging.info("Processed instruction count : {} ".format(instr_cnt))
117+
if instr_cnt == 0:
118+
logging.error("No Instructions in logfile: {}".format(ovpsim_log))
119+
sys.exit(RET_FATAL)
120+
logging.info("CSV saved to : {}".format(csv))
113121

114122

115123
def process_trace(trace):
116-
""" Process instruction operands """
117-
process_compressed_instr(trace)
118-
process_imm(trace)
119-
if trace.instr == "jalr":
120-
process_jalr(trace)
121-
trace.instr, trace.operand = convert_pseudo_instr(
122-
trace.instr, trace.operand, trace.binary)
123-
trace.operand = trace.operand.replace(")", "")
124-
trace.operand = trace.operand.replace("(", ",")
124+
""" Process instruction operands """
125+
process_compressed_instr(trace)
126+
process_imm(trace)
127+
if trace.instr == "jalr":
128+
process_jalr(trace)
129+
trace.instr, trace.operand = convert_pseudo_instr(
130+
trace.instr, trace.operand, trace.binary)
131+
trace.operand = trace.operand.replace(")", "")
132+
trace.operand = trace.operand.replace("(", ",")
125133

126134

127135
def process_imm(trace):
128-
""" Process imm to follow RISC-V standard convention """
129-
if trace.instr in ['beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu', 'c.beqz',
130-
'c.bnez', 'beqz', 'bnez', 'bgez', 'bltz', 'blez', 'bgtz'
131-
'c.j', "j", "c.jal", "jal"]:
132-
# convert from ovpsim logs branch/jump offsets as absolute to relative
133-
idx = trace.operand.rfind(",")
134-
if idx == -1:
135-
imm = trace.operand
136-
imm = str(sint_to_hex(int(imm, 16) - int(trace.pc, 16)))
137-
trace.operand = imm
138-
else:
139-
imm = trace.operand[idx+1:]
140-
imm = str(sint_to_hex(int(imm, 16) - int(trace.pc, 16)))
141-
trace.operand = trace.operand[0:idx+1] + imm
136+
""" Process imm to follow RISC-V standard convention """
137+
if trace.instr in ['beq', 'bne', 'blt', 'bge', 'bltu', 'bgeu', 'c.beqz',
138+
'c.bnez', 'beqz', 'bnez', 'bgez', 'bltz', 'blez', 'bgtz',
139+
'c.j','j', 'c.jal', 'jal']:
140+
# convert from ovpsim logs branch/jump offsets as absolute to relative
141+
idx = trace.operand.rfind(",")
142+
if idx == -1:
143+
imm = trace.operand
144+
imm = str(sint_to_hex(int(imm, 16) - int(trace.pc, 16)))
145+
trace.operand = imm
146+
else:
147+
imm = trace.operand[idx + 1:]
148+
imm = str(sint_to_hex(int(imm, 16) - int(trace.pc, 16)))
149+
trace.operand = trace.operand[0:idx + 1] + imm
142150

143151

144152
def process_jalr(trace):
145-
""" process jalr """
146-
## jalr x3
147-
## jalr 9(x3)
148-
## jalr x2,x3
149-
## jalr x2,4(x3)
150-
idx = trace.operand.rfind(",")
151-
if idx == -1:
152-
# Add default destination register : ra
153-
trace.operand = "ra," + trace.operand
154-
m = BASE_RE.search(trace.operand)
155-
if m:
156-
# Convert pseudo JALR format to normal format
157-
trace.operand = "%s,%s,%s" % (m.group("rd"), m.group("rs1"), m.group("imm"))
158-
else:
159-
# Add default imm 0
160-
trace.operand = trace.operand + ",0"
153+
""" process jalr """
154+
## jalr x3
155+
## jalr 9(x3)
156+
## jalr x2,x3
157+
## jalr x2,4(x3)
158+
idx = trace.operand.rfind(",")
159+
if idx == -1:
160+
# Add default destination register : ra
161+
trace.operand = "ra," + trace.operand
162+
m = BASE_RE.search(trace.operand)
163+
if m:
164+
# Convert pseudo JALR format to normal format
165+
trace.operand = "{},{},{}".format(
166+
m.group("rd"), m.group("rs1"), m.group("imm"))
167+
else:
168+
# Add default imm 0
169+
trace.operand = trace.operand + ",0"
161170

162171

163172
def process_compressed_instr(trace):
164-
""" convert naming for compressed instructions """
165-
trace_binary = int(trace.binary, 16)
166-
o = trace.operand.split(",")
167-
if len(trace.binary) == 4: # compressed are always 4 hex digits
168-
trace.instr = "c." + trace.instr
169-
if ("sp,sp," in trace.operand) and (trace.instr == "c.addi"):
170-
trace.instr = "c.addi16sp"
171-
idx = trace.operand.rfind(",")
172-
trace.operand = "sp," + trace.operand[idx+1:]
173-
elif (",sp," in trace.operand) and (trace.instr == "c.addi"):
174-
trace.instr = "c.addi4spn"
175-
elif ("(sp)" in trace.operand) and (trace_binary % 4 != 0):
176-
trace.instr = trace.instr + "sp"
177-
if not ("(" in trace.operand):
178-
# OVPSIM use non-compressed instruction format in the trace,
179-
# need to remove duplicated rs1/rd
180-
if len(o) > 2:
181-
trace.operand = ",".join(o[1:])
182-
if trace.instr == "c.jal":
183-
trace.operand = o[1]
173+
""" convert naming for compressed instructions """
174+
trace_binary = int(trace.binary, 16)
175+
o = trace.operand.split(",")
176+
if len(trace.binary) == 4: # compressed are always 4 hex digits
177+
trace.instr = "c." + trace.instr
178+
if ("sp,sp," in trace.operand) and (trace.instr == "c.addi"):
179+
trace.instr = "c.addi16sp"
180+
idx = trace.operand.rfind(",")
181+
trace.operand = "sp," + trace.operand[idx + 1:]
182+
elif (",sp," in trace.operand) and (trace.instr == "c.addi"):
183+
trace.instr = "c.addi4spn"
184+
elif ("(sp)" in trace.operand) and (trace_binary % 4 != 0):
185+
trace.instr = trace.instr + "sp"
186+
if not ("(" in trace.operand):
187+
# OVPSIM use non-compressed instruction format in the trace,
188+
# need to remove duplicated rs1/rd
189+
if len(o) > 2:
190+
trace.operand = ",".join(o[1:])
191+
if trace.instr == "c.jal":
192+
trace.operand = o[1]
184193

185194

186195
def main():
187-
""" if used standalone set up for testing """
188-
# Parse input arguments
189-
parser = argparse.ArgumentParser()
190-
parser.add_argument("--log", type=str, help="Input ovpsim simulation log")
191-
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
192-
parser.add_argument("--verbose", dest="verbose", action="store_true",
193-
help="Verbose logging")
194-
parser.add_argument("--stop_on_first_error", dest="stop_on_first_error",
195-
action="store_true",
196-
help="Stop on first error")
197-
parser.add_argument("--dont_truncate_after_first_ecall",
198-
dest="dont_truncate_after_first_ecall",
199-
action="store_true",
200-
help="Dont truncate on first ecall")
201-
parser.set_defaults(verbose=False)
202-
parser.set_defaults(stop_on_first_error=False)
203-
parser.set_defaults(dont_truncate_after_first_ecall=False)
204-
args = parser.parse_args()
205-
# Process ovpsim log
206-
process_ovpsim_sim_log(args.log,
207-
args.csv,
208-
args.stop_on_first_error,
209-
args.dont_truncate_after_first_ecall)
196+
""" if used standalone set up for testing """
197+
# Parse input arguments
198+
parser = argparse.ArgumentParser()
199+
parser.add_argument("--log", type=str, help="Input ovpsim simulation log")
200+
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
201+
parser.add_argument("--verbose", dest="verbose", action="store_true",
202+
help="Verbose logging")
203+
parser.add_argument("--stop_on_first_error", dest="stop_on_first_error",
204+
action="store_true",
205+
help="Stop on first error")
206+
parser.add_argument("--dont_truncate_after_first_ecall",
207+
dest="dont_truncate_after_first_ecall",
208+
action="store_true",
209+
help="Dont truncate on first ecall")
210+
parser.set_defaults(verbose=False)
211+
parser.set_defaults(stop_on_first_error=False)
212+
parser.set_defaults(dont_truncate_after_first_ecall=False)
213+
args = parser.parse_args()
214+
# Process ovpsim log
215+
process_ovpsim_sim_log(args.log,
216+
args.csv,
217+
args.stop_on_first_error,
218+
args.dont_truncate_after_first_ecall)
219+
210220

211221
if __name__ == "__main__":
212-
main()
222+
main()

‎scripts/riscv_trace_csv.py

+72-69
Original file line numberDiff line numberDiff line change
@@ -22,77 +22,80 @@
2222
import sys
2323
from lib import *
2424

25+
2526
class RiscvInstructionTraceEntry(object):
26-
"""RISC-V instruction trace entry"""
27-
def __init__(self):
28-
self.gpr = []
29-
self.csr = []
30-
self.instr = ""
31-
self.operand = ""
32-
self.pc = ""
33-
self.binary = ""
34-
self.instr_str = ""
35-
self.mode = ""
36-
37-
def get_trace_string(self):
38-
"""Return a short string of the trace entry"""
39-
return ("pc[%s] %s: %s %s" %
40-
(self.pc, self.instr_str, " ".join(self.gpr), " ".join(self.csr)))
27+
"""RISC-V instruction trace entry"""
28+
29+
def __init__(self):
30+
self.gpr = []
31+
self.csr = []
32+
self.instr = ""
33+
self.operand = ""
34+
self.pc = ""
35+
self.binary = ""
36+
self.instr_str = ""
37+
self.mode = ""
38+
39+
def get_trace_string(self):
40+
"""Return a short string of the trace entry"""
41+
return ("pc[{}] {}: {} {}".format(
42+
self.pc, self.instr_str, " ".join(self.gpr), " ".join(self.csr)))
43+
4144

4245
class RiscvInstructionTraceCsv(object):
43-
"""RISC-V instruction trace CSV class
44-
45-
This class provides functions to read/write trace CSV
46-
"""
47-
def __init__(self, csv_fd):
48-
self.csv_fd = csv_fd
49-
50-
51-
def start_new_trace(self):
52-
"""Create a CSV file handle for a new trace"""
53-
fields = [
54-
"pc", "instr", "gpr", "csr", "binary", "mode", "instr_str", "operand", "pad"]
55-
self.csv_writer = csv.DictWriter(self.csv_fd, fieldnames=fields)
56-
self.csv_writer.writeheader()
57-
58-
59-
def read_trace(self, trace):
60-
"""Read instruction trace from CSV file"""
61-
csv_reader = csv.DictReader(self.csv_fd)
62-
for row in csv_reader:
63-
new_trace = RiscvInstructionTraceEntry()
64-
new_trace.gpr = row['gpr'].split(';')
65-
new_trace.csr = row['csr'].split(';')
66-
new_trace.pc = row['pc']
67-
new_trace.operand = row['operand']
68-
new_trace.binary = row['binary']
69-
new_trace.instr_str = row['instr_str']
70-
new_trace.instr = row['instr']
71-
new_trace.mode = row['mode']
72-
trace.append(new_trace)
73-
74-
# TODO: Convert pseudo instruction to regular instruction
75-
76-
def write_trace_entry(self, entry):
77-
"""Write a new trace entry to CSV"""
78-
self.csv_writer.writerow({'instr_str' : entry.instr_str,
79-
'gpr' : ";".join(entry.gpr),
80-
'csr' : ";".join(entry.csr),
81-
'operand' : entry.operand,
82-
'pc' : entry.pc,
83-
'binary' : entry.binary,
84-
'instr' : entry.instr,
85-
'mode' : entry.mode})
46+
"""RISC-V instruction trace CSV class
47+
48+
This class provides functions to read/write trace CSV
49+
"""
50+
51+
def __init__(self, csv_fd):
52+
self.csv_fd = csv_fd
53+
54+
def start_new_trace(self):
55+
"""Create a CSV file handle for a new trace"""
56+
fields = ["pc", "instr", "gpr", "csr", "binary", "mode", "instr_str",
57+
"operand", "pad"]
58+
self.csv_writer = csv.DictWriter(self.csv_fd, fieldnames=fields)
59+
self.csv_writer.writeheader()
60+
61+
def read_trace(self, trace):
62+
"""Read instruction trace from CSV file"""
63+
csv_reader = csv.DictReader(self.csv_fd)
64+
for row in csv_reader:
65+
new_trace = RiscvInstructionTraceEntry()
66+
new_trace.gpr = row['gpr'].split(';')
67+
new_trace.csr = row['csr'].split(';')
68+
new_trace.pc = row['pc']
69+
new_trace.operand = row['operand']
70+
new_trace.binary = row['binary']
71+
new_trace.instr_str = row['instr_str']
72+
new_trace.instr = row['instr']
73+
new_trace.mode = row['mode']
74+
trace.append(new_trace)
75+
76+
# TODO: Convert pseudo instruction to regular instruction
77+
78+
def write_trace_entry(self, entry):
79+
"""Write a new trace entry to CSV"""
80+
self.csv_writer.writerow({'instr_str': entry.instr_str,
81+
'gpr' : ";".join(entry.gpr),
82+
'csr' : ";".join(entry.csr),
83+
'operand' : entry.operand,
84+
'pc' : entry.pc,
85+
'binary' : entry.binary,
86+
'instr' : entry.instr,
87+
'mode' : entry.mode})
88+
8689

8790
def get_imm_hex_val(imm):
88-
"""Get the hex representation of the imm value"""
89-
if imm[0] == '-':
90-
is_negative = 1
91-
imm = imm[1:]
92-
else:
93-
is_negative = 0
94-
imm_val = int(imm, 0)
95-
if is_negative:
96-
imm_val = -imm_val
97-
hexstr = sint_to_hex(imm_val)
98-
return hexstr[2:]
91+
"""Get the hex representation of the imm value"""
92+
if imm[0] == '-':
93+
is_negative = 1
94+
imm = imm[1:]
95+
else:
96+
is_negative = 0
97+
imm_val = int(imm, 0)
98+
if is_negative:
99+
imm_val = -imm_val
100+
hexstr = sint_to_hex(imm_val)
101+
return hexstr[2:]

‎scripts/sail_log_to_trace_csv.py

+61-58
Original file line numberDiff line numberDiff line change
@@ -27,69 +27,72 @@
2727
from riscv_trace_csv import *
2828

2929
START_RE = re.compile(r"\[4\] \[M\]: 0x.*00001010")
30-
END_RE = re.compile(r"ecall")
30+
END_RE = re.compile(r"ecall")
3131
INSTR_RE = re.compile(r"\[[0-9].*\] \[(?P<pri>.)\]: 0x(?P<addr>[A-F0-9]+?)"
32-
" \(0x(?P<bin>[A-F0-9]+?)\) (?P<instr>.+?$)")
33-
RD_RE = re.compile(r"x(?P<reg>[0-9]+?) <- 0x(?P<val>[A-F0-9]*)")
32+
" \(0x(?P<bin>[A-F0-9]+?)\) (?P<instr>.+?$)")
33+
RD_RE = re.compile(r"x(?P<reg>[0-9]+?) <- 0x(?P<val>[A-F0-9]*)")
34+
3435

3536
def process_sail_sim_log(sail_log, csv):
36-
"""Process SAIL RISCV simulation log.
37-
38-
Extract instruction and affected register information from sail simulation
39-
log and save to a list.
40-
"""
41-
logging.info("Processing sail log : %s" % sail_log)
42-
instr_cnt = 0
43-
44-
with open(sail_log, "r") as f, open(csv, "w") as csv_fd:
45-
search_start = 0
46-
instr_start = 0
47-
trace_csv = RiscvInstructionTraceCsv(csv_fd)
48-
trace_csv.start_new_trace()
49-
instr = None
50-
for line in f:
51-
# Extract instruction infromation
52-
m = START_RE.search(line)
53-
if m:
54-
search_start = 1
55-
continue
56-
m = END_RE.search(line)
57-
if m:
58-
break
59-
if search_start:
60-
instr = INSTR_RE.search(line)
61-
if instr:
62-
instr_start = 1
63-
pri = instr.group("pri")
64-
addr = instr.group("addr").lower()
65-
binary = instr.group("bin").lower()
66-
instr_str = instr.group("instr")
67-
continue
68-
if instr_start:
69-
m = RD_RE.search(line)
70-
if m:
71-
# Write the extracted instruction to a csvcol buffer file
72-
instr_cnt += 1
73-
rv_instr_trace = RiscvInstructionTraceEntry()
74-
rv_instr_trace.gpr.append(
75-
gpr_to_abi("x%0s" % m.group("reg")) + ":" + m.group("val").lower())
76-
rv_instr_trace.mode = pri
77-
rv_instr_trace.pc = addr
78-
rv_instr_trace.binary = binary
79-
rv_instr_trace.instr_str = instr_str
80-
trace_csv.write_trace_entry(rv_instr_trace)
81-
instr_start = 0
82-
logging.info("Processed instruction count : %d" % instr_cnt)
37+
"""Process SAIL RISCV simulation log.
38+
39+
Extract instruction and affected register information from sail simulation
40+
log and save to a list.
41+
"""
42+
logging.info("Processing sail log : {}".format(sail_log))
43+
instr_cnt = 0
44+
45+
with open(sail_log, "r") as f, open(csv, "w") as csv_fd:
46+
search_start = 0
47+
instr_start = 0
48+
trace_csv = RiscvInstructionTraceCsv(csv_fd)
49+
trace_csv.start_new_trace()
50+
instr = None
51+
for line in f:
52+
# Extract instruction infromation
53+
m = START_RE.search(line)
54+
if m:
55+
search_start = 1
56+
continue
57+
m = END_RE.search(line)
58+
if m:
59+
break
60+
if search_start:
61+
instr = INSTR_RE.search(line)
62+
if instr:
63+
instr_start = 1
64+
pri = instr.group("pri")
65+
addr = instr.group("addr").lower()
66+
binary = instr.group("bin").lower()
67+
instr_str = instr.group("instr")
68+
continue
69+
if instr_start:
70+
m = RD_RE.search(line)
71+
if m:
72+
# Write the extracted instruction to a csvcol buffer file
73+
instr_cnt += 1
74+
rv_instr_trace = RiscvInstructionTraceEntry()
75+
rv_instr_trace.gpr.append(
76+
gpr_to_abi("x{}".format(m.group("reg"))) + ":" + m.group(
77+
"val").lower())
78+
rv_instr_trace.mode = pri
79+
rv_instr_trace.pc = addr
80+
rv_instr_trace.binary = binary
81+
rv_instr_trace.instr_str = instr_str
82+
trace_csv.write_trace_entry(rv_instr_trace)
83+
instr_start = 0
84+
logging.info("Processed instruction count : {}".format(instr_cnt))
8385

8486

8587
def main():
86-
# Parse input arguments
87-
parser = argparse.ArgumentParser()
88-
parser.add_argument("--log", type=str, help="Input sail simulation log")
89-
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
90-
args = parser.parse_args()
91-
# Process sail log
92-
process_sail_sim_log(args.log, args.csv)
88+
# Parse input arguments
89+
parser = argparse.ArgumentParser()
90+
parser.add_argument("--log", type=str, help="Input sail simulation log")
91+
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
92+
args = parser.parse_args()
93+
# Process sail log
94+
process_sail_sim_log(args.log, args.csv)
95+
9396

9497
if __name__ == "__main__":
95-
main()
98+
main()

‎scripts/spike_log_to_trace_csv.py

+184-181
Original file line numberDiff line numberDiff line change
@@ -27,209 +27,212 @@
2727
from riscv_trace_csv import *
2828
from lib import *
2929

30-
RD_RE = re.compile(r"(?P<pri>\d) 0x(?P<addr>[a-f0-9]+?) " \
31-
"\((?P<bin>.*?)\) (?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
32-
CORE_RE = re.compile(r"core.*0x(?P<addr>[a-f0-9]+?) \(0x(?P<bin>.*?)\) (?P<instr>.*?)$")
33-
ILLE_RE = re.compile(r"trap_illegal_instruction")
30+
RD_RE = re.compile(r"(?P<pri>\d) 0x(?P<addr>[a-f0-9]+?) " \
31+
"\((?P<bin>.*?)\) (?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
32+
CORE_RE = re.compile(
33+
r"core.*0x(?P<addr>[a-f0-9]+?) \(0x(?P<bin>.*?)\) (?P<instr>.*?)$")
34+
ILLE_RE = re.compile(r"trap_illegal_instruction")
3435

3536
LOGGER = logging.getLogger()
3637

3738

3839
def process_instr(trace):
39-
if trace.instr == "jal":
40-
# Spike jal format jal rd, -0xf -> jal rd, -15
41-
idx = trace.operand.rfind(",")
42-
imm = trace.operand[idx+1:]
43-
if imm[0] == "-":
44-
imm = "-" + str(int(imm[1:], 16))
45-
else:
46-
imm = str(int(imm, 16))
47-
trace.operand = trace.operand[0:idx+1] + imm
48-
trace.operand = trace.operand.replace("(", ",")
49-
trace.operand = trace.operand.replace(")", "")
40+
if trace.instr == "jal":
41+
# Spike jal format jal rd, -0xf -> jal rd, -15
42+
idx = trace.operand.rfind(",")
43+
imm = trace.operand[idx + 1:]
44+
if imm[0] == "-":
45+
imm = "-" + str(int(imm[1:], 16))
46+
else:
47+
imm = str(int(imm, 16))
48+
trace.operand = trace.operand[0:idx + 1] + imm
49+
trace.operand = trace.operand.replace("(", ",")
50+
trace.operand = trace.operand.replace(")", "")
5051

5152

5253
def read_spike_instr(match, full_trace):
53-
'''Unpack a regex match for CORE_RE to a RiscvInstructionTraceEntry
54+
"""Unpack a regex match for CORE_RE to a RiscvInstructionTraceEntry
5455
55-
If full_trace is true, extract operand data from the disassembled
56-
instruction.
56+
If full_trace is true, extract operand data from the disassembled
57+
instruction.
5758
58-
'''
59+
"""
5960

60-
# Extract the disassembled instruction.
61-
disasm = match.group('instr')
61+
# Extract the disassembled instruction.
62+
disasm = match.group('instr')
6263

63-
# Spike's disassembler shows a relative jump as something like "j pc +
64-
# 0x123" or "j pc - 0x123". We just want the relative offset.
65-
disasm = disasm.replace('pc + ', '').replace('pc - ', '-')
64+
# Spike's disassembler shows a relative jump as something like "j pc +
65+
# 0x123" or "j pc - 0x123". We just want the relative offset.
66+
disasm = disasm.replace('pc + ', '').replace('pc - ', '-')
6667

67-
instr = RiscvInstructionTraceEntry()
68-
instr.pc = match.group('addr')
69-
instr.instr_str = disasm
70-
instr.binary = match.group('bin')
68+
instr = RiscvInstructionTraceEntry()
69+
instr.pc = match.group('addr')
70+
instr.instr_str = disasm
71+
instr.binary = match.group('bin')
7172

72-
if full_trace:
73-
opcode = disasm.split(' ')[0]
74-
operand = disasm[len(opcode):].replace(' ', '')
75-
instr.instr, instr.operand = \
76-
convert_pseudo_instr(opcode, operand, instr.binary)
73+
if full_trace:
74+
opcode = disasm.split(' ')[0]
75+
operand = disasm[len(opcode):].replace(' ', '')
76+
instr.instr, instr.operand = \
77+
convert_pseudo_instr(opcode, operand, instr.binary)
7778

78-
process_instr(instr)
79+
process_instr(instr)
7980

80-
return instr
81+
return instr
8182

8283

8384
def read_spike_trace(path, full_trace):
84-
'''Read a Spike simulation log at <path>, yielding executed instructions.
85-
86-
This assumes that the log was generated with the -l and --log-commits options
87-
to Spike.
88-
89-
If full_trace is true, extract operands from the disassembled instructions.
90-
91-
Since Spike has a strange trampoline that always runs at the start, we skip
92-
instructions up to and including the one at PC 0x1010 (the end of the
93-
trampoline). At the end of a DV program, there's an ECALL instruction, which
94-
we take as a signal to stop checking, so we ditch everything that follows
95-
that instruction.
96-
97-
This function yields instructions as it parses them as tuples of the form
98-
(entry, illegal). entry is a RiscvInstructionTraceEntry. illegal is a
99-
boolean, which is true if the instruction caused an illegal instruction trap.
100-
101-
'''
102-
103-
# This loop is a simple FSM with states TRAMPOLINE, INSTR, EFFECT. The idea
104-
# is that we're in state TRAMPOLINE until we get to the end of Spike's
105-
# trampoline, then we switch between INSTR (where we expect to read an
106-
# instruction) and EFFECT (where we expect to read commit information).
107-
#
108-
# We yield a RiscvInstructionTraceEntry object each time we leave EFFECT
109-
# (going back to INSTR), we loop back from INSTR to itself, or we get to the
110-
# end of the file and have an instruction in hand.
111-
#
112-
# On entry to the loop body, we are in state TRAMPOLINE if in_trampoline is
113-
# true. Otherwise, we are in state EFFECT if instr is not None, otherwise we
114-
# are in state INSTR.
115-
116-
end_trampoline_re = re.compile(r'core.*: 0x0*1010 ')
117-
118-
in_trampoline = True
119-
instr = None
120-
121-
with open(path, 'r') as handle:
122-
for line in handle:
123-
if in_trampoline:
124-
# The TRAMPOLINE state
125-
if end_trampoline_re.match(line):
126-
in_trampoline = False
127-
continue
128-
129-
if instr is None:
130-
# The INSTR state. We expect to see a line matching CORE_RE. We'll
131-
# discard any other lines.
132-
instr_match = CORE_RE.match(line)
133-
if not instr_match:
134-
continue
135-
136-
instr = read_spike_instr(instr_match, full_trace)
137-
138-
# If instr.instr_str is 'ecall', we should stop.
139-
if instr.instr_str == 'ecall':
140-
break
141-
142-
continue
143-
144-
# The EFFECT state. If the line matches CORE_RE, we should have been in
145-
# state INSTR, so we yield the instruction we had, read the new
146-
# instruction and continue. As above, if the new instruction is 'ecall',
147-
# we need to stop immediately.
148-
instr_match = CORE_RE.match(line)
149-
if instr_match:
150-
yield (instr, False)
151-
instr = read_spike_instr(instr_match, full_trace)
152-
if instr.instr_str == 'ecall':
153-
break
154-
continue
155-
156-
# The line doesn't match CORE_RE, so we are definitely on a follow-on
157-
# line in the log. First, check for illegal instructions
158-
if 'trap_illegal_instruction' in line:
159-
yield (instr, True)
160-
instr = None
161-
continue
162-
163-
# The instruction seems to have been fine. Do we have commit data (from
164-
# the --log-commits Spike option)?
165-
commit_match = RD_RE.match(line)
166-
if commit_match:
167-
instr.gpr.append(gpr_to_abi(commit_match.group('reg')
168-
.replace(' ', '')) +
169-
':' + commit_match.group('val'))
170-
instr.mode = commit_match.group('pri')
171-
172-
# At EOF, we might have an instruction in hand. Yield it if so.
173-
if instr is not None:
174-
yield (instr, False)
175-
176-
177-
def process_spike_sim_log(spike_log, csv, full_trace = 0):
178-
"""Process SPIKE simulation log.
179-
180-
Extract instruction and affected register information from spike simulation
181-
log and write the results to a CSV file at csv. Returns the number of
182-
instructions written.
183-
184-
"""
185-
logging.info("Processing spike log : %s" % spike_log)
186-
instrs_in = 0
187-
instrs_out = 0
188-
189-
with open(csv, "w") as csv_fd:
190-
trace_csv = RiscvInstructionTraceCsv(csv_fd)
191-
trace_csv.start_new_trace()
192-
193-
for (entry, illegal) in read_spike_trace(spike_log, full_trace):
194-
instrs_in += 1
195-
196-
if illegal and full_trace:
197-
logging.debug("Illegal instruction: {}, opcode:{}"
198-
.format(entry.instr_str, entry.binary))
199-
200-
# Instructions that cause no architectural update (which includes illegal
201-
# instructions) are ignored if full_trace is false.
202-
#
203-
# We say that an instruction caused an architectural update if either we
204-
# saw a commit line (in which case, entry.gpr will contain a single
205-
# entry) or the instruction was 'wfi' or 'ecall'.
206-
if not (full_trace or entry.gpr or entry.instr_str in ['wfi', 'ecall']):
207-
continue
208-
209-
trace_csv.write_trace_entry(entry)
210-
instrs_out += 1
211-
212-
logging.info("Processed instruction count : %d" % instrs_in)
213-
logging.info("CSV saved to : %s" % csv)
214-
return instrs_out
85+
"""Read a Spike simulation log at <path>, yielding executed instructions.
86+
87+
This assumes that the log was generated with the -l and --log-commits options
88+
to Spike.
89+
90+
If full_trace is true, extract operands from the disassembled instructions.
91+
92+
Since Spike has a strange trampoline that always runs at the start, we skip
93+
instructions up to and including the one at PC 0x1010 (the end of the
94+
trampoline). At the end of a DV program, there's an ECALL instruction, which
95+
we take as a signal to stop checking, so we ditch everything that follows
96+
that instruction.
97+
98+
This function yields instructions as it parses them as tuples of the form
99+
(entry, illegal). entry is a RiscvInstructionTraceEntry. illegal is a
100+
boolean, which is true if the instruction caused an illegal instruction trap.
101+
102+
"""
103+
104+
# This loop is a simple FSM with states TRAMPOLINE, INSTR, EFFECT. The idea
105+
# is that we're in state TRAMPOLINE until we get to the end of Spike's
106+
# trampoline, then we switch between INSTR (where we expect to read an
107+
# instruction) and EFFECT (where we expect to read commit information).
108+
#
109+
# We yield a RiscvInstructionTraceEntry object each time we leave EFFECT
110+
# (going back to INSTR), we loop back from INSTR to itself, or we get to the
111+
# end of the file and have an instruction in hand.
112+
#
113+
# On entry to the loop body, we are in state TRAMPOLINE if in_trampoline is
114+
# true. Otherwise, we are in state EFFECT if instr is not None, otherwise we
115+
# are in state INSTR.
116+
117+
end_trampoline_re = re.compile(r'core.*: 0x0*1010 ')
118+
119+
in_trampoline = True
120+
instr = None
121+
122+
with open(path, 'r') as handle:
123+
for line in handle:
124+
if in_trampoline:
125+
# The TRAMPOLINE state
126+
if end_trampoline_re.match(line):
127+
in_trampoline = False
128+
continue
129+
130+
if instr is None:
131+
# The INSTR state. We expect to see a line matching CORE_RE.
132+
# We'll discard any other lines.
133+
instr_match = CORE_RE.match(line)
134+
if not instr_match:
135+
continue
136+
137+
instr = read_spike_instr(instr_match, full_trace)
138+
139+
# If instr.instr_str is 'ecall', we should stop.
140+
if instr.instr_str == 'ecall':
141+
break
142+
143+
continue
144+
145+
# The EFFECT state. If the line matches CORE_RE, we should have been in
146+
# state INSTR, so we yield the instruction we had, read the new
147+
# instruction and continue. As above, if the new instruction is 'ecall',
148+
# we need to stop immediately.
149+
instr_match = CORE_RE.match(line)
150+
if instr_match:
151+
yield instr, False
152+
instr = read_spike_instr(instr_match, full_trace)
153+
if instr.instr_str == 'ecall':
154+
break
155+
continue
156+
157+
# The line doesn't match CORE_RE, so we are definitely on a follow-on
158+
# line in the log. First, check for illegal instructions
159+
if 'trap_illegal_instruction' in line:
160+
yield (instr, True)
161+
instr = None
162+
continue
163+
164+
# The instruction seems to have been fine. Do we have commit data (from
165+
# the --log-commits Spike option)?
166+
commit_match = RD_RE.match(line)
167+
if commit_match:
168+
instr.gpr.append(gpr_to_abi(commit_match.group('reg')
169+
.replace(' ', '')) +
170+
':' + commit_match.group('val'))
171+
instr.mode = commit_match.group('pri')
172+
173+
# At EOF, we might have an instruction in hand. Yield it if so.
174+
if instr is not None:
175+
yield (instr, False)
176+
177+
178+
def process_spike_sim_log(spike_log, csv, full_trace=0):
179+
"""Process SPIKE simulation log.
180+
181+
Extract instruction and affected register information from spike simulation
182+
log and write the results to a CSV file at csv. Returns the number of
183+
instructions written.
184+
185+
"""
186+
logging.info("Processing spike log : {}".format(spike_log))
187+
instrs_in = 0
188+
instrs_out = 0
189+
190+
with open(csv, "w") as csv_fd:
191+
trace_csv = RiscvInstructionTraceCsv(csv_fd)
192+
trace_csv.start_new_trace()
193+
194+
for (entry, illegal) in read_spike_trace(spike_log, full_trace):
195+
instrs_in += 1
196+
197+
if illegal and full_trace:
198+
logging.debug("Illegal instruction: {}, opcode:{}"
199+
.format(entry.instr_str, entry.binary))
200+
201+
# Instructions that cause no architectural update (which includes illegal
202+
# instructions) are ignored if full_trace is false.
203+
#
204+
# We say that an instruction caused an architectural update if either we
205+
# saw a commit line (in which case, entry.gpr will contain a single
206+
# entry) or the instruction was 'wfi' or 'ecall'.
207+
if not (full_trace or entry.gpr or entry.instr_str in ['wfi',
208+
'ecall']):
209+
continue
210+
211+
trace_csv.write_trace_entry(entry)
212+
instrs_out += 1
213+
214+
logging.info("Processed instruction count : {}".format(instrs_in))
215+
logging.info("CSV saved to : {}".format(csv))
216+
return instrs_out
215217

216218

217219
def main():
218-
# Parse input arguments
219-
parser = argparse.ArgumentParser()
220-
parser.add_argument("--log", type=str, help="Input spike simulation log")
221-
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
222-
parser.add_argument("-f", "--full_trace", dest="full_trace", action="store_true",
223-
help="Generate the full trace")
224-
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
225-
help="Verbose logging")
226-
parser.set_defaults(full_trace=False)
227-
parser.set_defaults(verbose=False)
228-
args = parser.parse_args()
229-
setup_logging(args.verbose)
230-
# Process spike log
231-
process_spike_sim_log(args.log, args.csv, args.full_trace)
220+
# Parse input arguments
221+
parser = argparse.ArgumentParser()
222+
parser.add_argument("--log", type=str, help="Input spike simulation log")
223+
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
224+
parser.add_argument("-f", "--full_trace", dest="full_trace",
225+
action="store_true",
226+
help="Generate the full trace")
227+
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
228+
help="Verbose logging")
229+
parser.set_defaults(full_trace=False)
230+
parser.set_defaults(verbose=False)
231+
args = parser.parse_args()
232+
setup_logging(args.verbose)
233+
# Process spike log
234+
process_spike_sim_log(args.log, args.csv, args.full_trace)
232235

233236

234237
if __name__ == "__main__":
235-
main()
238+
main()

‎scripts/whisper_log_trace_csv.py

+55-51
Original file line numberDiff line numberDiff line change
@@ -27,63 +27,67 @@
2727
from riscv_trace_csv import *
2828
from lib import *
2929

30-
INSTR_RE = re.compile(r"#(?P<n>[0-9]+?)\s+(?P<mode>[0-9]+?)\s+(?P<pc>[0-9a-f]+?)\s+" \
31-
"(?P<bin>[0-9a-f]+?)\s+(?P<type>[a-z]+?)\s+" \
32-
"(?P<reg>[0-9a-f]+?)\s+(?P<val>[0-9a-f]+?)\s+(?P<instr>.*?)$")
30+
INSTR_RE = re.compile(
31+
r"#(?P<n>[0-9]+?)\s+(?P<mode>[0-9]+?)\s+(?P<pc>[0-9a-f]+?)\s+" \
32+
"(?P<bin>[0-9a-f]+?)\s+(?P<type>[a-z]+?)\s+" \
33+
"(?P<reg>[0-9a-f]+?)\s+(?P<val>[0-9a-f]+?)\s+(?P<instr>.*?)$")
3334

3435
LOGGER = logging.getLogger()
3536

36-
def process_whisper_sim_log(whisper_log, csv, full_trace = 0):
37-
"""Process SPIKE simulation log.
38-
39-
Extract instruction and affected register information from whisper simulation
40-
log and save to a list.
41-
"""
42-
logging.info("Processing whisper log : %s" % whisper_log)
43-
instr_cnt = 0
44-
whisper_instr = ""
45-
46-
with open(whisper_log, "r") as f, open(csv, "w") as csv_fd:
47-
trace_csv = RiscvInstructionTraceCsv(csv_fd)
48-
trace_csv.start_new_trace()
49-
for line in f:
50-
# Extract instruction infromation
51-
m = INSTR_RE.search(line)
52-
if m:
53-
logging.debug("-> mode: %s, pc:%s, bin:%s, instr:%s" %
54-
(m.group('mode'), m.group('pc'), m.group('bin'), m.group('instr')))
55-
if re.search('ecall', m.group('instr')):
56-
break
57-
if m.group('type') == 'r':
58-
whisper_instr = m.group("instr").replace("\. + ", "")
59-
whisper_instr = whisper_instr.replace("\. - ", "-")
60-
rv_instr_trace = RiscvInstructionTraceEntry()
61-
rv_instr_trace.instr_str = whisper_instr
62-
rv_instr_trace.binary = m.group("bin")
63-
reg = "x" + str(int(m.group("reg"), 16))
64-
rv_instr_trace.gpr.append(gpr_to_abi(reg) + ":" + m.group("val"))
65-
trace_csv.write_trace_entry(rv_instr_trace)
66-
instr_cnt += 1
67-
logging.info("Processed instruction count : %d" % instr_cnt)
68-
logging.info("CSV saved to : %s" % csv)
37+
38+
def process_whisper_sim_log(whisper_log, csv, full_trace=0):
39+
"""Process SPIKE simulation log.
40+
41+
Extract instruction and affected register information from whisper simulation
42+
log and save to a list.
43+
"""
44+
logging.info("Processing whisper log : {}".format(whisper_log))
45+
instr_cnt = 0
46+
whisper_instr = ""
47+
48+
with open(whisper_log, "r") as f, open(csv, "w") as csv_fd:
49+
trace_csv = RiscvInstructionTraceCsv(csv_fd)
50+
trace_csv.start_new_trace()
51+
for line in f:
52+
# Extract instruction infromation
53+
m = INSTR_RE.search(line)
54+
if m:
55+
logging.debug("-> mode: {}, pc:{}, bin:{}, instr:{}".format(
56+
m.group('mode'), m.group('pc'), m.group('bin'),m.group('instr')))
57+
if re.search('ecall', m.group('instr')):
58+
break
59+
if m.group('type') == 'r':
60+
whisper_instr = m.group("instr").replace("\. + ", "")
61+
whisper_instr = whisper_instr.replace("\. - ", "-")
62+
rv_instr_trace = RiscvInstructionTraceEntry()
63+
rv_instr_trace.instr_str = whisper_instr
64+
rv_instr_trace.binary = m.group("bin")
65+
reg = "x" + str(int(m.group("reg"), 16))
66+
rv_instr_trace.gpr.append(
67+
gpr_to_abi(reg) + ":" + m.group("val"))
68+
trace_csv.write_trace_entry(rv_instr_trace)
69+
instr_cnt += 1
70+
logging.info("Processed instruction count : {}".format(instr_cnt))
71+
logging.info("CSV saved to : {}".format(csv))
6972

7073

7174
def main():
72-
# Parse input arguments
73-
parser = argparse.ArgumentParser()
74-
parser.add_argument("--log", type=str, help="Input whisper simulation log")
75-
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
76-
parser.add_argument("-f", "--full_trace", dest="full_trace", action="store_true",
77-
help="Generate the full trace")
78-
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
79-
help="Verbose logging")
80-
parser.set_defaults(full_trace=False)
81-
parser.set_defaults(verbose=False)
82-
args = parser.parse_args()
83-
setup_logging(args.verbose)
84-
# Process whisper log
85-
process_whisper_sim_log(args.log, args.csv, args.full_trace)
75+
# Parse input arguments
76+
parser = argparse.ArgumentParser()
77+
parser.add_argument("--log", type=str, help="Input whisper simulation log")
78+
parser.add_argument("--csv", type=str, help="Output trace csv_buf file")
79+
parser.add_argument("-f", "--full_trace", dest="full_trace",
80+
action="store_true",
81+
help="Generate the full trace")
82+
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
83+
help="Verbose logging")
84+
parser.set_defaults(full_trace=False)
85+
parser.set_defaults(verbose=False)
86+
args = parser.parse_args()
87+
setup_logging(args.verbose)
88+
# Process whisper log
89+
process_whisper_sim_log(args.log, args.csv, args.full_trace)
8690

8791

8892
if __name__ == "__main__":
89-
main()
93+
main()

0 commit comments

Comments
 (0)
Please sign in to comment.