Fix in calculating index into btb

This commit is contained in:
Florian Zaruba 2017-06-20 18:42:54 +02:00
parent 848a06ef77
commit 3c7c45ff1b
4 changed files with 21 additions and 18 deletions

View file

@ -74,7 +74,6 @@ module branch_unit (
automatic logic [63:0] jump_base = (operator_i == JALR) ? operand_a_i : pc_i;
target_address = 64'b0;
resolved_branch_o.pc = pc_i;
resolved_branch_o.target_address = 64'b0;
resolved_branch_o.is_taken = 1'b0;
resolved_branch_o.valid = branch_valid_i;
@ -92,17 +91,18 @@ module branch_unit (
// if we need to put the branch target address in a destination register, output it here to WB
branch_result_o = next_pc;
// save PC - we need this to get the target row in the branch target buffer
// we play this trick with the branch instruction which wraps a byte boundary:
// |---------- Place the prediction on this PC
// \/
// ____________________________________________________
// |branch [15:0] | branch[31:16] | compressed 1[15:0] |
// |____________________________________________________
// This will relief the pre-fetcher to re-fetch partially fetched unaligned branch instructions e.g.:
// we don't have a back arch between the pre-fetcher and decoder/instruction FIFO.
resolved_branch_o.pc = (is_compressed_instr_i || pc_i[1] == 1'b0) ? pc_i : ({pc_i[63:2], 2'b0} + 64'h4);
if (branch_valid_i) begin
// save PC - we need this to get the target row in the branch target buffer
// we play this trick with the branch instruction which wraps a byte boundary:
// |---------- Place the prediction on this PC
// \/
// ____________________________________________________
// |branch [15:0] | branch[31:16] | compressed 1[15:0] |
// |____________________________________________________
// This will relief the prefetcher to re-fetch partially fetched unaligned branch instructions e.g.:
// we don't have a back arch between prefetcher and decoder/instruction FIFO.
resolved_branch_o.pc = (is_compressed_instr_i || pc_i[1] == 1'b0) ? pc_i : ({pc_i[63:2], 2'b0} + 64'h4);
// save if the branch instruction was in the lower 16 bit of the instruction word
// the first case is a compressed instruction which is in slot 0
// the other case is a misaligned uncompressed instruction which we only predict in the next cycle (see notes above)

View file

@ -164,7 +164,6 @@ module fetch_fifo
status_cnt++;
write_pointer++;
// $display("Instruction: [ c | c ] @ %t", $time);
// or is it an unaligned 32 bit instruction like
// ____________________________________________________
// |instr [15:0] | instr [31:16] | compressed 1[15:0] |
@ -198,6 +197,12 @@ module fetch_fifo
mem_n[write_pointer_q] = {
branch_predict_q, ex_q, unaligned_address_q, {in_rdata_q[15:0], unaligned_instr_q}, 1'b0, 1'b0
};
// // check if we predicted on the unaligned instruction part
// if (!branch_predict_q.is_lower_16) begin
// // only output branch prediction here if we indeed meant it, e.g.: null it if it is not on the
// // lower 16 bit. Because then it would be valid for the upper part
// mem_n[write_pointer_q].branch_predict.valid = 1'b0;
// end
status_cnt++;
write_pointer++;
@ -217,7 +222,6 @@ module fetch_fifo
write_pointer++;
// unaligned access served
unaligned_n = 1'b0;
// $display("Instruction: [ c | i1 ] @ %t", $time);
// or is it an unaligned 32 bit instruction like
// ____________________________________________________
// |instr [15:0] | instr [31:16] | compressed 1[15:0] |

View file

@ -57,7 +57,7 @@ module load_unit (
input logic data_rvalid_i,
input logic [63:0] data_rdata_i
);
enum logic [2:0] {IDLE, WAIT_GNT, SEND_TAG, WAIT_PAGE_OFFSET, WAIT_TRANSLATION, ABORT_TRANSACTION, WAIT_FLUSH} NS, CS;
enum logic [2:0] {IDLE, WAIT_GNT, SEND_TAG, WAIT_PAGE_OFFSET, ABORT_TRANSACTION, WAIT_FLUSH} NS, CS;
// in order to decouple the response interface from the request interface we need a
// a queue which can hold all outstanding memory requests
typedef struct packed {
@ -230,10 +230,8 @@ module load_unit (
endcase
// if we just flushed and the queue is not empty or we are getting an rvalid this cycle wait in a extra stage
if (flush_i && (!empty || data_rvalid_i)) begin
if (flush_i) begin
NS = WAIT_FLUSH;
end else if (flush_i) begin
NS = IDLE;
end
end

View file

@ -111,7 +111,8 @@ module store_unit (
VALID_STORE: begin
valid_o = 1'b1;
// post this store to the store buffer
st_valid = 1'b1;
if (!flush_i)
st_valid = 1'b1;
// -----------------
// Access Exception
// -----------------