Implement DCSR (Writes are broken)

This commit is contained in:
Matthew 2024-06-14 00:35:20 -05:00
parent d319703d75
commit 6ae7ac9a6d
13 changed files with 244 additions and 137 deletions

View File

@ -35,6 +35,7 @@ from openocd_tcl_wrapper import OpenOCD
random_stimulus = True random_stimulus = True
random_order = False random_order = False
def main(): def main():
with OpenOCD() as cvw: with OpenOCD() as cvw:
registers = dict.fromkeys(cvw.register_translations.keys(),[]) registers = dict.fromkeys(cvw.register_translations.keys(),[])

View File

@ -131,14 +131,12 @@ class OpenOCD:
dmstat = int(self.read_dmi("0x11"), 16) # Check resumeack bit dmstat = int(self.read_dmi("0x11"), 16) # Check resumeack bit
if not ((dmstat >> 16) & 0x3): if not ((dmstat >> 16) & 0x3):
raise Exception("Error: Hart failed to resume") raise Exception("Error: Hart failed to resume")
self.write_dmi("0x10", "0x40000001") # Clear resumeack bit
def step(self): def step(self):
self.write_dmi("0x10", "0xC0000001") # Set halt bit #TODO save curent value of dcsr
# BOZO: checking resumeack after halt is pointless until sdext halt method is added self.write_data("DCSR", "0x4")
dmstat = int(self.read_dmi("0x11"), 16) # Resume
if not ((dmstat >> 16) & 0x3): #self.resume()
raise Exception("Error: Hart failed to resume")
def access_register(self, write, regno, addr_size=None): def access_register(self, write, regno, addr_size=None):
data = 1 << 17 # transfer bit always set data = 1 << 17 # transfer bit always set

View File

@ -101,6 +101,20 @@
`define CMDTYPE 31:24 `define CMDTYPE 31:24
`define CONTROL 23:0 `define CONTROL 23:0
// DCSR
`define EBREAKVS 17
`define EBREAKVU 16
`define EBREAKM 15
`define EBREAKS 13
`define EBREAKU 12
`define STEPIE 11
`define STOPCOUNT 10
`define STOPTIME 9
`define V 5
`define MPRVEN 4
`define STEP 2
`define PRV 1:0
//// Abstract Commands //// Abstract Commands
// cmderr // cmderr
`define CMDERR_NONE 3'h0 `define CMDERR_NONE 3'h0

View File

@ -26,14 +26,10 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// TODO List: // TODO List:
// fix CSR scanning
// determine config/permissions of all CSRs // determine config/permissions of all CSRs
// DCSR and DPC should exist even when not privileged_supported
// test all combinations of XLEN/FLEN
// improve halting / implement "debug mode" // improve halting / implement "debug mode"
//// Debug Mode = M-mode with stalled pipe //// Debug Mode = M-mode with stalled pipe
// Flush pipe with NOPs during halt? // Flush pipe with NOPs during halt?
// implement better steps
// Alias DPC to PCF/PCNextF? // Alias DPC to PCF/PCNextF?
// (stretch) add system bus access? // (stretch) add system bus access?
@ -51,8 +47,14 @@ module dm import cvw::*; #(parameter cvw_t P) (
// Platform reset signal // Platform reset signal
output logic NdmReset, output logic NdmReset,
// Core hazard signal // Core control signals
output logic DebugStall, input logic ResumeAck, // Signals Hart has been resumed
input logic HaveReset, // Signals Hart has been reset
input logic DebugMode, // Signals core is halted
output logic HaltReq, // Initiates core halt
output logic ResumeReq, // Initiates core resume
output logic HaltOnReset, // Halts core immediately on hart reset
output logic AckHaveReset, // Clears HaveReset status
// Scan Chain // Scan Chain
output logic DebugScanEn, // puts scannable flops into scan mode output logic DebugScanEn, // puts scannable flops into scan mode
@ -83,28 +85,16 @@ module dm import cvw::*; #(parameter cvw_t P) (
logic [1:0] RspOP; logic [1:0] RspOP;
// JTAG ID for Wally: // JTAG ID for Wally:
// [31:27] = 1 (4 bits) // Version [31:28] = 0x1 : 0001
// ver [27:12] = 0x2A (42) // PartNumber [27:12] = 0x2A : 00000000_00101010
// JEDEC number [11:1] = 000_0000_0010 (Open HW Group) // JEDEC number [11:1] = 0x602 : Bank 13 (1100) Open HW Group (0000010)
// [0] set to 1 // [0] = 1
localparam JTAG_DEVICE_ID = 32'h1002_A005; 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, .tck, .tdi, .tms, .tdo,
.ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady, .ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady,
.RspValid, .RspData, .RspOP); .RspValid, .RspData, .RspOP);
// Core control signals
logic HaltReq;
logic ResumeReq;
logic HaltOnReset;
logic Halted;
logic AckHaveReset;
hartcontrol hartcontrol(.clk, .rst(rst | ~DmActive), .NdmReset, .AckHaveReset, .HaltReq,
.ResumeReq, .HaltOnReset, .DebugStall, .Halted, .AllRunning, .AnyRunning,
.AllHalted, .AnyHalted, .AllResumeAck, .AnyResumeAck, .AllHaveReset, .AnyHaveReset);
enum logic [3:0] {INACTIVE, IDLE, ACK, R_DATA, W_DATA, DMSTATUS, W_DMCONTROL, R_DMCONTROL, enum logic [3:0] {INACTIVE, IDLE, ACK, R_DATA, W_DATA, DMSTATUS, W_DMCONTROL, R_DMCONTROL,
W_ABSTRACTCS, R_ABSTRACTCS, ABST_COMMAND, R_SYSBUSCS, READ_ZERO, W_ABSTRACTCS, R_ABSTRACTCS, ABST_COMMAND, R_SYSBUSCS, READ_ZERO,
INVALID} State; INVALID} State;
@ -149,7 +139,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
//// DM register fields //// DM register fields
// DMControl // DMControl
logic AckUnavail; logic AckUnavail;
logic DmActive; // This bit is used to (de)activate the DM. Toggling acts as reset logic DmActive; // This bit is used to (de)activate the DM. Toggling off/on acts as reset
// DMStatus // DMStatus
logic StickyUnavail; logic StickyUnavail;
logic ImpEBreak; logic ImpEBreak;
@ -157,10 +147,10 @@ module dm import cvw::*; #(parameter cvw_t P) (
logic AnyHaveReset; logic AnyHaveReset;
logic AllResumeAck; logic AllResumeAck;
logic AnyResumeAck; logic AnyResumeAck;
logic AllNonExistent; // TODO const logic AllNonExistent = 0;
logic AnyNonExistent; const logic AnyNonExistent = 0;
logic AllUnavail; // TODO const logic AllUnavail = 0;
logic AnyUnavail; const logic AnyUnavail = 0;
logic AllRunning; logic AllRunning;
logic AnyRunning; logic AnyRunning;
logic AllHalted; logic AllHalted;
@ -177,6 +167,18 @@ module dm import cvw::*; #(parameter cvw_t P) (
logic [2:0] CmdErr; logic [2:0] CmdErr;
const logic [3:0] DataCount = (P.LLEN/32); const logic [3:0] DataCount = (P.LLEN/32);
// Core control signals
assign AllHaveReset = HaveReset;
assign AnyHaveReset = HaveReset;
assign AnyHalted = DebugMode;
assign AllHalted = DebugMode;
assign AnyRunning = ~DebugMode;
assign AllRunning = ~DebugMode;
// I believe resumeack is used to determine when a resume is requested but never completes
// It's pretty worthless in this implementation (complain to the debug working group)
assign AllResumeAck = ResumeAck;
assign AnyResumeAck = ResumeAck;
// See spec 3.14.2 // See spec 3.14.2
assign DMControl = {2'b0, 1'b0, 2'b0, 1'b0, 10'b0, 10'b0, 4'b0, NdmReset, DmActive}; assign DMControl = {2'b0, 1'b0, 2'b0, 1'b0, 10'b0, 10'b0, 4'b0, NdmReset, DmActive};
@ -290,7 +292,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
// hartreset, ackhavereset, setresethaltreq, and clrresethaltreq. The others must be written 0 // hartreset, ackhavereset, setresethaltreq, and clrresethaltreq. The others must be written 0
case ({ReqData[`RESUMEREQ],ReqData[`ACKHAVERESET],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]}) case ({ReqData[`RESUMEREQ],ReqData[`ACKHAVERESET],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]})
4'b0000 :; // None 4'b0000 :; // None
4'b1000 : ResumeReq <= 1; 4'b1000 : ResumeReq <= ~ReqData[`HALTREQ]; // Ignore ResumeReq if HaltReq
4'b0100 : AckHaveReset <= 1; 4'b0100 : AckHaveReset <= 1;
4'b0010 : HaltOnReset <= 1; 4'b0010 : HaltOnReset <= 1;
4'b0001 : HaltOnReset <= 0; 4'b0001 : HaltOnReset <= 0;
@ -338,7 +340,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
if (CmdErr != `CMDERR_NONE); // If CmdErr, do nothing if (CmdErr != `CMDERR_NONE); // If CmdErr, do nothing
else if (Busy) else if (Busy)
CmdErr <= `CMDERR_BUSY; // If Busy, set CmdErr, do nothing CmdErr <= `CMDERR_BUSY; // If Busy, set CmdErr, do nothing
else if (~Halted) else if (~DebugMode)
CmdErr <= `CMDERR_HALTRESUME; // If not halted, set CmdErr, do nothing CmdErr <= `CMDERR_HALTRESUME; // If not halted, set CmdErr, do nothing
else begin else begin
case (ReqData[`CMDTYPE]) case (ReqData[`CMDTYPE])

View File

