forked from Github_Repos/cvw
1st attempt at multiple channel PLIC
This commit is contained in:
parent
aa60b57fb3
commit
4b376e2834
@ -101,10 +101,12 @@ then
|
|||||||
set logging on
|
set logging on
|
||||||
# Priority Levels for sources 1 thru 63
|
# Priority Levels for sources 1 thru 63
|
||||||
x/63xw 0x0C000004
|
x/63xw 0x0C000004
|
||||||
# Interrupt Enables
|
# Interrupt Enables for sources 1 thru 63 for contexts 0 and 1
|
||||||
x/2xw 0x0C020000
|
x/2xw 0x0C020000
|
||||||
# Global Priority Threshold
|
x/2xw 0x0C020080
|
||||||
|
# Global Priority Threshold for contexts 0 and 1
|
||||||
x/1xw 0x0C200000
|
x/1xw 0x0C200000
|
||||||
|
x/1xw 0x0C201000
|
||||||
set logging off
|
set logging off
|
||||||
shell echo \"GDB storing RAM to $rawRamFile\"
|
shell echo \"GDB storing RAM to $rawRamFile\"
|
||||||
dump binary memory $rawRamFile 0x80000000 0xffffffff
|
dump binary memory $rawRamFile 0x80000000 0xffffffff
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
import sys, os
|
import sys, os
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
################
|
################
|
||||||
# Helper Funcs #
|
# Helper Funcs #
|
||||||
@ -21,6 +22,9 @@ def tokenize(string):
|
|||||||
token = token + char
|
token = token + char
|
||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
|
def strip0x(num):
|
||||||
|
return num[2:]
|
||||||
|
|
||||||
def stripZeroes(num):
|
def stripZeroes(num):
|
||||||
num = num.strip('0')
|
num = num.strip('0')
|
||||||
if num=='':
|
if num=='':
|
||||||
@ -42,7 +46,7 @@ if not os.path.exists(rawPlicStateFile):
|
|||||||
sys.exit('Error input file '+rawPlicStateFile+'not found')
|
sys.exit('Error input file '+rawPlicStateFile+'not found')
|
||||||
|
|
||||||
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
||||||
plicIntPriorityArray=[]
|
plicIntPriorityArray = [] # iterates over number of different sources
|
||||||
# 0x0C000004 thru 0x0C000010
|
# 0x0C000004 thru 0x0C000010
|
||||||
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
# 0x0C000014 thru 0x0C000020
|
# 0x0C000014 thru 0x0C000020
|
||||||
@ -76,20 +80,30 @@ with open(rawPlicStateFile, 'r') as rawPlicStateFile:
|
|||||||
# 0x0C0000f4 thru 0x0C0000fc
|
# 0x0C0000f4 thru 0x0C0000fc
|
||||||
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
plicIntPriorityArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
|
||||||
|
plicIntEnableArray = [] # iterates over number of different contexts
|
||||||
# 0x0C020000 thru 0x0C020004
|
# 0x0C020000 thru 0x0C020004
|
||||||
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
|
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
plicIntEnable = map(strip0x,plicIntEnable)
|
||||||
|
plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable))
|
||||||
|
# 0x0C020080 thru 0x0C020084
|
||||||
|
plicIntEnable = tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
plicIntEnable = map(strip0x,plicIntEnable)
|
||||||
|
plicIntEnableArray.append(reduce(lambda x,y: x+y,plicIntEnable))
|
||||||
|
|
||||||
|
plicIntPriorityThresholdArray = [] # iterates over number of different contexts
|
||||||
# 0x0C200000
|
# 0x0C200000
|
||||||
plicIntPriorityThreshold = tokenize(rawPlicStateFile.readline())[1:]
|
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
# 0x0C201000
|
||||||
|
plicIntPriorityThresholdArray += tokenize(rawPlicStateFile.readline())[1:]
|
||||||
|
|
||||||
with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile:
|
||||||
for word in plicIntPriorityArray:
|
for word in plicIntPriorityArray:
|
||||||
outFile.write(stripZeroes(word[2:])+'\n')
|
outFile.write(stripZeroes(word[2:])+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile:
|
||||||
for word in plicIntEnable:
|
for word in plicIntEnableArray:
|
||||||
outFile.write(stripZeroes(word[2:]))
|
outFile.write(word+'\n')
|
||||||
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile:
|
||||||
for word in plicIntPriorityThreshold:
|
for word in plicIntPriorityThresholdArray:
|
||||||
outFile.write(stripZeroes(word[2:])+'\n')
|
outFile.write(stripZeroes(word[2:])+'\n')
|
||||||
|
|
||||||
print("Finished parsing PLIC state!")
|
print("Finished parsing PLIC state!")
|
||||||
|
@ -43,13 +43,13 @@ module csr #(parameter
|
|||||||
input logic [31:0] InstrM,
|
input logic [31:0] InstrM,
|
||||||
input logic [`XLEN-1:0] PCM, SrcAM,
|
input logic [`XLEN-1:0] PCM, SrcAM,
|
||||||
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
|
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
input logic InstrValidM, FRegWriteM, LoadStallD,
|
input logic InstrValidM, FRegWriteM, LoadStallD,
|
||||||
input logic BPPredDirWrongM,
|
input logic BPPredDirWrongM,
|
||||||
input logic BTBPredPCWrongM,
|
input logic BTBPredPCWrongM,
|
||||||
input logic RASPredPCWrongM,
|
input logic RASPredPCWrongM,
|
||||||
input logic BPPredClassNonCFIWrongM,
|
input logic BPPredClassNonCFIWrongM,
|
||||||
input logic [4:0] InstrClassM,
|
input logic [4:0] InstrClassM,
|
||||||
input logic DCacheMiss,
|
input logic DCacheMiss,
|
||||||
input logic DCacheAccess,
|
input logic DCacheAccess,
|
||||||
@ -123,7 +123,7 @@ module csr #(parameter
|
|||||||
assign CSRUWriteM = CSRWriteM;
|
assign CSRUWriteM = CSRWriteM;
|
||||||
|
|
||||||
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
|
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
|
||||||
.CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM,
|
.CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM,
|
||||||
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
|
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
|
||||||
csrsr csrsr(.clk, .reset, .StallW,
|
csrsr csrsr(.clk, .reset, .StallW,
|
||||||
.WriteMSTATUSM, .WriteSSTATUSM,
|
.WriteMSTATUSM, .WriteSSTATUSM,
|
||||||
@ -167,7 +167,7 @@ module csr #(parameter
|
|||||||
|
|
||||||
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
|
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
|
||||||
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
|
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
|
||||||
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
|
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
|
||||||
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
|
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
|
||||||
IllegalCSRSAccessM & IllegalCSRUAccessM |
|
IllegalCSRSAccessM & IllegalCSRUAccessM |
|
||||||
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
|
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
|
||||||
|
@ -41,7 +41,7 @@ module csri #(parameter
|
|||||||
input logic InstrValidNotFlushedM, StallW,
|
input logic InstrValidNotFlushedM, StallW,
|
||||||
input logic CSRMWriteM, CSRSWriteM,
|
input logic CSRMWriteM, CSRSWriteM,
|
||||||
input logic [11:0] CSRAdrM,
|
input logic [11:0] CSRAdrM,
|
||||||
input logic ExtIntM, TimerIntM, SwIntM,
|
input logic ExtIntM, ExtIntS, TimerIntM, SwIntM,
|
||||||
input logic [`XLEN-1:0] MIDELEG_REGW,
|
input logic [`XLEN-1:0] MIDELEG_REGW,
|
||||||
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
||||||
input logic [`XLEN-1:0] CSRWriteValM
|
input logic [`XLEN-1:0] CSRWriteValM
|
||||||
@ -57,12 +57,12 @@ module csri #(parameter
|
|||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
IntInM = 0;
|
IntInM = 0;
|
||||||
IntInM[11] = ExtIntM;; // MEIP
|
IntInM[11] = ExtIntM; // MEIP
|
||||||
IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP
|
IntInM[9] = ExtIntS | (ExtIntM & MIDELEG_REGW[9]); // SEIP
|
||||||
IntInM[7] = TimerIntM; // MTIP
|
IntInM[7] = TimerIntM; // MTIP
|
||||||
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
||||||
IntInM[3] = SwIntM; // MSIP
|
IntInM[3] = SwIntM; // MSIP
|
||||||
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
||||||
end
|
end
|
||||||
|
|
||||||
// Interrupt Write Enables
|
// Interrupt Write Enables
|
||||||
@ -82,21 +82,19 @@ module csri #(parameter
|
|||||||
assign MIP_WRITE_MASK = 12'h000;
|
assign MIP_WRITE_MASK = 12'h000;
|
||||||
assign SIP_WRITE_MASK = 12'h000;
|
assign SIP_WRITE_MASK = 12'h000;
|
||||||
end
|
end
|
||||||
always @(posedge clk) //, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21
|
always @(posedge clk)
|
||||||
if (reset) IP_REGW_writeable <= 10'b0;
|
if (reset) IP_REGW_writeable <= 10'b0;
|
||||||
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
|
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
|
||||||
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
|
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable
|
||||||
// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
|
else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
|
||||||
else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
|
always @(posedge clk)
|
||||||
always @(posedge clk) //, posedge reset) begin
|
|
||||||
if (reset) IE_REGW <= 12'b0;
|
if (reset) IE_REGW <= 12'b0;
|
||||||
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
|
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
|
||||||
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
|
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
|
||||||
// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
|
|
||||||
|
|
||||||
// restricted views of registers
|
// restricted views of registers
|
||||||
// Add MEIP read-only signal
|
// Add ExtIntM read-only signal
|
||||||
assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable};
|
assign IP_REGW = {ExtIntM,1'b0,ExtIntS,9'b0} | {2'b0,IP_REGW_writeable};
|
||||||
|
|
||||||
// Machine Mode
|
// Machine Mode
|
||||||
assign MIP_REGW = IP_REGW;
|
assign MIP_REGW = IP_REGW;
|
||||||
|
@ -55,7 +55,7 @@ module privileged (
|
|||||||
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
||||||
input logic LoadMisalignedFaultM,
|
input logic LoadMisalignedFaultM,
|
||||||
input logic StoreAmoMisalignedFaultM,
|
input logic StoreAmoMisalignedFaultM,
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
|
||||||
input logic [4:0] SetFflagsM,
|
input logic [4:0] SetFflagsM,
|
||||||
@ -150,7 +150,7 @@ module privileged (
|
|||||||
.StallE, .StallM, .StallW,
|
.StallE, .StallM, .StallW,
|
||||||
.InstrM, .PCM, .SrcAM,
|
.InstrM, .PCM, .SrcAM,
|
||||||
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
|
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.InstrValidM, .FRegWriteM, .LoadStallD,
|
.InstrValidM, .FRegWriteM, .LoadStallD,
|
||||||
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
|
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
|
||||||
|
@ -37,6 +37,15 @@
|
|||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
`define N `PLIC_NUM_SRC
|
||||||
|
// number of interrupt sources
|
||||||
|
// does not include source 0, which does not connect to anything according to spec
|
||||||
|
// up to 63 sources supported; *** in the future, allow up to 1023 sources
|
||||||
|
|
||||||
|
`define C 2
|
||||||
|
// number of conexts
|
||||||
|
// hardcoded to 2 contexts for now; *** later upgrade to arbitrary (up to 15872) contexts
|
||||||
|
|
||||||
module plic (
|
module plic (
|
||||||
input logic HCLK, HRESETn,
|
input logic HCLK, HRESETn,
|
||||||
input logic HSELPLIC,
|
input logic HSELPLIC,
|
||||||
@ -48,25 +57,26 @@ module plic (
|
|||||||
input logic UARTIntr,GPIOIntr,
|
input logic UARTIntr,GPIOIntr,
|
||||||
output logic [`XLEN-1:0] HREADPLIC,
|
output logic [`XLEN-1:0] HREADPLIC,
|
||||||
output logic HRESPPLIC, HREADYPLIC,
|
output logic HRESPPLIC, HREADYPLIC,
|
||||||
output logic ExtIntM);
|
output logic ExtIntM, ExtIntS);
|
||||||
|
|
||||||
localparam N=`PLIC_NUM_SRC; // should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
|
|
||||||
|
|
||||||
logic memwrite, memread, initTrans;
|
logic memwrite, memread, initTrans;
|
||||||
logic [23:0] entry, entryd;
|
logic [23:0] entry, entryd;
|
||||||
logic [31:0] Din, Dout;
|
logic [31:0] Din, Dout;
|
||||||
logic [N:1] requests;
|
|
||||||
|
|
||||||
logic [2:0] intPriority[N:1];
|
// context-independent signals
|
||||||
logic [2:0] intThreshold;
|
logic [`N:1] requests;
|
||||||
logic [N:1] intPending, nextIntPending, intEn, intInProgress;
|
logic [`N:1][2:0] intPriority;
|
||||||
logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
logic [`N:1] intInProgress, intPending, nextIntPending;
|
||||||
|
|
||||||
logic [N:1] pendingArray[7:1];
|
// context-dependent signals
|
||||||
logic [7:1] pendingPGrouped;
|
logic [`C-1:0][2:0] intThreshold;
|
||||||
logic [7:1] pendingMaxP;
|
logic [`C-1:0][`N:1] intEn;
|
||||||
logic [N:1] pendingRequestsAtMaxP;
|
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||||
logic [7:1] threshMask;
|
logic [`C-1:0][7:1][`N:1] irqMatrix;
|
||||||
|
logic [`C-1:0][7:1] priorities_with_irqs;
|
||||||
|
logic [`C-1:0][7:1] max_priority_with_irqs;
|
||||||
|
logic [`C-1:0][`N:1] irqs_at_max_priority;
|
||||||
|
logic [`C-1:0][7:1] threshMask;
|
||||||
|
|
||||||
// =======
|
// =======
|
||||||
// AHB I/O
|
// AHB I/O
|
||||||
@ -82,12 +92,12 @@ module plic (
|
|||||||
|
|
||||||
// account for subword read/write circuitry
|
// account for subword read/write circuitry
|
||||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||||
if (`XLEN == 64) begin
|
if (`XLEN == 64) begin
|
||||||
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
assign Din = entryd[2] ? HWDATA[63:32] : HWDATA[31:0];
|
||||||
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
assign HREADPLIC = entryd[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||||
end else begin // 32-bit
|
end else begin // 32-bit
|
||||||
assign Din = HWDATA[31:0];
|
|
||||||
assign HREADPLIC = Dout;
|
assign HREADPLIC = Dout;
|
||||||
|
assign Din = HWDATA[31:0];
|
||||||
end
|
end
|
||||||
|
|
||||||
// ==================
|
// ==================
|
||||||
@ -96,43 +106,56 @@ module plic (
|
|||||||
always @(posedge HCLK,negedge HRESETn) begin
|
always @(posedge HCLK,negedge HRESETn) begin
|
||||||
// resetting
|
// resetting
|
||||||
if (~HRESETn) begin
|
if (~HRESETn) begin
|
||||||
intPriority <= #1 '{default:3'b0};
|
intPriority <= #1 {`N{3'b0}};
|
||||||
intEn <= #1 {N{1'b0}};
|
intEn <= #1 {2{`N'b0}};
|
||||||
intThreshold <= #1 3'b0;
|
intThreshold <= #1 {2{3'b0}};
|
||||||
intInProgress <= #1 {N{1'b0}};
|
intInProgress <= #1 `N'b0;
|
||||||
// writing
|
// writing
|
||||||
end else begin
|
end else begin
|
||||||
if (memwrite)
|
if (memwrite)
|
||||||
casez(entryd)
|
casez(entryd)
|
||||||
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
24'h0000??: intPriority[entryd[7:2]] <= #1 Din[2:0];
|
||||||
`ifdef PLIC_NUM_SRC_LT_32
|
`ifdef PLIC_NUM_SRC_LT_32 // *** switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources
|
||||||
24'h002000: intEn[N:1] <= #1 Din[N:1];
|
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
|
||||||
|
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
|
||||||
`endif
|
`endif
|
||||||
`ifndef PLIC_NUM_SRC_LT_32
|
`ifndef PLIC_NUM_SRC_LT_32
|
||||||
24'h002000: intEn[31:1] <= #1 Din[31:1];
|
24'h002000: intEn[0][31:1] <= #1 Din[31:1];
|
||||||
24'h002004: intEn[N:32] <= #1 Din[31:0];
|
24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
|
||||||
|
24'h002080: intEn[1][31:1] <= #1 Din[31:1];
|
||||||
|
24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
|
||||||
`endif
|
`endif
|
||||||
24'h200000: intThreshold[2:0] <= #1 Din[2:0];
|
24'h200000: intThreshold[0] <= #1 Din[2:0];
|
||||||
24'h200004: intInProgress <= #1 intInProgress & ~(`PLIC_NUM_SRC'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
24'h200004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||||
|
24'h201000: intThreshold[1] <= #1 Din[2:0];
|
||||||
|
24'h201004: intInProgress <= #1 intInProgress & ~(`N'b1 << (Din[5:0]-1)); // lower "InProgress" to signify completion
|
||||||
endcase
|
endcase
|
||||||
// reading
|
// reading
|
||||||
if (memread)
|
if (memread)
|
||||||
casez(entry)
|
casez(entry)
|
||||||
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
|
||||||
`ifdef PLIC_NUM_SRC_LT_32
|
`ifdef PLIC_NUM_SRC_LT_32
|
||||||
24'h001000: Dout <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
24'h001000: Dout <= #1 {{(31-`N){1'b0}},intPending,1'b0};
|
||||||
24'h002000: Dout <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
|
24'h002000: Dout <= #1 {{(31-`N){1'b0}},intEn[0],1'b0};
|
||||||
|
24'h002080: Dout <= #1 {{(31-`N){1'b0}},intEn[1],1'b0};
|
||||||
`endif
|
`endif
|
||||||
`ifndef PLIC_NUM_SRC_LT_32
|
`ifndef PLIC_NUM_SRC_LT_32
|
||||||
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
24'h001000: Dout <= #1 {intPending[31:1],1'b0};
|
||||||
24'h001004: Dout <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
24'h001004: Dout <= #1 {{(63-`N){1'b0}},intPending[`N:32]};
|
||||||
24'h002000: Dout <= #1 {intEn[31:1],1'b0};
|
24'h002000: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||||
24'h002004: Dout <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
24'h002004: Dout <= #1 {{(63-`N){1'b0}},intEn[0][`N:32]};
|
||||||
|
24'h002080: Dout <= #1 {intEn[0][31:1],1'b0};
|
||||||
|
24'h002084: Dout <= #1 {{(63-`N){1'b0}},intEn[1][`N:32]};
|
||||||
`endif
|
`endif
|
||||||
24'h200000: Dout <= #1 {29'b0,intThreshold[2:0]};
|
24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
|
||||||
24'h200004: begin
|
24'h200004: begin
|
||||||
Dout <= #1 {26'b0,intClaim};
|
Dout <= #1 {26'b0,intClaim[0]};
|
||||||
intInProgress <= #1 intInProgress | (`PLIC_NUM_SRC'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[0]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||||
|
end
|
||||||
|
24'h201000: Dout <= #1 {29'b0,intThreshold[1]};
|
||||||
|
24'h201004: begin
|
||||||
|
Dout <= #1 {26'b0,intClaim[1]};
|
||||||
|
intInProgress <= #1 intInProgress | (`N'b1 << (intClaim[1]-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||||
end
|
end
|
||||||
default: Dout <= #1 32'h0; // invalid access
|
default: Dout <= #1 32'h0; // invalid access
|
||||||
endcase
|
endcase
|
||||||
@ -143,7 +166,7 @@ module plic (
|
|||||||
|
|
||||||
// connect sources to requests
|
// connect sources to requests
|
||||||
always_comb begin
|
always_comb begin
|
||||||
requests = {N{1'b0}};
|
requests = `N'b0;
|
||||||
`ifdef PLIC_GPIO_ID
|
`ifdef PLIC_GPIO_ID
|
||||||
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
requests[`PLIC_GPIO_ID] = GPIOIntr;
|
||||||
`endif
|
`endif
|
||||||
@ -152,66 +175,88 @@ module plic (
|
|||||||
`endif
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
// pending updates
|
// pending interrupt requests
|
||||||
// *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered)
|
assign nextIntPending =
|
||||||
assign nextIntPending = (intPending | (requests & ~intInProgress)) & // requests should raise intPending except when their service routine is already in progress
|
(intPending | // existing pending requests
|
||||||
~({N{((entry == 24'h200004) & memread)}} << (intClaim-1)); // clear pending bit when claim register is read
|
(requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced)
|
||||||
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed
|
||||||
|
~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1));
|
||||||
|
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
||||||
|
|
||||||
// pending array - indexed by priority_lvl x source_ID
|
// context-dependent signals
|
||||||
genvar i, j;
|
genvar ctx;
|
||||||
for (j=1; j<=7; j++) begin: pending
|
for (ctx=0; ctx<`C; ctx++) begin
|
||||||
for (i=1; i<=N; i=i+1) begin: pendingbit
|
// request matrix
|
||||||
assign pendingArray[j][i] = (intPriority[i]==j) & intEn[i] & intPending[i];
|
// priority level (rows) X source ID (columns)
|
||||||
|
//
|
||||||
|
// irqMatrix[ctx][pri][src] is high if source <src>
|
||||||
|
// has priority level <pri> and has an "active" interrupt request
|
||||||
|
// ("active" meaning it is enabled in context <ctx> and is pending)
|
||||||
|
genvar src, pri;
|
||||||
|
for (pri=1; pri<=7; pri++) begin
|
||||||
|
for (src=1; src<=`N; src++) begin
|
||||||
|
assign irqMatrix[ctx][pri][src] = (intPriority[src]==pri) & intPending[src] & intEn[ctx][src];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
// pending array, except grouped by priority
|
|
||||||
assign pendingPGrouped[7:1] = {|pendingArray[7],
|
|
||||||
|pendingArray[6],
|
|
||||||
|pendingArray[5],
|
|
||||||
|pendingArray[4],
|
|
||||||
|pendingArray[3],
|
|
||||||
|pendingArray[2],
|
|
||||||
|pendingArray[1]};
|
|
||||||
//assign pendingPGrouped = pendingArray.or;
|
|
||||||
|
|
||||||
// pendingPGrouped, except only topmost priority is active
|
// which prority levels have one or more active requests?
|
||||||
assign pendingMaxP[7:1] = {pendingPGrouped[7],
|
assign priorities_with_irqs[ctx][7:1] = {
|
||||||
pendingPGrouped[6] & ~|pendingPGrouped[7],
|
|irqMatrix[ctx][7],
|
||||||
pendingPGrouped[5] & ~|pendingPGrouped[7:6],
|
|irqMatrix[ctx][6],
|
||||||
pendingPGrouped[4] & ~|pendingPGrouped[7:5],
|
|irqMatrix[ctx][5],
|
||||||
pendingPGrouped[3] & ~|pendingPGrouped[7:4],
|
|irqMatrix[ctx][4],
|
||||||
pendingPGrouped[2] & ~|pendingPGrouped[7:3],
|
|irqMatrix[ctx][3],
|
||||||
pendingPGrouped[1] & ~|pendingPGrouped[7:2]};
|
|irqMatrix[ctx][2],
|
||||||
// select the pending requests at that priority
|
|irqMatrix[ctx][1]
|
||||||
assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7])
|
};
|
||||||
| ({N{pendingMaxP[6]}} & pendingArray[6])
|
|
||||||
| ({N{pendingMaxP[5]}} & pendingArray[5])
|
// get the highest priority level that has active requests
|
||||||
| ({N{pendingMaxP[4]}} & pendingArray[4])
|
assign max_priority_with_irqs[ctx][7:1] = {
|
||||||
| ({N{pendingMaxP[3]}} & pendingArray[3])
|
priorities_with_irqs[ctx][7],
|
||||||
| ({N{pendingMaxP[2]}} & pendingArray[2])
|
priorities_with_irqs[ctx][6] & ~|priorities_with_irqs[ctx][7],
|
||||||
| ({N{pendingMaxP[1]}} & pendingArray[1]);
|
priorities_with_irqs[ctx][5] & ~|priorities_with_irqs[ctx][7:6],
|
||||||
// find the lowest ID amongst active interrupts at the highest priority
|
priorities_with_irqs[ctx][4] & ~|priorities_with_irqs[ctx][7:5],
|
||||||
logic [5:0] k;
|
priorities_with_irqs[ctx][3] & ~|priorities_with_irqs[ctx][7:4],
|
||||||
always_comb begin
|
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
|
||||||
intClaim = 6'b0;
|
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
|
||||||
for (k=N; k>0; k=k-1) begin
|
};
|
||||||
if (pendingRequestsAtMaxP[k]) intClaim = k;
|
|
||||||
|
// of the sources at the highest priority level that has active requests,
|
||||||
|
// which sources have active requests?
|
||||||
|
assign irqs_at_max_priority[ctx][`N:1] =
|
||||||
|
({`N{max_priority_with_irqs[ctx][7]}} & irqMatrix[ctx][7]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][6]}} & irqMatrix[ctx][6]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][5]}} & irqMatrix[ctx][5]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][4]}} & irqMatrix[ctx][4]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][3]}} & irqMatrix[ctx][3]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][2]}} & irqMatrix[ctx][2]) |
|
||||||
|
({`N{max_priority_with_irqs[ctx][1]}} & irqMatrix[ctx][1]);
|
||||||
|
|
||||||
|
// of the sources at the highest priority level that has active requests,
|
||||||
|
// choose the source with the lowest source ID to be the most urgent
|
||||||
|
// and set intClaim to the source ID of the most urgent active request
|
||||||
|
integer k;
|
||||||
|
always_comb begin
|
||||||
|
intClaim[ctx] = 6'b0;
|
||||||
|
for (k=`N; k>0; k--) begin
|
||||||
|
if (irqs_at_max_priority[ctx][k]) intClaim[ctx] = k[5:0];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
// create threshold mask
|
||||||
// create threshold mask
|
always_comb begin
|
||||||
always_comb begin
|
threshMask[ctx][7] = (intThreshold[ctx] != 7);
|
||||||
threshMask[7] = (intThreshold != 7);
|
threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
|
||||||
threshMask[6] = (intThreshold != 6) & threshMask[7];
|
threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
|
||||||
threshMask[5] = (intThreshold != 5) & threshMask[6];
|
threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
|
||||||
threshMask[4] = (intThreshold != 4) & threshMask[5];
|
threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
|
||||||
threshMask[3] = (intThreshold != 3) & threshMask[4];
|
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
|
||||||
threshMask[2] = (intThreshold != 2) & threshMask[3];
|
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
|
||||||
threshMask[1] = (intThreshold != 1) & threshMask[2];
|
end
|
||||||
end
|
// is the max priority > threshold?
|
||||||
// is the max priority > threshold?
|
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
||||||
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
|
end
|
||||||
assign ExtIntM = |(threshMask & pendingPGrouped);
|
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
|
||||||
|
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ module uncore (
|
|||||||
input logic [3:0] HSIZED,
|
input logic [3:0] HSIZED,
|
||||||
input logic HWRITED,
|
input logic HWRITED,
|
||||||
// peripheral pins
|
// peripheral pins
|
||||||
output logic TimerIntM, SwIntM, ExtIntM,
|
output logic TimerIntM, SwIntM, ExtIntM, ExtIntS,
|
||||||
input logic [31:0] GPIOPinsIn,
|
input logic [31:0] GPIOPinsIn,
|
||||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||||
input logic UARTSin,
|
input logic UARTSin,
|
||||||
@ -133,9 +133,10 @@ module uncore (
|
|||||||
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
.HWRITE, .HREADY, .HTRANS, .HWDATA,
|
||||||
.UARTIntr, .GPIOIntr,
|
.UARTIntr, .GPIOIntr,
|
||||||
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
.HREADPLIC, .HRESPPLIC, .HREADYPLIC,
|
||||||
.ExtIntM);
|
.ExtIntM, .ExtIntS);
|
||||||
end else begin : plic
|
end else begin : plic
|
||||||
assign ExtIntM = 0;
|
assign ExtIntM = 0;
|
||||||
|
assign ExtIntS = 0;
|
||||||
end
|
end
|
||||||
if (`GPIO_SUPPORTED == 1) begin : gpio
|
if (`GPIO_SUPPORTED == 1) begin : gpio
|
||||||
gpio gpio(
|
gpio gpio(
|
||||||
|
@ -32,137 +32,137 @@
|
|||||||
/* verilator lint_on UNUSED */
|
/* verilator lint_on UNUSED */
|
||||||
|
|
||||||
module wallypipelinedcore (
|
module wallypipelinedcore (
|
||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
// Privileged
|
// Privileged
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
|
||||||
input logic [63:0] MTIME_CLINT,
|
input logic [63:0] MTIME_CLINT,
|
||||||
// Bus Interface
|
// Bus Interface
|
||||||
input logic [`AHBW-1:0] HRDATA,
|
input logic [`AHBW-1:0] HRDATA,
|
||||||
input logic HREADY, HRESP,
|
input logic HREADY, HRESP,
|
||||||
output logic HCLK, HRESETn,
|
output logic HCLK, HRESETn,
|
||||||
output logic [31:0] HADDR,
|
output logic [31:0] HADDR,
|
||||||
output logic [`AHBW-1:0] HWDATA,
|
output logic [`AHBW-1:0] HWDATA,
|
||||||
output logic HWRITE,
|
output logic HWRITE,
|
||||||
output logic [2:0] HSIZE,
|
output logic [2:0] HSIZE,
|
||||||
output logic [2:0] HBURST,
|
output logic [2:0] HBURST,
|
||||||
output logic [3:0] HPROT,
|
output logic [3:0] HPROT,
|
||||||
output logic [1:0] HTRANS,
|
output logic [1:0] HTRANS,
|
||||||
output logic HMASTLOCK,
|
output logic HMASTLOCK,
|
||||||
// Delayed signals for subword write
|
// Delayed signals for subword write
|
||||||
output logic [2:0] HADDRD,
|
output logic [2:0] HADDRD,
|
||||||
output logic [3:0] HSIZED,
|
output logic [3:0] HSIZED,
|
||||||
output logic HWRITED
|
output logic HWRITED
|
||||||
);
|
);
|
||||||
|
|
||||||
// logic [1:0] ForwardAE, ForwardBE;
|
// logic [1:0] ForwardAE, ForwardBE;
|
||||||
logic StallF, StallD, StallE, StallM, StallW;
|
logic StallF, StallD, StallE, StallM, StallW;
|
||||||
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
logic FlushF, FlushD, FlushE, FlushM, FlushW;
|
||||||
logic RetM;
|
logic RetM;
|
||||||
(* mark_debug = "true" *) logic TrapM;
|
(* mark_debug = "true" *) logic TrapM;
|
||||||
|
|
||||||
// new signals that must connect through DP
|
// new signals that must connect through DP
|
||||||
logic MDUE, W64E;
|
logic MDUE, W64E;
|
||||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic [1:0] AtomicM;
|
logic [1:0] AtomicM;
|
||||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
||||||
logic [`XLEN-1:0] SrcAM;
|
logic [`XLEN-1:0] SrcAM;
|
||||||
logic [2:0] Funct3E;
|
logic [2:0] Funct3E;
|
||||||
// logic [31:0] InstrF;
|
// logic [31:0] InstrF;
|
||||||
logic [31:0] InstrD, InstrW;
|
logic [31:0] InstrD, InstrW;
|
||||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
||||||
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||||
(* mark_debug = "true" *) logic InstrValidM;
|
(* mark_debug = "true" *) logic InstrValidM;
|
||||||
logic InstrMisalignedFaultM;
|
logic InstrMisalignedFaultM;
|
||||||
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
|
||||||
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
|
||||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||||
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM;
|
||||||
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
logic [`XLEN-1:0] InstrMisalignedAdrM;
|
||||||
logic InvalidateICacheM, FlushDCacheM;
|
logic InvalidateICacheM, FlushDCacheM;
|
||||||
logic PCSrcE;
|
logic PCSrcE;
|
||||||
logic CSRWritePendingDEM;
|
logic CSRWritePendingDEM;
|
||||||
logic DivBusyE;
|
logic DivBusyE;
|
||||||
logic DivE;
|
logic DivE;
|
||||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
// floating point unit signals
|
// floating point unit signals
|
||||||
logic [2:0] FRM_REGW;
|
logic [2:0] FRM_REGW;
|
||||||
logic [4:0] RdM, RdW;
|
logic [4:0] RdM, RdW;
|
||||||
logic FStallD;
|
logic FStallD;
|
||||||
logic FWriteIntE;
|
logic FWriteIntE;
|
||||||
logic [`XLEN-1:0] FWriteDataE;
|
logic [`XLEN-1:0] FWriteDataE;
|
||||||
logic [`XLEN-1:0] FIntResM;
|
logic [`XLEN-1:0] FIntResM;
|
||||||
logic FDivBusyE;
|
logic FDivBusyE;
|
||||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||||
logic FRegWriteM;
|
logic FRegWriteM;
|
||||||
logic FPUStallD;
|
logic FPUStallD;
|
||||||
logic [4:0] SetFflagsM;
|
logic [4:0] SetFflagsM;
|
||||||
|
|
||||||
// memory management unit signals
|
// memory management unit signals
|
||||||
logic ITLBWriteF;
|
logic ITLBWriteF;
|
||||||
logic ITLBFlushF, DTLBFlushM;
|
logic ITLBFlushF, DTLBFlushM;
|
||||||
logic ITLBMissF;
|
logic ITLBMissF;
|
||||||
logic [`XLEN-1:0] SATP_REGW;
|
logic [`XLEN-1:0] SATP_REGW;
|
||||||
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
|
||||||
logic [1:0] STATUS_MPP;
|
logic [1:0] STATUS_MPP;
|
||||||
logic [1:0] PrivilegeModeW;
|
logic [1:0] PrivilegeModeW;
|
||||||
logic [`XLEN-1:0] PTE;
|
logic [`XLEN-1:0] PTE;
|
||||||
logic [1:0] PageType;
|
logic [1:0] PageType;
|
||||||
|
|
||||||
// PMA checker signals
|
// PMA checker signals
|
||||||
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
|
||||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||||
|
|
||||||
// IMem stalls
|
// IMem stalls
|
||||||
logic IFUStallF;
|
logic IFUStallF;
|
||||||
logic LSUStallM;
|
logic LSUStallM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// cpu lsu interface
|
// cpu lsu interface
|
||||||
logic [2:0] Funct3M;
|
logic [2:0] Funct3M;
|
||||||
logic [`XLEN-1:0] IEUAdrE;
|
logic [`XLEN-1:0] IEUAdrE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataM;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] ReadDataM;
|
||||||
logic [`XLEN-1:0] ReadDataW;
|
logic [`XLEN-1:0] ReadDataW;
|
||||||
logic CommittedM;
|
logic CommittedM;
|
||||||
|
|
||||||
// AHB ifu interface
|
// AHB ifu interface
|
||||||
logic [`PA_BITS-1:0] IFUBusAdr;
|
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||||
logic [`XLEN-1:0] IFUBusHRDATA;
|
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||||
logic IFUBusRead;
|
logic IFUBusRead;
|
||||||
logic IFUBusAck;
|
logic IFUBusAck;
|
||||||
|
|
||||||
// AHB LSU interface
|
// AHB LSU interface
|
||||||
logic [`PA_BITS-1:0] LSUBusAdr;
|
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||||
logic LSUBusRead;
|
logic LSUBusRead;
|
||||||
logic LSUBusWrite;
|
logic LSUBusWrite;
|
||||||
logic LSUBusAck;
|
logic LSUBusAck;
|
||||||
logic [`XLEN-1:0] LSUBusHRDATA;
|
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||||
logic [`XLEN-1:0] LSUBusHWDATA;
|
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||||
|
|
||||||
logic BPPredWrongE;
|
logic BPPredWrongE;
|
||||||
logic BPPredDirWrongM;
|
logic BPPredDirWrongM;
|
||||||
logic BTBPredPCWrongM;
|
logic BTBPredPCWrongM;
|
||||||
logic RASPredPCWrongM;
|
logic RASPredPCWrongM;
|
||||||
logic BPPredClassNonCFIWrongM;
|
logic BPPredClassNonCFIWrongM;
|
||||||
logic [4:0] InstrClassM;
|
logic [4:0] InstrClassM;
|
||||||
logic InstrAccessFaultF;
|
logic InstrAccessFaultF;
|
||||||
logic [2:0] LSUBusSize;
|
logic [2:0] LSUBusSize;
|
||||||
|
|
||||||
logic ExceptionM;
|
logic ExceptionM;
|
||||||
logic PendingInterruptM;
|
logic PendingInterruptM;
|
||||||
logic DCacheMiss;
|
logic DCacheMiss;
|
||||||
logic DCacheAccess;
|
logic DCacheAccess;
|
||||||
logic ICacheMiss;
|
logic ICacheMiss;
|
||||||
logic ICacheAccess;
|
logic ICacheAccess;
|
||||||
logic BreakpointFaultM, EcallFaultM;
|
logic BreakpointFaultM, EcallFaultM;
|
||||||
logic InstrDAPageFaultF;
|
logic InstrDAPageFaultF;
|
||||||
|
|
||||||
ifu ifu(
|
ifu ifu(
|
||||||
@ -203,8 +203,8 @@ module wallypipelinedcore (
|
|||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||||
.InstrAccessFaultF,
|
.InstrAccessFaultF,
|
||||||
.InstrDAPageFaultF
|
.InstrDAPageFaultF
|
||||||
|
|
||||||
); // instruction fetch unit: PC, branch prediction, instruction cache
|
); // instruction fetch unit: PC, branch prediction, instruction cache
|
||||||
|
|
||||||
ieu ieu(
|
ieu ieu(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
@ -221,7 +221,7 @@ module wallypipelinedcore (
|
|||||||
// Memory stage interface
|
// Memory stage interface
|
||||||
.SquashSCW, // from LSU
|
.SquashSCW, // from LSU
|
||||||
.MemRWM, // read/write control goes to LSU
|
.MemRWM, // read/write control goes to LSU
|
||||||
.AtomicE, // atomic control goes to LSU
|
.AtomicE, // atomic control goes to LSU
|
||||||
.AtomicM, // atomic control goes to LSU
|
.AtomicM, // atomic control goes to LSU
|
||||||
.WriteDataM, // Write data to LSU
|
.WriteDataM, // Write data to LSU
|
||||||
.Funct3M, // size and signedness to LSU
|
.Funct3M, // size and signedness to LSU
|
||||||
@ -245,41 +245,41 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
lsu lsu(
|
lsu lsu(
|
||||||
.clk, .reset, .StallM, .FlushM, .StallW,
|
.clk, .reset, .StallM, .FlushM, .StallW,
|
||||||
.FlushW,
|
.FlushW,
|
||||||
// CPU interface
|
// CPU interface
|
||||||
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
|
||||||
.AtomicM, .TrapM,
|
.AtomicM, .TrapM,
|
||||||
.CommittedM, .DCacheMiss, .DCacheAccess,
|
.CommittedM, .DCacheMiss, .DCacheAccess,
|
||||||
.SquashSCW,
|
.SquashSCW,
|
||||||
//.DataMisalignedM(DataMisalignedM),
|
//.DataMisalignedM(DataMisalignedM),
|
||||||
.IEUAdrE, .IEUAdrM, .WriteDataM,
|
.IEUAdrE, .IEUAdrM, .WriteDataM,
|
||||||
.ReadDataM, .FlushDCacheM,
|
.ReadDataM, .FlushDCacheM,
|
||||||
// connected to ahb (all stay the same)
|
// connected to ahb (all stay the same)
|
||||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||||
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||||
|
|
||||||
// connect to csr or privilege and stay the same.
|
// connect to csr or privilege and stay the same.
|
||||||
.PrivilegeModeW, // connects to csr
|
.PrivilegeModeW, // connects to csr
|
||||||
.PMPCFG_ARRAY_REGW, // connects to csr
|
.PMPCFG_ARRAY_REGW, // connects to csr
|
||||||
.PMPADDR_ARRAY_REGW, // connects to csr
|
.PMPADDR_ARRAY_REGW, // connects to csr
|
||||||
// hptw keep i/o
|
// hptw keep i/o
|
||||||
.SATP_REGW, // from csr
|
.SATP_REGW, // from csr
|
||||||
.STATUS_MXR, // from csr
|
.STATUS_MXR, // from csr
|
||||||
.STATUS_SUM, // from csr
|
.STATUS_SUM, // from csr
|
||||||
.STATUS_MPRV, // from csr
|
.STATUS_MPRV, // from csr
|
||||||
.STATUS_MPP, // from csr
|
.STATUS_MPP, // from csr
|
||||||
|
|
||||||
.DTLBFlushM, // connects to privilege
|
.DTLBFlushM, // connects to privilege
|
||||||
.LoadPageFaultM, // connects to privilege
|
.LoadPageFaultM, // connects to privilege
|
||||||
.StoreAmoPageFaultM, // connects to privilege
|
.StoreAmoPageFaultM, // connects to privilege
|
||||||
.LoadMisalignedFaultM, // connects to privilege
|
.LoadMisalignedFaultM, // connects to privilege
|
||||||
.LoadAccessFaultM, // connects to privilege
|
.LoadAccessFaultM, // connects to privilege
|
||||||
.StoreAmoMisalignedFaultM, // connects to privilege
|
.StoreAmoMisalignedFaultM, // connects to privilege
|
||||||
.StoreAmoAccessFaultM, // connects to privilege
|
.StoreAmoAccessFaultM, // connects to privilege
|
||||||
.InstrDAPageFaultF,
|
.InstrDAPageFaultF,
|
||||||
|
|
||||||
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
|
||||||
.LSUStallM); // change to LSUStallM
|
.LSUStallM); // change to LSUStallM
|
||||||
|
|
||||||
|
|
||||||
// *** Ross: please make EBU conditional when only supporting internal memories
|
// *** Ross: please make EBU conditional when only supporting internal memories
|
||||||
@ -306,13 +306,13 @@ module wallypipelinedcore (
|
|||||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.LSUStallM, .IFUStallF,
|
.LSUStallM, .IFUStallF,
|
||||||
.FPUStallD, .FStallD,
|
.FPUStallD, .FStallD,
|
||||||
.DivBusyE, .FDivBusyE,
|
.DivBusyE, .FDivBusyE,
|
||||||
.EcallFaultM, .BreakpointFaultM,
|
.EcallFaultM, .BreakpointFaultM,
|
||||||
.InvalidateICacheM,
|
.InvalidateICacheM,
|
||||||
// Stall & flush outputs
|
// Stall & flush outputs
|
||||||
.StallF, .StallD, .StallE, .StallM, .StallW,
|
.StallF, .StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW
|
||||||
); // global stall and flush control
|
); // global stall and flush control
|
||||||
|
|
||||||
if (`ZICSR_SUPPORTED) begin:priv
|
if (`ZICSR_SUPPORTED) begin:priv
|
||||||
privileged priv(
|
privileged priv(
|
||||||
@ -331,7 +331,7 @@ module wallypipelinedcore (
|
|||||||
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
||||||
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
||||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.InstrMisalignedAdrM, .IEUAdrM,
|
.InstrMisalignedAdrM, .IEUAdrM,
|
||||||
.SetFflagsM,
|
.SetFflagsM,
|
||||||
|
@ -74,7 +74,7 @@ module wallypipelinedsoc (
|
|||||||
logic HRESP;
|
logic HRESP;
|
||||||
logic TimerIntM, SwIntM; // from CLINT
|
logic TimerIntM, SwIntM; // from CLINT
|
||||||
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
logic [63:0] MTIME_CLINT; // from CLINT to CSRs
|
||||||
logic ExtIntM; // from PLIC
|
logic ExtIntM,ExtIntS; // from PLIC
|
||||||
logic [2:0] HADDRD;
|
logic [2:0] HADDRD;
|
||||||
logic [3:0] HSIZED;
|
logic [3:0] HSIZED;
|
||||||
logic HWRITED;
|
logic HWRITED;
|
||||||
@ -84,7 +84,7 @@ module wallypipelinedsoc (
|
|||||||
|
|
||||||
// instantiate processor and memories
|
// instantiate processor and memories
|
||||||
wallypipelinedcore core(.clk, .reset,
|
wallypipelinedcore core(.clk, .reset,
|
||||||
.TimerIntM, .ExtIntM, .SwIntM,
|
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
|
||||||
.MTIME_CLINT,
|
.MTIME_CLINT,
|
||||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
|
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
|
||||||
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
|
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
|
||||||
@ -94,7 +94,7 @@ module wallypipelinedsoc (
|
|||||||
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||||
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||||
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
|
||||||
.TimerIntM, .SwIntM, .ExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
.TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
|
||||||
.HSELEXT,
|
.HSELEXT,
|
||||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK
|
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK
|
||||||
|
|
||||||
|
@ -334,8 +334,8 @@ module testbench;
|
|||||||
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
|
//`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]);
|
||||||
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
`INIT_CHECKPOINT_VAL(UART_SCR, [7:0]);
|
||||||
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1);
|
||||||
`INIT_CHECKPOINT_VAL(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1]);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0);
|
||||||
`INIT_CHECKPOINT_VAL(PLIC_THRESHOLD, [2:0]);
|
`INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_THRESHOLD, [2:0],1,0);
|
||||||
|
|
||||||
integer memFile;
|
integer memFile;
|
||||||
integer readResult;
|
integer readResult;
|
||||||
|
Loading…
Reference in New Issue
Block a user