1st attempt at multiple channel PLIC

This commit is contained in:
bbracker 2022-03-24 17:08:10 -07:00
parent aa60b57fb3
commit 4b376e2834
10 changed files with 325 additions and 265 deletions

View File

@ -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

View File

@ -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!")

View File

@ -43,7 +43,7 @@ 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,
@ -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,

View File

@ -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,8 +57,8 @@ 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
@ -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;

View File

@ -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,

View File

@ -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
@ -86,8 +96,8 @@ module plic (
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],
priorities_with_irqs[ctx][2] & ~|priorities_with_irqs[ctx][7:3],
priorities_with_irqs[ctx][1] & ~|priorities_with_irqs[ctx][7:2]
};
// 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 always_comb begin
intClaim = 6'b0; intClaim[ctx] = 6'b0;
for (k=N; k>0; k=k-1) begin for (k=`N; k>0; k--) begin
if (pendingRequestsAtMaxP[k]) intClaim = k; 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[7] = (intThreshold != 7); threshMask[ctx][7] = (intThreshold[ctx] != 7);
threshMask[6] = (intThreshold != 6) & threshMask[7]; threshMask[ctx][6] = (intThreshold[ctx] != 6) & threshMask[ctx][7];
threshMask[5] = (intThreshold != 5) & threshMask[6]; threshMask[ctx][5] = (intThreshold[ctx] != 5) & threshMask[ctx][6];
threshMask[4] = (intThreshold != 4) & threshMask[5]; threshMask[ctx][4] = (intThreshold[ctx] != 4) & threshMask[ctx][5];
threshMask[3] = (intThreshold != 3) & threshMask[4]; threshMask[ctx][3] = (intThreshold[ctx] != 3) & threshMask[ctx][4];
threshMask[2] = (intThreshold != 2) & threshMask[3]; threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
threshMask[1] = (intThreshold != 1) & threshMask[2]; threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][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?
assign ExtIntM = |(threshMask & pendingPGrouped); end
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
endmodule endmodule

View File

@ -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(

View File

@ -34,7 +34,7 @@
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,
@ -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,

View File

@ -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

View File

@ -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;