From ce7e1073fa8a99752337c7fee85d4047141d8503 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 22 Dec 2022 21:36:49 -0600 Subject: [PATCH] Success we've replaced TrapM with FlushD in the IFU. --- pipelined/src/cache/cachefsm.sv | 2 +- pipelined/src/ebu/buscachefsm.sv | 2 +- pipelined/src/ebu/busfsm.sv | 2 +- pipelined/src/hazard/hazard.sv | 3 +- pipelined/src/ifu/bpred.sv | 46 ++++++++++++++----------------- pipelined/src/ifu/ifu.sv | 12 +++----- pipelined/src/ifu/spillsupport.sv | 2 +- 7 files changed, 30 insertions(+), 39 deletions(-) diff --git a/pipelined/src/cache/cachefsm.sv b/pipelined/src/cache/cachefsm.sv index ed8cf606d..a8ba78564 100644 --- a/pipelined/src/cache/cachefsm.sv +++ b/pipelined/src/cache/cachefsm.sv @@ -142,7 +142,7 @@ module cachefsm // com back to CPU assign CacheCommitted = CurrState != STATE_READY; - assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss) & ~FlushStage) | + assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITE_LINE & ~(StoreAMO)) | // this cycle writes the sram, must keep stalling so the next cycle can read the next hit/miss unless its a write. diff --git a/pipelined/src/ebu/buscachefsm.sv b/pipelined/src/ebu/buscachefsm.sv index 79d22b63f..7d3d2bee7 100644 --- a/pipelined/src/ebu/buscachefsm.sv +++ b/pipelined/src/ebu/buscachefsm.sv @@ -128,7 +128,7 @@ module buscachefsm #(parameter integer BeatCountThreshold, assign CaptureEn = (CurrState == DATA_PHASE & BusRW[1]) | (CurrState == CACHE_FETCH & HREADY); assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK; - assign BusStall = (CurrState == ADR_PHASE & (|BusRW | |CacheBusRW) & ~Flush) | + assign BusStall = (CurrState == ADR_PHASE & (|BusRW | |CacheBusRW)) | //(CurrState == DATA_PHASE & ~BusRW[0]) | // replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem. (CurrState == DATA_PHASE) | (CurrState == CACHE_FETCH & ~HREADY) | diff --git a/pipelined/src/ebu/busfsm.sv b/pipelined/src/ebu/busfsm.sv index 0efd3ece2..34ab73ac1 100644 --- a/pipelined/src/ebu/busfsm.sv +++ b/pipelined/src/ebu/busfsm.sv @@ -71,7 +71,7 @@ module busfsm endcase end - assign BusStall = (CurrState == ADR_PHASE & |BusRW & ~Flush) | + assign BusStall = (CurrState == ADR_PHASE & |BusRW) | // (CurrState == DATA_PHASE & ~BusRW[0]); // possible optimization here. fails uart test, but i'm not sure the failure is valid. (CurrState == DATA_PHASE); diff --git a/pipelined/src/hazard/hazard.sv b/pipelined/src/hazard/hazard.sv index a9ace73e9..7191fb615 100644 --- a/pipelined/src/hazard/hazard.sv +++ b/pipelined/src/hazard/hazard.sv @@ -86,7 +86,8 @@ module hazard( assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; // WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap assign StallMCause = ((wfiM) & (~TrapM & ~IntPendingM)); - assign StallWCause = (IFUStallF | LSUStallM) & ~TrapM; + //assign StallWCause = (IFUStallF | LSUStallM) & ~TrapM; + assign StallWCause = (IFUStallF & ~(FlushDCause)) | (LSUStallM & ~TrapM); // Stall each stage for cause or if the next stage is stalled assign #1 StallF = StallFCause | StallD; diff --git a/pipelined/src/ifu/bpred.sv b/pipelined/src/ifu/bpred.sv index 89113f1ce..f1fd1df76 100644 --- a/pipelined/src/ifu/bpred.sv +++ b/pipelined/src/ifu/bpred.sv @@ -33,38 +33,36 @@ `include "wally-config.vh" -module bpred - (input logic clk, reset, +module bpred ( + input logic clk, reset, input logic StallF, StallD, StallE, StallM, input logic FlushD, FlushE, FlushM, // Fetch stage // the prediction - input logic [31:0] InstrD, - input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list - input logic [`XLEN-1:0] PCPlus2or4F, - output logic [`XLEN-1:0] PCNext1F, - output logic [`XLEN-1:0] NextValidPCE, // The address of the currently executing instruction + input logic [31:0] InstrD, // Decompressed decode stage instruction + input logic [`XLEN-1:0] PCNextF, // Next Fetch Address + input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4 + output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction + output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage. // Update Predictor - input logic [`XLEN-1:0] PCE, // The address of the currently executing instruction - input logic [`XLEN-1:0] PCF, // The address of the currently executing instruction + input logic [`XLEN-1:0] PCF, // Fetch stage instruction address. + input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took. + input logic [`XLEN-1:0] PCE, // Execution stage instruction address. - // 1 hot encoding - // return, jump register, jump, branch // *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class. // *** the specifics of how this is encode is subject to change. - input logic PCSrcE, // AKA Branch Taken - // Signals required to check the branch prediction accuracy. - input logic [`XLEN-1:0] IEUAdrE, // The branch destination if the branch is taken. - input logic [`XLEN-1:0] PCD, // The address the branch predictor took. - input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) - output logic [4:0] InstrClassM, + input logic PCSrcE, // Executation stage branch is taken + input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address + input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) + output logic [4:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br + // Report branch prediction status - output logic BPPredWrongE, - output logic BPPredDirWrongM, - output logic BTBPredPCWrongM, - output logic RASPredPCWrongM, - output logic BPPredClassNonCFIWrongM + output logic BPPredWrongE, // Prediction is wrong. + output logic BPPredDirWrongM, // Prediction direction is wrong. + output logic BTBPredPCWrongM, // Prediction target wrong. + output logic RASPredPCWrongM, // RAS prediction is wrong. + output logic BPPredClassNonCFIWrongM // Class prediction is wrong. ); logic BTBValidF; @@ -126,13 +124,11 @@ module bpred // 1) A direction (1 = Taken, 0 = Not Taken) // 2) Any information which is necessary for the predictor to build its next state. // For a 2 bit table this is the prediction count. - assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) | BPInstrClassF[3] | (BPInstrClassF[2] & BTBValidF) | BPInstrClassF[1] & BTBValidF) ; - // Part 2 Branch target address prediction // *** For now the BTB will house the direct and indirect targets @@ -162,8 +158,6 @@ module bpred .pushPC(PCLinkE)); assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF; - - // The prediction and its results need to be passed through the pipeline // *** for other predictors will will be different. diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 75ad7acb6..fc0de5eae 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -121,10 +121,6 @@ module ifu ( logic BusCommittedF, CacheCommittedF; logic SelIROM; - logic FlushDCause; - - assign FlushDCause = TrapM | RetM | BPPredWrongE | CSRWriteFenceM; - assign PCFExt = {2'b00, PCFSpill}; ///////////////////////////////////////////////////////////////////////////////////////////// @@ -132,7 +128,7 @@ module ifu ( ///////////////////////////////////////////////////////////////////////////////////////////// if(`C_SUPPORTED) begin : SpillSupport - spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(FlushDCause), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF), + spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(FlushD), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF), .InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill, .SelNextSpillF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpillSupport @@ -223,7 +219,7 @@ module ifu ( cache #(.LINELEN(`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .DCACHE(0)) - icache(.clk, .reset, .FlushStage(FlushDCause), .Stall(GatedStallD), + icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), .FetchBuffer, .CacheBusAck(ICacheBusAck), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .CacheBusRW, @@ -240,7 +236,7 @@ module ifu ( ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE) ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), .HRDATA, - .Flush(FlushDCause), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), + .Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr), .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), @@ -259,7 +255,7 @@ module ifu ( // assign BusRW = IFURWF & ~{IgnoreRequest, IgnoreRequest} & ~{SelIROM, SelIROM}; assign IFUHSIZE = 3'b010; - ahbinterface #(0) ahbinterface(.HCLK(clk), .Flush(FlushDCause), .HRESETn(~reset), .HREADY(IFUHREADY), + ahbinterface #(0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY), .HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(), .HWSTRB(), .BusRW, .ByteMask(), .WriteData('0), .Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer)); diff --git a/pipelined/src/ifu/spillsupport.sv b/pipelined/src/ifu/spillsupport.sv index 7049fac98..55de81f4a 100644 --- a/pipelined/src/ifu/spillsupport.sv +++ b/pipelined/src/ifu/spillsupport.sv @@ -84,7 +84,7 @@ module spillsupport #(parameter CACHE_ENABLED) end assign SelSpillF = (CurrState == STATE_SPILL); - assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF & ~Flush) | + assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) | (CurrState == STATE_SPILL & IFUCacheBusStallF); assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF; assign SavedInstr = CACHE_ENABLED ? InstrRawF[15:0] : InstrRawF[31:16];