Skip to content
Snippets Groups Projects
Commit 7d26784a authored by Alban Gruin's avatar Alban Gruin
Browse files

frontend: fix CF accounting


Signed-off-by: default avatarAlban Gruin <alban.gruin@irit.fr>
parent e127e7fa
No related branches found
No related tags found
No related merge requests found
...@@ -146,6 +146,7 @@ module frontend import ariane_pkg::*; #( ...@@ -146,6 +146,7 @@ module frontend import ariane_pkg::*; #(
logic [INSTR_PER_FETCH-1:0] is_jump; logic [INSTR_PER_FETCH-1:0] is_jump;
logic [INSTR_PER_FETCH-1:0] is_return; logic [INSTR_PER_FETCH-1:0] is_return;
logic [INSTR_PER_FETCH-1:0] is_jalr; logic [INSTR_PER_FETCH-1:0] is_jalr;
logic [INSTR_PER_FETCH-1:0] is_cf;
for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin for (genvar i = 0; i < INSTR_PER_FETCH; i++) begin
// branch history table -> BHT // branch history table -> BHT
...@@ -158,6 +159,9 @@ module frontend import ariane_pkg::*; #( ...@@ -158,6 +159,9 @@ module frontend import ariane_pkg::*; #(
assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]); assign is_jump[i] = instruction_valid[i] & (rvi_jump[i] | rvc_jump[i]);
// unconditional jumps with unknown target -> BTB // unconditional jumps with unknown target -> BTB
assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & ~is_call[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]); assign is_jalr[i] = instruction_valid[i] & ~is_return[i] & ~is_call[i] & (rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
// cf that needs a prediction
assign is_cf[i] = instruction_valid[i] & (rvi_branch[i] | rvc_branch[i] | rvi_jalr[i] | rvc_jalr[i] | rvc_jr[i]);
end end
// taken/not taken // taken/not taken
...@@ -423,6 +427,7 @@ module frontend import ariane_pkg::*; #( ...@@ -423,6 +427,7 @@ module frontend import ariane_pkg::*; #(
.flush_i ( flush_i ), .flush_i ( flush_i ),
.instr_i ( instr ), // from re-aligner .instr_i ( instr ), // from re-aligner
.addr_i ( addr ), // from re-aligner .addr_i ( addr ), // from re-aligner
.is_cf_i ( is_cf ),
.exception_i ( icache_ex_valid_q ), // from I$ .exception_i ( icache_ex_valid_q ), // from I$
.exception_addr_i ( icache_vaddr_q ), .exception_addr_i ( icache_vaddr_q ),
.predict_address_i ( predict_address ), .predict_address_i ( predict_address ),
......
...@@ -49,6 +49,7 @@ module instr_queue ( ...@@ -49,6 +49,7 @@ module instr_queue (
input logic flush_i, input logic flush_i,
input logic [ariane_pkg::INSTR_PER_FETCH-1:0][31:0] instr_i, input logic [ariane_pkg::INSTR_PER_FETCH-1:0][31:0] instr_i,
input logic [ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i, input logic [ariane_pkg::INSTR_PER_FETCH-1:0][riscv::VLEN-1:0] addr_i,
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] is_cf_i,
input logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid_i, input logic [ariane_pkg::INSTR_PER_FETCH-1:0] valid_i,
output logic ready_o, output logic ready_o,
output logic [ariane_pkg::INSTR_PER_FETCH-1:0] consumed_o, output logic [ariane_pkg::INSTR_PER_FETCH-1:0] consumed_o,
...@@ -73,6 +74,7 @@ module instr_queue ( ...@@ -73,6 +74,7 @@ module instr_queue (
typedef struct packed { typedef struct packed {
logic [31:0] instr; // instruction word logic [31:0] instr; // instruction word
ariane_pkg::cf_t cf; // branch was taken ariane_pkg::cf_t cf; // branch was taken
logic is_cf; // instruction is a cf that needs a prediction (ie. not a jump)
ariane_pkg::frontend_exception_t ex; // exception happened ariane_pkg::frontend_exception_t ex; // exception happened
logic [riscv::VLEN-1:0] ex_vaddr; // lower VLEN bits of tval for exception logic [riscv::VLEN-1:0] ex_vaddr; // lower VLEN bits of tval for exception
} instr_data_t; } instr_data_t;
...@@ -127,7 +129,7 @@ module instr_queue ( ...@@ -127,7 +129,7 @@ module instr_queue (
logic output_is_mem; logic output_is_mem;
// cf count // cf count
logic [ariane_pkg::INSTR_PER_FETCH-1:0] input_is_cf; logic [ariane_pkg::INSTR_PER_FETCH*2-1:0] input_is_cf;
logic [ariane_pkg::INSTR_PER_FETCH-1:0] fifo_has_no_cf; logic [ariane_pkg::INSTR_PER_FETCH-1:0] fifo_has_no_cf;
logic output_is_cf; logic output_is_cf;
...@@ -220,6 +222,8 @@ module instr_queue ( ...@@ -220,6 +222,8 @@ module instr_queue (
assign instr[i + ariane_pkg::INSTR_PER_FETCH] = instr_i[i]; assign instr[i + ariane_pkg::INSTR_PER_FETCH] = instr_i[i];
assign cf[i] = cf_type_i[i]; assign cf[i] = cf_type_i[i];
assign cf[i + ariane_pkg::INSTR_PER_FETCH] = cf_type_i[i]; assign cf[i + ariane_pkg::INSTR_PER_FETCH] = cf_type_i[i];
assign input_is_cf[i] = is_cf_i[i];
assign input_is_cf[i + ariane_pkg::INSTR_PER_FETCH] = is_cf_i[i];
end end
// shift the inputs // shift the inputs
...@@ -230,7 +234,7 @@ module instr_queue ( ...@@ -230,7 +234,7 @@ module instr_queue (
assign instr_data_in[i].ex = exception_i; // exceptions hold for the whole fetch packet assign instr_data_in[i].ex = exception_i; // exceptions hold for the whole fetch packet
assign instr_data_in[i].ex_vaddr = exception_addr_i; assign instr_data_in[i].ex_vaddr = exception_addr_i;
assign input_is_mem_in[i] = input_is_mem[i + idx_is_q]; assign input_is_mem_in[i] = input_is_mem[i + idx_is_q];
assign input_is_cf[i] = !(cf[i + idx_is_q] inside {ariane_pkg::NoCF, ariane_pkg::Jump}); assign instr_data_in[i].is_cf = input_is_cf[i + idx_is_q];
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
end end
...@@ -346,8 +350,6 @@ module instr_queue ( ...@@ -346,8 +350,6 @@ module instr_queue (
(instr_data_out[i].instr[6:0] == riscv::OpcodeStoreFp) | (instr_data_out[i].instr[6:0] == riscv::OpcodeStoreFp) |
(instr_data_out[i].instr[6:0] == riscv::OpcodeAmo)); (instr_data_out[i].instr[6:0] == riscv::OpcodeAmo));
assign fifo_output_is_cf[i] = !(instr_data_out[i].cf inside {ariane_pkg::NoCF, ariane_pkg::Jump});
fifo_v3 #( fifo_v3 #(
.DEPTH ( ariane_pkg::FETCH_FIFO_DEPTH ), .DEPTH ( ariane_pkg::FETCH_FIFO_DEPTH ),
.dtype (logic) .dtype (logic)
...@@ -377,9 +379,9 @@ module instr_queue ( ...@@ -377,9 +379,9 @@ module instr_queue (
.empty_o (fifo_has_no_cf[i]), .empty_o (fifo_has_no_cf[i]),
.usage_o (), .usage_o (),
.data_i (1'b1), .data_i (1'b1),
.push_i (push_instr_fifo[i] & !(instr_data_in[i].cf inside {ariane_pkg::NoCF, ariane_pkg::Jump})), .push_i (push_instr_fifo[i] & instr_data_in[i].is_cf),
.data_o (), .data_o (),
.pop_i (pop_instr[i] & fifo_output_is_cf[i]) .pop_i (pop_instr[i] & instr_data_out[i].is_cf)
); );
end end
// or reduce and check whether we are retiring a taken branch (might be that the corresponding) // or reduce and check whether we are retiring a taken branch (might be that the corresponding)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment