diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py index aecc89bc3..49f2a558e 100755 --- a/linux/testvector-generation/parsePlicState.py +++ b/linux/testvector-generation/parsePlicState.py @@ -98,8 +98,7 @@ with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile: outFile.write(stripZeroes(word[2:])+'\n') with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile: for word in plicIntEnableArray: - word = hex(int(word,16)>>1)[2:] # right shift by 1 because source 0 does not exist - outFile.write(stripZeroes(word)+'\n') + outFile.write(stripZeroes(word[2:])+'\n') with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile: for word in plicIntPriorityThresholdArray: outFile.write(stripZeroes(word[2:])+'\n') diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 05b0aa516..d5e2e88b3 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -115,6 +115,8 @@ module ifu ( (* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; // branch predictor signal logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F; + logic [31:0] InstrNextF; + logic wfiD; assign PCFExt = {2'b00, PCFSpill}; @@ -134,6 +136,13 @@ module ifu ( assign {SelNextSpillF, CompressedF} = 0; end + ///////////////////////////////////////////////////////////////////////////////////////////// + // WFI + ///////////////////////////////////////////////////////////////////////////////////////////// + + assign wfiD = (InstrD[6:0] == 7'b111011 && InstrD[31:20] == 12'b000100000101); // WFI in decode stage + assign InstrNextF = wfiD ? InstrD : PostSpillInstrRawF; // on WFI, keep replaying WFI + //////////////////////////////////////////////////////////////////////////////////////////////// // Memory management //////////////////////////////////////////////////////////////////////////////////////////////// @@ -239,7 +248,7 @@ module ifu ( assign IFUStallF = IFUCacheBusStallF | SelNextSpillF; assign CPUBusy = StallF & ~SelNextSpillF; - flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : PostSpillInstrRawF, nop, InstrRawD); + flopenl #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, FlushD ? nop : InstrNextF /*PostSpillInstrRawF*/, nop, InstrRawD); //////////////////////////////////////////////////////////////////////////////////////////////// // PCNextF logic diff --git a/pipelined/src/privileged/csr.sv b/pipelined/src/privileged/csr.sv index 2628726d6..cd3639670 100644 --- a/pipelined/src/privileged/csr.sv +++ b/pipelined/src/privileged/csr.sv @@ -41,7 +41,7 @@ module csr #(parameter input logic StallE, StallM, StallW, input logic [31:0] InstrM, input logic [`XLEN-1:0] PCM, SrcAM, - input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, + input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, wfiM, input logic TimerIntM, MExtIntM, SExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, input logic InstrValidM, FRegWriteM, LoadStallD, @@ -123,7 +123,7 @@ module csr #(parameter // write CSRs assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? (wfiM ? PCM+4 : PCM) : CSRWriteValM; assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? CauseM : CSRWriteValM; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; diff --git a/pipelined/src/privileged/csrsr.sv b/pipelined/src/privileged/csrsr.sv index c8955bcf7..92ca3bef0 100644 --- a/pipelined/src/privileged/csrsr.sv +++ b/pipelined/src/privileged/csrsr.sv @@ -140,6 +140,7 @@ module csrsr ( STATUS_MIE <= #1 STATUS_MPIE; STATUS_MPIE <= #1 1; STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why + // possible bug *** Ross Thompson //STATUS_MPRV_INT <= #1 (STATUS_MPP == `M_MODE & STATUS_MPRV_INT); //0; // per 20210108 draft spec STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec end else if (sretM) begin diff --git a/pipelined/src/privileged/privileged.sv b/pipelined/src/privileged/privileged.sv index 0336a3b00..003a84b76 100644 --- a/pipelined/src/privileged/privileged.sv +++ b/pipelined/src/privileged/privileged.sv @@ -167,7 +167,7 @@ module privileged ( .FlushE, .FlushM, .FlushW, .StallE, .StallM, .StallW, .InstrM, .PCM, .SrcAM, - .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, + .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .wfiM, .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, diff --git a/pipelined/testbench/common/instrNameDecTB.sv b/pipelined/testbench/common/instrNameDecTB.sv index f0aaba92d..4c1a68502 100644 --- a/pipelined/testbench/common/instrNameDecTB.sv +++ b/pipelined/testbench/common/instrNameDecTB.sv @@ -105,6 +105,7 @@ module instrNameDecTB( else if (imm == 258) name = "SRET"; else if (imm == 770) name = "MRET"; else if (funct7 == 9) name = "SFENCE.VMA"; + else if (imm == 261) name = "WFI"; else name = "ILLEGAL"; 10'b1110011_001: name = "CSRRW"; 10'b1110011_010: name = "CSRRS"; diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 5d50848ba..f00ca8257 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -27,7 +27,7 @@ `include "wally-config.vh" -`define DEBUG_TRACE 0 +`define DEBUG_TRACE 2 // Debug Levels // 0: don't check against QEMU // 1: print disagreements with QEMU, but only halt on PCW disagreements @@ -546,11 +546,11 @@ module testbench; end \ if(`"STAGE`"=="M") begin \ // override on special conditions \ - if ((dut.core.lsu.LSUPAdrM == 'h10000002) | (dut.core.lsu.LSUPAdrM == 'h10000005) | (dut.core.lsu.LSUPAdrM == 'h10000006)) \ - //$display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, InstrCountW-1); \ + if ((dut.core.lsu.LSUPAdrM == 'h10000002) | (dut.core.lsu.LSUPAdrM == 'h10000005) | (dut.core.lsu.LSUPAdrM == 'h10000006)) begin \ + $display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, AttemptedInstructionCount); \ if(!NO_IE_MTIME_CHECKPOINT) \ force dut.core.ieu.dp.ReadDataM = ExpectedMemReadDataM; \ - else \ + end else \ if(!NO_IE_MTIME_CHECKPOINT) \ release dut.core.ieu.dp.ReadDataM; \ if(textM.substr(0,5) == "rdtime") begin \ @@ -729,8 +729,11 @@ module testbench; // New IP spoofing logic globalIntsBecomeEnabled; assign globalIntsBecomeEnabled = (`CSR_BASE.csrm.WriteMSTATUSM || `CSR_BASE.csrs.WriteSSTATUSM) && (|(`CSR_BASE.CSRWriteValM & (~`CSR_BASE.csrm.MSTATUS_REGW) & 32'h22)); + logic checkInterruptM; + assign checkInterruptM = dut.core.ieu.InstrValidM & ~dut.core.priv.priv.trap.InstrPageFaultM & ~dut.core.priv.priv.trap.InterruptM; + always @(negedge clk) begin - if(checkInstrM) begin + if(checkInterruptM) begin if((interruptInstrCount+1) == AttemptedInstructionCount) begin if(!NO_IE_MTIME_CHECKPOINT) begin case (interruptCauseVal) diff --git a/tests/fp/run_all.sh b/tests/fp/run_all.sh index 9c45ff2d4..8d4b03dc7 100755 --- a/tests/fp/run_all.sh +++ b/tests/fp/run_all.sh @@ -1,5 +1,6 @@ #!/bin/sh +mkdir -p vectors ./create_vectors.sh ./remove_spaces.sh ./append_ctrlSig.sh