clean up repo

This commit is contained in:
Matthew 2024-06-03 22:21:02 -05:00
parent 5a03fbee97
commit bc36edece2
17 changed files with 697 additions and 668 deletions

View File

@ -71,6 +71,12 @@ set_property PACKAGE_PIN D9 [get_ports {south_reset}]
set_property IOSTANDARD LVCMOS33 [get_ports {south_reset}]
##### JTAG Port #####
set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports tck]
set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports tdo]
set_property -dict {PACKAGE_PIN A11 IOSTANDARD LVCMOS33} [get_ports tms]
set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports tdi]
##### SD Card I/O #####
#***** may have to switch to Pmod JB or JC.

View File

@ -58,7 +58,12 @@ module fpgaTop
output [0:0] ddr3_cke,
output [0:0] ddr3_cs_n,
output [1:0] ddr3_dm,
output [0:0] ddr3_odt
output [0:0] ddr3_odt,
// JTAG signals
input tck,
input tdi,
input tms,
output tdo
);
wire CPUCLK;
@ -490,7 +495,7 @@ module fpgaTop
`include "parameter-defs.vh"
wallypipelinedsoc #(P)
wallypipelinedsoc(.clk(CPUCLK), .reset_ext(bus_struct_reset), .reset(),
wallypipelinedsoc(.clk(CPUCLK), .reset_ext(bus_struct_reset), .reset(), .tck, .tdi, .tms, .tdo,
.HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT,
.HSELEXTSDC, .HCLK(HCLKOpen), .HRESETn(HRESETnOpen),
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,

View File

@ -26,411 +26,412 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module dm import cvw::*; #(parameter cvw_t P) (
input logic clk,
input logic rst, // Full hardware reset signal (reset button)
input logic clk,
input logic rst,
// External JTAG signals
input logic tck,
input logic tdi,
input logic tms,
output logic tdo,
input logic tck,
input logic tdi,
input logic tms,
output logic tdo,
// Platform reset signal
output logic NdmReset,
output logic NdmReset,
// Core hazard signal
output logic DebugStall,
output logic DebugStall,
// Scan Chain
output logic ScanEn,
input logic ScanIn,
output logic ScanOut,
output logic GPRSel,
output logic DebugCapture,
output logic DebugGPRUpdate,
output logic ScanEn,
input logic ScanIn,
output logic ScanOut,
output logic GPRSel,
output logic DebugCapture,
output logic DebugGPRUpdate,
output logic [P.E_SUPPORTED+3:0] GPRAddr,
output logic GPRScanEn,
input logic GPRScanIn,
output logic GPRScanOut
output logic GPRScanEn,
input logic GPRScanIn,
output logic GPRScanOut
);
`include "debug.vh"
// DMI Signals
logic ReqReady;
logic ReqValid;
logic [`ADDR_WIDTH-1:0] ReqAddress;
logic [31:0] ReqData;
logic [1:0] ReqOP;
logic RspReady;
logic RspValid;
logic [31:0] RspData;
logic [1:0] RspOP;
localparam JTAG_DEVICE_ID = 32'hdeadbeef; // TODO: put JTAG device ID in parameter struct
dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .tck, .tdi, .tms, .tdo,
.ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady,
.RspValid, .RspData, .RspOP);
// Core control signals
logic HaltReq;
logic ResumeReq;
logic HaltOnReset;
logic Halted;
hartcontrol hartcontrol(.clk, .rst(rst | ~DmActive), .NdmReset, .HaltReq,
.ResumeReq, .HaltOnReset, .DebugStall, .Halted, .AllRunning,
.AnyRunning, .AllHalted, .AnyHalted, .AllResumeAck, .AnyResumeAck);
// DMI Signals
logic ReqReady;
logic ReqValid;
logic [`ADDR_WIDTH-1:0] ReqAddress;
logic [31:0] ReqData;
logic [1:0] ReqOP;
logic RspReady;
logic RspValid;
logic [31:0] RspData;
logic [1:0] RspOP;
localparam JTAG_DEVICE_ID = 32'hdeadbeef; // TODO: put JTAG device ID in parameter struct
dtm #(`ADDR_WIDTH, JTAG_DEVICE_ID) dtm (.clk, .tck, .tdi, .tms, .tdo,
.ReqReady, .ReqValid, .ReqAddress, .ReqData, .ReqOP, .RspReady,
.RspValid, .RspData, .RspOP);
// Core control signals
logic HaltReq;
logic ResumeReq;
logic HaltOnReset;
logic Halted;
hartcontrol hartcontrol(.clk, .rst(rst || ~DmActive), .NdmReset, .HaltReq,
.ResumeReq, .HaltOnReset, .DebugStall, .Halted, .AllRunning,
.AnyRunning, .AllHalted, .AnyHalted, .AllResumeAck, .AnyResumeAck);
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,
INVALID} State;
enum logic [1:0] {AC_IDLE, AC_GPRUPDATE, AC_SCAN, AC_CAPTURE} AcState, NewAcState;
// AbsCmd internal state
logic AcWrite; // Abstract Command write state
logic [P.XLEN:0] ScanReg; // The part of the debug scan chain located within DM
logic [P.XLEN-1:0] ScanNext; // New ScanReg value
logic [P.XLEN-1:0] ARMask; // Masks which bits of the ScanReg get updated
logic [P.XLEN-1:0] PackedDataReg; // Combines DataX msg registers into a single XLEN wide register
logic [P.XLEN-1:0] MaskedScanReg; // Masks which bits of the ScanReg get written to DataX
logic [9:0] ShiftCount; // Position of the selected register on the debug scan chain
logic [9:0] ScanChainLen; // Total length of currently selected scan chain
logic [9:0] Cycle; // DM's current position in the scan chain
logic InvalidRegNo; // Requested RegNo is invalid
logic RegReadOnly; // Current RegNo points to a readonly register
logic GPRRegNo; // Requested RegNo is a GPR
logic StoreScanChain; // Store current value of ScanReg into DataX
logic WriteMsgReg; // Write to DataX
logic WriteScanReg; // Insert data from DataX 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
logic [31:0] Data3Wr; // Muxed inputs to DataX regs
enum logic [1:0] {AC_IDLE, AC_GPRUPDATE, AC_SCAN, AC_CAPTURE} AcState, NewAcState;
// AbsCmd internal state
logic AcWrite; // Abstract Command write state
logic [P.XLEN:0] ScanReg; // The part of the debug scan chain located within DM
logic [P.XLEN-1:0] ScanNext; // New ScanReg value
logic [P.XLEN-1:0] ARMask; // Masks which bits of the ScanReg get updated
logic [P.XLEN-1:0] PackedDataReg; // Combines DataX msg registers into a single XLEN wide register
logic [P.XLEN-1:0] MaskedScanReg; // Masks which bits of the ScanReg get written to DataX
logic [9:0] ShiftCount; // Position of the selected register on the debug scan chain
logic [9:0] ScanChainLen; // Total length of currently selected scan chain
logic [9:0] Cycle; // DM's current position in the scan chain
logic InvalidRegNo; // Requested RegNo is invalid
logic RegReadOnly; // Current RegNo points to a readonly register
logic GPRRegNo; // Requested RegNo is a GPR
logic StoreScanChain; // Store current value of ScanReg into DataX
logic WriteMsgReg; // Write to DataX
logic WriteScanReg; // Insert data from DataX 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
logic [31:0] Data3Wr; // Muxed inputs to DataX regs
// message registers
logic [31:0] Data0; // 0x04
logic [31:0] Data1; // 0x05
logic [31:0] Data2; // 0x06
logic [31:0] Data3; // 0x07
// debug module registers
logic [31:0] DMControl; // 0x10
logic [31:0] DMStatus; // 0x11
logic [31:0] AbstractCS; // 0x16
logic [31:0] SysBusCS; // 0x38
// DM register fields
// DMControl
logic AckUnavail;
logic DmActive; // This bit is used to (de)activate the DM. Toggling acts as reset
// DMStatus
logic StickyUnavail;
logic ImpEBreak;
logic AllResumeAck;
logic AnyResumeAck;
logic AllNonExistent;
logic AnyNonExistent;
logic AllUnavail; // TODO
logic AnyUnavail;
logic AllRunning;
logic AnyRunning;
logic AllHalted;
logic AnyHalted;
const logic Authenticated = 1;
logic AuthBusy;
const logic HasResetHaltReq = 1;
logic ConfStrPtrValid;
const logic [3:0] Version = 3; // DM Version
// AbstractCS
const logic [4:0] ProgBufSize = 0;
logic Busy;
const logic RelaxedPriv = 1;
logic [2:0] CmdErr;
const logic [3:0] DataCount = (P.XLEN/32);
// Pack registers
assign DMControl = {2'b0, 1'b0, 2'b0, 1'b0, 10'b0,
10'b0, 4'b0, NdmReset, DmActive};
logic [31:0] Data0; // 0x04
logic [31:0] Data1; // 0x05
logic [31:0] Data2; // 0x06
logic [31:0] Data3; // 0x07
assign DMStatus = {7'b0, 1'b0, StickyUnavail, ImpEBreak, 2'b0,
2'b0, AllResumeAck, AnyResumeAck, AllNonExistent,
AnyNonExistent, AllUnavail, AnyUnavail, AllRunning, AnyRunning, AllHalted,
AnyHalted, Authenticated, AuthBusy, HasResetHaltReq, ConfStrPtrValid, Version};
assign AbstractCS = {3'b0, ProgBufSize, 11'b0, Busy, RelaxedPriv, CmdErr, 4'b0, DataCount};
assign SysBusCS = 32'h20000000; // SBVersion = 1
assign RspValid = (State == ACK);
assign ReqReady = (State != ACK);
// debug module registers
logic [31:0] DMControl; // 0x10
logic [31:0] DMStatus; // 0x11
logic [31:0] AbstractCS; // 0x16
logic [31:0] SysBusCS; // 0x38
always_ff @(posedge clk) begin
if (rst) begin
DmActive <= 0;
State <= INACTIVE;
end else begin
case (State)
INACTIVE : begin
// Reset Values
RspData <= 0;
HaltReq <= 0;
HaltOnReset <= 0;
NdmReset <= 0;
StickyUnavail <= 0;
ImpEBreak <= 0;
AuthBusy <= 0;
ConfStrPtrValid <= 0;
CmdErr <= 0;
if (ReqValid) begin
if (ReqAddress == `DMCONTROL & ReqOP == `OP_WRITE & ReqData[`DMACTIVE]) begin
DmActive <= ReqData[`DMACTIVE];
RspOP <= `OP_SUCCESS;
end
State <= ACK; // acknowledge all Reqs even if they don't activate DM
//// DM register fields
// DMControl
logic AckUnavail;
logic DmActive; // This bit is used to (de)activate the DM. Toggling acts as reset
// DMStatus
logic StickyUnavail;
logic ImpEBreak;
logic AllResumeAck;
logic AnyResumeAck;
logic AllNonExistent;
logic AnyNonExistent;
logic AllUnavail; // TODO
logic AnyUnavail;
logic AllRunning;
logic AnyRunning;
logic AllHalted;
logic AnyHalted;
const logic Authenticated = 1;
logic AuthBusy;
const logic HasResetHaltReq = 1;
logic ConfStrPtrValid;
const logic [3:0] Version = 3; // DM Version
// AbstractCS
const logic [4:0] ProgBufSize = 0;
logic Busy;
const logic RelaxedPriv = 1;
logic [2:0] CmdErr;
const logic [3:0] DataCount = (P.XLEN/32);
// Pack registers
assign DMControl = {2'b0, 1'b0, 2'b0, 1'b0, 10'b0,
10'b0, 4'b0, NdmReset, DmActive};
assign DMStatus = {7'b0, 1'b0, StickyUnavail, ImpEBreak, 2'b0,
2'b0, AllResumeAck, AnyResumeAck, AllNonExistent,
AnyNonExistent, AllUnavail, AnyUnavail, AllRunning, AnyRunning, AllHalted,
AnyHalted, Authenticated, AuthBusy, HasResetHaltReq, ConfStrPtrValid, Version};
assign AbstractCS = {3'b0, ProgBufSize, 11'b0, Busy, RelaxedPriv, CmdErr, 4'b0, DataCount};
assign SysBusCS = 32'h20000000; // SBVersion = 1
assign RspValid = (State == ACK);
assign ReqReady = (State != ACK);
always_ff @(posedge clk) begin
if (rst) begin
DmActive <= 0;
State <= INACTIVE;
end else begin
case (State)
INACTIVE : begin
// Reset Values
RspData <= 0;
HaltReq <= 0;
HaltOnReset <= 0;
NdmReset <= 0;
StickyUnavail <= 0;
ImpEBreak <= 0;
AuthBusy <= 0;
ConfStrPtrValid <= 0;
CmdErr <= 0;
if (ReqValid) begin
if (ReqAddress == `DMCONTROL && ReqOP == `OP_WRITE && ReqData[`DMACTIVE]) begin
DmActive <= ReqData[`DMACTIVE];
RspOP <= `OP_SUCCESS;
end
State <= ACK; // acknowledge all Reqs even if they don't activate DM
end
end
ACK : begin
NewAcState <= AC_IDLE;
ResumeReq <= 0;
if (~ReqValid)
State <= ~DmActive ? INACTIVE : IDLE;
end
IDLE : begin
if (ReqValid)
case ({ReqOP, ReqAddress}) inside
{`OP_WRITE,`DATA0} : State <= W_DATA;
{`OP_READ,`DATA0} : State <= R_DATA;
{`OP_WRITE,`DATA1} : State <= (P.XLEN >= 64) ? W_DATA : INVALID;
{`OP_READ,`DATA1} : State <= (P.XLEN >= 64) ? R_DATA : INVALID;
[{`OP_WRITE,`DATA2}:{`OP_WRITE,`DATA3}] : State <= (P.XLEN >= 128) ? W_DATA : INVALID;
[{`OP_READ,`DATA2}:{`OP_READ,`DATA3}] : State <= (P.XLEN >= 128) ? R_DATA : INVALID;
{`OP_WRITE,`DMCONTROL} : State <= W_DMCONTROL;
{`OP_READ,`DMCONTROL} : State <= R_DMCONTROL;
{`OP_READ,`DMSTATUS} : State <= DMSTATUS;
{`OP_WRITE,`ABSTRACTCS} : State <= W_ABSTRACTCS;
{`OP_READ,`ABSTRACTCS} : State <= R_ABSTRACTCS;
{`OP_WRITE,`COMMAND} : State <= ABST_COMMAND;
{`OP_READ,`COMMAND} : State <= READ_ZERO;
{`OP_WRITE,`SBCS} : State <= READ_ZERO;
{`OP_READ,`SBCS} : State <= R_SYSBUSCS;
{2'bx,`HARTINFO},
{2'bx,`ABSTRACTAUTO},
{2'bx,`NEXTDM} : State <= READ_ZERO;
default : State <= INVALID;
endcase
end
R_DATA : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
case (ReqAddress)
`DATA0 : RspData <= Data0;
`DATA1 : RspData <= Data1;
`DATA2 : RspData <= Data2;
`DATA3 : RspData <= Data3;
endcase
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_DATA : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_DMCONTROL : begin
// While an abstract command is executing (busy in abstractcs is high), a debugger must not change
// hartsel, and must not write 1 to haltreq, resumereq, ackhavereset, setresethaltreq, or clrresethaltreq
if (Busy && (ReqData[`HALTREQ] || ReqData[`RESUMEREQ] || ReqData[`SETRESETHALTREQ] || ReqData[`CLRRESETHALTREQ]))
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
else begin
HaltReq <= ReqData[`HALTREQ];
AckUnavail <= ReqData[`ACKUNAVAIL];
NdmReset <= ReqData[`NDMRESET];
DmActive <= ReqData[`DMACTIVE]; // Writing 0 here resets the DM
// On any given write, a debugger may only write 1 to at most one of the following bits: resumereq,
// hartreset, ackhavereset, setresethaltreq, and clrresethaltreq. The others must be written 0
case ({ReqData[`RESUMEREQ],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]})
3'b000 :; // None
3'b100 : ResumeReq <= 1;
3'b010 : HaltOnReset <= 1;
3'b001 : HaltOnReset <= 0;
default : begin // Invalid (not onehot), dont write any changes
HaltReq <= HaltReq;
AckUnavail <= AckUnavail;
NdmReset <= NdmReset;
DmActive <= DmActive;
end
end
ACK : begin
NewAcState <= AC_IDLE;
ResumeReq <= 0;
if (~ReqValid)
State <= ~DmActive ? INACTIVE : IDLE;
end
IDLE : begin
if (ReqValid)
case ({ReqOP, ReqAddress}) inside
{`OP_WRITE,`DATA0} : State <= W_DATA;
{`OP_READ,`DATA0} : State <= R_DATA;
{`OP_WRITE,`DATA1} : State <= (P.XLEN >= 64) ? W_DATA : INVALID;
{`OP_READ,`DATA1} : State <= (P.XLEN >= 64) ? R_DATA : INVALID;
[{`OP_WRITE,`DATA2}:{`OP_WRITE,`DATA3}] : State <= (P.XLEN >= 128) ? W_DATA : INVALID;
[{`OP_READ,`DATA2}:{`OP_READ,`DATA3}] : State <= (P.XLEN >= 128) ? R_DATA : INVALID;
{`OP_WRITE,`DMCONTROL} : State <= W_DMCONTROL;
{`OP_READ,`DMCONTROL} : State <= R_DMCONTROL;
{`OP_READ,`DMSTATUS} : State <= DMSTATUS;
{`OP_WRITE,`ABSTRACTCS} : State <= W_ABSTRACTCS;
{`OP_READ,`ABSTRACTCS} : State <= R_ABSTRACTCS;
{`OP_WRITE,`COMMAND} : State <= ABST_COMMAND;
{`OP_READ,`COMMAND} : State <= READ_ZERO;
{`OP_WRITE,`SBCS} : State <= READ_ZERO;
{`OP_READ,`SBCS} : State <= R_SYSBUSCS;
{2'bx,`HARTINFO},
{2'bx,`ABSTRACTAUTO},
{2'bx,`NEXTDM} : State <= READ_ZERO;
default : State <= INVALID;
endcase
end
R_DATA : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
case (ReqAddress)
`DATA0 : RspData <= Data0;
`DATA1 : RspData <= Data1;
`DATA2 : RspData <= Data2;
`DATA3 : RspData <= Data3;
endcase
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_DATA : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_DMCONTROL : begin
// While an abstract command is executing (busy in abstractcs is high), a debugger must not change
// hartsel, and must not write 1 to haltreq, resumereq, ackhavereset, setresethaltreq, or clrresethaltreq
if (Busy & (ReqData[`HALTREQ] | ReqData[`RESUMEREQ] | ReqData[`SETRESETHALTREQ] | ReqData[`CLRRESETHALTREQ]))
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
else begin
HaltReq <= ReqData[`HALTREQ];
AckUnavail <= ReqData[`ACKUNAVAIL];
NdmReset <= ReqData[`NDMRESET];
DmActive <= ReqData[`DMACTIVE]; // Writing 0 here resets the DM
// On any given write, a debugger may only write 1 to at most one of the following bits: resumereq,
// hartreset, ackhavereset, setresethaltreq, and clrresethaltreq. The others must be written 0
case ({ReqData[`RESUMEREQ],ReqData[`SETRESETHALTREQ],ReqData[`CLRRESETHALTREQ]})
3'b000 :; // None
3'b100 : ResumeReq <= 1;
3'b010 : HaltOnReset <= 1;
3'b001 : HaltOnReset <= 0;
default : begin // Invalid (not onehot), dont write any changes
HaltReq <= HaltReq;
AckUnavail <= AckUnavail;
NdmReset <= NdmReset;
DmActive <= DmActive;
end
endcase
endcase
end
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_DMCONTROL : begin
RspData <= DMControl;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
DMSTATUS : begin
RspData <= DMStatus;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_ABSTRACTCS : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
else
CmdErr <= |ReqData[`CMDERR] ? `CMDERR_NONE : CmdErr; // clear CmdErr
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_ABSTRACTCS : begin
RspData <= AbstractCS;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
ABST_COMMAND : begin
if (CmdErr != `CMDERR_NONE); // If CmdErr, do nothing
else if (Busy)
CmdErr <= `CMDERR_BUSY; // If Busy, set CmdErr, do nothing
else if (~Halted)
CmdErr <= `CMDERR_HALTRESUME; // If not halted, set CmdErr, do nothing
else begin
case (ReqData[`CMDTYPE])
`ACCESS_REGISTER : begin
if (ReqData[`AARSIZE] > $clog2(P.XLEN/8)) // if AARSIZE (encoded) is greater than P.XLEN, set CmdErr, do nothing
CmdErr <= `CMDERR_BUS;
else if (~ReqData[`TRANSFER]); // If not TRANSFER, do nothing
else if (InvalidRegNo)
CmdErr <= `CMDERR_EXCEPTION; // If InvalidRegNo, set CmdErr, do nothing
else if (ReqData[`AARWRITE] && RegReadOnly)
CmdErr <= `CMDERR_NOT_SUPPORTED; // If writing to a read only register, set CmdErr, do nothing
else begin
AcWrite <= ReqData[`AARWRITE];
NewAcState <= AC_SCAN;
end
end
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_DMCONTROL : begin
RspData <= DMControl;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
DMSTATUS : begin
RspData <= DMStatus;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
W_ABSTRACTCS : begin
if (Busy)
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
else
CmdErr <= |ReqData[`CMDERR] ? `CMDERR_NONE : CmdErr; // clear CmdErr
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_ABSTRACTCS : begin
RspData <= AbstractCS;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
ABST_COMMAND : begin
if (CmdErr != `CMDERR_NONE); // If CmdErr, do nothing
else if (Busy)
CmdErr <= `CMDERR_BUSY; // If Busy, set CmdErr, do nothing
else if (~Halted)
CmdErr <= `CMDERR_HALTRESUME; // If not halted, set CmdErr, do nothing
else begin
case (ReqData[`CMDTYPE])
`ACCESS_REGISTER : begin
if (ReqData[`AARSIZE] > $clog2(P.XLEN/8)) // if AARSIZE (encoded) is greater than P.XLEN, set CmdErr, do nothing
CmdErr <= `CMDERR_BUS;
else if (~ReqData[`TRANSFER]); // If not TRANSFER, do nothing
else if (InvalidRegNo)
CmdErr <= `CMDERR_EXCEPTION; // If InvalidRegNo, set CmdErr, do nothing
else if (ReqData[`AARWRITE] & RegReadOnly)
CmdErr <= `CMDERR_NOT_SUPPORTED; // If writing to a read only register, set CmdErr, do nothing
else begin
AcWrite <= ReqData[`AARWRITE];
NewAcState <= AC_SCAN;
end
end
//`QUICK_ACCESS : State <= QUICK_ACCESS;
//`ACCESS_MEMORY : State <= ACCESS_MEMORY;
default : CmdErr <= `CMDERR_NOT_SUPPORTED;
endcase
end
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_SYSBUSCS : begin
RspData <= SysBusCS;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
READ_ZERO : begin // Writes ignored, Read Zero
RspData <= 0;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
INVALID : begin
RspOP <= `OP_FAILED;
State <= ACK;
end
endcase
end
end
// Abstract command engine
// Due to length of the register scan chain,
// abstract commands execute independently of other DM operations
always_ff @(posedge clk) begin
if (rst)
AcState <= AC_IDLE;
else begin
case (AcState)
AC_IDLE : begin
Cycle <= 0;
case (NewAcState)
AC_SCAN : AcState <= ~AcWrite ? AC_CAPTURE : AC_SCAN;
endcase
end
AC_CAPTURE : begin
AcState <= AC_SCAN;
end
AC_SCAN : begin
if (Cycle == ScanChainLen)
AcState <= (GPRRegNo & AcWrite) ? AC_GPRUPDATE : AC_IDLE;
else
Cycle <= Cycle + 1;
end
AC_GPRUPDATE : begin
AcState <= AC_IDLE;
end
endcase
end
end
assign Busy = ~(AcState == AC_IDLE);
assign DebugCapture = (AcState == AC_CAPTURE);
assign DebugGPRUpdate = (AcState == AC_GPRUPDATE);
// Scan Chain
assign GPRSel = GPRRegNo & (AcState != AC_IDLE);
assign ScanReg[P.XLEN] = GPRSel ? GPRScanIn : ScanIn;
assign ScanOut = GPRSel ? 1'b0 : ScanReg[0];
assign GPRScanOut = GPRSel ? ScanReg[0] : 1'b0;
assign ScanEn = ~GPRSel & (AcState == AC_SCAN);
assign GPRScanEn = GPRSel & (AcState == AC_SCAN);
// Load data from message registers into scan chain
if (P.XLEN == 32)
assign PackedDataReg = Data0;
else if (P.XLEN == 64)
assign PackedDataReg = {Data1,Data0};
else if (P.XLEN == 128)
assign PackedDataReg = {Data3,Data2,Data1,Data0};
assign WriteScanReg = AcWrite & (~GPRRegNo & (Cycle == ShiftCount) | GPRRegNo & (Cycle == 0));
genvar i;
for (i=0; i<P.XLEN; 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]));
end
// Message Registers
assign MaskedScanReg = ARMask & ScanReg[P.XLEN:1];
assign WriteMsgReg = (State == W_DATA) & ~Busy;
assign StoreScanChain = (AcState == AC_SCAN) & (Cycle == ShiftCount) & ~AcWrite;
assign Data0Wr = StoreScanChain ? MaskedScanReg[31:0] : ReqData;;
flopenr #(32) data0reg (.clk, .reset(rst), .en(StoreScanChain | WriteMsgReg & (ReqAddress == `DATA0)), .d(Data0Wr), .q(Data0));
if (P.XLEN >= 64) begin
assign Data1Wr = StoreScanChain ? MaskedScanReg[63:32] : ReqData;
flopenr #(32) data1reg (.clk, .reset(rst), .en(StoreScanChain | WriteMsgReg & (ReqAddress == `DATA1)), .d(Data1Wr), .q(Data1));
end
if (P.XLEN == 128) begin
assign Data2Wr = StoreScanChain ? MaskedScanReg[95:64] : ReqData;
assign Data3Wr = StoreScanChain ? MaskedScanReg[127:96] : ReqData;
flopenr #(32) data2reg (.clk, .reset(rst), .en(StoreScanChain | WriteMsgReg & (ReqAddress == `DATA2)), .d(Data2Wr), .q(Data2));
flopenr #(32) data3reg (.clk, .reset(rst), .en(StoreScanChain | WriteMsgReg & (ReqAddress == `DATA3)), .d(Data3Wr), .q(Data3));
end
rad #(P) regnodecode(.AarSize(ReqData[`AARSIZE]),.Regno(ReqData[`REGNO]),.GPRRegNo,.ScanChainLen,.ShiftCount,.InvalidRegNo,.RegReadOnly,.GPRAddr,.ARMask);
//`QUICK_ACCESS : State <= QUICK_ACCESS;
//`ACCESS_MEMORY : State <= ACCESS_MEMORY;
default : CmdErr <= `CMDERR_NOT_SUPPORTED;
endcase
end
RspOP <= `OP_SUCCESS;
State <= ACK;
end
R_SYSBUSCS : begin
RspData <= SysBusCS;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
READ_ZERO : begin // Writes ignored, Read Zero
RspData <= 0;
RspOP <= `OP_SUCCESS;
State <= ACK;
end
INVALID : begin
RspOP <= `OP_FAILED;
State <= ACK;
end
endcase
end
end
// Abstract command engine
// Due to length of the register scan chain,
// abstract commands execute independently of other DM operations
always_ff @(posedge clk) begin
if (rst)
AcState <= AC_IDLE;
else begin
case (AcState)
AC_IDLE : begin
Cycle <= 0;
case (NewAcState)
AC_SCAN : AcState <= ~AcWrite ? AC_CAPTURE : AC_SCAN;
endcase
end
AC_CAPTURE : begin
AcState <= AC_SCAN;
end
AC_SCAN : begin
if (Cycle == ScanChainLen)
AcState <= (GPRRegNo && AcWrite) ? AC_GPRUPDATE : AC_IDLE;
else
Cycle <= Cycle + 1;
end
AC_GPRUPDATE : begin
AcState <= AC_IDLE;
end
endcase
end
end
assign Busy = ~(AcState == AC_IDLE);
assign DebugCapture = (AcState == AC_CAPTURE);
assign DebugGPRUpdate = (AcState == AC_GPRUPDATE);
// Scan Chain
assign GPRSel = GPRRegNo && (AcState != AC_IDLE);
assign ScanReg[P.XLEN] = GPRSel ? GPRScanIn : ScanIn;
assign ScanOut = GPRSel ? 1'b0 : ScanReg[0];
assign GPRScanOut = GPRSel ? ScanReg[0] : 1'b0;
assign ScanEn = ~GPRSel && (AcState == AC_SCAN);
assign GPRScanEn = GPRSel && (AcState == AC_SCAN);
// Load data from message registers into scan chain
if (P.XLEN == 32)
assign PackedDataReg = Data0;
else if (P.XLEN == 64)
assign PackedDataReg = {Data1,Data0};
else if (P.XLEN == 128)
assign PackedDataReg = {Data3,Data2,Data1,Data0};
assign WriteScanReg = AcWrite && (~GPRRegNo && (Cycle == ShiftCount) || GPRRegNo && (Cycle == 0));
genvar i;
for (i=0; i<P.XLEN; 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]));
end
// Message Registers
assign MaskedScanReg = ARMask & ScanReg[P.XLEN:1];
assign WriteMsgReg = (State == W_DATA) && ~Busy;
assign StoreScanChain = (AcState == AC_SCAN) && (Cycle == ShiftCount) && ~AcWrite;
assign Data0Wr = StoreScanChain ? MaskedScanReg[31:0] : ReqData;;
flopenr #(32) data0reg (.clk, .reset(rst), .en(StoreScanChain || WriteMsgReg && (ReqAddress == `DATA0)), .d(Data0Wr), .q(Data0));
if (P.XLEN >= 64) begin
assign Data1Wr = StoreScanChain ? MaskedScanReg[63:32] : ReqData;
flopenr #(32) data1reg (.clk, .reset(rst), .en(StoreScanChain || WriteMsgReg && (ReqAddress == `DATA1)), .d(Data1Wr), .q(Data1));
end
if (P.XLEN == 128) begin
assign Data2Wr = StoreScanChain ? MaskedScanReg[95:64] : ReqData;
assign Data3Wr = StoreScanChain ? MaskedScanReg[127:96] : ReqData;
flopenr #(32) data2reg (.clk, .reset(rst), .en(StoreScanChain || WriteMsgReg && (ReqAddress == `DATA2)), .d(Data2Wr), .q(Data2));
flopenr #(32) data3reg (.clk, .reset(rst), .en(StoreScanChain || WriteMsgReg && (ReqAddress == `DATA3)), .d(Data3Wr), .q(Data3));
end
rad #(P) regnodecode(.AarSize(ReqData[`AARSIZE]),.Regno(ReqData[`REGNO]),.GPRRegNo,.ScanChainLen,.ShiftCount,.InvalidRegNo,.RegReadOnly,.GPRAddr,.ARMask);
endmodule

View File

@ -51,113 +51,114 @@ module dtm #(parameter ADDR_WIDTH, parameter JTAG_DEVICE_ID) (
);
`include "debug.vh"
enum logic [1:0] {IDLE, START, WAIT, COMPLETE} DMIState;
enum logic [1:0] {IDLE, START, WAIT, COMPLETE} DMIState;
// Clock Domain Crossing
logic tcks; // Synchronized JTAG clock
logic resetn;
logic UpdateDtmcs;
logic [31:0] DtmcsIn;
logic [31:0] DtmcsOut;
logic UpdateDmi;
logic CaptureDmi;
logic [34+ADDR_WIDTH-1:0] DmiIn;
logic [34+ADDR_WIDTH-1:0] DmiOut;
// DTMCS Register
const logic [2:0] ErrInfo = 0;
logic DtmHardReset;
logic DmiReset;
const logic [2:0] Idle = 0;
logic [1:0] DmiStat;
const logic [5:0] ABits = ADDR_WIDTH;
const logic [3:0] Version = 1; // DTM spec version 1
logic [31:0] ValRspData;
logic [1:0] ValRspOP;
logic Sticky;
assign DmiOut = {ReqAddress, ValRspData, ValRspOP};
assign DmiStat = ValRspOP;
// Synchronize the edges of tck to the system clock
synchronizer clksync (.clk(clk), .d(tck), .q(tcks));
jtag #(.ADDR_WIDTH(ADDR_WIDTH), .DEVICE_ID(JTAG_DEVICE_ID)) jtag (.tck(tcks), .tdi, .tms, .tdo,
// Clock Domain Crossing
logic tcks; // Synchronized JTAG clock
logic resetn;
logic UpdateDtmcs;
logic [31:0] DtmcsIn;
logic [31:0] DtmcsOut;
logic UpdateDmi;
logic CaptureDmi;
logic [34+ADDR_WIDTH-1:0] DmiIn;
logic [34+ADDR_WIDTH-1:0] DmiOut;
// DTMCS Register
const logic [2:0] ErrInfo = 0;
logic DtmHardReset;
logic DmiReset;
const logic [2:0] Idle = 0;
logic [1:0] DmiStat;
const logic [5:0] ABits = ADDR_WIDTH;
const logic [3:0] Version = 1; // DTM spec version 1
logic [31:0] ValRspData;
logic [1:0] ValRspOP;
logic Sticky;
assign DmiOut = {ReqAddress, ValRspData, ValRspOP};
assign DmiStat = ValRspOP;
// Synchronize the edges of tck to the system clock
synchronizer clksync (.clk(clk), .d(tck), .q(tcks));
jtag #(.ADDR_WIDTH(ADDR_WIDTH), .DEVICE_ID(JTAG_DEVICE_ID)) jtag (.tck(tcks), .tdi, .tms, .tdo,
.resetn, .UpdateDtmcs, .DtmcsIn, .DtmcsOut, .CaptureDmi, .UpdateDmi, .DmiIn, .DmiOut);
// DTMCS
assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version};
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
DtmHardReset <= 0;
DmiReset <= 0;
end else if (UpdateDtmcs) begin
DtmHardReset <= DtmcsIn[17];
DmiReset <= DtmcsIn[16];
end else if (DmiReset) begin
DmiReset <= 0;
end
end
// DMI
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
ValRspData <= 0;
ValRspOP <= `OP_SUCCESS;
//ErrInfo <= 4;
Sticky <= 0;
DMIState <= IDLE;
end else if (DmiReset) begin
ValRspOP <= `OP_SUCCESS;
//ErrInfo <= 4;
Sticky <= 0;
end else
case (DMIState)
IDLE : begin
if (UpdateDmi & ~Sticky & DmiIn[1:0] != `OP_NOP) begin
{ReqAddress, ReqData, ReqOP} <= DmiIn;
ReqValid <= 1;
// DmiOut is captured immediately on CaptureDmi
// this preemptively sets BUSY for next capture unless overwritten
ValRspOP <= `OP_BUSY;
DMIState <= START;
end else begin
ReqValid <= 0;
if (~Sticky)
ValRspOP <= `OP_SUCCESS;
end
end
START : begin
if (ReqReady) begin
ReqValid <= 0;
RspReady <= 1;
DMIState <= WAIT;
end
end
WAIT : begin
if (RspValid) begin
ValRspData <= RspData;
if (~Sticky) // update OP if it isn't currently a sticky value
ValRspOP <= RspOP;
if (RspOP == `OP_FAILED | RspOP == `OP_BUSY)
Sticky <= 1;
//if (RspOP == `OP_FAILED)
// ErrInfo <= 3;
DMIState <= COMPLETE;
end else if (CaptureDmi)
Sticky <= 1;
end
COMPLETE : begin
if (CaptureDmi) begin
RspReady <= 0;
DMIState <= IDLE;
end
// DTMCS
assign DtmcsOut = {11'b0, ErrInfo, 3'b0, Idle, DmiStat, ABits, Version};
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
DtmHardReset <= 0;
DmiReset <= 0;
end else if (UpdateDtmcs) begin
DtmHardReset <= DtmcsIn[17];
DmiReset <= DtmcsIn[16];
end else if (DmiReset) begin
DmiReset <= 0;
end
end
// DMI
always_ff @(posedge clk) begin
if (~resetn | DtmHardReset) begin
ValRspData <= 0;
ValRspOP <= `OP_SUCCESS;
//ErrInfo <= 4;
Sticky <= 0;
DMIState <= IDLE;
end else if (DmiReset) begin
ValRspOP <= `OP_SUCCESS;
//ErrInfo <= 4;
Sticky <= 0;
end else
case (DMIState)
IDLE : begin
if (UpdateDmi & ~Sticky & DmiIn[1:0] != `OP_NOP) begin
{ReqAddress, ReqData, ReqOP} <= DmiIn;
ReqValid <= 1;
// DmiOut is captured immediately on CaptureDmi
// this preemptively sets BUSY for next capture unless overwritten
ValRspOP <= `OP_BUSY;
DMIState <= START;
end else begin
ReqValid <= 0;
if (~Sticky)
ValRspOP <= `OP_SUCCESS;
end
endcase
end
end
START : begin
if (ReqReady) begin
ReqValid <= 0;
RspReady <= 1;
DMIState <= WAIT;
end
end
WAIT : begin
if (RspValid) begin
ValRspData <= RspData;
if (~Sticky) // update OP if it isn't currently a sticky value
ValRspOP <= RspOP;
if (RspOP == `OP_FAILED | RspOP == `OP_BUSY)
Sticky <= 1;
//if (RspOP == `OP_FAILED)
// ErrInfo <= 3;
DMIState <= COMPLETE;
end else if (CaptureDmi)
Sticky <= 1;
end
COMPLETE : begin
if (CaptureDmi) begin
RspReady <= 0;
DMIState <= IDLE;
end
end
endcase
end
endmodule

View File

@ -49,12 +49,12 @@ module ir (
// Shift register
always @(posedge clockIR) begin
shift_reg[0] <= shift_reg[1] | captureIR;
shift_reg[0] <= shift_reg[1] || captureIR;
end
genvar i;
for (i = INST_REG_WIDTH; i > 1; i = i - 1) begin
always @(posedge clockIR) begin
shift_reg[i-1] <= shift_reg[i] & ~captureIR;
shift_reg[i-1] <= shift_reg[i] && ~captureIR;
end
end

View File

@ -47,90 +47,90 @@ module jtag #(parameter ADDR_WIDTH, parameter DEVICE_ID) (
genvar i;
// Data signals
logic tdi_ir, tdi_dr;
logic tdo_ir, tdo_dr;
logic tdo_bypass;
logic tdo_idcode;
logic tdo_dtmcs;
logic tdo_dmi;
// TAP controller logic
logic tdo_en;
logic captureIR;
logic clockIR;
logic updateIR;
logic shiftDR;
logic captureDR;
logic clockDR;
logic updateDR;
logic select;
// Instruction signals
logic BypassInstr;
logic IDCodeInstr;
logic DtmcsIntrs;
logic DmiInstr;
logic [32:0] DtmcsShiftReg;
logic [34+ADDR_WIDTH:0] DmiShiftReg;
assign UpdateDtmcs = updateDR & DtmcsIntrs;
assign CaptureDmi = captureDR & DmiInstr;
assign UpdateDmi = updateDR & DmiInstr;
tap tap (.tck, .tms, .resetn, .tdo_en, .captureIR,
.clockIR, .updateIR, .shiftDR, .captureDR, .clockDR, .updateDR, .select);
// IR/DR input demux
assign tdi_ir = select ? tdi : 1'bz;
assign tdi_dr = select ? 1'bz : tdi;
// IR/DR output mux
assign tdo = ~tdo_en ? 1'bz :
select ? tdo_ir : tdo_dr;
ir ir (.clockIR, .tdi(tdi_ir), .resetn, .captureIR, .updateIR, .tdo(tdo_ir),
.BypassInstr, .IDCodeInstr, .DtmcsIntrs, .DmiInstr);
// DR demux
always_comb begin
unique case ({BypassInstr, IDCodeInstr, DtmcsIntrs, DmiInstr})
4'b1000 : tdo_dr <= tdo_bypass;
4'b0100 : tdo_dr <= tdo_idcode;
4'b0010 : tdo_dr <= tdo_dtmcs;
4'b0001 : tdo_dr <= tdo_dmi;
default : tdo_dr <= tdo_bypass;
endcase
end
always_ff @(posedge UpdateDtmcs)
DtmcsIn <= DtmcsShiftReg[31:0];
always_ff @(posedge UpdateDmi)
DmiIn <= DmiShiftReg[34+ADDR_WIDTH-1:0];
assign DtmcsShiftReg[32] = tdi_dr;
assign tdo_dtmcs = DtmcsShiftReg[0];
for (i = 0; i < 32; i = i + 1) begin
always_ff @(posedge clockDR) begin
DtmcsShiftReg[i] <= captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1];
end
end
assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr;
assign tdo_dmi = DmiShiftReg[0];
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) begin
always_ff @(posedge clockDR) begin
DmiShiftReg[i] <= captureDR ? DmiOut[i] : DmiShiftReg[i+1];
end
end
logic tdi_ir, tdi_dr;
logic tdo_ir, tdo_dr;
logic tdo_bypass;
logic tdo_idcode;
logic tdo_dtmcs;
logic tdo_dmi;
// TAP controller logic
logic tdo_en;
logic captureIR;
logic clockIR;
logic updateIR;
logic shiftDR;
logic captureDR;
logic clockDR;
logic updateDR;
logic select;
// Instruction signals
logic BypassInstr;
logic IDCodeInstr;
logic DtmcsIntrs;
logic DmiInstr;
logic [32:0] DtmcsShiftReg;
logic [34+ADDR_WIDTH:0] DmiShiftReg;
assign UpdateDtmcs = updateDR & DtmcsIntrs;
assign CaptureDmi = captureDR & DmiInstr;
assign UpdateDmi = updateDR & DmiInstr;
tap tap (.tck, .tms, .resetn, .tdo_en, .captureIR,
.clockIR, .updateIR, .shiftDR, .captureDR, .clockDR, .updateDR, .select);
// IR/DR input demux
assign tdi_ir = select ? tdi : 1'bz;
assign tdi_dr = select ? 1'bz : tdi;
// IR/DR output mux
assign tdo = ~tdo_en ? 1'bz :
select ? tdo_ir : tdo_dr;
ir ir (.clockIR, .tdi(tdi_ir), .resetn, .captureIR, .updateIR, .tdo(tdo_ir),
.BypassInstr, .IDCodeInstr, .DtmcsIntrs, .DmiInstr);
// DR demux
always_comb begin
unique case ({BypassInstr, IDCodeInstr, DtmcsIntrs, DmiInstr})
4'b1000 : tdo_dr <= tdo_bypass;
4'b0100 : tdo_dr <= tdo_idcode;
4'b0010 : tdo_dr <= tdo_dtmcs;
4'b0001 : tdo_dr <= tdo_dmi;
default : tdo_dr <= tdo_bypass;
endcase
end
always_ff @(posedge UpdateDtmcs)
DtmcsIn <= DtmcsShiftReg[31:0];
always_ff @(posedge UpdateDmi)
DmiIn <= DmiShiftReg[34+ADDR_WIDTH-1:0];
assign DtmcsShiftReg[32] = tdi_dr;
assign tdo_dtmcs = DtmcsShiftReg[0];
for (i = 0; i < 32; i = i + 1) begin
always_ff @(posedge clockDR) begin
DtmcsShiftReg[i] <= captureDR ? DtmcsOut[i] : DtmcsShiftReg[i+1];
end
end
assign DmiShiftReg[34+ADDR_WIDTH] = tdi_dr;
assign tdo_dmi = DmiShiftReg[0];
for (i = 0; i < 34+ADDR_WIDTH; i = i + 1) begin
always_ff @(posedge clockDR) begin
DmiShiftReg[i] <= captureDR ? DmiOut[i] : DmiShiftReg[i+1];
end
end
// jtag id register
idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode));
// bypass register
always_ff @(posedge clockDR) begin
tdo_bypass <= tdi_dr & shiftDR;
end
// jtag id register
idreg #(DEVICE_ID) id (.tdi(tdi_dr), .clockDR, .captureDR, .tdo(tdo_idcode));
// bypass register
always_ff @(posedge clockDR) begin
tdo_bypass <= tdi_dr & shiftDR;
end
endmodule

View File

@ -28,20 +28,21 @@
////////////////////////////////////////////////////////////////////////////////////////////////
module hazard import cvw::*; #(parameter cvw_t P) (
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
input logic StructuralStallD,
input logic LSUStallM, IFUStallF,
input logic FPUStallD,
input logic DivBusyE, FDivBusyE,
input logic wfiM, IntPendingM,
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
input logic StructuralStallD,
input logic LSUStallM, IFUStallF,
input logic FPUStallD,
input logic DivBusyE, FDivBusyE,
input logic wfiM, IntPendingM,
input logic DebugStall,
// Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushD, FlushE, FlushM, FlushW
);
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW;
logic FlushDCause, FlushECause, FlushMCause, FlushWCause;
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW;
logic FlushDCause, FlushECause, FlushMCause, FlushWCause;
logic WFIStallM, WFIInterruptedM;
@ -89,7 +90,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
// Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1.
// assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause;
// Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out.
assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause);
assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause) | DebugStall;
// Stall each stage for cause or if the next stage is stalled
// coverage off: StallFCause is always 0
@ -107,8 +108,9 @@ module hazard import cvw::*; #(parameter cvw_t P) (
assign LatestUnstalledW = ~StallW & StallM;
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
assign FlushD = LatestUnstalledD | FlushDCause;
assign FlushE = LatestUnstalledE | FlushECause;
assign FlushM = LatestUnstalledM | FlushMCause;
assign FlushW = LatestUnstalledW | FlushWCause;
// Do not flush if halted for Debug
assign FlushD = ~DebugStall & (LatestUnstalledD | FlushDCause);
assign FlushE = ~DebugStall & (LatestUnstalledE | FlushECause);
assign FlushM = ~DebugStall & (LatestUnstalledM | FlushMCause);
assign FlushW = ~DebugStall & (LatestUnstalledW | FlushWCause);
endmodule

View File

@ -93,7 +93,11 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
output logic [4:0] RdE, RdM, // Pipelined destination registers
// Forwarding controls
output logic [4:0] RdW // Register destinations in Execute, Memory, or Writeback stage
output logic [4:0] RdW, // Register destinations in Execute, Memory, or Writeback stage
// Debug scan chain
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
);
logic [4:0] Rs1E; // pipelined register sources
@ -452,11 +456,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM});
end
// FIXME: delete once working
//flopenrc #(25) controlregM(clk, reset, FlushM, ~StallM,
// {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE},
// {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM});
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
// Writeback stage pipeline control register

View File

@ -33,7 +33,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// Decode stage signals
input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, // Instruction in Decode stage
input logic [4:0] Rs1D, Rs2D, Rs2E, // Source registers
input logic [4:0] Rs1D, Rs2D, Rs2E, // Source registers
// Execute stage signals
input logic [P.XLEN-1:0] PCE, // PC in Execute stage
input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage)
@ -74,7 +74,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result
input logic [4:0] RdW, // Destination register
// Hazard Unit signals
// Debug scan chain
// Debug scan chain
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut,
@ -84,12 +84,12 @@ module datapath import cvw::*; #(parameter cvw_t P) (
input logic [P.E_SUPPORTED+3:0] GPRAddr,
input logic GPRScanEn,
input logic GPRScanIn,
output logic GPRScanOut
output logic GPRScanOut
);
// Fetch stage signals
// Decode stage signals
logic [4:0] DB_Rs1D; // (Debug) Muxed source register
logic [4:0] Rs1DM; // (Debug) Muxed source register
logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage
logic [4:0] RdD; // Destination register in Decode stage
@ -104,27 +104,29 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// Writeback stage signals
logic RegWriteWM; // (Debug) Muxed write enable
logic [P.XLEN-1:0] SCResultW; // Store Conditional result
logic [P.XLEN-1:0] ResultW; // Result to write to register file
logic [P.XLEN-1:0] ResultW;
logic [P.XLEN-1:0] ResultWM; // Result to write to register file
logic [4:0] RdWM; // Muxed GPR write address
logic [P.XLEN-1:0] IFResultW; // Result from either IEU or single-cycle FPU op writing an integer register
logic [P.XLEN-1:0] IFCvtResultW; // Result from IEU, signle-cycle FPU op, or 2-cycle FCVT float to int
logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division)
// Debug signals
// Debug signals
logic DSCR;
logic [P.XLEN-1:0] DebugGPRWriteD;
// Decode stage
extend #(P) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD);
// Access GPRs from Debug Module
if (P.DEBUG_SUPPORTED) begin
regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteWM, DB_Rs1D, Rs2D, RdWM, ResultWM, R1D, R2D);
regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteWM, Rs1DM, Rs2D, RdWM, ResultWM, R1D, R2D);
assign RegWriteWM = GPRSel ? DebugGPRUpdate : RegWriteW;
assign DB_Rs1D = GPRSel ? GPRAddr : Rs1D;
assign Rs1DM = GPRSel ? GPRAddr : Rs1D;
assign RdWM = GPRSel ? GPRAddr : RdW;
assign ResultWM = GPRSel ? DebugGPRWriteD : ResultW;
flopenrs #(P.XLEN) GPRScanReg(.clk, .reset, .en(DebugCapture), .d(R1D), .q(DebugGPRWriteD), .scan(GPRScanEn), .scanin(GPRScanIn), .scanout(GPRScanOut));
end else begin
regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
end
// FIXME: Delete once working
// regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
// Execute stage pipeline register and logic
flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
@ -147,8 +149,6 @@ module datapath import cvw::*; #(parameter cvw_t P) (
flopenrcs #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM, DebugScanEn, DebugScanIn, DebugScanOut);
else
flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
// FIXME: Delete once working
// flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
// Writeback stage pipeline register and logic
flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);

View File

@ -78,7 +78,19 @@ module ieu import cvw::*; #(parameter cvw_t P) (
output logic LoadStallD, // Structural stalls for load, sent to performance counters
output logic StoreStallD, // load after store hazard
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
output logic CSRWriteFenceM, // CSR write or fence instruction needs to flush subsequent instructions
// Debug scan chain
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut,
// GPR debug scan chain
input logic GPRSel,
input logic DebugCapture,
input logic DebugGPRUpdate,
input logic [P.E_SUPPORTED+3:0] GPRAddr,
input logic GPRScanEn,
input logic GPRScanIn,
output logic GPRScanOut
);
logic [2:0] ImmSrcD; // Select type of immediate extension
@ -107,6 +119,8 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic MDUE; // Multiply/divide instruction
logic BMUActiveE; // Bit manipulation instruction being executed
logic [1:0] CZeroE; // {czero.nez, czero.eqz} instructions active
logic DSCR;
controller #(P) c(
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
@ -120,7 +134,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM,
.RdW, .RdE, .RdM);
.RdW, .RdE, .RdM, .DebugScanEn, .DebugScanIn, .DebugScanOut(DSCR));
datapath #(P) dp(
.clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .Rs2E, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
@ -128,5 +142,6 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .CZeroE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW);
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .DebugScanEn, .DebugScanIn(DSCR), .DebugScanOut,
.GPRSel, .DebugCapture, .DebugGPRUpdate, .GPRAddr, .GPRScanEn, .GPRScanIn, .GPRScanOut);
endmodule

View File

@ -97,7 +97,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
output logic InstrAccessFaultF, // Instruction access fault
output logic ICacheAccess, // Report I$ read to performance counters
output logic ICacheMiss, // Report I$ miss to performance counters
// Debug scan chain
// Debug scan chain
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
@ -144,7 +144,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
logic [15:0] InstrRawE, InstrRawM;
logic [LINELEN-1:0] FetchBuffer;
logic [31:0] ShiftUncachedInstr;
// Debug scan chain
// Debug scan chain
logic DSCR;
assign PCFExt = {2'b00, PCSpillF};
@ -418,14 +418,9 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign InstrM = '0;
assign DebugScanOut = DSCR;
end
// FIXME: delete once working
// flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
//end else assign InstrM = '0;
// PCM is only needed with CSRs or branch prediction
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);
else
flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
@ -433,10 +428,6 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign PCM = '0;
assign DSCR = DebugScanIn;
end
// FIXME: delete once working
// flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
//else assign PCM = '0;
// If compressed instructions are supported, increment PCLink by 2 or 4 for a jal. Otherwise, just by 4
if (P.ZCA_SUPPORTED) begin

View File

@ -94,11 +94,11 @@ module lsu import cvw::*; #(parameter cvw_t P) (
output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP address from privileged unit
// Debug scan chain
// Debug scan chain
input logic DebugCapture,
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
output logic DebugScanOut
);
localparam logic MISALIGN_SUPPORT = P.ZICCLSM_SUPPORTED & P.DCACHE_SUPPORTED;
localparam MLEN = MISALIGN_SUPPORT ? 2*P.LLEN : P.LLEN; // widen buffer for misaligned accessess
@ -160,7 +160,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] WriteDataZM;
logic LSULoadPageFaultM, LSUStoreAmoPageFaultM;
logic DSCR; // Debug Register Scan In
logic DSCR;
/////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M
@ -170,10 +170,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
if (P.DEBUG_SUPPORTED)
flopenrcs #(P.XLEN) AddressMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(IEUAdrE), .q(IEUAdrM), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DSCR));
else
flopenrc #(P.XLEN) AddressMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(IEUAdrE), .q(IEUAdrM));
// FIXME: delete once working
// flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
flopenrc #(P.XLEN) AddressMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(IEUAdrE), .q(IEUAdrM));
if(MISALIGN_SUPPORT) begin : ziccslm_align
logic [P.XLEN-1:0] IEUAdrSpillE, IEUAdrSpillM;
align #(P) align(.clk, .reset, .StallM, .FlushM, .IEUAdrE, .IEUAdrM, .Funct3M, .FpLoadStoreM,

View File

@ -92,7 +92,12 @@ module csr import cvw::*; #(parameter cvw_t P) (
//
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 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 scan chain
input logic DebugCapture,
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
);
localparam MIP = 12'h344;
@ -236,7 +241,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
.MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM,
.IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM,
.MENVCFG_REGW);
.MENVCFG_REGW, .DebugCapture, .DebugScanEn, .DebugScanIn, .DebugScanOut);
if (P.S_SUPPORTED) begin:csrs

View File

@ -50,11 +50,11 @@ module csrm import cvw::*; #(parameter cvw_t P) (
output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM,
output logic [63:0] MENVCFG_REGW,
// Debug scan chain
// Debug scan chain
input logic DebugCapture,
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
output logic DebugScanOut
);
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
@ -136,7 +136,7 @@ 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
assign MISA_REGW = {(P.XLEN == 32 ? 2'b01 : 2'b10), {(P.XLEN-28){1'b0}}, MISA_26[25:0]};
// Dummy register to provide MISA read access to DM
// Dummy register to provide MISA read access to DM
if (P.DEBUG_SUPPORTED) begin
flopenrs #(P.XLEN) MISAScanReg (.clk, .reset, .en(DebugCapture), .d(MISA_REGW), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanOut));
end

View File

@ -96,9 +96,14 @@ module privileged import cvw::*; #(parameter cvw_t P) (
input logic InvalidateICacheM, // fence instruction
output logic BigEndianM, // Use big endian in current privilege mode
// 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
// Debug scan chain
input logic DebugCapture,
input logic DebugScanEn,
input logic DebugScanIn,
output logic DebugScanOut
);
logic [3:0] CauseM; // trap cause
logic [15:0] MEDELEG_REGW; // exception delegation CSR
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
@ -147,7 +152,8 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.SATP_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.SetFflagsM, .FRM_REGW, .ENVCFG_CBE, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.EPCM, .TrapVectorM,
.CSRReadValW, .IllegalCSRAccessM, .BigEndianM);
.CSRReadValW, .IllegalCSRAccessM, .BigEndianM,
.DebugCapture, .DebugScanEn, .DebugScanIn, .DebugScanOut);
// pipeline early-arriving trap sources
privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,

View File

@ -180,9 +180,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic DCacheStallM, ICacheStallF;
logic wfiM, IntPendingM;
// Debug register scan chain interconnects
// Debug register scan chain interconnects
logic [3:0] ScanReg;
// instruction fetch unit: PC, branch prediction, instruction cache
ifu #(P) ifu(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
@ -329,7 +329,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
end else begin
assign {CSRReadValW, PrivilegeModeW,
SATP_REGW, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_MPP, STATUS_FS, FRM_REGW,
// PMPCFG_ARRAY_REGW, PMPADDR_ARRAY_REGW,
// PMPCFG_ARRAY_REGW, PMPADDR_ARRAY_REGW,
ENVCFG_CBE, ENVCFG_PBMTE, ENVCFG_ADUE,
EPCM, TrapVectorM, RetM, TrapM,
sfencevmaM, BigEndianM, wfiM, IntPendingM} = '0;

View File

@ -73,31 +73,31 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
logic MExtInt,SExtInt; // from PLIC
// Debug Module signals
logic NdmReset;
logic DebugStall;
logic ScanEn;
logic ScanIn;
logic ScanOut;
logic GPRSel;
logic DebugCapture;
logic DebugGPRUpdate;
logic [P.E_SUPPORTED+3:0] GPRAddr;
logic GPRScanEn;
logic GPRScanIn;
logic GPRScanOut;
// Debug Module signals
logic NdmReset;
logic DebugStall;
logic ScanEn;
logic ScanIn;
logic ScanOut;
logic GPRSel;
logic DebugCapture;
logic DebugGPRUpdate;
logic [P.E_SUPPORTED+3:0] GPRAddr;
logic GPRScanEn;
logic GPRScanIn;
logic GPRScanOut;
// synchronize reset to SOC clock domain
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
// instantiate processor and internal memories
wallypipelinedcore #(P) core(.clk, .reset,
wallypipelinedcore #(P) core(.clk, .reset(reset || NdmReset),
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
.DebugStall, .DebugScanEn(ScanEn), .DebugScanIn(ScanOut), .DebugScanOut(ScanIn),
.GPRSel, .DebugCapture, .DebugGPRUpdate, .GPRAddr, .GPRScanEn, .GPRScanIn(GPRScanOut), .GPRScanOut(GPRScanIn)
);
.GPRSel, .DebugCapture, .DebugGPRUpdate, .GPRAddr, .GPRScanEn, .GPRScanIn(GPRScanOut), .GPRScanOut(GPRScanIn)
);
// instantiate uncore if a bus interface exists
if (P.BUS_SUPPORTED) begin : uncoregen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769
@ -111,12 +111,13 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
MTIME_CLINT, GPIOOUT, GPIOEN, UARTSout, SPIOut, SPICS} = '0;
end
// instantiate debug module (dm)
if (P.DEBUG_SUPPORTED) begin
// instantiate debug module
if (P.DEBUG_SUPPORTED) begin : dm
dm #(P) dm (.clk, .rst(reset), .NdmReset, .tck, .tdi, .tms, .tdo,
.DebugStall, .ScanEn, .ScanIn, .ScanOut, .GPRSel, .DebugCapture, .DebugGPRUpdate,
.GPRAddr, .GPRScanEn, .GPRScanIn, .GPRScanOut);
end else begin
assign {NdmReset, DebugStall, ScanOut, GPRSel, DebugCapture, DebugGPRUpdate, GPRAddr, GPRScanEn, GPRScanOut} = '0;
end
end
endmodule