@ -1,10 +1,10 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// hartcontrol.sv // dmc.sv
// //
// Written: matthew.n.otto@okstate.edu 10 May 2024 // Written: matthew.n.otto@okstate.edu 10 May 2024
// Modified: // Modified:
// //
// Purpose: Controls the state of connected hart // Purpose: Controls pipeline during Debug Mode
// //
// Documentation: RISC-V System on Chip Design // Documentation: RISC-V System on Chip Design
// //
@ -30,72 +30,43 @@
// Note: This module controls all of the per-hart debug state. // Note: This module controls all of the per-hart debug state.
// In a multihart system, this module should be instantiated under wallypipelinedcore // In a multihart system, this module should be instantiated under wallypipelinedcore
module hartcontrol( module dmc(
input logic clk, rst, input logic clk, reset,
input logic NdmReset, // Triggers HaltOnReset behavior input logic Step,
input logic AckHaveReset, // Clears *HaveReset status input logic HaltReq, // Initiates core halt
input logic HaltReq, // Initiate core halt
input logic ResumeReq, // Initiates core resume input logic ResumeReq, // Initiates core resume
input logic HaltOnReset, // Halts core immediately on hart reset input logic HaltOnReset, // Halts core immediately on hart reset
input logic AckHaveReset, // Clears HaveReset status
output logic DebugStall, // Stall signal goes to hazard unit output logic DebugMode,
output logic ResumeAck, // Signals Hart has been resumed
// DMStatus bits output logic HaveReset, // Signals Hart has been reset
output logic Halted, output logic DebugStall // Stall signal goes to hazard unit
output logic AllRunning,
output logic AnyRunning,
output logic AllHalted,
output logic AnyHalted,
output logic AllResumeAck,
output logic AnyResumeAck,
output logic AllHaveReset,
output logic AnyHaveReset
); );
enum logic {RUNNING, HALTED} State; enum logic {RUNNING, HALTED} State;
assign AnyHaveReset = AllHaveReset;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (NdmReset) if (reset)
AllHaveReset <= 1; HaveReset <= 1;
else if (AckHaveReset) else if (AckHaveReset)
AllHaveReset <= 0; HaveReset <= 0;
end end
assign Halted = DebugStall;
assign AllRunning = ~DebugStall;
assign AnyRunning = ~DebugStall;
assign AllHalted = DebugStall;
assign AnyHalted = DebugStall;
// BOZO: when sdext is implemented (proper step support is added)
// change ResumeReq to be ignored when HaltReq
// but ResumeReq should still always clear *ResumeAck
assign AnyResumeAck = AllResumeAck;
assign DebugMode = (State != RUNNING); // TODO: update this
assign DebugStall = (State == HALTED); assign DebugStall = (State == HALTED);
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (rst) if (reset)
State <= RUNNING;
else if (NdmReset)
State <= HaltOnReset ? HALTED : RUNNING; State <= HaltOnReset ? HALTED : RUNNING;
else begin else begin
case (State) case (State)
RUNNING : begin RUNNING : begin
if (HaltReq) begin State <= Step | HaltReq ? HALTED : RUNNING;
State <= HALTED;
end else if (ResumeReq) begin
AllResumeAck <= 0;
end
end end
HALTED : begin HALTED : begin
if (ResumeReq) begin State <= ResumeReq ? RUNNING : HALTED;
State <= RUNNING; ResumeAck <= ResumeReq ? 1 : ResumeAck;
AllResumeAck <= 1;
end
end end
endcase endcase
end end

View File

@ -106,7 +106,7 @@ module rad import cvw::*; #(parameter cvw_t P) (
`MIP_REGNO : begin `MIP_REGNO : begin
ShiftCount = P.LLEN - 1; ShiftCount = P.LLEN - 1;
CSRegNo = 1; CSRegNo = 1;
RegReadOnly = 1; // TODO: eventually DCSR (any maybe others) will be RW //RegReadOnly = 1;
end end
[`HPMCOUNTERBASE_REGNO:`TIME_REGNO], [`HPMCOUNTERBASE_REGNO:`TIME_REGNO],

View File

