mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-24 14:08:57 -04:00
branch cleanup
This commit is contained in:
parent
06f3c14115
commit
faede7fe7e
6 changed files with 34 additions and 65 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue