don't flush pipeline on writes to side-effect-free PCRs
notably, K0, K1, and EPC
This commit is contained in:
parent
8b439ef20d
commit
fc46daecf6
@ -6,6 +6,7 @@ import Constants._
|
|||||||
import Instructions._
|
import Instructions._
|
||||||
import hwacha._
|
import hwacha._
|
||||||
import ALU._
|
import ALU._
|
||||||
|
import Util._
|
||||||
|
|
||||||
class CtrlDpathIO extends Bundle()
|
class CtrlDpathIO extends Bundle()
|
||||||
{
|
{
|
||||||
@ -174,13 +175,13 @@ object XDecode extends DecodeConstants
|
|||||||
REMUW-> List(xpr64,N,N,BR_N, N,Y,Y,A2_RTYPE,DW_32, FN_REMU, N,M_X, MT_X, N,Y,Y,WA_RD,WB_X, PCR.N,N,N,N,N,N),
|
REMUW-> List(xpr64,N,N,BR_N, N,Y,Y,A2_RTYPE,DW_32, FN_REMU, N,M_X, MT_X, N,Y,Y,WA_RD,WB_X, PCR.N,N,N,N,N,N),
|
||||||
|
|
||||||
SYSCALL-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,Y,N,N),
|
SYSCALL-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,Y,N,N),
|
||||||
SETPCR-> List(Y, N,N,BR_N, N,N,N,A2_ITYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.S,N,N,N,Y,Y),
|
SETPCR-> List(Y, N,N,BR_N, N,N,N,A2_ITYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.S,N,N,N,Y,N),
|
||||||
CLEARPCR-> List(Y, N,N,BR_N, N,N,N,A2_ITYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.C,N,N,N,Y,Y),
|
CLEARPCR-> List(Y, N,N,BR_N, N,N,N,A2_ITYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.C,N,N,N,Y,N),
|
||||||
ERET-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,Y,N,Y,N),
|
ERET-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,Y,N,Y,N),
|
||||||
FENCE-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, Y,M_FENCE, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,N,N,N),
|
FENCE-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, Y,M_FENCE, MT_X, N,N,N,WA_X, WB_X, PCR.N,N,N,N,N,N),
|
||||||
FENCE_I-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, Y,M_FENCE, MT_X, N,N,N,WA_X, WB_X, PCR.N,Y,N,N,N,Y),
|
FENCE_I-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, Y,M_FENCE, MT_X, N,N,N,WA_X, WB_X, PCR.N,Y,N,N,N,Y),
|
||||||
MFPCR-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_X, PCR.F,N,N,N,Y,Y),
|
MFPCR-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_X, FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_X, PCR.F,N,N,N,Y,N),
|
||||||
MTPCR-> List(Y, N,N,BR_N, N,Y,N,A2_RTYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.T,N,N,N,Y,Y),
|
MTPCR-> List(Y, N,N,BR_N, N,Y,N,A2_RTYPE,DW_XPR,FN_OP2, N,M_X, MT_X, N,N,Y,WA_RD,WB_ALU,PCR.T,N,N,N,Y,N),
|
||||||
RDTIME-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_TSC,PCR.N,N,N,N,N,N),
|
RDTIME-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_TSC,PCR.N,N,N,N,N,N),
|
||||||
RDCYCLE-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_TSC,PCR.N,N,N,N,N,N),
|
RDCYCLE-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_TSC,PCR.N,N,N,N,N,N),
|
||||||
RDINSTRET-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_IRT,PCR.N,N,N,N,N,N))
|
RDINSTRET-> List(Y, N,N,BR_N, N,N,N,A2_X, DW_XPR,FN_X, N,M_X, MT_X, N,N,Y,WA_RD,WB_IRT,PCR.N,N,N,N,N,N))
|
||||||
@ -393,7 +394,6 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
val wb_reg_eret = Reg(resetVal = Bool(false))
|
val wb_reg_eret = Reg(resetVal = Bool(false))
|
||||||
val wb_reg_xcpt = Reg(resetVal = Bool(false))
|
val wb_reg_xcpt = Reg(resetVal = Bool(false))
|
||||||
val wb_reg_replay = Reg(resetVal = Bool(false))
|
val wb_reg_replay = Reg(resetVal = Bool(false))
|
||||||
val wb_reg_replay_next = Reg(resetVal = Bool(false))
|
|
||||||
val wb_reg_cause = Reg(){UFix()}
|
val wb_reg_cause = Reg(){UFix()}
|
||||||
val wb_reg_fp_val = Reg(resetVal = Bool(false))
|
val wb_reg_fp_val = Reg(resetVal = Bool(false))
|
||||||
val wb_reg_div_mul_val = Reg(resetVal = Bool(false))
|
val wb_reg_div_mul_val = Reg(resetVal = Bool(false))
|
||||||
@ -453,6 +453,9 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
|
|
||||||
// executing ERET when traps are enabled causes an illegal instruction exception
|
// executing ERET when traps are enabled causes an illegal instruction exception
|
||||||
val illegal_inst = !id_int_val.toBool || (id_eret.toBool && io.dpath.status.et)
|
val illegal_inst = !id_int_val.toBool || (id_eret.toBool && io.dpath.status.et)
|
||||||
|
// flush pipeline on PCR writes that may have side effects
|
||||||
|
val id_pcr_flush = id_pcr != PCR.N && id_pcr != PCR.F &&
|
||||||
|
id_raddr1 != PCR.K0 && id_raddr1 != PCR.K1 && id_raddr1 != PCR.EPC
|
||||||
|
|
||||||
val (id_xcpt, id_cause) = checkExceptions(List(
|
val (id_xcpt, id_cause) = checkExceptions(List(
|
||||||
(id_interrupt, id_interrupt_cause),
|
(id_interrupt, id_interrupt_cause),
|
||||||
@ -499,7 +502,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
ex_reg_flush_inst := id_fence_i
|
ex_reg_flush_inst := id_fence_i
|
||||||
ex_reg_fp_val := id_fp_val
|
ex_reg_fp_val := id_fp_val
|
||||||
ex_reg_vec_val := id_vec_val.toBool
|
ex_reg_vec_val := id_vec_val.toBool
|
||||||
ex_reg_replay_next := id_replay_next
|
ex_reg_replay_next := id_replay_next || id_pcr_flush
|
||||||
ex_reg_load_use := id_load_use;
|
ex_reg_load_use := id_load_use;
|
||||||
ex_reg_mem_cmd := id_mem_cmd
|
ex_reg_mem_cmd := id_mem_cmd
|
||||||
ex_reg_mem_type := id_mem_type.toUFix
|
ex_reg_mem_type := id_mem_type.toUFix
|
||||||
@ -567,7 +570,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
ctrl_killm := killm_common || mem_xcpt || fpu_kill_mem
|
ctrl_killm := killm_common || mem_xcpt || fpu_kill_mem
|
||||||
|
|
||||||
wb_reg_replay := replay_mem && !take_pc_wb
|
wb_reg_replay := replay_mem && !take_pc_wb
|
||||||
wb_reg_xcpt := mem_xcpt && !take_pc_wb && !wb_reg_replay_next
|
wb_reg_xcpt := mem_xcpt && !take_pc_wb
|
||||||
when (mem_xcpt) { wb_reg_cause := mem_cause }
|
when (mem_xcpt) { wb_reg_cause := mem_cause }
|
||||||
|
|
||||||
when (ctrl_killm) {
|
when (ctrl_killm) {
|
||||||
@ -580,7 +583,6 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
wb_reg_mem_val := Bool(false)
|
wb_reg_mem_val := Bool(false)
|
||||||
wb_reg_div_mul_val := Bool(false);
|
wb_reg_div_mul_val := Bool(false);
|
||||||
wb_reg_fp_val := Bool(false)
|
wb_reg_fp_val := Bool(false)
|
||||||
wb_reg_replay_next := Bool(false)
|
|
||||||
}
|
}
|
||||||
.otherwise {
|
.otherwise {
|
||||||
wb_reg_valid := mem_reg_valid
|
wb_reg_valid := mem_reg_valid
|
||||||
@ -592,7 +594,6 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
wb_reg_mem_val := mem_reg_mem_val
|
wb_reg_mem_val := mem_reg_mem_val
|
||||||
wb_reg_div_mul_val := mem_reg_div_mul_val
|
wb_reg_div_mul_val := mem_reg_div_mul_val
|
||||||
wb_reg_fp_val := mem_reg_fp_val
|
wb_reg_fp_val := mem_reg_fp_val
|
||||||
wb_reg_replay_next := mem_reg_replay_next
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val replay_wb = io.dmem.resp.bits.nack || wb_reg_replay || vec_replay || io.dpath.pcr_replay
|
val replay_wb = io.dmem.resp.bits.nack || wb_reg_replay || vec_replay || io.dpath.pcr_replay
|
||||||
@ -651,7 +652,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.imem.req.bits.taken := !ex_reg_btb_hit || ex_reg_jalr
|
io.imem.req.bits.taken := !ex_reg_btb_hit || ex_reg_jalr
|
||||||
io.imem.req.valid := take_pc
|
io.imem.req.valid := take_pc
|
||||||
|
|
||||||
// stall for RAW/WAW hazards on loads, AMOs, and mul/div in execute stage.
|
// stall for RAW/WAW hazards on PCRs, loads, AMOs, and mul/div in execute stage.
|
||||||
val data_hazard_ex = ex_reg_wen &&
|
val data_hazard_ex = ex_reg_wen &&
|
||||||
(id_renx1.toBool && id_raddr1 === io.dpath.ex_waddr ||
|
(id_renx1.toBool && id_raddr1 === io.dpath.ex_waddr ||
|
||||||
id_renx2.toBool && id_raddr2 === io.dpath.ex_waddr ||
|
id_renx2.toBool && id_raddr2 === io.dpath.ex_waddr ||
|
||||||
@ -661,10 +662,10 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.fpu.dec.ren2 && id_raddr2 === io.dpath.ex_waddr ||
|
io.fpu.dec.ren2 && id_raddr2 === io.dpath.ex_waddr ||
|
||||||
io.fpu.dec.ren3 && id_raddr3 === io.dpath.ex_waddr ||
|
io.fpu.dec.ren3 && id_raddr3 === io.dpath.ex_waddr ||
|
||||||
io.fpu.dec.wen && id_waddr === io.dpath.ex_waddr)
|
io.fpu.dec.wen && id_waddr === io.dpath.ex_waddr)
|
||||||
val id_ex_hazard = data_hazard_ex && (ex_reg_mem_val || ex_reg_div_mul_val || ex_reg_fp_val) ||
|
val id_ex_hazard = data_hazard_ex && (ex_reg_pcr != PCR.N || ex_reg_mem_val || ex_reg_div_mul_val || ex_reg_fp_val) ||
|
||||||
fp_data_hazard_ex && (ex_reg_mem_val || ex_reg_fp_val)
|
fp_data_hazard_ex && (ex_reg_mem_val || ex_reg_fp_val)
|
||||||
|
|
||||||
// stall for RAW/WAW hazards on LB/LH and mul/div in memory stage.
|
// stall for RAW/WAW hazards on PCRs, LB/LH, and mul/div in memory stage.
|
||||||
val mem_mem_cmd_bh =
|
val mem_mem_cmd_bh =
|
||||||
if (!conf.fastLoadWord) Bool(true)
|
if (!conf.fastLoadWord) Bool(true)
|
||||||
else if (conf.fastLoadByte) Bool(false)
|
else if (conf.fastLoadByte) Bool(false)
|
||||||
@ -678,7 +679,7 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
io.fpu.dec.ren2 && id_raddr2 === io.dpath.mem_waddr ||
|
io.fpu.dec.ren2 && id_raddr2 === io.dpath.mem_waddr ||
|
||||||
io.fpu.dec.ren3 && id_raddr3 === io.dpath.mem_waddr ||
|
io.fpu.dec.ren3 && id_raddr3 === io.dpath.mem_waddr ||
|
||||||
io.fpu.dec.wen && id_waddr === io.dpath.mem_waddr)
|
io.fpu.dec.wen && id_waddr === io.dpath.mem_waddr)
|
||||||
val id_mem_hazard = data_hazard_mem && (mem_reg_mem_val && mem_mem_cmd_bh || mem_reg_div_mul_val || mem_reg_fp_val) ||
|
val id_mem_hazard = data_hazard_mem && (mem_reg_pcr != PCR.N || mem_reg_mem_val && mem_mem_cmd_bh || mem_reg_div_mul_val || mem_reg_fp_val) ||
|
||||||
fp_data_hazard_mem && mem_reg_fp_val
|
fp_data_hazard_mem && mem_reg_fp_val
|
||||||
id_load_use := mem_reg_mem_val && (data_hazard_mem || fp_data_hazard_mem)
|
id_load_use := mem_reg_mem_val && (data_hazard_mem || fp_data_hazard_mem)
|
||||||
|
|
||||||
@ -705,10 +706,11 @@ class Control(implicit conf: RocketConfiguration) extends Component
|
|||||||
id_fp_val && id_stall_fpu ||
|
id_fp_val && id_stall_fpu ||
|
||||||
id_mem_val && !io.dmem.req.ready ||
|
id_mem_val && !io.dmem.req.ready ||
|
||||||
vec_stalld
|
vec_stalld
|
||||||
ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || id_interrupt
|
val ctrl_draind = id_interrupt || ex_reg_replay_next
|
||||||
|
ctrl_killd := !io.imem.resp.valid || take_pc || ctrl_stalld || ctrl_draind
|
||||||
|
|
||||||
io.dpath.killd := take_pc || ctrl_stalld && !id_interrupt
|
io.dpath.killd := take_pc || ctrl_stalld && !ctrl_draind
|
||||||
io.imem.resp.ready := pc_taken || !ctrl_stalld
|
io.imem.resp.ready := pc_taken || !ctrl_stalld || ctrl_draind
|
||||||
io.imem.invalidate := wb_reg_flush_inst
|
io.imem.invalidate := wb_reg_flush_inst
|
||||||
|
|
||||||
io.dpath.mem_load := mem_reg_mem_val && mem_reg_wen
|
io.dpath.mem_load := mem_reg_mem_val && mem_reg_wen
|
||||||
|
Loading…
Reference in New Issue
Block a user