branch cleanup

This commit is contained in:
Eric Matthews 2020-05-21 21:45:34 -07:00
parent 06f3c14115
commit faede7fe7e
6 changed files with 34 additions and 65 deletions

View file

@ -27,7 +27,6 @@ import taiga_types::*;
module branch_predictor (
input logic clk,
input logic rst,
branch_predictor_interface.branch_predictor bp,
output branch_metadata_t branch_metadata_if,
input branch_metadata_t branch_metadata_ex,

View file

@ -30,7 +30,7 @@ module branch_unit(
unit_issue_interface.unit issue,
input branch_inputs_t branch_inputs,
input logic [31:0] dec_pc_plus_4,//Sourced from ALU datapath on jal/jalr
input logic [31:0] issue_pc_plus_4,//Sourced from ALU datapath on jal/jalr
output branch_results_t br_results,
ras_interface.branch_unit ras,
output logic branch_flush,
@ -52,39 +52,21 @@ module branch_unit(
logic branch_issued_r;
logic [31:0] jump_base;
logic result;
logic result_ex;
logic [2:0] fn3_ex;
logic jump_ex;
//Branch Predictor
logic branch_taken;
logic branch_taken_ex;
logic branch_correctly_taken;
logic branch_correclty_not_taken;
logic miss_predict;
id_t id_ex;
logic [31:0] new_pc;
logic [31:0] new_pc_ex;
logic [31:0] pc_ex;
logic [31:0] jump_pc;
logic [31:0] njump_pc;
logic [1:0] branch_metadata;
logic branch_prediction_used;
logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way;
logic instruction_is_completing;
//RAS
logic is_call;
logic is_return;
//implementation
////////////////////////////////////////////////////
//Implementation
//Only stall condition is if the following instruction is not valid for pc comparisons.
//If the next instruction isn't valid, no instruction can be issued anyways, so it
//is safe to hardcode this to one.
@ -94,12 +76,18 @@ module branch_unit(
set_clr_reg_with_rst #(.SET_OVER_CLR(1), .WIDTH(1), .RST_VALUE(0)) branch_issued_m (
.clk, .rst,
.set(issue.new_request),
.clr(branch_inputs.dec_pc_valid | br_exception.valid),
.clr(branch_inputs.issue_pc_valid | br_exception.valid),
.result(branch_issued_r)
);
assign instruction_is_completing = branch_issued_r & branch_inputs.dec_pc_valid;
//To determine if the branch was predicted correctly we need to wait until the
//subsequent instruction has reached the issue stage
assign instruction_is_completing = branch_issued_r & branch_inputs.issue_pc_valid;
////////////////////////////////////////////////////
//Branch/Jump target determination
//Branch comparison and final address calculation
//are performed in the issue stage
branch_comparator bc (
.use_signed(branch_inputs.use_signed),
.less_than(branch_inputs.fn3[2]),
@ -111,23 +99,14 @@ module branch_unit(
assign branch_taken = result | branch_inputs.jalr | branch_inputs.jal;
always_comb begin
if (branch_inputs.jalr)
jump_base = branch_inputs.rs1;
else
jump_base = branch_inputs.dec_pc;
end
assign jump_base = branch_inputs.jalr ? branch_inputs.rs1 : branch_inputs.issue_pc;
assign new_pc = jump_base + (branch_taken ? 32'(signed'(branch_inputs.pc_offset)) : 4);
always_ff @(posedge clk) begin
if (instruction_is_completing | ~branch_issued_r) begin
branch_taken_ex <= branch_taken;
new_pc_ex <= new_pc;
fn3_ex <= branch_inputs.fn3;
result_ex <= result;
jump_ex <= (branch_inputs.jal | branch_inputs.jalr);
new_pc_ex[31:1] <= new_pc[31:1];
new_pc_ex[0] <= new_pc[0] & ~branch_inputs.jalr;
id_ex <= issue.id;
end
end
@ -142,32 +121,30 @@ module branch_unit(
jmp_instruction_id <= issue.instruction_id;
end
assign potential_branch_exception = 0;// jump_pc_dec[1] & issue.new_request;
assign potential_branch_exception = new_pc[1] & issue.new_request;
assign branch_exception_is_jump = (branch_inputs.jal | branch_inputs.jalr);
assign br_exception.valid = 0;//(jump_pc[1] & branch_taken) & branch_issued_r;
assign br_exception.valid = new_pc_ex[1] & branch_taken_ex & branch_issued_r;
assign br_exception.code = INST_ADDR_MISSALIGNED;
assign br_exception.pc = pc_ex;
assign br_exception.tval = new_pc_ex;
assign br_exception.id = jmp_instruction_id;
assign branch_exception_is_jump = (branch_inputs.jal | branch_inputs.jalr);
end
endgenerate
////////////////////////////////////////////////////
//ID Management
assign branch_complete = instruction_is_completing;
assign branch_complete = instruction_is_completing | br_exception.valid;
assign branch_id = id_ex;
////////////////////////////////////////////////////
//Predictor support
always_ff @(posedge clk) begin
if (issue.new_request)
njump_pc <= dec_pc_plus_4;
end
logic is_return;
always_ff @(posedge clk) begin
if (instruction_is_completing | ~branch_issued_r) begin
pc_ex <= branch_inputs.dec_pc;
is_return <= branch_inputs.is_return;
pc_ex <= branch_inputs.issue_pc;
end
end
@ -177,23 +154,17 @@ module branch_unit(
assign br_results.branch_ex = instruction_is_completing;
assign br_results.is_return_ex = is_return;
assign branch_flush = instruction_is_completing && (branch_inputs.dec_pc[31:1] != new_pc_ex[31:1]);
assign branch_flush = instruction_is_completing && (branch_inputs.issue_pc[31:1] != new_pc_ex[31:1]);
////////////////////////////////////////////////////
//RAS support
generate if (USE_BRANCH_PREDICTOR) begin
always_ff @(posedge clk) begin
if (instruction_is_completing | ~branch_issued_r) begin
is_call <= branch_inputs.is_call;
is_return <= branch_inputs.is_return;
end
end
assign ras.push = instruction_is_completing & is_call;
assign ras.pop = instruction_is_completing & is_return;
assign ras.new_addr = njump_pc;
always_ff @(posedge clk) begin
ras.push <= branch_inputs.is_call & issue.new_request;
ras.pop <= branch_inputs.is_return & issue.new_request;
ras.new_addr <= issue_pc_plus_4;
end
endgenerate
end endgenerate
////////////////////////////////////////////////////
//End of Implementation
////////////////////////////////////////////////////

View file

@ -463,9 +463,8 @@ module decode_and_issue (
assign branch_inputs.jal = opcode_issue_stage[3];//(opcode == JAL);
assign branch_inputs.jalr = ~opcode_issue_stage[3] & opcode_issue_stage[2];//(opcode == JALR);
assign branch_inputs.dec_pc = pc_issue_stage;
assign branch_inputs.dec_pc_valid = issue_stage_valid;
assign branch_inputs.issue_pc = pc_issue_stage;
assign branch_inputs.issue_pc_valid = issue_stage_valid;
assign branch_inputs.rs1 = rf_issue.rs1_data;
assign branch_inputs.rs2 = rf_issue.rs2_data;

View file

@ -95,10 +95,10 @@ module fetch(
end
always_comb begin
if (branch_flush)
next_pc = bp.branch_flush_pc;
else if (gc_fetch_pc_override)
if (gc_fetch_pc_override)
next_pc = gc_fetch_pc;
else if (branch_flush)
next_pc = bp.branch_flush_pc;
else if (bp.use_prediction)
next_pc = (bp.use_ras & ras.valid) ? ras.addr : bp.predicted_pc;
else

View file

@ -219,7 +219,7 @@ module taiga (
////////////////////////////////////////////////////
//Execution Units
branch_unit branch_unit_block (.*, .issue(unit_issue[BRANCH_UNIT_ID]), .dec_pc_plus_4(unit_wb[ALU_UNIT_WB_ID].rd));
branch_unit branch_unit_block (.*, .issue(unit_issue[BRANCH_UNIT_ID]), .issue_pc_plus_4(unit_wb[ALU_UNIT_WB_ID].rd));
alu_unit alu_unit_block (.*, .issue(unit_issue[ALU_UNIT_WB_ID]), .wb(unit_wb[ALU_UNIT_WB_ID]));
load_store_unit load_store_unit_block (.*, .dcache_on(1'b1), .clear_reservation(1'b0), .tlb(dtlb), .issue(unit_issue[LS_UNIT_WB_ID]), .wb(unit_wb[LS_UNIT_WB_ID]), .l1_request(l1_request[L1_DCACHE_ID]), .l1_response(l1_response[L1_DCACHE_ID]));
generate if (ENABLE_S_MODE) begin

View file

@ -120,8 +120,8 @@ package taiga_types;
logic [XLEN-1:0] rs1;
logic [XLEN-1:0] rs2;
logic [2:0] fn3;
logic [31:0] dec_pc;
logic dec_pc_valid;
logic [31:0] issue_pc;
logic issue_pc_valid;
logic use_signed;
logic jal;
logic jalr;