1
0
Fork 0

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:
Andrew Waterman 2012-01-01 17:04:14 -08:00
parent 2f8fcebea0
commit efc623cc36
3 changed files with 28 additions and 19 deletions

View File

@ -39,6 +39,7 @@ class ioCtrlDpath extends Bundle()
val wen = Bool('output);
// instruction in execute is an unconditional jump
val ex_jmp = Bool('output);
val ex_jr = Bool('output);
// enable/disable interrupts
val irq_enable = Bool('output);
val irq_disable = Bool('output);
@ -49,6 +50,7 @@ class ioCtrlDpath extends Bundle()
// inputs from datapath
val xcpt_ma_inst = Bool('input); // high on a misaligned/illegal virtual PC
val btb_hit = Bool('input);
val btb_match = Bool('input);
val inst = Bits(32, 'input);
val br_eq = 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 bne = ~io.dpath.br_eq;
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_LTU) & bltu |
(ex_reg_br_type === BR_GE) & bge |
(ex_reg_br_type === BR_GEU) & bgeu;
val jr_taken = (ex_reg_br_type === BR_JR);
val j_taken = (ex_reg_br_type === BR_J);
io.dpath.ex_jmp := j_taken;
(ex_reg_br_type === BR_GEU) & bgeu |
j_taken; // treat J/JAL like a taken branch
val mem_reg_div_mul_val = Reg(){Bool()};
val mem_reg_eret = Reg(){Bool()};
@ -537,7 +541,9 @@ class rocketCtrl extends Component
val kill_mem = mem_hazard || mem_exception;
// 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 = take_pc_ex || take_pc_mem
@ -553,17 +559,16 @@ class rocketCtrl extends Component
mem_reg_kill_dmem <== ex_kill_dmem
io.dpath.sel_pc :=
Mux(replay_mem, PC_MEM, // dtlb miss
Mux(mem_exception, PC_EVEC, // exception
Mux(mem_reg_eret, PC_PCR, // eret instruction
Mux(!ex_reg_btb_hit && br_taken, PC_BR, // mispredicted taken branch
Mux(j_taken, PC_BR, // jump
Mux(ex_reg_btb_hit && !br_taken, PC_EX4, // mispredicted not taken branch
Mux(jr_taken, PC_JR, // jump register
Mux(io.dpath.btb_hit, PC_BTB, // predicted PC from BTB
PC_4)))))))); // PC+4
Mux(replay_mem, PC_MEM, // dtlb miss
Mux(mem_exception, PC_EVEC, // exception
Mux(mem_reg_eret, PC_PCR, // eret instruction
Mux(ex_reg_btb_hit && !br_jr_taken, PC_EX4, // mispredicted not taken branch
Mux(!ex_btb_match && br_taken, PC_BR, // mispredicted taken branch
Mux(!ex_btb_match && jr_taken, PC_JR, // mispredicted jump register
Mux(io.dpath.btb_hit, PC_BTB, // predicted PC from BTB
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 :=
~take_pc &

View File

@ -47,7 +47,8 @@ class rocketDpath extends Component
val alu = new rocketDpathALU();
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_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;
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 =
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.wen ^^ io.ctrl.wen_btb;
btb.io.correct_pc4 := ex_reg_pc_plus4;
io.ctrl.btb_match := id_reg_pc === btb.io.correct_target;
// instruction decode stage
when (!io.ctrl.stalld) {
@ -297,7 +299,7 @@ class rocketDpath extends Component
// D$ request interface (registered inside D$ 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_tag := ex_reg_waddr;

View File

@ -14,6 +14,7 @@ class ioALU extends Bundle(){
val in2 = UFix(64, 'input);
val in1 = UFix(64, 'input);
val out = UFix(64, 'output);
val adder_out = UFix(64, 'output);
}
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)))
io.out := Cat(out_hi, out64(31,0)).toUFix
io.adder_out := adder_out
}
}