Yee hoo first draft of PLIC plus self-checking tests

This commit is contained in:
bbracker 2021-04-04 06:40:53 -04:00
parent 6b43381c38
commit 31c6b2d01f
15 changed files with 718 additions and 316 deletions

View File

@ -93,6 +93,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 4
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */

View File

@ -90,6 +90,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 4
// Can add PLIC Config here // Can add PLIC Config here
// Num interrupt sources // Num interrupt sources

View File

@ -90,6 +90,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 4
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
/* verilator lint_off ASSIGNDLY */ /* verilator lint_off ASSIGNDLY */

View File

@ -89,6 +89,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 4
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */

View File

@ -90,6 +90,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 4
`define PLIC_UART_ID 4
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
/* verilator lint_off ASSIGNDLY */ /* verilator lint_off ASSIGNDLY */

View File

@ -25,6 +25,10 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // 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) // Virtual Memory Constants (sv39)
`define VPN_BITS 27 `define VPN_BITS 27
`define PPN_BITS 44 `define PPN_BITS 44

View File

@ -90,6 +90,10 @@
// Hardware configuration // Hardware configuration
`define UART_PRESCALE 1 `define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 53
`define PLIC_UART_ID 4
/* verilator lint_off STMTDLY */ /* verilator lint_off STMTDLY */
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
/* verilator lint_off ASSIGNDLY */ /* verilator lint_off ASSIGNDLY */

View File

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

View File

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

View File

