blob: 740a2e2dadc91ffc560729e41eef186e2d57e1d5 [file] [log] [blame]
module BranchPredictor (
clk,
rst,
IN_clearICache,
IN_mispredFlush,
IN_branch,
IN_pcValid,
IN_pc,
OUT_branchTaken,
OUT_isJump,
OUT_branchSrc,
OUT_branchDst,
OUT_branchHistory,
OUT_branchInfo,
OUT_multipleBranches,
OUT_branchFound,
OUT_branchCompr,
IN_btUpdates,
IN_bpUpdate
);
parameter NUM_IN = 2;
parameter NUM_ENTRIES = 32;
parameter ID_BITS = 16;
input wire clk;
input wire rst;
input wire IN_clearICache;
input wire IN_mispredFlush;
input wire [75:0] IN_branch;
input wire IN_pcValid;
input wire [31:0] IN_pc;
output wire OUT_branchTaken;
output wire OUT_isJump;
output wire [31:0] OUT_branchSrc;
output wire [31:0] OUT_branchDst;
output wire [15:0] OUT_branchHistory;
output wire [8:0] OUT_branchInfo;
output wire OUT_multipleBranches;
output wire OUT_branchFound;
output wire OUT_branchCompr;
input wire [(NUM_IN * 67) - 1:0] IN_btUpdates;
input wire [58:0] IN_bpUpdate;
integer i;
reg [15:0] gHistory;
reg [15:0] gHistoryCom;
reg [66:0] btUpdate;
always @(*) begin
btUpdate = 67'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
btUpdate[0] = 0;
for (i = 0; i < NUM_IN; i = i + 1)
if (IN_btUpdates[i * 67])
btUpdate = IN_btUpdates[i * 67+:67];
end
wire [30:0] branchAddr = IN_pc[31:1];
assign OUT_branchHistory = gHistory;
assign OUT_branchInfo[8] = OUT_branchFound;
assign OUT_branchInfo[7] = OUT_branchTaken;
assign OUT_branchInfo[0] = OUT_isJump;
wire tageTaken;
assign OUT_branchTaken = OUT_branchFound && (OUT_isJump ? 1 : tageTaken);
assign OUT_branchDst[0] = 1'b0;
assign OUT_branchSrc[0] = 1'b0;
BranchTargetBuffer btb(
.clk(clk),
.rst(rst || IN_clearICache),
.IN_pcValid(IN_pcValid),
.IN_pc(IN_pc[31:1]),
.OUT_branchFound(OUT_branchFound),
.OUT_branchDst(OUT_branchDst[31:1]),
.OUT_branchSrc(OUT_branchSrc[31:1]),
.OUT_branchIsJump(OUT_isJump),
.OUT_branchCompr(OUT_branchCompr),
.OUT_multipleBranches(OUT_multipleBranches),
.IN_BPT_branchTaken(OUT_branchTaken),
.IN_btUpdate(btUpdate)
);
TagePredictor tagePredictor(
.clk(clk),
.rst(rst),
.IN_predAddr(branchAddr),
.IN_predHistory(gHistory),
.OUT_predTageID(OUT_branchInfo[6-:3]),
.OUT_predUseful(OUT_branchInfo[3-:3]),
.OUT_predTaken(tageTaken),
.IN_writeValid((IN_bpUpdate[0] && IN_bpUpdate[26]) && !IN_mispredFlush),
.IN_writeAddr(IN_bpUpdate[58:28]),
.IN_writeHistory(IN_bpUpdate[17-:16]),
.IN_writeTageID(IN_bpUpdate[24-:3]),
.IN_writeTaken(IN_bpUpdate[1]),
.IN_writeUseful(IN_bpUpdate[21-:3]),
.IN_writePred(IN_bpUpdate[25])
);
always @(posedge clk) begin
if (rst) begin
gHistory <= 0;
gHistoryCom <= 0;
end
else begin
if (OUT_branchFound && !OUT_isJump)
gHistory <= {gHistory[14:0], OUT_branchTaken};
if (IN_bpUpdate[0] && !IN_mispredFlush)
gHistoryCom <= {gHistoryCom[14:0], IN_bpUpdate[1]};
end
if (!rst && IN_branch[0])
gHistory <= IN_branch[16-:16];
end
endmodule