Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix branch predictor #40

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9360125
fix: fix to be able to set RAS_ENTRY_NUM from MicroArchConf.sv
reo-pon Feb 17, 2021
68b2113
fix: change the branch prediction performed within one cycle to once
reo-pon Feb 17, 2021
a22cd37
refactor: add comment related to RAS
reo-pon Feb 24, 2021
32ccaf1
fix: modify to be able to set FETCH_WIDTH to 1 without errors
reo-pon Feb 24, 2021
d084f80
fix: jump instruction is predicted always taken
reo-pon Feb 24, 2021
8133210
fix: fix a bug where a queuing direction in predictors is incorrect
shioyadan Feb 25, 2021
9ba806a
feat: recover branch history when a branch is resolved in DC stage
reo-pon Feb 27, 2021
7c3e54f
fix: dont update branch global history immediately after midprediction
reo-pon Mar 3, 2021
11f48ba
refactor: change the name of interface
reo-pon Mar 3, 2021
61e73c4
fix: fix incorrect variable name
reo-pon Mar 3, 2021
2bffe36
fix: change to recovery brHistory at redirecting PC
reo-pon Mar 10, 2021
c950310
fix: change the default number of PHT entry
reo-pon Mar 11, 2021
8000d22
feat: enable to configure branch predictor in MicroArchConf.sv
reo-pon Mar 11, 2021
28e6ecf
fix: remove reset logic in brpredictor queue
reo-pon Mar 23, 2021
e85ea04
refactor: optimize logic in gshare
reo-pon Mar 23, 2021
30b7ea0
refactor: remove unneccessary logic in BimodalBP
reo-pon Mar 23, 2021
c86b6c8
fix: change to use queue when BTB & PHT write has bank conflict
reo-pon Mar 23, 2021
3fbb8d4
refactor: change function name
reo-pon Mar 23, 2021
db57590
refactor: optimize logic and add comment
reo-pon Mar 23, 2021
575e2c2
fix: change to make multiple branch predictions in one cycle
reo-pon Mar 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Processor/Src/BasicTypes.sv
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ typedef struct packed { // PRegNumPath

// Fetch width
localparam FETCH_WIDTH = CONF_FETCH_WIDTH;
localparam FETCH_WIDTH_BIT_SIZE = $clog2( FETCH_WIDTH ); // log2(FETCH_WIDTH)
localparam FETCH_WIDTH_BIT_SIZE = FETCH_WIDTH == 1 ? 1 : $clog2( FETCH_WIDTH ); // log2(FETCH_WIDTH)
typedef logic [ FETCH_WIDTH_BIT_SIZE-1:0 ] FetchLaneIndexPath;

// Decode width
Expand Down
8 changes: 6 additions & 2 deletions Processor/Src/Decoder/DecodedBranchResolver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// This unit includes a simple return address stack.
//

import MicroArchConf::*;
import BasicTypes::*;
import MemoryMapTypes::*;
import OpFormatTypes::*;
Expand All @@ -29,10 +30,11 @@ output
logic insnFlushTriggering[DECODE_WIDTH],
logic flushTriggered,
BranchPred brPredOut[DECODE_WIDTH],
PC_Path recoveredPC
PC_Path recoveredPC,
BranchGlobalHistoryPath recoveredBrHistory
);
// Return address stack.
parameter RAS_ENTRY_NUM = 4;
parameter RAS_ENTRY_NUM = CONF_RAS_ENTRY_NUM;
typedef logic [$clog2(RAS_ENTRY_NUM)-1 : 0] RAS_IndexPath;
PC_Path ras[RAS_ENTRY_NUM];
PC_Path nextRAS;
Expand Down Expand Up @@ -94,6 +96,7 @@ output
// Initialize
flushTriggered = FALSE;
recoveredPC = '0;
recoveredBrHistory = '0;

pushRAS = FALSE;
popRAS = FALSE;
Expand Down Expand Up @@ -218,6 +221,7 @@ output
end
end
recoveredPC = decodedPC[addrCheckLane];
recoveredBrHistory = brPredIn[addrCheckLane].globalHistory;

// Update the RAS.
nextRAS = nextPC[addrCheckLane];
Expand Down
97 changes: 59 additions & 38 deletions Processor/Src/FetchUnit/BTB.sv
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import FetchUnitTypes::*;

module BTB(
NextPCStageIF.BTB port,
FetchStageIF.BTB next
FetchStageIF.BTB fetch
);

