diff options
| -rw-r--r-- | conspiracion.qsf | 3 | ||||
| -rw-r--r-- | rtl/core/arm810.sv | 7 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 6 | ||||
| -rw-r--r-- | rtl/core/control/debug.sv | 25 | ||||
| -rw-r--r-- | rtl/core/control/issue.sv | 2 | ||||
| -rw-r--r-- | rtl/core/decode/decode.sv | 1 | ||||
| -rw-r--r-- | rtl/core/decode/mux.sv | 1 | ||||
| -rw-r--r-- | rtl/core/fetch/fetch.sv | 6 | ||||
| -rw-r--r-- | rtl/core/fetch/prefetch.sv | 6 | ||||
| -rw-r--r-- | rtl/core/porch/porch.sv | 8 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 1 | ||||
| -rw-r--r-- | rtl/top/conspiracion.sv | 1 | ||||
| -rw-r--r-- | sim/gdbstub.py | 24 | ||||
| -rwxr-xr-x | sim/sim.py | 5 | ||||
| -rw-r--r-- | tb/top/conspiracion.cpp | 9 |
15 files changed, 78 insertions, 27 deletions
diff --git a/conspiracion.qsf b/conspiracion.qsf index c6252b9..5dab632 100644 --- a/conspiracion.qsf +++ b/conspiracion.qsf @@ -212,6 +212,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/control.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/coproc.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/cycles.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/data.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/debug.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/exception.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/issue.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/core/control/mul.sv @@ -364,4 +365,4 @@ set_global_assignment -name SIGNALTAP_FILE bus_test.stp -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 05bce76..1771464 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -6,6 +6,7 @@ module arm810 rst_n, irq, halt, + step, output ptr bus_addr, output logic bus_start, @@ -21,19 +22,21 @@ module arm810 ptr fetch_insn_pc, fetch_head, insn_addr; word fetch_insn; - logic stall, flush, prefetch_flush, insn_start; + logic fetch_nop, stall, flush, prefetch_flush, insn_start; //TODO - assign prefetch_flush = 0; + assign prefetch_flush = halt; core_fetch #(.PREFETCH_ORDER(2)) fetch ( + .nop(fetch_nop), .addr(insn_addr), .insn(fetch_insn), .fetch(insn_start), .fetched(insn_ready), .insn_pc(fetch_insn_pc), .fetch_data(insn_data_rd), + .porch_insn_pc(insn_pc), .* ); diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 92e27d6..7658ee9 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -5,6 +5,7 @@ module core_control input logic clk, rst_n, halt, + step, input insn_decode dec, input ptr insn_pc, @@ -156,4 +157,9 @@ module core_control .* ); + core_control_debug ctrl_dbg + ( + .* + ); + endmodule diff --git a/rtl/core/control/debug.sv b/rtl/core/control/debug.sv new file mode 100644 index 0000000..35b1334 --- /dev/null +++ b/rtl/core/control/debug.sv @@ -0,0 +1,25 @@ +`include "core/uarch.sv" + +module core_control_debug +( + input logic clk, + rst_n, + step, + + input ctrl_cycle next_cycle, + input logic issue, + next_bubble, + input insn_decode dec, + + output logic breakpoint +); + + logic stable, step_trigger; + + assign stable = next_cycle.issue && !dec.ctrl.nop && !next_bubble; + assign breakpoint = stable && (dec.ctrl.bkpt || step_trigger); + + always @(posedge clk or negedge rst_n) + step_trigger <= !rst_n ? 0 : step && (step_trigger || stable) && !breakpoint; + +endmodule diff --git a/rtl/core/control/issue.sv b/rtl/core/control/issue.sv index b8cf3ff..ffdf250 100644 --- a/rtl/core/control/issue.sv +++ b/rtl/core/control/issue.sv @@ -18,7 +18,6 @@ module core_control_issue output logic issue, undefined, - breakpoint, output ptr pc, pc_visible, next_pc_visible @@ -28,7 +27,6 @@ module core_control_issue assign valid = !next_bubble && !halt; assign issue = next_cycle.issue && dec.ctrl.execute && valid; - assign breakpoint = issue && dec.ctrl.bkpt; assign next_pc_visible = insn_pc + 2; always_ff @(posedge clk or negedge rst_n) diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index 6534897..c4ffd52 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -26,6 +26,7 @@ module core_decode assign dec.branch = dec_branch; assign dec.coproc = dec_coproc; + assign dec_ctrl.nop = 0; assign dec_ctrl.mul = mul; assign dec_ctrl.psr = psr; assign dec_ctrl.ldst = ldst; diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv index f05b711..25e390b 100644 --- a/rtl/core/decode/mux.sv +++ b/rtl/core/decode/mux.sv @@ -262,7 +262,6 @@ module core_decode_mux mul = 1'bx; psr = 1'bx; - bkpt = 1'bx; ldst = 1'bx; branch = 1'bx; coproc = 1'bx; diff --git a/rtl/core/fetch/fetch.sv b/rtl/core/fetch/fetch.sv index acc8e9d..c024e7d 100644 --- a/rtl/core/fetch/fetch.sv +++ b/rtl/core/fetch/fetch.sv @@ -11,18 +11,20 @@ module core_fetch wr_pc, prefetch_flush, input ptr branch_target, + porch_insn_pc, input word wr_current, fetch_data, output logic fetch, flush, + nop, output word insn, output ptr insn_pc, addr, fetch_head ); - ptr next_pc, hold_addr, target; + ptr hold_addr, target; logic branch, prefetch_ready, fetched_valid, discard, pending, next_pending; assign fetch = prefetch_ready && !discard; @@ -44,7 +46,7 @@ module core_fetch if(branch) fetch_head = target; else if(prefetch_flush) - fetch_head = next_pc; + fetch_head = porch_insn_pc; else fetch_head = {30{1'bx}}; diff --git a/rtl/core/fetch/prefetch.sv b/rtl/core/fetch/prefetch.sv index 2f0a866..1b5a4c5 100644 --- a/rtl/core/fetch/prefetch.sv +++ b/rtl/core/fetch/prefetch.sv @@ -13,15 +13,17 @@ module core_prefetch output word insn, output ptr insn_pc, - next_pc, - output logic fetch + output logic fetch, + nop ); localparam SIZE = (1 << ORDER) - 1; + ptr next_pc; logic[31:0] prefetch[SIZE]; logic[ORDER - 1:0] valid; + assign nop = flush ? 1 : ~|valid; assign insn = flush ? `NOP : prefetch[0]; assign next_pc = ~stall & |valid ? insn_pc + 1 : insn_pc; assign fetch = !stall || ~&valid; diff --git a/rtl/core/porch/porch.sv b/rtl/core/porch/porch.sv index 238da88..4369836 100644 --- a/rtl/core/porch/porch.sv +++ b/rtl/core/porch/porch.sv @@ -9,6 +9,7 @@ module core_porch input psr_flags flags, input word fetch_insn, + input logic fetch_nop, input ptr fetch_insn_pc, fetch_head, input insn_decode fetch_dec, @@ -18,12 +19,13 @@ module core_porch output insn_decode dec ); - logic execute, conditional, undefined; + logic execute, conditional, undefined, nop; insn_decode hold_dec; always_comb begin dec = hold_dec; - dec.ctrl.execute = !flush && dec.ctrl.execute && execute; + dec.ctrl.nop = nop; + dec.ctrl.execute = !flush && dec.ctrl.execute && execute && !nop; dec.ctrl.undefined = !flush && (dec.ctrl.undefined || undefined); dec.ctrl.conditional = !flush && (dec.ctrl.conditional || conditional); end @@ -35,10 +37,12 @@ module core_porch always_ff @(posedge clk or negedge rst_n) if(!rst_n) begin + nop <= 0; // Even though it is a NOP insn <= `NOP; insn_pc <= 0; hold_dec <= {$bits(hold_dec){1'b0}}; end else if(flush || !stall) begin + nop <= flush ? 1 : fetch_nop; insn <= flush ? `NOP : fetch_insn; insn_pc <= flush ? fetch_head : fetch_insn_pc; hold_dec <= fetch_dec; diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index ac3b567..74e536b 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -88,6 +88,7 @@ typedef struct packed ldst, mul, psr, + nop, bkpt; } ctrl_decode; diff --git a/rtl/top/conspiracion.sv b/rtl/top/conspiracion.sv index 507a74c..c9e940f 100644 --- a/rtl/top/conspiracion.sv +++ b/rtl/top/conspiracion.sv @@ -3,6 +3,7 @@ module conspiracion input wire clk_clk, input wire rst_n, input wire halt, + input wire step, output wire cpu_halted, output wire breakpoint, output wire [12:0] memory_mem_a, diff --git a/sim/gdbstub.py b/sim/gdbstub.py index e214a73..75c15cb 100644 --- a/sim/gdbstub.py +++ b/sim/gdbstub.py @@ -22,8 +22,8 @@ def halt(): if haltFromStop: reply(b'S05') - haltFromStop = False + haltFromStop = True while True: data = client.recv(4096) if not data: @@ -52,9 +52,8 @@ def halt(): if data == b'?': out = b'S05' - elif data[0] == b'c'[0]: - assert not data[1:] #TODO - break + elif data == b'c': + return 'continue' elif data == b'D': out = b'OK' elif data == b'g': @@ -74,14 +73,14 @@ def halt(): elif data[0] == b'p'[0]: reg = gdb_reg(int(data[1:], 16)) out = hexout(read_reg(reg) if reg is not None else None) + elif data == b's': + return 'step' else: - print('unhandled packet:', data) + print('unhandled packet:', data, file=sys.stderr) out = b'' reply(out) - haltFromStop = True - def reply(out): client.send(b'$' + out + b'#' + hexout(sum(out) & 0xff, 1)) @@ -100,26 +99,27 @@ def gdb_reg(n): if mode == 0b10001: regs = (r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq) else: - regs = (r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq) + regs = (r8_usr, r9_usr, r10_usr, r11_usr, r12_usr) return regs[n - 8] if 13 <= n < 15: if mode == 0b10011: regs = (r13_svc, r14_svc) - if mode == 0b10111: + elif mode == 0b10111: regs = (r13_abt, r14_abt) - if mode == 0b11011: + elif mode == 0b11011: regs = (r13_und, r14_und) - if mode == 0b10010: + elif mode == 0b10010: regs = (r13_irq, r14_irq) - if mode == 0b10001: + elif mode == 0b10001: regs = (r13_fiq, r14_fiq) else: regs = (r13_usr, r14_usr) return regs[n - 13] + print('bad gdb regnum:', n, file=sys.stderr) return None def hexout(data, size=4): @@ -343,11 +343,12 @@ while True: else: break + mode = None halted = True if halt: - halt() + mode = halt() - print('continue', file=sim_end, flush=True) + print('step' if mode == 'step' else 'continue', file=sim_end, flush=True) if not halt: break diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp index 96fd57f..bd1086a 100644 --- a/tb/top/conspiracion.cpp +++ b/tb/top/conspiracion.cpp @@ -391,6 +391,7 @@ int main(int argc, char **argv) ttyJ0.takeover(); } + top.step = 0; top.halt = start_halted; top.rst_n = 0; cycle(); @@ -458,6 +459,9 @@ int main(int argc, char **argv) if(top.cpu_halted) { + top.step = 0; + top.halt = 0; + do_reg_dump(); std::fputs("=== halted ===\n", ctrl); @@ -486,7 +490,10 @@ int main(int argc, char **argv) const char *cmd = std::strtok(line, " "); if(!std::strcmp(cmd, "continue")) { - top.halt = 0; + break; + } else if(!std::strcmp(cmd, "step")) + { + top.step = 1; break; } else if(!std::strcmp(cmd, "dump-mem")) { |
