Removing unnecessary branch operators

This commit is contained in:
Florian Zaruba 2017-05-12 00:14:48 +02:00
parent 0a81031e5a
commit 74c33bf1ba
5 changed files with 50 additions and 60 deletions

View file

@ -63,14 +63,14 @@ package ariane_pkg;
// ---------------
// EX Stage
// ---------------
typedef enum logic [7:0] { // basic ALU op
typedef enum logic [5:0] { // basic ALU op
ADD, SUB, ADDW, SUBW,
// logic operations
XORL, ORL, ANDL,
// shifts
SRA, SRL, SLL, SRLW, SLLW, SRAW,
// comparisons
LTS, LTU, LES, LEU, GTS, GTU, GES, GEU, EQ, NE,
LTS, LTU, GES, GEU, EQ, NE,
// jumps
JAL, JALR,
// set lower than operations

View file

@ -58,11 +58,8 @@ module alu
SUB, SUBW,
// COMPARATOR OPs
EQ, NE,
GTU, GEU,
LTU, LEU,
GTS, GES,
LTS, LES,
SLTS, SLTU,
GEU, LTU,
GES, LTS,
SLETS, SLETU: adder_op_b_negate = 1'b1;
default: ;
@ -150,12 +147,7 @@ module alu
cmp_signed = 1'b0;
unique case (operator_i)
GTS,
GES,
LTS,
LES,
SLTS,
SLETS: begin
GES, LTS: begin
cmp_signed = 1'b1;
end
@ -187,15 +179,12 @@ module alu
cmp_result = 1'b1;
unique case (operator_i)
EQ: cmp_result = is_equal;
NE: cmp_result = (~is_equal);
GTS, GTU: cmp_result = is_greater_equal && (~is_equal);
EQ: cmp_result = is_equal;
NE: cmp_result = (~is_equal);
// GTS, GTU: cmp_result = is_greater_equal && (~is_equal);
GES, GEU: cmp_result = is_greater_equal;
LTS, SLTS,
LTU, SLTU: cmp_result = (~is_greater_equal);
SLETS,
SLETU,
LES, LEU: cmp_result = (~is_greater_equal) || is_equal;
LTS, LTU: cmp_result = (~is_greater_equal);
// LES, LEU: cmp_result = (~is_greater_equal) || is_equal;
default: ;
endcase
@ -228,13 +217,9 @@ module alu
SRLW, SRAW: result_o = {{32{shift_result32[31]}}, shift_result32[31:0]};
// Comparison Operations
EQ, NE,
GTU, GEU,
LTU, LEU,
GTS, GES,
LTS, LES,
SLTS, SLTU,
SLETS, SLETU: result_o = {63'b0, cmp_result};
EQ, NE,
LTU, GEU,
GES, LTS : result_o = {63'b0, cmp_result};
default: ; // default case to suppress unique warning
endcase

View file

@ -127,6 +127,7 @@ module ariane
logic [63:0] operand_b_id_ex;
logic [63:0] operand_c_id_ex;
logic [63:0] pc_id_ex;
logic is_compressed_instr_id_ex;
// ALU
logic alu_ready_ex_id;
logic alu_valid_id_ex;

View file

@ -34,6 +34,7 @@ module branch_engine (
output exception branch_ex_o // branch exception out
);
logic [63:0] target_address;
logic [63:0] next_pc;
always_comb begin : target_address_calc
target_address = 64'b0;
@ -42,17 +43,20 @@ module branch_engine (
branchpredict_o.is_taken = 1'b0;
branchpredict_o.valid = valid_i;
branchpredict_o.is_mispredict = 1'b0;
// calculate next PC, depending on whether the instruction is compressed or not this may be different
next_pc = pc_i + (is_compressed_instr_i) ? 64'h2 : 64'h4;
// calculate target address simple 64 bit addition
target_address = $signed(operand_a_i) + $signed(operand_b_i);
// save pc
branchpredict_o.pc = pc_i;
// write target address which goes to pc gen
branchpredict_o.target_address = (comparison_result_i) ? target_address : next_pc;
branchpredict_o.is_taken = comparison_result_i;
if (valid_i) begin
// save pc
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 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
// TODO in case of branch which is not taken it is not necessary to check for the address
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 reality it was one

View file

@ -353,32 +353,32 @@ module lsu #(
// essentially the same part as in IDLE but we can't accept a new store
// as the store could immediately be performed and we would collide on the
// trans id part (e.g.: a structural hazard)
if (op == LD_OP & lsu_valid_i) begin
translation_req = 1'b1;
// we can never handle a load in a single cycle
// but at least on a tlb hit we can output it to the memory
if (translation_valid) begin
// check if the address is in the store buffer otherwise we need
// to wait until the store buffer has cleared its entry
if (~address_match) begin
// lets request this read
data_req_i[1] = 1'b1;
// we already got a grant here so lets wait for the rvalid
if (data_gnt_o[1]) begin
NS = LOAD_WAIT_RVALID;
end else begin // we didn't get a grant so wait for it in a separate stage
NS = LOAD_WAIT_GNT;
end
end
end else begin// otherwise we need to wait for the translation
NS = LOAD_WAIT_TRANSLATION;
end
// STORE
end else if (op == ST_OP & lsu_valid_i) begin
NS = STORE;
end else begin
// if (op == LD_OP & lsu_valid_i) begin
// translation_req = 1'b1;
// // we can never handle a load in a single cycle
// // but at least on a tlb hit we can output it to the memory
// if (translation_valid) begin
// // check if the address is in the store buffer otherwise we need
// // to wait until the store buffer has cleared its entry
// if (~address_match) begin
// // lets request this read
// data_req_i[1] = 1'b1;
// // we already got a grant here so lets wait for the rvalid
// if (data_gnt_o[1]) begin
// NS = LOAD_WAIT_RVALID;
// end else begin // we didn't get a grant so wait for it in a separate stage
// NS = LOAD_WAIT_GNT;
// end
// end
// end else begin// otherwise we need to wait for the translation
// NS = LOAD_WAIT_TRANSLATION;
// end
// // STORE
// end else if (op == ST_OP & lsu_valid_i) begin
// NS = STORE;
// end else begin
NS = IDLE;
end
// end
end else begin
// and stall