Skip to content

Commit

Permalink
Merge pull request #344 from riscv-boom/no-pc-in-fb
Browse files Browse the repository at this point in the history
[core/rob] Get exception PC's from FTQ
  • Loading branch information
bkorpan committed Jul 25, 2019
2 parents d0c5520 + 2723e0d commit f02e389
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/common/micro-op.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MicroOp(implicit p: Parameters) extends BoomBundle
val inst = UInt(32.W)
val debug_inst = UInt(32.W)
val is_rvc = Bool()
val pc = UInt(coreMaxAddrBits.W) // TODO remove -- use FTQ to get PC. Change to debug_pc.
val debug_pc = UInt(coreMaxAddrBits.W)
val iq_type = UInt(IQT_SZ.W) // which issue unit do we use?
val fu_code = UInt(FUConstants.FUC_SZ.W) // which functional unit do we use?
val ctrl = new CtrlSignals
Expand Down
49 changes: 39 additions & 10 deletions src/main/scala/exu/core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
val dec_fire = Wire(Vec(coreWidth, Bool())) // can the instruction fire beyond decode?
// (can still be stopped in ren or dis)
val dec_ready = Wire(Bool())
val dec_xcpts = Wire(Vec(coreWidth, Bool()))

// Rename2/Dispatch stage
val dis_valids = Wire(Vec(coreWidth, Bool()))
Expand Down Expand Up @@ -393,12 +394,45 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
dec_uops(w) := decode_units(w).io.deq.uop
}

//-------------------------------------------------------------
// FTQ GetPC Port Arbitration

val bru_pc_req = Wire(Decoupled(UInt(log2Ceil(ftqSz).W)))
val xcpt_pc_req = Wire(Decoupled(UInt(log2Ceil(ftqSz).W)))

val ftq_arb = Module(new Arbiter(UInt(log2Ceil(ftqSz).W), 2))

ftq_arb.io.in(0) <> bru_pc_req
ftq_arb.io.in(1) <> xcpt_pc_req

// Hookup FTQ
io.ifu.get_pc.ftq_idx := ftq_arb.io.out.bits
ftq_arb.io.out.ready := true.B

// Branch Unit Requests
bru_pc_req.valid := RegNext(iss_valids(brunit_idx))
bru_pc_req.bits := RegNext(iss_uops(brunit_idx).ftq_idx)
exe_units(brunit_idx).io.get_ftq_pc.fetch_pc := RegNext(io.ifu.get_pc.fetch_pc)
exe_units(brunit_idx).io.get_ftq_pc.next_val := RegNext(io.ifu.get_pc.next_val)
exe_units(brunit_idx).io.get_ftq_pc.next_pc := RegNext(io.ifu.get_pc.next_pc)

// Frontend Exception Requests
val xcpt_idx = PriorityEncoder(dec_xcpts)
xcpt_pc_req.valid := dec_xcpts.reduce(_||_)
xcpt_pc_req.bits := dec_uops(xcpt_idx).ftq_idx
rob.io.xcpt_fetch_pc := RegEnable(io.ifu.get_pc.fetch_pc, dis_ready)

//-------------------------------------------------------------
// Decode/Rename1 pipeline logic

dec_xcpts := dec_uops zip dec_valids map {case (u,v) => u.exception && v}
val dec_xcpt_stall = dec_xcpts.reduce(_||_) && !xcpt_pc_req.ready

val dec_hazards = (0 until coreWidth).map(w =>
dec_valids(w) &&
( !dis_ready
|| rob.io.commit.rollback
|| dec_xcpt_stall
|| branch_mask_full(w)
|| !rename_stage.io.inst_can_proceed(w)
|| flush_ifu))
Expand Down Expand Up @@ -464,6 +498,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
//-------------------------------------------------------------
//-------------------------------------------------------------

//-------------------------------------------------------------
// Rename2/Dispatch pipeline logic

val dis_prior_slot_valid = dis_valids.scanLeft(false.B) ((s,v) => s || v)
Expand Down Expand Up @@ -993,12 +1028,6 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
// branch resolution
rob.io.brinfo <> br_unit.brinfo