@ -145,7 +145,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
logic [LINELEN-1:0] FetchBuffer; logic [LINELEN-1:0] FetchBuffer;
logic [31:0] ShiftUncachedInstr; logic [31:0] ShiftUncachedInstr;
// Debug scan chain // Debug scan chain
logic DSCR; // Debug Scan Chain Register logic DebugScanChainReg; // Debug Scan Chain Register
assign PCFExt = {2'b00, PCSpillF}; assign PCFExt = {2'b00, PCSpillF};
@ -411,22 +411,22 @@ module ifu import cvw::*; #(parameter cvw_t P) (
if (P.ZICSR_SUPPORTED | P.A_SUPPORTED) begin if (P.ZICSR_SUPPORTED | P.A_SUPPORTED) begin
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
if (P.DEBUG_SUPPORTED) if (P.DEBUG_SUPPORTED)
flopenrs #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM, DebugScanEn, DSCR, DebugScanOut); flopenrs #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM, DebugScanEn, DebugScanChainReg, DebugScanOut);
else else
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
end else begin end else begin
assign InstrM = '0; assign InstrM = '0;
assign DebugScanOut = DSCR; assign DebugScanOut = DebugScanChainReg;
end end
// PCM is only needed with CSRs or branch prediction // PCM is only needed with CSRs or branch prediction
if (P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED) if (P.ZICSR_SUPPORTED | P.BPRED_SUPPORTED)
if (P.DEBUG_SUPPORTED) if (P.DEBUG_SUPPORTED)
flopenrs #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM, DebugScanEn, DebugScanIn, DSCR); flopenrs #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM, DebugScanEn, DebugScanIn, DebugScanChainReg);
else else
flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
else begin else begin
assign PCM = '0; assign PCM = '0;
assign DSCR = DebugScanIn; assign DebugScanChainReg = DebugScanIn;
end end
// If compressed instructions are supported, increment PCLink by 2 or 4 for a jal. Otherwise, just by 4 // If compressed instructions are supported, increment PCLink by 2 or 4 for a jal. Otherwise, just by 4

View File

@ -93,6 +93,8 @@ module csr import cvw::*; #(parameter cvw_t P) (
output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR
output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level
output logic BigEndianM, // memory access is big-endian based on privilege mode and STATUS register endian fields output logic BigEndianM, // memory access is big-endian based on privilege mode and STATUS register endian fields
// Debug Mode output
output logic Step,
// Debug scan chain // Debug scan chain
input logic DebugSel, input logic DebugSel,
input logic [11:0] DebugRegAddr, input logic [11:0] DebugRegAddr,
@ -106,7 +108,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
localparam MIP = 12'h344; localparam MIP = 12'h344;
localparam SIP = 12'h144; localparam SIP = 12'h144;
logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM; logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM, CSRDReadValM;
logic [P.XLEN-1:0] CSRReadValM; logic [P.XLEN-1:0] CSRReadValM;
logic [P.XLEN-1:0] CSRSrcM; logic [P.XLEN-1:0] CSRSrcM;
logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
@ -116,13 +118,14 @@ module csr import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW; logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic CSRWriteDM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM, CSRDWriteM;
logic UngatedCSRMWriteM; logic UngatedCSRMWriteM;
logic WriteFRMM, WriteFFLAGSM; logic WriteFRMM, WriteFFLAGSM;
logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM;
logic [4:0] NextCauseM; logic [4:0] NextCauseM;
logic [11:0] CSRAdrM, CSRAdrDM; logic [11:0] CSRAdrM, CSRAdrDM;
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRDAccessM;
logic InsufficientCSRPrivilegeM; logic InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM; logic IllegalCSRMWriteReadonlyM;
logic [P.XLEN-1:0] CSRReadVal2M; logic [P.XLEN-1:0] CSRReadVal2M;
@ -137,7 +140,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] SENVCFG_REGW; logic [P.XLEN-1:0] SENVCFG_REGW;
logic ENVCFG_STCE; // supervisor timer counter enable logic ENVCFG_STCE; // supervisor timer counter enable
logic ENVCFG_FIOM; // fence implies io (presently not used) logic ENVCFG_FIOM; // fence implies io (presently not used)
logic CSRMWriteDM;
// only valid unflushed instructions can access CSRs // only valid unflushed instructions can access CSRs
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
@ -212,10 +214,11 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign NextEPCM = P.ZCA_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextEPCM = P.ZCA_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment
assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValDM[P.XLEN-1], CSRWriteValDM[3:0]}; assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValDM[P.XLEN-1], CSRWriteValDM[3:0]};
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValDM; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValDM;
assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == P.M_MODE); assign UngatedCSRMWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE);
assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM; assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM;
assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; assign CSRSWriteM = CSRWriteDM & (|PrivilegeModeW) & InstrValidNotFlushedM;
assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM; assign CSRUWriteM = CSRWriteDM & InstrValidNotFlushedM;
assign CSRDWriteM = CSRWriteDM;
assign MTrapM = TrapM & (NextPrivilegeModeM == P.M_MODE); assign MTrapM = TrapM & (NextPrivilegeModeM == P.M_MODE);
assign STrapM = TrapM & (NextPrivilegeModeM == P.S_MODE) & P.S_SUPPORTED; assign STrapM = TrapM & (NextPrivilegeModeM == P.S_MODE) & P.S_SUPPORTED;
@ -283,7 +286,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
if (P.ZICNTR_SUPPORTED) begin:counters if (P.ZICNTR_SUPPORTED) begin:counters
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM, csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM, .InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM(CSRWriteDM), .CSRMWriteM,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
.IClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, .IClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
.InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
@ -295,6 +298,16 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign IllegalCSRCAccessM = 1'b1; // counters aren't enabled assign IllegalCSRCAccessM = 1'b1; // counters aren't enabled
end end
if (P.DEBUG_SUPPORTED) begin:csrd
csrd #(P) csrd(.clk, .reset,
.CSRWriteDM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .CSRDReadValM, .IllegalCSRDAccessM,
.Step
);
end else begin
assign CSRDReadValM = '0;
assign IllegalCSRDAccessM = 1'b1; // Debug isn't supported
end
// Broadcast appropriate environment configuration based on privilege mode // Broadcast appropriate environment configuration based on privilege mode
assign ENVCFG_STCE = MENVCFG_REGW[63]; // supervisor timer counter enable assign ENVCFG_STCE = MENVCFG_REGW[63]; // supervisor timer counter enable
assign ENVCFG_PBMTE = MENVCFG_REGW[62]; // page-based memory types enable assign ENVCFG_PBMTE = MENVCFG_REGW[62]; // page-based memory types enable
@ -308,7 +321,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
(MENVCFG_REGW[0] & SENVCFG_REGW[0]); (MENVCFG_REGW[0] & SENVCFG_REGW[0]);
// merge CSR Reads // merge CSR Reads
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM; assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM | CSRDReadValM;
flopenrc #(P.XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW); flopenrc #(P.XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW);
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient // merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
@ -316,19 +329,19 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign InsufficientCSRPrivilegeM = (CSRAdrDM[9:8] == 2'b11 & PrivilegeModeW != P.M_MODE) | assign InsufficientCSRPrivilegeM = (CSRAdrDM[9:8] == 2'b11 & PrivilegeModeW != P.M_MODE) |
(CSRAdrDM[9:8] == 2'b01 & PrivilegeModeW == P.U_MODE); (CSRAdrDM[9:8] == 2'b01 & PrivilegeModeW == P.U_MODE);
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM & assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
IllegalCSRSAccessM & IllegalCSRUAccessM | IllegalCSRSAccessM & IllegalCSRUAccessM /*& IllegalCSRDAccessM*/ |
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM; InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
// Debug module CSR access // Debug module CSR access
// TODO: should DM be able to access CSRs when hart isn't in M mode? // TODO: should DM be able to access CSRs when hart isn't in M mode?
if (P.DEBUG_SUPPORTED) begin if (P.DEBUG_SUPPORTED) begin
assign CSRAdrDM = DebugSel ? DebugRegAddr : CSRAdrM; assign CSRAdrDM = DebugSel ? DebugRegAddr : CSRAdrM;
//assign CSRMWriteDM = DebugSel ? DebugRegUpdate : CSRMWriteM; // TODO: add write support assign CSRWriteDM = DebugSel ? DebugRegUpdate : CSRWriteM; // TODO: add write support
assign CSRWriteValDM = DebugSel ? DebugCSRScanVal : CSRWriteValM; assign CSRWriteValDM = DebugSel ? DebugCSRScanVal : CSRWriteValM;
flopenrs #(P.XLEN) GPScanReg(.clk, .reset, .en(DebugCapture), .d(CSRReadValM), .q(DebugCSRScanVal), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut)); flopenrs #(P.XLEN) GPScanReg(.clk, .reset, .en(DebugCapture), .d(CSRReadValM), .q(DebugCSRScanVal), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut));
end else begin end else begin
assign CSRAdrDM = CSRAdrM; assign CSRAdrDM = CSRAdrM;
//assign CSRMWriteDM = CSRMWriteM; assign CSRWriteDM = CSRWriteM;
assign CSRWriteValDM = CSRWriteValM; assign CSRWriteValDM = CSRWriteValM;
end end
endmodule endmodule

