1
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); 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 &

View File

@ -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;

View File

@ -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
} }
} }