mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	More branch predictor cleanup.
Found small bug. The decode stage was using the predicted instruction class rather than the decoded instruction class.
This commit is contained in:
		
							parent
							
								
									cf608ee45f
								
							
						
					
					
						commit
						de7f3b14fc
					
				| @ -65,7 +65,7 @@ module bpred ( | ||||
|   logic                     BTBValidF; | ||||
|   logic [1:0]               DirPredictionF; | ||||
| 
 | ||||
|   logic [4:0]               BPInstrClassF, BPInstrClassD, BPInstrClassE; | ||||
|   logic [4:0]               PredInstrClassF, PredInstrClassD, PredInstrClassE; | ||||
|   logic [`XLEN-1:0]         BTBPredPCF, RASPCF; | ||||
|   logic                     TargetWrongE; | ||||
|   logic                     FallThroughWrongE; | ||||
| @ -95,7 +95,7 @@ module bpred ( | ||||
|   end else if (`BPTYPE == "BPSPECULATIVEGLOBAL") begin:Predictor | ||||
|     speculativeglobalhistory #(10) DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, | ||||
|       .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, | ||||
|       .BranchInstrF(BPInstrClassF[0]), .BranchInstrD(BPInstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), | ||||
|       .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), | ||||
|       .BranchInstrW(InstrClassW[0]), .PCSrcE); | ||||
|      | ||||
|   end else if (`BPTYPE == "BPGSHARE") begin:Predictor | ||||
| @ -106,7 +106,7 @@ module bpred ( | ||||
|   end else if (`BPTYPE == "BPSPECULATIVEGSHARE") begin:Predictor | ||||
|     speculativegshare DirPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, | ||||
|       .PCNextF, .PCF, .PCD, .PCE, .PCM, .DirPredictionF, .DirPredictionWrongE, | ||||
|       .BranchInstrF(BPInstrClassF[0]), .BranchInstrD(BPInstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), | ||||
|       .BranchInstrF(PredInstrClassF[0]), .BranchInstrD(InstrClassD[0]), .BranchInstrE(InstrClassE[0]), .BranchInstrM(InstrClassM[0]), | ||||
|       .BranchInstrW(InstrClassW[0]), .PCSrcE); | ||||
| 
 | ||||
