From 0b15b19381f026a05ae791c9d6a0c006e147407c Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Tue, 1 Dec 2015 10:22:31 -0800 Subject: [PATCH] add arbiter for FPU --- rocket/src/main/scala/arbiter.scala | 49 +++++++++++++++++++++++++++++ rocket/src/main/scala/rocket.scala | 7 ----- rocket/src/main/scala/tile.scala | 14 +++++++-- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/rocket/src/main/scala/arbiter.scala b/rocket/src/main/scala/arbiter.scala index 27bfcc86..16c04858 100644 --- a/rocket/src/main/scala/arbiter.scala +++ b/rocket/src/main/scala/arbiter.scala @@ -5,6 +5,7 @@ package rocket import Chisel._ import uncore._ import cde.{Parameters, Field} +import junctions.ParameterizedBundle class HellaCacheArbiter(n: Int)(implicit p: Parameters) extends Module { @@ -53,3 +54,51 @@ class HellaCacheArbiter(n: Int)(implicit p: Parameters) extends Module io.requestor(i).replay_next.bits := io.mem.replay_next.bits >> log2Up(n) } } + +class InOrderArbiter[T <: Data, U <: Data](reqTyp: T, respTyp: U, n: Int) + (implicit p: Parameters) extends Module { + val io = new Bundle { + val in_req = Vec(n, Decoupled(reqTyp)).flip + val in_resp = Vec(n, Decoupled(respTyp)) + val out_req = Decoupled(reqTyp) + val out_resp = Decoupled(respTyp).flip + } + + if (n > 1) { + val route_q = Module(new Queue(UInt(width = log2Up(n)), 2)) + val req_arb = Module(new RRArbiter(reqTyp, n)) + req_arb.io.in <> io.in_req + + val req_helper = DecoupledHelper( + req_arb.io.out.valid, + route_q.io.enq.ready, + io.out_req.ready) + + io.out_req.bits := req_arb.io.out.bits + io.out_req.valid := req_helper.fire(io.out_req.ready) + + route_q.io.enq.bits := req_arb.io.chosen + route_q.io.enq.valid := req_helper.fire(route_q.io.enq.ready) + + req_arb.io.out.ready := req_helper.fire(req_arb.io.out.valid) + + val resp_sel = route_q.io.deq.bits + val resp_ready = io.in_resp(resp_sel).ready + val resp_helper = DecoupledHelper( + resp_ready, + route_q.io.deq.valid, + io.out_resp.valid) + + val resp_valid = resp_helper.fire(resp_ready) + for (i <- 0 until n) { + io.in_resp(i).bits := io.out_resp.bits + io.in_resp(i).valid := resp_valid && resp_sel === UInt(i) + } + + route_q.io.deq.ready := resp_helper.fire(route_q.io.deq.valid) + io.out_resp.ready := resp_helper.fire(io.out_resp.valid) + } else { + io.out_req <> io.in_req.head + io.in_resp.head <> io.out_resp + } +} diff --git a/rocket/src/main/scala/rocket.scala b/rocket/src/main/scala/rocket.scala index 251ac330..53824d51 100644 --- a/rocket/src/main/scala/rocket.scala +++ b/rocket/src/main/scala/rocket.scala @@ -537,13 +537,6 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { io.rocc.cmd.bits.rs1 := wb_reg_wdata io.rocc.cmd.bits.rs2 := wb_reg_rs2 - if (usingFPU && usingRoCC) { - io.fpu.cp_req <> io.rocc.fpu_req - io.fpu.cp_resp <> io.rocc.fpu_resp - } else { - io.fpu.cp_req.valid := Bool(false) - } - if (enableCommitLog) { val pc = Wire(SInt(width=64)) pc := wb_reg_pc diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index 7c838475..0420c6a5 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -52,8 +52,8 @@ class RocketTile(resetSignal: Bool = null)(implicit p: Parameters) extends Tile( icache.io.cpu <> core.io.imem core.io.ptw <> ptw.io.dpath - //If so specified, build an FPU module and wire it in - if (p(UseFPU)) core.io.fpu <> Module(new FPU()(p)).io + val fpuOpt = if (p(UseFPU)) Some(Module(new FPU)) else None + fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) // Connect the caches and ROCC to the outer memory system io.cached.head <> dcache.io.mem @@ -86,6 +86,16 @@ class RocketTile(resetSignal: Bool = null)(implicit p: Parameters) extends Tile( rocc } + fpuOpt.foreach { fpu => + val fpArb = Module(new InOrderArbiter(new FPInput, new FPResult, nRocc)) + fpArb.io.in_req <> roccs.map(_.io.fpu_req) + roccs.zip(fpArb.io.in_resp).foreach { + case (rocc, fpu_resp) => rocc.io.fpu_resp <> fpu_resp + } + fpu.io.cp_req <> fpArb.io.out_req + fpArb.io.out_resp <> fpu.io.cp_resp + } + core.io.rocc.busy := cmdRouter.io.busy || roccs.map(_.io.busy).reduce(_ || _) core.io.rocc.interrupt := roccs.map(_.io.interrupt).reduce(_ || _) respArb.io.in <> roccs.map(rocc => Queue(rocc.io.resp))