validate BTB address and use BTB for J/JAL/JR/JALR
even if we weren't using the BTB for JR/JALR, we'd need to flush the BTB on FENCE.I and on context switches, but validating its result suffices instead.
This commit is contained in:
parent
2f8fcebea0
commit
efc623cc36
@ -39,6 +39,7 @@ class ioCtrlDpath extends Bundle()
|
|||||||
val wen = Bool('output);
|
val wen = Bool('output);
|
||||||
// instruction in execute is an unconditional jump
|
// instruction in execute is an unconditional jump
|
||||||
val ex_jmp = Bool('output);
|
val ex_jmp = Bool('output);
|
||||||
|
val ex_jr = Bool('output);
|
||||||
// enable/disable interrupts
|
// enable/disable interrupts
|
||||||
val irq_enable = Bool('output);
|
val irq_enable = Bool('output);
|
||||||
val irq_disable = Bool('output);
|
val irq_disable = Bool('output);
|
||||||
@ -49,6 +50,7 @@ class ioCtrlDpath extends Bundle()
|
|||||||
// inputs from datapath
|
// inputs from datapath
|
||||||
val xcpt_ma_inst = Bool('input); // high on a misaligned/illegal virtual PC
|
val xcpt_ma_inst = Bool('input); // high on a misaligned/illegal virtual PC
|
||||||
val btb_hit = Bool('input);
|
val btb_hit = Bool('input);
|
||||||
|
val btb_match = Bool('input);
|
||||||
val inst = Bits(32, 'input);
|
val inst = Bits(32, 'input);
|
||||||
val br_eq = Bool('input);
|
val br_eq = Bool('input);
|
||||||
val br_lt = Bool('input);
|
val br_lt = Bool('input);
|
||||||
@ -418,6 +420,11 @@ class rocketCtrl extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val jr_taken = (ex_reg_br_type === BR_JR);
|
||||||
|
val j_taken = (ex_reg_br_type === BR_J);
|
||||||
|
io.dpath.ex_jmp := j_taken;
|
||||||
|
io.dpath.ex_jr := jr_taken;
|
||||||
|
|
||||||
val beq = io.dpath.br_eq;
|
val beq = io.dpath.br_eq;
|
||||||
val bne = ~io.dpath.br_eq;
|
val bne = ~io.dpath.br_eq;
|
||||||
val blt = io.dpath.br_lt;
|
val blt = io.dpath.br_lt;
|
||||||
@ -431,11 +438,8 @@ class rocketCtrl extends Component
|
|||||||
(ex_reg_br_type === BR_LT) & blt |
|
(ex_reg_br_type === BR_LT) & blt |
|
||||||
(ex_reg_br_type === BR_LTU) & bltu |
|
(ex_reg_br_type === BR_LTU) & bltu |
|
||||||
(ex_reg_br_type === BR_GE) & bge |
|
(ex_reg_br_type === BR_GE) & bge |
|
||||||
(ex_reg_br_type === BR_GEU) & bgeu;
|
(ex_reg_br_type === BR_GEU) & bgeu |
|
||||||
|
j_taken; // treat J/JAL like a taken branch
|
||||||
val jr_taken = (ex_reg_br_type === BR_JR);
|
|
||||||
val j_taken = (ex_reg_br_type === BR_J);
|
|
||||||
io.dpath.ex_jmp := j_taken;
|
|
||||||
|
|
||||||
val mem_reg_div_mul_val = Reg(){Bool()};
|
val mem_reg_div_mul_val = Reg(){Bool()};
|
||||||
val mem_reg_eret = Reg(){Bool()};
|
val mem_reg_eret = Reg(){Bool()};
|
||||||
@ -537,7 +541,9 @@ class rocketCtrl extends Component
|
|||||||
val kill_mem = mem_hazard || mem_exception;
|
val kill_mem = mem_hazard || mem_exception;
|
||||||
|
|
||||||
// control transfer from ex/mem
|
// control transfer from ex/mem
|
||||||
val take_pc_ex = (ex_reg_btb_hit != br_taken) || jr_taken || j_taken
|
val ex_btb_match = ex_reg_btb_hit && io.dpath.btb_match
|
||||||
|
val br_jr_taken = br_taken || jr_taken
|
||||||
|
val take_pc_ex = !ex_btb_match && br_jr_taken || ex_reg_btb_hit && !br_jr_taken
|
||||||
val take_pc_mem = mem_exception || mem_reg_eret || replay_mem
|
val take_pc_mem = mem_exception || mem_reg_eret || replay_mem
|
||||||
val take_pc = take_pc_ex || take_pc_mem
|
val take_pc = take_pc_ex || take_pc_mem
|
||||||
|
|
||||||
@ -553,17 +559,16 @@ class rocketCtrl extends Component
|
|||||||
mem_reg_kill_dmem <== ex_kill_dmem
|
mem_reg_kill_dmem <== ex_kill_dmem
|
||||||
|
|
||||||
io.dpath.sel_pc :=
|
io.dpath.sel_pc :=
|
||||||
Mux(replay_mem, PC_MEM, // dtlb miss
|
Mux(replay_mem, PC_MEM, // dtlb miss
|
||||||
Mux(mem_exception, PC_EVEC, // exception
|
Mux(mem_exception, PC_EVEC, // exception
|
||||||
Mux(mem_reg_eret, PC_PCR, // eret instruction
|
Mux(mem_reg_eret, PC_PCR, // eret instruction
|
||||||
Mux(!ex_reg_btb_hit && br_taken, PC_BR, // mispredicted taken branch
|
Mux(ex_reg_btb_hit && !br_jr_taken, PC_EX4, // mispredicted not taken branch
|
||||||
Mux(j_taken, PC_BR, // jump
|
Mux(!ex_btb_match && br_taken, PC_BR, // mispredicted taken branch
|
||||||
Mux(ex_reg_btb_hit && !br_taken, PC_EX4, // mispredicted not taken branch
|
Mux(!ex_btb_match && jr_taken, PC_JR, // mispredicted jump register
|
||||||
Mux(jr_taken, PC_JR, // jump register
|
Mux(io.dpath.btb_hit, PC_BTB, // predicted PC from BTB
|
||||||
Mux(io.dpath.btb_hit, PC_BTB, // predicted PC from BTB
|
PC_4))))))); // PC+4
|
||||||
PC_4)))))))); // PC+4
|
|
||||||
|
|
||||||
io.dpath.wen_btb := ~ex_reg_btb_hit & br_taken & ~kill_ex & ~kill_mem;
|
io.dpath.wen_btb := !ex_btb_match && br_jr_taken && !kill_ex;
|
||||||
|
|
||||||
io.dpath.stallf :=
|
io.dpath.stallf :=
|
||||||
~take_pc &
|
~take_pc &
|
||||||
|
@ -47,7 +47,8 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
val alu = new rocketDpathALU();
|
val alu = new rocketDpathALU();
|
||||||
val ex_alu_out = alu.io.out;
|
val ex_alu_out = alu.io.out;
|
||||||
val ex_jr_target = ex_alu_out(VADDR_BITS-1,0);
|
val ex_alu_adder_out = alu.io.adder_out;
|
||||||
|
val ex_jr_target = ex_alu_adder_out(VADDR_BITS-1,0);
|
||||||
|
|
||||||
val div = new rocketDivider(64);
|
val div = new rocketDivider(64);
|
||||||
val div_result = div.io.div_result_bits;
|
val div_result = div.io.div_result_bits;
|
||||||
@ -129,7 +130,7 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
val ex_branch_target = ex_reg_pc + branch_adder_rhs.toUFix;
|
val ex_branch_target = ex_reg_pc + branch_adder_rhs.toUFix;
|
||||||
|
|
||||||
btb.io.correct_target := ex_branch_target;
|
btb.io.correct_target := Mux(io.ctrl.ex_jr, ex_jr_target, ex_branch_target);
|
||||||
|
|
||||||
val if_next_pc =
|
val if_next_pc =
|
||||||
Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
|
Mux(io.ctrl.sel_pc === PC_BTB, if_btb_target,
|
||||||
@ -156,6 +157,7 @@ class rocketDpath extends Component
|
|||||||
btb.io.hit ^^ io.ctrl.btb_hit;
|
btb.io.hit ^^ io.ctrl.btb_hit;
|
||||||
btb.io.wen ^^ io.ctrl.wen_btb;
|
btb.io.wen ^^ io.ctrl.wen_btb;
|
||||||
btb.io.correct_pc4 := ex_reg_pc_plus4;
|
btb.io.correct_pc4 := ex_reg_pc_plus4;
|
||||||
|
io.ctrl.btb_match := id_reg_pc === btb.io.correct_target;
|
||||||
|
|
||||||
// instruction decode stage
|
// instruction decode stage
|
||||||
when (!io.ctrl.stalld) {
|
when (!io.ctrl.stalld) {
|
||||||
@ -297,7 +299,7 @@ class rocketDpath extends Component
|
|||||||
|
|
||||||
// D$ request interface (registered inside D$ module)
|
// D$ request interface (registered inside D$ module)
|
||||||
// other signals (req_val, req_rdy) connect to control module
|
// other signals (req_val, req_rdy) connect to control module
|
||||||
io.dmem.req_addr := ex_alu_out(VADDR_BITS-1,0);
|
io.dmem.req_addr := ex_alu_adder_out(VADDR_BITS-1,0);
|
||||||
io.dmem.req_data := ex_reg_rs2;
|
io.dmem.req_data := ex_reg_rs2;
|
||||||
io.dmem.req_tag := ex_reg_waddr;
|
io.dmem.req_tag := ex_reg_waddr;
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ class ioALU extends Bundle(){
|
|||||||
val in2 = UFix(64, 'input);
|
val in2 = UFix(64, 'input);
|
||||||
val in1 = UFix(64, 'input);
|
val in1 = UFix(64, 'input);
|
||||||
val out = UFix(64, 'output);
|
val out = UFix(64, 'output);
|
||||||
|
val adder_out = UFix(64, 'output);
|
||||||
}
|
}
|
||||||
|
|
||||||
class rocketDpathALU extends Component
|
class rocketDpathALU extends Component
|
||||||
@ -54,6 +55,7 @@ class rocketDpathALU extends Component
|
|||||||
|
|
||||||
val out_hi = Mux(io.dw === DW_64, out64(63,32), Fill(32, out64(31)))
|
val out_hi = Mux(io.dw === DW_64, out64(63,32), Fill(32, out64(31)))
|
||||||
io.out := Cat(out_hi, out64(31,0)).toUFix
|
io.out := Cat(out_hi, out64(31,0)).toUFix
|
||||||
|
io.adder_out := adder_out
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user