Skip to content

Commit

Permalink
Merge pull request #393 from riscv-boom/cfifix
Browse files Browse the repository at this point in the history
[core] Refactor CfiTypes constants
  • Loading branch information
jerryz123 committed Sep 24, 2019
2 parents 36aeeb4 + b788d64 commit 783b936
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/bpu/btb/btb-sa.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class BTBsa(val bankBytes: Int)(implicit p: Parameters) extends BoomBTB
val target = UInt((vaddrBits - log2Ceil(coreInstBytes)).W)
val cfi_idx = UInt(log2Ceil(fetchWidth).W)
val bpd_type = BpredType()
val cfi_type = CfiType()
val cfi_type = UInt(CFI_SZ.W)
val is_rvc = Bool()
val is_edge = Bool()
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/bpu/btb/btb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class BoomBTBResp(implicit p: Parameters) extends BoomBTBBundle
// shifting off the lowest log(inst_bytes) bits off).
val cfi_idx = UInt(log2Ceil(fetchWidth).W) // where is cfi we are predicting?
val bpd_type = BpredType() // which predictor should we use?
val cfi_type = CfiType() // what type of instruction is this?
val cfi_type = UInt(CFI_SZ.W) // what type of instruction is this?
val fetch_pc = UInt(vaddrBits.W) // the PC we're predicting on (start of the fetch packet).

val bim_resp = Valid(new BimResp) // Output from the bimodal table. Valid if prediction provided.
Expand All @@ -151,7 +151,7 @@ class BoomBTBUpdate(implicit p: Parameters) extends BoomBTBBundle

// other branch information
val bpd_type = BpredType()
val cfi_type = CfiType()
val cfi_type = UInt(CFI_SZ.W)

val is_rvc = Bool()
val is_edge = Bool()
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/bpu/btb/dense-btb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class DenseBTB(val bankBytes: Int)(implicit p: Parameters) extends BoomBTB
val tag = UInt(tagSz.W)
val offset = UInt(offsetSz.W)
val bpd_type = BpredType()
val cfi_type = CfiType()
val cfi_type = UInt(CFI_SZ.W)
val cfi_idx = UInt(log2Ceil(fetchWidth).W)
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/scala/common/consts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ trait IQType
val IQT_MFP = 6.U(IQT_SZ.W)
}


/**
* Mixin for scalar operation constants
*/
Expand All @@ -83,6 +84,13 @@ trait ScalarOpConstants
//************************************
// Control Signals

// CFI types
val CFI_SZ = 3
val CFI_X = 0.U(CFI_SZ.W) // Not a CFI instruction
val CFI_BR = 1.U(CFI_SZ.W) // Branch
val CFI_JAL = 2.U(CFI_SZ.W) // JAL
val CFI_JALR = 3.U(CFI_SZ.W) // JALR

// PC Select Signal
val PC_PLUS4 = 0.U(2.W) // PC + 4
val PC_BRJMP = 1.U(2.W) // brjmp_target
Expand Down
12 changes: 0 additions & 12 deletions src/main/scala/common/micro-op.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,6 @@ class DebugStageEvents extends Bundle()
val fetch_seq = UInt(32.W)
}

/**
* Object to get type of control flow instruction
*/
object CfiType
{
def SZ = 3
def apply() = UInt(SZ.W)
def none = 0.U
def branch = 1.U
def jal = 2.U
def jalr = 3.U
}