// BTB access
Expand All @@ -37,8 +37,7 @@ module BTB(

BTBQueueEntry btbQueue[BTB_QUEUE_SIZE];
BTBQueuePointerPath headPtr, tailPtr;

logic updateBtb;
BTBQueueEntry btbQueueWV;

generate
BlockMultiBankRAM #(
Expand Down Expand Up @@ -92,13 +91,8 @@ module BTB(

always_ff @(posedge port.clk) begin
// Push btb Queue
if (port.rst) begin
btbQueue[resetIndex % BTB_QUEUE_SIZE].btbWA <= '0;
btbQueue[resetIndex % BTB_QUEUE_SIZE].btbWV <= '0;
end
else if (pushBtbQueue) begin
btbQueue[headPtr].btbWA <= btbWA[INT_ISSUE_WIDTH-1];
btbQueue[headPtr].btbWV <= btbWV[INT_ISSUE_WIDTH-1];
if (pushBtbQueue) begin
btbQueue[tailPtr] <= btbQueueWV;
end
end

Expand All @@ -120,39 +114,66 @@ module BTB(
readIsCondBr[i] = btbRV[i].isCondBr;
end

// Write request from IntEx Stage
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin
btbWE[i] = FALSE;
end
updateBtb = FALSE;
pushBtbQueue = FALSE;

// Write to BTB.
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin
// Make BTB entry when branch is Taken.
if (updateBtb) begin
pushBtbQueue = port.brResult[i].valid && port.brResult[i].execTaken;
end
else begin
btbWE[i] = port.brResult[i].valid && port.brResult[i].execTaken;
updateBtb |= btbWE[i];
end

btbWE[i] = port.brResult[i].valid && port.brResult[i].execTaken;
btbWA[i] = ToBTB_Index(port.brResult[i].brAddr);
btbWV[i].tag = ToBTB_Tag(port.brResult[i].brAddr);
btbWV[i].data = ToBTB_Addr(port.brResult[i].nextAddr);
btbWV[i].valid = TRUE;
btbWV[i].isCondBr = port.brResult[i].isCondBr;
end

// Pop btb Queue
if (!empty && !updateBtb) begin
popBtbQueue = TRUE;
btbWE[0] = TRUE;
btbWA[0] = btbQueue[tailPtr].btbWA;
btbWV[0] = btbQueue[tailPtr].btbWV;
end
else begin
popBtbQueue = FALSE;
pushBtbQueue = FALSE;
// check whether bank conflict occurs
for (int i = 1; i < INT_ISSUE_WIDTH; i++) begin
if (btbWE[i]) begin
for (int j = 0; j < i; j++) begin
if (!btbWE[j]) begin // check only valid write
continue;
end

if (IsBankConflict(btbWA[i], btbWA[j])) begin
// Detect bank conflict
// push this write access to queue
btbWE[i] = FALSE;
pushBtbQueue = TRUE;
btbQueueWV.wv = btbWV[i];
btbQueueWV.wa = btbWA[i];
break;
end
end
end
end

// Write request from BTB Queue
popBtbQueue = FALSE;
if (!empty) begin
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin : outer
// Find idle write port
if (btbWE[i]) begin
continue;
end

// Check whether bank conflict occurs
for (int j = 0; j < INT_ISSUE_WIDTH; j++) begin
if (i == j || !btbWE[j]) begin
continue;
end

if (IsBankConflict(btbQueue[headPtr].wa, btbWA[j])) begin
// Detect bank conflict
// skip popping BTB queue
disable outer;
end
end

// Write request from BTB queue
popBtbQueue = TRUE;
btbWE[i] = TRUE;
btbWA[i] = btbQueue[headPtr].wa;
btbWV[i] = btbQueue[headPtr].wv;
end
end


Expand All @@ -176,9 +197,9 @@ module BTB(
popBtbQueue = FALSE;
end

next.readIsCondBr = readIsCondBr;
next.btbOut = btbOut;
next.btbHit = btbHit;
fetch.readIsCondBr = readIsCondBr;
fetch.btbOut = btbOut;
fetch.btbHit = btbHit;

end

Expand Down
134 changes: 75 additions & 59 deletions Processor/Src/FetchUnit/Bimodal.sv
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ import BasicTypes::*;
import MemoryMapTypes::*;
import FetchUnitTypes::*;

function automatic PHT_IndexPath ToPHT_Index_Local(PC_Path addr);
return
addr[
PHT_ENTRY_NUM_BIT_WIDTH + INSN_ADDR_BIT_WIDTH - 1:
INSN_ADDR_BIT_WIDTH
];
endfunction

module Bimodal(
NextPCStageIF.BranchPredictor port,
FetchStageIF.BranchPredictor next
FetchStageIF.BranchPredictor fetch
);

function automatic PHT_IndexPath ToPHT_Index_Local(PC_Path addr);
return
addr[
PHT_ENTRY_NUM_BIT_WIDTH + INSN_ADDR_BIT_WIDTH - 1:
INSN_ADDR_BIT_WIDTH
];
endfunction

PC_Path pcIn;

logic brPredTaken;
logic brPredTaken[FETCH_WIDTH];

// PHT control logic
logic phtWE[INT_ISSUE_WIDTH];
Expand All @@ -37,14 +37,12 @@ module Bimodal(
PHT_IndexPath phtRA[FETCH_WIDTH];
PHT_EntryPath phtRV[FETCH_WIDTH];

// assert when misprediction occured.
logic mispred;

logic pushPhtQueue, popPhtQueue;
logic full, empty;

PhtQueueEntry phtQueue[PHT_QUEUE_SIZE];
PhtQueuePointerPath headPtr, tailPtr;
PhtQueueEntry phtQueueWV;

logic updatePht;

Expand Down Expand Up @@ -95,13 +93,8 @@ module Bimodal(

always_ff @(posedge port.clk) begin
// Push Pht Queue
if (port.rst) begin
phtQueue[resetIndex % PHT_QUEUE_SIZE].phtWA <= '0;
phtQueue[resetIndex % PHT_QUEUE_SIZE].phtWV <= PHT_ENTRY_MAX / 2 + 1;
end
else if (pushPhtQueue) begin
phtQueue[headPtr].phtWA <= phtWA[INT_ISSUE_WIDTH-1];
phtQueue[headPtr].phtWV <= phtWV[INT_ISSUE_WIDTH-1];
if (pushPhtQueue) begin
phtQueue[tailPtr] <= phtQueueWV;
end
end

Expand All @@ -111,43 +104,30 @@ module Bimodal(
pcIn = port.predNextPC;

for (int i = 0; i < FETCH_WIDTH; i++) begin
next.phtPrevValue[i] = phtRV[i];
brPredTaken[i] = FALSE;
end

for (int i = 0; i < FETCH_WIDTH; i++) begin
fetch.phtPrevValue[i] = phtRV[i];

// Predict directions (Check the MSB).
brPredTaken =
phtRV[i][PHT_ENTRY_WIDTH - 1] && next.btbHit[i];
next.brPredTaken[i] = brPredTaken;
brPredTaken[i] =
phtRV[i][PHT_ENTRY_WIDTH - 1] && fetch.btbHit[i];

if (brPredTaken) begin
if (brPredTaken[i]) begin
// If brPred is taken, next instruction don't be executed.
break;
end
end
fetch.brPredTaken = brPredTaken;

// Negate first. (to discard the result of previous cycle)
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin
phtWE[i] = FALSE;
updatePht = FALSE;
pushPhtQueue = FALSE;
end

// Write request from IntEx Stage
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin
// When branch instruction is executed, update PHT.
if (updatePht) begin
pushPhtQueue = port.brResult[i].valid;
end
else begin
phtWE[i] = port.brResult[i].valid;
updatePht |= phtWE[i];
end

phtWE[i] = port.brResult[i].valid;
phtWA[i] = ToPHT_Index_Local(port.brResult[i].brAddr);

mispred = port.brResult[i].mispred && port.brResult[i].valid;

// Counter's value.
phtPrevValue[i] = port.brResult[i].phtPrevValue;

// Update PHT's counter (saturated up/down counter).
if (port.brResult[i].execTaken) begin
phtWV[i] = (phtPrevValue[i] == PHT_ENTRY_MAX) ?
Expand All @@ -157,10 +137,58 @@ module Bimodal(
phtWV[i] = (phtPrevValue[i] == 0) ?
0 : phtPrevValue[i] - 1;
end
end

// When miss prediction is occured, recovory history.
if (mispred) begin
break;
pushPhtQueue = FALSE;
// check whether bank conflict occurs
for (int i = 1; i < INT_ISSUE_WIDTH; i++) begin
if (phtWE[i]) begin
for (int j = 0; j < i; j++) begin
if (!phtWE[j]) begin // check only valid write
continue;
end

if (IsBankConflict(phtWA[i], phtWA[j])) begin
// Detect bank conflict
// push this write access to queue
phtWE[i] = FALSE;
pushPhtQueue = TRUE;
phtQueueWV.wv = phtWV[i];
phtQueueWV.wa = phtWA[i];
break;
end
end
end
end

// Write request from PHT Queue
popPhtQueue = FALSE;
if (!empty) begin
for (int i = 0; i < INT_ISSUE_WIDTH; i++) begin : outer
// Find idle write port
if (phtWE[i]) begin
continue;
end

// Check whether bank conflict occurs
for (int j = 0; j < INT_ISSUE_WIDTH; j++) begin
if (i == j || !phtWE[j]) begin
continue;
end

if (IsBankConflict(phtQueue[headPtr].wa, phtWA[j])) begin
// Detect bank conflict
// skip popping PHT queue
disable outer;
end
end

// Write request from PHT queue
popPhtQueue = TRUE;
phtWE[i] = TRUE;
phtWA[i] = phtQueue[headPtr].wa;
phtWV[i] = phtQueue[headPtr].wv;
disable outer;
end
end

Expand All @@ -169,18 +197,6 @@ module Bimodal(
phtRA[i] = ToPHT_Index_Local(pcIn + i*INSN_BYTE_WIDTH);
end


// Pop PHT Queue
if (!empty && !updatePht) begin
popPhtQueue = TRUE;
phtWE[0] = TRUE;
phtWA[0] = phtQueue[tailPtr].phtWA;
phtWV[0] = phtQueue[tailPtr].phtWV;
end
else begin
popPhtQueue = FALSE;
end

// In reset sequence, the write port 0 is used for initializing, and
// the other write ports are disabled.
if (port.rst) begin
Expand Down
Loading