-
Notifications
You must be signed in to change notification settings - Fork 0
/
simulation.py
executable file
·113 lines (86 loc) · 3.61 KB
/
simulation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
import argparse
import json
import time
import IPython
import pandas as pd
import simpy
from tomasulo_simulator import Parser
from tomasulo_simulator import assemble
from tomasulo_simulator import CpuConfig
from tomasulo_simulator import CPU
from tomasulo_simulator.execution_trace import ExecutionTraceSerializer
def main():
print_figlet()
with open(args.program) as f:
program = f.read()
directives, code = Parser().parse_code(program)
instructions = assemble(code)
config = CpuConfig(directives)
if args.dump_assembled_instructions:
print("Assembled instructions:")
print(dump_instructions(instructions))
env = simpy.Environment()
# cpu = CPU(env, code, breakpoint_handler=spawn_ipython_handler)
# cpu = CPU(env, code, breakpoint_handler=lambda cpu: print(cpu))
cpu = CPU(env, instructions, config)
run_simulation(env, cpu)
collect_statistics(cpu)
def print_figlet():
if not args.quiet:
from pyfiglet import Figlet
f = Figlet(font="nancyj-improved")
print(f.renderText("Tomasulo simulator"))
def run_simulation(env, cpu):
env.process(cpu.run())
if args.step_by_step:
while True:
try:
env.step()
except simpy.core.EmptySchedule:
break
finally:
print(cpu)
if args.interactive:
try:
spawn_ipython_handler(cpu)
except Exception as e:
print(e)
else:
env.run()
print(cpu)
def collect_statistics(cpu):
stats = [i.stats.to_dict() for i in cpu.executed_instructions]
if not args.no_stats:
print_stats(stats)
if args.output:
filename = "./outputs/out_{:.0f}.json".format(time.time())
with open(filename, "x") as f:
json.dump(stats, f, cls=ExecutionTraceSerializer)
def print_stats(stats):
columns = ["Instruction", "Issue", "Start exec.", "Write res.", "Written res.", "Hazards", "RS", "FU"]
col_order = ["instruction", "issued", "start_execution", "write_result", "written_result", "hazards", "rs", "fu"]
df = pd.DataFrame(stats).sort_values(by="issued")[col_order]
pd.set_option('display.max_colwidth', -1)
formatters = {
"hazards": lambda hazards: " ".join([hazard.__repr__() for hazard in hazards])
}
print("\n")
print(df.to_string(header=columns, justify="end", formatters=formatters))
# TODO: print ClockPerInstruction/InstructionsPerClock
def spawn_ipython_handler(cpu):
header = "The cpu variable contains a reference to the CPU instance.\nUse 'quit' to exit."
IPython.embed(header=header)
def dump_instructions(instructions):
return "\n".join([str(i) for i in instructions]) + "\n"
argparser = argparse.ArgumentParser(description="Tomasulo algorithm simulator")
argparser.add_argument("program", help="the assembly file to execute")
argparser.add_argument("--output", "-o", help="Output statistics to json")
argparser.add_argument("--no-stats", "-n", help="Don't output statistics on STDOUT", action="store_true")
argparser.add_argument("--interactive", "-i", help="Spawn IPython shell during the simulation", action="store_true")
argparser.add_argument("--step-by-step", "-s", help="Execute the simulation step by step", action="store_true")
argparser.add_argument("--dump-assembled-instructions", "-d", help="Print the assembled instructions", action="store_true")
argparser.add_argument("--quiet", "-q", help="Don't print the program logo", action="store_true")
if __name__ == "__main__":
args = argparser.parse_args()
main()