diff --git a/regression/Makefile b/regression/Makefile index 945fb602..4b716828 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-debug.stamp $(abspath $(TOP))/riscv-tools/riscv-tests/debug/gdbserver.py \ - --run "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*-debug +vcdplusfile=foo.vpd" \ - --cmd="$(OPENOCD_DIR)/bin/openocd \ + --run "$(abspath $(TOP))/vsim/simv-$(PROJECT)-$*-debug +verbose +vcdplusfile=foo.vpd" \ + --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-debug stamps/%/jtag-dtm-64-$(JTAG_DTM_TEST).stamp: install_openocd stamps/%/vsim-debug.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/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index c6aaeb09..4785658a 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -476,16 +476,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) @@ -625,8 +632,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))}) @@ -662,7 +679,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 @@ -681,11 +698,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. @@ -740,10 +761,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) { @@ -850,6 +875,7 @@ class DebugModule ()(implicit val p:cde.Parameters) // SB Access Write Decoder sbRamWrEn := Bool(false) + sbRamWrEnFinal := Bool(false) SETHALTNOTWrEn := Bool(false) CLEARDEBINTWrEn := Bool(false) @@ -859,6 +885,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){ @@ -881,6 +911,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) && @@ -897,12 +931,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..a9ab330b 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,31 @@ 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 +182,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 +263,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)