diff --git a/rocket b/rocket index 23a104b0..6a2c51c4 160000 --- a/rocket +++ b/rocket @@ -1 +1 @@ -Subproject commit 23a104b04472df241ca3074d0adf45c93d3da223 +Subproject commit 6a2c51c405a8687f40e229846a27c6cdb788f221 diff --git a/src/main/scala/Backends.scala b/src/main/scala/Backends.scala new file mode 100644 index 00000000..e1157837 --- /dev/null +++ b/src/main/scala/Backends.scala @@ -0,0 +1,69 @@ +package referencechip + +import Chisel._ +import ReferenceChipBackend._ +import scala.collection.mutable.HashMap + +object ReferenceChipBackend { + val initMap = new HashMap[Module, Bool]() +} + +class ReferenceChipBackend extends VerilogBackend +{ + initMap.clear() + override def emitPortDef(m: MemAccess, idx: Int) = { + val res = new StringBuilder() + for (node <- m.mem.inputs) { + if(node.name.contains("init")) + res.append(" .init(" + node.name + "),\n") + } + (if (idx == 0) res.toString else "") + super.emitPortDef(m, idx) + } + + def addMemPin(c: Module) = { + for (mod <- Module.components; node <- mod.nodes) { + if (node.isInstanceOf[Mem[ _ ]] && node.component != null && node.asInstanceOf[Mem[_]].seqRead) { + connectMemPin(c, node.component, node) + } + } + } + + def connectMemPin(topC: Module, c: Module, p: Node): Unit = { + var isNewPin = false + val compInitPin = + if (initMap.contains(c)) { + initMap(c) + } else { + isNewPin = true + val res = Bool(INPUT) + res.isIo = true + res + } + + p.inputs += compInitPin + + if (isNewPin) { + compInitPin.setName("init") + c.io.asInstanceOf[Bundle] += compInitPin + compInitPin.component = c + initMap += (c -> compInitPin) + connectMemPin(topC, c.parent, compInitPin) + } + } + + def addTopLevelPin(c: Module) = { + val init = Bool(INPUT) + init.isIo = true + init.setName("init") + init.component = c + c.io.asInstanceOf[Bundle] += init + initMap += (c -> init) + } + + transforms += ((c: Module) => addTopLevelPin(c)) + transforms += ((c: Module) => addMemPin(c)) + transforms += ((c: Module) => collectNodesIntoComp(initializeDFS)) +} + +class Fame1ReferenceChipBackend extends ReferenceChipBackend with Fame1Transform + diff --git a/src/main/scala/RocketChip.scala b/src/main/scala/RocketChip.scala index cf07125f..2f9fb09f 100644 --- a/src/main/scala/RocketChip.scala +++ b/src/main/scala/RocketChip.scala @@ -4,9 +4,6 @@ import Chisel._ import uncore._ import rocket._ import rocket.Util._ -import ReferenceChipBackend._ -import scala.collection.mutable.HashMap -import DRAMModel._ object DesignSpaceConstants { val NTILES = 1 @@ -44,69 +41,6 @@ import DesignSpaceConstants._ import MemoryConstants._ import TileLinkSizeConstants._ -object ReferenceChipBackend { - val initMap = new HashMap[Module, Bool]() -} - -class ReferenceChipBackend extends VerilogBackend -{ - initMap.clear() - override def emitPortDef(m: MemAccess, idx: Int) = { - val res = new StringBuilder() - for (node <- m.mem.inputs) { - if(node.name.contains("init")) - res.append(" .init(" + node.name + "),\n") - } - (if (idx == 0) res.toString else "") + super.emitPortDef(m, idx) - } - - def addMemPin(c: Module) = { - for (mod <- Module.components; node <- mod.nodes) { - if (node.isInstanceOf[Mem[ _ ]] && node.component != null && node.asInstanceOf[Mem[_]].seqRead) { - connectMemPin(c, node.component, node) - } - } - } - - def connectMemPin(topC: Module, c: Module, p: Node): Unit = { - var isNewPin = false - val compInitPin = - if (initMap.contains(c)) { - initMap(c) - } else { - isNewPin = true - val res = Bool(INPUT) - res.isIo = true - res - } - - p.inputs += compInitPin - - if (isNewPin) { - compInitPin.setName("init") - c.io.asInstanceOf[Bundle] += compInitPin - compInitPin.component = c - initMap += (c -> compInitPin) - connectMemPin(topC, c.parent, compInitPin) - } - } - - def addTopLevelPin(c: Module) = { - val init = Bool(INPUT) - init.isIo = true - init.setName("init") - init.component = c - c.io.asInstanceOf[Bundle] += init - initMap += (c -> init) - } - - transforms += ((c: Module) => addTopLevelPin(c)) - transforms += ((c: Module) => addMemPin(c)) - transforms += ((c: Module) => collectNodesIntoComp(initializeDFS)) -} - -class Fame1ReferenceChipBackend extends ReferenceChipBackend with Fame1Transform - class OuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) extends Module { implicit val (tl, ln, l2, mif) = (conf.tl, conf.tl.ln, conf.l2, conf.mif) @@ -120,13 +54,19 @@ class OuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) ext } val refill_cycles = tl.dataBits/mif.dataBits - val llc_tag_leaf = Mem(Bits(width = 152), 512, seqRead = true) - val llc_data_leaf = Mem(Bits(width = 64), 4096, seqRead = true) - val llc = Module(new DRAMSideLLC(sets=512, ways=8, outstanding=16, refill_cycles=refill_cycles, tagLeaf=llc_tag_leaf, dataLeaf=llc_data_leaf)) - //val llc = Module(new DRAMSideLLCNull(NL2_REL_XACTS+NL2_ACQ_XACTS, refill_cycles)) - val mem_serdes = Module(new MemSerdes(htif_width)) + val (llc, masterEndpoints) = if(conf.useDRAMSideLLC) { + val llc_tag_leaf = Mem(Bits(width = 152), 512, seqRead = true) + val llc_data_leaf = Mem(Bits(width = 64), 4096, seqRead = true) + val llc = Module(new DRAMSideLLC(sets=512, ways=8, outstanding=16, + refill_cycles=refill_cycles, tagLeaf=llc_tag_leaf, dataLeaf=llc_data_leaf)) + val mes = (0 until ln.nMasters).map(i => Module(new L2CoherenceAgent(i))) + (llc, mes) + } else { + val llc = Module(new DRAMSideLLCNull(16, refill_cycles)) + val mes = (0 until ln.nMasters).map(i => Module(new L2HellaCache(i))) + (llc, mes) + } - val masterEndpoints = (0 until ln.nMasters).map(i => Module(new L2CoherenceAgent(i))) val net = Module(new ReferenceChipCrossbarNetwork) net.io.clients zip (io.tiles :+ io.htif) map { case (net, end) => net <> end } net.io.masters zip (masterEndpoints.map(_.io.client)) map { case (net, end) => net <> end } @@ -145,6 +85,7 @@ class OuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) ext conv.io.mem.resp <> llc.io.cpu.resp // mux between main and backup memory ports + val mem_serdes = Module(new MemSerdes(htif_width)) val mem_cmdq = Module(new Queue(new MemReqCmd, 2)) mem_cmdq.io.enq <> llc.io.mem.req_cmd mem_cmdq.io.deq.ready := Mux(io.mem_backup_en, mem_serdes.io.wide.req_cmd.ready, io.mem.req_cmd.ready) @@ -168,7 +109,7 @@ class OuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) ext io.mem_backup <> mem_serdes.io.narrow } -case class UncoreConfiguration(l2: L2CoherenceAgentConfiguration, tl: TileLinkConfiguration, mif: MemoryIFConfiguration, nTiles: Int, nBanks: Int, bankIdLsb: Int, nSCR: Int, offsetBits: Int) +case class UncoreConfiguration(l2: L2CacheConfig, tl: TileLinkConfiguration, mif: MemoryIFConfiguration, nTiles: Int, nBanks: Int, bankIdLsb: Int, nSCR: Int, offsetBits: Int, useDRAMSideLLC: Boolean) class Uncore(htif_width: Int)(implicit conf: UncoreConfiguration) extends Module { @@ -200,7 +141,7 @@ class Uncore(htif_width: Int)(implicit conf: UncoreConfiguration) extends Module case ((outer, client), i) => outer.acquire <> Queue(TileLinkHeaderOverwriter(client.acquire, i, conf.nBanks, convertAddrToBank _)) outer.release <> Queue(TileLinkHeaderOverwriter(client.release, i, conf.nBanks, convertAddrToBank _)) - outer.finish <> Queue(TileLinkHeaderOverwriter(client.finish, i)) + outer.finish <> Queue(TileLinkHeaderOverwriter(client.finish, i, true)) client.grant <> Queue(outer.grant, 1, pipe = true) client.probe <> Queue(outer.probe) } @@ -277,9 +218,9 @@ class Top extends Module { writeMaskBits = WRITE_MASK_BITS, wordAddrBits = SUBWORD_ADDR_BITS, atomicOpBits = ATOMIC_OP_BITS) - implicit val l2 = L2CoherenceAgentConfiguration(tl, NL2_REL_XACTS, NL2_ACQ_XACTS) + implicit val l2 = L2CacheConfig(512, 8, 1, 1, NL2_REL_XACTS, NL2_ACQ_XACTS, tl, as) implicit val mif = MemoryIFConfiguration(MEM_ADDR_BITS, MEM_DATA_BITS, MEM_TAG_BITS, MEM_DATA_BEATS) - implicit val uc = UncoreConfiguration(l2, tl, mif, NTILES, NBANKS, bankIdLsb = 5, nSCR = 64, offsetBits = OFFSET_BITS) + implicit val uc = UncoreConfiguration(l2, tl, mif, NTILES, NBANKS, bankIdLsb = 5, nSCR = 64, offsetBits = OFFSET_BITS, useDRAMSideLLC = true) val ic = ICacheConfig(sets = 128, assoc = 2, ntlb = 8, tl = tl, as = as, btb = BTBConfig(as, 64, 2)) val dc = DCacheConfig(sets = 128, ways = 4, @@ -306,11 +247,12 @@ class Top extends Module { resetSigs(i) := hl.reset val tile = tileList(i) + tile.io.tilelink <> tl il := hl.reset + tile.io.host.id := UInt(i) tile.io.host.reset := Reg(next=Reg(next=hl.reset)) tile.io.host.pcr_req <> Queue(hl.pcr_req, 1) - tile.io.host.id := i hl.pcr_rep <> Queue(tile.io.host.pcr_rep, 1) hl.ipi_req <> Queue(tile.io.host.ipi_req, 1) tile.io.host.ipi_rep <> Queue(hl.ipi_rep, 1) @@ -327,5 +269,3 @@ class Top extends Module { io.mem_backup_en <> uncore.io.mem_backup_en io.mem <> uncore.io.mem } - - diff --git a/src/main/scala/fpga.scala b/src/main/scala/fpga.scala index 54fc35a2..fcb17943 100644 --- a/src/main/scala/fpga.scala +++ b/src/main/scala/fpga.scala @@ -1,14 +1,13 @@ package referencechip import Chisel._ -import Node._ import uncore._ import rocket._ import DRAMModel._ import DRAMModel.MemModelConstants._ -class FPGAOuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) extends Module -{ +class FPGAOuterMemorySystem(htif_width: Int)(implicit conf: FPGAUncoreConfiguration) + extends Module { implicit val (tl, ln, l2, mif) = (conf.tl, conf.tl.ln, conf.l2, conf.mif) val io = new Bundle { val tiles = Vec.fill(conf.nTiles){new TileLinkIO}.flip @@ -17,28 +16,23 @@ class FPGAOuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) val mem = new MemIO } - val masterEndpoints = (0 until ln.nMasters).map(i => Module(new L2CoherenceAgent(i))) - + val master = Module(new L2CoherenceAgent(0)) val net = Module(new ReferenceChipCrossbarNetwork) net.io.clients zip (io.tiles :+ io.htif) map { case (net, end) => net <> end } - net.io.masters zip (masterEndpoints.map(_.io.client)) map { case (net, end) => net <> end } - masterEndpoints.map{ _.io.incoherent zip io.incoherent map { case (m, c) => m := c } } + net.io.masters.head <> master.io.client + master.io.incoherent zip io.incoherent map { case (m, c) => m := c } val conv = Module(new MemIOUncachedTileLinkIOConverter(2)) - if(ln.nMasters > 1) { - val arb = Module(new UncachedTileLinkIOArbiterThatAppendsArbiterId(ln.nMasters)) - arb.io.in zip masterEndpoints.map(_.io.master) map { case (arb, cache) => arb <> cache } - conv.io.uncached <> arb.io.out - } else { - conv.io.uncached <> masterEndpoints.head.io.master - } - io.mem.req_cmd <> Queue(conv.io.mem.req_cmd) + conv.io.uncached <> master.io.master + io.mem.req_cmd <> Queue(conv.io.mem.req_cmd, 2) io.mem.req_data <> Queue(conv.io.mem.req_data, tl.dataBits/mif.dataBits) conv.io.mem.resp <> Queue(io.mem.resp) } -class FPGAUncore(htif_width: Int)(implicit conf: UncoreConfiguration) extends Module -{ +case class FPGAUncoreConfiguration(l2: L2CoherenceAgentConfiguration, tl: TileLinkConfiguration, mif: MemoryIFConfiguration, nTiles: Int, nSCR: Int, offsetBits: Int) + +class FPGAUncore(htif_width: Int)(implicit conf: FPGAUncoreConfiguration) + extends Module { implicit val (tl, ln, mif) = (conf.tl, conf.tl.ln, conf.mif) val io = new Bundle { val host = new HostIO(htif_width) @@ -55,16 +49,11 @@ class FPGAUncore(htif_width: Int)(implicit conf: UncoreConfiguration) extends Mo outmemsys.io.mem <> io.mem // Add networking headers and endpoint queues - def convertAddrToBank(addr: Bits): UInt = { - require(conf.bankIdLsb + log2Up(conf.nBanks) < conf.mif.addrBits, {println("Invalid bits for bank multiplexing.")}) - addr(conf.bankIdLsb + log2Up(conf.nBanks) - 1, conf.bankIdLsb) - } - (outmemsys.io.tiles :+ outmemsys.io.htif).zip(io.tiles :+ htif.io.mem).zipWithIndex.map { case ((outer, client), i) => - outer.acquire <> Queue(TileLinkHeaderOverwriter(client.acquire, i, conf.nBanks, convertAddrToBank _)) - outer.release <> Queue(TileLinkHeaderOverwriter(client.release, i, conf.nBanks, convertAddrToBank _)) - outer.finish <> Queue(TileLinkHeaderOverwriter(client.finish, i)) + outer.acquire <> Queue(TileLinkHeaderOverwriter(client.acquire, i, false)) + outer.release <> Queue(TileLinkHeaderOverwriter(client.release, i, false)) + outer.finish <> Queue(TileLinkHeaderOverwriter(client.finish, i, true)) client.grant <> Queue(outer.grant, 1, pipe = true) client.probe <> Queue(outer.probe) } @@ -81,17 +70,12 @@ import MemoryConstants._ class FPGATopIO(htifWidth: Int)(implicit conf: MemoryIFConfiguration) extends TopIO(htifWidth)(conf) class FPGATop extends Module { + val ntiles = 1 + val nmshrs = 2 val htif_width = 16 - implicit val mif = MemoryIFConfiguration(MEM_ADDR_BITS, MEM_DATA_BITS, MEM_TAG_BITS, 4) - - val io = new FPGATopIO(htif_width) - val co = new MESICoherence - val ntiles = 1 - val nbanks = 1 - val nmshrs = 2 - implicit val ln = LogicalNetworkConfiguration(log2Up(ntiles)+1, nbanks, ntiles+1) + implicit val ln = LogicalNetworkConfiguration(log2Up(ntiles)+1, 1, ntiles+1) implicit val as = AddressSpaceConfiguration(PADDR_BITS, VADDR_BITS, PGIDX_BITS, ASID_BITS, PERM_BITS) implicit val tl = TileLinkConfiguration(co = co, ln = ln, addrBits = as.paddrBits-OFFSET_BITS, @@ -102,13 +86,16 @@ class FPGATop extends Module { wordAddrBits = SUBWORD_ADDR_BITS, atomicOpBits = ATOMIC_OP_BITS) implicit val l2 = L2CoherenceAgentConfiguration(tl, 1, 8) - implicit val uc = UncoreConfiguration(l2, tl, mif, ntiles, nbanks, bankIdLsb = 5, nSCR = 64, offsetBits = OFFSET_BITS) + implicit val mif = MemoryIFConfiguration(MEM_ADDR_BITS, MEM_DATA_BITS, MEM_TAG_BITS, 4) + implicit val uc = FPGAUncoreConfiguration(l2, tl, mif, ntiles, nSCR = 64, offsetBits = OFFSET_BITS) - val ic = ICacheConfig(64, 1, ntlb = 4, tl = tl, as = as, btb = BTBConfig(as, 8)) + val ic = ICacheConfig(64, 1, ntlb = 4, tl = tl, as = as, btb = BTBConfig(as, 8, 2)) val dc = DCacheConfig(64, 1, ntlb = 4, nmshr = 2, nrpq = 16, nsdq = 17, tl = tl, as = as, reqtagbits = -1, databits = -1) val rc = RocketConfiguration(tl, as, ic, dc, fpu = None, fastMulDiv = false) + val io = new FPGATopIO(htif_width) + val resetSigs = Vec.fill(uc.nTiles){Bool()} val tileList = (0 until uc.nTiles).map(r => Module(new Tile(resetSignal = resetSigs(r))(rc))) val uncore = Module(new FPGAUncore(htif_width)) diff --git a/src/main/scala/network.scala b/src/main/scala/network.scala index 6670f89a..5deda918 100644 --- a/src/main/scala/network.scala +++ b/src/main/scala/network.scala @@ -6,24 +6,25 @@ import scala.reflect._ import scala.reflect.runtime.universe._ object TileLinkHeaderOverwriter { - def apply[T <: ClientSourcedMessage](in: DecoupledIO[LogicalNetworkIO[T]], clientId: Int)(implicit conf: TileLinkConfiguration): DecoupledIO[LogicalNetworkIO[T]] = { + def apply[T <: ClientSourcedMessage](in: DecoupledIO[LogicalNetworkIO[T]], clientId: Int, passThrough: Boolean)(implicit conf: TileLinkConfiguration): DecoupledIO[LogicalNetworkIO[T]] = { val out = in.clone.asDirectionless out.bits.payload := in.bits.payload out.bits.header.src := UInt(clientId) - out.bits.header.dst := in.bits.header.dst + out.bits.header.dst := (if(passThrough) in.bits.header.dst else UInt(0)) out.valid := in.valid in.ready := out.ready out } def apply[T <: ClientSourcedMessage with HasPhysicalAddress](in: DecoupledIO[LogicalNetworkIO[T]], clientId: Int, nBanks: Int, addrConvert: UInt => UInt)(implicit conf: TileLinkConfiguration): DecoupledIO[LogicalNetworkIO[T]] = { - val out: DecoupledIO[LogicalNetworkIO[T]] = apply(in, clientId) + val out: DecoupledIO[LogicalNetworkIO[T]] = apply(in, clientId, false) out.bits.header.dst := (if(nBanks > 1) addrConvert(in.bits.payload.addr) else UInt(0)) out } } -class ReferenceChipCrossbarNetwork(implicit conf: UncoreConfiguration) extends LogicalNetwork[TileLinkIO]()(conf.tl.ln) { - implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) +class ReferenceChipCrossbarNetwork(implicit conf: TileLinkConfiguration) + extends LogicalNetwork[TileLinkIO]()(conf.ln) { + implicit val (ln, co) = (conf.ln, conf.co) val io = new Bundle { val clients = Vec.fill(ln.nClients){(new TileLinkIO).flip} val masters = Vec.fill(ln.nMasters){new TileLinkIO} diff --git a/uncore b/uncore index 4ca76eba..181a3596 160000 --- a/uncore +++ b/uncore @@ -1 +1 @@ -Subproject commit 4ca76ebaad5e796121fcb6843b00a6e5da25cd6f +Subproject commit 181a35962b3ed19f8687551568300a0a4039eb11