mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-06-28 09:16:22 -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 flush_ftq_i,
|
||||||
input logic debug_mode_i,
|
input logic debug_mode_i,
|
||||||
input logic [63:0] vpc_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 instr_queue_overflow_i,
|
||||||
input logic [63:0] instr_queue_replay_addr_i,
|
input logic [63:0] instr_queue_replay_addr_i,
|
||||||
input logic serving_unaligned_i, // we have an unalinged instruction at the beginning
|
input logic serving_unaligned_i, // we have an unalinged instruction at the beginning
|
||||||
input ariane_pkg::bht_update_t bht_update_i,
|
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] valid_i,
|
||||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_branch_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 cf_t [ariane_pkg::INSTR_PER_FETCH-1:0] cf_type_i,
|
||||||
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] taken_rvc_cf_i,
|
|
||||||
output logic ftq_overflow_o,
|
output logic ftq_overflow_o,
|
||||||
// we potentially need INSTR_PER_FETCH predictions/cycle
|
// we potentially need INSTR_PER_FETCH predictions/cycle
|
||||||
output ariane_pkg::bht_prediction_t [ariane_pkg::INSTR_PER_FETCH-1:0] bht_prediction_o
|
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] 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_replay; // replay logic per instruction
|
||||||
logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_valid_branch;
|
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
|
// fetch target queue signals
|
||||||
logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] ftq_usage;
|
logic [$clog2(ariane_pkg::FETCH_FIFO_DEPTH)-1:0] ftq_usage;
|
||||||
|
@ -113,8 +112,6 @@ module bht #(
|
||||||
end
|
end
|
||||||
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
|
// realigned pc address to fetch block width
|
||||||
assign realigned_vpc = {vpc_i[63:ROW_ADDR_BITS+1], (ROW_ADDR_BITS+1)'(0)};
|
assign realigned_vpc = {vpc_i[63:ROW_ADDR_BITS+1], (ROW_ADDR_BITS+1)'(0)};
|
||||||
assign ftq_entry_i = { gshare_index, // gshare index
|
assign ftq_entry_i = { gshare_index, // gshare index
|
||||||
|
@ -124,25 +121,25 @@ module bht #(
|
||||||
};
|
};
|
||||||
assign push_ftq = (|is_valid_branch);
|
assign push_ftq = (|is_valid_branch);
|
||||||
|
|
||||||
assign realigned_update_pc = bht_update_i.pc + (1<<$clog2(ariane_pkg::INSTR_PER_FETCH));
|
assign realigned_update_pc = bht_update_i.pc + 2;
|
||||||
assign is_unaligned_instr = ftq_entry_o.serving_unaligned
|
assign is_unaligned_instr = ftq_entry_o.serving_unaligned & (&bht_update_i.pc[ROW_ADDR_BITS + OFFSET - 1:OFFSET]);
|
||||||
& (bht_update_i.pc[ROW_ADDR_BITS + OFFSET - 1:OFFSET] == {ROW_ADDR_BITS{1'b1}});
|
|
||||||
assign pop_ftq = bht_update_i.valid & ((bp_count_q == 1) || ftq_entry_o.bp_count == 1);
|
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_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 update_pc = ftq_entry_o.gshare_index;
|
||||||
assign ftq_overflow_o = full_ftq & push_ftq;
|
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
|
// 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,
|
// 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.
|
// 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:
|
// an instruction is a valid branch instruction to push to fetch target queue if:
|
||||||
// 1) it is a valid branch instruction
|
// 1) it is a valid branch instruction
|
||||||
// 2) it is not a replay
|
// 2) it is not a replay
|
||||||
// 3) no taken control flow before it in the same fetch block
|
// 3) no taken control flow before it in the same fetch block
|
||||||
for (genvar i = 0; i < ariane_pkg::INSTR_PER_FETCH; i++) begin
|
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
|
if (i == 0) begin
|
||||||
assign is_valid_branch[i] = is_branch_i[i] & ~is_replay[i];
|
assign is_valid_branch[i] = is_branch_i[i] & ~is_replay[i];
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -217,8 +214,7 @@ module bht #(
|
||||||
bht_d[update_pc][update_row_index].saturation_counter = 2'b01;
|
bht_d[update_pc][update_row_index].saturation_counter = 2'b01;
|
||||||
else
|
else
|
||||||
bht_d[update_pc][update_row_index].saturation_counter = 2'b10;
|
bht_d[update_pc][update_row_index].saturation_counter = 2'b10;
|
||||||
end else
|
end else if (saturation_counter == 2'b11) begin
|
||||||
if (saturation_counter == 2'b11) begin
|
|
||||||
// we can safely decrease it
|
// we can safely decrease it
|
||||||
if (!bht_update_i.taken)
|
if (!bht_update_i.taken)
|
||||||
bht_d[update_pc][update_row_index].saturation_counter = saturation_counter - 1;
|
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] replay_addr;
|
||||||
logic [63:0] instr_queue_replay_addr;
|
logic [63:0] instr_queue_replay_addr;
|
||||||
logic instr_queue_overflow, ftq_overflow;
|
logic instr_queue_overflow, ftq_overflow;
|
||||||
|
logic [$clog2(INSTR_PER_FETCH)-1:0] push_instr_cnt;
|
||||||
// replay if any of the queue overflows
|
// replay if any of the queue overflows
|
||||||
assign replay = instr_queue_overflow | ftq_overflow;
|
assign replay = instr_queue_overflow | ftq_overflow;
|
||||||
assign replay_addr = ftq_overflow ? addr[0] : instr_queue_replay_addr;
|
assign replay_addr = ftq_overflow ? addr[0] : instr_queue_replay_addr;
|
||||||
|
@ -388,13 +389,13 @@ module frontend #(
|
||||||
.flush_ftq_i ( flush_i ),
|
.flush_ftq_i ( flush_i ),
|
||||||
.debug_mode_i,
|
.debug_mode_i,
|
||||||
.vpc_i ( icache_vaddr_q ),
|
.vpc_i ( icache_vaddr_q ),
|
||||||
|
.push_instr_cnt_i ( push_instr_cnt ),
|
||||||
.instr_queue_overflow_i ( instr_queue_overflow ), // from instruction queue
|
.instr_queue_overflow_i ( instr_queue_overflow ), // from instruction queue
|
||||||
.instr_queue_replay_addr_i ( instr_queue_replay_addr ),
|
.instr_queue_replay_addr_i ( instr_queue_replay_addr ),
|
||||||
.is_branch_i ( is_branch ),
|
.is_branch_i ( is_branch ),
|
||||||
.valid_i ( instruction_valid ),
|
.valid_i ( instruction_valid ),
|
||||||
.serving_unaligned_i ( serving_unaligned ),
|
.serving_unaligned_i ( serving_unaligned ),
|
||||||
.taken_rvc_cf_i ( taken_rvc_cf ),
|
.cf_type_i ( cf_type ),
|
||||||
.taken_rvi_cf_i ( taken_rvi_cf ),
|
|
||||||
.bht_update_i ( bht_update ),
|
.bht_update_i ( bht_update ),
|
||||||
.ftq_overflow_o ( ftq_overflow ),
|
.ftq_overflow_o ( ftq_overflow ),
|
||||||
.bht_prediction_o ( bht_prediction )
|
.bht_prediction_o ( bht_prediction )
|
||||||
|
@ -432,6 +433,7 @@ module frontend #(
|
||||||
.cf_type_i ( cf_type ),
|
.cf_type_i ( cf_type ),
|
||||||
.valid_i ( instruction_valid ), // from re-aligner
|
.valid_i ( instruction_valid ), // from re-aligner
|
||||||
.consumed_o ( instr_queue_consumed ),
|
.consumed_o ( instr_queue_consumed ),
|
||||||
|
.push_instr_cnt_o ( push_instr_cnt ),
|
||||||
.ftq_overflow_i ( ftq_overflow ), // from branch predictor
|
.ftq_overflow_i ( ftq_overflow ), // from branch predictor
|
||||||
.ready_o ( instr_queue_ready ),
|
.ready_o ( instr_queue_ready ),
|
||||||
.overflow_o ( instr_queue_overflow ),
|
.overflow_o ( instr_queue_overflow ),
|
||||||
|
|
|
@ -61,6 +61,7 @@ module instr_queue (
|
||||||
input logic ftq_overflow_i,
|
input logic ftq_overflow_i,
|
||||||
// replay instruction because one of the FIFO was already full
|
// replay instruction because one of the FIFO was already full
|
||||||
output logic overflow_o,
|
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
|
output logic [63:0] replay_addr_o, // address at which to replay this instruction
|
||||||
// to processor backend
|
// to processor backend
|
||||||
output ariane_pkg::fetch_entry_t fetch_entry_o,
|
output ariane_pkg::fetch_entry_t fetch_entry_o,
|
||||||
|
@ -154,6 +155,7 @@ module instr_queue (
|
||||||
.popcount_o ( popcount )
|
.popcount_o ( popcount )
|
||||||
);
|
);
|
||||||
assign shamt = popcount[$bits(shamt)-1:0];
|
assign shamt = popcount[$bits(shamt)-1:0];
|
||||||
|
assign push_instr_cnt_o = shamt_push_instr;
|
||||||
|
|
||||||
// save the shift amount for next cycle
|
// save the shift amount for next cycle
|
||||||
assign idx_is_d = idx_is_q + shamt;
|
assign idx_is_d = idx_is_q + shamt;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue