Add support for compressed branches

This commit is contained in:
Florian Zaruba 2017-05-11 11:11:51 +02:00
parent d624a4163c
commit 2b790db79b
5 changed files with 41 additions and 31 deletions

View file

@ -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 ),

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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