diff --git a/src/ariane.sv b/src/ariane.sv index 9f7e39b64..1a2abc6e5 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -283,6 +283,7 @@ module ariane .imm_o ( imm_id_ex ), .trans_id_o ( trans_id_id_ex ), .pc_o ( pc_id_ex ), + .is_compressed_instr_o ( is_compressed_instr_id_ex ), // ALU .alu_ready_i ( alu_ready_ex_id ), .alu_valid_o ( alu_valid_id_ex ), @@ -330,6 +331,7 @@ module ariane .imm_i ( imm_id_ex ), .trans_id_i ( trans_id_id_ex ), .pc_i ( pc_id_ex ), + .is_compressed_instr_i ( is_compressed_instr_id_ex ), // ALU .alu_ready_o ( alu_ready_ex_id ), .alu_valid_i ( alu_valid_id_ex ), diff --git a/src/branch_engine.sv b/src/branch_engine.sv index cc5521fa4..ef92f0f86 100644 --- a/src/branch_engine.sv +++ b/src/branch_engine.sv @@ -23,6 +23,7 @@ module branch_engine ( input logic [63:0] operand_a_i, input logic [63:0] operand_b_i, input logic [63:0] pc_i, + input logic is_compressed_instr_i, input logic valid_i, input logic comparison_result_i, // result of comparison @@ -47,14 +48,14 @@ module branch_engine ( branchpredict_o.pc = pc_i; // calculate target address simple 64 bit addition target_address = $signed(operand_a_i) + $signed(operand_b_i); - // write target address - branchpredict_o.target_address = target_address; + // write target address which goes to pc gen + branchpredict_o.target_address = (comparison_result_i) ? target_address : pc_i + (is_compressed_instr_i) ? 64'h2 : 64'h4; branchpredict_o.is_taken = comparison_result_i; // we mis-predicted e.g.: the predicted address is unequal to the actual address if (target_address[1:0] == 2'b0) begin if ( target_address != predict_address_i // we mis-predicted the address of the branch || predict_taken_i != comparison_result_i // we mis-predicted the outcome of the branch - || predict_branch_valid_i == 1'b0 // this means branch-prediction thought it was no branch but in real it was one + || predict_branch_valid_i == 1'b0 // this means branch-prediction thought it was no branch but in reality it was one ) begin branchpredict_o.is_mispredict = 1'b1; end diff --git a/src/ex_stage.sv b/src/ex_stage.sv index ba8dc6f18..81b212739 100644 --- a/src/ex_stage.sv +++ b/src/ex_stage.sv @@ -33,6 +33,8 @@ module ex_stage #( input logic [63:0] imm_i, input logic [TRANS_ID_BITS-1:0] trans_id_i, input logic [63:0] pc_i, // PC of current instruction + input logic is_compressed_instr_i, // we need to know if this was a compressed instruction + // in order to calculate the next PC on a mis-predict // ALU 1 output logic alu_ready_o, // FU is ready input logic alu_valid_i, // Output is valid diff --git a/src/id_stage.sv b/src/id_stage.sv index 725a034d0..ec57bfd69 100644 --- a/src/id_stage.sv +++ b/src/id_stage.sv @@ -43,6 +43,7 @@ module id_stage #( output logic [63:0] imm_o, output logic [TRANS_ID_BITS-1:0] trans_id_o, output logic [63:0] pc_o, + output logic is_compressed_instr_o, input logic alu_ready_i, output logic alu_valid_o, diff --git a/src/issue_read_operands.sv b/src/issue_read_operands.sv index 504941c09..9a161d0ee 100644 --- a/src/issue_read_operands.sv +++ b/src/issue_read_operands.sv @@ -46,6 +46,7 @@ module issue_read_operands ( output logic [63:0] imm_o, // output immediate for the LSU output logic [TRANS_ID_BITS-1:0] trans_id_o, output logic [63:0] pc_o, + output logic is_compressed_instr_o, // ALU 1 input logic alu_ready_i, // FU is ready output logic alu_valid_o, // Output is valid @@ -74,6 +75,7 @@ module issue_read_operands ( operand_b_n, operand_b_q, operand_c_n, operand_c_q, imm_n, imm_q; + logic alu_valid_n, alu_valid_q; logic mult_valid_n, mult_valid_q; logic lsu_valid_n, lsu_valid_q; @@ -232,15 +234,15 @@ module issue_read_operands ( JAL: begin operator_n = ADD; // output 4 as operand b as we - // need to save PC + 4 - operand_b_n = 64'h4; + // need to save PC + 4 or in case of a compressed instruction PC + 4 + operand_b_n = (issue_instr_i.is_compressed) ? 64'h2 : 64'h4; end JALR: begin operator_n = ADD; // output 4 as operand b as we - // need to save PC + 4 - operand_b_n = 64'h4; + // need to save PC + 4 or in case of a compressed instruction PC + 4 + operand_b_n = (issue_instr_i.is_compressed) ? 64'h2 : 64'h4; // get RS1 as operand C operand_c_n = operand_a_regfile; // forward rs1 @@ -304,31 +306,33 @@ module issue_read_operands ( // Registers always_ff @(posedge clk_i or negedge rst_ni) begin if(~rst_ni) begin - operand_a_q <= '{default: 0}; - operand_b_q <= '{default: 0}; - operand_c_q <= '{default: 0}; - imm_q <= 64'b0; - alu_valid_q <= 1'b0; - branch_valid_q <= 1'b0; - mult_valid_q <= 1'b0; - lsu_valid_q <= 1'b0; - csr_valid_q <= 1'b0; - operator_q <= ADD; - trans_id_q <= 5'b0; - pc_o <= 64'b0; + operand_a_q <= '{default: 0}; + operand_b_q <= '{default: 0}; + operand_c_q <= '{default: 0}; + imm_q <= 64'b0; + alu_valid_q <= 1'b0; + branch_valid_q <= 1'b0; + mult_valid_q <= 1'b0; + lsu_valid_q <= 1'b0; + csr_valid_q <= 1'b0; + operator_q <= ADD; + trans_id_q <= 5'b0; + pc_o <= 64'b0; + is_compressed_instr_o <= 1'b0; end else begin - operand_a_q <= operand_a_n; - operand_b_q <= operand_b_n; - operand_c_q <= operand_c_n; - imm_q <= imm_n; - alu_valid_q <= alu_valid_n; - branch_valid_q <= branch_valid_n; - mult_valid_q <= mult_valid_n; - lsu_valid_q <= lsu_valid_n; - csr_valid_q <= csr_valid_n; - operator_q <= operator_n; - trans_id_q <= trans_id_n; - pc_o <= issue_instr_i.pc; + operand_a_q <= operand_a_n; + operand_b_q <= operand_b_n; + operand_c_q <= operand_c_n; + imm_q <= imm_n; + alu_valid_q <= alu_valid_n; + branch_valid_q <= branch_valid_n; + mult_valid_q <= mult_valid_n; + lsu_valid_q <= lsu_valid_n; + csr_valid_q <= csr_valid_n; + operator_q <= operator_n; + trans_id_q <= trans_id_n; + pc_o <= issue_instr_i.pc; + is_compressed_instr_o <= issue_instr_i.is_compressed; end end endmodule