mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
Fix a minor bug in BHT
This commit is contained in:
parent
f70c961e7a
commit
c9537f8221
3 changed files with 15 additions and 15 deletions
|
@ -24,14 +24,14 @@ module bht #(
|
|||
input logic flush_ftq_i,
|
||||
input logic debug_mode_i,
|
||||
input logic [63:0] vpc_i,
|
||||
input logic [$clog2(ariane_pkg::INSTR_PER_FETCH)-1:0] push_instr_cnt_i,
|
||||
input logic instr_queue_overflow_i,
|
||||
input logic [63:0] instr_queue_replay_addr_i,
|
||||
input logic serving_unaligned_i, // we have an unalinged instruction at the beginning
|
||||
input ariane_pkg::bht_update_t bht_update_i,
|
||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid_i,
|
||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_branch_i,
|
||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvi_cf_i,
|
||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvc_cf_i,
|
||||
input cf_t [ariane_pkg::INSTR_PER_FETCH-1:0] cf_type_i,
|
||||
output logic ftq_overflow_o,
|
||||
// we potentially need INSTR_PER_FETCH predictions/cycle
|
||||
output ariane_pkg::bht_prediction_t [ariane_pkg::INSTR_PER_FETCH-1:0] bht_prediction_o
|
||||
|
@ -74,7 +74,6 @@ module bht #(
|
|||
logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid_taken_cf;
|
||||
logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_replay; // replay logic per instruction
|
||||
logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_valid_branch;
|
||||
logic [$clog2(ariane_pkg::INSTR_PER_FETCH)-1:0] replay_pos;
|
||||
|
||||
// fetch target queue signals
|
||||
logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] ftq_usage;
|
||||
|
@ -113,8 +112,6 @@ module bht #(
|
|||
end
|
||||
end
|
||||
|
||||
// check if the instructions are valid control flows
|
||||
assign valid_taken_cf = valid_i & (taken_rvc_cf_i | taken_rvi_cf_i);
|
||||
// realigned pc address to fetch block width
|
||||
assign realigned_vpc = {vpc_i[63:ROW_ADDR_BITS+1], (ROW_ADDR_BITS+1)'(0)};
|
||||
assign ftq_entry_i = { gshare_index, // gshare index
|
||||
|
@ -124,25 +121,25 @@ module bht #(
|
|||
};
|
||||
assign push_ftq = (|is_valid_branch);
|
||||
|
||||
assign realigned_update_pc = bht_update_i.pc + (1<<$clog2(ariane_pkg::INSTR_PER_FETCH));
|
||||
assign is_unaligned_instr = ftq_entry_o.serving_unaligned
|
||||
& (bht_update_i.pc[ROW_ADDR_BITS + OFFSET - 1:OFFSET] == {ROW_ADDR_BITS{1'b1}});
|
||||
assign realigned_update_pc = bht_update_i.pc + 2;
|
||||
assign is_unaligned_instr = ftq_entry_o.serving_unaligned & (&bht_update_i.pc[ROW_ADDR_BITS + OFFSET - 1:OFFSET]);
|
||||
assign pop_ftq = bht_update_i.valid & ((bp_count_q == 1) || ftq_entry_o.bp_count == 1);
|
||||
assign update_row_index = is_unaligned_instr ? 0 : bht_update_i.pc[ROW_ADDR_BITS + OFFSET - 1:OFFSET];
|
||||
assign update_pc = ftq_entry_o.gshare_index;
|
||||
assign ftq_overflow_o = full_ftq & push_ftq;
|
||||
|
||||
// if replay starts from an unaglined address, replay position should be 0.
|
||||
assign replay_pos = serving_unaligned_i ? 0 : instr_queue_replay_addr_i[$clog2(ariane_pkg::INSTR_PER_FETCH):1];
|
||||
// if the incoming instruction is a replay at the replay address, then the rest of the fetched
|
||||
// instruction should also be replay. For example, in 64 bit fetch if the replay starts from 0x42,
|
||||
// the replay mask should be 1 1 1 0 from the highest to lowest.
|
||||
assign is_replay = {ariane_pkg::INSTR_PER_FETCH{instr_queue_overflow_i}} << replay_pos;
|
||||
assign is_replay = {ariane_pkg::INSTR_PER_FETCH{instr_queue_overflow_i}} << push_instr_cnt_i;
|
||||
// an instruction is a valid branch instruction to push to fetch target queue if:
|
||||
// 1) it is a valid branch instruction
|
||||
// 2) it is not a replay
|
||||
// 3) no taken control flow before it in the same fetch block
|
||||
for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin
|
||||
// check if the instructions are valid control flows
|
||||
assign valid_taken_cf[i] = valid_i[i] & (cf_type_i[i] != ariane_pkg::NoCF);
|
||||
|
||||
if (i == 0) begin
|
||||
assign is_valid_branch[i] = is_branch_i[i] & ~is_replay[i];
|
||||
end else begin
|
||||
|
@ -217,8 +214,7 @@ module bht #(
|
|||
bht_d[update_pc][update_row_index].saturation_counter = 2'b01;
|
||||
else
|
||||
bht_d[update_pc][update_row_index].saturation_counter = 2'b10;
|
||||
end else
|
||||
if (saturation_counter == 2'b11) begin
|
||||
end else 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 = saturation_counter - 1;
|
||||
|
|
|
@ -68,6 +68,7 @@ module frontend #(
|
|||
logic [63:0] replay_addr;
|
||||
logic [63:0] instr_queue_replay_addr;
|
||||
logic instr_queue_overflow, ftq_overflow;
|
||||
logic [$clog2(INSTR_PER_FETCH)-1:0] push_instr_cnt;
|
||||
// replay if any of the queue overflows
|
||||
assign replay = instr_queue_overflow | ftq_overflow;
|
||||
assign replay_addr = ftq_overflow ? addr[0] : instr_queue_replay_addr;
|
||||
|
@ -388,13 +389,13 @@ module frontend #(
|
|||
.flush_ftq_i ( flush_i ),
|
||||
.debug_mode_i,
|
||||
.vpc_i ( icache_vaddr_q ),
|
||||
.push_instr_cnt_i ( push_instr_cnt ),
|
||||
.instr_queue_overflow_i ( instr_queue_overflow ), // from instruction queue
|
||||
.instr_queue_replay_addr_i ( instr_queue_replay_addr ),
|
||||
.is_branch_i ( is_branch ),
|
||||
.valid_i ( instruction_valid ),
|
||||
.serving_unaligned_i ( serving_unaligned ),
|
||||
.taken_rvc_cf_i ( taken_rvc_cf ),
|
||||
.taken_rvi_cf_i ( taken_rvi_cf ),
|
||||
.cf_type_i ( cf_type ),
|
||||
.bht_update_i ( bht_update ),
|
||||
.ftq_overflow_o ( ftq_overflow ),
|
||||
.bht_prediction_o ( bht_prediction )
|
||||
|
@ -432,6 +433,7 @@ module frontend #(
|
|||
.cf_type_i ( cf_type ),
|
||||
.valid_i ( instruction_valid ), // from re-aligner
|
||||
.consumed_o ( instr_queue_consumed ),
|
||||
.push_instr_cnt_o ( push_instr_cnt ),
|
||||
.ftq_overflow_i ( ftq_overflow ), // from branch predictor
|
||||
.ready_o ( instr_queue_ready ),
|
||||
.overflow_o ( instr_queue_overflow ),
|
||||
|
|
|
@ -61,6 +61,7 @@ module instr_queue (
|
|||
input logic ftq_overflow_i,
|
||||
// replay instruction because one of the FIFO was already full
|
||||
output logic overflow_o,
|
||||
output logic [$clog2(ariane_pkg::INSTR_PER_FETCH)-1:0] push_instr_cnt_o,
|
||||
output logic [63:0] replay_addr_o, // address at which to replay this instruction
|
||||
// to processor backend
|
||||
output ariane_pkg::fetch_entry_t fetch_entry_o,
|
||||
|
@ -154,6 +155,7 @@ module instr_queue (
|
|||
.popcount_o ( popcount )
|
||||
);
|
||||
assign shamt = popcount[$bits(shamt)-1:0];
|
||||
assign push_instr_cnt_o = shamt_push_instr;
|
||||
|
||||
// save the shift amount for next cycle
|
||||
assign idx_is_d = idx_is_q + shamt;
|
||||
|
|
Loading…
Add table
Reference in a new issue