Skip to content

Commit 6eea0ca

Browse files
committed
parsing
1 parent 32c3f47 commit 6eea0ca

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import re
2+
import json
3+
import sys
4+
5+
def parse_pipeline_output(file_path):
6+
with open(file_path, 'r') as f:
7+
content = f.read()
8+
9+
cycles = []
10+
cycle_blocks = content.split("--------------------------------")
11+
12+
for block in cycle_blocks:
13+
if "Time=" not in block:
14+
continue
15+
16+
cycle_data = {}
17+
18+
# Extract cycle number
19+
cycle_match = re.search(r"Cycle=(\d+)", block)
20+
if cycle_match:
21+
cycle_data["cycle"] = int(cycle_match.group(1))
22+
23+
# Extract IF stage data
24+
pc_match = re.search(r"IF Stage: PC=([0-9a-fA-Fx]+)", block)
25+
if pc_match:
26+
cycle_data["pc_current"] = pc_match.group(1)
27+
28+
inst_match = re.search(r"Instruction=([0-9a-fA-Fx]+)", block)
29+
if inst_match:
30+
cycle_data["instruction"] = inst_match.group(1)
31+
32+
# Extract pipeline register contents
33+
if_id_inst_match = re.search(r"IF/ID: .*?Instruction=([0-9a-fA-Fx]+)", block)
34+
if if_id_inst_match:
35+
cycle_data["if_id_instruction"] = if_id_inst_match.group(1)
36+
37+
id_ex_inst_match = re.search(r"ID/EX: .*?Instruction=([0-9a-fA-Fx]+)", block)
38+
if id_ex_inst_match:
39+
cycle_data["id_ex_instruction"] = id_ex_inst_match.group(1)
40+
41+
ex_mem_inst_match = re.search(r"EX/MEM: .*?Instruction=([0-9a-fA-Fx]+)", block)
42+
if ex_mem_inst_match:
43+
cycle_data["ex_mem_instruction"] = ex_mem_inst_match.group(1)
44+
45+
mem_wb_inst_match = re.search(r"MEM/WB: .*?Instruction=([0-9a-fA-Fx]+)", block)
46+
if mem_wb_inst_match:
47+
cycle_data["mem_wb_instruction"] = mem_wb_inst_match.group(1)
48+
49+
# Extract ID stage data
50+
id_match = re.search(r"ID Stage: rs1=x(\d+) \((-?\d+)\), rs2=x(\d+) \((-?\d+)\), rd=x(\d+)", block)
51+
if id_match:
52+
cycle_data["rs1"] = int(id_match.group(1))
53+
cycle_data["reg_read_data1"] = int(id_match.group(2))
54+
cycle_data["rs2"] = int(id_match.group(3))
55+
cycle_data["reg_read_data2"] = int(id_match.group(4))
56+
cycle_data["reg_rd"] = int(id_match.group(5))
57+
58+
# Extract register operand values and destination registers
59+
reg_values_match = re.search(r"ID/EX: .*?rs1=x(\d+), rs2=x(\d+), rd=x(\d+)", block)
60+
if reg_values_match:
61+
cycle_data["id_ex_rs1"] = int(reg_values_match.group(1))
62+
cycle_data["id_ex_rs2"] = int(reg_values_match.group(2))
63+
cycle_data["id_ex_rd"] = int(reg_values_match.group(3))
64+
65+
ex_mem_rd_match = re.search(r"EX/MEM: .*?rd=x(\d+)", block)
66+
if ex_mem_rd_match:
67+
cycle_data["ex_mem_rd"] = int(ex_mem_rd_match.group(1))
68+
69+
mem_wb_rd_match = re.search(r"MEM/WB: .*?rd=x(\d+)", block)
70+
if mem_wb_rd_match:
71+
cycle_data["mem_wb_rd"] = int(mem_wb_rd_match.group(1))
72+
73+
# Extract EX stage data
74+
ex_match = re.search(r"EX Stage: ALU Result=([0-9a-fA-Fx]+)", block)
75+
if ex_match:
76+
cycle_data["alu_result"] = ex_match.group(1)
77+
78+
# Extract control signals
79+
control_match = re.search(r"Control signals: branch=(\d), mem_read=(\d), mem_to_reg=(\d), mem_write=(\d), alu_src=(\d), reg_write=(\d)", block)
80+
if control_match:
81+
cycle_data["branch"] = bool(int(control_match.group(1)))
82+
cycle_data["mem_read"] = bool(int(control_match.group(2)))
83+
cycle_data["mem_to_reg"] = bool(int(control_match.group(3)))
84+
cycle_data["mem_write"] = bool(int(control_match.group(4)))
85+
cycle_data["alu_src"] = bool(int(control_match.group(5)))
86+
cycle_data["reg_write"] = bool(int(control_match.group(6)))
87+
88+
# Extract WB activity (register writes)
89+
wb_match = re.search(r"WB Stage: Writing (-?\d+) to register x(\d+)", block)
90+
if wb_match:
91+
cycle_data["reg_write_data"] = int(wb_match.group(1))
92+
cycle_data["reg_write_rd"] = int(wb_match.group(2))
93+
94+
# Extract memory access information
95+
mem_read_match = re.search(r"MEM Stage: Reading from address (-?\d+), value=(-?\d+)", block)
96+
if mem_read_match:
97+
cycle_data["mem_read_address"] = int(mem_read_match.group(1))
98+
cycle_data["mem_read_data"] = int(mem_read_match.group(2))
99+
100+
mem_write_match = re.search(r"MEM Stage: Writing (-?\d+) to address (-?\d+)", block)
101+
if mem_write_match:
102+
cycle_data["mem_write_data"] = int(mem_write_match.group(1))
103+
cycle_data["mem_write_address"] = int(mem_write_match.group(2))
104+
105+
# Detect stall signals
106+
if "stall detected" in block.lower() or "stalling pipeline" in block.lower():
107+
cycle_data["if_stalled"] = True
108+
cycle_data["id_stalled"] = True
109+
110+
# Check for load-use hazard keywords
111+
if "hazard detected" in block.lower() or "stalling pipeline" in block.lower():
112+
cycle_data["stall"] = True
113+
cycle_data["load_hazard"] = True
114+
115+
# Detect forwarding
116+
if "forwarding active" in block.lower():
117+
# Check for specific forwarding types
118+
if "ex → ex forwarding" in block.lower():
119+
cycle_data["ex_forwarding"] = True
120+
cycle_data["forwardA"] = "10" # If showing rs1
121+
122+
if "mem → ex forwarding" in block.lower():
123+
cycle_data["mem_forwarding"] = True
124+
cycle_data["forwardA"] = "01" # If showing rs1
125+
126+
# Detect branch misprediction
127+
if "branch mispredicted" in block.lower() or "pipeline flush" in block.lower():
128+
cycle_data["branch_mispredicted"] = True
129+
cycle_data["flush"] = True
130+
131+
# Check for load-use hazard keywords
132+
if "load-use hazard" in block.lower() or "load hazard" in block.lower():
133+
cycle_data["load_hazard"] = True
134+
135+
# Detect forwarding
136+
if "forwarding from ex" in block.lower() or "ex → ex forwarding" in block.lower():
137+
cycle_data["ex_forwarding"] = True
138+
139+
if "forwarding from mem" in block.lower() or "mem → ex forwarding" in block.lower():
140+
cycle_data["mem_forwarding"] = True
141+
142+
# Extract forwarding specific info
143+
ex_forward_match = re.search(r"forwardA=2'b10|forwardB=2'b10", block)
144+
if ex_forward_match:
145+
cycle_data["ex_forwarding"] = True
146+
147+
mem_forward_match = re.search(r"forwardA=2'b01|forwardB=2'b01", block)
148+
if mem_forward_match:
149+
cycle_data["mem_forwarding"] = True
150+
151+
# Detect branch misprediction
152+
if "branch misprediction" in block.lower() or "pipeline flush" in block.lower() or "branch_mispredicted" in block.lower():
153+
cycle_data["branch_mispredicted"] = True
154+
cycle_data["id_flushed"] = True
155+
cycle_data["ex_flushed"] = True
156+
157+
# Additional branch info
158+
if "branch at pc=" in block.lower() and "mispredicted" in block.lower():
159+
cycle_data["branch_mispredicted"] = True
160+
161+
162+
# More specific branch information parsing
163+
branch_target_match = re.search(r"Branch at PC=([0-9a-fA-Fx]+): Taking branch", block)
164+
if branch_target_match:
165+
cycle_data["branch_taken"] = True
166+
cycle_data["branch_pc"] = branch_target_match.group(1)
167+
168+
branch_prediction_match = re.search(r"Branch prediction: ([A-Za-z]+)", block)
169+
if branch_prediction_match:
170+
cycle_data["branch_prediction"] = branch_prediction_match.group(1).lower()
171+
172+
# Find branch source and target addresses
173+
branch_addr_match = re.search(r"beq .* (-?\d+)", block)
174+
if branch_addr_match and cycle_data.get("pc_current"):
175+
try:
176+
offset = int(branch_addr_match.group(1))
177+
pc = int(cycle_data["pc_current"], 16)
178+
cycle_data["branch_target_addr"] = pc + offset
179+
except:
180+
pass
181+
182+
# Track control flow more precisely
183+
if "taking branch" in block.lower():
184+
cycle_data["control_flow_changed"] = True
185+
186+
if "pipeline flushed" in block.lower():
187+
cycle_data["flush_occurred"] = True
188+
cycle_data["pipeline_recovery"] = True
189+
190+
191+
192+
cycles.append(cycle_data)
193+
194+
195+
return {"cycles": cycles}
196+
197+
if __name__ == "__main__":
198+
if len(sys.argv) < 2:
199+
print("Usage: python parse_pipeline.py <simulation_output.txt>")
200+
sys.exit(1)
201+
202+
pipeline_data = parse_pipeline_output(sys.argv[1])
203+
204+
with open("visualization/pipeline-data.js", "w") as f:
205+
f.write("const pipelineData = " + json.dumps(pipeline_data, indent=2) + ";")
206+
207+
print(f"Generated pipeline-data.js with {len(pipeline_data['cycles'])} cycles of data")

0 commit comments

Comments
 (0)