Yee hoo first draft of PLIC plus self-checking tests

This commit is contained in:
bbracker 2021-04-04 06:40:53 -04:00
parent 5946b860ca
commit ce7b2314ef
15 changed files with 718 additions and 316 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
vsim -do wally-peripherals.do

View File

@ -40,4 +40,4 @@ vsim workopt
view wave
do wally-peripherals-signals.do
do wave-dos/peripheral-waves.do

View File

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

View File

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

View 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

View File

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

View File

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

View File

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