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

bp: add BHT with private history #2793

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ sources:
# Frontend (i.e., fetch, decode, dispatch)
- core/frontend/btb.sv
- core/frontend/bht.sv
- core/frontend/bht2lvl.sv
- core/frontend/ras.sv
- core/frontend/instr_scan.sv
- core/frontend/instr_queue.sv
Expand Down
1 change: 1 addition & 0 deletions Flist.ariane
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ core/decoder.sv
core/ex_stage.sv
core/frontend/btb.sv
core/frontend/bht.sv
core/frontend/bht2lvl.sv
core/frontend/ras.sv
core/frontend/instr_scan.sv
core/frontend/instr_queue.sv
Expand Down
1 change: 1 addition & 0 deletions core/Flist.cva6
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ ${CVA6_REPO_DIR}/core/cva6_fifo_v3.sv
// What is "frontend"?
${CVA6_REPO_DIR}/core/frontend/btb.sv
${CVA6_REPO_DIR}/core/frontend/bht.sv
${CVA6_REPO_DIR}/core/frontend/bht2lvl.sv
${CVA6_REPO_DIR}/core/frontend/ras.sv
${CVA6_REPO_DIR}/core/frontend/instr_scan.sv
${CVA6_REPO_DIR}/core/frontend/instr_queue.sv
Expand Down
135 changes: 135 additions & 0 deletions core/frontend/bht2lvl.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2025 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Original author: Gianmarco Ottavi, University of Bologna
// Description: Private history BHT

module bht2lvl #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter int unsigned NR_ENTRIES = 256,
parameter int unsigned HISTORY_LENGTH = 3,
parameter type bht_update_t = logic
) (
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic [ CVA6Cfg.VLEN-1:0] vpc_i,
input bht_update_t bht_update_i,
// we potentially need INSTR_PER_FETCH predictions/cycle
output ariane_pkg::bht_prediction_t [CVA6Cfg.INSTR_PER_FETCH-1:0] bht_prediction_o
);

// the last bit is always zero, we don't need it for indexing
localparam OFFSET = CVA6Cfg.RVC == 1'b1 ? 1 : 2;
// re-shape the branch history table
localparam NR_ROWS = NR_ENTRIES / CVA6Cfg.INSTR_PER_FETCH;
// number of bits needed to index the row
localparam ROW_ADDR_BITS = $clog2(CVA6Cfg.INSTR_PER_FETCH);
localparam ROW_INDEX_BITS = CVA6Cfg.RVC == 1'b1 ? $clog2(CVA6Cfg.INSTR_PER_FETCH) : 1;
// number of bits we should use for prediction
localparam PREDICTION_BITS = $clog2(NR_ROWS) + OFFSET + ROW_ADDR_BITS;

struct packed {
logic valid;
logic [HISTORY_LENGTH-1:0] hist;
logic [2**HISTORY_LENGTH-1:0][1:0] saturation_counter;
}
bht_d[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0],
bht_q[NR_ROWS-1:0][CVA6Cfg.INSTR_PER_FETCH-1:0];


logic [$clog2(NR_ROWS)-1:0] index, update_pc;
logic [HISTORY_LENGTH-1:0] update_hist;
logic [ROW_INDEX_BITS-1:0] update_row_index;

assign index = vpc_i[PREDICTION_BITS-1:ROW_ADDR_BITS+OFFSET];
assign update_pc = bht_update_i.pc[PREDICTION_BITS-1:ROW_ADDR_BITS+OFFSET];
assign update_hist = bht_q[update_pc][update_row_index].hist;

if (CVA6Cfg.RVC) begin : gen_update_row_index
assign update_row_index = bht_update_i.pc[ROW_ADDR_BITS+OFFSET-1:OFFSET];
end else begin
assign update_row_index = '0;
end


logic [1:0] saturation_counter;

// Get the current history of the entry
logic [CVA6Cfg.INSTR_PER_FETCH-1:0][HISTORY_LENGTH-1:0] read_history;
for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin
assign read_history[i] = bht_q[index][i].hist;
end

// prediction assignment
for (genvar i = 0; i < CVA6Cfg.INSTR_PER_FETCH; i++) begin : gen_bht_output
assign bht_prediction_o[i].valid = bht_q[index][i].valid;
assign bht_prediction_o[i].taken = bht_q[index][i].saturation_counter[read_history[i]][1] == 1'b1;
end

always_comb begin : update_bht
bht_d = bht_q;
saturation_counter = bht_q[update_pc][update_row_index].saturation_counter[update_hist];

if (bht_update_i.valid) begin
bht_d[update_pc][update_row_index].valid = 1'b1;