99
src/privileged/csrd.sv Normal file
View File

@ -0,0 +1,99 @@
///////////////////////////////////////////
// csrd.sv
//
// Written: matthew.n.otto@okstate.edu
// Created: 13 June 2024
//
// Purpose: Debug Control and Status Registers
// See RISC-V Debug Specification (4.10)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
// https://github.com/openhwgroup/cvw
//
// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License Version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module csrd import cvw::*; #(parameter cvw_t P) (
input logic clk, reset,
input logic CSRWriteDM,
input logic [11:0] CSRAdrM,
input logic [P.XLEN-1:0] CSRWriteValM,
output logic [P.XLEN-1:0] CSRDReadValM,
output logic IllegalCSRDAccessM,
output logic Step
);
`include "debug.vh"
localparam DCSR = 12'h7B0; // Debug Control and Status Register
localparam DPC = 12'h7B1; // Debug PC
// TODO: these registers are only accessible from Debug Mode.
logic [31:0] DCSR_REGW;
logic [31:0] DPC_REGW;
logic WriteDCSRM;
logic WriteDPCM;
// DCSR fields
const logic [3:0] DebugVer = 4;
const logic ebreakVS = 0;
const logic ebreakVU = 0;
logic ebreakM;
logic ebreakS;
logic ebreakU;
const logic StepIE = 0;
const logic StopCount = 0;
const logic StopTime = 0;
logic [2:0] Cause; // TODO: give reason for entering debug mode
const logic V = 0;
const logic MPrvEn = 0;
logic NMIP; // pending non-maskable interrupt
logic [1:0] Prv;
assign WriteDCSRM = CSRWriteDM & (CSRAdrM == DCSR);
assign WriteDPCM = CSRWriteDM & (CSRAdrM == DPC);
always_ff @(posedge clk) begin
if (reset)
Prv <= 3;
//else if (Halt) // TODO: trigger when hart enters debug mode
// Prv <= // hart priv mode
else if (WriteDCSRM)
Prv <= CSRWriteValM[`PRV]; // TODO: overwrite hart privilege mode
end
flopenr ebreakreg(clk, reset, WriteDCSRM,
{CSRWriteValM[`EBREAKM], CSRWriteValM[`EBREAKS], CSRWriteValM[`EBREAKU], CSRWriteValM[`STEP]},
{ebreakM, ebreakS, ebreakU, Step});
assign DCSR_REGW = {4'b0100, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE,
StopCount, StopTime, Cause, V, MPrvEn, NMIP, Step, Prv};
assign DPC_REGW = {32'hd099f00d};
always_comb begin
CSRDReadValM = 0;
IllegalCSRDAccessM = 0;
case (CSRAdrM)
DCSR : CSRDReadValM = DCSR_REGW;
DPC : CSRDReadValM = DPC_REGW;
default: IllegalCSRDAccessM = 1'b1;
endcase
end
endmodule

View File

@ -58,8 +58,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic [31:0] DCSR_REGW, DPC_REGW;
logic WriteDPCM, WriteDCSRM;
// Machine CSRs // Machine CSRs
localparam MVENDORID = 12'hF11; localparam MVENDORID = 12'hF11;
@ -91,10 +89,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
localparam TDATA1 = 12'h7A1; localparam TDATA1 = 12'h7A1;
localparam TDATA2 = 12'h7A2; localparam TDATA2 = 12'h7A2;
localparam TDATA3 = 12'h7A3; localparam TDATA3 = 12'h7A3;
localparam DCSR = 12'h7B0; // Debug Control and Status Register
localparam DPC = 12'h7B1; // Debug PC
localparam DSCRATCH0 = 12'h7B2; // Debug Scratch Register 0 (opt)
localparam DSCRATCH1 = 12'h7B3; // Debug Scratch Register 1 (opt)
// Constants // Constants
localparam ZERO = {(P.XLEN){1'b0}}; localparam ZERO = {(P.XLEN){1'b0}};
// when compressed instructions are supported, there can't be misaligned instructions // when compressed instructions are supported, there can't be misaligned instructions
@ -132,9 +126,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
// MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally // MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally
assign MISA_REGW = {(P.XLEN == 32 ? 2'b01 : 2'b10), {(P.XLEN-28){1'b0}}, MISA_26[25:0]}; assign MISA_REGW = {(P.XLEN == 32 ? 2'b01 : 2'b10), {(P.XLEN-28){1'b0}}, MISA_26[25:0]};
// Debug registers (stubbed out)
assign DPC_REGW = {32'hd099f00d};
assign DCSR_REGW = {32'hdeadbeef};
// MHARTID is hardwired. It only exists as a signal so that the testbench can easily see it. // MHARTID is hardwired. It only exists as a signal so that the testbench can easily see it.
assign MHARTID_REGW = '0; assign MHARTID_REGW = '0;
@ -151,10 +142,8 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL));
assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN);
assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT);
assign WriteDPCM = CSRMWriteM & (CSRAdrM == DPC);
assign WriteDCSRM = CSRMWriteM & (CSRAdrM == DCSR);
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR); // TODO: add DPC assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID | CSRAdrM == MCONFIGPTR);
// CSRs // CSRs
flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); flopenr #(P.XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
@ -171,12 +160,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
if (P.U_SUPPORTED) begin: mcounteren // MCOUNTEREN only exists when user mode is supported if (P.U_SUPPORTED) begin: mcounteren // MCOUNTEREN only exists when user mode is supported
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW); flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
end else assign MCOUNTEREN_REGW = '0; end else assign MCOUNTEREN_REGW = '0;
if (P.DEBUG_SUPPORTED) begin
//flopenr #(32) DPCreg(clk, reset, WriteDPCM, CSRWriteValM[31:0], DPC_REGW); // TODO: update DPC from PC (M?)
//flopenr #(32) DCSRreg(clk, reset, WriteDCSRM, CSRWriteValM[31:0], DCSR_REGW); // TODO: control writes to DCSR
end else begin
assign {DPC_REGW,DCSR_REGW} = '0;
end
// MENVCFG register // MENVCFG register
if (P.U_SUPPORTED) begin // menvcfg only exists if there is a lower privilege to control if (P.U_SUPPORTED) begin // menvcfg only exists if there is a lower privilege to control
@ -253,10 +236,6 @@ module csrm import cvw::*; #(parameter cvw_t P) (
MENVCFGH: if (P.U_SUPPORTED & P.XLEN==32) CSRMReadValM = MENVCFGH_REGW; MENVCFGH: if (P.U_SUPPORTED & P.XLEN==32) CSRMReadValM = MENVCFGH_REGW;
else IllegalCSRMAccessM = 1'b1; else IllegalCSRMAccessM = 1'b1;
MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
DCSR: if (P.DEBUG_SUPPORTED) CSRMReadValM = DCSR_REGW;
else IllegalCSRMAccessM = 1'b1;
DPC: if (P.DEBUG_SUPPORTED) CSRMReadValM = DPC_REGW;
else IllegalCSRMAccessM = 1'b1;
default: IllegalCSRMAccessM = 1'b1; default: IllegalCSRMAccessM = 1'b1;
endcase endcase
end end

