mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
Fix in calculating index into btb
This commit is contained in:
parent
848a06ef77
commit
3c7c45ff1b
4 changed files with 21 additions and 18 deletions
|
@ -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)
|
||||
|
|
|
@ -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] |
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
// -----------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue