mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Update DCSR to include more bits
This commit is contained in:
parent
44335fdac9
commit
27256ff01d
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -58,6 +58,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
|
||||
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 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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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<P.XLEN/8;i++)
|
||||
if(PSTRB[i])
|
||||
MTIME[32 + i*8 +: 8]<= PWDATA[i*8 +: 8];
|
||||
end else MTIME <= MTIME + 1;
|
||||
end else if (~DebugStopTime_REGW) MTIME <= MTIME + 1;
|
||||
end
|
||||
|
||||
// Software interrupt when MSIP is set
|
||||
|
@ -57,6 +57,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
output logic UARTSout, // UART serial output
|
||||
input logic SDCIntr,
|
||||
input logic SPIIn,
|
||||
input logic DebugStopTime_REGW,
|
||||
output logic SPIOut,
|
||||
output logic [3:0] SPICS
|
||||
);
|
||||
@ -120,7 +121,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
|
||||
// memory-mapped I/O peripherals
|
||||
if (P.CLINT_SUPPORTED == 1) begin : clint
|
||||
clint_apb #(P) clint(.PCLK, .PRESETn, .PSEL(PSEL[1]), .PADDR(PADDR[15:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]), .MTIME(MTIME_CLINT), .MTimerInt, .MSwInt);
|
||||
.PRDATA(PRDATA[1]), .PREADY(PREADY[1]), .MTIME(MTIME_CLINT), .MTimerInt, .MSwInt, .DebugStopTime_REGW);
|
||||
end else begin : clint
|
||||
assign MTIME_CLINT = '0;
|
||||
assign MTimerInt = 1'b0; assign MSwInt = 1'b0;
|
||||
|
@ -55,6 +55,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
output logic DebugStall,
|
||||
input logic ExecProgBuf,
|
||||
// Debug scan chain
|
||||
output logic DebugStopTime_REGW,
|
||||
input logic DebugScanEn, // puts scannable flops into scan mode
|
||||
output logic DebugScanOut, // (misc) scan chain data out
|
||||
output logic GPRScanOut, // (GPR) scan chain data out
|
||||
@ -355,13 +356,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM, .ebreakM,
|
||||
.ebreakEn, .ForceBreakPoint, .DebugMode, .DebugCause, .Step, .DPC, .DCall,
|
||||
.ebreakEn, .ForceBreakPoint, .DebugMode, .DebugCause, .Step, .DebugStopTime_REGW, .DPC, .DCall,
|
||||
.DRet, .ExecProgBuf, .DebugSel(CSRSel), .DebugRegAddr, .DebugCapture,
|
||||
.DebugRegUpdate, .DebugScanEn(DebugScanEn & CSRSel), .DebugScanIn, .DebugScanOut(CSRScanOut));
|
||||
if (P.DEBUG_SUPPORTED) begin
|
||||
flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(),
|
||||
.scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanReg[0]));
|
||||
end else begin
|
||||
assign DebugStopTime_REGW = '0;
|
||||
assign DebugScanReg[0] = DebugScanIn;
|
||||
end
|
||||
end else begin
|
||||
@ -372,6 +374,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
||||
EPCM, TrapVectorM, RetM, TrapM,
|
||||
sfencevmaM, BigEndianM, wfiM, IntPendingM, CSRScanOut} = '0;
|
||||
assign DebugScanReg[0] = DebugScanIn;
|
||||
assign DebugStopTime_REGW = '0;
|
||||
end
|
||||
|
||||
// multiply/divide unit
|
||||
|
@ -100,6 +100,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
logic DebugRegUpdate;
|
||||
logic [P.XLEN-1:0] ProgBufAddr;
|
||||
logic ProgBuffScanEn;
|
||||
logic DebugStopTime_REGW;
|
||||
|
||||
// synchronize reset to SOC clock domain
|
||||
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
|
||||
@ -112,7 +113,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
.HaveReset, .DebugStall, .ExecProgBuf, .DebugScanEn, .DebugScanOut(DebugScanIn),
|
||||
.GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn),
|
||||
.DebugScanIn(DebugScanOut), .MiscSel, .GPRSel, .FPRSel, .CSRSel, .DebugRegAddr, .DebugCapture,
|
||||
.DebugRegUpdate, .ProgBufAddr, .ProgBuffScanEn
|
||||
.DebugRegUpdate, .ProgBufAddr, .ProgBuffScanEn, .DebugStopTime_REGW
|
||||
);
|
||||
|
||||
// instantiate uncore if a bus interface exists
|
||||
@ -121,7 +122,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
||||
.HCLK, .HRESETn, .TIMECLK, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT,
|
||||
.HSELEXTSDC, .MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin,
|
||||
.UARTSout, .MTIME_CLINT, .SDCIntr, .SPIIn, .SPIOut, .SPICS
|
||||
.UARTSout, .MTIME_CLINT, .SDCIntr, .SPIIn, .DebugStopTime_REGW, .SPIOut, .SPICS
|
||||
);
|
||||
end else begin
|
||||
assign {HRDATA, HREADY, HRESP, HSELEXT, HSELEXTSDC, MTimerInt, MSwInt, MExtInt, SExtInt,
|
||||
|
Loading…
Reference in New Issue
Block a user