aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-08-26 14:54:27 +0200
committerClifford Wolf <clifford@clifford.at>2016-08-26 14:54:27 +0200
commit98d248d2c2f785f1b35ce7a08df7705e1945597f (patch)
tree67560a9a31fd39220d27c6bef2afd665dc50e59a
parent7094e61af7dfe3c24ff4218557b209a1b09e5793 (diff)
downloadpicorv32-98d248d2c2f785f1b35ce7a08df7705e1945597f.tar.gz
picorv32-98d248d2c2f785f1b35ce7a08df7705e1945597f.zip
Finalized tracer support
-rw-r--r--Makefile2
-rw-r--r--README.md7
-rw-r--r--picorv32.v6
-rw-r--r--showtrace.py26
-rw-r--r--testbench.v3
5 files changed, 34 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index bb73fd9..c585588 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ test: testbench.vvp firmware/firmware.hex
vvp -N testbench.vvp
testbench.vcd: testbench.vvp firmware/firmware.hex
- vvp -N $< +vcd +trace
+ vvp -N $< +vcd +trace +noerror
view: testbench.vcd
gtkwave $< testbench.gtkw
diff --git a/README.md b/README.md
index 51eb17e..2ebf19a 100644
--- a/README.md
+++ b/README.md
@@ -256,6 +256,13 @@ Set this to 0 to disable support for the `timer` instruction.
Support for the timer is always disabled when ENABLE_IRQ is set to 0.
+#### ENABLE_TRACE (default = 0)
+
+Produce an execution trace using the `trace_valid` and `trace_data` output ports.
+For a demontration of this feature run `make testbench.vcd` to create a trace file
+and then run `python3 showtrace.py testbench.trace firmware/firmware.elf` to decode
+it.
+
#### REGS_INIT_ZERO (default = 0)
Set this to 1 to initialize all registers to zero (using a Verilog `initial` block).
diff --git a/picorv32.v b/picorv32.v
index a2dc8a2..1400e0c 100644
--- a/picorv32.v
+++ b/picorv32.v
@@ -1236,7 +1236,7 @@ module picorv32 #(
latched_trace <= 0;
trace_valid <= 1;
if (latched_branch)
- trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | current_pc;
+ trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_BRANCH | (current_pc & 32'hfffffffe);
else
trace_data <= (irq_active ? TRACE_IRQ : 0) | (latched_stalu ? alu_out_q : reg_out);
end
@@ -1556,7 +1556,7 @@ module picorv32 #(
endcase
if (ENABLE_TRACE) begin
trace_valid <= 1;
- trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | (reg_op1 + decoded_imm);
+ trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff);
end
reg_op1 <= reg_op1 + decoded_imm;
set_mem_do_wdata = 1;
@@ -1584,7 +1584,7 @@ module picorv32 #(
latched_is_lb <= instr_lb;
if (ENABLE_TRACE) begin
trace_valid <= 1;
- trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | (reg_op1 + decoded_imm);
+ trace_data <= (irq_active ? TRACE_IRQ : 0) | TRACE_ADDR | ((reg_op1 + decoded_imm) & 32'hffffffff);
end
reg_op1 <= reg_op1 + decoded_imm;
set_mem_do_rdata = 1;
diff --git a/showtrace.py b/showtrace.py
index 56c91ff..7d7316a 100644
--- a/showtrace.py
+++ b/showtrace.py
@@ -23,6 +23,7 @@ with open(trace_filename, "r") as f:
irq_active = (raw_data & 0x800000000) != 0
is_addr = (raw_data & 0x200000000) != 0
is_branch = (raw_data & 0x100000000) != 0
+ info = "%s %s%08x" % ("IRQ" if irq_active else " ", ">" if is_branch else "@" if is_addr else "=", payload)
if irq_active and not last_irq:
pc = 0x10
@@ -30,18 +31,31 @@ with open(trace_filename, "r") as f:
if pc >= 0:
if pc in insns:
insn_opcode, insn_desc = insns[pc]
+ opname = insn_desc.split()[0]
+
+ if insn_desc.startswith("custom0 0,0,0,2"):
+ opname = "retirq"
+
+ if is_branch and opname not in ["j", "jal", "jr", "jalr", "ret", "retirq",
+ "beq", "bne", "blt", "ble", "bge", "bgt", "bltu", "bleu", "bgeu", "bgtu",
+ "beqz", "bnez", "blez", "bgez", "bltz", "bgtz"]:
+ print("%s ** UNEXPECTED BRANCH DATA FOR INSN AT %08x! **" % (info, pc))
+
+ if is_addr and opname not in ["lb", "lh", "lw", "lbu", "lhu", "sb", "sh", "sw"]:
+ print("%s ** UNEXPECTED ADDR DATA FOR INSN AT %08x! **" % (info, pc))
+
opcode_fmt = "%08x" if (insn_opcode & 3) == 3 else " %04x"
- print(("%s %s%08x | %08x | " + opcode_fmt + " | %s") % ("IRQ" if irq_active else " ",
- ">" if is_branch else "@" if is_addr else "=", payload, pc, insn_opcode, insn_desc))
+ print(("%s | %08x | " + opcode_fmt + " | %s") % (info, pc, insn_opcode, insn_desc))
if not is_addr:
pc += 4 if (insn_opcode & 3) == 3 else 2
else:
- print("%s %s%08x ** NO INFORMATION ON INSN AT %08x! **" % ("IRQ" if irq_active else " ",
- ">" if is_branch else "@" if is_addr else "=", payload, pc))
+ print("%s ** NO INFORMATION ON INSN AT %08x! **" % (info, pc))
pc = -1
else:
- print("%s %s%08x ** SKIPPING DATA UNTIL NEXT BRANCH **" % ("IRQ" if irq_active else " ",
- ">" if is_branch else "@" if is_addr else "=", payload))
+ if is_branch:
+ print("%s ** FOUND BRANCH AND STARTING DECODING **" % info)
+ else:
+ print("%s ** SKIPPING DATA UNTIL NEXT BRANCH **" % info)
if is_branch:
pc = payload
diff --git a/testbench.v b/testbench.v
index dc7a7f3..18cce40 100644
--- a/testbench.v
+++ b/testbench.v
@@ -48,6 +48,7 @@ module testbench #(
$fwrite(trace_file, "%x\n", trace_data);
end
$fclose(trace_file);
+ $display("Finished writing testbench.trace.");
end
end
@@ -194,6 +195,8 @@ module picorv32_wrapper #(
$finish;
end else begin
$display("ERROR!");
+ if ($test$plusargs("noerror"))
+ $finish;
$stop;
end
end