From caff6e788c7c6b24e6ff34b974a434e1d3e5e925 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 17 Jan 2023 15:39:34 -0600 Subject: [PATCH 1/2] Somehow the imperas files spilled into the main branch. --- .../regression/wally-pipelined-imperas.do | 45 ---- pipelined/testbench/common/rvvitrace.sv | 251 ------------------ pipelined/testbench/testbench.sv | 52 ---- 3 files changed, 348 deletions(-) delete mode 100644 pipelined/regression/wally-pipelined-imperas.do delete mode 100644 pipelined/testbench/common/rvvitrace.sv diff --git a/pipelined/regression/wally-pipelined-imperas.do b/pipelined/regression/wally-pipelined-imperas.do deleted file mode 100644 index 285d013f..00000000 --- a/pipelined/regression/wally-pipelined-imperas.do +++ /dev/null @@ -1,45 +0,0 @@ -# wally-pipelined.do -# -# Modification by Oklahoma State University & Harvey Mudd College -# Use with Testbench -# James Stine, 2008; David Harris 2021 -# Go Cowboys!!!!!! -# -# Takes 1:10 to run RV64IC tests using gui - -# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m" - -# Use this wally-pipelined.do file to run this example. -# Either bring up ModelSim and type the following at the "ModelSim>" prompt: -# do wally-pipelined.do -# or, to run from a shell, type the following at the shell prompt: -# vsim -do wally-pipelined.do -c -# (omit the "-c" to see the GUI while running from the shell) - -onbreak {resume} - -# create library -if [file exists work] { - vdel -all -} -vlib work - -# compile source files -# suppress spurious warnngs about -# "Extra checking for conflicts with always_comb done at vopt time" -# because vsim will run vopt - -# start and run simulation -# remove +acc flag for faster sim during regressions if there is no need to access internal signals - # *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings. -vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench_imperas.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063 -vopt +acc work.testbench -G DEBUG=1 -o workopt -vsim workopt +nowarn3829 -fatal 7 -view wave -#-- display input and output signals as hexidecimal values -add log -recursive /* -do wave.do - -run -all -noview ../testbench/testbench_imperas.sv -view wave diff --git a/pipelined/testbench/common/rvvitrace.sv b/pipelined/testbench/common/rvvitrace.sv deleted file mode 100644 index cc564d38..00000000 --- a/pipelined/testbench/common/rvvitrace.sv +++ /dev/null @@ -1,251 +0,0 @@ -`include "wally-config.vh" - -`define NUM_REGS 32 -`define NUM_CSRS 4096 - -`define PRINT_PC_INSTR 1 -`define PRINT_MOST 1 -`define PRINT_ALL 0 - -module rvviTrace #( - parameter int ILEN = `XLEN, // Instruction length in bits - parameter int XLEN = `XLEN, // GPR length in bits - parameter int FLEN = `FLEN, // FPR length in bits - parameter int VLEN = 0, // Vector register size in bits - parameter int NHART = 1, // Number of harts reported - parameter int RETIRE = 1) // Number of instructions that can retire during valid event - (); - - localparam NUMREGS = `E_SUPPORTED ? 16 : 32; - - // wally specific signals - logic reset; - - logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM, PCW; - logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; - logic InstrValidM, InstrValidW; - logic StallE, StallM, StallW; - logic FlushD, FlushE, FlushM, FlushW; - logic TrapM, TrapW; - logic IntrF, IntrD, IntrE, IntrM, IntrW; - logic HaltM, HaltW; - logic [1:0] PrivilegeModeW; - logic [`XLEN-1:0] rf[NUMREGS]; - logic [NUMREGS-1:0] rf_wb; - logic [4:0] rf_a3; - logic rf_we3; - logic [`XLEN-1:0] frf[32]; - logic [`NUM_REGS-1:0] frf_wb; - logic [4:0] frf_a4; - logic frf_we4; - logic [`XLEN-1:0] CSRArray [logic[11:0]]; - logic CSRWriteM, CSRWriteW; - logic [11:0] CSRAdrM, CSRAdrW; - - // tracer signals - logic clk; - logic valid; - logic [63:0] order [(NHART-1):0][(RETIRE-1):0]; - logic [ILEN-1:0] insn [(NHART-1):0][(RETIRE-1):0]; - logic intr [(NHART-1):0][(RETIRE-1):0]; - logic [(XLEN-1):0] pc_rdata [(NHART-1):0][(RETIRE-1):0]; - logic [(XLEN-1):0] pc_wdata [(NHART-1):0][(RETIRE-1):0]; - logic trap [(NHART-1):0][(RETIRE-1):0]; - logic halt [(NHART-1):0][(RETIRE-1):0]; - logic [1:0] mode [(NHART-1):0][(RETIRE-1):0]; - logic [1:0] ixl [(NHART-1):0][(RETIRE-1):0]; - logic [`NUM_REGS-1:0][(XLEN-1):0] x_wdata [(NHART-1):0][(RETIRE-1):0]; - logic [`NUM_REGS-1:0] x_wb [(NHART-1):0][(RETIRE-1):0]; - logic [`NUM_REGS-1:0][(XLEN-1):0] f_wdata [(NHART-1):0][(RETIRE-1):0]; - logic [`NUM_REGS-1:0] f_wb [(NHART-1):0][(RETIRE-1):0]; - logic [4095:0][(XLEN-1):0] csr [(NHART-1):0][(RETIRE-1):0]; - logic [4095:0] csr_wb [(NHART-1):0][(RETIRE-1):0]; - logic lrsc_cancel[(NHART-1):0][(RETIRE-1):0]; - - assign clk = testbench.dut.clk; - // assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet - assign InstrValidD = testbench.dut.core.ieu.c.InstrValidD; - assign InstrValidE = testbench.dut.core.ieu.c.InstrValidE; - assign InstrValidM = testbench.dut.core.ieu.InstrValidM; - assign InstrRawD = testbench.dut.core.ifu.InstrRawD; - assign PCNextF = testbench.dut.core.ifu.PCNextF; - assign PCF = testbench.dut.core.ifu.PCF; - assign PCD = testbench.dut.core.ifu.PCD; - assign PCE = testbench.dut.core.ifu.PCE; - assign PCM = testbench.dut.core.ifu.PCM; - assign reset = testbench.reset; - assign StallE = testbench.dut.core.StallE; - assign StallM = testbench.dut.core.StallM; - assign StallW = testbench.dut.core.StallW; - assign FlushD = testbench.dut.core.FlushD; - assign FlushE = testbench.dut.core.FlushE; - assign FlushM = testbench.dut.core.FlushM; - assign FlushW = testbench.dut.core.FlushW; - assign TrapM = testbench.dut.core.TrapM; - assign HaltM = testbench.DCacheFlushStart; - assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW; - assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL; - assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; - - always_comb begin - // machine CSRs - // *** missing PMP and performance counters. - CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW; - CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; - CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW; - CSRArray[12'h341] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW; - CSRArray[12'h306] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; - CSRArray[12'h320] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; - CSRArray[12'h302] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW; - CSRArray[12'h303] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; - CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW; - CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW; - CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW; - CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW; - CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; - CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW; - CSRArray[12'h343] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW; - CSRArray[12'hF11] = 0; - CSRArray[12'hF12] = 0; - CSRArray[12'hF13] = `XLEN'h100; - CSRArray[12'hF15] = 0; - CSRArray[12'h34A] = 0; - // MCYCLE and MINSTRET - CSRArray[12'hB00] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - CSRArray[12'hB02] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - // supervisor CSRs - CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.SSTATUS_REGW; - CSRArray[12'h104] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; - CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.STVEC_REGW; - CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.SEPC_REGW; - CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.SCOUNTEREN_REGW; - CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.SATP_REGW; - CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; - CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; - CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; - CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; - // user CSRs - CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; - CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.FRM_REGW; - CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; - end - - genvar index; - assign rf[0] = '0; - for(index = 1; index < NUMREGS; index += 1) - assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index]; - - assign rf_a3 = testbench.dut.core.ieu.dp.regf.a3; - assign rf_we3 = testbench.dut.core.ieu.dp.regf.we3; - - always_comb begin - rf_wb <= '0; - if(rf_we3) - rf_wb[rf_a3] <= 1'b1; - end - - for(index = 0; index < NUMREGS; index += 1) - assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index]; - - assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4; - assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4; - - always_comb begin - frf_wb <= '0; - if(frf_we4) - frf_wb[frf_a4] <= 1'b1; - end - - assign CSRAdrM = testbench.dut.core.priv.priv.csr.CSRAdrM; - assign CSRWriteM = testbench.dut.core.priv.priv.csr.CSRWriteM; - - // pipeline to writeback stage - flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE); - flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM); - flopenrc #(`XLEN) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW); - flopenrc #(`XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW); - flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); - flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); - flopenrc #(1) HaltWReg (clk, reset, 1'b0, ~StallW, HaltM, HaltW); - - flopenrc #(1) IntrFReg (clk, reset, 1'b0, ~StallF, TrapM, IntrF); - flopenrc #(1) IntrDReg (clk, reset, FlushD, ~StallD, IntrF, IntrD); - flopenrc #(1) IntrEReg (clk, reset, FlushE, ~StallE, IntrD, IntrE); - flopenrc #(1) IntrMReg (clk, reset, FlushM, ~StallM, IntrE, IntrM); - flopenrc #(1) IntrWReg (clk, reset, FlushW, ~StallW, IntrM, IntrW); - - flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW); - flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW); - - // Initially connecting the writeback stage signals, but may need to use M stage - // and gate on ~FlushW. - - assign valid = InstrValidW & ~StallW & ~FlushW; - assign order[0][0] = CSRArray[12'hB02]; - assign insn[0][0] = InstrRawW; - assign pc_rdata[0][0] = PCW; - assign trap[0][0] = TrapW; - assign halt[0][0] = HaltW; - assign intr[0][0] = IntrW; - assign mode[0][0] = PrivilegeModeW; - assign ixl[0][0] = PrivilegeModeW == 2'b11 ? 2'b10 : - PrivilegeModeW == 2'b01 ? STATUS_SXL : STATUS_UXL; - assign pc_wdata[0][0] = ~FlushW ? PCM : - ~FlushM ? PCE : - ~FlushE ? PCD : - ~FlushD ? PCF : PCNextF; - - for(index = 0; index < `NUM_REGS; index += 1) begin - assign x_wdata[0][0][index] = rf[index]; - assign x_wb[0][0][index] = rf_wb[index]; - assign f_wdata[0][0][index] = frf[index]; - assign f_wb[0][0][index] = frf_wb[index]; - end - - always_comb begin - csr_wb[0][0] <= '0; - if(CSRWriteW) - csr_wb[0][0][CSRAdrW] <= 1'b1; - end - - integer index3; - - always_comb begin - for(index3 = 0; index3 < `NUM_CSRS; index3 += 1) begin - if(CSRArray.exists(index3)) - csr[0][0][index3] = CSRArray[index3]; - else - csr[0][0][index3] = '0; - end - end - - // *** implementation only cancel? so sc does not clear? - assign lrsc_cancel[0][0] = '0; - - integer index2; - - always_ff @(posedge clk) begin - if(valid) begin - if(`PRINT_PC_INSTR & !(`PRINT_ALL | `PRINT_MOST)) - $display("order = %08d, PC = %08x, insn = %08x", order[0][0], pc_rdata[0][0], insn[0][0]); - else if(`PRINT_MOST & !`PRINT_ALL) - $display("order = %08d, PC = %010x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %010x, x%02d = %016x, f%02d = %016x, csr%03x = %016x", - order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0], rf_a3, x_wdata[0][0][rf_a3], frf_a4, f_wdata[0][0][frf_a4], CSRAdrW, csr[0][0][CSRAdrW]); - else if(`PRINT_ALL) begin - $display("order = %08d, PC = %08x, insn = %08x, trap = %1d, halt = %1d, intr = %1d, mode = %1x, ixl = %1x, pc_wdata = %08x", - order[0][0], pc_rdata[0][0], insn[0][0], trap[0][0], halt[0][0], intr[0][0], mode[0][0], ixl[0][0], pc_wdata[0][0]); - for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin - $display("x%02d = %08x", index2, x_wdata[0][0][index2]); - end - for(index2 = 0; index2 < `NUM_REGS; index2 += 1) begin - $display("f%02d = %08x", index2, f_wdata[0][0][index2]); - end - end - end - if(HaltW) $stop(); - end - - - -endmodule - diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index fcf4fca8..4fb646f7 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -692,55 +692,3 @@ task automatic updateProgramAddrLabelArray; $fclose(ProgramAddrMapFP); endtask -`define NUM_REGS 32 -`define NUM_CSRS 4096 - -module rvviTrace(); - - // wally specific signals - logic reset; - - logic [`XLEN-1:0] PCM, PCW; - logic [`XLEN-1:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; - logic InstrValidM, InstrValidW; - logic StallE, StallM, StallW; - logic FlushE, FlushM, FlushW; - - // tracer signals - logic clk; - logic valid; - logic [`XLEN-1:0] insn; - logic [`XLEN-1:0 ] pc_rdata; - - assign clk = testbench.dut.clk; - assign InstrValidM = testbench.dut.core.ieu.InstrValidM; - assign InstrRawD = testbench.dut.core.ifu.InstrRawD; - assign PCM = testbench.dut.core.ifu.PCM; - assign reset = testbench.reset; - assign StallE = testbench.dut.core.StallE; - assign StallM = testbench.dut.core.StallM; - assign StallW = testbench.dut.core.StallW; - assign FlushE = testbench.dut.core.FlushE; - assign FlushM = testbench.dut.core.FlushM; - assign FlushW = testbench.dut.core.FlushW; - - // pipeline to writeback stage - flopenrc #(`XLEN) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE); - flopenrc #(`XLEN) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM); - flopenrc #(`XLEN) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW); - flopenrc #(`XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW); - flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); - - assign valid = InstrValidW; - assign insn = InstrRawW; - assign pc_rdata = PCW; - - always_ff @(posedge clk) begin - if(valid) begin - $display("PC = %x, insn = %x", pc_rdata, insn); - end - end - - -endmodule - From c73bea83cdb1586c5496d5d781b4a7cca21c2e43 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 17 Jan 2023 13:43:39 -0800 Subject: [PATCH 2/2] Clean up warnings from Questa --- pipelined/regression/makefile-memfile | 3 +- pipelined/src/mmu/hptw.sv | 15 ++++----- pipelined/src/mmu/mmu.sv | 14 +++----- pipelined/src/mmu/pmpchecker.sv | 46 +++++++++++++++----------- pipelined/src/mmu/tlbcontrol.sv | 8 ++--- pipelined/src/mmu/vm64check.sv | 18 ++++++---- pipelined/testbench/testbench-linux.sv | 2 +- 7 files changed, 53 insertions(+), 53 deletions(-) diff --git a/pipelined/regression/makefile-memfile b/pipelined/regression/makefile-memfile index d41af90c..646da5ac 100644 --- a/pipelined/regression/makefile-memfile +++ b/pipelined/regression/makefile-memfile @@ -5,7 +5,8 @@ WALLYDIR:= $(ROOT)/tests/wally-riscv-arch-test # IMPERASDIR := $(ROOT)/tests/imperas-riscv-tests # ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) $(IMPERASDIR)/$(SUFFIX) IMPERASDIR := $(ROOT)/tests/imperas-riscv-tests -ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) +#ALLDIRS := $(ARCHDIR)/$(SUFFIX) $(WALLYDIR)/$(SUFFIX) +ALLDIRS := $(ARCHDIR)/$(SUFFIX) ELFFILES ?= $(shell find $(ALLDIRS) -type f -regex ".*\.elf") OBJDUMPFILES ?= $(shell find $(ALLDIRS) -type f -regex ".*\.elf.objdump") diff --git a/pipelined/src/mmu/hptw.sv b/pipelined/src/mmu/hptw.sv index 92b60d18..e7fdc416 100644 --- a/pipelined/src/mmu/hptw.sv +++ b/pipelined/src/mmu/hptw.sv @@ -98,7 +98,6 @@ module hptw ( logic [2:0] HPTWSize; // 32 or 64 bit access (* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState; - // map hptw access faults onto either the original LSU load/store fault or instruction access fault assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0]; assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[0]; @@ -189,13 +188,13 @@ module hptw ( // FSM to track PageType based on the levels of the page table traversed flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); always_comb - case (WalkerState) - L3_RD: NextPageType = 2'b11; // terapage - L2_RD: NextPageType = 2'b10; // gigapage - L1_RD: NextPageType = 2'b01; // megapage - L0_RD: NextPageType = 2'b00; // kilopage - default: NextPageType = PageType; - endcase + case (WalkerState) + L3_RD: NextPageType = 2'b11; // terapage + L2_RD: NextPageType = 2'b10; // gigapage + L1_RD: NextPageType = 2'b01; // megapage + L0_RD: NextPageType = 2'b00; // kilopage + default: NextPageType = PageType; + endcase // HPTWAdr muxing if (`XLEN==32) begin // RV32 diff --git a/pipelined/src/mmu/mmu.sv b/pipelined/src/mmu/mmu.sv index 4a89b439..8a440c39 100644 --- a/pipelined/src/mmu/mmu.sv +++ b/pipelined/src/mmu/mmu.sv @@ -107,16 +107,10 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( .Cacheable, .Idempotent, .SelTIM, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); - if (`PMP_ENTRIES > 0) // instantiate PMP - pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, - .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .ExecuteAccessF, .WriteAccessM, .ReadAccessM, - .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); - else begin - assign PMPInstrAccessFaultF = 0; - assign PMPLoadAccessFaultM = 0; - assign PMPStoreAmoAccessFaultM = 0; - end + pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, + .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, + .ExecuteAccessF, .WriteAccessM, .ReadAccessM, + .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); // Access faults // If TLB miss and translating we want to not have faults from the PMA and PMP checkers. diff --git a/pipelined/src/mmu/pmpchecker.sv b/pipelined/src/mmu/pmpchecker.sv index de8ce7b3..a5796136 100644 --- a/pipelined/src/mmu/pmpchecker.sv +++ b/pipelined/src/mmu/pmpchecker.sv @@ -49,28 +49,34 @@ module pmpchecker ( output logic PMPStoreAmoAccessFaultM ); - // Bit i is high when the address falls in PMP region i - logic EnforcePMP; - logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges - logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. - logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null - logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set - logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] + if (`PMP_ENTRIES > 0) begin + // Bit i is high when the address falls in PMP region i + logic EnforcePMP; + logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges + logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. + logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null + logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set + logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] - pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( - .PhysicalAddress, - .PMPCfg(PMPCFG_ARRAY_REGW), - .PMPAdr(PMPADDR_ARRAY_REGW), - .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), - .PAgePMPAdrOut(PAgePMPAdr), - .Match, .Active, .L, .X, .W, .R); + pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( + .PhysicalAddress, + .PMPCfg(PMPCFG_ARRAY_REGW), + .PMPAdr(PMPADDR_ARRAY_REGW), + .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), + .PAgePMPAdrOut(PAgePMPAdr), + .Match, .Active, .L, .X, .W, .R); - priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. + priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. - // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region - assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; + // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region + assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; - assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; - assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; - assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ; + assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; + assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; + assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~|(R & FirstMatch) ; + end else begin + assign PMPInstrAccessFaultF = 0; + assign PMPStoreAmoAccessFaultM = 0; + assign PMPLoadAccessFaultM = 0; + end endmodule diff --git a/pipelined/src/mmu/tlbcontrol.sv b/pipelined/src/mmu/tlbcontrol.sv index 1561b239..abbdba8f 100644 --- a/pipelined/src/mmu/tlbcontrol.sv +++ b/pipelined/src/mmu/tlbcontrol.sv @@ -63,12 +63,8 @@ module tlbcontrol #(parameter ITLB = 0) ( // Determine whether TLB is being used assign TLBAccess = ReadAccess | WriteAccess; - if (`XLEN==64) // Check whether upper bits of 64-bit virtual addressses are all equal - vm64check vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequalPageFault); - else begin - assign SV39Mode = 0; - assign UpperBitsUnequalPageFault = 0; - end + // Check that upper bits are legal (all 0s or all 1s) + vm64check vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequalPageFault); // unswizzle useful PTE bits assign {PTE_D, PTE_A} = PTEAccessBits[7:6]; diff --git a/pipelined/src/mmu/vm64check.sv b/pipelined/src/mmu/vm64check.sv index 975890d9..a78b853e 100644 --- a/pipelined/src/mmu/vm64check.sv +++ b/pipelined/src/mmu/vm64check.sv @@ -35,12 +35,16 @@ module vm64check ( output logic UpperBitsUnequalPageFault ); - logic eq_63_47, eq_46_38; + if (`XLEN == 64) begin + assign SV39Mode = (SATP_MODE == `SV39); - assign SV39Mode = (SATP_MODE == `SV39); - - // page fault if upper bits aren't all the same - assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]); - assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); - assign UpperBitsUnequalPageFault = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47; + // page fault if upper bits aren't all the same + logic eq_63_47, eq_46_38; + assign eq_46_38 = &(VAdr[46:38]) | ~|(VAdr[46:38]); + assign eq_63_47 = &(VAdr[63:47]) | ~|(VAdr[63:47]); + assign UpperBitsUnequalPageFault = SV39Mode ? ~(eq_63_47 & eq_46_38) : ~eq_63_47; + end else begin + assign SV39Mode = 0; + assign UpperBitsUnequalPageFault = 0; + end endmodule diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index d4034e0b..f24a7a61 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -155,7 +155,7 @@ module testbench; `define MCOUNTEREN `CSR_BASE.csrm.mcounteren.MCOUNTERENreg.q `define SCOUNTEREN `CSR_BASE.csrs.csrs.SCOUNTERENreg.q `define MSCRATCH `CSR_BASE.csrm.MSCRATCHreg.q - `define SSCRATCH `CSR_BASE.csrs.csrs.csrs.SSCRATCHreg.q + `define SSCRATCH `CSR_BASE.csrs.csrs.SSCRATCHreg.q `define MTVEC `CSR_BASE.csrm.MTVECreg.q `define STVEC `CSR_BASE.csrs.csrs.STVECreg.q `define SATP `CSR_BASE.csrs.csrs.genblk1.SATPreg.q