@ -10,25 +10,26 @@ restart -f
delete wave /* delete wave /*
view wave view wave
-- display input and output signals as hexidecimal values # general stuff
# Diplays All Signals recursively
add wave /testbench/clk add wave /testbench/clk
add wave /testbench/reset add wave /testbench/reset
add wave -divider add wave -divider
add wave /testbench/dut/hart/DataStall add wave /testbench/dut/hart/DataStall
add wave /testbench/dut/hart/InstrStall add wave /testbench/dut/hart/InstrStall
add wave /testbench/dut/hart/StallF add wave /testbench/dut/hart/StallF
add wave /testbench/dut/hart/StallD 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/FlushD
add wave /testbench/dut/hart/FlushE add wave /testbench/dut/hart/FlushE
add wave /testbench/dut/hart/FlushM add wave /testbench/dut/hart/FlushM
add wave /testbench/dut/hart/FlushW add wave /testbench/dut/hart/FlushW
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/ifu/PCF add wave -hex /testbench/dut/hart/ifu/PCF
add wave -hex /testbench/dut/hart/ifu/InstrF add wave -hex /testbench/dut/hart/ifu/PCD
add wave /testbench/InstrFName
#add wave -hex /testbench/dut/hart/ifu/PCD
add wave -hex /testbench/dut/hart/ifu/InstrD add wave -hex /testbench/dut/hart/ifu/InstrD
add wave /testbench/InstrDName add wave /testbench/InstrDName
add wave -divider 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/SrcAE
add wave -hex /testbench/dut/hart/ieu/dp/SrcBE add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
#add wave /testbench/dut/hart/ieu/dp/PCSrcE
add wave -divider add wave -divider
add wave -hex /testbench/dut/hart/ifu/PCM add wave -hex /testbench/dut/hart/ifu/PCM
add wave -hex /testbench/dut/hart/ifu/InstrM 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/HADDR
add wave -hex /testbench/dut/uncore/HWDATA add wave -hex /testbench/dut/uncore/HWDATA
add wave -divider 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/InstrWName
add wave /testbench/dut/hart/ieu/dp/RegWriteW 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/ResultW
add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider add wave -divider
add wave -divider
# peripherals
add wave -hex /testbench/dut/hart/ebu/* add wave -hex /testbench/dut/hart/ebu/*
add wave -divider add wave -divider
add wave -hex /testbench/dut/uncore/uart/u/* add wave -hex /testbench/dut/uncore/uart/u/*
add wave -divider 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/* add wave -hex -r /testbench/*
-- Set Wave Output Items -- Set Wave Output Items
@ -77,4 +89,4 @@ set DefaultRadix hexadecimal
run -all run -all
#quit #quit
noview ../testbench/testbench-peripherals.sv noview ../testbench/testbench-peripherals.sv
view wave view wave

View File

@ -5,9 +5,16 @@
// Modified: // Modified:
// //
// Purpose: Platform-Level Interrupt Controller // Purpose: Platform-Level Interrupt Controller
// See FU540-C000-Manual-v1p0 for specifications // Based on RISC-V spec (https://github.com/riscv/riscv-plic-spec/blob/master/riscv-plic.adoc)
// *** we might want to add support for FE310-G002-Manual-v19p05 version // 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. // A component of the Wally configurable RISC-V project.
// //
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
@ -32,292 +39,215 @@ module plic (
input logic HSELPLIC, input logic HSELPLIC,
input logic [27:0] HADDR, input logic [27:0] HADDR,
input logic HWRITE, input logic HWRITE,
input logic HREADY,
input logic [1:0] HTRANS,
input logic [`XLEN-1:0] HWDATA, input logic [`XLEN-1:0] HWDATA,
input logic UARTIntr,
output logic [`XLEN-1:0] HREADPLIC, output logic [`XLEN-1:0] HREADPLIC,
output logic HRESPPLIC, HREADYPLIC); output logic HRESPPLIC, HREADYPLIC,
output logic ExtIntM);
logic memread, memwrite; // N in config should not exceed 63; does not inlcude source 0, which does not connect to anything according to spec
parameter numSrc = 53; localparam N=`PLIC_NUM_SRC;
logic [2:0] intPriority [numSrc:1];
logic memread, memwrite, initTrans;
logic [27:0] entry, A;
logic [N:1] requests;
logic [2:0] intPriority[N:1];
logic [2:0] intThreshold; logic [2:0] intThreshold;
logic [numSrc:1] intPending, intEn; logic [N:1] intPending, nextIntPending, intEn, intInProgress;
logic [31:0] intClaim; logic [5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
logic [27:0] entry;
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 // AHB I/O
assign memread = HSELPLIC & ~HWRITE; assign initTrans = HREADY & HSELPLIC & (HTRANS != 2'b00);
assign memwrite = HSELPLIC & HWRITE; 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 HRESPPLIC = 0; // OK
assign HREADYPLIC = 1'b1; // will need to be modified if PLIC ever needs more than 1 cycle to do something assign HREADYPLIC = 1'b1; // will need to be modified if PLIC ever needs more than 1 cycle to do something
// word aligned reads // word aligned reads
generate assign #2 entry = {A[27:2], 2'b00};
if (`XLEN==64)
assign #2 entry = {HADDR[15:3], 3'b000};
else
assign #2 entry = {HADDR[15:2], 2'b00};
endgenerate
// register access // register access
genvar i;
generate generate
if (`XLEN==64) begin // priority registers
always @(posedge HCLK) begin for (i=1; i<=N; i=i+1)
// reading always @(posedge HCLK,negedge HRESETn)
case(entry) if (~HRESETn)
// priority assignments intPriority[i] <= 3'b0;
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]}; else if (entry == 28'hc000000+4*i) // *** make sure this does not synthesize into N 28-bit equality comparators
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]}; if (memwrite) intPriority[i] <= #1 HWDATA[2:0];
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]}; else HREADPLIC <= #1 {{(`XLEN-3){1'b0}},intPriority[i]};
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]}; // pending and enable registers
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]}; if (N<32 && `XLEN==32)
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]}; always @(posedge HCLK,negedge HRESETn)
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]}; if (~HRESETn)
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]}; intEn <= {N{1'b0}};
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]}; else
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]}; case(entry)
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]}; 28'hc001000: HREADPLIC <= #1 {{(31-N){1'b0}},intPending[N:1],1'b0};
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]}; 28'hc002000: if (memwrite) intEn[N:1] <= #1 HWDATA[N:1];
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]}; else HREADPLIC <= #1 {{(31-N){1'b0}},intEn[N:1],1'b0};
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]}; endcase
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]}; else if (N>=32 && `XLEN==32)
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]}; always @(posedge HCLK,negedge HRESETn)
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]}; if (~HRESETn)
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]}; intEn <= {N{1'b0}};
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]}; else
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]}; case(entry)
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]}; 28'hc001000: HREADPLIC <= #1 {intPending[31:1],1'b0};
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]}; 28'hc001004: HREADPLIC <= #1 {{(63-N){1'b0}},intPending[N:32]};
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]}; 28'hc002000: if (memwrite) intEn[31:1] <= #1 HWDATA[31:1];
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]}; else HREADPLIC <= #1 {intEn[31:1],1'b0};
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]}; 28'hc002004: if (memwrite) intEn[N:32] <= #1 HWDATA[31:0];
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]}; else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:32]};
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]}; endcase
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]}; else if (N<32 && `XLEN==64)
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]}; always @(posedge HCLK,negedge HRESETn)
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]}; if (~HRESETn)
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]}; intEn <= {N{1'b0}};
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]}; else
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]}; case(entry)
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]}; 28'hc001000: HREADPLIC <= #1 {{(63-N){1'b0}},intPending[N:1],1'b0};
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]}; 28'hc002000: if (memwrite) intEn[N:1] <= #1 HWDATA[N:1];
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]}; else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:1],1'b0};
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]}; endcase
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]}; else if (N>=32 && `XLEN==64)
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]}; always @(posedge HCLK,negedge HRESETn)
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]}; if (~HRESETn)
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]}; intEn <= {N{1'b0}};
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]}; else
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]}; case(entry)
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]}; 28'hc001000: HREADPLIC <= #1 {32'b0,intPending[31:1],1'b0};
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]}; 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'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]}; 28'hc002000: if (memwrite) intEn[31:1] <= #1 HWDATA[31:1];
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]}; else HREADPLIC <= #1 {intEn[31:1],1'b0};
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]}; 28'hc002004: if (memwrite) intEn[N:32] <= #1 HWDATA[63:32];
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]}; else HREADPLIC <= #1 {{(63-N){1'b0}},intEn[N:32],32'b0};
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]}; endcase
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]}; // threshold and claim/complete registers
// hart 0 configurations if (`XLEN==32)
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0}; always @(posedge HCLK, negedge HRESETn)
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]}; if (~HRESETn) begin
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0}; intThreshold<=3'b0;
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]}; intInProgress <= {N{1'b0}};
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]}; end else
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]}; case (HADDR)
default: HREADPLIC <= 0; 28'hc200000: if (memwrite) intThreshold[2:0] <= #1 HWDATA[2:0];
endcase else HREADPLIC <= #1 {{29{1'b0}},intThreshold[2:0]};
// writing 28'hc200004: if (memwrite) intInProgress <= #1 intInProgress & ~(1'b1 << (HWDATA[5:0]-1)); // lower "InProgress" to signify completion
case(entry) else begin
// priority assignments HREADPLIC <= #1 {{26{1'b0}},intClaim};
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0]; intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0]; end
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0]; endcase
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0]; else if (`XLEN==64)
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0]; always @(posedge HCLK, negedge HRESETn)
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0]; if (~HRESETn) begin
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0]; intThreshold<=3'b0;
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0]; intInProgress <= {N{1'b0}};
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0]; end else
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0]; case (HADDR)
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0]; 28'hc200000: if (memwrite) intThreshold[2:0] <= #1 HWDATA[2:0];
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0]; else HREADPLIC <= #1 {{61{1'b0}},intThreshold[2:0]};
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0]; 28'hc200004: if (memwrite) intInProgress <= #1 intInProgress & ~(1'b1 << (HWDATA[5:0]-1)); // lower "InProgress" to signify completion
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0]; else begin
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0]; HREADPLIC <= #1 {{26{1'b0}},intClaim,32'b0};
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0]; intInProgress <= #1 intInProgress | (1'b1 << (intClaim-1)); // claimed requests are currently in progress of being serviced until they are completed
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0]; end
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0]; endcase
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 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 endmodule

View File

@ -0,0 +1,325 @@
///////////////////////////////////////////
// plic_temp.sv
//
// This was made to provide a register interface to busybear. I think we'll end up replacing it with our more configurable plic.
//
// Written: bbracker@hmc.edu 18 January 2021
// Modified:
//
// Purpose: Platform-Level Interrupt Controller
// See FU540-C000-Manual-v1p0 for specifications
// *** we might want to add support for FE310-G002-Manual-v19p05 version
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module plic_temp (
input logic HCLK, HRESETn,
input logic HSELPLIC,
input logic [27:0] HADDR,
input logic HWRITE,
input logic [`XLEN-1:0] HWDATA,
output logic [`XLEN-1:0] HREADPLIC,
output logic HRESPPLIC, HREADYPLIC);
logic memread, memwrite;
parameter numSrc = 53;
logic [2:0] intPriority [numSrc:1];
logic [2:0] intThreshold;
logic [numSrc:1] intPending, intEn;
logic [31:0] intClaim;
logic [27:0] entry;
// AHB I/O
assign memread = HSELPLIC & ~HWRITE;
assign memwrite = HSELPLIC & HWRITE;
assign HRESPPLIC = 0; // OK
assign HREADYPLIC = 1'b1; // will need to be modified if PLIC ever needs more than 1 cycle to do something
// word aligned reads
generate
if (`XLEN==64)
assign #2 entry = {HADDR[15:3], 3'b000};
else
assign #2 entry = {HADDR[15:2], 2'b00};
endgenerate
// register access
generate
if (`XLEN==64) begin
always @(posedge HCLK) begin
// reading
case(entry)
// priority assignments
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
// hart 0 configurations
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
default: HREADPLIC <= 0;
endcase
// writing
case(entry)
// priority assignments
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
// hart 0 configurations
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
endcase
end
end else begin // 32-bit
always @(posedge HCLK) begin
// reading
case(entry)
// priority assignments
28'hc000004: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[1]};
28'hc000008: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[2]};
28'hc00000c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[3]};
28'hc000010: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[4]};
28'hc000014: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[5]};
28'hc000018: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[6]};
28'hc00001c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[7]};
28'hc000020: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[8]};
28'hc000024: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[9]};
28'hc000028: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[10]};
28'hc00002c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[11]};
28'hc000030: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[12]};
28'hc000034: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[13]};
28'hc000038: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[14]};
28'hc00003c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[15]};
28'hc000040: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[16]};
28'hc000044: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[17]};
28'hc000048: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[18]};
28'hc00004c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[19]};
28'hc000050: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[20]};
28'hc000054: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[21]};
28'hc000058: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[22]};
28'hc00005c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[23]};
28'hc000060: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[24]};
28'hc000064: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[25]};
28'hc000068: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[26]};
28'hc00006c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[27]};
28'hc000070: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[28]};
28'hc000074: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[29]};
28'hc000078: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[30]};
28'hc00007c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[31]};
28'hc000080: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[32]};
28'hc000084: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[33]};
28'hc000088: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[34]};
28'hc00008c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[35]};
28'hc000090: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[36]};
28'hc000094: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[37]};
28'hc000098: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[38]};
28'hc00009c: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[39]};
28'hc0000a0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[40]};
28'hc0000a4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[41]};
28'hc0000a8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[42]};
28'hc0000ac: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[43]};
28'hc0000b0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[44]};
28'hc0000b4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[45]};
28'hc0000b8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[46]};
28'hc0000bc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[47]};
28'hc0000c0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[48]};
28'hc0000c4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[49]};
28'hc0000c8: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[50]};
28'hc0000cc: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[51]};
28'hc0000d0: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[52]};
28'hc0000d4: HREADPLIC <= {{(`XLEN-3){1'b0}},intPriority[53]};
// hart 0 configurations
28'hc001000: HREADPLIC <= {{(`XLEN-32){1'b0}},intPending[31:1],1'b0};
28'hc001004: HREADPLIC <= {{(`XLEN-22){1'b0}},intPending[53:32]};
28'hc002000: HREADPLIC <= {{(`XLEN-32){1'b0}},intEn[31:1],1'b0};
28'hc002004: HREADPLIC <= {{(`XLEN-22){1'b0}},intEn[53:32]};
28'hc200000: HREADPLIC <= {{(`XLEN-3){1'b0}},intThreshold[2:0]};
28'hc200004: HREADPLIC <= {{(`XLEN-32){1'b0}},intClaim[31:0]};
default: HREADPLIC <= 0;
endcase
// writing
case(entry)
// priority assignments
28'hc000004: if (memwrite) intPriority[1] <= HWDATA[2:0];
28'hc000008: if (memwrite) intPriority[2] <= HWDATA[2:0];
28'hc00000c: if (memwrite) intPriority[3] <= HWDATA[2:0];
28'hc000010: if (memwrite) intPriority[4] <= HWDATA[2:0];
28'hc000014: if (memwrite) intPriority[5] <= HWDATA[2:0];
28'hc000018: if (memwrite) intPriority[6] <= HWDATA[2:0];
28'hc00001c: if (memwrite) intPriority[7] <= HWDATA[2:0];
28'hc000020: if (memwrite) intPriority[8] <= HWDATA[2:0];
28'hc000024: if (memwrite) intPriority[9] <= HWDATA[2:0];
28'hc000028: if (memwrite) intPriority[10] <= HWDATA[2:0];
28'hc00002c: if (memwrite) intPriority[11] <= HWDATA[2:0];
28'hc000030: if (memwrite) intPriority[12] <= HWDATA[2:0];
28'hc000034: if (memwrite) intPriority[13] <= HWDATA[2:0];
28'hc000038: if (memwrite) intPriority[14] <= HWDATA[2:0];
28'hc00003c: if (memwrite) intPriority[15] <= HWDATA[2:0];
28'hc000040: if (memwrite) intPriority[16] <= HWDATA[2:0];
28'hc000044: if (memwrite) intPriority[17] <= HWDATA[2:0];
28'hc000048: if (memwrite) intPriority[18] <= HWDATA[2:0];
28'hc00004c: if (memwrite) intPriority[19] <= HWDATA[2:0];
28'hc000050: if (memwrite) intPriority[20] <= HWDATA[2:0];
28'hc000054: if (memwrite) intPriority[21] <= HWDATA[2:0];
28'hc000058: if (memwrite) intPriority[22] <= HWDATA[2:0];
28'hc00005c: if (memwrite) intPriority[23] <= HWDATA[2:0];
28'hc000060: if (memwrite) intPriority[24] <= HWDATA[2:0];
28'hc000064: if (memwrite) intPriority[25] <= HWDATA[2:0];
28'hc000068: if (memwrite) intPriority[26] <= HWDATA[2:0];
28'hc00006c: if (memwrite) intPriority[27] <= HWDATA[2:0];
28'hc000070: if (memwrite) intPriority[28] <= HWDATA[2:0];
28'hc000074: if (memwrite) intPriority[29] <= HWDATA[2:0];
28'hc000078: if (memwrite) intPriority[30] <= HWDATA[2:0];
28'hc00007c: if (memwrite) intPriority[31] <= HWDATA[2:0];
28'hc000080: if (memwrite) intPriority[32] <= HWDATA[2:0];
28'hc000084: if (memwrite) intPriority[33] <= HWDATA[2:0];
28'hc000088: if (memwrite) intPriority[34] <= HWDATA[2:0];
28'hc00008c: if (memwrite) intPriority[35] <= HWDATA[2:0];
28'hc000090: if (memwrite) intPriority[36] <= HWDATA[2:0];
28'hc000094: if (memwrite) intPriority[37] <= HWDATA[2:0];
28'hc000098: if (memwrite) intPriority[38] <= HWDATA[2:0];
28'hc00009c: if (memwrite) intPriority[39] <= HWDATA[2:0];
28'hc0000a0: if (memwrite) intPriority[40] <= HWDATA[2:0];
28'hc0000a4: if (memwrite) intPriority[41] <= HWDATA[2:0];
28'hc0000a8: if (memwrite) intPriority[42] <= HWDATA[2:0];
28'hc0000ac: if (memwrite) intPriority[43] <= HWDATA[2:0];
28'hc0000b0: if (memwrite) intPriority[44] <= HWDATA[2:0];
28'hc0000b4: if (memwrite) intPriority[45] <= HWDATA[2:0];
28'hc0000b8: if (memwrite) intPriority[46] <= HWDATA[2:0];
28'hc0000bc: if (memwrite) intPriority[47] <= HWDATA[2:0];
28'hc0000c0: if (memwrite) intPriority[48] <= HWDATA[2:0];
28'hc0000c4: if (memwrite) intPriority[49] <= HWDATA[2:0];
28'hc0000c8: if (memwrite) intPriority[50] <= HWDATA[2:0];
28'hc0000cc: if (memwrite) intPriority[51] <= HWDATA[2:0];
28'hc0000d0: if (memwrite) intPriority[52] <= HWDATA[2:0];
28'hc0000d4: if (memwrite) intPriority[53] <= HWDATA[2:0];
// hart 0 configurations
28'hc002000: if (memwrite) intEn[31:1] <= HWDATA[31:1];
28'hc002004: if (memwrite) intEn[53:32] <= HWDATA[22:0];
endcase
end
end
endgenerate
endmodule

View File

@ -50,12 +50,12 @@ module uncore (
// bus interface // bus interface
output logic DataAccessFaultM, output logic DataAccessFaultM,
// peripheral pins // peripheral pins
output logic TimerIntM, SwIntM, output logic TimerIntM, SwIntM, ExtIntM,
input logic [31:0] GPIOPinsIn, input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn, output logic [31:0] GPIOPinsOut, GPIOPinsEn,
input logic UARTSin, input logic UARTSin,
output logic UARTSout output logic UARTSout
); );
logic [`XLEN-1:0] HWDATA; logic [`XLEN-1:0] HWDATA;
logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART; logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART;

View File

@ -60,9 +60,9 @@ module wallypipelinedsoc (
// Uncore signals // Uncore signals
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
logic HREADY, HRESP; logic HREADY, HRESP;
logic InstrAccessFaultF, DataAccessFaultM; logic InstrAccessFaultF, DataAccessFaultM;
logic TimerIntM, SwIntM; // from CLINT logic TimerIntM, SwIntM; // from CLINT
logic ExtIntM = 0; // not yet connected logic ExtIntM; // from PLIC
logic [2:0] HADDRD; logic [2:0] HADDRD;
logic [3:0] HSIZED; logic [3:0] HSIZED;
logic HWRITED; logic HWRITED;

View File

@ -1,12 +1,11 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// testbench-peripherals.sv // testbench-imperas.sv
// //
// Written: Ben Bracker (bbracker@hmc.edu) 11 Feb. 2021 // Written: David_Harris@hmc.edu 9 January 2021
// Based on: testbench-imperas.sv by David Harris // Modified:
// //
// Purpose: Wally Testbench and helper modules // Purpose: Wally Testbench and helper modules
// Applies test programs meant to test peripherals // Applies test programs from the Imperas suite
// These tests assume the processor itself is already working!
// //
// A component of the Wally configurable RISC-V project. // A component of the Wally configurable RISC-V project.
// //
@ -28,6 +27,9 @@
`include "wally-config.vh" `include "wally-config.vh"
module testbench(); module testbench();
parameter DEBUG = 0;
parameter TESTSBP = 0;
logic clk; logic clk;
logic reset; logic reset;
@ -38,11 +40,36 @@ module testbench();
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW; logic [31:0] InstrW;
logic [`XLEN-1:0] meminit; logic [`XLEN-1:0] meminit;
string tests[] = '{ string tests64i[] = {
"peripherals/WALLY-UART", "2000" "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 [`AHBW-1:0] HRDATAEXT;
logic HREADYEXT, HRESPEXT; logic HREADYEXT, HRESPEXT;
logic [31:0] HADDR; logic [31:0] HADDR;
@ -54,11 +81,39 @@ module testbench();
logic [1:0] HTRANS; logic [1:0] HTRANS;
logic HMASTLOCK; logic HMASTLOCK;
logic HCLK, HRESETn; 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 // pick tests based on modes supported
// *** actually I no longer support this initial begin
// would need to put this back in if you wanted to test anything other than rv64i 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; string signame, memfilename;
@ -73,15 +128,13 @@ module testbench();
assign HRDATAEXT = 0; assign HRDATAEXT = 0;
wallypipelinedsoc dut(.*); wallypipelinedsoc dut(.*);
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
// Track names of instructions // Track names of instructions
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE, instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
dut.hart.ifu.InstrD, dut.hart.ifu.InstrE, dut.hart.ifu.ic.InstrF, dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
dut.hart.ifu.InstrM, InstrW, dut.hart.ifu.InstrM, InstrW, InstrFName, InstrDName,
InstrDName, InstrEName, InstrMName, InstrWName); InstrEName, InstrMName, InstrWName);
logic [`XLEN-1:0] PCW;
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, dut.hart.ifu.PCM, PCW);
// initialize tests // initialize tests
initial initial
begin begin
@ -99,7 +152,10 @@ module testbench();
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.imem.RAM); $readmemh(memfilename, dut.imem.RAM);
$readmemh(memfilename, dut.uncore.dtim.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 end
// generate clock to sequence tests // generate clock to sequence tests
@ -172,10 +228,26 @@ module testbench();
$readmemh(memfilename, dut.imem.RAM); $readmemh(memfilename, dut.imem.RAM);
$readmemh(memfilename, dut.uncore.dtim.RAM); $readmemh(memfilename, dut.uncore.dtim.RAM);
$display("Read memfile %s", memfilename); $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; reset = 1; # 17; reset = 0;
end end
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 endmodule
/* verilator lint_on STMTDLY */ /* verilator lint_on STMTDLY */
@ -183,14 +255,16 @@ endmodule
module instrTrackerTB( module instrTrackerTB(
input logic clk, reset, FlushE, input logic clk, reset, FlushE,
input logic [31:0] InstrD, input logic [31:0] InstrF, InstrD,
input logic [31:0] InstrE, InstrM, input logic [31:0] InstrE, InstrM,
output logic [31:0] InstrW, input logic [31:0] InstrW,
output string InstrDName, InstrEName, InstrMName, InstrWName); // output logic [31:0] InstrW,
output string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
// stage Instr to Writeback for visualization // 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 ddec(InstrD, InstrDName);
instrNameDecTB edec(InstrE, InstrEName); instrNameDecTB edec(InstrE, InstrEName);
instrNameDecTB mdec(InstrM, InstrMName); instrNameDecTB mdec(InstrM, InstrMName);
@ -249,10 +323,18 @@ module instrNameDecTB(
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW";
else if (funct7 == 7'b0100000) name = "SUBW"; 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"; else name = "ILLEGAL";
10'b0111011_001: name = "SLLW";
10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW";
else if (funct7 == 7'b0100000) name = "SRAW"; 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"; else name = "ILLEGAL";
10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD";
else if (funct7 == 7'b0000001) name = "MUL"; else if (funct7 == 7'b0000001) name = "MUL";
@ -265,10 +347,10 @@ module instrNameDecTB(
else if (funct7 == 7'b0000001) name = "MULHSU"; else if (funct7 == 7'b0000001) name = "MULHSU";
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU"; 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"; else name = "ILLEGAL";
10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR"; 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"; else name = "ILLEGAL";
10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL"; 10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL";
else if (funct7 == 7'b0000001) name = "DIVU"; else if (funct7 == 7'b0000001) name = "DIVU";
@ -301,6 +383,30 @@ module instrNameDecTB(
10'b1110011_101: name = "CSRRWI"; 10'b1110011_101: name = "CSRRWI";
10'b1110011_110: name = "CSRRSI"; 10'b1110011_110: name = "CSRRSI";
10'b1110011_111: name = "CSRRCI"; 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"; 10'b0001111_???: name = "FENCE";
default: name = "ILLEGAL"; default: name = "ILLEGAL";
endcase endcase