View File

@ -97,6 +97,8 @@ module privileged import cvw::*; #(parameter cvw_t P) (
output logic BigEndianM, // Use big endian in current privilege mode output logic BigEndianM, // Use big endian in current privilege mode
// Fault outputs // Fault outputs
output logic wfiM, IntPendingM, // Stall in Memory stage for WFI until interrupt pending or timeout output logic wfiM, IntPendingM, // Stall in Memory stage for WFI until interrupt pending or timeout
// Debuge Mode
output logic Step,
// Debug scan chain // Debug scan chain
input logic DebugSel, input logic DebugSel,
input logic [11:0] DebugRegAddr, input logic [11:0] DebugRegAddr,
@ -155,7 +157,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.EPCM, .TrapVectorM, .EPCM, .TrapVectorM,
.CSRReadValW, .IllegalCSRAccessM, .BigEndianM, .CSRReadValW, .IllegalCSRAccessM, .BigEndianM, .Step,
.DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut); .DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut);
// pipeline early-arriving trap sources // pipeline early-arriving trap sources

View File

@ -45,7 +45,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
output logic [3:0] HPROT, output logic [3:0] HPROT,
output logic [1:0] HTRANS, output logic [1:0] HTRANS,
output logic HMASTLOCK, output logic HMASTLOCK,
input logic DebugStall, // Debug Mode Control
input logic HaltReq,
input logic ResumeReq,
input logic HaltOnReset,
input logic AckHaveReset,
output logic ResumeAck,
output logic HaveReset,
output logic DebugMode,
// Debug scan chain // Debug scan chain
input logic DebugScanEn, // puts scannable flops into scan mode input logic DebugScanEn, // puts scannable flops into scan mode
output logic DebugScanOut, // (misc) scan chain data out output logic DebugScanOut, // (misc) scan chain data out
@ -65,6 +72,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic StallF, StallD, StallE, StallM, StallW; logic StallF, StallD, StallE, StallM, StallW;
logic FlushD, FlushE, FlushM, FlushW; logic FlushD, FlushE, FlushM, FlushW;
logic TrapM, RetM; logic TrapM, RetM;
logic DebugStall, Step;
// signals that must connect through DP // signals that must connect through DP
logic IntDivE, W64E; logic IntDivE, W64E;
@ -184,7 +192,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic wfiM, IntPendingM; logic wfiM, IntPendingM;
// Debug register scan chain interconnects // Debug register scan chain interconnects
logic [2:0] ScanReg; logic [2:0] DebugScanReg;
// instruction fetch unit: PC, branch prediction, instruction cache // instruction fetch unit: PC, branch prediction, instruction cache
ifu #(P) ifu(.clk, .reset, ifu #(P) ifu(.clk, .reset,
@ -208,7 +216,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissF, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .ITLBWriteF, .sfencevmaM, .ITLBMissF,
// pmp/pma (inside mmu) signals. // pmp/pma (inside mmu) signals.
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .InstrAccessFaultF, .InstrUpdateDAF,
.DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(ScanReg[0]), .DebugScanOut(ScanReg[1])); .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(DebugScanReg[0]), .DebugScanOut(DebugScanReg[1]));
// integer execution unit: integer register file, datapath and controller // integer execution unit: integer register file, datapath and controller
ieu #(P) ieu(.clk, .reset, ieu #(P) ieu(.clk, .reset,
@ -234,7 +242,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.StructuralStallD, .LoadStallD, .StoreStallD, .PCSrcE, .StructuralStallD, .LoadStallD, .StoreStallD, .PCSrcE,
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM,
.DebugScanEn, .DebugScanIn(ScanReg[1]), .GPRScanIn(DebugScanIn), .DebugScanOut(ScanReg[2]), .GPRScanOut, .DebugScanEn, .DebugScanIn(DebugScanReg[1]), .GPRScanIn(DebugScanIn), .DebugScanOut(DebugScanReg[2]), .GPRScanOut,
.MiscSel, .GPRSel, .DebugCapture, .DebugRegUpdate, .DebugRegAddr(DebugRegAddr[4:0])); .MiscSel, .GPRSel, .DebugCapture, .DebugRegUpdate, .DebugRegAddr(DebugRegAddr[4:0]));
lsu #(P) lsu( lsu #(P) lsu(
@ -271,7 +279,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.StoreAmoAccessFaultM, // connects to privilege .StoreAmoAccessFaultM, // connects to privilege
.InstrUpdateDAF, .InstrUpdateDAF,
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM, .DebugCapture, .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(ScanReg[2]), .DebugScanOut); .LSUStallM, .DebugCapture, .DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(DebugScanReg[2]), .DebugScanOut);
if(P.BUS_SUPPORTED) begin : ebu if(P.BUS_SUPPORTED) begin : ebu
ebu #(P) ebu(// IFU connections ebu #(P) ebu(// IFU connections
@ -300,7 +308,17 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.wfiM, .IntPendingM, .DebugStall, .wfiM, .IntPendingM, .DebugStall,
// Stall & flush outputs // Stall & flush outputs
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushD, .FlushE, .FlushM, .FlushW); .FlushD, .FlushE, .FlushM, .FlushW);
if (P.DEBUG_SUPPORTED) begin
dmc debugcontrol(
.clk, .reset,
.Step, .HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset,
.ResumeAck, .HaveReset, .DebugMode, .DebugStall
);
end else begin
assign DebugStall = 1'b0;
end
// privileged unit // privileged unit
if (P.ZICSR_SUPPORTED) begin:priv if (P.ZICSR_SUPPORTED) begin:priv
@ -324,10 +342,10 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PrivilegeModeW, .SATP_REGW, .PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE, .wfiM, .IntPendingM, .BigEndianM, .Step,
.DebugSel(CSRSel), .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn(DebugScanEn & CSRSel), .DebugScanIn, .DebugScanOut(CSRScanOut)); .DebugSel(CSRSel), .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn(DebugScanEn & CSRSel), .DebugScanIn, .DebugScanOut(CSRScanOut));
if (P.DEBUG_SUPPORTED) begin if (P.DEBUG_SUPPORTED) begin
flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(ScanReg[0])); flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanReg[0]));
end end
end else begin end else begin
assign {CSRReadValW, PrivilegeModeW, assign {CSRReadValW, PrivilegeModeW,
@ -336,7 +354,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
ENVCFG_CBE, ENVCFG_PBMTE, ENVCFG_ADUE, ENVCFG_CBE, ENVCFG_PBMTE, ENVCFG_ADUE,
EPCM, TrapVectorM, RetM, TrapM, EPCM, TrapVectorM, RetM, TrapM,
sfencevmaM, BigEndianM, wfiM, IntPendingM} = '0; sfencevmaM, BigEndianM, wfiM, IntPendingM} = '0;
assign ScanReg[0] = DebugScanIn; assign DebugScanReg[0] = DebugScanIn;
end end
// multiply/divide unit // multiply/divide unit

View File

@ -73,9 +73,17 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic [63:0] MTIME_CLINT; // from CLINT to CSRs
logic MExtInt,SExtInt; // from PLIC logic MExtInt,SExtInt; // from PLIC
// Debug Module signals // Debug Mode control signals
logic NdmReset; logic NdmReset;
logic HaltReq;
logic ResumeReq;
logic HaltOnReset;
logic AckHaveReset;
logic ResumeAck;
logic HaveReset;
logic DebugMode;
logic DebugStall; logic DebugStall;
// Debug Module signals
logic DebugScanEn; logic DebugScanEn;
logic DebugScanIn; logic DebugScanIn;
logic GPRScanIn; logic GPRScanIn;
@ -98,7 +106,8 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
.DebugStall, .DebugScanEn, .DebugScanOut(DebugScanIn), .GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn), .HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugMode,
.DebugScanEn, .DebugScanOut(DebugScanIn), .GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn),
.DebugScanIn(DebugScanOut), .MiscSel, .GPRSel, .FPRSel, .CSRSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate); .DebugScanIn(DebugScanOut), .MiscSel, .GPRSel, .FPRSel, .CSRSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate);
// instantiate uncore if a bus interface exists // instantiate uncore if a bus interface exists
@ -115,7 +124,8 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
// instantiate debug module // instantiate debug module
if (P.DEBUG_SUPPORTED) begin : dm if (P.DEBUG_SUPPORTED) begin : dm
dm #(P) dm (.clk, .rst(reset), .tck, .tdi, .tms, .tdo, .NdmReset, .DebugStall, dm #(P) dm (.clk, .rst(reset), .tck, .tdi, .tms, .tdo, .NdmReset,
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugMode,
.DebugScanEn, .DebugScanIn, .GPRScanIn, .FPRScanIn, .CSRScanIn, .DebugScanOut, .DebugScanEn, .DebugScanIn, .GPRScanIn, .FPRScanIn, .CSRScanIn, .DebugScanOut,
.MiscSel, .GPRSel, .FPRSel, .CSRSel, .RegAddr(DebugRegAddr), .DebugCapture, .DebugRegUpdate); .MiscSel, .GPRSel, .FPRSel, .CSRSel, .RegAddr(DebugRegAddr), .DebugCapture, .DebugRegUpdate);
end end