diff --git a/src/debug/dm.sv b/src/debug/dm.sv index 0f50af99d..0684b4143 100644 --- a/src/debug/dm.sv +++ b/src/debug/dm.sv @@ -114,11 +114,6 @@ module dm import cvw::*; #(parameter cvw_t P) ( logic AcceptAbstrCmdReqs; logic ValAccRegReq; - assign AcceptAbstrCmdReqs = ~|CmdErr & ~Busy & DebugStall; // No cmderr, not busy (another abstrcmd isn't running), and core is halted - - // Transfer set, AARSIZE (encoded) isn't bigger than XLEN, RegNo is valid, not writing to readonly RegNo - assign ValAccRegReq = (AARSIZE_ENC[2:0] >= ReqData[`AARSIZE]) & ~InvalidRegNo & ~(ReqData[`AARWRITE] & RegReadOnly); - //// DM register fields // DMControl logic AckUnavail; @@ -197,6 +192,9 @@ module dm import cvw::*; #(parameter cvw_t P) ( assign dmreset = rst | ~DmActive; assign ActivateReq = (State == INACTIVE) & ReqValid & (ReqAddress == `DMCONTROL) & (ReqOP == `OP_WRITE); + // Transfer set, AARSIZE (encoded) isn't bigger than XLEN, RegNo is valid, not writing to readonly RegNo + assign ValAccRegReq = (AARSIZE_ENC[2:0] >= ReqData[`AARSIZE]) & ~InvalidRegNo & ~(ReqData[`AARWRITE] & RegReadOnly); + assign AcceptAbstrCmdReqs = ~|CmdErr & ~Busy & DebugStall; // No cmderr, not busy (another abstrcmd isn't running), and core is halted // DMControl // While an abstract command is executing (busy in abstractcs is high), a debugger must not change @@ -236,6 +234,7 @@ module dm import cvw::*; #(parameter cvw_t P) ( assign RspValid = (State == ACK); assign ReqReady = (State != ACK); + // BOZO: review DTM/DM interface always_ff @(posedge clk) begin if (rst) begin State <= INACTIVE; @@ -472,8 +471,8 @@ module dm import cvw::*; #(parameter cvw_t P) ( assign ScanNext[i] = WriteProgBuff ? ReqData[i] : WriteScanReg & ARMask[i] ? PackedDataReg[i] : ScanReg[i+1]; else assign ScanNext[i] = WriteScanReg & ARMask[i] ? PackedDataReg[i] : ScanReg[i+1]; - flopenr #(1) scanreg (.clk, .reset(rst), .en(DebugScanEn | ProgBuffScanEn), .d(ScanNext[i]), .q(ScanReg[i])); end + flopenr #(P.LLEN) scanreg (.clk, .reset(rst), .en(DebugScanEn | ProgBuffScanEn), .d(ScanNext), .q(ScanReg[P.LLEN-1:0])); // Message Registers assign MaskedScanReg = ARMask & ScanReg[P.LLEN:1]; diff --git a/src/debug/dmc.sv b/src/debug/dmc.sv index d94b536b4..441d6427e 100644 --- a/src/debug/dmc.sv +++ b/src/debug/dmc.sv @@ -119,7 +119,7 @@ module dmc ( DebugCause <= `CAUSE_STEP; State <= HALTED; end else - Counter <= Counter - 1; + Counter <= Counter - 1; // TODO: sync unstall bit in pipe instead of counting cycles end default: ; // empty defualt case to make the linter happy endcase diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 6b63a0ac1..8e1a3aeec 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -96,8 +96,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( // Debug Mode output input logic DebugMode, input logic [2:0] DebugCause, + input logic ebreakM, output logic ebreakEn, output logic Step, + output logic DebugStopTime_REGW, output logic [P.XLEN-1:0] DPC, input logic DCall, input logic DRet, @@ -147,6 +149,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( logic [P.XLEN-1:0] SENVCFG_REGW; logic ENVCFG_STCE; // supervisor timer counter enable logic ENVCFG_FIOM; // fence implies io (presently not used) + logic DebugStopCount_REGW; // only valid unflushed instructions can access CSRs assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; @@ -309,7 +312,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .CSRAdrM(CSRAdrDM), .PrivilegeModeW, .CSRWriteValM(CSRWriteValDM), .MCOUNTINHIBIT_REGW, .MCOUNTEREN_REGW, .SCOUNTEREN_REGW, - .MTIME_CLINT, .CSRCReadValM, .IllegalCSRCAccessM); + .MTIME_CLINT, .DebugStopCount_REGW, .CSRCReadValM, .IllegalCSRCAccessM); end else begin assign CSRCReadValM = '0; assign IllegalCSRCAccessM = 1'b1; // counters aren't enabled @@ -318,8 +321,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( if (P.DEBUG_SUPPORTED) begin:csrd csrd #(P) csrd(.clk, .reset, .DebugMode, .PrivilegeModeW, .CSRWriteDM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .CSRDReadValM, .IllegalCSRDAccessM, - .DebugCause, .ebreakEn, .Step, .DPC, .PCM, .DCall); + .DebugCause, .ebreakM, .ebreakEn, .Step, .DebugStopTime_REGW, .DebugStopCount_REGW, .DPC, .PCM, .DCall); end else begin + assign DebugStopCount_REGW = '0; + assign DebugStopTime_REGW = '0; assign Step = '0; assign DPC = '0; assign DebugScanOut = '0; diff --git a/src/privileged/csrc.sv b/src/privileged/csrc.sv index d8ce0e709..be8d6d5cb 100644 --- a/src/privileged/csrc.sv +++ b/src/privileged/csrc.sv @@ -57,7 +57,8 @@ module csrc import cvw::*; #(parameter cvw_t P) ( input logic [1:0] PrivilegeModeW, input logic [P.XLEN-1:0] CSRWriteValM, input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, - input logic [63:0] MTIME_CLINT, + input logic [63:0] MTIME_CLINT, + input logic DebugStopCount_REGW, output logic [P.XLEN-1:0] CSRCReadValM, output logic IllegalCSRCAccessM ); @@ -138,7 +139,7 @@ module csrc import cvw::*; #(parameter cvw_t P) ( if (P.XLEN==32) begin // write high and low separately logic [P.COUNTERS-1:0] WriteHPMCOUNTERHM; logic [P.XLEN-1:0] NextHPMCOUNTERHM[P.COUNTERS-1:0]; - assign HPMCOUNTERPlusM[i] = {HPMCOUNTERH_REGW[i], HPMCOUNTER_REGW[i]} + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]}; + assign HPMCOUNTERPlusM[i] = {HPMCOUNTERH_REGW[i], HPMCOUNTER_REGW[i]} + {63'b0, CounterEvent[i] & ~(MCOUNTINHIBIT_REGW[i] | DebugStopCount_REGW)}; assign WriteHPMCOUNTERHM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERHBASE + i); assign NextHPMCOUNTERHM[i] = WriteHPMCOUNTERHM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][63:32]; always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop diff --git a/src/privileged/csrd.sv b/src/privileged/csrd.sv index cded34e03..c05b965f1 100644 --- a/src/privileged/csrd.sv +++ b/src/privileged/csrd.sv @@ -38,8 +38,11 @@ module csrd import cvw::*; #(parameter cvw_t P) ( input logic [P.XLEN-1:0] PCM, input logic DCall, input logic [2:0] DebugCause, + input logic ebreakM, output logic ebreakEn, output logic Step, + output logic DebugStopTime_REGW, + output logic DebugStopCount_REGW, output logic [P.XLEN-1:0] DPC ); `include "debug.vh" @@ -54,19 +57,17 @@ module csrd import cvw::*; #(parameter cvw_t P) ( logic WriteDPCM; // DCSR fields - const logic [3:0] DebugVer = 4; - const logic ebreakVS = 0; - const logic ebreakVU = 0; - logic ebreakM; - const logic ebreakS = 0; - const logic ebreakU = 0; - const logic StepIE = 0; - const logic StopCount = 0; - const logic StopTime = 0; + const logic [3:0] DebugVer = 4'h4; + const logic ebreakVS = '0; + const logic ebreakVU = '0; + logic MEbreak; + logic SEbreak; + logic UEbreak; + const logic StepIE = '0; logic [2:0] Cause; - const logic V = 0; - const logic MPrvEn = 0; - const logic NMIP = 0; // pending non-maskable interrupt TODO: update + const logic V = '0; + const logic MPrvEn = '0; + const logic NMIP = '0; // pending non-maskable interrupt TODO: update logic [1:0] Prv; @@ -84,13 +85,38 @@ module csrd import cvw::*; #(parameter cvw_t P) ( end else if (DCall) begin Prv <= PrivilegeModeW; Cause <= DebugCause; + end else if (WriteDCSRM) begin + Prv <= CSRWriteValM[`PRV]; end end - flopenr #(2) DCSRreg (clk, reset, WriteDCSRM, {CSRWriteValM[`EBREAKM], CSRWriteValM[`STEP]}, {ebreakM, Step}); + always_ff @(posedge clk) begin + MEbreak <= '0; + SEbreak <= '0; + UEbreak <= '0; + if (reset) begin + MEbreak <= '0; + SEbreak <= '0; + UEbreak <= '0; + end else begin + if (ebreakM) begin + if (PrivilegeModeW == P.M_MODE) MEbreak <= 1'b1; + if (PrivilegeModeW == P.S_MODE) SEbreak <= 1'b1; + if (PrivilegeModeW == P.U_MODE) UEbreak <= 1'b1; + end else if (WriteDCSRM) begin + MEbreak <= CSRWriteValM[`EBREAKM]; + SEbreak <= CSRWriteValM[`EBREAKS]; + UEbreak <= CSRWriteValM[`EBREAKU]; + end + end + end - assign DCSR = {DebugVer, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE, - StopCount, StopTime, Cause, V, MPrvEn, NMIP, Step, Prv}; + flopenr #(3) DCSRreg (clk, reset, WriteDCSRM, + {CSRWriteValM[`STEP], CSRWriteValM[`STOPTIME], CSRWriteValM[`STOPCOUNT]}, + {Step, DebugStopTime_REGW, DebugStopCount_REGW}); + + assign DCSR = {DebugVer, 10'b0, ebreakVS, ebreakVU, MEbreak, 1'b0, SEbreak, UEbreak, StepIE, + DebugStopCount_REGW, DebugStopTime_REGW, Cause, V, MPrvEn, NMIP, Step, Prv}; assign DPCWriteVal = DCall ? PCM : CSRWriteValM; flopenr #(P.XLEN) DPCreg (clk, reset, WriteDPCM | DCall, DPCWriteVal, DPC); diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index ed4cbfa1b..411261d67 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -104,6 +104,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( input logic DebugMode, input logic [2:0] DebugCause, output logic Step, + output logic DebugStopTime_REGW, output logic [P.XLEN-1:0] DPC, input logic DCall, input logic DRet, @@ -167,7 +168,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .EPCM, .TrapVectorM, .CSRReadValW, .IllegalCSRAccessM, .BigEndianM, - .DebugMode, .DebugCause, .ebreakEn, .Step, .DPC, .DCall, .DRet, .ExecProgBuf, + .DebugMode, .DebugCause, .ebreakM, .ebreakEn, .Step, .DebugStopTime_REGW, .DPC, .DCall, .DRet, .ExecProgBuf, .DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut); // pipeline early-arriving trap sources diff --git a/src/uncore/clint_apb.sv b/src/uncore/clint_apb.sv index 76735aaa6..d6fca2172 100644 --- a/src/uncore/clint_apb.sv +++ b/src/uncore/clint_apb.sv @@ -36,6 +36,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( input logic [P.XLEN/8-1:0] PSTRB, input logic PWRITE, input logic PENABLE, + input logic DebugStopTime_REGW, output logic [P.XLEN-1:0] PRDATA, output logic PREADY, output logic [63:0] MTIME, @@ -144,7 +145,7 @@ module clint_apb import cvw::*; #(parameter cvw_t P) ( for(i=0;i