diff --git a/src/branch_unit.sv b/src/branch_unit.sv index 4471d6bd8..2f0aa9642 100644 --- a/src/branch_unit.sv +++ b/src/branch_unit.sv @@ -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) diff --git a/src/fetch_fifo.sv b/src/fetch_fifo.sv index bdf698262..7ed17f436 100644 --- a/src/fetch_fifo.sv +++ b/src/fetch_fifo.sv @@ -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] | diff --git a/src/load_unit.sv b/src/load_unit.sv index c71be0c15..6cb986895 100644 --- a/src/load_unit.sv +++ b/src/load_unit.sv @@ -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 diff --git a/src/store_unit.sv b/src/store_unit.sv index 679771c41..0f3f19fc2 100644 --- a/src/store_unit.sv +++ b/src/store_unit.sv @@ -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 // -----------------