mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Implement progbuf and attempt to halt/resume using existing trap logic (very broken)
This commit is contained in:
parent
5c593c3321
commit
9514eab75e
@ -38,7 +38,13 @@ random_order = False
|
|||||||
|
|
||||||
def prog_buff_test(cvw):
|
def prog_buff_test(cvw):
|
||||||
cvw.halt()
|
cvw.halt()
|
||||||
cvw.write_dmi("0x20", "0x7ee7beef")
|
cvw.write_dmi("0x20", "0x00100073")
|
||||||
|
#cvw.write_dmi("0x21", "0xf00daedd")
|
||||||
|
#cvw.write_dmi("0x22", "0xdaede105")
|
||||||
|
#cvw.write_dmi("0x23", "0x00100073") # ebreak
|
||||||
|
|
||||||
|
cvw.write_data("DPC", "0x00002000") # Progbuf addr
|
||||||
|
cvw.resume()
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
@ -46,10 +52,13 @@ def flow_control_test(cvw):
|
|||||||
#time.sleep(70) # wait for OpenSBI
|
#time.sleep(70) # wait for OpenSBI
|
||||||
|
|
||||||
cvw.halt()
|
cvw.halt()
|
||||||
cvw.read_data("DCSR")
|
time.sleep(1)
|
||||||
|
#cvw.read_data("DCSR")
|
||||||
for _ in range(50):
|
for _ in range(50):
|
||||||
cvw.step()
|
cvw.resume()
|
||||||
print(cvw.read_data("PCM"))
|
cvw.halt()
|
||||||
|
#cvw.step()
|
||||||
|
#print(cvw.read_data("PCM"))
|
||||||
cvw.resume()
|
cvw.resume()
|
||||||
|
|
||||||
|
|
||||||
@ -154,11 +163,11 @@ def random_hex(reg_name):
|
|||||||
|
|
||||||
|
|
||||||
with OpenOCD() as cvw:
|
with OpenOCD() as cvw:
|
||||||
print(cvw.read_dmi("0x16"))
|
#cvw.trst()
|
||||||
cvw.trst()
|
|
||||||
cvw.reset_dm()
|
cvw.reset_dm()
|
||||||
|
time.sleep(1)
|
||||||
cvw.reset_hart()
|
cvw.reset_hart()
|
||||||
quit()
|
time.sleep(1)
|
||||||
#register_rw_test(cvw)
|
#register_rw_test(cvw)
|
||||||
flow_control_test(cvw)
|
#flow_control_test(cvw)
|
||||||
#prog_buff_test(cvw)
|
prog_buff_test(cvw)
|
||||||
|
@ -114,6 +114,12 @@ class OpenOCD:
|
|||||||
raise Exception("Error: Hart failed to reset")
|
raise Exception("Error: Hart failed to reset")
|
||||||
self.write_dmi("0x10", "0x10000001") # ack HaveReset
|
self.write_dmi("0x10", "0x10000001") # ack HaveReset
|
||||||
|
|
||||||
|
def write_progbuf(self, data):
|
||||||
|
#TODO query progbuf size and error is len(data) is greater
|
||||||
|
baseaddr = 0x20
|
||||||
|
for idx, instr in enumerate(data):
|
||||||
|
self.write_dmi(hex(baseaddr+idx), instr)
|
||||||
|
|
||||||
def set_haltonreset(self):
|
def set_haltonreset(self):
|
||||||
self.write_dmi("0x10", "0x9")
|
self.write_dmi("0x10", "0x9")
|
||||||
|
|
||||||
@ -139,7 +145,7 @@ class OpenOCD:
|
|||||||
dcsr |= 0x4
|
dcsr |= 0x4
|
||||||
self.write_data("DCSR", hex(dcsr))
|
self.write_data("DCSR", hex(dcsr))
|
||||||
# Resume once
|
# Resume once
|
||||||
self.resume()
|
self.write_dmi("0x10", "0x40000001")
|
||||||
# Unset step bit
|
# Unset step bit
|
||||||
dcsr &= ~0x4
|
dcsr &= ~0x4
|
||||||
self.write_data("DCSR", hex(dcsr))
|
self.write_data("DCSR", hex(dcsr))
|
||||||
|
@ -186,6 +186,9 @@ localparam logic [63:0] SDC_RANGE = 64'h0000007F;
|
|||||||
localparam logic SPI_SUPPORTED = 1;
|
localparam logic SPI_SUPPORTED = 1;
|
||||||
localparam logic [63:0] SPI_BASE = 64'h10040000;
|
localparam logic [63:0] SPI_BASE = 64'h10040000;
|
||||||
localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
|
localparam logic [63:0] SPI_RANGE = 64'h00000FFF;
|
||||||
|
// Debug program buffer support is enabled with DEBUG_SUPPORTED
|
||||||
|
localparam logic [63:0] PROGBUF_BASE = 64'h00002000;
|
||||||
|
localparam logic [63:0] PROGBUF_RANGE = 64'h0000000F;
|
||||||
|
|
||||||
// Bus Interface width
|
// Bus Interface width
|
||||||
localparam AHBW = (XLEN);
|
localparam AHBW = (XLEN);
|
||||||
|
@ -48,6 +48,21 @@
|
|||||||
`define ABSTRACTAUTO `ADDR_WIDTH'h18
|
`define ABSTRACTAUTO `ADDR_WIDTH'h18
|
||||||
`define NEXTDM `ADDR_WIDTH'h1d
|
`define NEXTDM `ADDR_WIDTH'h1d
|
||||||
`define PROGBUF0 `ADDR_WIDTH'h20
|
`define PROGBUF0 `ADDR_WIDTH'h20
|
||||||
|
`define PROGBUF1 `ADDR_WIDTH'h21
|
||||||
|
`define PROGBUF2 `ADDR_WIDTH'h22
|
||||||
|
`define PROGBUF3 `ADDR_WIDTH'h23
|
||||||
|
`define PROGBUF4 `ADDR_WIDTH'h24
|
||||||
|
`define PROGBUF5 `ADDR_WIDTH'h25
|
||||||
|
`define PROGBUF6 `ADDR_WIDTH'h26
|
||||||
|
`define PROGBUF7 `ADDR_WIDTH'h27
|
||||||
|
`define PROGBUF8 `ADDR_WIDTH'h28
|
||||||
|
`define PROGBUF9 `ADDR_WIDTH'h29
|
||||||
|
`define PROGBUFA `ADDR_WIDTH'h2A
|
||||||
|
`define PROGBUFB `ADDR_WIDTH'h2B
|
||||||
|
`define PROGBUFC `ADDR_WIDTH'h2C
|
||||||
|
`define PROGBUFD `ADDR_WIDTH'h2D
|
||||||
|
`define PROGBUFE `ADDR_WIDTH'h2E
|
||||||
|
`define PROGBUFF `ADDR_WIDTH'h2F
|
||||||
//`define dmcs2 `ADDR_WIDTH'h32
|
//`define dmcs2 `ADDR_WIDTH'h32
|
||||||
`define SBCS `ADDR_WIDTH'h38
|
`define SBCS `ADDR_WIDTH'h38
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ localparam cvw_t P = '{
|
|||||||
SPI_SUPPORTED : SPI_SUPPORTED,
|
SPI_SUPPORTED : SPI_SUPPORTED,
|
||||||
SPI_BASE : SPI_BASE,
|
SPI_BASE : SPI_BASE,
|
||||||
SPI_RANGE : SPI_RANGE,
|
SPI_RANGE : SPI_RANGE,
|
||||||
|
PROGBUF_BASE : PROGBUF_BASE,
|
||||||
|
PROGBUF_RANGE : PROGBUF_RANGE,
|
||||||
GPIO_LOOPBACK_TEST : GPIO_LOOPBACK_TEST,
|
GPIO_LOOPBACK_TEST : GPIO_LOOPBACK_TEST,
|
||||||
SPI_LOOPBACK_TEST : SPI_LOOPBACK_TEST,
|
SPI_LOOPBACK_TEST : SPI_LOOPBACK_TEST,
|
||||||
UART_PRESCALE : UART_PRESCALE ,
|
UART_PRESCALE : UART_PRESCALE ,
|
||||||
|
@ -140,6 +140,9 @@ typedef struct packed {
|
|||||||
logic SPI_SUPPORTED;
|
logic SPI_SUPPORTED;
|
||||||
logic [63:0] SPI_BASE;
|
logic [63:0] SPI_BASE;
|
||||||
logic [63:0] SPI_RANGE;
|
logic [63:0] SPI_RANGE;
|
||||||
|
// Debug program buffer support is enabled with DEBUG_SUPPORTED
|
||||||
|
logic [63:0] PROGBUF_BASE;
|
||||||
|
logic [63:0] PROGBUF_RANGE;
|
||||||
|
|
||||||
// Test modes
|
// Test modes
|
||||||
|
|
||||||
|
@ -74,12 +74,14 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic DebugRegUpdate, // writes values from scan register after scanning in
|
output logic DebugRegUpdate, // writes values from scan register after scanning in
|
||||||
|
|
||||||
// Program Buffer
|
// Program Buffer
|
||||||
|
output logic [3:0] ProgBufAddr,
|
||||||
output logic ProgBuffScanEn,
|
output logic ProgBuffScanEn,
|
||||||
output logic ProgBuffScanOut,
|
|
||||||
output logic ExecProgBuff
|
output logic ExecProgBuff
|
||||||
);
|
);
|
||||||
`include "debug.vh"
|
`include "debug.vh"
|
||||||
|
|
||||||
|
localparam PROGBUF_SIZE = (P.PROGBUF_RANGE+1)/4;
|
||||||
|
|
||||||
// DMI Signals
|
// DMI Signals
|
||||||
logic ReqReady;
|
logic ReqReady;
|
||||||
logic ReqValid;
|
logic ReqValid;
|
||||||
@ -93,7 +95,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
// JTAG ID for Wally:
|
// JTAG ID for Wally:
|
||||||
// Version [31:28] = 0x1 : 0001
|
// Version [31:28] = 0x1 : 0001
|
||||||
// PartNumber [27:12] = 0x2A : 00000000_00101010
|
// PartNumber [27:12] = 0x2A : Wally (00000000_00101010)
|
||||||
// JEDEC number [11:1] = 0x602 : Bank 13 (1100) Open HW Group (0000010)
|
// JEDEC number [11:1] = 0x602 : Bank 13 (1100) Open HW Group (0000010)
|
||||||
// [0] = 1
|
// [0] = 1
|
||||||
localparam JTAG_DEVICE_ID = 32'h1002AC05;
|
localparam JTAG_DEVICE_ID = 32'h1002AC05;
|
||||||
@ -151,7 +153,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
// DMStatus
|
// DMStatus
|
||||||
const logic NdmResetPending = 0;
|
const logic NdmResetPending = 0;
|
||||||
const logic StickyUnavail = 0;
|
const logic StickyUnavail = 0;
|
||||||
const logic ImpEBreak = 1;
|
const logic ImpEBreak = 0;
|
||||||
logic AllHaveReset;
|
logic AllHaveReset;
|
||||||
logic AnyHaveReset;
|
logic AnyHaveReset;
|
||||||
logic AllResumeAck;
|
logic AllResumeAck;
|
||||||
@ -170,7 +172,7 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
const logic ConfStrPtrValid = 0; // Used with SysBusAccess
|
const logic ConfStrPtrValid = 0; // Used with SysBusAccess
|
||||||
const logic [3:0] Version = 3; // DM Version
|
const logic [3:0] Version = 3; // DM Version
|
||||||
// AbstractCS
|
// AbstractCS
|
||||||
const logic [4:0] ProgBufSize = 1;
|
const logic [4:0] ProgBufSize = PROGBUF_SIZE;
|
||||||
logic Busy;
|
logic Busy;
|
||||||
const logic RelaxedPriv = 1;
|
const logic RelaxedPriv = 1;
|
||||||
logic [2:0] CmdErr;
|
logic [2:0] CmdErr;
|
||||||
@ -248,12 +250,12 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
{`OP_READ,`COMMAND} : State <= READ_ZERO;
|
{`OP_READ,`COMMAND} : State <= READ_ZERO;
|
||||||
{`OP_WRITE,`SBCS} : State <= READ_ZERO;
|
{`OP_WRITE,`SBCS} : State <= READ_ZERO;
|
||||||
{`OP_READ,`SBCS} : State <= R_SYSBUSCS;
|
{`OP_READ,`SBCS} : State <= R_SYSBUSCS;
|
||||||
{`OP_WRITE,`PROGBUF0} : State <= W_PROGBUF;
|
[{`OP_WRITE,`PROGBUF0}:{`OP_WRITE,`PROGBUF3}] : State <= W_PROGBUF; // TODO: update decode range dynamically using PROGBUF_RANGE
|
||||||
{`OP_READ,`PROGBUF0},
|
[{`OP_READ,`PROGBUF0}:{`OP_READ,`PROGBUFF}],
|
||||||
{2'bx,`HARTINFO},
|
{2'bx,`HARTINFO},
|
||||||
{2'bx,`ABSTRACTAUTO},
|
{2'bx,`ABSTRACTAUTO},
|
||||||
{2'bx,`NEXTDM} : State <= READ_ZERO;
|
{2'bx,`NEXTDM} : State <= READ_ZERO;
|
||||||
default : State <= READ_ZERO;//INVALID;
|
default : State <= INVALID;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -369,8 +371,10 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
W_PROGBUF : begin
|
W_PROGBUF : begin
|
||||||
if (Busy)
|
if (Busy)
|
||||||
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
|
CmdErr <= ~|CmdErr ? `CMDERR_BUSY : CmdErr;
|
||||||
else
|
else begin
|
||||||
NewAcState <= PROGBUFF_WRITE;
|
NewAcState <= PROGBUFF_WRITE;
|
||||||
|
ProgBufAddr <= ReqAddress[$clog2(PROGBUF_SIZE)-1:0];
|
||||||
|
end
|
||||||
RspOP <= `OP_SUCCESS;
|
RspOP <= `OP_SUCCESS;
|
||||||
State <= ACK;
|
State <= ACK;
|
||||||
end
|
end
|
||||||
@ -441,7 +445,6 @@ module dm import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
// Program Buffer
|
// Program Buffer
|
||||||
assign ProgBuffScanEn = (AcState == PROGBUFF_WRITE);
|
assign ProgBuffScanEn = (AcState == PROGBUFF_WRITE);
|
||||||
assign ProgBuffScanOut = ScanReg[0];
|
|
||||||
|
|
||||||
// Scan Chain
|
// Scan Chain
|
||||||
assign DebugScanOut = ScanReg[0];
|
assign DebugScanOut = ScanReg[0];
|
||||||
|
@ -27,12 +27,28 @@
|
|||||||
// and limitations under the License.
|
// and limitations under the License.
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Note: This module controls all of the per-hart debug state.
|
// On HaltReq/eBreak:
|
||||||
// In a multihart system, this module should be instantiated under wallypipelinedcore
|
// store value of NextPC in DPC
|
||||||
|
// trigger trap (flush pipe)
|
||||||
|
// stall pipe
|
||||||
|
|
||||||
|
// On Step:
|
||||||
|
// unstall pipe until instruction receaches M stage
|
||||||
|
// goto: HaltReq/eBreak
|
||||||
|
|
||||||
|
// On exec_progbuf
|
||||||
|
// change NextPC to progbuf_address (using DPC?)
|
||||||
|
// goto: resume (implicic ebreak will return to debug mode)
|
||||||
|
|
||||||
|
// On Resume:
|
||||||
|
// update NextPC from DPC
|
||||||
|
// Unstall pipe
|
||||||
|
|
||||||
module dmc (
|
module dmc (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic Step,
|
input logic Step,
|
||||||
|
input logic ebreakM, // ebreak instruction
|
||||||
|
input logic ebreakEn, // DCSR: enter debug mode on ebreak
|
||||||
input logic HaltReq, // Initiates core halt
|
input logic HaltReq, // Initiates 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
|
||||||
@ -46,14 +62,14 @@ module dmc (
|
|||||||
|
|
||||||
output logic EnterDebugMode, // Store PCNextF in DPC when entering Debug Mode
|
output logic EnterDebugMode, // Store PCNextF in DPC when entering Debug Mode
|
||||||
output logic ExitDebugMode, // Updates PCNextF with the current value of DPC
|
output logic ExitDebugMode, // Updates PCNextF with the current value of DPC
|
||||||
output logic ForceNOP // Fills the pipeline with NOP
|
output logic ForceBreakPoint // Causes artificial ebreak that puts core in debug mode
|
||||||
);
|
);
|
||||||
`include "debug.vh"
|
`include "debug.vh"
|
||||||
|
|
||||||
enum logic [1:0] {RUNNING, FLUSH, HALTED, RESUME} State;
|
enum logic [2:0] {RUNNING, HALTED, RESUME, STEP, PROGBUF} State;
|
||||||
|
|
||||||
localparam NOP_CYCLE_DURATION = 0;
|
localparam E2M_CYCLE_COUNT = 3;
|
||||||
logic [$clog2(NOP_CYCLE_DURATION+1)-1:0] Counter;
|
logic [$clog2(E2M_CYCLE_COUNT+1)-1:0] Counter;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset)
|
if (reset)
|
||||||
@ -62,12 +78,13 @@ module dmc (
|
|||||||
HaveReset <= 0;
|
HaveReset <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
assign DebugMode = (State != RUNNING);
|
assign ForceBreakPoint = (State == RUNNING) & HaltReq | (State == STEP) & ~|Counter;
|
||||||
assign DebugStall = (State == HALTED);
|
|
||||||
|
|
||||||
assign EnterDebugMode = (State == FLUSH) & ~|Counter;
|
assign DebugMode = (State != RUNNING);
|
||||||
|
assign DebugStall = (State == HALTED) | (State == RESUME);
|
||||||
|
|
||||||
|
assign EnterDebugMode = (State == RUNNING) & (ebreakM & ebreakEn) | ForceBreakPoint;
|
||||||
assign ExitDebugMode = (State == HALTED) & ResumeReq;
|
assign ExitDebugMode = (State == HALTED) & ResumeReq;
|
||||||
assign ForceNOP = (State == FLUSH);
|
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@ -77,33 +94,37 @@ module dmc (
|
|||||||
case (State)
|
case (State)
|
||||||
RUNNING : begin
|
RUNNING : begin
|
||||||
if (HaltReq) begin
|
if (HaltReq) begin
|
||||||
Counter <= NOP_CYCLE_DURATION;
|
|
||||||
State <= FLUSH;
|
|
||||||
DebugCause <= `CAUSE_HALTREQ;
|
|
||||||
end
|
|
||||||
//else if (eBreak) TODO: halt on ebreak if DCSR bit is set
|
|
||||||
// DebugCause <= `CAUSE_EBREAK;
|
|
||||||
end
|
|
||||||
|
|
||||||
// fill the pipe with NOP before halting
|
|
||||||
FLUSH : begin
|
|
||||||
if (~|Counter)
|
|
||||||
State <= HALTED;
|
State <= HALTED;
|
||||||
else
|
DebugCause <= `CAUSE_HALTREQ;
|
||||||
Counter <= Counter - 1;
|
end else if (ebreakM & ebreakEn) begin
|
||||||
|
State <= HALTED;
|
||||||
|
DebugCause <= `CAUSE_EBREAK;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
HALTED : begin
|
HALTED : begin
|
||||||
if (ResumeReq) begin
|
if (ResumeReq)
|
||||||
|
State <= RESUME;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Wait a cycle to load PCF from DPC before resuming
|
||||||
|
// TODO: test without resume stage
|
||||||
|
RESUME : begin
|
||||||
if (Step) begin
|
if (Step) begin
|
||||||
Counter <= NOP_CYCLE_DURATION;
|
Counter <= E2M_CYCLE_COUNT;
|
||||||
State <= FLUSH;
|
State <= STEP;
|
||||||
DebugCause <= `CAUSE_STEP;
|
|
||||||
end else begin
|
end else begin
|
||||||
State <= RUNNING;
|
State <= RUNNING;
|
||||||
ResumeAck <= 1;
|
ResumeAck <= 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
STEP : begin
|
||||||
|
if (~|Counter) begin
|
||||||
|
DebugCause <= `CAUSE_STEP;
|
||||||
|
State <= HALTED;
|
||||||
|
end else
|
||||||
|
Counter <= Counter - 1;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -108,9 +108,8 @@ module hazard import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign LatestUnstalledW = ~StallW & StallM;
|
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
|
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
|
||||||
// Do not flush if halted for Debug
|
assign FlushD = (LatestUnstalledD | FlushDCause);
|
||||||
assign FlushD = ~DebugStall & (LatestUnstalledD | FlushDCause);
|
assign FlushE = (LatestUnstalledE | FlushECause);
|
||||||
assign FlushE = ~DebugStall & (LatestUnstalledE | FlushECause);
|
assign FlushM = (LatestUnstalledM | FlushMCause);
|
||||||
assign FlushM = ~DebugStall & (LatestUnstalledM | FlushMCause);
|
assign FlushW = (LatestUnstalledW | FlushWCause);
|
||||||
assign FlushW = ~DebugStall & (LatestUnstalledW | FlushWCause);
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -98,11 +98,13 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic ICacheAccess, // Report I$ read to performance counters
|
output logic ICacheAccess, // Report I$ read to performance counters
|
||||||
output logic ICacheMiss, // Report I$ miss to performance counters
|
output logic ICacheMiss, // Report I$ miss to performance counters
|
||||||
// Debug Mode logic
|
// Debug Mode logic
|
||||||
|
output logic [P.XLEN-1:0] PCNextF, // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
||||||
input logic ExitDebugMode,
|
input logic ExitDebugMode,
|
||||||
input logic [P.XLEN-1:0] DPC,
|
input logic [P.XLEN-1:0] DPC,
|
||||||
output logic [P.XLEN-1:0] PCNextF, // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
input logic ProgBuffScanEn,
|
||||||
input logic ForceNOP,
|
|
||||||
// Debug scan chain
|
// Debug scan chain
|
||||||
|
input logic [3:0] ProgBufAddr,
|
||||||
|
input logic ProgBufScanIn,
|
||||||
input logic DebugScanEn,
|
input logic DebugScanEn,
|
||||||
input logic DebugScanIn,
|
input logic DebugScanIn,
|
||||||
output logic DebugScanOut
|
output logic DebugScanOut
|
||||||
@ -111,7 +113,6 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
||||||
localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN;
|
localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN;
|
||||||
|
|
||||||
logic [P.XLEN-1:0] PCNextFM; // (muxed for debug) Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
|
||||||
logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF
|
logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF
|
||||||
logic [P.XLEN-1:0] PC2NextF; // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
logic [P.XLEN-1:0] PC2NextF; // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
||||||
logic [P.XLEN-1:0] UnalignedPCNextF; // The next PCF, but not aligned to 2 bytes.
|
logic [P.XLEN-1:0] UnalignedPCNextF; // The next PCF, but not aligned to 2 bytes.
|
||||||
@ -128,6 +129,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [31:0] IROMInstrF; // Instruction from the IROM
|
logic [31:0] IROMInstrF; // Instruction from the IROM
|
||||||
logic [31:0] ICacheInstrF; // Instruction from the I$
|
logic [31:0] ICacheInstrF; // Instruction from the I$
|
||||||
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
||||||
|
logic [31:0] ProgBufInstrF; // Instruction from the ProgBuf
|
||||||
logic CompressedF, CompressedE; // The fetched instruction is compressed
|
logic CompressedF, CompressedE; // The fetched instruction is compressed
|
||||||
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
||||||
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
||||||
@ -146,6 +148,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
||||||
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
||||||
logic SelIROM; // PMA indicates instruction address is in the IROM
|
logic SelIROM; // PMA indicates instruction address is in the IROM
|
||||||
|
logic SelProgBuf; // PMA indicates instruction address is in Program Buffer
|
||||||
logic [15:0] InstrRawE, InstrRawM;
|
logic [15:0] InstrRawE, InstrRawM;
|
||||||
logic [LINELEN-1:0] FetchBuffer;
|
logic [LINELEN-1:0] FetchBuffer;
|
||||||
logic [31:0] ShiftUncachedInstr;
|
logic [31:0] ShiftUncachedInstr;
|
||||||
@ -196,7 +199,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
.TLBFlush,
|
.TLBFlush,
|
||||||
.PhysicalAddress(PCPF),
|
.PhysicalAddress(PCPF),
|
||||||
.TLBMiss(ITLBMissF),
|
.TLBMiss(ITLBMissF),
|
||||||
.Cacheable(CacheableF), .Idempotent(), .SelTIM(SelIROM),
|
.Cacheable(CacheableF), .Idempotent(), .SelTIM(SelIROM), .SelProgBuf,
|
||||||
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
|
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
|
||||||
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
|
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
|
||||||
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
|
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
|
||||||
@ -209,6 +212,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign PCPF = PCFExt[P.PA_BITS-1:0];
|
assign PCPF = PCFExt[P.PA_BITS-1:0];
|
||||||
assign CacheableF = 1'b1;
|
assign CacheableF = 1'b1;
|
||||||
assign SelIROM = '0;
|
assign SelIROM = '0;
|
||||||
|
assign SelProgBuf = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -218,7 +222,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
// CommittedM tells the CPU's privileged unit the current instruction
|
// CommittedM tells the CPU's privileged unit the current instruction
|
||||||
// in the memory stage is a memory operaton and that memory operation is either completed
|
// in the memory stage is a memory operaton and that memory operation is either completed
|
||||||
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
||||||
// There is not a clean way to restore back to a partial executed instruction. CommiteedM will
|
// There is not a clean way to restore back to a partial executed instruction. CommittedM will
|
||||||
// delay the interrupt until the LSU is in a clean state.
|
// delay the interrupt until the LSU is in a clean state.
|
||||||
assign CommittedF = CacheCommittedF | BusCommittedF;
|
assign CommittedF = CacheCommittedF | BusCommittedF;
|
||||||
|
|
||||||
@ -314,7 +318,14 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign IFUStallF = IFUCacheBusStallF | SelSpillNextF;
|
assign IFUStallF = IFUCacheBusStallF | SelSpillNextF;
|
||||||
assign GatedStallD = StallD & ~SelSpillNextF;
|
assign GatedStallD = StallD & ~SelSpillNextF;
|
||||||
|
|
||||||
|
if (P.DEBUG_SUPPORTED) begin
|
||||||
|
logic [31:0] PostSpillInstrRawFM;
|
||||||
|
progbuf #(P) progbuf(.clk, .reset, .Addr(PCNextF[3:0]), .ProgBufInstrF, .ScanAddr(ProgBufAddr), .Scan(ProgBuffScanEn), .ScanIn(ProgBufScanIn));
|
||||||
|
assign PostSpillInstrRawFM = SelProgBuf ? ProgBufInstrF : PostSpillInstrRawF;
|
||||||
|
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawFM, nop, InstrRawD);
|
||||||
|
end else begin
|
||||||
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD);
|
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD);
|
||||||
|
end
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// PCNextF logic
|
// PCNextF logic
|
||||||
@ -324,10 +335,11 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
|||||||
mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
|
mux2 #(P.XLEN) pcmux2(.d0(PC1NextF), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PC2NextF));
|
||||||
else assign PC2NextF = PC1NextF;
|
else assign PC2NextF = PC1NextF;
|
||||||
|
|
||||||
|
|
||||||
mux3 #(P.XLEN) pcmux3(PC2NextF, EPCM, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF);
|
mux3 #(P.XLEN) pcmux3(PC2NextF, EPCM, TrapVectorM, {TrapM, RetM}, UnalignedPCNextF);
|
||||||
|
|
||||||
if (P.DEBUG_SUPPORTED) begin
|
if (P.DEBUG_SUPPORTED) begin
|
||||||
mux2 #(P.XLEN) pcresetmux({UnalignedPCNextF[P.XLEN-1:1], 1'b0}, P.RESET_VECTOR[P.XLEN-1:0], reset, PCNextFM);
|
mux3 #(P.XLEN) pcresetmux(.d2(P.RESET_VECTOR[P.XLEN-1:0]), .d1(DPC), .d0({UnalignedPCNextF[P.XLEN-1:1], 1'b0}), .s({reset,ExitDebugMode}), .y(PCNextF));
|
||||||
assign PCNextF = ExitDebugMode ? DPC : PCNextFM;
|
|
||||||
flopen #(P.XLEN) pcreg(clk, ~StallF | reset | ExitDebugMode, PCNextF, PCF);
|
flopen #(P.XLEN) pcreg(clk, ~StallF | reset | ExitDebugMode, PCNextF, PCF);
|
||||||
end else begin
|
end else begin
|
||||||
mux2 #(P.XLEN) pcresetmux({UnalignedPCNextF[P.XLEN-1:1], 1'b0}, P.RESET_VECTOR[P.XLEN-1:0], reset, PCNextF);
|
mux2 #(P.XLEN) pcresetmux({UnalignedPCNextF[P.XLEN-1:1], 1'b0}, P.RESET_VECTOR[P.XLEN-1:0], reset, PCNextF);
|
||||||
|
69
src/ifu/progbuf.sv
Normal file
69
src/ifu/progbuf.sv
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// progbuf.sv
|
||||||
|
//
|
||||||
|
// Written: matthew.n.otto@okstate.edu
|
||||||
|
// Created: 18 June 2024
|
||||||
|
//
|
||||||
|
// Purpose: Holds small programs to be executed in debug mode
|
||||||
|
// This module acts like a small ROM except it can be written by serial Scanning via the Debug Module
|
||||||
|
//
|
||||||
|
// 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 progbuf import cvw::*; #(parameter cvw_t P) (
|
||||||
|
input logic clk, reset,
|
||||||
|
input logic [3:0] Addr,
|
||||||
|
output logic [31:0] ProgBufInstrF,
|
||||||
|
|
||||||
|
input logic [3:0] ScanAddr,
|
||||||
|
input logic Scan,
|
||||||
|
input logic ScanIn
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam PROGBUF_SIZE = (P.PROGBUF_RANGE+1)/4;
|
||||||
|
localparam ADDR_WIDTH = $clog2(PROGBUF_SIZE);
|
||||||
|
|
||||||
|
bit [31:0] RAM [PROGBUF_SIZE-1:0];
|
||||||
|
|
||||||
|
logic EnPrevClk;
|
||||||
|
logic WriteProgBuf;
|
||||||
|
logic [32:0] WriteData;
|
||||||
|
logic [ADDR_WIDTH-1:0] AddrM;
|
||||||
|
|
||||||
|
flopr #(1) Scanenhist (.clk, .reset, .d(Scan), .q(EnPrevClk));
|
||||||
|
assign WriteProgBuf = ~Scan & EnPrevClk;
|
||||||
|
|
||||||
|
assign WriteData[32] = ScanIn;
|
||||||
|
genvar i;
|
||||||
|
for (i=0; i<32; i=i+1) begin
|
||||||
|
flopenr #(1) Scanreg (.clk, .reset, .en(Scan), .d(WriteData[i+1]), .q(WriteData[i]));
|
||||||
|
end
|
||||||
|
|
||||||
|
assign AddrM = WriteProgBuf ? ScanAddr[ADDR_WIDTH-1:0] : Addr[ADDR_WIDTH-1:0];
|
||||||
|
|
||||||
|
always_ff @(posedge clk) begin
|
||||||
|
if (WriteProgBuf)
|
||||||
|
RAM[AddrM] <= WriteData;
|
||||||
|
if (reset)
|
||||||
|
ProgBufInstrF <= 0;
|
||||||
|
else
|
||||||
|
ProgBufInstrF <= RAM[AddrM];
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@ -33,7 +33,7 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [P.PA_BITS-1:0] PhysicalAddress,
|
input logic [P.PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic AccessRW, AccessRX, AccessRWXC,
|
input logic AccessRW, AccessRX, AccessRWXC,
|
||||||
input logic [1:0] Size,
|
input logic [1:0] Size,
|
||||||
output logic [11:0] SelRegions
|
output logic [12:0] SelRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
|
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
|
||||||
@ -49,6 +49,7 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
|
|||||||
adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[9]);
|
adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[9]);
|
||||||
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[10]);
|
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[10]);
|
||||||
adrdec #(P.PA_BITS) spidec(PhysicalAddress, P.SPI_BASE[P.PA_BITS-1:0], P.SPI_RANGE[P.PA_BITS-1:0], P.SPI_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[11]);
|
adrdec #(P.PA_BITS) spidec(PhysicalAddress, P.SPI_BASE[P.PA_BITS-1:0], P.SPI_RANGE[P.PA_BITS-1:0], P.SPI_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[11]);
|
||||||
|
adrdec #(P.PA_BITS) progbufdec(PhysicalAddress, P.PROGBUF_BASE[P.PA_BITS-1:0], P.PROGBUF_RANGE[P.PA_BITS-1:0], P.DEBUG_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[12]);
|
||||||
|
|
||||||
assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected
|
assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -50,6 +50,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
output logic Cacheable, // PMA indicates memory address is cachable
|
output logic Cacheable, // PMA indicates memory address is cachable
|
||||||
output logic Idempotent, // PMA indicates memory address is idempotent
|
output logic Idempotent, // PMA indicates memory address is idempotent
|
||||||
output logic SelTIM, // Select a tightly integrated memory
|
output logic SelTIM, // Select a tightly integrated memory
|
||||||
|
output logic SelProgBuf, // Select ProgBuf
|
||||||
// Faults
|
// Faults
|
||||||
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, // access fault sources
|
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, // access fault sources
|
||||||
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, // page fault sources
|
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, // page fault sources
|
||||||
@ -112,7 +113,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
|||||||
|
|
||||||
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOpM,
|
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOpM,
|
||||||
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
|
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
|
||||||
.Cacheable, .Idempotent, .SelTIM,
|
.Cacheable, .Idempotent, .SelTIM, .SelProgBuf,
|
||||||
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
||||||
|
|
||||||
if (P.PMP_ENTRIES > 0) begin : pmp
|
if (P.PMP_ENTRIES > 0) begin : pmp
|
||||||
|
@ -38,7 +38,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic WriteAccessM, // Write access
|
input logic WriteAccessM, // Write access
|
||||||
input logic ReadAccessM, // Read access
|
input logic ReadAccessM, // Read access
|
||||||
input logic [1:0] PBMemoryType, // PBMT field of PTE during TLB hit, or 00 otherwise
|
input logic [1:0] PBMemoryType, // PBMT field of PTE during TLB hit, or 00 otherwise
|
||||||
output logic Cacheable, Idempotent, SelTIM,
|
output logic Cacheable, Idempotent, SelTIM, SelProgBuf,
|
||||||
output logic PMAInstrAccessFaultF,
|
output logic PMAInstrAccessFaultF,
|
||||||
output logic PMALoadAccessFaultM,
|
output logic PMALoadAccessFaultM,
|
||||||
output logic PMAStoreAmoAccessFaultM
|
output logic PMAStoreAmoAccessFaultM
|
||||||
@ -46,7 +46,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
logic PMAAccessFault;
|
logic PMAAccessFault;
|
||||||
logic AccessRW, AccessRWXC, AccessRX;
|
logic AccessRW, AccessRWXC, AccessRX;
|
||||||
logic [11:0] SelRegions;
|
logic [12:0] SelRegions;
|
||||||
logic AtomicAllowed;
|
logic AtomicAllowed;
|
||||||
logic CacheableRegion, IdempotentRegion;
|
logic CacheableRegion, IdempotentRegion;
|
||||||
|
|
||||||
@ -72,6 +72,9 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
|
|||||||
// Check if tightly integrated memories are selected
|
// Check if tightly integrated memories are selected
|
||||||
assign SelTIM = SelRegions[1] | SelRegions[2]; // exclusion-tag: unused-tim
|
assign SelTIM = SelRegions[1] | SelRegions[2]; // exclusion-tag: unused-tim
|
||||||
|
|
||||||
|
// Debug program buffer
|
||||||
|
assign SelProgBuf = SelRegions[12];
|
||||||
|
|
||||||
// Detect access faults
|
// Detect access faults
|
||||||
assign PMAAccessFault = SelRegions[0] & AccessRWXC | AtomicAccessM & ~AtomicAllowed;
|
assign PMAAccessFault = SelRegions[0] & AccessRWXC | AtomicAccessM & ~AtomicAllowed;
|
||||||
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
|
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
|
||||||
|
@ -96,9 +96,9 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
// Debug Mode output
|
// Debug Mode output
|
||||||
input logic DebugMode,
|
input logic DebugMode,
|
||||||
input logic [2:0] DebugCause,
|
input logic [2:0] DebugCause,
|
||||||
|
output logic ebreakEn,
|
||||||
output logic Step,
|
output logic Step,
|
||||||
output logic [P.XLEN-1:0] DPC,
|
output logic [P.XLEN-1:0] DPC,
|
||||||
input logic [P.XLEN-1:0] PCNextF,
|
|
||||||
input logic EnterDebugMode,
|
input logic EnterDebugMode,
|
||||||
// Debug scan chain
|
// Debug scan chain
|
||||||
input logic DebugSel,
|
input logic DebugSel,
|
||||||
@ -215,10 +215,10 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
assign CSRAdrM = InstrM[31:20];
|
assign CSRAdrM = InstrM[31:20];
|
||||||
assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValDM;
|
assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM;
|
||||||
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}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]};
|
||||||
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValDM;
|
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
|
||||||
assign UngatedCSRMWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE);
|
assign UngatedCSRMWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE);
|
||||||
assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM;
|
assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM;
|
||||||
assign CSRSWriteM = CSRWriteDM & (|PrivilegeModeW) & InstrValidNotFlushedM;
|
assign CSRSWriteM = CSRWriteDM & (|PrivilegeModeW) & InstrValidNotFlushedM;
|
||||||
@ -305,7 +305,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
|||||||
if (P.DEBUG_SUPPORTED) begin:csrd
|
if (P.DEBUG_SUPPORTED) begin:csrd
|
||||||
csrd #(P) csrd(.clk, .reset, .DebugMode, .PrivilegeModeW,
|
csrd #(P) csrd(.clk, .reset, .DebugMode, .PrivilegeModeW,
|
||||||
.CSRWriteDM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .CSRDReadValM, .IllegalCSRDAccessM,
|
.CSRWriteDM, .CSRAdrM(CSRAdrDM), .CSRWriteValM(CSRWriteValDM), .CSRDReadValM, .IllegalCSRDAccessM,
|
||||||
.DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode);
|
.DebugCause, .ebreakEn, .Step, .DPC, .PCM, .EnterDebugMode);
|
||||||
end else begin
|
end else begin
|
||||||
assign CSRDReadValM = '0;
|
assign CSRDReadValM = '0;
|
||||||
assign IllegalCSRDAccessM = 1'b1; // Debug isn't supported
|
assign IllegalCSRDAccessM = 1'b1; // Debug isn't supported
|
||||||
|
@ -35,12 +35,12 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [P.XLEN-1:0] CSRWriteValM,
|
input logic [P.XLEN-1:0] CSRWriteValM,
|
||||||
output logic [P.XLEN-1:0] CSRDReadValM,
|
output logic [P.XLEN-1:0] CSRDReadValM,
|
||||||
output logic IllegalCSRDAccessM,
|
output logic IllegalCSRDAccessM,
|
||||||
|
input logic [P.XLEN-1:0] PCM,
|
||||||
|
input logic EnterDebugMode,
|
||||||
input logic [2:0] DebugCause,
|
input logic [2:0] DebugCause,
|
||||||
|
output logic ebreakEn,
|
||||||
output logic Step,
|
output logic Step,
|
||||||
output logic [P.XLEN-1:0] DPC,
|
output logic [P.XLEN-1:0] DPC
|
||||||
input logic [P.XLEN-1:0] PCNextF,
|
|
||||||
input logic EnterDebugMode
|
|
||||||
);
|
);
|
||||||
`include "debug.vh"
|
`include "debug.vh"
|
||||||
|
|
||||||
@ -58,8 +58,8 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
|||||||
const logic ebreakVS = 0;
|
const logic ebreakVS = 0;
|
||||||
const logic ebreakVU = 0;
|
const logic ebreakVU = 0;
|
||||||
logic ebreakM;
|
logic ebreakM;
|
||||||
logic ebreakS;
|
const logic ebreakS = 0;
|
||||||
logic ebreakU;
|
const logic ebreakU = 0;
|
||||||
const logic StepIE = 0;
|
const logic StepIE = 0;
|
||||||
const logic StopCount = 0;
|
const logic StopCount = 0;
|
||||||
const logic StopTime = 0;
|
const logic StopTime = 0;
|
||||||
@ -70,6 +70,7 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [1:0] Prv;
|
logic [1:0] Prv;
|
||||||
|
|
||||||
|
|
||||||
|
assign ebreakEn = ebreakM; // Only support ebreak from M mode
|
||||||
assign CSRDWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE) & DebugMode;
|
assign CSRDWriteM = CSRWriteDM & (PrivilegeModeW == P.M_MODE) & DebugMode;
|
||||||
|
|
||||||
assign WriteDCSRM = CSRDWriteM & (CSRAdrM == DCSR_ADDR);
|
assign WriteDCSRM = CSRDWriteM & (CSRAdrM == DCSR_ADDR);
|
||||||
@ -85,15 +86,13 @@ module csrd import cvw::*; #(parameter cvw_t P) (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
flopenr #(4) DCSRreg (clk, reset, WriteDCSRM,
|
flopenr #(4) DCSRreg (clk, reset, WriteDCSRM, {CSRWriteValM[`EBREAKM], CSRWriteValM[`STEP]}, {ebreakM, Step});
|
||||||
{CSRWriteValM[`EBREAKM], CSRWriteValM[`EBREAKS], CSRWriteValM[`EBREAKU], CSRWriteValM[`STEP]},
|
|
||||||
{ebreakM, ebreakS, ebreakU, Step});
|
|
||||||
|
|
||||||
assign DCSR = {DebugVer, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE,
|
assign DCSR = {DebugVer, 10'b0, ebreakVS, ebreakVU, ebreakM, 1'b0, ebreakS, ebreakU, StepIE,
|
||||||
StopCount, StopTime, Cause, V, MPrvEn, NMIP, Step, Prv};
|
StopCount, StopTime, Cause, V, MPrvEn, NMIP, Step, Prv};
|
||||||
|
|
||||||
assign DPCWriteVal = EnterDebugMode ? PCNextF : CSRWriteValM;
|
assign DPCWriteVal = EnterDebugMode ? PCM : CSRWriteValM;
|
||||||
flopenr #(P.XLEN) DPCreg (clk, reset, WriteDPCM | EnterDebugMode, DPCWriteVal, DPC);
|
flopenr #(P.XLEN) DPCreg (clk, reset, WriteDPCM | EnterDebugMode, DPCWriteVal, DPC); // TODO: reset to something sane (0x80000000?)
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
CSRDReadValM = '0;
|
CSRDReadValM = '0;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
module privdec import cvw::*; #(parameter cvw_t P) (
|
module privdec import cvw::*; #(parameter cvw_t P) (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic StallW, FlushW,
|
input logic StallW, FlushW,
|
||||||
|
input logic ForceBreakPoint, // Debug Module initiated break to debug mode
|
||||||
input logic [31:15] InstrM, // privileged instruction function field
|
input logic [31:15] InstrM, // privileged instruction function field
|
||||||
input logic PrivilegedM, // is this a privileged instruction (from IEU controller)
|
input logic PrivilegedM, // is this a privileged instruction (from IEU controller)
|
||||||
input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction
|
input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction
|
||||||
@ -40,13 +41,14 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic IllegalInstrFaultM, // Illegal instruction
|
output logic IllegalInstrFaultM, // Illegal instruction
|
||||||
output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs
|
output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs
|
||||||
output logic sretM, mretM, RetM, // return instructions
|
output logic sretM, mretM, RetM, // return instructions
|
||||||
output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions
|
output logic wfiM, wfiW, sfencevmaM, // wfi / sfence.vma / sinval.vma instructions
|
||||||
|
output logic ebreakM // ebreak instruction
|
||||||
);
|
);
|
||||||
|
|
||||||
logic rs1zeroM; // rs1 field = 0
|
logic rs1zeroM; // rs1 field = 0
|
||||||
logic IllegalPrivilegedInstrM; // privileged instruction isn't a legal one or in legal mode
|
logic IllegalPrivilegedInstrM; // privileged instruction isn't a legal one or in legal mode
|
||||||
logic WFITimeoutM; // WFI reaches timeout threshold
|
logic WFITimeoutM; // WFI reaches timeout threshold
|
||||||
logic ebreakM, ecallM; // ebreak / ecall instructions
|
logic ecallM; // ecall instructions
|
||||||
logic sinvalvmaM; // sinval.vma
|
logic sinvalvmaM; // sinval.vma
|
||||||
logic sfencewinvalM, sfenceinvalirM; // sfence.w.inval, sfence.inval.ir
|
logic sfencewinvalM, sfenceinvalirM; // sfence.w.inval, sfence.inval.ir
|
||||||
logic invalM; // any of the svinval instructions
|
logic invalM; // any of the svinval instructions
|
||||||
@ -94,7 +96,10 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
|||||||
// Extract exceptions by name and handle them
|
// Extract exceptions by name and handle them
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
assign BreakpointFaultM = ebreakM; // could have other causes from a debugger
|
if (P.DEBUG_SUPPORTED)
|
||||||
|
assign BreakpointFaultM = ebreakM | ForceBreakPoint;
|
||||||
|
else
|
||||||
|
assign BreakpointFaultM = ebreakM;
|
||||||
assign EcallFaultM = ecallM;
|
assign EcallFaultM = ecallM;
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -97,12 +97,14 @@ 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
|
||||||
|
output logic ebreakM, // Notifies DM to enter debug mode
|
||||||
// Debuge Mode
|
// Debuge Mode
|
||||||
|
output logic ebreakEn,
|
||||||
|
input logic ForceBreakPoint,
|
||||||
input logic DebugMode,
|
input logic DebugMode,
|
||||||
input logic [2:0] DebugCause,
|
input logic [2:0] DebugCause,
|
||||||
output logic Step,
|
output logic Step,
|
||||||
output logic [P.XLEN-1:0] DPC,
|
output logic [P.XLEN-1:0] DPC,
|
||||||
input logic [P.XLEN-1:0] PCNextF,
|
|
||||||
input logic EnterDebugMode,
|
input logic EnterDebugMode,
|
||||||
// Debug scan chain
|
// Debug scan chain
|
||||||
input logic DebugSel,
|
input logic DebugSel,
|
||||||
@ -142,9 +144,9 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
// decode privileged instructions
|
// decode privileged instructions
|
||||||
privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:15]),
|
privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:15]),
|
||||||
.PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM,
|
.PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .ForceBreakPoint,
|
||||||
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM,
|
.PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM,
|
||||||
.EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .RetM, .wfiM, .wfiW, .sfencevmaM);
|
.EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .RetM, .wfiM, .wfiW, .sfencevmaM, .ebreakM);
|
||||||
|
|
||||||
// Control and Status Registers
|
// Control and Status Registers
|
||||||
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
||||||
@ -163,7 +165,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
|
|||||||
.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,
|
||||||
.DebugMode, .DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
.DebugMode, .DebugCause, .ebreakEn, .Step, .DPC, .EnterDebugMode,
|
||||||
.DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut);
|
.DebugSel, .DebugRegAddr, .DebugCapture, .DebugRegUpdate, .DebugScanEn, .DebugScanIn, .DebugScanOut);
|
||||||
|
|
||||||
// pipeline early-arriving trap sources
|
// pipeline early-arriving trap sources
|
||||||
|
@ -53,6 +53,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
output logic ResumeAck,
|
output logic ResumeAck,
|
||||||
output logic HaveReset,
|
output logic HaveReset,
|
||||||
output logic DebugStall,
|
output logic DebugStall,
|
||||||
|
input logic ExecProgBuff,
|
||||||
// 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
|
||||||
@ -66,13 +67,16 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic CSRSel, // selects CSR scan chain
|
input logic CSRSel, // selects CSR scan chain
|
||||||
input logic [11:0] DebugRegAddr, // address for scanable regfiles (GPR, FPR, CSR)
|
input logic [11:0] DebugRegAddr, // address for scanable regfiles (GPR, FPR, CSR)
|
||||||
input logic DebugCapture, // latches values into scan register before scanning out
|
input logic DebugCapture, // latches values into scan register before scanning out
|
||||||
input logic DebugRegUpdate // writes values from scan register after scanning in
|
input logic DebugRegUpdate, // writes values from scan register after scanning in
|
||||||
|
input logic [3:0] ProgBufAddr,
|
||||||
|
input logic ProgBuffScanEn
|
||||||
);
|
);
|
||||||
|
|
||||||
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 DebugMode, Step;
|
logic DebugMode, Step;
|
||||||
|
logic ebreakEn;
|
||||||
|
|
||||||
// signals that must connect through DP
|
// signals that must connect through DP
|
||||||
logic IntDivE, W64E;
|
logic IntDivE, W64E;
|
||||||
@ -190,13 +194,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic BranchD, BranchE, JumpD, JumpE;
|
logic BranchD, BranchE, JumpD, JumpE;
|
||||||
logic DCacheStallM, ICacheStallF;
|
logic DCacheStallM, ICacheStallF;
|
||||||
logic wfiM, IntPendingM;
|
logic wfiM, IntPendingM;
|
||||||
|
logic ebreakM;
|
||||||
|
|
||||||
// Debug mode logic
|
// Debug mode logic
|
||||||
logic [P.XLEN-1:0] DPC, PCNextF;
|
logic [P.XLEN-1:0] DPC, PCNextF;
|
||||||
logic ExitDebugMode;
|
logic ExitDebugMode;
|
||||||
logic EnterDebugMode;
|
logic EnterDebugMode;
|
||||||
logic [2:0] DebugCause;
|
logic [2:0] DebugCause;
|
||||||
logic ForceNOP;
|
logic ForceBreakPoint;
|
||||||
// Debug register scan chain interconnects
|
// Debug register scan chain interconnects
|
||||||
logic [2:0] DebugScanReg;
|
logic [2:0] DebugScanReg;
|
||||||
|
|
||||||
@ -222,7 +227,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,
|
||||||
.ExitDebugMode, .DPC, .PCNextF, .ForceNOP,
|
.ExitDebugMode, .DPC, .PCNextF, .ProgBuffScanEn, .ProgBufAddr, .ProgBufScanIn(DebugScanIn),
|
||||||
.DebugScanEn(DebugScanEn & MiscSel), .DebugScanIn(DebugScanReg[0]), .DebugScanOut(DebugScanReg[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
|
||||||
@ -320,9 +325,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
|
|||||||
if (P.DEBUG_SUPPORTED) begin
|
if (P.DEBUG_SUPPORTED) begin
|
||||||
dmc debugcontrol(
|
dmc debugcontrol(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.Step, .HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset,
|
.Step, .ebreakM, .ebreakEn, .HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset,
|
||||||
.ResumeAck, .HaveReset, .DebugMode, .DebugCause, .DebugStall,
|
.ResumeAck, .HaveReset, .DebugMode, .DebugCause, .DebugStall,
|
||||||
.EnterDebugMode, .ExitDebugMode, .ForceNOP);
|
.EnterDebugMode, .ExitDebugMode, .ForceBreakPoint);
|
||||||
end else begin
|
end else begin
|
||||||
assign DebugStall = 1'b0;
|
assign DebugStall = 1'b0;
|
||||||
end
|
end
|
||||||
@ -349,8 +354,8 @@ 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, .ebreakM,
|
||||||
.DebugMode, .DebugCause, .Step, .DPC, .PCNextF, .EnterDebugMode,
|
.ebreakEn, .ForceBreakPoint, .DebugMode, .DebugCause, .Step, .DPC, .EnterDebugMode,
|
||||||
.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(DebugScanReg[0]));
|
flopenrs #(1) scantrapm (.clk, .reset, .en(DebugCapture), .d(TrapM), .q(), .scan(DebugScanEn), .scanin(DebugScanIn), .scanout(DebugScanReg[0]));
|
||||||
|
@ -82,6 +82,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic ResumeAck;
|
logic ResumeAck;
|
||||||
logic HaveReset;
|
logic HaveReset;
|
||||||
logic DebugStall;
|
logic DebugStall;
|
||||||
|
logic ExecProgBuff;
|
||||||
// Debug Module signals
|
// Debug Module signals
|
||||||
logic DebugScanEn;
|
logic DebugScanEn;
|
||||||
logic DebugScanIn;
|
logic DebugScanIn;
|
||||||
@ -96,9 +97,8 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [11:0] DebugRegAddr;
|
logic [11:0] DebugRegAddr;
|
||||||
logic DebugCapture;
|
logic DebugCapture;
|
||||||
logic DebugRegUpdate;
|
logic DebugRegUpdate;
|
||||||
|
logic [3:0] ProgBufAddr;
|
||||||
logic ProgBuffScanEn;
|
logic ProgBuffScanEn;
|
||||||
logic ProgBuffScanOut;
|
|
||||||
logic ExecProgBuff;
|
|
||||||
|
|
||||||
// synchronize reset to SOC clock domain
|
// synchronize reset to SOC clock domain
|
||||||
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
|
synchronizer resetsync(.clk, .d(reset_ext), .q(reset));
|
||||||
@ -108,9 +108,10 @@ 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,
|
||||||
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall,
|
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall, .ExecProgBuff,
|
||||||
.DebugScanEn, .DebugScanOut(DebugScanIn), .GPRScanOut(GPRScanIn), .FPRScanOut(FPRScanIn), .CSRScanOut(CSRScanIn),
|
.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,
|
||||||
|
.ProgBufAddr, .ProgBuffScanEn);
|
||||||
|
|
||||||
// instantiate uncore if a bus interface exists
|
// 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
|
if (P.BUS_SUPPORTED) begin : uncoregen // Hack to work around Verilator bug https://github.com/verilator/verilator/issues/4769
|
||||||
@ -130,7 +131,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
|
|||||||
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall,
|
.HaltReq, .ResumeReq, .HaltOnReset, .AckHaveReset, .ResumeAck, .HaveReset, .DebugStall,
|
||||||
.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,
|
||||||
.ProgBuffScanEn, .ProgBuffScanOut, .ExecProgBuff);
|
.ProgBufAddr, .ProgBuffScanEn, .ExecProgBuff);
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user