|   end else if (`BPTYPE == "BPLOCALPAg") begin:Predictor | ||||
| @ -129,10 +129,10 @@ 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] & DirPredictionF[1] & BTBValidF) |  | ||||
|          BPInstrClassF[3] | | ||||
|          (BPInstrClassF[2] & BTBValidF) |  | ||||
|          BPInstrClassF[1] & BTBValidF) ; | ||||
|   assign SelBPPredF = ((PredInstrClassF[0] & DirPredictionF[1] & BTBValidF) |  | ||||
|          PredInstrClassF[3] | | ||||
|          (PredInstrClassF[2] & BTBValidF) |  | ||||
|          PredInstrClassF[1] & BTBValidF) ; | ||||
| 
 | ||||
|   // Part 2 Branch target address prediction
 | ||||
|   // *** For now the BTB will house the direct and indirect targets
 | ||||
| @ -143,7 +143,7 @@ module bpred ( | ||||
|           .*, // Stalls and flushes
 | ||||
|           .LookUpPC(PCNextF), | ||||
|           .TargetPC(BTBPredPCF), | ||||
|           .InstrClass(BPInstrClassF), | ||||
|           .InstrClass(PredInstrClassF), | ||||
|           .Valid(BTBValidF), | ||||
|           // update
 | ||||
|           .UpdateEN((|InstrClassE | (PredictionInstrClassWrongE)) & ~StallE), | ||||
| @ -156,13 +156,13 @@ module bpred ( | ||||
|   // *** need to add the logic to restore RAS on flushes.  We will use incr for this.
 | ||||
|   RASPredictor RASPredictor(.clk(clk), | ||||
|        .reset(reset), | ||||
|        .pop(BPInstrClassF[3] & ~StallF), | ||||
|        .pop(PredInstrClassF[3] & ~StallF), | ||||
|        .popPC(RASPCF), | ||||
|        .push(InstrClassE[4] & ~StallE), | ||||
|        .incr(1'b0), | ||||
|        .pushPC(PCLinkE)); | ||||
| 
 | ||||
|   assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF; | ||||
|   assign BPPredPCF = PredInstrClassF[3] ? RASPCF : BTBPredPCF; | ||||
| 
 | ||||
|   // the branch predictor needs a compact decoding of the instruction class.
 | ||||
|   // *** consider adding in the alternate return address x5 for returns.
 | ||||
| @ -182,8 +182,8 @@ module bpred ( | ||||
|     {DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM}); | ||||
| 
 | ||||
|   // pipeline the class
 | ||||
|   flopenrc #(5) BPInstrClassRegD(clk, reset, FlushD, ~StallD, BPInstrClassF, BPInstrClassD); | ||||
|   flopenrc #(5) BPInstrClassRegE(clk, reset, FlushE, ~StallE, BPInstrClassD, BPInstrClassE); | ||||
|   flopenrc #(5) PredInstrClassRegD(clk, reset, FlushD, ~StallD, PredInstrClassF, PredInstrClassD); | ||||
|   flopenrc #(5) PredInstrClassRegE(clk, reset, FlushE, ~StallE, PredInstrClassD, PredInstrClassE); | ||||
| 
 | ||||
|   // Check the prediction
 | ||||
|   // first check if the target or fallthrough address matches what was predicted.
 | ||||
| @ -201,7 +201,7 @@ module bpred ( | ||||
|    | ||||
|   // Finally we need to check if the class is wrong.  When the class is wrong the BTB needs to be updated.
 | ||||
|   // Also we want to track this in a performance counter.
 | ||||
|   assign PredictionInstrClassWrongE = InstrClassE != BPInstrClassE; | ||||
|   assign PredictionInstrClassWrongE = InstrClassE != PredInstrClassE; | ||||
| 
 | ||||
|   // We want to output to the instruction fetch if the PC fetched was wrong.  If by chance the predictor was wrong about
 | ||||
|   // the direction or class, but correct about the target we don't have the flush the pipeline.  However we still
 | ||||
|  | ||||
| @ -44,18 +44,18 @@ module speculativegshare | ||||
|    input logic             PCSrcE | ||||
|    ); | ||||
| 
 | ||||
|   logic                    MatchF, MatchD, MatchE, MatchM, MatchW; | ||||
|   logic                    MatchF, MatchD, MatchE, MatchM; | ||||
|   logic                    MatchNextX, MatchXF; | ||||
| 
 | ||||
|   logic [1:0]              TableDirPredictionF, DirPredictionD, DirPredictionE; | ||||
|   logic [1:0]              NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM, NewDirPredictionW; | ||||
|   logic [1:0]              NewDirPredictionF, NewDirPredictionD, NewDirPredictionE, NewDirPredictionM; | ||||
| 
 | ||||
|   logic [k-1:0]            GHRF; | ||||
|   logic [k:0]              GHRD, OldGHRE, GHRE, GHRM, GHRW; | ||||
|   logic [k-1:0]            GHRNextF; | ||||
|   logic [k:0]              GHRNextD, GHRNextE, GHRNextM, GHRNextW; | ||||
|   logic [k-1:0]            IndexNextF, IndexF; | ||||
|   logic [k-1:0]            IndexD, IndexE, IndexM, IndexW; | ||||
|   logic [k-1:0]            IndexD, IndexE, IndexM; | ||||
|    | ||||
|   logic                    PCSrcM, PCSrcW; | ||||
|   logic [`XLEN-1:0]        PCW; | ||||
| @ -67,34 +67,31 @@ module speculativegshare | ||||
|   assign IndexD = GHRD[k-1:0] ^ {PCD[k+1] ^ PCD[1], PCD[k:2]}; | ||||
|   assign IndexE = GHRE[k-1:0] ^ {PCE[k+1] ^ PCE[1], PCE[k:2]}; | ||||
|   assign IndexM = GHRM[k-1:0] ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; | ||||
|   assign IndexW = GHRW[k-1:0] ^ {PCW[k+1] ^ PCW[1], PCW[k:2]}; | ||||
|        | ||||
|   ram2p1r1wbefix #(2**k, 2) PHT(.clk(clk), | ||||
|     .ce1(~StallF | reset), .ce2(~StallW & ~FlushW), | ||||
|     .ra1(IndexNextF), | ||||
|     .rd1(TableDirPredictionF), | ||||
|     .wa2(IndexW), | ||||
|     .wd2(NewDirPredictionW), | ||||
|     .we2(BranchInstrW & ~StallW & ~FlushW), | ||||
|     .wa2(IndexM), | ||||
|     .wd2(NewDirPredictionM), | ||||
|     .we2(BranchInstrM & ~StallW & ~FlushW), | ||||
|     .bwe2(1'b1)); | ||||
| 
 | ||||
|   // if there are non-flushed branches in the pipeline we need to forward the prediction from that stage to the NextF demi stage
 | ||||
|   //  and then register for use in the Fetch stage.
 | ||||
|   // and then register for use in the Fetch stage.
 | ||||
|   assign MatchF = BranchInstrF & ~FlushD & (IndexNextF == IndexF); | ||||
|   assign MatchD = BranchInstrD & ~FlushE & (IndexNextF == IndexD); | ||||
|   assign MatchE = BranchInstrE & ~FlushM & (IndexNextF == IndexE); | ||||
|   assign MatchM = BranchInstrM & ~FlushW & (IndexNextF == IndexM); | ||||
|   assign MatchW = BranchInstrW & (IndexNextF == IndexW); | ||||
|   assign MatchNextX = MatchF | MatchD | MatchE | MatchM | MatchW; | ||||
|   assign MatchNextX = MatchF | MatchD | MatchE | MatchM; | ||||
| 
 | ||||
|   flopenr #(1) MatchReg(clk, reset, ~StallF, MatchNextX, MatchXF); | ||||
| 
 | ||||
|   assign ForwardNewDirPrediction = MatchF ? NewDirPredictionF : | ||||
|                                    MatchD ? NewDirPredictionD : | ||||
|                                    MatchE ? NewDirPredictionE : | ||||
|                                    MatchM ? NewDirPredictionM : | ||||
|                                    NewDirPredictionW; | ||||
| 
 | ||||
|                                    NewDirPredictionM; | ||||
|    | ||||
|   flopenr #(2) ForwardDirPredicitonReg(clk, reset, ~StallF, ForwardNewDirPrediction, ForwardDirPredictionF); | ||||
| 
 | ||||
|   assign DirPredictionF = MatchXF ? ForwardDirPredictionF : TableDirPredictionF; | ||||
| @ -109,7 +106,6 @@ module speculativegshare | ||||
|   flopenr #(2) NewPredDReg(clk, reset, ~StallD, NewDirPredictionF, NewDirPredictionD); | ||||
|   satCounter2 BPDirUpdateE(.BrDir(PCSrcE), .OldState(DirPredictionE), .NewState(NewDirPredictionE)); | ||||
|   flopenr #(2) NewPredMReg(clk, reset, ~StallM, NewDirPredictionE, NewDirPredictionM); | ||||
|   flopenr #(2) NewPredWReg(clk, reset, ~StallW, NewDirPredictionM, NewDirPredictionW); | ||||
| 
 | ||||
|   // PCSrc pipeline
 | ||||
|   flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, PCSrcM); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user