diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh index 3a619598..84a26430 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 5f0714ae..798e1cf0 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 a5e3f097..9bcbf985 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 0c820d00..e1e955af 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 1288889f..68ae9dcb 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 55fb4e94..a9041d4d 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 a1150f78..833aba7b 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 00000000..2c3a505c --- /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 ea860b95..83ad02d0 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 3ce8e848..c156be93 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 878f2e92..3ad9329e 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 00000000..ddc322b2 --- /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 4a432c73..ea6040e8 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 81f0faf4..c91c3494 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 9067fede..62afc496 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