From 684d260005fa5e4729d28a66ebf98c5fe3737afe Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 20 Dec 2022 12:58:54 -0600 Subject: [PATCH] Reorganized IFU PCNextF logic. --- pipelined/src/ifu/bpred.sv | 31 ++++++++--------- pipelined/src/ifu/ifu.sv | 56 +++++++++++++++---------------- pipelined/src/ifu/spillsupport.sv | 9 ++--- 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/pipelined/src/ifu/bpred.sv b/pipelined/src/ifu/bpred.sv index 87d7557b..eacdb814 100644 --- a/pipelined/src/ifu/bpred.sv +++ b/pipelined/src/ifu/bpred.sv @@ -43,7 +43,6 @@ module bpred 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] PCCorrectE, output logic [`XLEN-1:0] NextValidPCE, // The address of the currently executing instruction // Update Predictor @@ -84,13 +83,10 @@ module bpred logic [`XLEN-1:0] BPPredPCF; logic BPPredWrongM; logic [`XLEN-1:0] PCNext0F; - - - - + logic [`XLEN-1:0] PCCorrectE; // Part 1 branch direction prediction - + // look into the 2 port Sram model. something is wrong. if (`BPTYPE == "BPTWOBIT") begin:Predictor twoBitPredictor DirPredictor(.clk, .reset, .StallF, .LookUpPC(PCNextF), @@ -263,23 +259,28 @@ module bpred .NewState(UpdateBPPredE)); + // Selects the BP or PC+2/4. mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), .d1(BPPredPCF), .s(SelBPPredF), .y(PCNext0F)); + // If the prediction is wrong select the correct address. + mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F)); - - + // Correct branch/jump target. mux2 #(`XLEN) pccorrectemux(.d0(PCLinkE), .d1(IEUAdrE), .s(PCSrcE), .y(PCCorrectE)); + // If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE. - // could also just use PCM+4, which should be pclinke - mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(NextValidPCE)); + // could also just use PCM+4, or PCLinkM + // ONLY valid for class prediction. add option for class prediction. +// if(`BPCLASS) begin + mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(NextValidPCE)); +// end else begin +// assign NextValidPCE = PCE; +// end + //logic [`XLEN-1:0] PCLinkM; //flopenr #(`XLEN) PCPEReg(clk, reset, ~StallM, PCLinkE, PCLinkM); //assign NextValidPCE = PCLinkM; // of the three, the mux is the cheapest, but the least clear. // this could move entirely into ifu with no relation to bp with the third. - - //assign NextValidPCE = PCE; - - - mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F)); + endmodule diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index b8294419..f33737ec 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -85,9 +85,8 @@ module ifu ( output logic ICacheAccess, output logic ICacheMiss ); - (* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; + (* mark_debug = "true" *) logic [`XLEN-1:0] UnalignedPCNextF, PCNextF; logic BranchMisalignedFaultE; - logic PrivilegedChangePCM; logic IllegalCompInstrD; logic [`XLEN-1:0] PCPlus2or4F, PCLinkD; logic [`XLEN-3:0] PCPlusUpperF; @@ -286,41 +285,19 @@ module ifu ( // PCNextF logic //////////////////////////////////////////////////////////////////////////////////////////////// - assign PrivilegedChangePCM = RetM | TrapM; - - // if(`ICACHE | `ZICSR_SUPPORTED) mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(NextValidPCE), .s(CSRWriteFenceM),.y(PCNext2F)); // mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCM+4), .s(CSRWriteFenceM),.y(PCNext2F)); // else assign PCNext2F = PCNext1F; - if(`ZICSR_SUPPORTED) + if(`ZICSR_SUPPORTED) begin + logic PrivilegedChangePCM; + assign PrivilegedChangePCM = RetM | TrapM; mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), - .y(UnalignedPCNextF)); - else assign UnalignedPCNextF = PCNext2F; - + .y(UnalignedPCNextF)); + end else assign UnalignedPCNextF = PCNext2F; assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); - //////////////////////////////////////////////////////////////////////////////////////////////// - // Branch and Jump Predictor - //////////////////////////////////////////////////////////////////////////////////////////////// - if (`BPRED_ENABLED) begin : bpred - bpred bpred(.clk, .reset, - .StallF, .StallD, .StallE, .StallM, - .FlushD, .FlushE, .FlushM, - .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCSrcE, .IEUAdrE, .PCCorrectE, .PCF, .NextValidPCE, - .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, - .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM); - - end else begin : bpred - mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); - assign BPPredWrongE = PCSrcE; - assign {BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0; - assign PCNext0F = PCPlus2or4F; - assign PCCorrectE = IEUAdrE; - assign NextValidPCE = PCE; - end - // pcadder // add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32 assign PCPlusUpperF = PCF[`XLEN-1:2] + 1; // add 4 to PC @@ -334,6 +311,27 @@ module ifu ( else PCPlus2or4F = {PCF[`XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCPlusUpperF, PCF[1:0]}; // add 4 + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Branch and Jump Predictor + //////////////////////////////////////////////////////////////////////////////////////////////// + if (`BPRED_ENABLED) begin : bpred + bpred bpred(.clk, .reset, + .StallF, .StallD, .StallE, .StallM, + .FlushD, .FlushE, .FlushM, + .InstrD, .PCNextF, .PCPlus2or4F, .PCNext1F, .PCE, .PCSrcE, .IEUAdrE, .PCF, .NextValidPCE, + .PCD, .PCLinkE, .InstrClassM, .BPPredWrongE, + .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM); + + end else begin : bpred + mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F)); + assign BPPredWrongE = PCSrcE; + assign {BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0; + assign PCNext0F = PCPlus2or4F; + assign NextValidPCE = PCE; + end + + //////////////////////////////////////////////////////////////////////////////////////////////// // Decode stage pipeline register and compressed instruction decoding. //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/pipelined/src/ifu/spillsupport.sv b/pipelined/src/ifu/spillsupport.sv index b247c2d3..5a6efe0b 100644 --- a/pipelined/src/ifu/spillsupport.sv +++ b/pipelined/src/ifu/spillsupport.sv @@ -59,10 +59,11 @@ module spillsupport #(parameter CACHE_ENABLED) typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; (* mark_debug = "true" *) statetype CurrState, NextState; - mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), - .s(PCF[1]), .y(PCPlus2F)); - mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF & ~Flush), - .y(PCNextFSpill)); + // compute PCF+2 + mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); + // select between PCNextF and PCF+2 + mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF & ~Flush), .y(PCNextFSpill)); + // select between PCF adn PCF+2 mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];