/**
* MicroOp with data
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/exu/decode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ class BranchDecode(implicit p: Parameters) extends BoomModule
val is_ret = Output(Bool())
val is_call = Output(Bool())
val target = Output(UInt(vaddrBitsExtended.W))
val cfi_type = Output(UInt(CfiType.SZ.W))
val cfi_type = Output(UInt(CFI_SZ.W))
})

val bpd_csignals =
Expand Down Expand Up @@ -626,12 +626,12 @@ class BranchDecode(implicit p: Parameters) extends BoomModule
ComputeJALTarget(io.pc, io.inst, xLen))
io.cfi_type :=
Mux(cs_is_jalr,
CfiType.jalr,
CFI_JALR,
Mux(cs_is_jal,
CfiType.jal,
CFI_JAL,
Mux(cs_is_br,
CfiType.branch,
CfiType.none)))
CFI_BR,
CFI_X)))
}

/**
Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/exu/execution-units/functional-unit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class BrResolutionInfo(implicit p: Parameters) extends BoomBundle
val rxq_idx = UInt(log2Ceil(numRxqEntries).W) // ditto for RoCC queue
val taken = Bool() // which direction did the branch go?
val is_jr = Bool() // TODO remove use cfi_type instead
val cfi_type = CfiType()
val cfi_type = UInt(CFI_SZ.W)

// for stats
val btb_made_pred = Bool()
Expand Down Expand Up @@ -528,9 +528,9 @@ class ALUUnit(isBranchUnit: Boolean = false, numStages: Int = 1, dataWidth: Int)
brinfo.stq_idx := uop.stq_idx
brinfo.rxq_idx := uop.rxq_idx
brinfo.is_jr := pc_sel === PC_JALR
brinfo.cfi_type := Mux(uop.is_jal, CfiType.jal,
Mux(pc_sel === PC_JALR, CfiType.jalr,
Mux(uop.is_br_or_jmp, CfiType.branch, CfiType.none)))
brinfo.cfi_type := Mux(uop.is_jal, CFI_JAL,
Mux(pc_sel === PC_JALR, CFI_JALR,
Mux(uop.is_br_or_jmp, CFI_BR, CFI_X)))
brinfo.taken := is_taken
brinfo.btb_mispredict := btb_mispredict
brinfo.bpd_mispredict := bpd_mispredict
Expand All @@ -555,9 +555,9 @@ class ALUUnit(isBranchUnit: Boolean = false, numStages: Int = 1, dataWidth: Int)
br_unit.btb_update.bits.target := (target.asSInt & (-coreInstBytes).S).asUInt
br_unit.btb_update.bits.taken := is_taken // was this branch/jal/jalr "taken"
br_unit.btb_update.bits.cfi_type :=
Mux(uop.is_jal , CfiType.jal,
Mux(uop.is_jump && !uop.is_jal, CfiType.jalr,
CfiType.branch))
Mux(uop.is_jal , CFI_JAL,
Mux(uop.is_jump && !uop.is_jal, CFI_JALR,
CFI_BR))
br_unit.btb_update.bits.bpd_type :=
Mux(uop.is_ret, BpredType.RET,
Mux(uop.is_call, BpredType.CALL,
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/ifu/branch-checker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,18 @@ class BranchChecker(implicit p: Parameters) extends BoomModule
val bpd_predicted_taken = io.bpd_resp.valid && io.bpd_resp.bits.takens(io.btb_resp.bits.cfi_idx)

when (io.btb_resp.valid) {
when (io.btb_resp.bits.cfi_type === CfiType.branch && (io.btb_resp.bits.taken || bpd_predicted_taken)) {
when (io.btb_resp.bits.cfi_type === CFI_BR && (io.btb_resp.bits.taken || bpd_predicted_taken)) {
wrong_cfi := !io.is_br(btb_idx)
wrong_target := io.br_targs(btb_idx) =/= btb_target
} .elsewhen (io.btb_resp.bits.cfi_type === CfiType.jal) {
} .elsewhen (io.btb_resp.bits.cfi_type === CFI_JAL) {
wrong_cfi := !io.is_jal(btb_idx)
wrong_target := io.jal_targs(btb_idx) =/= btb_target
} .elsewhen (io.btb_resp.bits.cfi_type === CfiType.jalr) {
} .elsewhen (io.btb_resp.bits.cfi_type === CFI_JALR) {
wrong_cfi := !io.is_jr(btb_idx)
} .otherwise {
wrong_cfi := io.btb_resp.bits.cfi_type === CfiType.none && io.btb_resp.bits.taken
wrong_cfi := io.btb_resp.bits.cfi_type === CFI_X && io.btb_resp.bits.taken
when (io.valid) {
assert (io.btb_resp.bits.cfi_type =/= CfiType.none, "[fetch] predicted on a non-cfi type.")
assert (io.btb_resp.bits.cfi_type =/= CFI_X, "[fetch] predicted on a non-cfi type.")
}
}
}
Expand Down Expand Up @@ -132,7 +132,7 @@ class BranchChecker(implicit p: Parameters) extends BoomModule
io.btb_update.bits.taken := true.B
io.btb_update.bits.cfi_idx := jal_idx
io.btb_update.bits.bpd_type := Mux(io.is_call(jal_idx), BpredType.CALL, BpredType.JUMP)
io.btb_update.bits.cfi_type := CfiType.jal
io.btb_update.bits.cfi_type := CFI_JAL
io.btb_update.bits.is_rvc := io.is_rvc(jal_idx)
io.btb_update.bits.is_edge := io.edge_inst && (jal_idx === 0.U)

Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/ifu/fetch-control-unit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule
f3_btb_update_bits.target := f3_bpd_target
f3_btb_update_bits.cfi_idx := f3_bpd_br_idx
f3_btb_update_bits.bpd_type := BpredType.BRANCH
f3_btb_update_bits.cfi_type := CfiType.branch
f3_btb_update_bits.cfi_type := CFI_BR
f3_btb_update_bits.is_rvc := is_rvc(f3_bpd_br_idx)
f3_btb_update_bits.is_edge := f3_fetch_bundle.edge_inst && (f3_bpd_br_idx === 0.U)
}
Expand Down Expand Up @@ -618,7 +618,7 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule
val last_pc = Reg(UInt(vaddrBitsExtended.W))
val last_target = Reg(UInt(vaddrBitsExtended.W))
val last_nextlinepc = Reg(UInt(vaddrBitsExtended.W))
val last_cfi_type = Reg(UInt(CfiType.SZ.W))
val last_cfi_type = Reg(UInt(CFI_SZ.W))

val cfi_idx = (fetchWidth-1).U - PriorityEncoder(Reverse(f3_fetch_bundle.mask))
val fetch_pc = f3_fetch_bundle.pc
Expand All @@ -640,16 +640,16 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule

val cfi_type = GetCfiType(curr_inst)
last_cfi_type := cfi_type
last_target := Mux(cfi_type === CfiType.jal,
last_target := Mux(cfi_type === CFI_JAL,
ComputeJALTarget(cfi_pc, curr_inst, xLen),
ComputeBranchTarget(cfi_pc, curr_inst, xLen))

when (last_valid) {
// check for error
when (last_cfi_type === CfiType.none) {
when (last_cfi_type === CFI_X) {
assert (fetch_pc === last_nextlinepc,
"[fetch] A non-cfi instruction is followed by the wrong instruction.")
} .elsewhen (last_cfi_type === CfiType.jal) {
} .elsewhen (last_cfi_type === CFI_JAL) {
// ignore misaligned fetches -- we should have marked the instruction as excepting,
// but when it makes a misaligned fetch request the I$ gives us back an aligned PC.
val f_pc = (fetch_pc(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
Expand All @@ -662,7 +662,7 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule
fetch_pc, last_target, last_nextlinepc)
}
assert (f_pc === targ, "[fetch] JAL is followed by the wrong instruction.")
} .elsewhen (last_cfi_type === CfiType.branch) {
} .elsewhen (last_cfi_type === CFI_BR) {
// again, ignore misaligned fetches -- an exception should be caught.
val f_pc = (fetch_pc(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
- Mux(f3_fetch_bundle.edge_inst, 1.U, 0.U))
Expand All @@ -675,7 +675,7 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule
"[fetch] branch is followed by the wrong instruction.")
} .otherwise {
// we can't verify JALR instruction stream integrity -- /throws hands up.
assert (last_cfi_type === CfiType.jalr, "[fetch] Should be a JALR if none of the others were valid.")
assert (last_cfi_type === CFI_JALR, "[fetch] Should be a JALR if none of the others were valid.")
}
}
}
Expand All @@ -694,7 +694,7 @@ class FetchControlUnit(implicit p: Parameters) extends BoomModule
// <beq, jal, bne, ...>, either the beq or jal may be the last instruction, but because
// the jal dominates everything after it, nothing valid can be after it.
val f3_is_jal = VecInit(f3_fetch_bundle.insts map {x =>
GetCfiType(ExpandRVC(x)) === CfiType.jal}).asUInt & f3_fetch_bundle.mask
GetCfiType(ExpandRVC(x)) === CFI_JAL}).asUInt & f3_fetch_bundle.mask
val f3_jal_idx = PriorityEncoder(f3_is_jal)
val has_jal = f3_is_jal.orR

Expand Down
24 changes: 12 additions & 12 deletions src/main/scala/ifu/fetch-monitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
var prev_valid = WireInit(false.B)
// What was the previous uop's PC?
var prev_pc = WireInit(0.U(vaddrBitsExtended.W))
var prev_cfitype = WireInit(CfiType.none)
var prev_cfitype = WireInit(CFI_X)
// What is the straight-line next PC for the previous uop?
var prev_npc = WireInit(0.U(vaddrBitsExtended.W))
// What is the target of the previous PC if a CFI.
Expand All @@ -67,16 +67,16 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule

for (uop <- io.uops) {
when (prev_valid && uop.valid && io.fire) {
when (prev_cfitype === CfiType.none) {
when (prev_cfitype === CFI_X) {
assert (uop.bits.debug_pc === prev_npc, "[fetchmonitor] non-cfi went to bad next-pc.")
} .elsewhen (prev_cfitype === CfiType.branch) {
} .elsewhen (prev_cfitype === CFI_BR) {
assert (uop.bits.debug_pc === prev_npc || uop.bits.debug_pc === prev_target,
"[fetchmonitor] branch went to bad next-pc.")
} .elsewhen (prev_cfitype === CfiType.jal) {
} .elsewhen (prev_cfitype === CFI_JAL) {
assert (uop.bits.debug_pc === prev_target, "[fetchmonitor] JAL went to bad target.")
} .otherwise {
// should only be here if a JALR.
assert (prev_cfitype === CfiType.jalr, "[fetchmonitor] CFI type not JALR.")
assert (prev_cfitype === CFI_JALR, "[fetchmonitor] CFI type not JALR.")
}
}

Expand All @@ -86,7 +86,7 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
val inst = ExpandRVC(uop.bits.debug_inst)
prev_cfitype = GetCfiType(inst)
prev_target =
Mux(prev_cfitype === CfiType.jal,
Mux(prev_cfitype === CFI_JAL,
ComputeJALTarget(uop.bits.debug_pc, inst, xLen),
ComputeBranchTarget(uop.bits.debug_pc, inst, xLen))
}
Expand All @@ -97,7 +97,7 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
var last_valid = RegInit(false.B)
// What was the previous decode group's last uop's PC?
var last_pc = RegInit(0.U(vaddrBitsExtended.W))
var last_cfitype = RegInit(CfiType.none)
var last_cfitype = RegInit(CFI_X)
// What is the straight-line next PC for the previous uop?
var last_npc = RegInit(0.U(vaddrBitsExtended.W))
// What is the target of the previous PC if a CFI.
Expand All @@ -121,35 +121,35 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
}
last_cfitype := GetCfiType(inst)
last_target :=
Mux(GetCfiType(inst) === CfiType.jal,
Mux(GetCfiType(inst) === CFI_JAL,
ComputeJALTarget(end_uop.debug_pc, inst, xLen),
ComputeBranchTarget(end_uop.debug_pc, inst, xLen))

when (last_valid) {
val first_idx = PriorityEncoder(valid_mask)
val first_pc = io.uops(first_idx).bits.debug_pc
when (last_cfitype === CfiType.none) {
when (last_cfitype === CFI_X) {
when (first_pc =/= last_npc) {
printf(" first_pc: 0x%x last_npc: 0x%x ",
first_pc, last_npc)
}
assert (first_pc === last_npc,
"[fetchmonitor] A non-cfi instruction is followed by the wrong instruction.")
} .elsewhen (last_cfitype === CfiType.jal) {
} .elsewhen (last_cfitype === CFI_JAL) {
// ignore misaligned fetches.
val f_pc = first_pc(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
val targ = last_target(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
assert (f_pc === targ,
"[fetchmonitor] A jump is followed by the wrong instruction.")
} .elsewhen (last_cfitype === CfiType.branch) {
} .elsewhen (last_cfitype === CFI_BR) {
// ignore misaligned fetches.
val f_pc = first_pc(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
val targ = last_target(vaddrBitsExtended-1, log2Ceil(coreInstBytes))
assert (first_pc === last_npc || f_pc === targ,
"[fetchmonitor] A branch is followed by the wrong instruction.")
} .otherwise {
// we can't verify JALR instruction stream integrity -- /throws hands up.
assert (last_cfitype === CfiType.jalr,
assert (last_cfitype === CFI_JALR,
"[fetchmonitor] Should be a JALR if none of the others were valid.")
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/ifu/fetch-target-queue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class CfiMissInfo(implicit p: Parameters) extends BoomBundle
val mispredicted = Bool() // Was a branch or jump mispredicted in this fetch group?
val taken = Bool() // If a branch, was it taken?
val cfi_idx = UInt(log2Ceil(fetchWidth).W) // which instruction in fetch group?
val cfi_type = CfiType() // What kind of instruction is stored here?
val cfi_type = UInt(CFI_SZ.W) // What kind of instruction is stored here?
}

/**
Expand Down Expand Up @@ -141,7 +141,7 @@ class FetchTargetQueue(num_entries: Int)(implicit p: Parameters) extends BoomMod
b.mispredicted := false.B
b.taken := false.B
b.cfi_idx := cfi_idx
b.cfi_type := Mux(br_seen, CfiType.branch, CfiType.none)
b.cfi_type := Mux(br_seen, CFI_BR, CFI_X)
b
}

Expand Down Expand Up @@ -227,7 +227,7 @@ class FetchTargetQueue(num_entries: Int)(implicit p: Parameters) extends BoomMod
val saturated = (com_cntr === 0.U && !com_taken) || (com_cntr === 3.U && com_taken)

io.bim_update.valid :=
miss_data.cfi_type === CfiType.branch &&
miss_data.cfi_type === CFI_BR &&
(miss_data.mispredicted) ||
(!miss_data.mispredicted && miss_data.executed && !saturated)

Expand Down

0 comments on commit 783b936

Please sign in to comment.