add progbuff write logic stub

This commit is contained in:
Matthew 2024-06-16 15:21:02 -05:00
parent c853eeec9c
commit 7dd0182407
5 changed files with 80 additions and 33 deletions

View File

@ -36,6 +36,12 @@ random_stimulus = True
random_order = False
def prog_buff_test(cvw):
cvw.halt()
cvw.write_dmi("0x20", "0x7ee7beef")
print()
def flow_control_test():
with OpenOCD() as cvw:
cvw.reset_dm()
@ -153,5 +159,9 @@ def random_hex(reg_name):
return "0x" + f"{(data & (2**size-1)):x}".rjust(pad, "0")
#register_rw_test()
flow_control_test()
with OpenOCD() as cvw:
cvw.reset_dm()
cvw.reset_hart()
#register_rw_test()
#flow_control_test()
prog_buff_test(cvw)

View File

@ -47,6 +47,7 @@
`define COMMAND `ADDR_WIDTH'h17
`define ABSTRACTAUTO `ADDR_WIDTH'h18
`define NEXTDM `ADDR_WIDTH'h1d
`define PROGBUF0 `ADDR_WIDTH'h20
//`define dmcs2 `ADDR_WIDTH'h32
`define SBCS `ADDR_WIDTH'h38

View File

@ -26,13 +26,15 @@
////////////////////////////////////////////////////////////////////////////////////////////////
// TODO List:
// determine config/permissions of all CSRs
// improve halting / implement "debug mode"
//// Debug Mode = M-mode with stalled pipe
// Flush pipe with NOPs during halt?
// Alias DPC to PCF/PCNextF?
// add "progbuff" register to overwrite instrF
// overwrite wfi instructions with NOP during DebugMode
// mask all interrupts in debug mode (even NMI)
// Ignore traps in debug mode
// capture CSR read/write failures as convert them to cmderr
// Flush pipe with NOPs during halt?
// (stretch) add system bus access?
module dm import cvw::*; #(parameter cvw_t P) (
@ -50,7 +52,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
// Core control signals
input logic ResumeAck, // Signals Hart has been resumed
input logic HaveReset, // Signals Hart has been reset
input logic DebugMode, // Signals core is halted
input logic DebugStall, // 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
@ -69,7 +71,12 @@ module dm import cvw::*; #(parameter cvw_t P) (
output logic CSRSel, // selects CSR scan chain
output logic [11:0] RegAddr, // address for scanable regfiles (GPR, FPR, CSR)
output logic DebugCapture, // latches values into scan register before scanning out
output logic DebugRegUpdate // writes values from scan register after scanning in
output logic DebugRegUpdate, // writes values from scan register after scanning in
// Program Buffer
output logic ProgBuffScanEn,
output logic ProgBuffScanOut,
output logic ExecProgBuff
);
`include "debug.vh"
@ -96,10 +103,10 @@ module dm import cvw::*; #(parameter cvw_t P) (
.RspValid, .RspData, .RspOP);
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, W_PROGBUF, READ_ZERO,
INVALID} State;
enum logic [1:0] {AC_IDLE, AC_UPDATE, AC_SCAN, AC_CAPTURE} AcState, NewAcState;
enum logic [2:0] {AC_IDLE, AC_UPDATE, AC_SCAN, AC_CAPTURE, PROGBUFF_WRITE} AcState, NewAcState;
// AbsCmd internal state
logic AcWrite; // Abstract Command write state
@ -120,6 +127,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
logic StoreScanChain; // Store current value of ScanReg into DataX
logic WriteMsgReg; // Write to DataX
logic WriteScanReg; // Insert data from DataX into ScanReg
logic WriteProgBuff; // Insert data from DMI into ScanReg
logic [31:0] Data0Wr; // Muxed inputs to DataX regs
logic [31:0] Data1Wr; // Muxed inputs to DataX regs
logic [31:0] Data2Wr; // Muxed inputs to DataX regs
@ -143,7 +151,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
// DMStatus
const logic NdmResetPending = 0;
const logic StickyUnavail = 0;
const logic ImpEBreak = 0; // TODO: change this to const 1 if implementing 1x32bit progbuf
const logic ImpEBreak = 1;
logic AllHaveReset;
logic AnyHaveReset;
logic AllResumeAck;
@ -162,7 +170,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
const logic ConfStrPtrValid = 0; // Used with SysBusAccess
const logic [3:0] Version = 3; // DM Version
// AbstractCS
const logic [4:0] ProgBufSize = 0;
const logic [4:0] ProgBufSize = 1;
logic Busy;
const logic RelaxedPriv = 1;
logic [2:0] CmdErr;
@ -171,10 +179,10 @@ module dm import cvw::*; #(parameter cvw_t P) (
// Core control signals
assign AllHaveReset = HaveReset;
assign AnyHaveReset = HaveReset;
assign AnyHalted = DebugMode;
assign AllHalted = DebugMode;
assign AnyRunning = ~DebugMode;
assign AllRunning = ~DebugMode;
assign AnyHalted = DebugStall;
assign AllHalted = DebugStall;
assign AnyRunning = ~DebugStall;
assign AllRunning = ~DebugStall;
// 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;
@ -240,6 +248,8 @@ module dm import cvw::*; #(parameter cvw_t P) (
{`OP_READ,`COMMAND} : State <= READ_ZERO;
{`OP_WRITE,`SBCS} : State <= READ_ZERO;
{`OP_READ,`SBCS} : State <= R_SYSBUSCS;
{`OP_WRITE,`PROGBUF0} : State <= W_PROGBUF;
{`OP_READ,`PROGBUF0},
{2'bx,`HARTINFO},
{2'bx,`ABSTRACTAUTO},
{2'bx,`NEXTDM} : State <= READ_ZERO;
@ -330,7 +340,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
if (CmdErr != `CMDERR_NONE); // If CmdErr, do nothing
else if (Busy)
CmdErr <= `CMDERR_BUSY; // If Busy, set CmdErr, do nothing
else if (~DebugMode)
else if (~DebugStall)
CmdErr <= `CMDERR_HALTRESUME; // If not halted, set CmdErr, do nothing
else begin
case (ReqData[`CMDTYPE])
@ -344,7 +354,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
CmdErr <= `CMDERR_NOT_SUPPORTED; // If writing to a read only register, set CmdErr, do nothing
else begin
AcWrite <= ReqData[`AARWRITE];
NewAcState <= AC_SCAN;
NewAcState <= ~ReqData[`AARWRITE] ? AC_CAPTURE : AC_SCAN;
end
end
//`QUICK_ACCESS : State <= QUICK_ACCESS;
@ -356,6 +366,15 @@ module dm import cvw::*; #(parameter cvw_t P) (
State <= ACK;
end
W_PROGBUF : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
else
NewAcState <= PROGBUFF_WRITE;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_SYSBUSCS : begin
RspData <= SysBusCS;
RspOP <= `OP_SUCCESS;
@ -386,9 +405,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
case (AcState)
AC_IDLE : begin
Cycle <= 0;
case (NewAcState)
AC_SCAN : AcState <= ~AcWrite ? AC_CAPTURE : AC_SCAN;
endcase
AcState <= NewAcState;
end
AC_CAPTURE : begin
@ -409,13 +426,25 @@ module dm import cvw::*; #(parameter cvw_t P) (
AC_UPDATE : begin
AcState <= AC_IDLE;
end
PROGBUFF_WRITE : begin
if (Cycle == 32)
AcState <= AC_IDLE;
else
Cycle <= Cycle + 1;
end
endcase
end
end
assign Busy = ~(AcState == AC_IDLE);
// Program Buffer
assign ProgBuffScanEn = (AcState == PROGBUFF_WRITE);
assign ProgBuffScanOut = ScanReg[0];
// Scan Chain
assign DebugScanOut = ScanReg[0];
assign DebugScanEn = (AcState == AC_SCAN);
assign DebugCapture = (AcState == AC_CAPTURE);
assign DebugRegUpdate = (AcState == AC_UPDATE);
@ -426,7 +455,6 @@ module dm import cvw::*; #(parameter cvw_t P) (
assign GPRSel = GPRegNo & (AcState != AC_IDLE);
assign FPRSel = FPRegNo & (AcState != AC_IDLE);
assign DebugScanOut = ScanReg[0];
always_comb begin
case ({CSRSel, GPRSel, FPRSel})
@ -443,14 +471,19 @@ module dm import cvw::*; #(parameter cvw_t P) (
assign PackedDataReg = {Data1,Data0};
else if (P.LLEN == 128)
assign PackedDataReg = {Data3,Data2,Data1,Data0};
// Load data from DMI into scan chain
assign WriteProgBuff = (AcState == PROGBUFF_WRITE) & (Cycle == 0);
// Load data from message registers into scan chain
assign WriteScanReg = AcWrite & (MiscRegNo & (Cycle == ShiftCount) | ~MiscRegNo & (Cycle == 0));
genvar i;
for (i=0; i<P.LLEN; i=i+1) begin
// ARMask is used as write enable for subword overwrites (basic mask would overwrite neighbors in the chain)
assign ScanNext[i] = WriteScanReg & ARMask[i] ? PackedDataReg[i] : ScanReg[i+1];
flopenr #(1) scanreg (.clk, .reset(rst), .en(AcState == AC_SCAN), .d(ScanNext[i]), .q(ScanReg[i]));
if (i < 32)
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
// Message Registers

View File

@ -52,7 +52,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
input logic AckHaveReset,
output logic ResumeAck,
output logic HaveReset,
output logic DebugMode,
output logic DebugStall,
// Debug scan chain
input logic DebugScanEn, // puts scannable flops into scan mode
output logic DebugScanOut, // (misc) scan chain data out
@ -72,7 +72,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic StallF, StallD, StallE, StallM, StallW;
logic FlushD, FlushE, FlushM, FlushW;
logic TrapM, RetM;
logic DebugStall, Step;
logic DebugMode, Step;
// signals that must connect through DP
logic IntDivE, W64E;

View File

@ -81,7 +81,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
logic AckHaveReset;
logic ResumeAck;
logic HaveReset;
logic DebugMode;
logic DebugStall;
// Debug Module signals
logic DebugScanEn;
@ -97,6 +96,9 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
logic [11:0] DebugRegAddr;
logic DebugCapture;
logic DebugRegUpdate;
logic ProgBuffScanEn;
logic ProgBuffScanOut;
logic ExecProgBuff;
// synchronize reset to SOC clock domain
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
@ -106,7 +108,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugMode,
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall,
.DebugScanEn, .DebugScanOut(DebugScanIn), .GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn),
.DebugScanIn(DebugScanOut), .MiscSel, .GPRSel, .FPRSel, .CSRSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate);
@ -125,9 +127,10 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
// instantiate debug module
if (P.DEBUG_SUPPORTED) begin : dm
dm #(P) dm (.clk, .rst(reset), .tck, .tdi, .tms, .tdo, .NdmReset,
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugMode,
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall,
.DebugScanEn, .DebugScanIn, .GPRScanIn, .FPRScanIn, .CSRScanIn, .DebugScanOut,
.MiscSel, .GPRSel, .FPRSel, .CSRSel, .RegAddr(DebugRegAddr), .DebugCapture, .DebugRegUpdate);
.MiscSel, .GPRSel, .FPRSel, .CSRSel, .RegAddr(DebugRegAddr), .DebugCapture, .DebugRegUpdate,
.ProgBuffScanEn, .ProgBuffScanOut, .ExecProgBuff);
end
endmodule