diff --git a/bin/hw_debug_test.py b/bin/hw_debug_test.py index c78484926..c77577057 100755 --- a/bin/hw_debug_test.py +++ b/bin/hw_debug_test.py @@ -42,105 +42,99 @@ def prog_buff_test(cvw): print() -def flow_control_test(): - with OpenOCD() as cvw: - cvw.reset_dm() - cvw.reset_hart() +def flow_control_test(cvw): + #time.sleep(70) # wait for OpenSBI - cvw.halt() - cvw.read_data("DCSR") - for _ in range(50): - cvw.step() - print(cvw.read_data("PCM")) - cvw.resume() + cvw.halt() + cvw.read_data("DCSR") + for _ in range(50): + cvw.step() + print(cvw.read_data("PCM")) + cvw.resume() -def register_rw_test(): - with OpenOCD() as cvw: - registers = dict.fromkeys(cvw.register_translations.keys(),[]) - reg_addrs = list(registers.keys()) +def register_rw_test(cvw): + registers = dict.fromkeys(cvw.register_translations.keys(),[]) + reg_addrs = list(registers.keys()) - global XLEN - XLEN = cvw.LLEN - global nonstandard_register_lengths - nonstandard_register_lengths = cvw.nonstandard_register_lengths + global XLEN + XLEN = cvw.LLEN + global nonstandard_register_lengths + nonstandard_register_lengths = cvw.nonstandard_register_lengths - cvw.reset_dm() - cvw.reset_hart() + #time.sleep(70) # wait for OpenSBI - #time.sleep(70) # wait for OpenSBI + cvw.halt() - cvw.halt() - - # dump data in all registers - for r in reg_addrs: - try: - data = cvw.read_data(r) - registers[r] = data - print(f"{r}: {data}") - except Exception as e: - if e.args[0] == "exception": # Invalid register (not implemented) - del registers[r] - cvw.clear_abstrcmd_err() - else: - raise e - input("Compare values to ILA, press any key to continue") - - # Write random data to all registers - reg_addrs = list(registers.keys()) - if random_order: - random.shuffle(reg_addrs) - test_reg_data = {} - for r in reg_addrs: - test_data = random_hex(r) - try: - cvw.write_data(r, test_data) - test_reg_data[r] = test_data - print(f"Writing {test_data} to {r}") - except Exception as e: - if e.args[0] == "not supported": # Register is read only - del registers[r] - cvw.clear_abstrcmd_err() - else: - raise e - - # GPR X0 is always 0 - test_reg_data["x0"] = "0x" + "0"*(cvw.LLEN//4) - - # Confirm data was written correctly - reg_addrs = list(registers.keys()) - if random_order: - random.shuffle(reg_addrs) - for r in reg_addrs: - try: - rdata = cvw.read_data(r) - except Exception as e: - raise e - if rdata != test_reg_data[r]: - print(f"Error: register {r} read did not return correct data: {rdata} != {test_reg_data[r]}") + # dump data in all registers + for r in reg_addrs: + try: + data = cvw.read_data(r) + registers[r] = data + print(f"{r}: {data}") + except Exception as e: + if e.args[0] == "exception": # Invalid register (not implemented) + del registers[r] + cvw.clear_abstrcmd_err() else: - print(f"Reading {rdata} from {r}") + raise e + input("Compare values to ILA, press any key to continue") - # Return all registers to original state - reg_addrs = list(registers.keys()) - for r in reg_addrs: - print(f"Writing {registers[r]} to {r}") - try: - cvw.write_data(r, registers[r]) - except Exception as e: + # Write random data to all registers + reg_addrs = list(registers.keys()) + if random_order: + random.shuffle(reg_addrs) + test_reg_data = {} + for r in reg_addrs: + test_data = random_hex(r) + try: + cvw.write_data(r, test_data) + test_reg_data[r] = test_data + print(f"Writing {test_data} to {r}") + except Exception as e: + if e.args[0] == "not supported": # Register is read only + del registers[r] + cvw.clear_abstrcmd_err() + else: raise e - # Confirm data was written correctly - for r in reg_addrs: - try: - rdata = cvw.read_data(r) - except Exception as e: - raise e - if rdata != registers[r]: - raise Exception(f"Register {r} read did not return correct data: {rdata} != {registers[r]}") - print("All writes successful") + # GPR X0 is always 0 + test_reg_data["x0"] = "0x" + "0"*(cvw.LLEN//4) - cvw.resume() + # Confirm data was written correctly + reg_addrs = list(registers.keys()) + if random_order: + random.shuffle(reg_addrs) + for r in reg_addrs: + try: + rdata = cvw.read_data(r) + except Exception as e: + raise e + if rdata != test_reg_data[r]: + print(f"Error: register {r} read did not return correct data: {rdata} != {test_reg_data[r]}") + else: + print(f"Reading {rdata} from {r}") + + # Return all registers to original state + reg_addrs = list(registers.keys()) + for r in reg_addrs: + print(f"Writing {registers[r]} to {r}") + try: + cvw.write_data(r, registers[r]) + except Exception as e: + raise e + + # Confirm data was written correctly + for r in reg_addrs: + try: + rdata = cvw.read_data(r) + except Exception as e: + raise e + if rdata != registers[r]: + raise Exception(f"Register {r} read did not return correct data: {rdata} != {registers[r]}") + print("All writes successful") + + cvw.resume() def random_hex(reg_name): @@ -160,8 +154,11 @@ def random_hex(reg_name): with OpenOCD() as cvw: + print(cvw.read_dmi("0x16")) + cvw.trst() cvw.reset_dm() cvw.reset_hart() - #register_rw_test() - #flow_control_test() - prog_buff_test(cvw) + quit() + #register_rw_test(cvw) + flow_control_test(cvw) + #prog_buff_test(cvw) diff --git a/src/debug/dm.sv b/src/debug/dm.sv index 4e7879f7f..132f902db 100644 --- a/src/debug/dm.sv +++ b/src/debug/dm.sv @@ -98,7 +98,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( // [0] = 1 localparam JTAG_DEVICE_ID = 32'h1002AC05; - dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .tck, .tdi, .tms, .tdo, + dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .rst, .tck, .tdi, .tms, .tdo, .ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady, .RspValid, .RspData, .RspOP); @@ -253,7 +253,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( {2'bx,`HARTINFO}, {2'bx,`ABSTRACTAUTO}, {2'bx,`NEXTDM} : State <= READ_ZERO; - default : State <= INVALID; + default : State <= READ_ZERO;//INVALID; endcase end @@ -388,7 +388,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( end INVALID : begin - RspOP <= `OP_FAILED; + RspOP <= `OP_SUCCESS;//`OP_FAILED; State <= ACK; end endcase diff --git a/src/debug/dmc.sv b/src/debug/dmc.sv index 4b0ac8d16..719e9f02e 100644 --- a/src/debug/dmc.sv +++ b/src/debug/dmc.sv @@ -65,7 +65,7 @@ module dmc ( assign DebugMode = (State != RUNNING); assign DebugStall = (State == HALTED); - assign EnterDebugMode = (State == FLUSH) & (Counter == 0); + assign EnterDebugMode = (State == FLUSH) & ~|Counter; assign ExitDebugMode = (State == HALTED) & ResumeReq; assign ForceNOP = (State == FLUSH); @@ -77,7 +77,7 @@ module dmc ( case (State) RUNNING : begin if (HaltReq) begin - Counter <= 0; + Counter <= NOP_CYCLE_DURATION; State <= FLUSH; DebugCause <= `CAUSE_HALTREQ; end @@ -87,25 +87,22 @@ module dmc ( // fill the pipe with NOP before halting FLUSH : begin - if (Counter == NOP_CYCLE_DURATION) + if (~|Counter) State <= HALTED; else - Counter <= Counter + 1; + Counter <= Counter - 1; end HALTED : begin - if (ResumeReq) - State <= RESUME; - end - - RESUME : begin - if (Step) begin - Counter <= 0; - State <= FLUSH; - DebugCause <= `CAUSE_STEP; - end else begin - State <= RUNNING; - ResumeAck <= 1; + if (ResumeReq) begin + if (Step) begin + Counter <= NOP_CYCLE_DURATION; + State <= FLUSH; + DebugCause <= `CAUSE_STEP; + end else begin + State <= RUNNING; + ResumeAck <= 1; + end end end endcase diff --git a/src/debug/dtm.sv b/src/debug/dtm.sv index 16e8fd96b..da748fadb 100644 --- a/src/debug/dtm.sv +++ b/src/debug/dtm.sv @@ -31,7 +31,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) ( // System clock - input logic clk, + input logic clk, rst, // External JTAG signals input logic tck, input logic tdi, @@ -90,7 +90,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) ( // DTMCS assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version}; always_ff @(posedge clk) begin - if (~resetn | DtmHardReset) begin + if (rst | ~resetn | DtmHardReset) begin DtmHardReset <= 0; DmiReset <= 0; end else if (UpdateDtmcs) begin @@ -103,7 +103,7 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) ( // DMI always_ff @(posedge clk) begin - if (~resetn | DtmHardReset) begin + if (rst | ~resetn | DtmHardReset) begin ValRspData <= 0; ValRspOP <= `OP_SUCCESS; //ErrInfo <= 4; diff --git a/src/debug/ir.sv b/src/debug/ir.sv index dd99c7cc1..61651c5cf 100644 --- a/src/debug/ir.sv +++ b/src/debug/ir.sv @@ -48,15 +48,10 @@ module ir ( assign tdo = shift_reg[0]; // Shift register - always @(posedge clockIR) begin - shift_reg[0] <= shift_reg[1] | captureIR; - end + flop #(1) shift_regmsb (.clk(clockIR), .d(shift_reg[1] | captureIR), .q(shift_reg[0])); genvar i; - for (i = INST_REG_WIDTH; i > 1; i = i - 1) begin - always @(posedge clockIR) begin - shift_reg[i-1] <= shift_reg[i] & ~captureIR; - end - end + for (i = INST_REG_WIDTH; i > 1; i = i - 1) + flop #(1) shift_reg (.clk(clockIR), .d(shift_reg[i] & ~captureIR), .q(shift_reg[i-1])); // Instruction decoder // 6.1.2 diff --git a/src/debug/jtag.sv b/src/debug/jtag.sv index 221f4eb40..c7c2ec0f9 100644 --- a/src/debug/jtag.sv +++ b/src/debug/jtag.sv @@ -26,6 +26,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) ( + input logic rst, // JTAG signals input logic tck, input logic tdi, @@ -79,7 +80,7 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) ( assign CaptureDmi = captureDR & DmiInstr; assign UpdateDmi = updateDR & DmiInstr; - tap tap (.tck, .tms, .resetn, .tdo_en, .captureIR, + tap tap (.rst, .tck, .tms, .resetn, .tdo_en, .captureIR, .clockIR, .updateIR, .shiftDR, .captureDR, .clockDR, .updateDR, .select); // IR/DR input demux @@ -103,34 +104,23 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) ( endcase end - always_ff @(posedge UpdateDtmcs) - DtmcsIn <= DtmcsShiftReg[31:0]; - - always_ff @(posedge UpdateDmi) - DmiIn <= DmiShiftReg[34+ADDR_WIDTH-1:0]; + flopr #(32) dtmcsreg (.clk(UpdateDtmcs), .reset(rst), .d(DtmcsShiftReg[31:0]), .q(DtmcsIn)); + flopr #(34+ADDR_WIDTH) dmireg (.clk(UpdateDmi), .reset(rst), .d(DmiShiftReg[34+ADDR_WIDTH-1:0]), .q(DmiIn)); assign DtmcsShiftReg[32] = tdi_dr; assign tdo_dtmcs = DtmcsShiftReg[0]; - for (i = 0; i < 32; i = i + 1) begin - always_ff @(posedge clockDR) begin - DtmcsShiftReg[i] <= captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1]; - end - end + for (i = 0; i < 32; i = i + 1) + flopr #(1) dtmcsshiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1]), .q(DtmcsShiftReg[i])); assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr; assign tdo_dmi = DmiShiftReg[0]; - for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) begin - always_ff @(posedge clockDR) begin - DmiShiftReg[i] <= captureDR ? DmiOut[i] : DmiShiftReg[i+1]; - end - end + for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) + flopr #(1) dmishiftreg (.clk(clockDR), .reset(rst), .d(captureDR ? DmiOut[i] : DmiShiftReg[i+1]), .q(DmiShiftReg[i])); // jtag id register idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode)); // bypass register - always_ff @(posedge clockDR) begin - tdo_bypass <= tdi_dr & shiftDR; - end + flopr #(1) bypassreg (.clk(clockDR), .reset(rst), .d(tdi_dr & shiftDR), .q(tdo_bypass)); endmodule diff --git a/src/debug/tap.sv b/src/debug/tap.sv index b76afca8f..e781595e8 100644 --- a/src/debug/tap.sv +++ b/src/debug/tap.sv @@ -26,6 +26,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module tap ( + input logic rst, input logic tck, input logic tms, output logic resetn, @@ -40,6 +41,8 @@ module tap ( output logic select ); + logic tckn; + enum logic [3:0] { Exit2DR = 4'h0, Exit1DR = 4'h1, @@ -59,36 +62,39 @@ module tap ( TLReset = 4'hF } State; - always @(posedge tck) begin - case (State) - TLReset : State <= tms ? TLReset : RunTestIdle; - RunTestIdle : State <= tms ? SelectDR : RunTestIdle; - SelectDR : State <= tms ? SelectIR : CaptureDR; - CaptureDR : State <= tms ? Exit1DR : ShiftDR; - ShiftDR : State <= tms ? Exit1DR : ShiftDR; - Exit1DR : State <= tms ? UpdateDR : PauseDR; - PauseDR : State <= tms ? Exit2DR : PauseDR; - Exit2DR : State <= tms ? UpdateDR : ShiftDR; - UpdateDR : State <= tms ? SelectDR : RunTestIdle; - SelectIR : State <= tms ? TLReset : CaptureIR; - CaptureIR : State <= tms ? Exit1IR : ShiftIR; - ShiftIR : State <= tms ? Exit1IR : ShiftIR; - Exit1IR : State <= tms ? UpdateIR : PauseIR; - PauseIR : State <= tms ? Exit2IR : PauseIR; - Exit2IR : State <= tms ? UpdateIR : ShiftIR; - UpdateIR : State <= tms ? SelectDR : RunTestIdle; - endcase + always @(posedge rst, posedge tck) begin + if (rst) + State <= TLReset; + else + case (State) + TLReset : State <= tms ? TLReset : RunTestIdle; + RunTestIdle : State <= tms ? SelectDR : RunTestIdle; + SelectDR : State <= tms ? SelectIR : CaptureDR; + CaptureDR : State <= tms ? Exit1DR : ShiftDR; + ShiftDR : State <= tms ? Exit1DR : ShiftDR; + Exit1DR : State <= tms ? UpdateDR : PauseDR; + PauseDR : State <= tms ? Exit2DR : PauseDR; + Exit2DR : State <= tms ? UpdateDR : ShiftDR; + UpdateDR : State <= tms ? SelectDR : RunTestIdle; + SelectIR : State <= tms ? TLReset : CaptureIR; + CaptureIR : State <= tms ? Exit1IR : ShiftIR; + ShiftIR : State <= tms ? Exit1IR : ShiftIR; + Exit1IR : State <= tms ? UpdateIR : PauseIR; + PauseIR : State <= tms ? Exit2IR : PauseIR; + Exit2IR : State <= tms ? UpdateIR : ShiftIR; + UpdateIR : State <= tms ? SelectDR : RunTestIdle; + endcase end + + assign tckn = ~tck; - always @(negedge tck) begin - resetn <= ~(State == TLReset); - tdo_en <= State == ShiftIR | State == ShiftDR; - captureIR <= State == CaptureIR; - updateIR <= State == UpdateIR; - shiftDR <= State == ShiftDR; - captureDR <= State == CaptureDR; - updateDR <= State == UpdateDR; - end + flopr #(1) resetnreg (.clk(tckn), .reset(rst), .d(~(State == TLReset)), .q(resetn)); + flopr #(1) tdo_enreg (.clk(tckn), .reset(rst), .d(State == ShiftIR | State == ShiftDR), .q(tdo_en)); + flopr #(1) captureIRreg (.clk(tckn), .reset(rst), .d(State == CaptureIR), .q(captureIR)); + flopr #(1) updateIRreg (.clk(tckn), .reset(rst), .d(State == UpdateIR), .q(updateIR)); + flopr #(1) shiftDRreg (.clk(tckn), .reset(rst), .d(State == ShiftDR), .q(shiftDR)); + flopr #(1) captureDRreg (.clk(tckn), .reset(rst), .d(State == CaptureDR), .q(captureDR)); + flopr #(1) updateDRreg (.clk(tckn), .reset(rst), .d(State == UpdateDR), .q(updateDR)); assign clockIR = tck | State[0] | ~State[1] | ~State[3]; assign clockDR = tck | State[0] | ~State[1] | State[3];