Skip to content

Commit 0a04f0b

Browse files
committed
assembler for visualization and script
1 parent 2aafb18 commit 0a04f0b

File tree

3 files changed

+136
-2
lines changed

3 files changed

+136
-2
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# visualize_pipeline.sh
2+
#!/bin/bash
3+
4+
mkdir -p test_results
5+
mkdir -p visualization
6+
7+
# Check for test file argument
8+
if [ $# -eq 0 ]; then
9+
echo "Usage: $0 <test_file>"
10+
exit 1
11+
fi
12+
13+
TEST_FILE=$1
14+
15+
# Assemble the test file
16+
echo "Assembling test file..."
17+
python3 testcases/assembler.py "$TEST_FILE"
18+
19+
# Compile Verilog files
20+
echo "Compiling Verilog files..."
21+
iverilog -o test_results/cpu_test \
22+
verilog/cpu_pipelined.v \
23+
verilog/testbench_pipelined.v \
24+
-I modules/
25+
26+
if [ $? -eq 0 ]; then
27+
echo "Compilation successful!"
28+
29+
# Run simulation and capture output
30+
echo "Running simulation..."
31+
vvp test_results/cpu_test | tee test_results/simulation_output.txt
32+
33+
# Generate visualization data
34+
echo "Generating visualization data..."
35+
python3 visualization/parse-pipeline.py test_results/simulation_output.txt
36+
37+
# Open visualization in browser
38+
echo "Opening visualization in browser..."
39+
xdg-open visualization/index.html 2>/dev/null || \
40+
open visualization/index.html 2>/dev/null || \
41+
echo "Please open visualization/index.html in your browser manually"
42+
43+
echo "Visualization complete!"
44+
else
45+
echo "Compilation failed."
46+
exit 1
47+
fi

pipelined/testcases/assembler.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def generate_testbench(instructions):
329329
$display("ID Stage: rs1=x%0d (%0d), rs2=x%0d (%0d), rd=x%0d",
330330
cpu.rs1, cpu.reg_read_data1, cpu.rs2, cpu.reg_read_data2, cpu.reg_rd);
331331
332-
// Show EX stage activity (removed alu_control as it doesn't exist)
332+
// Show EX stage activity
333333
$display("EX Stage: ALU Result=%0h", cpu.alu_result);
334334
335335
// Show MEM stage activity
@@ -349,6 +349,49 @@ def generate_testbench(instructions):
349349
$display("Control signals: branch=%b, mem_read=%b, mem_to_reg=%b, mem_write=%b, alu_src=%b, reg_write=%b",
350350
cpu.branch, cpu.mem_read, cpu.mem_to_reg, cpu.mem_write, cpu.alu_src, cpu.reg_write);
351351
352+
// Add pipeline register contents - MORE DETAILED INFO
353+
$display("Pipeline Registers:");
354+
$display("IF/ID: PC=%h, Instruction=%h", cpu.if_id_pc, cpu.if_id_instruction);
355+
$display("ID/EX: PC=%h, Instruction=%h, rs1=x%0d, rs2=x%0d, rd=x%0d, RegWrite=%b, MemWrite=%b",
356+
cpu.id_ex_pc, cpu.id_ex_instruction, cpu.id_ex_rs1, cpu.id_ex_rs2,
357+
cpu.id_ex_rd, cpu.id_ex_reg_write, cpu.id_ex_mem_write);
358+
$display("EX/MEM: Instruction=%h, rd=x%0d, RegWrite=%b, MemWrite=%b, ALUResult=%h",
359+
cpu.ex_mem_instruction, cpu.ex_mem_rd, cpu.ex_mem_reg_write,
360+
cpu.ex_mem_mem_write, cpu.ex_mem_alu_result);
361+
$display("MEM/WB: Instruction=%h, rd=x%0d, RegWrite=%b, MemToReg=%b",
362+
cpu.mem_wb_instruction, cpu.mem_wb_rd, cpu.mem_wb_reg_write,
363+
cpu.mem_wb_mem_to_reg);
364+
365+
// Hazard detection information
366+
if (cpu.stall) begin // Use cpu.stall directly instead of cpu.hazard_detection_unit.stall_pipeline
367+
$display("HAZARD DETECTED: Stalling pipeline");
368+
$display("Load-use hazard between instructions at PC=%h and PC=%h",
369+
cpu.if_id_pc - 4, cpu.if_id_pc);
370+
end
371+
372+
// Forwarding information
373+
if (cpu.forwardA != 0 || cpu.forwardB != 0) begin // Use cpu.forwardA/B directly
374+
$display("Forwarding active:");
375+
if (cpu.forwardA == 2'b10)
376+
$display("EX → EX Forwarding to rs1 (x%0d)", cpu.id_ex_rs1);
377+
if (cpu.forwardA == 2'b01)
378+
$display("MEM → EX Forwarding to rs1 (x%0d)", cpu.id_ex_rs1);
379+
if (cpu.forwardB == 2'b10)
380+
$display("EX → EX Forwarding to rs2 (x%0d)", cpu.id_ex_rs2);
381+
if (cpu.forwardB == 2'b01)
382+
$display("MEM → EX Forwarding to rs2 (x%0d)", cpu.id_ex_rs2);
383+
end
384+
385+
// Branch information
386+
if (cpu.branch && cpu.zero) begin // Use cpu.zero instead of cpu.alu_zero
387+
$display("Branch at PC=%h: Taking branch", cpu.pc_current);
388+
if (cpu.branch_mispredicted) // Use cpu.branch_mispredicted directly
389+
$display("Branch mispredicted: Pipeline flush required");
390+
end
391+
392+
// Pipeline stall/flush status
393+
if (cpu.flush) // Use cpu.flush instead of cpu.if_id_flush
394+
$display("Pipeline flushed");
352395
end
353396
end
354397
@@ -365,6 +408,7 @@ def generate_testbench(instructions):
365408

366409
print(f"Generated testbench file: {output_file}")
367410

411+
368412
def get_instruction_type(instruction):
369413
if instruction in ["add", "sub", "or", "and"]:
370414
return 'R'

pipelined/verilog/testbench_pipelined.v

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ module testbench_pipelined();
125125
$display("ID Stage: rs1=x%0d (%0d), rs2=x%0d (%0d), rd=x%0d",
126126
cpu.rs1, cpu.reg_read_data1, cpu.rs2, cpu.reg_read_data2, cpu.reg_rd);
127127

128-
// Show EX stage activity (removed alu_control as it doesn't exist)
128+
// Show EX stage activity
129129
$display("EX Stage: ALU Result=%0h", cpu.alu_result);
130130

131131
// Show MEM stage activity
@@ -145,6 +145,49 @@ module testbench_pipelined();
145145
$display("Control signals: branch=%b, mem_read=%b, mem_to_reg=%b, mem_write=%b, alu_src=%b, reg_write=%b",
146146
cpu.branch, cpu.mem_read, cpu.mem_to_reg, cpu.mem_write, cpu.alu_src, cpu.reg_write);
147147

148+
// Add pipeline register contents - MORE DETAILED INFO
149+
$display("Pipeline Registers:");
150+
$display("IF/ID: PC=%h, Instruction=%h", cpu.if_id_pc, cpu.if_id_instruction);
151+
$display("ID/EX: PC=%h, Instruction=%h, rs1=x%0d, rs2=x%0d, rd=x%0d, RegWrite=%b, MemWrite=%b",
152+
cpu.id_ex_pc, cpu.id_ex_instruction, cpu.id_ex_rs1, cpu.id_ex_rs2,
153+
cpu.id_ex_rd, cpu.id_ex_reg_write, cpu.id_ex_mem_write);
154+
$display("EX/MEM: Instruction=%h, rd=x%0d, RegWrite=%b, MemWrite=%b, ALUResult=%h",
155+
cpu.ex_mem_instruction, cpu.ex_mem_rd, cpu.ex_mem_reg_write,
156+
cpu.ex_mem_mem_write, cpu.ex_mem_alu_result);
157+
$display("MEM/WB: Instruction=%h, rd=x%0d, RegWrite=%b, MemToReg=%b",
158+
cpu.mem_wb_instruction, cpu.mem_wb_rd, cpu.mem_wb_reg_write,
159+
cpu.mem_wb_mem_to_reg);
160+
161+
// Hazard detection information
162+
if (cpu.stall) begin // Use cpu.stall directly instead of cpu.hazard_detection_unit.stall_pipeline
163+
$display("HAZARD DETECTED: Stalling pipeline");
164+
$display("Load-use hazard between instructions at PC=%h and PC=%h",
165+
cpu.if_id_pc - 4, cpu.if_id_pc);
166+
end
167+
168+
// Forwarding information
169+
if (cpu.forwardA != 0 || cpu.forwardB != 0) begin // Use cpu.forwardA/B directly
170+
$display("Forwarding active:");
171+
if (cpu.forwardA == 2'b10)
172+
$display("EX → EX Forwarding to rs1 (x%0d)", cpu.id_ex_rs1);
173+
if (cpu.forwardA == 2'b01)
174+
$display("MEM → EX Forwarding to rs1 (x%0d)", cpu.id_ex_rs1);
175+
if (cpu.forwardB == 2'b10)
176+
$display("EX → EX Forwarding to rs2 (x%0d)", cpu.id_ex_rs2);
177+
if (cpu.forwardB == 2'b01)
178+
$display("MEM → EX Forwarding to rs2 (x%0d)", cpu.id_ex_rs2);
179+
end
180+
181+
// Branch information
182+
if (cpu.branch && cpu.zero) begin // Use cpu.zero instead of cpu.alu_zero
183+
$display("Branch at PC=%h: Taking branch", cpu.pc_current);
184+
if (cpu.branch_mispredicted) // Use cpu.branch_mispredicted directly
185+
$display("Branch mispredicted: Pipeline flush required");
186+
end
187+
188+
// Pipeline stall/flush status
189+
if (cpu.flush) // Use cpu.flush instead of cpu.if_id_flush
190+
$display("Pipeline flushed");
148191
end
149192
end
150193

0 commit comments

Comments
 (0)