diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh
index 3a6195985..84a264308 100644
--- a/wally-pipelined/config/busybear/wally-config.vh
+++ b/wally-pipelined/config/busybear/wally-config.vh
@@ -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 */
 
diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh
index 5f0714ae1..798e1cf0a 100644
--- a/wally-pipelined/config/coremark/wally-config.vh
+++ b/wally-pipelined/config/coremark/wally-config.vh
@@ -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
 
diff --git a/wally-pipelined/config/coremark_bare/wally-config.vh b/wally-pipelined/config/coremark_bare/wally-config.vh
index a5e3f097a..9bcbf9855 100644
--- a/wally-pipelined/config/coremark_bare/wally-config.vh
+++ b/wally-pipelined/config/coremark_bare/wally-config.vh
@@ -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 */
diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh
index 0c820d006..e1e955af7 100644
--- a/wally-pipelined/config/rv32ic/wally-config.vh
+++ b/wally-pipelined/config/rv32ic/wally-config.vh
@@ -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 */
 
diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh
index 1288889f2..68ae9dcb5 100644
--- a/wally-pipelined/config/rv64ic/wally-config.vh
+++ b/wally-pipelined/config/rv64ic/wally-config.vh
@@ -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 */
diff --git a/wally-pipelined/config/rv64ic/wally-constants.vh b/wally-pipelined/config/rv64ic/wally-constants.vh
index 55fb4e947..a9041d4da 100644
--- a/wally-pipelined/config/rv64ic/wally-constants.vh
+++ b/wally-pipelined/config/rv64ic/wally-constants.vh
@@ -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
diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh
index a1150f78d..833aba7b9 100644
--- a/wally-pipelined/config/rv64imc/wally-config.vh
+++ b/wally-pipelined/config/rv64imc/wally-config.vh
@@ -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 */
diff --git a/wally-pipelined/regression/sim-peripherals b/wally-pipelined/regression/sim-peripherals
new file mode 100755
index 000000000..2c3a505ca
--- /dev/null
+++ b/wally-pipelined/regression/sim-peripherals
@@ -0,0 +1 @@
+vsim -do wally-peripherals.do
diff --git a/wally-pipelined/regression/wally-peripherals.do b/wally-pipelined/regression/wally-peripherals.do
index ea860b95a..83ad02d0c 100644
--- a/wally-pipelined/regression/wally-peripherals.do
+++ b/wally-pipelined/regression/wally-peripherals.do
@@ -40,4 +40,4 @@ vsim workopt
 
 
 view wave
-do wally-peripherals-signals.do
+do wave-dos/peripheral-waves.do
diff --git a/wally-pipelined/regression/wally-peripherals-signals.do b/wally-pipelined/regression/wave-dos/peripheral-waves.do
similarity index 78%
rename from wally-pipelined/regression/wally-peripherals-signals.do
rename to wally-pipelined/regression/wave-dos/peripheral-waves.do
index 3ce8e8480..c156be930 100644
--- a/wally-pipelined/regression/wally-peripherals-signals.do
+++ b/wally-pipelined/regression/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
\ No newline at end of file
diff --git a/wally-pipelined/src/uncore/plic.sv b/wally-pipelined/src/uncore/plic.sv
index 878f2e92f..3ad9329e7 100644
--- a/wally-pipelined/src/uncore/plic.sv
+++ b/wally-pipelined/src/uncore/plic.sv
@@ -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
 
diff --git a/wally-pipelined/src/uncore/plic_temp.sv b/wally-pipelined/src/uncore/plic_temp.sv
new file mode 100644
index 000000000..ddc322b2c
--- /dev/null
+++ b/wally-pipelined/src/uncore/plic_temp.sv
@@ -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
+
diff --git a/wally-pipelined/src/uncore/uncore.sv b/wally-pipelined/src/uncore/uncore.sv
index 4a432c73c..ea6040e83 100644
--- a/wally-pipelined/src/uncore/uncore.sv
+++ b/wally-pipelined/src/uncore/uncore.sv
@@ -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;
diff --git a/wally-pipelined/src/wally/wallypipelinedsoc.sv b/wally-pipelined/src/wally/wallypipelinedsoc.sv
index 81f0faf40..c91c3494f 100644
--- a/wally-pipelined/src/wally/wallypipelinedsoc.sv
+++ b/wally-pipelined/src/wally/wallypipelinedsoc.sv
@@ -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;
diff --git a/wally-pipelined/testbench/testbench-peripherals.sv b/wally-pipelined/testbench/testbench-peripherals.sv
index 9067fede1..62afc496c 100644
--- a/wally-pipelined/testbench/testbench-peripherals.sv
+++ b/wally-pipelined/testbench/testbench-peripherals.sv
@@ -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