From c77c244016e1d28ec1b48d0b6510c5170feeca2a Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Tue, 27 Sep 2016 13:13:22 -0700 Subject: [PATCH] Get rid of NASTI memory interconnects These were made for a previous Hurricane tapeout, but we are now doing all of the memory routing in TileLink, so they are no longer needed. --- src/main/scala/junctions/NastiDemuxTest.scala | 109 ------------ src/main/scala/junctions/nasti.scala | 165 ------------------ src/main/scala/unittest/Configs.scala | 1 - 3 files changed, 275 deletions(-) delete mode 100644 src/main/scala/junctions/NastiDemuxTest.scala diff --git a/src/main/scala/junctions/NastiDemuxTest.scala b/src/main/scala/junctions/NastiDemuxTest.scala deleted file mode 100644 index ea7d8b9a..00000000 --- a/src/main/scala/junctions/NastiDemuxTest.scala +++ /dev/null @@ -1,109 +0,0 @@ -package junctions - -import Chisel._ -import cde.Parameters - -class NastiDemuxDriver(n: Int)(implicit p: Parameters) extends Module { - val io = new Bundle { - val start = Bool(INPUT) - val finished = Bool(OUTPUT) - val nasti = new NastiIO - val select = UInt(OUTPUT, log2Up(n)) - } - - val (s_idle :: s_write_addr :: s_write_data :: s_write_resp :: - s_read_addr :: s_read_resp :: s_done :: Nil) = Enum(Bits(), 7) - val state = Reg(init = s_idle) - - val select = Reg(init = UInt(0, log2Up(n))) - - when (state === s_idle && io.start) { state := s_write_addr } - when (io.nasti.aw.fire()) { state := s_write_data } - when (io.nasti.w.fire()) { state := s_write_resp } - when (io.nasti.b.fire()) { state := s_read_addr } - when (io.nasti.ar.fire()) { state := s_read_resp } - when (io.nasti.r.fire()) { - when (select === UInt(n - 1)) { - state := s_done - } .otherwise { - select := select + UInt(1) - state := s_write_addr - } - } - - io.nasti.aw.valid := (state === s_write_addr) - io.nasti.aw.bits := NastiWriteAddressChannel( - id = UInt(0), - addr = UInt(0), - size = UInt("b011")) - io.nasti.w.valid := (state === s_write_data) - io.nasti.w.bits := NastiWriteDataChannel(data = select) - io.nasti.b.ready := (state === s_write_resp) - io.nasti.ar.valid := (state === s_read_addr) - io.nasti.ar.bits := NastiReadAddressChannel( - id = UInt(0), - addr = UInt(0), - size = UInt("b011")) - io.nasti.r.ready := (state === s_read_resp) - - io.finished := (state === s_done) - io.select := select - - assert(!io.nasti.r.valid || io.nasti.r.bits.data === select, - "NASTI DeMux test: Read data did not match") -} - -class NastiDemuxSlave(implicit p: Parameters) extends NastiModule()(p) { - val io = (new NastiIO).flip - - val (s_write_wait :: s_write_data :: s_write_resp :: - s_read_wait :: s_read_resp :: s_done :: Nil) = Enum(Bits(), 6) - val state = Reg(init = s_write_wait) - - val value = Reg(UInt(width = 64)) - val id = Reg(UInt(width = nastiXIdBits)) - - when (io.aw.fire()) { - id := io.aw.bits.id - state := s_write_data - } - - when (io.w.fire()) { - value := io.w.bits.data - state := s_write_resp - } - - when (io.b.fire()) { state := s_read_wait } - - when (io.ar.fire()) { - id := io.ar.bits.id - state := s_read_resp - } - - when (io.r.fire()) { state := s_done } - - io.aw.ready := (state === s_write_wait) - io.w.ready := (state === s_write_data) - io.b.valid := (state === s_write_resp) - io.b.bits := NastiWriteResponseChannel(id = id) - io.ar.ready := (state === s_read_wait) - io.r.valid := (state === s_read_resp) - io.r.bits := NastiReadDataChannel(id = id, data = value) -} - -class NastiMemoryDemuxTest(implicit p: Parameters) extends unittest.UnitTest { - val nSlaves = 4 - - val driver = Module(new NastiDemuxDriver(nSlaves)) - driver.io.start := io.start - io.finished := driver.io.finished - - val demux = Module(new NastiMemoryDemux(nSlaves)) - demux.io.master <> driver.io.nasti - demux.io.select := driver.io.select - - for (i <- 0 until nSlaves) { - val slave = Module(new NastiDemuxSlave) - slave.io <> demux.io.slaves(i) - } -} diff --git a/src/main/scala/junctions/nasti.scala b/src/main/scala/junctions/nasti.scala index ab580523..f2b4b467 100644 --- a/src/main/scala/junctions/nasti.scala +++ b/src/main/scala/junctions/nasti.scala @@ -553,171 +553,6 @@ class NastiRecursiveInterconnect(val nMasters: Int, addrMap: AddrMap) } } -class ChannelHelper(nChannels: Int) - (implicit val p: Parameters) extends HasNastiParameters { - - val dataBytes = p(MIFDataBits) * p(MIFDataBeats) / 8 - val chanSelBits = log2Ceil(nChannels) - val selOffset = log2Up(dataBytes) - val blockOffset = selOffset + chanSelBits - - def getSelect(addr: UInt) = - if (nChannels > 1) addr(blockOffset - 1, selOffset) else UInt(0) - - def getAddr(addr: UInt) = - if (nChannels > 1) - Cat(addr(nastiXAddrBits - 1, blockOffset), addr(selOffset - 1, 0)) - else addr -} - -class NastiMemoryInterconnect( - nBanksPerChannel: Int, nChannels: Int) - (implicit p: Parameters) extends NastiInterconnect()(p) { - - val nBanks = nBanksPerChannel * nChannels - val nMasters = nBanks - val nSlaves = nChannels - - val chanHelper = new ChannelHelper(nChannels) - def connectChannel(outer: NastiIO, inner: NastiIO) { - outer <> inner - outer.ar.bits.addr := chanHelper.getAddr(inner.ar.bits.addr) - outer.aw.bits.addr := chanHelper.getAddr(inner.aw.bits.addr) - } - - for (i <- 0 until nChannels) { - /* Bank assignments to channels are strided so that consecutive banks - * map to different channels. That way, consecutive cache lines also - * map to different channels */ - val banks = (i until nBanks by nChannels).map(j => io.masters(j)) - - val channelArb = Module(new NastiArbiter(nBanksPerChannel)) - channelArb.io.master <> banks - connectChannel(io.slaves(i), channelArb.io.slave) - } -} - -/** Allows users to switch between various memory configurations. Note that - * this is a dangerous operation: not only does switching the select input to - * this module violate Nasti, it also causes the memory of the machine to - * become garbled. It's expected that select only changes at boot time, as - * part of the memory controller configuration. */ -class NastiMemorySelectorIO(val nBanks: Int, val maxMemChannels: Int, nConfigs: Int) - (implicit p: Parameters) - extends NastiInterconnectIO(nBanks, maxMemChannels) { - val select = UInt(INPUT, width = log2Up(nConfigs)) - override def cloneType = - new NastiMemorySelectorIO(nMasters, nSlaves, nConfigs).asInstanceOf[this.type] -} - -class NastiMemorySelector(nBanks: Int, maxMemChannels: Int, configs: Seq[Int]) - (implicit p: Parameters) - extends NastiInterconnect()(p) { - val nMasters = nBanks - val nSlaves = maxMemChannels - val nConfigs = configs.size - - override lazy val io = new NastiMemorySelectorIO(nBanks, maxMemChannels, nConfigs) - - def muxOnSelect(up: DecoupledIO[Bundle], dn: DecoupledIO[Bundle], active: Bool): Unit = { - when (active) { dn.bits := up.bits } - when (active) { up.ready := dn.ready } - when (active) { dn.valid := up.valid } - } - - def muxOnSelect(up: NastiIO, dn: NastiIO, active: Bool): Unit = { - muxOnSelect(up.aw, dn.aw, active) - muxOnSelect(up.w, dn.w, active) - muxOnSelect(dn.b, up.b, active) - muxOnSelect(up.ar, dn.ar, active) - muxOnSelect(dn.r, up.r, active) - } - - def muxOnSelect(up: Vec[NastiIO], dn: Vec[NastiIO], active: Bool) : Unit = { - for (i <- 0 until up.size) - muxOnSelect(up(i), dn(i), active) - } - - /* Disconnects a vector of Nasti ports, which involves setting them to - * invalid. Due to Chisel reasons, we need to also set the bits to 0 (since - * there can't be any unconnected inputs). */ - def disconnectSlave(slave: Vec[NastiIO]) = { - slave.foreach{ m => - m.aw.valid := Bool(false) - m.aw.bits := m.aw.bits.fromBits( UInt(0) ) - m.w.valid := Bool(false) - m.w.bits := m.w.bits.fromBits( UInt(0) ) - m.b.ready := Bool(false) - m.ar.valid := Bool(false) - m.ar.bits := m.ar.bits.fromBits( UInt(0) ) - m.r.ready := Bool(false) - } - } - - def disconnectMaster(master: Vec[NastiIO]) = { - master.foreach{ m => - m.aw.ready := Bool(false) - m.w.ready := Bool(false) - m.b.valid := Bool(false) - m.b.bits := m.b.bits.fromBits( UInt(0) ) - m.ar.ready := Bool(false) - m.r.valid := Bool(false) - m.r.bits := m.r.bits.fromBits( UInt(0) ) - } - } - - /* Provides default wires on all our outputs. */ - disconnectMaster(io.masters) - disconnectSlave(io.slaves) - - /* Constructs interconnects for each of the layouts suggested by the - * configuration and switches between them based on the select input. */ - configs.zipWithIndex.foreach{ case (nChannels, select) => - val nBanksPerChannel = nBanks / nChannels - val ic = Module(new NastiMemoryInterconnect(nBanksPerChannel, nChannels)) - disconnectMaster(ic.io.slaves) - disconnectSlave(ic.io.masters) - muxOnSelect( io.masters, ic.io.masters, io.select === UInt(select)) - muxOnSelect(ic.io.slaves, io.slaves, io.select === UInt(select)) - } -} - -class NastiMemoryDemux(nRoutes: Int)(implicit p: Parameters) extends NastiModule()(p) { - val io = new Bundle { - val master = (new NastiIO).flip - val slaves = Vec(nRoutes, new NastiIO) - val select = UInt(INPUT, log2Up(nRoutes)) - } - - def connectReqChannel[T <: Data](idx: Int, out: DecoupledIO[T], in: DecoupledIO[T]) { - out.valid := in.valid && io.select === UInt(idx) - out.bits := in.bits - when (io.select === UInt(idx)) { in.ready := out.ready } - } - - def connectRespChannel[T <: Data](idx: Int, out: DecoupledIO[T], in: DecoupledIO[T]) { - when (io.select === UInt(idx)) { out.valid := in.valid } - when (io.select === UInt(idx)) { out.bits := in.bits } - in.ready := out.ready && io.select === UInt(idx) - } - - io.master.ar.ready := Bool(false) - io.master.aw.ready := Bool(false) - io.master.w.ready := Bool(false) - io.master.r.valid := Bool(false) - io.master.r.bits := NastiReadDataChannel(id = UInt(0), data = UInt(0)) - io.master.b.valid := Bool(false) - io.master.b.bits := NastiWriteResponseChannel(id = UInt(0)) - - io.slaves.zipWithIndex.foreach { case (slave, i) => - connectReqChannel(i, slave.ar, io.master.ar) - connectReqChannel(i, slave.aw, io.master.aw) - connectReqChannel(i, slave.w, io.master.w) - connectRespChannel(i, io.master.r, slave.r) - connectRespChannel(i, io.master.b, slave.b) - } -} - object AsyncNastiCrossing { // takes from_source from the 'from' clock domain to the 'to' clock domain def apply(from_clock: Clock, from_reset: Bool, from_source: NastiIO, to_clock: Clock, to_reset: Bool, depth: Int = 8, sync: Int = 3) = { diff --git a/src/main/scala/unittest/Configs.scala b/src/main/scala/unittest/Configs.scala index 19ad911a..1cf21ae4 100644 --- a/src/main/scala/unittest/Configs.scala +++ b/src/main/scala/unittest/Configs.scala @@ -12,7 +12,6 @@ class WithJunctionsUnitTests extends Config( case rocket.XLen => 64 case UnitTests => (p: Parameters) => Seq( Module(new junctions.MultiWidthFifoTest), - Module(new junctions.NastiMemoryDemuxTest()(p)), Module(new junctions.HastiTest()(p))) case _ => throw new CDEMatchError })