if (saturation_counter == 2'b11) begin
// we can safely decrease it
if (!bht_update_i.taken)
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter - 1;
// then check if it saturated in the negative regime e.g.: branch not taken
end else if (saturation_counter == 2'b00) begin
// we can safely increase it
if (bht_update_i.taken)
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter + 1;
end else begin // otherwise we are not in any boundaries and can decrease or increase it
if (bht_update_i.taken)
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter + 1;
else
bht_d[update_pc][update_row_index].saturation_counter[update_hist] = saturation_counter - 1;
end

bht_d[update_pc][update_row_index].hist = {
update_hist[HISTORY_LENGTH-2:0], bht_update_i.taken
};
end
end

always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
for (int unsigned i = 0; i < NR_ROWS; i++) begin
for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin
bht_q[i][j] <= '0;
for (int k = 0; k < 2 ** HISTORY_LENGTH; k++) begin
bht_q[i][j].saturation_counter[k] <= 2'b10;
end
end
end
end else begin
// evict all entries
if (flush_i) begin
for (int i = 0; i < NR_ROWS; i++) begin
for (int j = 0; j < CVA6Cfg.INSTR_PER_FETCH; j++) begin
bht_q[i][j].valid <= 1'b0;
bht_q[i][j].hist <= '0;
for (int k = 0; k < 2 ** HISTORY_LENGTH; k++) begin
bht_q[i][j].saturation_counter[k] <= 2'b10;
end
end
end
end else begin
bht_q <= bht_d;
end
end
end


endmodule
16 changes: 15 additions & 1 deletion core/frontend/frontend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ module frontend

if (CVA6Cfg.BHTEntries == 0) begin
assign bht_prediction = '0;
end else begin : bht_gen
end else if (CVA6Cfg.BPType == config_pkg::BHT) begin : bht_gen
bht #(
.CVA6Cfg (CVA6Cfg),
.bht_update_t(bht_update_t),
Expand All @@ -524,6 +524,20 @@ module frontend
.bht_update_i (bht_update),
.bht_prediction_o(bht_prediction)
);
end else if (CVA6Cfg.BPType == config_pkg::PH_BHT) begin : bht2lvl_gen
bht2lvl #(
.CVA6Cfg (CVA6Cfg),
.NR_ENTRIES (CVA6Cfg.BHTEntries),
.HISTORY_LENGTH(CVA6Cfg.BHTHist),
.bht_update_t (bht_update_t)
) i_bht (
.clk_i,
.rst_ni,
.flush_i (flush_bp_i),
.vpc_i (icache_vaddr_q),
.bht_update_i (bht_update),
.bht_prediction_o(bht_prediction)
);
end

// we need to inspect up to CVA6Cfg.INSTR_PER_FETCH instructions for branches
Expand Down
2 changes: 2 additions & 0 deletions core/include/build_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ package build_config_pkg;
cfg.ExceptionAddress = CVA6Cfg.ExceptionAddress;
cfg.RASDepth = CVA6Cfg.RASDepth;
cfg.BTBEntries = CVA6Cfg.BTBEntries;
cfg.BPType = CVA6Cfg.BPType;
cfg.BHTEntries = CVA6Cfg.BHTEntries;
cfg.BHTHist = CVA6Cfg.BHTHist;
cfg.DmBaseAddress = CVA6Cfg.DmBaseAddress;
cfg.TvalEn = CVA6Cfg.TvalEn;
cfg.DirectVecOnly = CVA6Cfg.DirectVecOnly;
Expand Down
12 changes: 12 additions & 0 deletions core/include/config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ package config_pkg;
HPDCACHE_WT_WB = 4
} cache_type_t;

/// Branch predictor parameter
typedef enum logic {
BHT = 0, // Bimodal predictor
PH_BHT = 1 // Private History Bimodal predictor
} bp_type_t;

/// Data and Address length
typedef enum logic [3:0] {
ModeOff = 0,
Expand Down Expand Up @@ -214,8 +220,12 @@ package config_pkg;
int unsigned RASDepth;
// Branch target buffer entries
int unsigned BTBEntries;
// Branch predictor type
bp_type_t BPType;
// Branch history entries
int unsigned BHTEntries;
// Branch history bits
int unsigned BHTHist;
// MMU instruction TLB entries
int unsigned InstrTlbEntries;
// MMU data TLB entries
Expand Down Expand Up @@ -299,7 +309,9 @@ package config_pkg;
logic [63:0] ExceptionAddress;
int unsigned RASDepth;
int unsigned BTBEntries;
bp_type_t BPType;
int unsigned BHTEntries;
int unsigned BHTHist;
int unsigned InstrTlbEntries;
int unsigned DataTlbEntries;
bit unsigned UseSharedTlb;
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a60x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(2),
BTBEntries: unsigned'(0),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(32),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(0),
DirectVecOnly: bit'(1),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a65x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(2),
BTBEntries: unsigned'(0),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(32),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(0),
DirectVecOnly: bit'(1),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_embedded_config_pkg_deprecated.sv
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_ima_sv32_fpga_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: unsigned'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imac_sv0_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: unsigned'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imac_sv32_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a6_imafc_sv32_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a60ax_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{
ExceptionAddress: 64'h808,
RASDepth: unsigned'(4),
BTBEntries: unsigned'(16),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(64),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(1),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_hpdcache_wb_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdch_sv39_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ package cva6_config_pkg;
ExceptionAddress: 64'h808,
RASDepth: unsigned'(CVA6ConfigRASDepth),
BTBEntries: unsigned'(CVA6ConfigBTBEntries),
BPType: config_pkg::BHT,
BHTEntries: unsigned'(CVA6ConfigBHTEntries),
BHTHist: unsigned'(3),
DmBaseAddress: 64'h0,
TvalEn: bit'(CVA6ConfigTvalEn),
DirectVecOnly: bit'(0),
Expand Down
Loading