mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Yee hoo first draft of PLIC plus self-checking tests
This commit is contained in:
parent
5946b860ca
commit
ce7b2314ef
@ -93,6 +93,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
||||
|
||||
|
@ -90,6 +90,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
// Can add PLIC Config here
|
||||
// Num interrupt sources
|
||||
|
||||
|
@ -90,6 +90,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
||||
/* verilator lint_off ASSIGNDLY */
|
||||
|
@ -89,6 +89,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
||||
|
||||
|
@ -90,6 +90,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 4
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
||||
/* verilator lint_off ASSIGNDLY */
|
||||
|
@ -25,6 +25,10 @@
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
// Virtual Memory Constants (sv39)
|
||||
`define VPN_BITS 27
|
||||
`define PPN_BITS 44
|
||||
|
@ -90,6 +90,10 @@
|
||||
// Hardware configuration
|
||||
`define UART_PRESCALE 1
|
||||
|
||||
// Interrupt configuration
|
||||
`define PLIC_NUM_SRC 53
|
||||
`define PLIC_UART_ID 4
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
||||
/* verilator lint_off ASSIGNDLY */
|
||||
|
1
wally-pipelined/regression/sim-peripherals
Executable file
1
wally-pipelined/regression/sim-peripherals
Executable file
@ -0,0 +1 @@
|
||||
vsim -do wally-peripherals.do
|
@ -40,4 +40,4 @@ vsim workopt
|
||||
|
||||
|
||||
view wave
|
||||
do wally-peripherals-signals.do
|
||||
do wave-dos/peripheral-waves.do
|
||||
|
@ -10,25 +10,26 @@ restart -f
|
||||
delete wave /*
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
# general stuff
|
||||
add wave /testbench/clk
|
||||
add wave /testbench/reset
|
||||
add wave -divider
|
||||
|
||||
add wave /testbench/dut/hart/DataStall
|
||||
add wave /testbench/dut/hart/InstrStall
|
||||
add wave /testbench/dut/hart/StallF
|
||||
add wave /testbench/dut/hart/StallD
|
||||
add wave /testbench/dut/hart/StallE
|
||||
add wave /testbench/dut/hart/StallM
|
||||
add wave /testbench/dut/hart/StallW
|
||||
add wave /testbench/dut/hart/FlushD
|
||||
add wave /testbench/dut/hart/FlushE
|
||||
add wave /testbench/dut/hart/FlushM
|
||||
add wave /testbench/dut/hart/FlushW
|
||||
|
||||
add wave -divider
|
||||
|
||||
add wave -hex /testbench/dut/hart/ifu/PCF
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrF
|
||||
add wave /testbench/InstrFName
|
||||
#add wave -hex /testbench/dut/hart/ifu/PCD
|
||||
add wave -hex /testbench/dut/hart/ifu/PCD
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrD
|
||||
add wave /testbench/InstrDName
|
||||
add wave -divider
|
||||
@ -38,6 +39,7 @@ add wave /testbench/InstrEName
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcAE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
|
||||
#add wave /testbench/dut/hart/ieu/dp/PCSrcE
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCM
|
||||
add wave -hex /testbench/dut/hart/ifu/InstrM
|
||||
@ -46,17 +48,27 @@ add wave /testbench/dut/uncore/dtim/memwrite
|
||||
add wave -hex /testbench/dut/uncore/HADDR
|
||||
add wave -hex /testbench/dut/uncore/HWDATA
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/ifu/PCW
|
||||
add wave -hex /testbench/PCW
|
||||
add wave -hex /testbench/InstrW
|
||||
add wave /testbench/InstrWName
|
||||
add wave /testbench/dut/hart/ieu/dp/RegWriteW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/ResultW
|
||||
add wave -hex /testbench/dut/hart/ieu/dp/RdW
|
||||
add wave -divider
|
||||
add wave -divider
|
||||
|
||||
# peripherals
|
||||
add wave -hex /testbench/dut/hart/ebu/*
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/uncore/uart/u/*
|
||||
add wave -divider
|
||||
#add ww
|
||||
add wave -hex /testbench/dut/uncore/plic/*
|
||||
add wave -hex /testbench/dut/uncore/plic/intPriority
|
||||
add wave -hex /testbench/dut/uncore/plic/pendingArray
|
||||
add wave -divider
|
||||
add wave -divider
|
||||
|
||||
# everything else
|
||||
add wave -hex -r /testbench/*
|
||||
|
||||
-- Set Wave Output Items
|
||||
@ -77,4 +89,4 @@ set DefaultRadix hexadecimal
|
||||
run -all
|
||||
#quit
|
||||
noview ../testbench/testbench-peripherals.sv
|
||||
view wave
|
||||
view wave
|
@ -5,9 +5,16 @@
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Platform-Level Interrupt Controller
|
||||
// See FU540-C000-Manual-v1p0 for specifications
|
||||
// *** we might want to add support for FE310-G002-Manual-v19p05 version
|
||||
// Based on RISC-V spec (https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc)
|
||||
// With clarifications from ROA's existing implementation (https://roalogic.github.io/plic/docs/AHB-Lite_PLIC_Datasheet.pdf)
|
||||
// Supports only 1 target core and only a global threshold.
|
||||
//
|
||||
// *** Big questions:
|
||||
// Do we detect requests as level-triggered or edge-trigged?
|
||||
// If edge-triggered, do we want to allow 1 source to be able to make a number of repeated requests?
|
||||
// Should PLIC also output SEIP or just MEIP?
|
||||
// MEIP is the same as ExtIntM, right?
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
@ -32,292 +39,215 @@ module plic (
|
||||
input logic HSELPLIC,
|
||||
input logic [27:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
input logic UARTIntr,
|
||||
output logic [`XLEN-1:0] HREADPLIC,
|
||||
output logic HRESPPLIC, HREADYPLIC);
|
||||
output logic HRESPPLIC, HREADYPLIC,
|
||||
output logic ExtIntM);
|
||||
|
||||
logic memread, memwrite;
|
||||
parameter numSrc = 53;
|
||||
logic [2:0] intPriority [numSrc:1];
|
||||
// N in config should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
|
||||
localparam N=`PLIC_NUM_SRC;
|
||||
|
||||
logic memread, memwrite, initTrans;
|
||||
logic [27:0] entry, A;
|
||||
logic [N:1] requests;
|
||||
|
||||
logic [2:0] intPriority[N:1];
|
||||
logic [2:0] intThreshold;
|
||||
logic [numSrc:1] intPending, intEn;
|
||||
logic [31:0] intClaim;
|
||||
logic [27:0] entry;
|
||||
logic [N:1] intPending, nextIntPending, intEn, intInProgress;
|
||||
logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
|
||||
|
||||
logic [N:1] pendingArray[7:1];
|
||||
logic [7:1] pendingPGrouped;
|
||||
logic [7:1] pendingMaxP;
|
||||
logic [N:1] pendingRequestsAtMaxP;
|
||||
logic [7:1] threshMask;
|
||||
|
||||
// AHB I/O
|
||||
assign memread = HSELPLIC & ~HWRITE;
|
||||
assign memwrite = HSELPLIC & HWRITE;
|
||||
assign initTrans = HREADY & HSELPLIC & (HTRANS != 2'b00);
|
||||
flopenrc #(1) memreadreg(HCLK, ~HRESETn, memread&HREADY, (memread&HREADY)|initTrans, HSELPLIC & ~HWRITE, memread);
|
||||
flopenrc #(1) memwritereg(HCLK, ~HRESETn, memwrite&HREADY, (memwrite&HREADY)|initTrans, HSELPLIC & HWRITE, memwrite);
|
||||
flopenr #(28) haddrreg(HCLK, ~HRESETn,initTrans, HADDR, A);
|
||||
assign HRESPPLIC = 0; // OK
|
||||
assign HREADYPLIC = 1'b1; // will need to be modified if PLIC ever needs more than 1 cycle to do something
|
||||
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
if (`XLEN==64)
|
||||
assign #2 entry = {HADDR[15:3], 3'b000};
|
||||
else
|
||||
assign #2 entry = {HADDR[15:2], 2'b00};
|
||||
endgenerate
|
||||
assign #2 entry = {A[27:2], 2'b00};
|
||||
|
||||
// register access
|
||||
genvar i;
|
||||
generate
|
||||
if (`XLEN==64) begin
|
||||
always @(posedge HCLK) begin
|
||||
// reading
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
|
||||
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
|
||||
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
|
||||
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
|
||||
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
|
||||
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
|
||||
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
|
||||
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
|
||||
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
|
||||
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
|
||||
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
|
||||
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
|
||||
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
|
||||
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
|
||||
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
|
||||
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
|
||||
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
|
||||
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
|
||||
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
|
||||
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
|
||||
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
|
||||
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
|
||||
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
|
||||
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
|
||||
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
|
||||
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
|
||||
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
|
||||
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
|
||||
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
|
||||
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
|
||||
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
|
||||
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
|
||||
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
|
||||
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
|
||||
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
|
||||
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
|
||||
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
|
||||
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
|
||||
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
|
||||
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
|
||||
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
|
||||
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
|
||||
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
|
||||
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
|
||||
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
|
||||
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
|
||||
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
|
||||
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
|
||||
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
|
||||
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
|
||||
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
|
||||
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
|
||||
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
|
||||
// hart 0 configurations
|
||||
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
|
||||
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
|
||||
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
|
||||
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
|
||||
default: HREADPLIC <= 0;
|
||||
endcase
|
||||
// writing
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
|
||||
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
|
||||
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
|
||||
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
|
||||
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
|
||||
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
|
||||
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
|
||||
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
|
||||
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
|
||||
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
|
||||
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
|
||||
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
|
||||
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
|
||||
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
|
||||
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
|
||||
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
|
||||
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
|
||||
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
|
||||
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
|
||||
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
|
||||
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
|
||||
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
|
||||
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
|
||||
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
|
||||
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
|
||||
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
|
||||
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
|
||||
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
|
||||
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
|
||||
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
|
||||
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
|
||||
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
|
||||
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
|
||||
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
|
||||
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
|
||||
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
|
||||
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
|
||||
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
|
||||
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
|
||||
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
|
||||
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
|
||||
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
|
||||
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
|
||||
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
|
||||
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
|
||||
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
|
||||
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
|
||||
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
|
||||
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
|
||||
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
|
||||
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
|
||||
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
|
||||
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
|
||||
// hart 0 configurations
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
|
||||
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
|
||||
endcase
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always @(posedge HCLK) begin
|
||||
// reading
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
|
||||
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
|
||||
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
|
||||
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
|
||||
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
|
||||
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
|
||||
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
|
||||
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
|
||||
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
|
||||
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
|
||||
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
|
||||
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
|
||||
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
|
||||
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
|
||||
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
|
||||
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
|
||||
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
|
||||
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
|
||||
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
|
||||
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
|
||||
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
|
||||
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
|
||||
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
|
||||
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
|
||||
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
|
||||
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
|
||||
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
|
||||
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
|
||||
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
|
||||
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
|
||||
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
|
||||
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
|
||||
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
|
||||
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
|
||||
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
|
||||
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
|
||||
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
|
||||
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
|
||||
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
|
||||
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
|
||||
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
|
||||
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
|
||||
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
|
||||
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
|
||||
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
|
||||
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
|
||||
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
|
||||
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
|
||||
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
|
||||
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
|
||||
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
|
||||
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
|
||||
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
|
||||
// hart 0 configurations
|
||||
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
|
||||
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
|
||||
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
|
||||
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
|
||||
default: HREADPLIC <= 0;
|
||||
endcase
|
||||
// writing
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
|
||||
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
|
||||
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
|
||||
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
|
||||
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
|
||||
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
|
||||
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
|
||||
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
|
||||
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
|
||||
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
|
||||
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
|
||||
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
|
||||
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
|
||||
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
|
||||
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
|
||||
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
|
||||
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
|
||||
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
|
||||
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
|
||||
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
|
||||
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
|
||||
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
|
||||
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
|
||||
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
|
||||
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
|
||||
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
|
||||
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
|
||||
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
|
||||
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
|
||||
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
|
||||
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
|
||||
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
|
||||
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
|
||||
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
|
||||
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
|
||||
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
|
||||
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
|
||||
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
|
||||
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
|
||||
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
|
||||
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
|
||||
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
|
||||
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
|
||||
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
|
||||
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
|
||||
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
|
||||
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
|
||||
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
|
||||
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
|
||||
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
|
||||
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
|
||||
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
|
||||
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
|
||||
// hart 0 configurations
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
|
||||
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
// priority registers
|
||||
for (i=1; i<=N; i=i+1)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intPriority[i] <= 3'b0;
|
||||
else if (entry == 28'hc000000+4*i) // *** make sure this does not synthesize into N 28-bit equality comparators
|
||||
if (memwrite) intPriority[i] <= #1 HWDATA[2:0];
|
||||
else HREADPLIC <= #1 {{(`XLEN-3){1'b0}},intPriority[i]};
|
||||
|
||||
// pending and enable registers
|
||||
if (N<32 && `XLEN==32)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else
|
||||
case(entry)
|
||||
28'hc001000: HREADPLIC <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
|
||||
28'hc002000: if (memwrite) intEn[N:1] <= #1 HWDATA[N:1];
|
||||
else HREADPLIC <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
|
||||
endcase
|
||||
else if (N>=32 && `XLEN==32)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else
|
||||
case(entry)
|
||||
28'hc001000: HREADPLIC <= #1 {intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= #1 {{(63-N){1'b0}},intPending[N:32]};
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= #1 HWDATA[31:1];
|
||||
else HREADPLIC <= #1 {intEn[31:1],1'b0};
|
||||
28'hc002004: if (memwrite) intEn[N:32] <= #1 HWDATA[31:0];
|
||||
else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:32]};
|
||||
endcase
|
||||
else if (N<32 && `XLEN==64)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else
|
||||
case(entry)
|
||||
28'hc001000: HREADPLIC <= #1 {{(63-N){1'b0}},intPending[N:1],1'b0};
|
||||
28'hc002000: if (memwrite) intEn[N:1] <= #1 HWDATA[N:1];
|
||||
else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:1],1'b0};
|
||||
endcase
|
||||
else if (N>=32 && `XLEN==64)
|
||||
always @(posedge HCLK,negedge HRESETn)
|
||||
if (~HRESETn)
|
||||
intEn <= {N{1'b0}};
|
||||
else
|
||||
case(entry)
|
||||
28'hc001000: HREADPLIC <= #1 {32'b0,intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= #1 {{(63-N){1'b0}},intPending[N:32],32'b0}; // rearranged so that you can access it with lw (when addr%8 = 4, subwordwrite thinks we are looking at the upper half of a 64bit word); *** is this reasonable? Why does SWW work like that anyways?; if we don't mind 32 and 64 bit versions having different memory maps, that might clean things up, but it might also be a departure of spec
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= #1 HWDATA[31:1];
|
||||
else HREADPLIC <= #1 {intEn[31:1],1'b0};
|
||||
28'hc002004: if (memwrite) intEn[N:32] <= #1 HWDATA[63:32];
|
||||
else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:32],32'b0};
|
||||
endcase
|
||||
|
||||
// threshold and claim/complete registers
|
||||
if (`XLEN==32)
|
||||
always @(posedge HCLK, negedge HRESETn)
|
||||
if (~HRESETn) begin
|
||||
intThreshold<=3'b0;
|
||||
intInProgress <= {N{1'b0}};
|
||||
end else
|
||||
case (HADDR)
|
||||
28'hc200000: if (memwrite) intThreshold[2:0] <= #1 HWDATA[2:0];
|
||||
else HREADPLIC <= #1 {{29{1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: if (memwrite) intInProgress <= #1 intInProgress & ~(1'b1 << (HWDATA[5:0]-1)); // lower "InProgress" to signify completion
|
||||
else begin
|
||||
HREADPLIC <= #1 {{26{1'b0}},intClaim};
|
||||
intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
endcase
|
||||
else if (`XLEN==64)
|
||||
always @(posedge HCLK, negedge HRESETn)
|
||||
if (~HRESETn) begin
|
||||
intThreshold<=3'b0;
|
||||
intInProgress <= {N{1'b0}};
|
||||
end else
|
||||
case (HADDR)
|
||||
28'hc200000: if (memwrite) intThreshold[2:0] <= #1 HWDATA[2:0];
|
||||
else HREADPLIC <= #1 {{61{1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: if (memwrite) intInProgress <= #1 intInProgress & ~(1'b1 << (HWDATA[5:0]-1)); // lower "InProgress" to signify completion
|
||||
else begin
|
||||
HREADPLIC <= #1 {{26{1'b0}},intClaim,32'b0};
|
||||
intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
|
||||
end
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
// connect sources to requests
|
||||
`ifdef PLIC_UART_ID
|
||||
assign requests[`PLIC_UART_ID] = UARTIntr;
|
||||
`endif
|
||||
// or temporarily connect them to nothing
|
||||
assign requests[3:1] = 3'b0;
|
||||
// pending updates
|
||||
// *** verify that this matches the expectations of the things that make requests (in terms of timing, edge-triggered vs level-triggered)
|
||||
assign nextIntPending = (intPending | (requests & ~intInProgress)) // requests should raise intPending except when their service routine is already in progress
|
||||
& ~((entry == 28'hc200004) << (intClaim-1)); // clear pending bit when claim register is read
|
||||
|
||||
flopr #(N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
|
||||
// pending array - indexed by priority_lvl x source_ID
|
||||
generate
|
||||
for (i=1; i<=N; i=i+1) begin
|
||||
// *** make sure that this synthesizes into N decoders, not 7*N 3-bit equality comparators (right?)
|
||||
assign pendingArray[7][i] = (intPriority[i]==7) & intEn[i] & intPending[i];
|
||||
assign pendingArray[6][i] = (intPriority[i]==6) & intEn[i] & intPending[i];
|
||||
assign pendingArray[5][i] = (intPriority[i]==5) & intEn[i] & intPending[i];
|
||||
assign pendingArray[4][i] = (intPriority[i]==4) & intEn[i] & intPending[i];
|
||||
assign pendingArray[3][i] = (intPriority[i]==3) & intEn[i] & intPending[i];
|
||||
assign pendingArray[2][i] = (intPriority[i]==2) & intEn[i] & intPending[i];
|
||||
assign pendingArray[1][i] = (intPriority[i]==1) & intEn[i] & intPending[i];
|
||||
end
|
||||
endgenerate
|
||||
// pending array, except grouped by priority
|
||||
assign pendingPGrouped[7:1] = {|pendingArray[7],
|
||||
|pendingArray[6],
|
||||
|pendingArray[5],
|
||||
|pendingArray[4],
|
||||
|pendingArray[3],
|
||||
|pendingArray[2],
|
||||
|pendingArray[1]};
|
||||
// pendingPGrouped, except only topmost priority is active
|
||||
assign pendingMaxP[7:1] = {pendingPGrouped[7],
|
||||
pendingPGrouped[6] & ~|pendingPGrouped[7],
|
||||
pendingPGrouped[5] & ~|pendingPGrouped[7:6],
|
||||
pendingPGrouped[4] & ~|pendingPGrouped[7:5],
|
||||
pendingPGrouped[3] & ~|pendingPGrouped[7:4],
|
||||
pendingPGrouped[2] & ~|pendingPGrouped[7:3],
|
||||
pendingPGrouped[1] & ~|pendingPGrouped[7:2]};
|
||||
// select the pending requests at that priority
|
||||
assign pendingRequestsAtMaxP[N:1] = ({N{pendingMaxP[7]}} & pendingArray[7])
|
||||
| ({N{pendingMaxP[6]}} & pendingArray[6])
|
||||
| ({N{pendingMaxP[5]}} & pendingArray[5])
|
||||
| ({N{pendingMaxP[4]}} & pendingArray[4])
|
||||
| ({N{pendingMaxP[3]}} & pendingArray[3])
|
||||
| ({N{pendingMaxP[2]}} & pendingArray[2])
|
||||
| ({N{pendingMaxP[1]}} & pendingArray[1]);
|
||||
// find the lowest ID amongst active interrupts at the highest priority
|
||||
|
||||
integer j;
|
||||
// *** verify that this synthesizes to a reasonable priority encoder and that j doesn't actually exist in hardware
|
||||
always_comb begin
|
||||
intClaim = 6'b0;
|
||||
for(j=N; j>0; j=j-1) begin
|
||||
if(pendingRequestsAtMaxP[j]) intClaim = j;
|
||||
end
|
||||
end
|
||||
|
||||
// create threshold mask
|
||||
// *** I think this commented out version would be nice, but linter complains about circular logic
|
||||
//assign threshMask[7:1] = {~(7==intThreshold),
|
||||
// ~(6==intThreshold) & threshMask[7],
|
||||
// ~(5==intThreshold) & threshMask[6],
|
||||
// ~(4==intThreshold) & threshMask[5],
|
||||
// ~(3==intThreshold) & threshMask[4],
|
||||
// ~(2==intThreshold) & threshMask[3],
|
||||
// ~(1==intThreshold) & threshMask[2]};
|
||||
// *** verify that this alternate version does not synthesize to 7 separate comparators
|
||||
assign threshMask[7:1] = {(7>intThreshold),
|
||||
(6>intThreshold),
|
||||
(5>intThreshold),
|
||||
(4>intThreshold),
|
||||
(3>intThreshold),
|
||||
(2>intThreshold),
|
||||
(1>intThreshold)};
|
||||
// is the max priority > threshold?
|
||||
// *** currently we decode threshold into threshMask and bitwise &, then reductive | ; would it be any better to binary encode maxPriority and ">" with threshold?
|
||||
assign ExtIntM = |(threshMask & pendingPGrouped);
|
||||
endmodule
|
||||
|
||||
|
325
wally-pipelined/src/uncore/plic_temp.sv
Normal file
325
wally-pipelined/src/uncore/plic_temp.sv
Normal file
@ -0,0 +1,325 @@
|
||||
///////////////////////////////////////////
|
||||
// plic_temp.sv
|
||||
//
|
||||
// This was made to provide a register interface to busybear. I think we'll end up replacing it with our more configurable plic.
|
||||
//
|
||||
// Written: bbracker@hmc.edu 18 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Platform-Level Interrupt Controller
|
||||
// See FU540-C000-Manual-v1p0 for specifications
|
||||
// *** we might want to add support for FE310-G002-Manual-v19p05 version
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module plic_temp (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSELPLIC,
|
||||
input logic [27:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
output logic [`XLEN-1:0] HREADPLIC,
|
||||
output logic HRESPPLIC, HREADYPLIC);
|
||||
|
||||
logic memread, memwrite;
|
||||
parameter numSrc = 53;
|
||||
logic [2:0] intPriority [numSrc:1];
|
||||
logic [2:0] intThreshold;
|
||||
logic [numSrc:1] intPending, intEn;
|
||||
logic [31:0] intClaim;
|
||||
logic [27:0] entry;
|
||||
|
||||
// AHB I/O
|
||||
assign memread = HSELPLIC & ~HWRITE;
|
||||
assign memwrite = HSELPLIC & HWRITE;
|
||||
assign HRESPPLIC = 0; // OK
|
||||
assign HREADYPLIC = 1'b1; // will need to be modified if PLIC ever needs more than 1 cycle to do something
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
if (`XLEN==64)
|
||||
assign #2 entry = {HADDR[15:3], 3'b000};
|
||||
else
|
||||
assign #2 entry = {HADDR[15:2], 2'b00};
|
||||
endgenerate
|
||||
|
||||
// register access
|
||||
generate
|
||||
if (`XLEN==64) begin
|
||||
always @(posedge HCLK) begin
|
||||
// reading
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
|
||||
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
|
||||
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
|
||||
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
|
||||
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
|
||||
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
|
||||
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
|
||||
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
|
||||
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
|
||||
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
|
||||
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
|
||||
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
|
||||
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
|
||||
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
|
||||
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
|
||||
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
|
||||
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
|
||||
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
|
||||
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
|
||||
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
|
||||
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
|
||||
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
|
||||
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
|
||||
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
|
||||
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
|
||||
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
|
||||
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
|
||||
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
|
||||
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
|
||||
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
|
||||
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
|
||||
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
|
||||
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
|
||||
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
|
||||
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
|
||||
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
|
||||
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
|
||||
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
|
||||
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
|
||||
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
|
||||
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
|
||||
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
|
||||
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
|
||||
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
|
||||
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
|
||||
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
|
||||
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
|
||||
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
|
||||
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
|
||||
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
|
||||
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
|
||||
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
|
||||
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
|
||||
// hart 0 configurations
|
||||
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
|
||||
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
|
||||
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
|
||||
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
|
||||
default: HREADPLIC <= 0;
|
||||
endcase
|
||||
// writing
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
|
||||
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
|
||||
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
|
||||
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
|
||||
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
|
||||
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
|
||||
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
|
||||
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
|
||||
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
|
||||
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
|
||||
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
|
||||
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
|
||||
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
|
||||
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
|
||||
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
|
||||
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
|
||||
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
|
||||
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
|
||||
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
|
||||
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
|
||||
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
|
||||
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
|
||||
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
|
||||
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
|
||||
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
|
||||
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
|
||||
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
|
||||
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
|
||||
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
|
||||
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
|
||||
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
|
||||
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
|
||||
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
|
||||
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
|
||||
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
|
||||
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
|
||||
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
|
||||
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
|
||||
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
|
||||
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
|
||||
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
|
||||
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
|
||||
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
|
||||
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
|
||||
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
|
||||
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
|
||||
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
|
||||
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
|
||||
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
|
||||
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
|
||||
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
|
||||
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
|
||||
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
|
||||
// hart 0 configurations
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
|
||||
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
|
||||
endcase
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always @(posedge HCLK) begin
|
||||
// reading
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
|
||||
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
|
||||
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
|
||||
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
|
||||
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
|
||||
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
|
||||
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
|
||||
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
|
||||
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
|
||||
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
|
||||
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
|
||||
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
|
||||
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
|
||||
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
|
||||
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
|
||||
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
|
||||
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
|
||||
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
|
||||
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
|
||||
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
|
||||
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
|
||||
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
|
||||
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
|
||||
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
|
||||
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
|
||||
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
|
||||
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
|
||||
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
|
||||
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
|
||||
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
|
||||
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
|
||||
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
|
||||
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
|
||||
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
|
||||
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
|
||||
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
|
||||
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
|
||||
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
|
||||
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
|
||||
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
|
||||
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
|
||||
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
|
||||
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
|
||||
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
|
||||
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
|
||||
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
|
||||
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
|
||||
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
|
||||
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
|
||||
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
|
||||
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
|
||||
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
|
||||
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
|
||||
// hart 0 configurations
|
||||
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
|
||||
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
|
||||
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
|
||||
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
|
||||
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
|
||||
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
|
||||
default: HREADPLIC <= 0;
|
||||
endcase
|
||||
// writing
|
||||
case(entry)
|
||||
// priority assignments
|
||||
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
|
||||
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
|
||||
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
|
||||
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
|
||||
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
|
||||
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
|
||||
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
|
||||
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
|
||||
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
|
||||
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
|
||||
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
|
||||
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
|
||||
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
|
||||
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
|
||||
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
|
||||
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
|
||||
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
|
||||
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
|
||||
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
|
||||
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
|
||||
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
|
||||
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
|
||||
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
|
||||
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
|
||||
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
|
||||
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
|
||||
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
|
||||
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
|
||||
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
|
||||
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
|
||||
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
|
||||
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
|
||||
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
|
||||
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
|
||||
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
|
||||
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
|
||||
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
|
||||
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
|
||||
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
|
||||
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
|
||||
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
|
||||
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
|
||||
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
|
||||
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
|
||||
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
|
||||
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
|
||||
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
|
||||
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
|
||||
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
|
||||
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
|
||||
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
|
||||
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
|
||||
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
|
||||
// hart 0 configurations
|
||||
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
|
||||
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
@ -50,12 +50,12 @@ module uncore (
|
||||
// bus interface
|
||||
output logic DataAccessFaultM,
|
||||
// peripheral pins
|
||||
output logic TimerIntM, SwIntM,
|
||||
output logic TimerIntM, SwIntM, ExtIntM,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||
input logic UARTSin,
|
||||
output logic UARTSout
|
||||
);
|
||||
);
|
||||
|
||||
logic [`XLEN-1:0] HWDATA;
|
||||
logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART;
|
||||
|
@ -60,9 +60,9 @@ module wallypipelinedsoc (
|
||||
// Uncore signals
|
||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||
logic HREADY, HRESP;
|
||||
logic InstrAccessFaultF, DataAccessFaultM;
|
||||
logic TimerIntM, SwIntM; // from CLINT
|
||||
logic ExtIntM = 0; // not yet connected
|
||||
logic InstrAccessFaultF, DataAccessFaultM;
|
||||
logic TimerIntM, SwIntM; // from CLINT
|
||||
logic ExtIntM; // from PLIC
|
||||
logic [2:0] HADDRD;
|
||||
logic [3:0] HSIZED;
|
||||
logic HWRITED;
|
||||
|
@ -1,12 +1,11 @@
|
||||
///////////////////////////////////////////
|
||||
// testbench-peripherals.sv
|
||||
// testbench-imperas.sv
|
||||
//
|
||||
// Written: Ben Bracker (bbracker@hmc.edu) 11 Feb. 2021
|
||||
// Based on: testbench-imperas.sv by David Harris
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Wally Testbench and helper modules
|
||||
// Applies test programs meant to test peripherals
|
||||
// These tests assume the processor itself is already working!
|
||||
// Applies test programs from the Imperas suite
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
@ -28,6 +27,9 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module testbench();
|
||||
parameter DEBUG = 0;
|
||||
parameter TESTSBP = 0;
|
||||
|
||||
logic clk;
|
||||
logic reset;
|
||||
|
||||
@ -38,11 +40,36 @@ module testbench();
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
logic [31:0] InstrW;
|
||||
logic [`XLEN-1:0] meminit;
|
||||
|
||||
string tests[] = '{
|
||||
"peripherals/WALLY-UART", "2000"
|
||||
|
||||
string tests64i[] = {
|
||||
"peripherals/WALLY-PLIC", "2000"
|
||||
//"peripherals/WALLY-UART", "2000"
|
||||
};
|
||||
string tests64ic[] = {
|
||||
};
|
||||
string tests64iNOc[] = {
|
||||
};
|
||||
string tests64m[] = {
|
||||
};
|
||||
string tests64a[] = {
|
||||
};
|
||||
string tests32a[] = {
|
||||
};
|
||||
string tests32m[] = {
|
||||
};
|
||||
string tests32ic[] = {
|
||||
};
|
||||
string tests32iNOc[] = {
|
||||
};
|
||||
string tests32i[] = {
|
||||
};
|
||||
string testsBP64[] = {
|
||||
};
|
||||
string tests64p[] = {
|
||||
};
|
||||
|
||||
string tests[];
|
||||
string ProgramAddrMapFile, ProgramLabelMapFile;
|
||||
logic [`AHBW-1:0] HRDATAEXT;
|
||||
logic HREADYEXT, HRESPEXT;
|
||||
logic [31:0] HADDR;
|
||||
@ -54,11 +81,39 @@ module testbench();
|
||||
logic [1:0] HTRANS;
|
||||
logic HMASTLOCK;
|
||||
logic HCLK, HRESETn;
|
||||
|
||||
logic [`XLEN-1:0] PCW;
|
||||
|
||||
flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
||||
// pick tests based on modes supported
|
||||
// *** actually I no longer support this
|
||||
// would need to put this back in if you wanted to test anything other than rv64i
|
||||
initial begin
|
||||
if (`XLEN == 64) begin // RV64
|
||||
if (TESTSBP) begin
|
||||
tests = testsBP64;
|
||||
end else begin
|
||||
tests = {tests64i};
|
||||
if (`C_SUPPORTED) tests = {tests, tests64ic};
|
||||
else tests = {tests, tests64iNOc};
|
||||
if (`M_SUPPORTED) tests = {tests, tests64m};
|
||||
// if (`F_SUPPORTED) tests = {tests64f, tests};
|
||||
// if (`D_SUPPORTED) tests = {tests64d, tests};
|
||||
if (`A_SUPPORTED) tests = {tests, tests64a};
|
||||
end
|
||||
// tests = {tests64a, tests};
|
||||
tests = {tests, tests64p};
|
||||
end else begin // RV32
|
||||
// *** add the 32 bit bp tests
|
||||
tests = {tests32i};
|
||||
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
|
||||
else tests = {tests, tests32iNOc};
|
||||
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m};
|
||||
// if (`F_SUPPORTED) tests = {tests32f, tests};
|
||||
if (`A_SUPPORTED) tests = {tests, tests32a};
|
||||
end
|
||||
|
||||
// tests = tests64p;
|
||||
end
|
||||
|
||||
|
||||
string signame, memfilename;
|
||||
|
||||
@ -73,15 +128,13 @@ module testbench();
|
||||
assign HRDATAEXT = 0;
|
||||
|
||||
wallypipelinedsoc dut(.*);
|
||||
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
||||
|
||||
// Track names of instructions
|
||||
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
||||
dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
|
||||
dut.hart.ifu.InstrM, InstrW,
|
||||
InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
dut.hart.ifu.ic.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
|
||||
dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName,
|
||||
InstrEName, InstrMName, InstrWName);
|
||||
|
||||
logic [`XLEN-1:0] PCW;
|
||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW);
|
||||
// initialize tests
|
||||
initial
|
||||
begin
|
||||
@ -99,7 +152,10 @@ module testbench();
|
||||
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||
$readmemh(memfilename, dut.imem.RAM);
|
||||
$readmemh(memfilename, dut.uncore.dtim.RAM);
|
||||
reset = 1; # 22; reset = 0;
|
||||
ProgramAddrMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.addr"};
|
||||
ProgramLabelMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.lab"};
|
||||
$display("Read memfile %s", memfilename);
|
||||
reset = 1; # 42; reset = 0;
|
||||
end
|
||||
|
||||
// generate clock to sequence tests
|
||||
@ -172,10 +228,26 @@ module testbench();
|
||||
$readmemh(memfilename, dut.imem.RAM);
|
||||
$readmemh(memfilename, dut.uncore.dtim.RAM);
|
||||
$display("Read memfile %s", memfilename);
|
||||
ProgramAddrMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.addr"};
|
||||
ProgramLabelMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.lab"};
|
||||
reset = 1; # 17; reset = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // always @ (negedge clk)
|
||||
|
||||
// track the current function or global label
|
||||
if (DEBUG == 1) begin : functionRadix
|
||||
function_radix function_radix(.reset(reset),
|
||||
.ProgramAddrMapFile(ProgramAddrMapFile),
|
||||
.ProgramLabelMapFile(ProgramLabelMapFile));
|
||||
end
|
||||
|
||||
// initialize the branch predictor
|
||||
initial begin
|
||||
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.Predictor.DirPredictor.PHT.memory);
|
||||
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.TargetPredictor.memory.memory);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
@ -183,14 +255,16 @@ endmodule
|
||||
|
||||
module instrTrackerTB(
|
||||
input logic clk, reset, FlushE,
|
||||
input logic [31:0] InstrD,
|
||||
input logic [31:0] InstrF, InstrD,
|
||||
input logic [31:0] InstrE, InstrM,
|
||||
output logic [31:0] InstrW,
|
||||
output string InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
input logic [31:0] InstrW,
|
||||
// output logic [31:0] InstrW,
|
||||
output string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// stage Instr to Writeback for visualization
|
||||
//flopr #(32) InstrWReg(clk, reset, InstrM, InstrW);
|
||||
// flopr #(32) InstrWReg(clk, reset, InstrM, InstrW);
|
||||
|
||||
instrNameDecTB fdec(InstrF, InstrFName);
|
||||
instrNameDecTB ddec(InstrD, InstrDName);
|
||||
instrNameDecTB edec(InstrE, InstrEName);
|
||||
instrNameDecTB mdec(InstrM, InstrMName);
|
||||
@ -249,10 +323,18 @@ module instrNameDecTB(
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW";
|
||||
else if (funct7 == 7'b0100000) name = "SUBW";
|
||||
else if (funct7 == 7'b0000001) name = "MULW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_001: if (funct7 == 7'b0000000) name = "SLLW";
|
||||
else if (funct7 == 7'b0000001) name = "DIVW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_001: name = "SLLW";
|
||||
10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW";
|
||||
else if (funct7 == 7'b0100000) name = "SRAW";
|
||||
else if (funct7 == 7'b0000001) name = "DIVUW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_110: if (funct7 == 7'b0000001) name = "REMW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_111: if (funct7 == 7'b0000001) name = "REMUW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD";
|
||||
else if (funct7 == 7'b0000001) name = "MUL";
|
||||
@ -265,10 +347,10 @@ module instrNameDecTB(
|
||||
else if (funct7 == 7'b0000001) name = "MULHSU";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU";
|
||||
else if (funct7 == 7'b0000001) name = "DIV";
|
||||
else if (funct7 == 7'b0000001) name = "MULHU";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR";
|
||||
else if (funct7 == 7'b0000001) name = "MUL";
|
||||
else if (funct7 == 7'b0000001) name = "DIV";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL";
|
||||
else if (funct7 == 7'b0000001) name = "DIVU";
|
||||
@ -301,6 +383,30 @@ module instrNameDecTB(
|
||||
10'b1110011_101: name = "CSRRWI";
|
||||
10'b1110011_110: name = "CSRRSI";
|
||||
10'b1110011_111: name = "CSRRCI";
|
||||
10'b0101111_010: if (funct7[6:2] == 5'b00010) name = "LR.W";
|
||||
else if (funct7[6:2] == 5'b00011) name = "SC.W";
|
||||
else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.W";
|
||||
else if (funct7[6:2] == 5'b00000) name = "AMOADD.W";
|
||||
else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.W";
|
||||
else if (funct7[6:2] == 5'b01100) name = "AMOAND.W";
|
||||
else if (funct7[6:2] == 5'b01000) name = "AMOOR.W";
|
||||
else if (funct7[6:2] == 5'b10000) name = "AMOMIN.W";
|
||||
else if (funct7[6:2] == 5'b10100) name = "AMOMAX.W";
|
||||
else if (funct7[6:2] == 5'b11000) name = "AMOMINU.W";
|
||||
else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.W";
|
||||
else name = "ILLEGAL";
|
||||
10'b0101111_011: if (funct7[6:2] == 5'b00010) name = "LR.D";
|
||||
else if (funct7[6:2] == 5'b00011) name = "SC.D";
|
||||
else if (funct7[6:2] == 5'b00001) name = "AMOSWAP.D";
|
||||
else if (funct7[6:2] == 5'b00000) name = "AMOADD.D";
|
||||
else if (funct7[6:2] == 5'b00100) name = "AMOAXOR.D";
|
||||
else if (funct7[6:2] == 5'b01100) name = "AMOAND.D";
|
||||
else if (funct7[6:2] == 5'b01000) name = "AMOOR.D";
|
||||
else if (funct7[6:2] == 5'b10000) name = "AMOMIN.D";
|
||||
else if (funct7[6:2] == 5'b10100) name = "AMOMAX.D";
|
||||
else if (funct7[6:2] == 5'b11000) name = "AMOMINU.D";
|
||||
else if (funct7[6:2] == 5'b11100) name = "AMOMAXU.D";
|
||||
else name = "ILLEGAL";
|
||||
10'b0001111_???: name = "FENCE";
|
||||
default: name = "ILLEGAL";
|
||||
endcase
|
||||
|
Loading…
Reference in New Issue
Block a user