diff --git a/regression/Makefile b/regression/Makefile index 32cf5b05..b1218cfd 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -222,8 +222,8 @@ JTAG_DTM_TEST ?= SimpleRegisterTest.test_s0 stamps/%/jtag-dtm-32-$(JTAG_DTM_TEST).stamp: install_openocd stamps/%/vsim-ndebug.stamp $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \ - --run $(abspath $(TOP))/vsim/simv-$(PROJECT)-$* \ - --cmd="$(OPENOCD_DIR)/bin/openocd \ + --run "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*" \ + --cmd="$(OPENOCD_DIR)/bin/openocd -d \ --s $(OPENOCD_DIR)/share/openocd/scripts" \ --freedom-e300-sim \ $(JTAG_DTM_TEST) @@ -232,7 +232,7 @@ stamps/%/jtag-dtm-32-$(JTAG_DTM_TEST).stamp: install_openocd stamps/%/vsim-ndebu stamps/%/jtag-dtm-64-$(JTAG_DTM_TEST).stamp: install_openocd stamps/%/vsim-ndebug.stamp $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \ --run $(abspath $(TOP))/vsim/simv-$(PROJECT)-$* \ - --cmd="$(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/bin/openocd \ + --cmd="$(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/bin/openocd -d \ --s $(OPENOCD_INSTALL)_$(OPENOCD_VERSION)/share/openocd/scripts" \ --freedom-u500-sim \ $(JTAG_DTM_TEST) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 06c9b709..2e14b362 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -100,7 +100,7 @@ class BaseCoreplexConfig extends Config ( case UseCompressed => true case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen)) case NCustomMRWCSRs => 0 - case MtvecInit => None + case MtvecInit => Some(BigInt(0)) case MtvecWritable => true //Uncore Paramters case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients diff --git a/src/main/scala/rocketchip/DebugTransport.scala b/src/main/scala/rocketchip/DebugTransport.scala index 99043538..74078853 100644 --- a/src/main/scala/rocketchip/DebugTransport.scala +++ b/src/main/scala/rocketchip/DebugTransport.scala @@ -55,7 +55,7 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) val jtag_dtm = Module (new DebugTransportModuleJtag(req_width, resp_width)) - jtag_dtm.io.jtag <> io.jtag + jtag_dtm.io.jtag := io.jtag val dtm_req = Wire(new DecoupledIO(UInt(width = req_width))) val dtm_resp = Wire(new DecoupledIO(UInt(width = resp_width))) @@ -73,6 +73,9 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) dtm_resp.valid := io_debug_bus.resp.valid dtm_resp.bits := io_debug_bus.resp.bits.asUInt io_debug_bus.resp.ready := dtm_resp.ready + + dtm_req := jtag_dtm.io.dtm_req + jtag_dtm.io.dtm_resp := dtm_resp } class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters) extends BlackBox { diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index 27f27307..9997f493 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -475,16 +475,23 @@ class DebugModule ()(implicit val p:cde.Parameters) val ramWrEn = Wire(Bool()) val dbRamAddr = Wire(UInt(width=dbRamAddrWidth)) + val dbRamAddrValid = Wire(Bool()) val dbRamRdData = Wire (UInt(width=dbRamDataWidth)) val dbRamWrData = Wire(UInt(width=dbRamDataWidth)) val dbRamWrEn = Wire(Bool()) val dbRamRdEn = Wire(Bool()) + val dbRamWrEnFinal = Wire(Bool()) + val dbRamRdEnFinal = Wire(Bool()) val sbRamAddr = Wire(UInt(width=sbRamAddrWidth)) + val sbRamAddrValid = Wire(Bool()) val sbRamRdData = Wire (UInt(width=sbRamDataWidth)) val sbRamWrData = Wire(UInt(width=sbRamDataWidth)) val sbRamWrEn = Wire(Bool()) val sbRamRdEn = Wire(Bool()) + val sbRamWrEnFinal = Wire(Bool()) + val sbRamRdEnFinal = Wire(Bool()) + val sbRomRdData = Wire(UInt(width=tlDataBits)) val sbRomAddrOffset = log2Up(tlDataBits/8) @@ -624,8 +631,18 @@ class DebugModule ()(implicit val p:cde.Parameters) // 0x40 - 0x6F Not Implemented dbRamAddr := dbReq.addr( dbRamAddrWidth-1 , 0) dbRamWrData := dbReq.data + dbRamAddrValid := Bool(true) + if (dbRamAddrWidth < 4){ + dbRamAddrValid := (dbReq.addr(3, dbRamAddrWidth) === UInt(0)) + } + sbRamAddr := sbAddr(sbRamAddrWidth + sbRamAddrOffset - 1, sbRamAddrOffset) sbRamWrData := sbWrData + sbRamAddrValid := Bool(true) + // From Specification: Debug RAM is 0x400 - 0x4FF + if ((sbRamAddrWidth + sbRamAddrOffset) < 8){ + sbRamAddrValid := (sbAddr(7, sbRamAddrWidth + sbRamAddrOffset) === UInt(0)) + } require (dbRamAddrWidth >= ramAddrWidth) // SB accesses less than 32 bits Not Implemented. val dbRamWrMask = Wire(init=Vec.fill(1 << (dbRamAddrWidth - ramAddrWidth)){Fill(dbRamDataWidth, UInt(1, width=1))}) @@ -661,7 +678,7 @@ class DebugModule ()(implicit val p:cde.Parameters) ramRdData := ramMem(ramAddr) when (ramWrEn) { ramMem(ramAddr) := ramWrData } - ramWrEn := sbRamWrEn | dbRamWrEn + ramWrEn := sbRamWrEnFinal | dbRamWrEnFinal //-------------------------------------------------------------- // Debug Bus Access @@ -680,11 +697,15 @@ class DebugModule ()(implicit val p:cde.Parameters) CONTROLWrData := new CONTROLFields().fromBits(dbReq.data) RAMWrData := new RAMFields().fromBits(dbReq.data) - dbRamWrEn := Bool(false) - CONTROLWrEn := Bool(false) - when ((dbReq.addr >> 4) === Bits(0)) { // 0x00 - 0x0F Debug RAM + dbRamWrEn := Bool(false) + dbRamWrEnFinal := Bool(false) + CONTROLWrEn := Bool(false) + when ((dbReq.addr >> 4) === Bits(0)) { // 0x00 - 0x0F Debug RAM dbRamWrEn := dbWrEn - }.elsewhen (dbReq.addr === DMCONTROL) { + when (dbRamAddrValid) { + dbRamWrEnFinal := dbWrEn + } + }.elsewhen (dbReq.addr === DMCONTROL) { CONTROLWrEn := dbWrEn }.otherwise { //Other registers/RAM are Not Implemented. @@ -739,10 +760,14 @@ class DebugModule ()(implicit val p:cde.Parameters) } } - dbRamRdEn := Bool(false) - when ((dbReq.addr >> 4) === Bits(0)) { // 0x00 - 0x0F Debug RAM - dbRdData := RAMRdData.asUInt + dbRamRdEn := Bool(false) + dbRamRdEnFinal := Bool(false) + when ((dbReq.addr >> 4) === Bits(0)) { // 0x00 - 0x0F Debug RAM dbRamRdEn := dbRdEn + when (dbRamAddrValid) { + dbRdData := RAMRdData.asUInt + dbRamRdEnFinal := dbRdEn + } }.elsewhen (dbReq.addr === DMCONTROL) { dbRdData := CONTROLRdData.asUInt }.elsewhen (dbReq.addr === DMINFO) { @@ -849,6 +874,7 @@ class DebugModule ()(implicit val p:cde.Parameters) // SB Access Write Decoder sbRamWrEn := Bool(false) + sbRamWrEnFinal := Bool(false) SETHALTNOTWrEn := Bool(false) CLEARDEBINTWrEn := Bool(false) @@ -858,6 +884,10 @@ class DebugModule ()(implicit val p:cde.Parameters) when (sbAddr(11, 8) === UInt(4)){ // 0x400-0x4ff is Debug RAM sbRamWrEn := sbWrEn sbRamRdEn := sbRdEn + when (sbRamAddrValid) { + sbRamWrEnFinal := sbWrEn + sbRamRdEnFinal := sbRdEn + } }.elsewhen (sbAddr === SETHALTNOT){ SETHALTNOTWrEn := sbWrEn }.elsewhen (sbAddr === CLEARDEBINT){ @@ -880,6 +910,10 @@ class DebugModule ()(implicit val p:cde.Parameters) when (sbAddr(11,8) === UInt(4)){ //0x400-0x4ff is Debug RAM sbRamWrEn := sbWrEn sbRamRdEn := sbRdEn + when (sbRamAddrValid){ + sbRamWrEnFinal := sbWrEn + sbRamRdEnFinal := sbRdEn + } } SETHALTNOTWrEn := sbAddr(sbAddrWidth - 1, sbWrSelTop + 1) === SETHALTNOT(sbAddrWidth-1, sbWrSelTop + 1) && @@ -896,12 +930,15 @@ class DebugModule ()(implicit val p:cde.Parameters) // SB Access Read Mux sbRdData := UInt(0) - sbRamRdEn := Bool(false) + sbRamRdEn := Bool(false) + sbRamRdEnFinal := Bool(false) - dbRamRdEn := Bool(false) when (sbAddr(11, 8) === UInt(4)) { //0x400-0x4FF Debug RAM - sbRdData := sbRamRdData sbRamRdEn := sbRdEn + when (sbRamAddrValid) { + sbRdData := sbRamRdData + sbRamRdEnFinal := sbRdEn + } }.elsewhen (sbAddr(11,8).isOneOf(UInt(8), UInt(9))){ //0x800-0x9FF Debug ROM if (cfg.hasDebugRom) { sbRdData := sbRomRdData diff --git a/vsrc/DebugTransportModuleJtag.v b/vsrc/DebugTransportModuleJtag.v index 7c9b81c7..da74adde 100755 --- a/vsrc/DebugTransportModuleJtag.v +++ b/vsrc/DebugTransportModuleJtag.v @@ -9,7 +9,7 @@ module DebugTransportModuleJtag ( jtag_TCK, jtag_TMS, jtag_TRST, - + jtag_DRV_TDO, dtm_req_valid, @@ -27,15 +27,22 @@ module DebugTransportModuleJtag ( parameter DEBUG_DATA_BITS = 34; parameter DEBUG_ADDR_BITS = 5; // Spec allows values are 5-7 parameter DEBUG_OP_BITS = 2; // OP and RESP are the same size. - + parameter JTAG_VERSION = 4'h1; parameter JTAG_PART_NUM = 16'h0E31; // E31 parameter JTAG_MANUF_ID = 11'h489; // As Assigned by JEDEC - + + // Number of cycles which must remain in IDLE + // The software should handle even if the + // answer is actually higher than this, or + // the software may choose to ignore it entirely + // and just check for busy. + parameter DBUS_IDLE_CYCLES = 3'h5; + localparam IR_BITS = 5; localparam DEBUG_VERSION = 0; - + // JTAG State Machine localparam TEST_LOGIC_RESET = 4'h0; localparam RUN_TEST_IDLE = 4'h1; @@ -78,16 +85,15 @@ module DebugTransportModuleJtag ( input jtag_TMS; input jtag_TRST; - // To allow tri-state outside of this block. output reg jtag_DRV_TDO; // RISC-V Core Side - + output dtm_req_valid; input dtm_req_ready; output [DBUS_REQ_BITS - 1 :0] dtm_req_bits; - + input dtm_resp_valid; output dtm_resp_ready; input [DBUS_RESP_BITS - 1 : 0] dtm_resp_bits; @@ -110,9 +116,11 @@ module DebugTransportModuleJtag ( reg doDbusReadReg; reg busyReg; + reg stickyBusyReg; + reg stickyNonzeroRespReg; + reg skipOpReg; // Skip op because we're busy. reg downgradeOpReg; // Downgrade op because prev. op failed. - wire busy; wire nonzeroResp; @@ -127,15 +135,30 @@ module DebugTransportModuleJtag ( wire [3:0] debugAddrBits = DEBUG_ADDR_BITS[3:0]; wire [3:0] debugVersion = DEBUG_VERSION[3:0]; + + wire [1:0] dbusStatus; + wire [2:0] dbusIdleCycles; + + wire dbusReset; - assign dtminfo = {24'b0, debugAddrBits, debugVersion}; + assign dbusIdleCycles = DBUS_IDLE_CYCLES; + assign dbusStatus = {stickyNonzeroRespReg, stickyNonzeroRespReg | stickyBusyReg}; + assign dbusReset = shiftReg[16]; + + assign dtminfo = {15'b0, + 1'b0, // dbusreset goes here but is write-only + 3'b0, + dbusIdleCycles, + dbusStatus, + debugAddrBits, + debugVersion}; //busy, dtm_resp* is only valid during CAPTURE_DR, // so these signals should only be used at that time. // This assumes there is only one transaction in flight at a time. - assign busy = busyReg & ~dtm_resp_valid; + assign busy = (busyReg & ~dtm_resp_valid) | stickyBusyReg; // This is needed especially for the first request. - assign nonzeroResp = dtm_resp_valid ? |{dtm_resp_bits[DEBUG_OP_BITS-1:0]} : 1'b0; + assign nonzeroResp = (dtm_resp_valid ? | {dtm_resp_bits[DEBUG_OP_BITS-1:0]} : 1'b0) | stickyNonzeroRespReg; // Interface to DM. // Note that this means dtm_resp_bits must only be used during CAPTURE_DR. @@ -158,7 +181,7 @@ module DebugTransportModuleJtag ( // Sequential Logic // JTAG STATE MACHINE - + always @(posedge jtag_TCK or posedge jtag_TRST) begin if (jtag_TRST) begin jtagStateReg <= TEST_LOGIC_RESET; @@ -239,19 +262,32 @@ module DebugTransportModuleJtag ( // during every CAPTURE_DR, and use the result in UPDATE_DR. always @(posedge jtag_TCK or posedge jtag_TRST) begin if (jtag_TRST) begin - skipOpReg <= 1'b0; - downgradeOpReg <= 1'b0; + skipOpReg <= 1'b0; + downgradeOpReg <= 1'b0; + stickyBusyReg <= 1'b0; + stickyNonzeroRespReg <= 1'b0; end else if (irReg == REG_DEBUG_ACCESS) begin case(jtagStateReg) CAPTURE_DR: begin skipOpReg <= busy; downgradeOpReg <= (~busy & nonzeroResp); + stickyBusyReg <= busy; + stickyNonzeroRespReg <= nonzeroResp; end UPDATE_DR: begin skipOpReg <= 1'b0; downgradeOpReg <= 1'b0; end endcase // case (jtagStateReg) + end else if (irReg == REG_DTM_INFO) begin + case(jtagStateReg) + UPDATE_DR: begin + if (dbusReset) begin + stickyNonzeroRespReg <= 1'b0; + stickyBusyReg <= 1'b0; + end + end + endcase // case (jtagStateReg) end end // always @ (posedge jtag_TCK or posedge jtag_TRST)