// branch unit requests PCs and predictions from ROB during register read
// (fetch PC from ROB cycle earlier than needed for critical path reasons)
io.ifu.get_pc.ftq_idx := RegNext(iss_uops(brunit_idx).ftq_idx)
exe_units(brunit_idx).io.get_ftq_pc.fetch_pc := RegNext(io.ifu.get_pc.fetch_pc)
exe_units(brunit_idx).io.get_ftq_pc.next_val := RegNext(io.ifu.get_pc.next_val)
exe_units(brunit_idx).io.get_ftq_pc.next_pc := RegNext(io.ifu.get_pc.next_pc)
exe_units(brunit_idx).io.status := csr.io.status

// LSU <> ROB
Expand Down Expand Up @@ -1073,7 +1102,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
for (w <- 0 until coreWidth) {
printf(" Slot:%d (PC:0x%x Valids:%c%c Inst:DASM(%x))\n",
w.U,
dec_uops(w).pc(19,0),
dec_uops(w).debug_pc(19,0),
BoolToChar(io.ifu.fetchpacket.valid && dec_fbundle.uops(w).valid && !dec_finished_mask(w), 'V'),
BoolToChar(dec_fire(w), 'V'),
dec_fbundle.uops(w).bits.debug_inst)
Expand All @@ -1083,7 +1112,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
for (w <- 0 until coreWidth) {
printf(" Slot:%d (PC:0x%x Valid:%c Inst:DASM(%x))\n",
w.U,
rename_stage.io.ren2_uops(w).pc(19,0),
rename_stage.io.ren2_uops(w).debug_pc(19,0),
BoolToChar(rename_stage.io.ren2_mask(w), 'V'),
rename_stage.io.ren2_uops(w).debug_inst)
}
Expand Down Expand Up @@ -1187,7 +1216,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
when (rob.io.commit.valids(w)) {
printf("%d 0x%x ",
priv,
Sext(rob.io.commit.uops(w).pc(vaddrBits-1,0), xLen))
Sext(rob.io.commit.uops(w).debug_pc(vaddrBits-1,0), xLen))
printf_inst(rob.io.commit.uops(w))
when (rob.io.commit.uops(w).dst_rtype === RT_FIX && rob.io.commit.uops(w).ldst =/= 0.U) {
printf(" x%d 0x%x\n",
Expand Down Expand Up @@ -1293,7 +1322,7 @@ class BoomCore(implicit p: Parameters, edge: freechips.rocketchip.tilelink.TLEdg
if (p(BoomTilesKey)(0).trace) {
for (w <- 0 until coreWidth) {
io.trace(w).valid := rob.io.commit.valids(w)
io.trace(w).iaddr := Sext(rob.io.commit.uops(w).pc(vaddrBits-1,0), xLen)
io.trace(w).iaddr := Sext(rob.io.commit.uops(w).debug_pc(vaddrBits-1,0), xLen)
io.trace(w).insn := rob.io.commit.uops(w).debug_inst
// I'm uncertain the commit signals from the ROB match these CSR exception signals
io.trace(w).priv := csr.io.status.prv
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/exu/issue-units/issue-unit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ abstract class IssueUnit(
issue_slots(i).uop.prs1,
issue_slots(i).uop.prs2,
issue_slots(i).uop.prs3,
issue_slots(i).uop.pc(31,0),
issue_slots(i).uop.debug_pc(31,0),
issue_slots(i).uop.debug_inst,
issue_slots(i).uop.uopc,
issue_slots(i).uop.rob_idx,
Expand Down
18 changes: 10 additions & 8 deletions src/main/scala/exu/rob.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class RobIo(
// and stalling on the rest of it (don't
// advance the tail ptr)

val xcpt_fetch_pc = Input(UInt(vaddrBitsExtended.W))

val rob_tail_idx = Output(UInt(robAddrSz.W))
val rob_pnr_idx = Output(UInt(robAddrSz.W))
val rob_head_idx = Output(UInt(robAddrSz.W))
Expand Down Expand Up @@ -648,7 +650,7 @@ class Rob(
// if no exception yet, dispatch exception wins
r_xcpt_val := true.B
next_xcpt_uop := io.enq_uops(idx)
r_xcpt_badvaddr := io.enq_uops(idx).pc + Mux(io.enq_uops(idx).edge_inst, 2.U, 0.U)
r_xcpt_badvaddr := AlignPCToBoundary(io.xcpt_fetch_pc, icBlockBytes) | io.enq_uops(idx).pc_lob

assert(!(usingCompressed.B && (io.enq_uops(idx).uopc === uopJAL) && !io.enq_uops(idx).exc_cause.orR),
"when using RVC, JAL exceptions should not be seen")
Expand Down Expand Up @@ -917,7 +919,7 @@ class Rob(
BoolToChar( debug_entry(r_idx+0).valid, 'V'),
BoolToChar( debug_entry(r_idx+0).busy, 'B'),
BoolToChar(debug_entry(r_idx+0).unsafe, 'U'),
debug_entry(r_idx+0).uop.pc(31,0),
debug_entry(r_idx+0).uop.debug_pc(31,0),
debug_entry(r_idx+0).uop.debug_inst,
BoolToChar(debug_entry(r_idx+0).exception, 'E'))
} else if (coreWidth == 2) {
Expand All @@ -929,8 +931,8 @@ class Rob(
BoolToChar( debug_entry(r_idx+1).busy, 'B'),
BoolToChar(debug_entry(r_idx+0).unsafe, 'U'),
BoolToChar(debug_entry(r_idx+1).unsafe, 'U'),
debug_entry(r_idx+0).uop.pc(31,0),
debug_entry(r_idx+1).uop.pc(15,0),
debug_entry(r_idx+0).uop.debug_pc(31,0),
debug_entry(r_idx+1).uop.debug_pc(15,0),
debug_entry(r_idx+0).uop.debug_inst,
debug_entry(r_idx+1).uop.debug_inst,
BoolToChar(debug_entry(r_idx+0).exception, 'E'),
Expand All @@ -952,10 +954,10 @@ class Rob(
BoolToChar(debug_entry(r_idx+1).unsafe, 'U'),
BoolToChar(debug_entry(r_idx+2).unsafe, 'U'),
BoolToChar(debug_entry(r_idx+3).unsafe, 'U'),
debug_entry(r_idx+0).uop.pc(23,0),
debug_entry(r_idx+1).uop.pc(15,0),
debug_entry(r_idx+2).uop.pc(15,0),
debug_entry(r_idx+3).uop.pc(15,0),
debug_entry(r_idx+0).uop.debug_pc(23,0),
debug_entry(r_idx+1).uop.debug_pc(15,0),
debug_entry(r_idx+2).uop.debug_pc(15,0),
debug_entry(r_idx+3).uop.debug_pc(15,0),
debug_entry(r_idx+0).uop.debug_inst,
debug_entry(r_idx+1).uop.debug_inst,
debug_entry(r_idx+2).uop.debug_inst,
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/ifu/fetch-buffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ class FetchBuffer(numEntries: Int)(implicit p: Parameters) extends BoomModule
in_uops(i) := DontCare
in_mask(i) := io.enq.valid && io.enq.bits.mask(i)
in_uops(i).edge_inst := false.B
in_uops(i).pc := (alignToFetchBoundary(io.enq.bits.pc)
in_uops(i).debug_pc := (alignToFetchBoundary(io.enq.bits.pc)
+ (i << log2Ceil(coreInstBytes)).U)
in_uops(i).pc_lob := in_uops(i).pc // LHS width will cut off high-order bits.
in_uops(i).pc_lob := in_uops(i).debug_pc // LHS width will cut off high-order bits.
in_uops(i).cfi_idx := i.U
if (i == 0) {
when (io.enq.bits.edge_inst) {
assert(usingCompressed.B)
in_uops(i).pc := alignToFetchBoundary(io.enq.bits.pc) - 2.U
in_uops(i).debug_pc := alignToFetchBoundary(io.enq.bits.pc) - 2.U
in_uops(i).pc_lob := alignToFetchBoundary(io.enq.bits.pc)
in_uops(i).edge_inst:= true.B
}
Expand Down Expand Up @@ -209,6 +209,6 @@ class FetchBuffer(numEntries: Int)(implicit p: Parameters) extends BoomModule

printf(" Fetch4: Deq:(V:%c PC:0x%x)\n",
BoolToChar(io.deq.valid, 'V'),
io.deq.bits.uops(0).bits.pc)
io.deq.bits.uops(0).bits.debug_pc)
}
}
22 changes: 11 additions & 11 deletions src/main/scala/ifu/fetch-monitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,34 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
i.U,
BoolToChar(io.fire, 'F'),
BoolToChar(uop.valid, 'V'),
uop.bits.pc)
uop.bits.debug_pc)
}
}

for (uop <- io.uops) {
when (prev_valid && uop.valid && io.fire) {
when (prev_cfitype === CfiType.none) {
assert (uop.bits.pc === prev_npc, "[fetchmonitor] non-cfi went to bad next-pc.")
assert (uop.bits.debug_pc === prev_npc, "[fetchmonitor] non-cfi went to bad next-pc.")
} .elsewhen (prev_cfitype === CfiType.branch) {
assert (uop.bits.pc === prev_npc || uop.bits.pc === prev_target,
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) {
assert (uop.bits.pc === prev_target, "[fetchmonitor] JAL went to bad target.")
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.")
}
}

prev_valid = uop.valid && io.fire
prev_pc = uop.bits.pc
prev_pc = uop.bits.debug_pc
prev_npc = prev_pc + Mux(uop.bits.is_rvc, 2.U, 4.U)
val inst = ExpandRVC(uop.bits.debug_inst)
prev_cfitype = GetCfiType(inst)
prev_target =
Mux(prev_cfitype === CfiType.jal,
ComputeJALTarget(uop.bits.pc, inst, xLen),
ComputeBranchTarget(uop.bits.pc, inst, xLen))
ComputeJALTarget(uop.bits.debug_pc, inst, xLen),
ComputeBranchTarget(uop.bits.debug_pc, inst, xLen))
}

// Check if the enqueue'd PC is a target of the previous valid enqueue'd PC.
Expand All @@ -112,7 +112,7 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
assert (valid_mask =/= 0.U)
val end_idx = (decodeWidth-1).U - PriorityEncoder(Reverse(valid_mask))
val end_uop = io.uops(end_idx).bits
val end_pc = end_uop.pc
val end_pc = end_uop.debug_pc
val end_compressed = end_uop.debug_inst(1,0) =/= 3.U && usingCompressed.B
val inst = ExpandRVC(end_uop.debug_inst)
last_pc := end_pc
Expand All @@ -124,12 +124,12 @@ class FetchMonitor(implicit p: Parameters) extends BoomModule
last_cfitype := GetCfiType(inst)
last_target :=
Mux(GetCfiType(inst) === CfiType.jal,
ComputeJALTarget(end_uop.pc, inst, xLen),
ComputeBranchTarget(end_uop.pc, inst, xLen))
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.pc
val first_pc = io.uops(first_idx).bits.debug_pc
when (last_cfitype === CfiType.none) {
when (first_pc =/= last_npc) {
printf(" first_pc: 0x%x last_npc: 0x%x ",
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/ifu/old-fetch-buffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ class OldFetchBuffer(numEntries: Int)(implicit p: Parameters) extends BoomModule
in_uops(i) := DontCare
in_mask(i) := io.enq.valid && io.enq.bits.mask(i)
in_uops(i).edge_inst := false.B
in_uops(i).pc := (alignToFetchBoundary(io.enq.bits.pc)
in_uops(i).debug_pc := (alignToFetchBoundary(io.enq.bits.pc)
+ (i << log2Ceil(coreInstBytes)).U)
in_uops(i).pc_lob := in_uops(i).pc // LHS width will cut off high-order bits.
in_uops(i).pc_lob := in_uops(i).debug_pc // LHS width will cut off high-order bits.
in_uops(i).cfi_idx := i.U
if (i == 0) {
when (io.enq.bits.edge_inst) {
assert(usingCompressed.B)
in_uops(i).pc := alignToFetchBoundary(io.enq.bits.pc) - 2.U
in_uops(i).debug_pc := alignToFetchBoundary(io.enq.bits.pc) - 2.U
in_uops(i).pc_lob := alignToFetchBoundary(io.enq.bits.pc)
in_uops(i).edge_inst:= true.B
}
Expand Down Expand Up @@ -240,7 +240,7 @@ class OldFetchBuffer(numEntries: Int)(implicit p: Parameters) extends BoomModule
printf(" Fetch4: Deq:(V:%c DeqCnt:%d PC:0x%x)\n",
BoolToChar(io.deq.valid, 'V'),
deq_count,
io.deq.bits.uops(0).bits.pc)
io.deq.bits.uops(0).bits.debug_pc)
}

//-------------------------------------------------------------
Expand Down

0 comments on commit f02e389

Please sign in to comment.