diff --git a/rocket/src/main/scala/btb.scala b/rocket/src/main/scala/btb.scala index 7cf4094f..7cf24b5d 100644 --- a/rocket/src/main/scala/btb.scala +++ b/rocket/src/main/scala/btb.scala @@ -5,13 +5,13 @@ import Util._ import Node._ import uncore._ -case object BTBEntries extends Field[Int] +case object NBTBEntries extends Field[Int] case object NRAS extends Field[Int] abstract trait BTBParameters extends UsesParameters { val vaddrBits = params(VAddrBits) val matchBits = params(PgIdxBits) - val entries = params(BTBEntries) + val entries = params(NBTBEntries) val nRAS = params(NRAS) val nPages = ((1 max(log2Up(entries)))+1)/2*2 // control logic assumes 2 divides pages val opaqueBits = log2Up(entries) diff --git a/rocket/src/main/scala/core.scala b/rocket/src/main/scala/core.scala index 0b22b42a..a6dee39f 100644 --- a/rocket/src/main/scala/core.scala +++ b/rocket/src/main/scala/core.scala @@ -2,10 +2,34 @@ package rocket import Chisel._ import Util._ -import uncore.HTIFIO +import uncore._ -case object FPUParams extends Field[PF] case object BuildFPU extends Field[Option[() => FPU]] +case object XprLen extends Field[Int] +case object NMultXpr extends Field[Int] +case object RetireWidth extends Field[Int] +case object UseVM extends Field[Boolean] +case object FastLoadWord extends Field[Boolean] +case object FastLoadByte extends Field[Boolean] +case object FastMulDiv extends Field[Boolean] +case object CoreInstBits extends Field[Int] +case object CoreDataBits extends Field[Int] +case object CoreDCacheReqTagBits extends Field[Int] + +abstract trait CoreParameters extends UsesParameters { + val xprLen = params(XprLen) + val coreInstBits = params(CoreInstBits) + val coreInstBytes = coreInstBits/8 + val coreDataBits = xprLen + val coreDataBytes = coreDataBits/8 + val coreDCacheReqTagBits = params(CoreDCacheReqTagBits) + val coreMaxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits) + + if(params(FastLoadByte)) require(params(FastLoadWord)) + require(params(RetireWidth) == 1) // for now... +} +abstract class CoreBundle extends Bundle with CoreParameters +abstract class CoreModule extends Module with CoreParameters class RocketIO extends Bundle { @@ -16,19 +40,20 @@ class RocketIO extends Bundle val rocc = new RoCCInterface().flip } -class Core extends Module +class Core extends Module with CoreParameters { val io = new RocketIO val ctrl = Module(new Control) val dpath = Module(new Datapath) - if (!params(BuildFPU).isEmpty) { - val p = Some(params.alter(params(FPUParams))) - val fpu = Module(params(BuildFPU).get())(p) - dpath.io.fpu <> fpu.io.dpath - ctrl.io.fpu <> fpu.io.ctrl - } + //If so specified, build an FPU module and wire it in + params(BuildFPU) + .map { bf => Module(bf()) } + .foreach { fpu => + dpath.io.fpu <> fpu.io.dpath + ctrl.io.fpu <> fpu.io.ctrl + } ctrl.io.dpath <> dpath.io.ctrl dpath.io.host <> io.host diff --git a/rocket/src/main/scala/dpath.scala b/rocket/src/main/scala/dpath.scala index e932b1dd..84a0a400 100644 --- a/rocket/src/main/scala/dpath.scala +++ b/rocket/src/main/scala/dpath.scala @@ -171,7 +171,7 @@ class Datapath extends Module io.dmem.req.bits.addr := Cat(vaSign(ex_rs(0), alu.io.adder_out), alu.io.adder_out(params(VAddrBits)-1,0)).toUInt io.dmem.req.bits.tag := Cat(io.ctrl.ex_waddr, io.ctrl.ex_fp_val) require(io.dmem.req.bits.tag.getWidth >= 6) - require(params(DcacheReqTagBits) >= 6) + require(params(CoreDCacheReqTagBits) >= 6) // processor control regfile read val pcr = Module(new CSRFile) diff --git a/rocket/src/main/scala/icache.scala b/rocket/src/main/scala/icache.scala index aac6a21b..1f85a22b 100644 --- a/rocket/src/main/scala/icache.scala +++ b/rocket/src/main/scala/icache.scala @@ -4,29 +4,30 @@ import Chisel._ import uncore._ import Util._ -case object InstBytes extends Field[Int] +case object NITLBEntries extends Field[Int] +case object ECCCode extends Field[Option[Code]] -abstract trait FrontendParameters extends CacheParameters { - val instBytes = params(InstBytes) +abstract trait L1CacheParameters extends CacheParameters with CoreParameters { val co = params(TLCoherence) - val code = params(ECCCode) -} + val code = params(ECCCode).getOrElse(new IdentityCode) +} +abstract trait FrontendParameters extends L1CacheParameters abstract class FrontendBundle extends Bundle with FrontendParameters abstract class FrontendModule extends Module with FrontendParameters -class FrontendReq extends FrontendBundle { - val pc = UInt(width = vaddrBits+1) +class FrontendReq extends CoreBundle { + val pc = UInt(width = params(VAddrBits)+1) } -class FrontendResp extends FrontendBundle { - val pc = UInt(width = vaddrBits+1) // ID stage PC - val data = Bits(width = instBytes*8) +class FrontendResp extends CoreBundle { + val pc = UInt(width = params(VAddrBits)+1) // ID stage PC + val data = Bits(width = coreInstBits) val xcpt_ma = Bool() val xcpt_if = Bool() } -class CPUFrontendIO extends FrontendBundle { +class CPUFrontendIO extends CoreBundle { val req = Valid(new FrontendReq) val resp = Decoupled(new FrontendResp).flip val btb_resp = Valid(new BTBResp).flip @@ -44,7 +45,7 @@ class Frontend extends FrontendModule val btb = Module(new BTB) val icache = Module(new ICache) - val tlb = Module(new TLB(params(NTLBEntries))) + val tlb = Module(new TLB(params(NITLBEntries))) val s1_pc_ = Reg(UInt()) val s1_pc = s1_pc_ & SInt(-2) // discard LSB of PC (throughout the pipeline) @@ -57,7 +58,7 @@ class Frontend extends FrontendModule val msb = vaddrBits-1 val btbTarget = Cat(btb.io.resp.bits.target(msb), btb.io.resp.bits.target) - val pcp4_0 = s1_pc + UInt(instBytes) + val pcp4_0 = s1_pc + UInt(coreInstBytes) val pcp4 = Cat(s1_pc(msb) & pcp4_0(msb), pcp4_0(msb,0)) val icmiss = s2_valid && !icache.io.resp.valid val predicted_npc = Mux(btb.io.resp.bits.taken, btbTarget, pcp4) @@ -82,7 +83,7 @@ class Frontend extends FrontendModule s2_valid := Bool(false) } - btb.io.req := s1_pc & SInt(-instBytes) + btb.io.req := s1_pc & SInt(-coreInstBytes) btb.io.update := io.cpu.btb_update btb.io.invalidate := io.cpu.invalidate || io.cpu.ptw.invalidate @@ -102,9 +103,9 @@ class Frontend extends FrontendModule icache.io.resp.ready := !stall && !s1_same_block io.cpu.resp.valid := s2_valid && (s2_xcpt_if || icache.io.resp.valid) - io.cpu.resp.bits.pc := s2_pc & SInt(-instBytes) // discard PC LSBs - io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(rowBytes)-1,log2Up(instBytes)) << log2Up(instBytes*8)) - io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(instBytes)-1,0) != UInt(0) + io.cpu.resp.bits.pc := s2_pc & SInt(-coreInstBytes) // discard PC LSBs + io.cpu.resp.bits.data := icache.io.resp.bits.datablock >> (s2_pc(log2Up(rowBytes)-1,log2Up(coreInstBytes)) << log2Up(coreInstBits)) + io.cpu.resp.bits.xcpt_ma := s2_pc(log2Up(coreInstBytes)-1,0) != UInt(0) io.cpu.resp.bits.xcpt_if := s2_xcpt_if io.cpu.btb_resp.valid := s2_btb_resp_valid @@ -118,7 +119,7 @@ class ICacheReq extends FrontendBundle { } class ICacheResp extends FrontendBundle { - val data = Bits(width = instBytes*8) + val data = Bits(width = coreInstBits) val datablock = Bits(width = rowBits) } @@ -131,7 +132,7 @@ class ICache extends FrontendModule val mem = new UncachedTileLinkIO } require(isPow2(nSets) && isPow2(nWays)) - require(isPow2(instBytes)) + require(isPow2(coreInstBytes)) require(pgIdxBits >= untagBits) val s_ready :: s_request :: s_refill_wait :: s_refill :: Nil = Enum(UInt(), 4) @@ -249,7 +250,7 @@ class ICache extends FrontendModule // if s1_tag_match is critical, replace with partial tag check when (s1_valid && rdy && !stall && (Bool(isDM) || s1_tag_match(i))) { s2_dout(i) := data_array(s1_raddr) } } - val s2_dout_word = s2_dout.map(x => (x >> (s2_offset(log2Up(rowBytes)-1,log2Up(instBytes)) << log2Up(instBytes*8)))(instBytes*8-1,0)) + val s2_dout_word = s2_dout.map(x => (x >> (s2_offset(log2Up(rowBytes)-1,log2Up(coreInstBytes)) << log2Up(coreInstBits)))(coreInstBits-1,0)) io.resp.bits.data := Mux1H(s2_tag_hit, s2_dout_word) io.resp.bits.datablock := Mux1H(s2_tag_hit, s2_dout) diff --git a/rocket/src/main/scala/multiplier.scala b/rocket/src/main/scala/multiplier.scala index 02cf199c..6a595c4b 100644 --- a/rocket/src/main/scala/multiplier.scala +++ b/rocket/src/main/scala/multiplier.scala @@ -9,12 +9,12 @@ class MultiplierReq extends Bundle { val dw = Bits(width = SZ_DW) val in1 = Bits(width = params(XprLen)) val in2 = Bits(width = params(XprLen)) - val tag = UInt(width = params(NXprBits)) + val tag = UInt(width = log2Up(params(NMultXpr))) } class MultiplierResp extends Bundle { val data = Bits(width = params(XprLen)) - val tag = UInt(width = params(NXprBits)) + val tag = UInt(width = log2Up(params(NMultXpr))) } class MultiplierIO extends Bundle { diff --git a/rocket/src/main/scala/nbdcache.scala b/rocket/src/main/scala/nbdcache.scala index b1a44d0c..cdf360c4 100644 --- a/rocket/src/main/scala/nbdcache.scala +++ b/rocket/src/main/scala/nbdcache.scala @@ -7,25 +7,14 @@ import Util._ case object StoreDataQueueDepth extends Field[Int] case object ReplayQueueDepth extends Field[Int] case object NMSHRs extends Field[Int] -case object CoreReqTagBits extends Field[Int] -case object CoreDataBits extends Field[Int] case object LRSCCycles extends Field[Int] -//TODO PARAMS Also used by icache: is this ok?: -case object NTLBEntries extends Field[Int] -case object ECCCode extends Field[Code] +case object NDTLBEntries extends Field[Int] -abstract trait L1HellaCacheParameters extends CacheParameters { +abstract trait L1HellaCacheParameters extends L1CacheParameters { val indexmsb = untagBits-1 val indexlsb = blockOffBits val offsetmsb = indexlsb-1 val offsetlsb = wordOffBits - - val co = params(TLCoherence) - val code = params(ECCCode) - val coreReqTagBits = params(CoreReqTagBits) - val coreDataBits = params(CoreDataBits) - val maxAddrBits = math.max(params(PPNBits),params(VPNBits)+1) + params(PgIdxBits) - val coreDataBytes = coreDataBits/8 val doNarrowRead = coreDataBits * nWays % rowBits == 0 val encDataBits = code.width(coreDataBits) val encRowBits = encDataBits*rowWords @@ -66,26 +55,26 @@ class LoadGen(typ: Bits, addr: Bits, dat: Bits, zero: Bool) val byte = Cat(Mux(zero || t.byte, Fill(56, sign && byteShift(7)), half(63,8)), byteShift) } -class HellaCacheReq extends L1HellaCacheBundle { +class HellaCacheReq extends CoreBundle { val kill = Bool() val typ = Bits(width = MT_SZ) val phys = Bool() - val addr = UInt(width = maxAddrBits) + val addr = UInt(width = coreMaxAddrBits) val data = Bits(width = coreDataBits) - val tag = Bits(width = coreReqTagBits) + val tag = Bits(width = coreDCacheReqTagBits) val cmd = Bits(width = M_SZ) } -class HellaCacheResp extends L1HellaCacheBundle { +class HellaCacheResp extends CoreBundle { val nack = Bool() // comes 2 cycles after req.fire val replay = Bool() val typ = Bits(width = 3) val has_data = Bool() val data = Bits(width = coreDataBits) val data_subword = Bits(width = coreDataBits) - val tag = Bits(width = coreReqTagBits) + val tag = Bits(width = coreDCacheReqTagBits) val cmd = Bits(width = 4) - val addr = UInt(width = maxAddrBits) + val addr = UInt(width = coreMaxAddrBits) val store_data = Bits(width = coreDataBits) } @@ -100,22 +89,22 @@ class HellaCacheExceptions extends Bundle { } // interface between D$ and processor/DTLB -class HellaCacheIO extends L1HellaCacheBundle { +class HellaCacheIO extends CoreBundle { val req = Decoupled(new HellaCacheReq) val resp = Valid(new HellaCacheResp).flip - val replay_next = Valid(Bits(width = coreReqTagBits)).flip + val replay_next = Valid(Bits(width = coreDCacheReqTagBits)).flip val xcpt = (new HellaCacheExceptions).asInput val ptw = new TLBPTWIO().flip val ordered = Bool(INPUT) } -class MSHRReq extends HellaCacheReq { +class MSHRReq extends HellaCacheReq with L1HellaCacheParameters { val tag_match = Bool() val old_meta = new L1Metadata val way_en = Bits(width = nWays) } -class Replay extends HellaCacheReq { +class Replay extends HellaCacheReq with L1HellaCacheParameters { val sdq_id = UInt(width = log2Up(params(StoreDataQueueDepth))) } @@ -704,7 +693,7 @@ class HellaCache extends L1HellaCacheModule { val s1_sc = s1_req.cmd === M_XSC val s1_readwrite = s1_read || s1_write || isPrefetch(s1_req.cmd) - val dtlb = Module(new TLB(params(NTLBEntries))) + val dtlb = Module(new TLB(params(NDTLBEntries))) dtlb.io.ptw <> io.cpu.ptw dtlb.io.req.valid := s1_valid_masked && s1_readwrite && !s1_req.phys dtlb.io.req.bits.passthrough := s1_req.phys diff --git a/rocket/src/main/scala/tile.scala b/rocket/src/main/scala/tile.scala index d0f49fbe..0b54af00 100644 --- a/rocket/src/main/scala/tile.scala +++ b/rocket/src/main/scala/tile.scala @@ -4,44 +4,24 @@ import Chisel._ import uncore._ import Util._ +case object WhichL1Cache extends Field[String] case object NDCachePorts extends Field[Int] case object NTilePorts extends Field[Int] +case object NPTWPorts extends Field[Int] case object BuildRoCC extends Field[Option[() => RoCC]] -case object RetireWidth extends Field[Int] -case object UseVM extends Field[Boolean] -case object FastLoadWord extends Field[Boolean] -case object FastLoadByte extends Field[Boolean] -case object FastMulDiv extends Field[Boolean] -case object DcacheReqTagBits extends Field[Int] -case object XprLen extends Field[Int] -case object NXpr extends Field[Int] -case object NXprBits extends Field[Int] -case object RocketDCacheParams extends Field[PF] -case object RocketFrontendParams extends Field[PF] class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { - - if(params(FastLoadByte)) require(params(FastLoadWord)) - require(params(RetireWidth) == 1) // for now... - val io = new Bundle { val tilelink = new TileLinkIO val host = new HTIFIO } - // Mimic client id extension done by UncachedTileLinkIOArbiter for Acquires from either client) - val optionalRoCC = params(BuildRoCC) + val icache = Module(new Frontend, { case CacheName => "L1I" }) + val dcache = Module(new HellaCache, { case CacheName => "L1D" }) + val ptw = Module(new PTW(params(NPTWPorts))) + val core = Module(new Core) - val p = params.alter(params(RocketFrontendParams)) // Used in icache, Core - val icache = Module(new Frontend)(p) //TODO PARAMS: best way to alter both? - val p2 = params.alter(params(RocketDCacheParams)) // Used in dcache, PTW, RoCCm Core - val dcache = Module(new HellaCache)(p2) - val ptw = Module(new PTW(if(optionalRoCC.isEmpty) 2 else 5))(p2) - // 2 ports, 1 from I$, 1 from D$, maybe 3 from RoCC - val p3 = params.alter(params(RocketFrontendParams)).alter(params(RocketDCacheParams)) - val core = Module(new Core)(p3) - - val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts)))(p2) + val dcArb = Module(new HellaCacheArbiter(params(NDCachePorts))) dcArb.io.requestor(0) <> ptw.io.mem dcArb.io.requestor(1) <> core.io.dmem dcArb.io.mem <> dcache.io.cpu @@ -58,17 +38,19 @@ class Tile(resetSignal: Bool = null) extends Module(_reset = resetSignal) { memArb.io.in(dcPortId) <> dcache.io.mem memArb.io.in(1) <> icache.io.mem - if(!optionalRoCC.isEmpty) { - val rocc = Module(optionalRoCC.get()) - val dcIF = Module(new SimpleHellaCacheIF) - dcIF.io.requestor <> rocc.io.mem - core.io.rocc <> rocc.io - dcArb.io.requestor(2) <> dcIF.io.cache - memArb.io.in(2) <> rocc.io.imem - ptw.io.requestor(2) <> rocc.io.iptw - ptw.io.requestor(3) <> rocc.io.dptw - ptw.io.requestor(4) <> rocc.io.pptw - } + //If so specified, build an RoCC module and wire it in + params(BuildRoCC) + .map { br => Module(br()) } + .foreach { rocc => + val dcIF = Module(new SimpleHellaCacheIF) + dcIF.io.requestor <> rocc.io.mem + core.io.rocc <> rocc.io + dcArb.io.requestor(2) <> dcIF.io.cache + memArb.io.in(2) <> rocc.io.imem + ptw.io.requestor(2) <> rocc.io.iptw + ptw.io.requestor(3) <> rocc.io.dptw + ptw.io.requestor(4) <> rocc.io.pptw + } io.tilelink.acquire <> memArb.io.out.acquire io.tilelink.grant <> memArb.io.out.grant