From 39a749843c9b7181b521c3d79346867e6b5c7e87 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 2 Oct 2015 14:19:51 -0700 Subject: [PATCH 1/4] refactor NASTI to not use param; new AddrMap class --- junctions/src/main/scala/nasti.scala | 302 ++++++++++++++------------- junctions/src/main/scala/smi.scala | 36 ++-- junctions/src/main/scala/util.scala | 7 + 3 files changed, 181 insertions(+), 164 deletions(-) create mode 100644 junctions/src/main/scala/util.scala diff --git a/junctions/src/main/scala/nasti.scala b/junctions/src/main/scala/nasti.scala index 26306e54..413f3f5c 100644 --- a/junctions/src/main/scala/nasti.scala +++ b/junctions/src/main/scala/nasti.scala @@ -6,21 +6,20 @@ import scala.math.max import scala.collection.mutable.ArraySeq import scala.collection.mutable.HashMap +case object NastiBitWidths extends Field[NastiParameters] +case object NastiAddrMap extends Field[AddrMap] case object MMIOBase extends Field[BigInt] -case object NASTIDataBits extends Field[Int] -case object NASTIAddrBits extends Field[Int] -case object NASTIIdBits extends Field[Int] -object bigIntPow2 { - def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) -} +case class NastiParameters(dataBits: Int, addrBits: Int, idBits: Int) -trait NASTIParameters extends UsesParameters { - val nastiXDataBits = params(NASTIDataBits) +trait HasNastiParameters { + implicit val p: Parameters + val external = p(NastiBitWidths) + val nastiXDataBits = external.dataBits val nastiWStrobeBits = nastiXDataBits / 8 - val nastiXAddrBits = params(NASTIAddrBits) - val nastiWIdBits = params(NASTIIdBits) - val nastiRIdBits = params(NASTIIdBits) + val nastiXAddrBits = external.addrBits + val nastiWIdBits = external.idBits + val nastiRIdBits = external.idBits val nastiXIdBits = max(nastiWIdBits, nastiRIdBits) val nastiXUserBits = 1 val nastiAWUserBits = nastiXUserBits @@ -48,22 +47,16 @@ trait NASTIParameters extends UsesParameters { UInt(128) -> UInt(7))) } -abstract class NASTIBundle extends Bundle with NASTIParameters -abstract class NASTIModule extends Module with NASTIParameters - -trait NASTIChannel extends NASTIBundle -trait NASTIMasterToSlaveChannel extends NASTIChannel -trait NASTISlaveToMasterChannel extends NASTIChannel - -class NASTIIO extends Bundle { - val aw = Decoupled(new NASTIWriteAddressChannel) - val w = Decoupled(new NASTIWriteDataChannel) - val b = Decoupled(new NASTIWriteResponseChannel).flip - val ar = Decoupled(new NASTIReadAddressChannel) - val r = Decoupled(new NASTIReadDataChannel).flip +abstract class NastiModule extends Module with HasNastiParameters +abstract class NastiBundle(implicit val p: Parameters) extends Bundle with HasNastiParameters { + override def cloneType = this.getClass.getConstructors.head.newInstance(p).asInstanceOf[this.type] } -trait HasNASTIMetadata extends NASTIBundle { +abstract class NastiChannel(implicit p: Parameters) extends NastiBundle()(p) +abstract class NastiMasterToSlaveChannel(implicit p: Parameters) extends NastiChannel()(p) +abstract class NastiSlaveToMasterChannel(implicit p: Parameters) extends NastiChannel()(p) + +trait HasNastiMetadata extends HasNastiParameters { val addr = UInt(width = nastiXAddrBits) val len = UInt(width = nastiXLenBits) val size = UInt(width = nastiXSizeBits) @@ -75,45 +68,56 @@ trait HasNASTIMetadata extends NASTIBundle { val region = UInt(width = nastiXRegionBits) } -trait HasNASTIData extends NASTIBundle { +trait HasNastiData extends HasNastiParameters { val data = UInt(width = nastiXDataBits) val last = Bool() } -class NASTIAddressChannel extends NASTIMasterToSlaveChannel with HasNASTIMetadata +class NastiIO(implicit p: Parameters) extends NastiBundle()(p) { + val aw = Decoupled(new NastiWriteAddressChannel) + val w = Decoupled(new NastiWriteDataChannel) + val b = Decoupled(new NastiWriteResponseChannel).flip + val ar = Decoupled(new NastiReadAddressChannel) + val r = Decoupled(new NastiReadDataChannel).flip +} -class NASTIResponseChannel extends NASTISlaveToMasterChannel { +class NastiAddressChannel(implicit p: Parameters) extends NastiMasterToSlaveChannel()(p) + with HasNastiMetadata + +class NastiResponseChannel(implicit p: Parameters) extends NastiSlaveToMasterChannel()(p) { val resp = UInt(width = nastiXRespBits) } -class NASTIWriteAddressChannel extends NASTIAddressChannel { +class NastiWriteAddressChannel(implicit p: Parameters) extends NastiAddressChannel()(p) { val id = UInt(width = nastiWIdBits) val user = UInt(width = nastiAWUserBits) } -class NASTIWriteDataChannel extends NASTIMasterToSlaveChannel with HasNASTIData { +class NastiWriteDataChannel(implicit p: Parameters) extends NastiMasterToSlaveChannel()(p) + with HasNastiData { val strb = UInt(width = nastiWStrobeBits) val user = UInt(width = nastiWUserBits) } -class NASTIWriteResponseChannel extends NASTIResponseChannel { +class NastiWriteResponseChannel(implicit p: Parameters) extends NastiResponseChannel()(p) { val id = UInt(width = nastiWIdBits) val user = UInt(width = nastiBUserBits) } -class NASTIReadAddressChannel extends NASTIAddressChannel { +class NastiReadAddressChannel(implicit p: Parameters) extends NastiAddressChannel()(p) { val id = UInt(width = nastiRIdBits) val user = UInt(width = nastiARUserBits) } -class NASTIReadDataChannel extends NASTIResponseChannel with HasNASTIData { +class NastiReadDataChannel(implicit p: Parameters) extends NastiResponseChannel()(p) + with HasNastiData { val id = UInt(width = nastiRIdBits) val user = UInt(width = nastiRUserBits) } -object NASTIWriteAddressChannel { - def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0)) = { - val aw = Wire(new NASTIWriteAddressChannel) +object NastiWriteAddressChannel { + def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0))(implicit p: Parameters) = { + val aw = Wire(new NastiWriteAddressChannel) aw.id := id aw.addr := addr aw.len := len @@ -129,9 +133,9 @@ object NASTIWriteAddressChannel { } } -object NASTIReadAddressChannel { - def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0)) = { - val ar = Wire(new NASTIReadAddressChannel) +object NastiReadAddressChannel { + def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0))(implicit p: Parameters) = { + val ar = Wire(new NastiReadAddressChannel) ar.id := id ar.addr := addr ar.len := len @@ -147,22 +151,27 @@ object NASTIReadAddressChannel { } } -object NASTIWriteDataChannel { - private def strobeBits = new NASTIWriteDataChannel().nastiWStrobeBits - def fullStrobe = Fill(strobeBits, UInt(1, 1)) - def apply(data: UInt, strb: UInt = fullStrobe, last: Bool = Bool(true)) = { - val w = Wire(new NASTIWriteDataChannel) - w.strb := strb +object NastiWriteDataChannel { + def apply(data: UInt, last: Bool = Bool(true))(implicit p: Parameters): NastiWriteDataChannel = { + val w = Wire(new NastiWriteDataChannel) + w.strb := Fill(w.nastiWStrobeBits, UInt(1, 1)) w.data := data w.last := last w.user := UInt(0) w } + def apply(data: UInt, strb: UInt, last: Bool) + (implicit p: Parameters): NastiWriteDataChannel = { + val w = apply(data, last) + w.strb := strb + w + } } -object NASTIReadDataChannel { - def apply(id: UInt, data: UInt, last: Bool = Bool(true), resp: UInt = UInt(0)) = { - val r = Wire(new NASTIReadDataChannel) +object NastiReadDataChannel { + def apply(id: UInt, data: UInt, last: Bool = Bool(true), resp: UInt = UInt(0))( + implicit p: Parameters) = { + val r = Wire(new NastiReadDataChannel) r.id := id r.data := data r.last := last @@ -172,9 +181,9 @@ object NASTIReadDataChannel { } } -object NASTIWriteResponseChannel { - def apply(id: UInt, resp: UInt = UInt(0)) = { - val b = Wire(new NASTIWriteResponseChannel) +object NastiWriteResponseChannel { + def apply(id: UInt, resp: UInt = UInt(0))(implicit p: Parameters) = { + val b = Wire(new NastiWriteResponseChannel) b.id := id b.resp := resp b.user := UInt(0) @@ -182,9 +191,10 @@ object NASTIWriteResponseChannel { } } -class MemIONASTIIOConverter(cacheBlockOffsetBits: Int) extends MIFModule with NASTIParameters { +class MemIONastiIOConverter(cacheBlockOffsetBits: Int)(implicit val p: Parameters) extends MIFModule + with HasNastiParameters { val io = new Bundle { - val nasti = (new NASTIIO).flip + val nasti = (new NastiIO).flip val mem = new MemIO } @@ -192,13 +202,13 @@ class MemIONASTIIOConverter(cacheBlockOffsetBits: Int) extends MIFModule with NA val (mif_cnt_out, mif_wrap_out) = Counter(io.mem.resp.fire(), mifDataBeats) assert(!io.nasti.aw.valid || io.nasti.aw.bits.size === UInt(log2Up(mifDataBits/8)), - "NASTI data size does not match MemIO data size") + "Nasti data size does not match MemIO data size") assert(!io.nasti.ar.valid || io.nasti.ar.bits.size === UInt(log2Up(mifDataBits/8)), - "NASTI data size does not match MemIO data size") + "Nasti data size does not match MemIO data size") assert(!io.nasti.aw.valid || io.nasti.aw.bits.len === UInt(mifDataBeats - 1), - "NASTI length does not match number of MemIO beats") + "Nasti length does not match number of MemIO beats") assert(!io.nasti.ar.valid || io.nasti.ar.bits.len === UInt(mifDataBeats - 1), - "NASTI length does not match number of MemIO beats") + "Nasti length does not match number of MemIO beats") // according to the spec, we can't send b until the last transfer on w val b_ok = Reg(init = Bool(true)) @@ -236,17 +246,17 @@ class MemIONASTIIOConverter(cacheBlockOffsetBits: Int) extends MIFModule with NA } /** Arbitrate among arbN masters requesting to a single slave */ -class NASTIArbiter(val arbN: Int) extends NASTIModule { +class NastiArbiter(val arbN: Int)(implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val master = Vec(new NASTIIO, arbN).flip - val slave = new NASTIIO + val master = Vec(new NastiIO, arbN).flip + val slave = new NastiIO } if (arbN > 1) { val arbIdBits = log2Up(arbN) - val ar_arb = Module(new RRArbiter(new NASTIReadAddressChannel, arbN)) - val aw_arb = Module(new RRArbiter(new NASTIWriteAddressChannel, arbN)) + val ar_arb = Module(new RRArbiter(new NastiReadAddressChannel, arbN)) + val aw_arb = Module(new RRArbiter(new NastiWriteAddressChannel, arbN)) val slave_r_arb_id = io.slave.r.bits.id(arbIdBits - 1, 0) val slave_b_arb_id = io.slave.b.bits.id(arbIdBits - 1, 0) @@ -304,12 +314,12 @@ class NASTIArbiter(val arbN: Int) extends NASTIModule { } else { io.slave <> io.master.head } } -/** Locking RR arbiter for NASTI read data channel +/** Locking RR arbiter for Nasti read data channel * Arbiter locks until last message in channel is sent */ -class NASTIReadDataArbiter(arbN: Int) extends NASTIModule { +class NastiReadDataArbiter(arbN: Int)(implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val in = Vec(Decoupled(new NASTIReadDataChannel), arbN).flip - val out = Decoupled(new NASTIReadDataChannel) + val in = Vec(Decoupled(new NastiReadDataChannel), arbN).flip + val out = Decoupled(new NastiReadDataChannel) } def rotateLeft[T <: Data](norm: Vec[T], rot: UInt): Vec[T] = { @@ -347,13 +357,13 @@ class NASTIReadDataArbiter(arbN: Int) extends NASTIModule { } /** A slave that send decode error for every request it receives */ -class NASTIErrorSlave extends NASTIModule { - val io = (new NASTIIO).flip +class NastiErrorSlave(implicit val p: Parameters) extends NastiModule { + val io = (new NastiIO).flip when (io.ar.fire()) { printf("Invalid read address %x\n", io.ar.bits.addr) } when (io.aw.fire()) { printf("Invalid write address %x\n", io.aw.bits.addr) } - val r_queue = Module(new Queue(new NASTIReadAddressChannel, 2)) + val r_queue = Module(new Queue(new NastiReadAddressChannel, 2)) r_queue.io.enq <> io.ar val responding = Reg(init = Bool(false)) @@ -396,15 +406,15 @@ class NASTIErrorSlave extends NASTIModule { b_queue.io.deq.ready := io.b.ready && !draining } -/** Take a single NASTI master and route its requests to various slaves +/** Take a single Nasti master and route its requests to various slaves * @param addrmap a sequence of base address + memory size pairs, * on for each slave interface */ -class NASTIRouter(addrmap: Seq[(BigInt, BigInt)]) extends NASTIModule { +class NastiRouter(addrmap: Seq[(BigInt, BigInt)])(implicit val p: Parameters) extends NastiModule { val nSlaves = addrmap.size val io = new Bundle { - val master = (new NASTIIO).flip - val slave = Vec(new NASTIIO, nSlaves) + val master = (new NastiIO).flip + val slave = Vec(new NastiIO, nSlaves) } var ar_ready = Bool(false) @@ -446,7 +456,7 @@ class NASTIRouter(addrmap: Seq[(BigInt, BigInt)]) extends NASTIModule { w_ready = w_ready || (s.w.ready && chosen) } - val err_slave = Module(new NASTIErrorSlave) + val err_slave = Module(new NastiErrorSlave) err_slave.io.ar.valid := !r_valid_addr && io.master.ar.valid err_slave.io.ar.bits := io.master.ar.bits err_slave.io.aw.valid := !w_valid_addr && io.master.aw.valid @@ -458,8 +468,8 @@ class NASTIRouter(addrmap: Seq[(BigInt, BigInt)]) extends NASTIModule { io.master.aw.ready := aw_ready || (!w_valid_addr && err_slave.io.aw.ready) io.master.w.ready := w_ready || err_slave.io.w.ready - val b_arb = Module(new RRArbiter(new NASTIWriteResponseChannel, nSlaves + 1)) - val r_arb = Module(new NASTIReadDataArbiter(nSlaves + 1)) + val b_arb = Module(new RRArbiter(new NastiWriteResponseChannel, nSlaves + 1)) + val r_arb = Module(new NastiReadDataArbiter(nSlaves + 1)) for (i <- 0 until nSlaves) { b_arb.io.in(i) <> io.slave(i).b @@ -473,20 +483,20 @@ class NASTIRouter(addrmap: Seq[(BigInt, BigInt)]) extends NASTIModule { io.master.r <> r_arb.io.out } -/** Crossbar between multiple NASTI masters and slaves - * @param nMasters the number of NASTI masters - * @param nSlaves the number of NASTI slaves +/** Crossbar between multiple Nasti masters and slaves + * @param nMasters the number of Nasti masters + * @param nSlaves the number of Nasti slaves * @param addrmap a sequence of base - size pairs; * size of addrmap should be nSlaves */ -class NASTICrossbar(nMasters: Int, nSlaves: Int, addrmap: Seq[(BigInt, BigInt)]) - extends NASTIModule { +class NastiCrossbar(nMasters: Int, nSlaves: Int, addrmap: Seq[(BigInt, BigInt)]) + (implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val masters = Vec(new NASTIIO, nMasters).flip - val slaves = Vec(new NASTIIO, nSlaves) + val masters = Vec(new NastiIO, nMasters).flip + val slaves = Vec(new NastiIO, nSlaves) } - val routers = Vec.fill(nMasters) { Module(new NASTIRouter(addrmap)).io } - val arbiters = Vec.fill(nSlaves) { Module(new NASTIArbiter(nMasters)).io } + val routers = Vec.fill(nMasters) { Module(new NastiRouter(addrmap)).io } + val arbiters = Vec.fill(nSlaves) { Module(new NastiArbiter(nMasters)).io } for (i <- 0 until nMasters) { routers(i).master <> io.masters(i) @@ -498,13 +508,7 @@ class NASTICrossbar(nMasters: Int, nSlaves: Int, addrmap: Seq[(BigInt, BigInt)]) } } -case object NASTINMasters extends Field[Int] -case object NASTINSlaves extends Field[Int] - -object AddrMap { - type AddrMapEntry = (String, Option[BigInt], MemRegion) - type AddrMapSeq = Seq[AddrMapEntry] - +object AddrMapConsts { val R = 0x4 val W = 0x2 val X = 0x1 @@ -512,19 +516,6 @@ object AddrMap { val RX = R | X val RWX = R | W | X } -import AddrMap._ - -abstract class MemRegion { def size: BigInt } - -case class MemSize(size: BigInt, prot: Int) extends MemRegion -case class MemSubmap(size: BigInt, entries: AddrMapSeq) extends MemRegion - -object Submap { - def apply(size: BigInt, entries: AddrMapEntry*) = - new MemSubmap(size, entries) -} - -case class AddrHashMapEntry(port: Int, start: BigInt, size: BigInt, prot: Int) class AddrMapProt extends Bundle { val r = Bool() @@ -532,14 +523,47 @@ class AddrMapProt extends Bundle { val x = Bool() } -class AddrHashMap(addrmap: AddrMapSeq) { +abstract class MemRegion { def size: BigInt } + +case class MemSize(size: BigInt, prot: Int) extends MemRegion + +case class MemSubmap(size: BigInt, entries: AddrMap) extends MemRegion + +//object Submap { +// def apply(size: BigInt, entries: AddrMapEntry*) = +// new MemSubmap(size, entries) +//} + +case class AddrMapEntry(name: String, start: Option[BigInt], region: MemRegion) + +case class AddrHashMapEntry(port: Int, start: BigInt, size: BigInt, prot: Int) + +class AddrMap(entries: Seq[AddrMapEntry]) extends scala.collection.IndexedSeq[AddrMapEntry] { + + def apply(index: Int): AddrMapEntry = entries(index) + + def length: Int = entries.size + + def countSlaves: Int = { + this map { entry: AddrMapEntry => entry.region match { + case MemSize(_, _) => 1 + case MemSubmap(_, submap) => submap.countSlaves + }} reduceLeft(_ + _) + } +} + +object AddrMap { + def apply(elems: AddrMapEntry*): AddrMap = new AddrMap(elems) +} + +class AddrHashMap(addrmap: AddrMap) { val mapping = new HashMap[String, AddrHashMapEntry] - private def genPairs(addrmap: AddrMapSeq): Seq[(String, AddrHashMapEntry)] = { + private def genPairs(am: AddrMap): Seq[(String, AddrHashMapEntry)] = { var ind = 0 var base = BigInt(0) var pairs = Seq[(String, AddrHashMapEntry)]() - addrmap.foreach { case (name, startOpt, region) => + am.foreach { case AddrMapEntry(name, startOpt, region) => region match { case MemSize(size, prot) => { if (!startOpt.isEmpty) base = startOpt.get @@ -590,43 +614,35 @@ class AddrHashMap(addrmap: AddrMapSeq) { } } -case object NASTIAddrMap extends Field[AddrMapSeq] -case object NASTIAddrHashMap extends Field[AddrHashMap] - -class NASTIInterconnectIO(val nMasters: Int, val nSlaves: Int) extends Bundle { +class NastiInterconnectIO(val nMasters: Int, val nSlaves: Int) + (implicit p: Parameters) extends Bundle { /* This is a bit confusing. The interconnect is a slave to the masters and * a master to the slaves. Hence why the declarations seem to be backwards. */ - val masters = Vec(new NASTIIO, nMasters).flip - val slaves = Vec(new NASTIIO, nSlaves) + val masters = Vec(new NastiIO, nMasters).flip + val slaves = Vec(new NastiIO, nSlaves) override def cloneType = - new NASTIInterconnectIO(nMasters, nSlaves).asInstanceOf[this.type] + new NastiInterconnectIO(nMasters, nSlaves).asInstanceOf[this.type] } -abstract class NASTIInterconnect extends NASTIModule { +abstract class NastiInterconnect extends NastiModule { val nMasters: Int val nSlaves: Int - lazy val io = new NASTIInterconnectIO(nMasters, nSlaves) + lazy val io = new NastiInterconnectIO(nMasters, nSlaves) } -class NASTIRecursiveInterconnect( - val nMasters: Int, val nSlaves: Int, - addrmap: AddrMapSeq, base: BigInt = 0) extends NASTIInterconnect { - - private def mapCountSlaves(addrmap: AddrMapSeq): Int = { - addrmap.map { - case (_, _, MemSize(_, _)) => 1 - case (_, _, MemSubmap(_, submap)) => mapCountSlaves(submap) - }.reduceLeft(_ + _) - } - +class NastiRecursiveInterconnect( + val nMasters: Int, + val nSlaves: Int, + addrmap: AddrMap, + base: BigInt = 0) + (implicit val p: Parameters) extends NastiInterconnect { var lastEnd = base var slaveInd = 0 val levelSize = addrmap.size - val realAddrMap = new ArraySeq[(BigInt, BigInt)](addrmap.size) - addrmap.zipWithIndex.foreach { case ((_, startOpt, region), i) => + addrmap.zipWithIndex.foreach { case (AddrMapEntry(_, startOpt, region), i) => val start = startOpt.getOrElse(lastEnd) val size = region.size realAddrMap(i) = (start, size) @@ -634,25 +650,24 @@ class NASTIRecursiveInterconnect( } val flatSlaves = if (nMasters > 1) { - val xbar = Module(new NASTICrossbar(nMasters, levelSize, realAddrMap)) + val xbar = Module(new NastiCrossbar(nMasters, levelSize, realAddrMap)) xbar.io.masters <> io.masters xbar.io.slaves } else { - val router = Module(new NASTIRouter(realAddrMap)) + val router = Module(new NastiRouter(realAddrMap)) router.io.master <> io.masters.head router.io.slave } addrmap.zip(realAddrMap).zipWithIndex.foreach { - case (((_, _, region), (start, size)), i) => { - region match { + case ((entry, (start, size)), i) => { + entry.region match { case MemSize(_, _) => io.slaves(slaveInd) <> flatSlaves(i) slaveInd += 1 case MemSubmap(_, submap) => - val subSlaves = mapCountSlaves(submap) - val ic = Module(new NASTIRecursiveInterconnect( - 1, subSlaves, submap, start)) + val subSlaves = submap.countSlaves + val ic = Module(new NastiRecursiveInterconnect(1, subSlaves, submap, start)) ic.io.masters.head <> flatSlaves(i) io.slaves.drop(slaveInd).take(subSlaves).zip(ic.io.slaves).foreach { case (s, m) => s <> m @@ -663,20 +678,15 @@ class NASTIRecursiveInterconnect( } } -class NASTITopInterconnect extends NASTIInterconnect { - val nMasters = params(NASTINMasters) - val nSlaves = params(NASTINSlaves) - - bigIntPow2(params(MMIOBase)) - - val temp = Module(new NASTIRecursiveInterconnect( - nMasters, nSlaves, params(NASTIAddrMap))) +class NastiTopInterconnect(val nMasters: Int, val nSlaves: Int) + (implicit val p: Parameters) extends NastiInterconnect { + val temp = Module(new NastiRecursiveInterconnect(nMasters, nSlaves, p(NastiAddrMap))) temp.io.masters.zip(io.masters).foreach { case (t, i) => t.ar <> i.ar t.aw <> i.aw // this queue is necessary to break up the aw - w dependence - // introduced by the TileLink -> NASTI converter + // introduced by the TileLink -> Nasti converter t.w <> Queue(i.w) i.b <> t.b i.r <> t.r diff --git a/junctions/src/main/scala/smi.scala b/junctions/src/main/scala/smi.scala index ec2e554e..52d98779 100644 --- a/junctions/src/main/scala/smi.scala +++ b/junctions/src/main/scala/smi.scala @@ -87,11 +87,11 @@ class SMIArbiter(val n: Int, val dataWidth: Int, val addrWidth: Int) io.out.resp.ready := io.in(choice).resp.ready } -class SMIIONASTIReadIOConverter(val dataWidth: Int, val addrWidth: Int) - extends NASTIModule { +class SMIIONastiReadIOConverter(val dataWidth: Int, val addrWidth: Int) + (implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val ar = Decoupled(new NASTIReadAddressChannel).flip - val r = Decoupled(new NASTIReadDataChannel) + val ar = Decoupled(new NastiReadAddressChannel).flip + val r = Decoupled(new NastiReadDataChannel) val smi = new SMIIO(dataWidth, addrWidth) } @@ -127,7 +127,7 @@ class SMIIONASTIReadIOConverter(val dataWidth: Int, val addrWidth: Int) io.smi.resp.ready := (state === s_read) io.r.valid := (state === s_resp) - io.r.bits := NASTIReadDataChannel( + io.r.bits := NastiReadDataChannel( id = id, data = buffer.toBits, last = (nBeats === UInt(0))) @@ -169,12 +169,12 @@ class SMIIONASTIReadIOConverter(val dataWidth: Int, val addrWidth: Int) } } -class SMIIONASTIWriteIOConverter(val dataWidth: Int, val addrWidth: Int) - extends NASTIModule { +class SMIIONastiWriteIOConverter(val dataWidth: Int, val addrWidth: Int) + (implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val aw = Decoupled(new NASTIWriteAddressChannel).flip - val w = Decoupled(new NASTIWriteDataChannel).flip - val b = Decoupled(new NASTIWriteResponseChannel) + val aw = Decoupled(new NastiWriteAddressChannel).flip + val w = Decoupled(new NastiWriteDataChannel).flip + val b = Decoupled(new NastiWriteResponseChannel) val smi = new SMIIO(dataWidth, addrWidth) } @@ -184,7 +184,7 @@ class SMIIONASTIWriteIOConverter(val dataWidth: Int, val addrWidth: Int) private val addrOffBits = addrWidth + byteOffBits assert(!io.aw.valid || io.aw.bits.size >= UInt(byteOffBits), - "NASTI size must be >= SMI size") + "Nasti size must be >= SMI size") val id = Reg(UInt(width = nastiWIdBits)) val addr = Reg(UInt(width = addrWidth)) @@ -213,7 +213,7 @@ class SMIIONASTIWriteIOConverter(val dataWidth: Int, val addrWidth: Int) io.smi.req.bits.data := data(dataWidth - 1, 0) io.smi.resp.ready := (state === s_ack) io.b.valid := (state === s_resp) - io.b.bits := NASTIWriteResponseChannel(id) + io.b.bits := NastiWriteResponseChannel(id) val jump = PriorityMux(strb(maxWordsPerBeat - 1, 1), (1 until maxWordsPerBeat).map(UInt(_))) @@ -249,21 +249,21 @@ class SMIIONASTIWriteIOConverter(val dataWidth: Int, val addrWidth: Int) when (io.b.fire()) { state := s_idle } } -/** Convert NASTI protocol to SMI protocol */ -class SMIIONASTIIOConverter(val dataWidth: Int, val addrWidth: Int) - extends NASTIModule { +/** Convert Nasti protocol to SMI protocol */ +class SMIIONastiIOConverter(val dataWidth: Int, val addrWidth: Int) + (implicit val p: Parameters) extends NastiModule { val io = new Bundle { - val nasti = (new NASTIIO).flip + val nasti = (new NastiIO).flip val smi = new SMIIO(dataWidth, addrWidth) } require(isPow2(dataWidth), "SMI data width must be power of 2") - val reader = Module(new SMIIONASTIReadIOConverter(dataWidth, addrWidth)) + val reader = Module(new SMIIONastiReadIOConverter(dataWidth, addrWidth)) reader.io.ar <> io.nasti.ar io.nasti.r <> reader.io.r - val writer = Module(new SMIIONASTIWriteIOConverter(dataWidth, addrWidth)) + val writer = Module(new SMIIONastiWriteIOConverter(dataWidth, addrWidth)) writer.io.aw <> io.nasti.aw writer.io.w <> io.nasti.w io.nasti.b <> writer.io.b diff --git a/junctions/src/main/scala/util.scala b/junctions/src/main/scala/util.scala new file mode 100644 index 00000000..1aebcad9 --- /dev/null +++ b/junctions/src/main/scala/util.scala @@ -0,0 +1,7 @@ +/// See LICENSE for license details. +package junctions +import Chisel._ + +object bigIntPow2 { + def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) +} From 970445a26a258b50291219ca895ebc06ec227637 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 2 Oct 2015 15:37:41 -0700 Subject: [PATCH 2/4] refactor MemIO to not use params --- junctions/src/main/scala/memserdes.scala | 101 ++++++----------------- junctions/src/main/scala/nasti.scala | 7 +- junctions/src/main/scala/util.scala | 53 ++++++++++++ 3 files changed, 82 insertions(+), 79 deletions(-) diff --git a/junctions/src/main/scala/memserdes.scala b/junctions/src/main/scala/memserdes.scala index 78212952..1e15a78c 100644 --- a/junctions/src/main/scala/memserdes.scala +++ b/junctions/src/main/scala/memserdes.scala @@ -18,54 +18,57 @@ case object MIFDataBits extends Field[Int] case object MIFTagBits extends Field[Int] case object MIFDataBeats extends Field[Int] -trait MIFParameters extends UsesParameters { - val mifTagBits = params(MIFTagBits) - val mifAddrBits = params(MIFAddrBits) - val mifDataBits = params(MIFDataBits) - val mifDataBeats = params(MIFDataBeats) +trait HasMIFParameters { + implicit val p: Parameters + val mifTagBits = p(MIFTagBits) + val mifAddrBits = p(MIFAddrBits) + val mifDataBits = p(MIFDataBits) + val mifDataBeats = p(MIFDataBeats) } -abstract class MIFBundle extends Bundle with MIFParameters -abstract class MIFModule extends Module with MIFParameters +abstract class MIFModule extends Module with HasMIFParameters +abstract class MIFBundle(implicit p: Parameters) extends ParameterizedBundle()(p) + with HasMIFParameters -trait HasMemData extends MIFBundle { +trait HasMemData extends HasMIFParameters { val data = Bits(width = mifDataBits) } -trait HasMemAddr extends MIFBundle { +trait HasMemAddr extends HasMIFParameters { val addr = UInt(width = mifAddrBits) } -trait HasMemTag extends MIFBundle { +trait HasMemTag extends HasMIFParameters { val tag = UInt(width = mifTagBits) } -class MemReqCmd extends HasMemAddr with HasMemTag { +class MemReqCmd(implicit p: Parameters) extends MIFBundle()(p) with HasMemAddr with HasMemTag { val rw = Bool() } -class MemTag extends HasMemTag -class MemData extends HasMemData -class MemResp extends HasMemData with HasMemTag +class MemTag(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemTag +class MemData(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemData +class MemResp(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemData with HasMemTag -class MemIO extends Bundle { +class MemIO(implicit p: Parameters) extends ParameterizedBundle()(p) { val req_cmd = Decoupled(new MemReqCmd) val req_data = Decoupled(new MemData) val resp = Decoupled(new MemResp).flip } -class MemPipeIO extends Bundle { +class MemPipeIO(implicit p: Parameters) extends ParameterizedBundle()(p) { val req_cmd = Decoupled(new MemReqCmd) val req_data = Decoupled(new MemData) val resp = Valid(new MemResp).flip } -class MemSerializedIO(w: Int) extends Bundle { +class MemSerializedIO(w: Int)(implicit p: Parameters) extends ParameterizedBundle()(p) { val req = Decoupled(Bits(width = w)) val resp = Valid(Bits(width = w)).flip + //override def cloneType = new MemSerializedIO(w)(p).asInstanceOf[this.type] } -class MemSerdes(w: Int) extends MIFModule +class MemSerdes(w: Int)(implicit val p: Parameters) extends MIFModule { val io = new Bundle { val wide = new MemIO().flip @@ -140,12 +143,12 @@ class MemSerdes(w: Int) extends MIFModule io.wide.resp.bits := io.wide.resp.bits.fromBits(in_buf) } -class MemDesserIO(w: Int) extends Bundle { +class MemDesserIO(w: Int)(implicit p: Parameters) extends ParameterizedBundle()(p) { val narrow = new MemSerializedIO(w).flip val wide = new MemIO } -class MemDesser(w: Int) extends Module // test rig side +class MemDesser(w: Int)(implicit p: Parameters) extends Module // test rig side { val io = new MemDesserIO(w) val abits = io.wide.req_cmd.bits.toBits.getWidth @@ -211,59 +214,7 @@ class MemDesser(w: Int) extends Module // test rig side io.narrow.resp.bits := dataq.io.deq.bits.toBits >> (recv_cnt * UInt(w)) } -class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Module -{ - val io = new QueueIO(data, entries) - require(entries > 1) - - val do_flow = Wire(Bool()) - val do_enq = io.enq.fire() && !do_flow - val do_deq = io.deq.fire() && !do_flow - - val maybe_full = Reg(init=Bool(false)) - val enq_ptr = Counter(do_enq, entries)._1 - val (deq_ptr, deq_done) = Counter(do_deq, entries) - when (do_enq != do_deq) { maybe_full := do_enq } - - val ptr_match = enq_ptr === deq_ptr - val empty = ptr_match && !maybe_full - val full = ptr_match && maybe_full - val atLeastTwo = full || enq_ptr - deq_ptr >= UInt(2) - do_flow := empty && io.deq.ready - - val ram = SeqMem(data, entries) - when (do_enq) { ram.write(enq_ptr, io.enq.bits) } - - val ren = io.deq.ready && (atLeastTwo || !io.deq.valid && !empty) - val raddr = Mux(io.deq.valid, Mux(deq_done, UInt(0), deq_ptr + UInt(1)), deq_ptr) - val ram_out_valid = Reg(next = ren) - - io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid) - io.enq.ready := !full - io.deq.bits := Mux(empty, io.enq.bits, ram.read(raddr, ren)) -} - -class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Module -{ - val io = new QueueIO(data, entries) - - val fq = Module(new HellaFlowQueue(entries)(data)) - fq.io.enq <> io.enq - io.deq <> Queue(fq.io.deq, 1, pipe = true) -} - -object HellaQueue -{ - def apply[T <: Data](enq: DecoupledIO[T], entries: Int) = { - val q = Module((new HellaQueue(entries)) { enq.bits }) - q.io.enq.valid := enq.valid // not using <> so that override is allowed - q.io.enq.bits := enq.bits - enq.ready := q.io.enq.ready - q.io.deq - } -} - -class MemIOArbiter(val arbN: Int) extends MIFModule { +class MemIOArbiter(val arbN: Int)(implicit val p: Parameters) extends MIFModule { val io = new Bundle { val inner = Vec(new MemIO, arbN).flip val outer = new MemIO @@ -307,7 +258,7 @@ class MemIOArbiter(val arbN: Int) extends MIFModule { } object MemIOMemPipeIOConverter { - def apply(in: MemPipeIO): MemIO = { + def apply(in: MemPipeIO)(implicit p: Parameters): MemIO = { val out = Wire(new MemIO()) in.resp.valid := out.resp.valid in.resp.bits := out.resp.bits @@ -322,7 +273,7 @@ object MemIOMemPipeIOConverter { } } -class MemPipeIOMemIOConverter(numRequests: Int) extends MIFModule { +class MemPipeIOMemIOConverter(numRequests: Int)(implicit val p: Parameters) extends MIFModule { val io = new Bundle { val cpu = new MemIO().flip val mem = new MemPipeIO diff --git a/junctions/src/main/scala/nasti.scala b/junctions/src/main/scala/nasti.scala index 413f3f5c..f26cf526 100644 --- a/junctions/src/main/scala/nasti.scala +++ b/junctions/src/main/scala/nasti.scala @@ -48,9 +48,8 @@ trait HasNastiParameters { } abstract class NastiModule extends Module with HasNastiParameters -abstract class NastiBundle(implicit val p: Parameters) extends Bundle with HasNastiParameters { - override def cloneType = this.getClass.getConstructors.head.newInstance(p).asInstanceOf[this.type] -} +abstract class NastiBundle(implicit p: Parameters) extends ParameterizedBundle()(p) + with HasNastiParameters abstract class NastiChannel(implicit p: Parameters) extends NastiBundle()(p) abstract class NastiMasterToSlaveChannel(implicit p: Parameters) extends NastiChannel()(p) @@ -73,7 +72,7 @@ trait HasNastiData extends HasNastiParameters { val last = Bool() } -class NastiIO(implicit p: Parameters) extends NastiBundle()(p) { +class NastiIO(implicit p: Parameters) extends ParameterizedBundle()(p) { val aw = Decoupled(new NastiWriteAddressChannel) val w = Decoupled(new NastiWriteDataChannel) val b = Decoupled(new NastiWriteResponseChannel).flip diff --git a/junctions/src/main/scala/util.scala b/junctions/src/main/scala/util.scala index 1aebcad9..cefe8470 100644 --- a/junctions/src/main/scala/util.scala +++ b/junctions/src/main/scala/util.scala @@ -5,3 +5,56 @@ import Chisel._ object bigIntPow2 { def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) } + +class ParameterizedBundle(implicit val p: Parameters) extends Bundle { + override def cloneType = this.getClass.getConstructors.head.newInstance(p).asInstanceOf[this.type] +} + +class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Module { + val io = new QueueIO(data, entries) + require(entries > 1) + + val do_flow = Wire(Bool()) + val do_enq = io.enq.fire() && !do_flow + val do_deq = io.deq.fire() && !do_flow + + val maybe_full = Reg(init=Bool(false)) + val enq_ptr = Counter(do_enq, entries)._1 + val (deq_ptr, deq_done) = Counter(do_deq, entries) + when (do_enq != do_deq) { maybe_full := do_enq } + + val ptr_match = enq_ptr === deq_ptr + val empty = ptr_match && !maybe_full + val full = ptr_match && maybe_full + val atLeastTwo = full || enq_ptr - deq_ptr >= UInt(2) + do_flow := empty && io.deq.ready + + val ram = SeqMem(data, entries) + when (do_enq) { ram.write(enq_ptr, io.enq.bits) } + + val ren = io.deq.ready && (atLeastTwo || !io.deq.valid && !empty) + val raddr = Mux(io.deq.valid, Mux(deq_done, UInt(0), deq_ptr + UInt(1)), deq_ptr) + val ram_out_valid = Reg(next = ren) + + io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid) + io.enq.ready := !full + io.deq.bits := Mux(empty, io.enq.bits, ram.read(raddr, ren)) +} + +class HellaQueue[T <: Data](val entries: Int)(data: => T) extends Module { + val io = new QueueIO(data, entries) + + val fq = Module(new HellaFlowQueue(entries)(data)) + fq.io.enq <> io.enq + io.deq <> Queue(fq.io.deq, 1, pipe = true) +} + +object HellaQueue { + def apply[T <: Data](enq: DecoupledIO[T], entries: Int) = { + val q = Module((new HellaQueue(entries)) { enq.bits }) + q.io.enq.valid := enq.valid // not using <> so that override is allowed + q.io.enq.bits := enq.bits + enq.ready := q.io.enq.ready + q.io.deq + } +} From adcd77db36ac25d7bc986dfcefc6274ac2ecb051 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Mon, 5 Oct 2015 20:33:55 -0700 Subject: [PATCH 3/4] Removed all traces of params --- junctions/src/main/scala/addrmap.scala | 107 ++++++++++++++++++ junctions/src/main/scala/hasti.scala | 74 ++++++------ junctions/src/main/scala/memserdes.scala | 18 +-- junctions/src/main/scala/nasti.scala | 136 +++-------------------- junctions/src/main/scala/package.scala | 2 +- junctions/src/main/scala/poci.scala | 17 ++- junctions/src/main/scala/smi.scala | 6 +- junctions/src/main/scala/util.scala | 2 +- 8 files changed, 182 insertions(+), 180 deletions(-) create mode 100644 junctions/src/main/scala/addrmap.scala diff --git a/junctions/src/main/scala/addrmap.scala b/junctions/src/main/scala/addrmap.scala new file mode 100644 index 00000000..f37111c9 --- /dev/null +++ b/junctions/src/main/scala/addrmap.scala @@ -0,0 +1,107 @@ +// See LICENSE for license details. + +package junctions + +import Chisel._ +import scala.collection.mutable.HashMap + +abstract class MemRegion { def size: BigInt } + +case class MemSize(size: BigInt, prot: Int) extends MemRegion + +case class MemSubmap(size: BigInt, entries: AddrMap) extends MemRegion + +object AddrMapConsts { + val R = 0x4 + val W = 0x2 + val X = 0x1 + val RW = R | W + val RX = R | X + val RWX = R | W | X +} + +class AddrMapProt extends Bundle { + val r = Bool() + val w = Bool() + val x = Bool() +} + +case class AddrMapEntry(name: String, start: Option[BigInt], region: MemRegion) + +case class AddrHashMapEntry(port: Int, start: BigInt, size: BigInt, prot: Int) + +class AddrMap(entries: Seq[AddrMapEntry]) extends scala.collection.IndexedSeq[AddrMapEntry] { + + def apply(index: Int): AddrMapEntry = entries(index) + + def length: Int = entries.size + + def countSlaves: Int = { + this map { entry: AddrMapEntry => entry.region match { + case MemSize(_, _) => 1 + case MemSubmap(_, submap) => submap.countSlaves + }} reduceLeft(_ + _) + } +} + +object AddrMap { + def apply(elems: AddrMapEntry*): AddrMap = new AddrMap(elems) +} + +class AddrHashMap(addrmap: AddrMap) { + val mapping = new HashMap[String, AddrHashMapEntry] + + private def genPairs(am: AddrMap): Seq[(String, AddrHashMapEntry)] = { + var ind = 0 + var base = BigInt(0) + var pairs = Seq[(String, AddrHashMapEntry)]() + am.foreach { case AddrMapEntry(name, startOpt, region) => + region match { + case MemSize(size, prot) => { + if (!startOpt.isEmpty) base = startOpt.get + pairs = (name, AddrHashMapEntry(ind, base, size, prot)) +: pairs + base += size + ind += 1 + } + case MemSubmap(size, submap) => { + if (!startOpt.isEmpty) base = startOpt.get + val subpairs = genPairs(submap).map { + case (subname, AddrHashMapEntry(subind, subbase, subsize, prot)) => + (name + ":" + subname, + AddrHashMapEntry(ind + subind, base + subbase, subsize, prot)) + } + pairs = subpairs ++ pairs + ind += subpairs.size + base += size + } + } + } + pairs + } + + for ((name, ind) <- genPairs(addrmap)) { mapping(name) = ind } + + def nEntries: Int = mapping.size + def apply(name: String): AddrHashMapEntry = mapping(name) + def get(name: String): Option[AddrHashMapEntry] = mapping.get(name) + def sortedEntries(): Seq[(String, BigInt, BigInt, Int)] = { + val arr = new Array[(String, BigInt, BigInt, Int)](mapping.size) + mapping.foreach { case (name, AddrHashMapEntry(port, base, size, prot)) => + arr(port) = (name, base, size, prot) + } + arr.toSeq + } + + def isValid(addr: UInt): Bool = { + sortedEntries().map { case (_, base, size, _) => + addr >= UInt(base) && addr < UInt(base + size) + }.reduceLeft(_ || _) + } + + def getProt(addr: UInt): AddrMapProt = { + Mux1H(sortedEntries().map { case (_, base, size, prot) => + (addr >= UInt(base) && addr < UInt(base + size), + new AddrMapProt().fromBits(Bits(prot, 3))) + }) + } +} diff --git a/junctions/src/main/scala/hasti.scala b/junctions/src/main/scala/hasti.scala index 2e3b1ff7..7a913dfe 100644 --- a/junctions/src/main/scala/hasti.scala +++ b/junctions/src/main/scala/hasti.scala @@ -2,7 +2,7 @@ package junctions import Chisel._ -abstract trait HASTIConstants +trait HastiConstants { val SZ_HTRANS = 2 val HTRANS_IDLE = UInt(0, SZ_HTRANS) @@ -27,16 +27,22 @@ abstract trait HASTIConstants val SZ_HSIZE = 3 val SZ_HPROT = 4 - // TODO: Parameterize - val SZ_HADDR = 32 - val SZ_HDATA = 32 - def dgate(valid: Bool, b: UInt) = Fill(b.getWidth, valid) & b } -class HASTIMasterIO extends Bundle -{ - val haddr = UInt(OUTPUT, SZ_HADDR) +trait HasHastiParameters { + implicit val p: Parameters + val hastiAddrBits = 32 + val hastiDataBits = 32 +} + +abstract class HastiModule(implicit val p: Parameters) extends Module + with HasHastiParameters +abstract class HastiBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) + with HasHastiParameters + +class HastiMasterIO(implicit p: Parameters) extends HastiBundle()(p) { + val haddr = UInt(OUTPUT, hastiAddrBits) val hwrite = Bool(OUTPUT) val hsize = UInt(OUTPUT, SZ_HSIZE) val hburst = UInt(OUTPUT, SZ_HBURST) @@ -44,16 +50,15 @@ class HASTIMasterIO extends Bundle val htrans = UInt(OUTPUT, SZ_HTRANS) val hmastlock = Bool(OUTPUT) - val hwdata = Bits(OUTPUT, SZ_HDATA) - val hrdata = Bits(INPUT, SZ_HDATA) + val hwdata = Bits(OUTPUT, hastiDataBits) + val hrdata = Bits(INPUT, hastiDataBits) val hready = Bool(INPUT) val hresp = UInt(INPUT, SZ_HRESP) } -class HASTISlaveIO extends Bundle -{ - val haddr = UInt(INPUT, SZ_HADDR) +class HastiSlaveIO(implicit p: Parameters) extends HastiBundle()(p) { + val haddr = UInt(INPUT, hastiAddrBits) val hwrite = Bool(INPUT) val hsize = UInt(INPUT, SZ_HSIZE) val hburst = UInt(INPUT, SZ_HBURST) @@ -61,8 +66,8 @@ class HASTISlaveIO extends Bundle val htrans = UInt(INPUT, SZ_HTRANS) val hmastlock = Bool(INPUT) - val hwdata = Bits(INPUT, SZ_HDATA) - val hrdata = Bits(OUTPUT, SZ_HDATA) + val hwdata = Bits(INPUT, hastiDataBits) + val hrdata = Bits(OUTPUT, hastiDataBits) val hsel = Bool(INPUT) val hreadyin = Bool(INPUT) @@ -70,23 +75,22 @@ class HASTISlaveIO extends Bundle val hresp = UInt(OUTPUT, SZ_HRESP) } -class HASTIBus(amap: Seq[UInt=>Bool]) extends Module -{ +class HastiBus(amap: Seq[UInt=>Bool])(implicit p: Parameters) extends HastiModule()(p) { val io = new Bundle { - val master = new HASTIMasterIO().flip - val slaves = Vec(new HASTISlaveIO, amap.size).flip + val master = new HastiMasterIO().flip + val slaves = Vec(new HastiSlaveIO, amap.size).flip } // skid buffer val skb_valid = Reg(init = Bool(false)) - val skb_haddr = Reg(UInt(width = SZ_HADDR)) + val skb_haddr = Reg(UInt(width = hastiAddrBits)) val skb_hwrite = Reg(Bool()) val skb_hsize = Reg(UInt(width = SZ_HSIZE)) val skb_hburst = Reg(UInt(width = SZ_HBURST)) val skb_hprot = Reg(UInt(width = SZ_HPROT)) val skb_htrans = Reg(UInt(width = SZ_HTRANS)) val skb_hmastlock = Reg(Bool()) - val skb_hwdata = Reg(UInt(width = SZ_HDATA)) + val skb_hwdata = Reg(UInt(width = hastiDataBits)) val master_haddr = Mux(skb_valid, skb_haddr, io.master.haddr) val master_hwrite = Mux(skb_valid, skb_hwrite, io.master.hwrite) @@ -142,16 +146,15 @@ class HASTIBus(amap: Seq[UInt=>Bool]) extends Module io.master.hresp := Mux1H(s1_hsels, io.slaves.map(_.hresp)) } -class HASTISlaveMux(n: Int) extends Module -{ +class HastiSlaveMux(n: Int)(implicit p: Parameters) extends HastiModule()(p) { val io = new Bundle { - val ins = Vec(new HASTISlaveIO, n) - val out = new HASTISlaveIO().flip + val ins = Vec(new HastiSlaveIO, n) + val out = new HastiSlaveIO().flip } // skid buffers val skb_valid = Array.fill(n){Reg(init = Bool(false))} - val skb_haddr = Array.fill(n){Reg(UInt(width = SZ_HADDR))} + val skb_haddr = Array.fill(n){Reg(UInt(width = hastiAddrBits))} val skb_hwrite = Array.fill(n){Reg(Bool())} val skb_hsize = Array.fill(n){Reg(UInt(width = SZ_HSIZE))} val skb_hburst = Array.fill(n){Reg(UInt(width = SZ_HBURST))} @@ -212,15 +215,15 @@ class HASTISlaveMux(n: Int) extends Module } } } -class HASTIXbar(nMasters: Int, addressMap: Seq[UInt=>Bool]) extends Module -{ +class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool]) + (implicit p: Parameters) extends HastiModule()(p) { val io = new Bundle { - val masters = Vec(new HASTIMasterIO, nMasters).flip - val slaves = Vec(new HASTISlaveIO, addressMap.size).flip + val masters = Vec(new HastiMasterIO, nMasters).flip + val slaves = Vec(new HastiSlaveIO, addressMap.size).flip } - val buses = List.fill(nMasters){Module(new HASTIBus(addressMap))} - val muxes = List.fill(addressMap.size){Module(new HASTISlaveMux(nMasters))} + val buses = List.fill(nMasters){Module(new HastiBus(addressMap))} + val muxes = List.fill(addressMap.size){Module(new HastiSlaveMux(nMasters))} (buses.map(b => b.io.master) zip io.masters) foreach { case (b, m) => b <> m } (muxes.map(m => m.io.out) zip io.slaves ) foreach { case (x, s) => x <> s } @@ -229,11 +232,10 @@ class HASTIXbar(nMasters: Int, addressMap: Seq[UInt=>Bool]) extends Module } } -class HASTISlaveToMaster extends Module -{ +class HastiSlaveToMaster(implicit p: Parameters) extends HastiModule()(p) { val io = new Bundle { - val in = new HASTISlaveIO - val out = new HASTIMasterIO + val in = new HastiSlaveIO + val out = new HastiMasterIO } io.out.haddr := io.in.haddr diff --git a/junctions/src/main/scala/memserdes.scala b/junctions/src/main/scala/memserdes.scala index 1e15a78c..a439c8a9 100644 --- a/junctions/src/main/scala/memserdes.scala +++ b/junctions/src/main/scala/memserdes.scala @@ -26,8 +26,8 @@ trait HasMIFParameters { val mifDataBeats = p(MIFDataBeats) } -abstract class MIFModule extends Module with HasMIFParameters -abstract class MIFBundle(implicit p: Parameters) extends ParameterizedBundle()(p) +abstract class MIFModule(implicit val p: Parameters) extends Module with HasMIFParameters +abstract class MIFBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) with HasMIFParameters trait HasMemData extends HasMIFParameters { @@ -46,9 +46,9 @@ class MemReqCmd(implicit p: Parameters) extends MIFBundle()(p) with HasMemAddr w val rw = Bool() } -class MemTag(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemTag -class MemData(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemData -class MemResp(implicit p: Parameters) extends ParameterizedBundle()(p) with HasMemData with HasMemTag +class MemTag(implicit p: Parameters) extends MIFBundle()(p) with HasMemTag +class MemData(implicit p: Parameters) extends MIFBundle()(p) with HasMemData +class MemResp(implicit p: Parameters) extends MIFBundle()(p) with HasMemData with HasMemTag class MemIO(implicit p: Parameters) extends ParameterizedBundle()(p) { val req_cmd = Decoupled(new MemReqCmd) @@ -68,7 +68,7 @@ class MemSerializedIO(w: Int)(implicit p: Parameters) extends ParameterizedBundl //override def cloneType = new MemSerializedIO(w)(p).asInstanceOf[this.type] } -class MemSerdes(w: Int)(implicit val p: Parameters) extends MIFModule +class MemSerdes(w: Int)(implicit p: Parameters) extends MIFModule { val io = new Bundle { val wide = new MemIO().flip @@ -154,7 +154,7 @@ class MemDesser(w: Int)(implicit p: Parameters) extends Module // test rig side val abits = io.wide.req_cmd.bits.toBits.getWidth val dbits = io.wide.req_data.bits.toBits.getWidth val rbits = io.wide.resp.bits.getWidth - val mifDataBeats = params(MIFDataBeats) + val mifDataBeats = p(MIFDataBeats) require(dbits >= abits && rbits >= dbits) val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w))) @@ -214,7 +214,7 @@ class MemDesser(w: Int)(implicit p: Parameters) extends Module // test rig side io.narrow.resp.bits := dataq.io.deq.bits.toBits >> (recv_cnt * UInt(w)) } -class MemIOArbiter(val arbN: Int)(implicit val p: Parameters) extends MIFModule { +class MemIOArbiter(val arbN: Int)(implicit p: Parameters) extends MIFModule { val io = new Bundle { val inner = Vec(new MemIO, arbN).flip val outer = new MemIO @@ -273,7 +273,7 @@ object MemIOMemPipeIOConverter { } } -class MemPipeIOMemIOConverter(numRequests: Int)(implicit val p: Parameters) extends MIFModule { +class MemPipeIOMemIOConverter(numRequests: Int)(implicit p: Parameters) extends MIFModule { val io = new Bundle { val cpu = new MemIO().flip val mem = new MemPipeIO diff --git a/junctions/src/main/scala/nasti.scala b/junctions/src/main/scala/nasti.scala index f26cf526..32e25228 100644 --- a/junctions/src/main/scala/nasti.scala +++ b/junctions/src/main/scala/nasti.scala @@ -4,9 +4,8 @@ package junctions import Chisel._ import scala.math.max import scala.collection.mutable.ArraySeq -import scala.collection.mutable.HashMap -case object NastiBitWidths extends Field[NastiParameters] +case object NastiKey extends Field[NastiParameters] case object NastiAddrMap extends Field[AddrMap] case object MMIOBase extends Field[BigInt] @@ -14,7 +13,7 @@ case class NastiParameters(dataBits: Int, addrBits: Int, idBits: Int) trait HasNastiParameters { implicit val p: Parameters - val external = p(NastiBitWidths) + val external = p(NastiKey) val nastiXDataBits = external.dataBits val nastiWStrobeBits = nastiXDataBits / 8 val nastiXAddrBits = external.addrBits @@ -47,8 +46,9 @@ trait HasNastiParameters { UInt(128) -> UInt(7))) } -abstract class NastiModule extends Module with HasNastiParameters -abstract class NastiBundle(implicit p: Parameters) extends ParameterizedBundle()(p) +abstract class NastiModule(implicit val p: Parameters) extends Module + with HasNastiParameters +abstract class NastiBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) with HasNastiParameters abstract class NastiChannel(implicit p: Parameters) extends NastiBundle()(p) @@ -72,7 +72,7 @@ trait HasNastiData extends HasNastiParameters { val last = Bool() } -class NastiIO(implicit p: Parameters) extends ParameterizedBundle()(p) { +class NastiIO(implicit val p: Parameters) extends ParameterizedBundle()(p) { val aw = Decoupled(new NastiWriteAddressChannel) val w = Decoupled(new NastiWriteDataChannel) val b = Decoupled(new NastiWriteResponseChannel).flip @@ -190,7 +190,7 @@ object NastiWriteResponseChannel { } } -class MemIONastiIOConverter(cacheBlockOffsetBits: Int)(implicit val p: Parameters) extends MIFModule +class MemIONastiIOConverter(cacheBlockOffsetBits: Int)(implicit p: Parameters) extends MIFModule with HasNastiParameters { val io = new Bundle { val nasti = (new NastiIO).flip @@ -245,7 +245,7 @@ class MemIONastiIOConverter(cacheBlockOffsetBits: Int)(implicit val p: Parameter } /** Arbitrate among arbN masters requesting to a single slave */ -class NastiArbiter(val arbN: Int)(implicit val p: Parameters) extends NastiModule { +class NastiArbiter(val arbN: Int)(implicit p: Parameters) extends NastiModule { val io = new Bundle { val master = Vec(new NastiIO, arbN).flip val slave = new NastiIO @@ -315,7 +315,7 @@ class NastiArbiter(val arbN: Int)(implicit val p: Parameters) extends NastiModul /** Locking RR arbiter for Nasti read data channel * Arbiter locks until last message in channel is sent */ -class NastiReadDataArbiter(arbN: Int)(implicit val p: Parameters) extends NastiModule { +class NastiReadDataArbiter(arbN: Int)(implicit p: Parameters) extends NastiModule { val io = new Bundle { val in = Vec(Decoupled(new NastiReadDataChannel), arbN).flip val out = Decoupled(new NastiReadDataChannel) @@ -356,7 +356,7 @@ class NastiReadDataArbiter(arbN: Int)(implicit val p: Parameters) extends NastiM } /** A slave that send decode error for every request it receives */ -class NastiErrorSlave(implicit val p: Parameters) extends NastiModule { +class NastiErrorSlave(implicit p: Parameters) extends NastiModule { val io = (new NastiIO).flip when (io.ar.fire()) { printf("Invalid read address %x\n", io.ar.bits.addr) } @@ -408,7 +408,7 @@ class NastiErrorSlave(implicit val p: Parameters) extends NastiModule { /** Take a single Nasti master and route its requests to various slaves * @param addrmap a sequence of base address + memory size pairs, * on for each slave interface */ -class NastiRouter(addrmap: Seq[(BigInt, BigInt)])(implicit val p: Parameters) extends NastiModule { +class NastiRouter(addrmap: Seq[(BigInt, BigInt)])(implicit p: Parameters) extends NastiModule { val nSlaves = addrmap.size val io = new Bundle { @@ -488,7 +488,7 @@ class NastiRouter(addrmap: Seq[(BigInt, BigInt)])(implicit val p: Parameters) ex * @param addrmap a sequence of base - size pairs; * size of addrmap should be nSlaves */ class NastiCrossbar(nMasters: Int, nSlaves: Int, addrmap: Seq[(BigInt, BigInt)]) - (implicit val p: Parameters) extends NastiModule { + (implicit p: Parameters) extends NastiModule { val io = new Bundle { val masters = Vec(new NastiIO, nMasters).flip val slaves = Vec(new NastiIO, nSlaves) @@ -507,112 +507,6 @@ class NastiCrossbar(nMasters: Int, nSlaves: Int, addrmap: Seq[(BigInt, BigInt)]) } } -object AddrMapConsts { - val R = 0x4 - val W = 0x2 - val X = 0x1 - val RW = R | W - val RX = R | X - val RWX = R | W | X -} - -class AddrMapProt extends Bundle { - val r = Bool() - val w = Bool() - val x = Bool() -} - -abstract class MemRegion { def size: BigInt } - -case class MemSize(size: BigInt, prot: Int) extends MemRegion - -case class MemSubmap(size: BigInt, entries: AddrMap) extends MemRegion - -//object Submap { -// def apply(size: BigInt, entries: AddrMapEntry*) = -// new MemSubmap(size, entries) -//} - -case class AddrMapEntry(name: String, start: Option[BigInt], region: MemRegion) - -case class AddrHashMapEntry(port: Int, start: BigInt, size: BigInt, prot: Int) - -class AddrMap(entries: Seq[AddrMapEntry]) extends scala.collection.IndexedSeq[AddrMapEntry] { - - def apply(index: Int): AddrMapEntry = entries(index) - - def length: Int = entries.size - - def countSlaves: Int = { - this map { entry: AddrMapEntry => entry.region match { - case MemSize(_, _) => 1 - case MemSubmap(_, submap) => submap.countSlaves - }} reduceLeft(_ + _) - } -} - -object AddrMap { - def apply(elems: AddrMapEntry*): AddrMap = new AddrMap(elems) -} - -class AddrHashMap(addrmap: AddrMap) { - val mapping = new HashMap[String, AddrHashMapEntry] - - private def genPairs(am: AddrMap): Seq[(String, AddrHashMapEntry)] = { - var ind = 0 - var base = BigInt(0) - var pairs = Seq[(String, AddrHashMapEntry)]() - am.foreach { case AddrMapEntry(name, startOpt, region) => - region match { - case MemSize(size, prot) => { - if (!startOpt.isEmpty) base = startOpt.get - pairs = (name, AddrHashMapEntry(ind, base, size, prot)) +: pairs - base += size - ind += 1 - } - case MemSubmap(size, submap) => { - if (!startOpt.isEmpty) base = startOpt.get - val subpairs = genPairs(submap).map { - case (subname, AddrHashMapEntry(subind, subbase, subsize, prot)) => - (name + ":" + subname, - AddrHashMapEntry(ind + subind, base + subbase, subsize, prot)) - } - pairs = subpairs ++ pairs - ind += subpairs.size - base += size - } - } - } - pairs - } - - for ((name, ind) <- genPairs(addrmap)) { mapping(name) = ind } - - def nEntries: Int = mapping.size - def apply(name: String): AddrHashMapEntry = mapping(name) - def get(name: String): Option[AddrHashMapEntry] = mapping.get(name) - def sortedEntries(): Seq[(String, BigInt, BigInt, Int)] = { - val arr = new Array[(String, BigInt, BigInt, Int)](mapping.size) - mapping.foreach { case (name, AddrHashMapEntry(port, base, size, prot)) => - arr(port) = (name, base, size, prot) - } - arr.toSeq - } - - def isValid(addr: UInt): Bool = { - sortedEntries().map { case (_, base, size, _) => - addr >= UInt(base) && addr < UInt(base + size) - }.reduceLeft(_ || _) - } - - def getProt(addr: UInt): AddrMapProt = { - Mux1H(sortedEntries().map { case (_, base, size, prot) => - (addr >= UInt(base) && addr < UInt(base + size), - new AddrMapProt().fromBits(Bits(prot, 3))) - }) - } -} - class NastiInterconnectIO(val nMasters: Int, val nSlaves: Int) (implicit p: Parameters) extends Bundle { /* This is a bit confusing. The interconnect is a slave to the masters and @@ -623,7 +517,7 @@ class NastiInterconnectIO(val nMasters: Int, val nSlaves: Int) new NastiInterconnectIO(nMasters, nSlaves).asInstanceOf[this.type] } -abstract class NastiInterconnect extends NastiModule { +abstract class NastiInterconnect(implicit p: Parameters) extends NastiModule()(p) { val nMasters: Int val nSlaves: Int @@ -635,7 +529,7 @@ class NastiRecursiveInterconnect( val nSlaves: Int, addrmap: AddrMap, base: BigInt = 0) - (implicit val p: Parameters) extends NastiInterconnect { + (implicit p: Parameters) extends NastiInterconnect { var lastEnd = base var slaveInd = 0 val levelSize = addrmap.size @@ -678,7 +572,7 @@ class NastiRecursiveInterconnect( } class NastiTopInterconnect(val nMasters: Int, val nSlaves: Int) - (implicit val p: Parameters) extends NastiInterconnect { + (implicit p: Parameters) extends NastiInterconnect { val temp = Module(new NastiRecursiveInterconnect(nMasters, nSlaves, p(NastiAddrMap))) temp.io.masters.zip(io.masters).foreach { case (t, i) => diff --git a/junctions/src/main/scala/package.scala b/junctions/src/main/scala/package.scala index deb7549d..3181064e 100644 --- a/junctions/src/main/scala/package.scala +++ b/junctions/src/main/scala/package.scala @@ -1 +1 @@ -package object junctions extends HASTIConstants with POCIConstants +package object junctions extends HastiConstants with PociConstants diff --git a/junctions/src/main/scala/poci.scala b/junctions/src/main/scala/poci.scala index bfd581c7..bac75966 100644 --- a/junctions/src/main/scala/poci.scala +++ b/junctions/src/main/scala/poci.scala @@ -2,13 +2,13 @@ package junctions import Chisel._ -abstract trait POCIConstants +abstract trait PociConstants { val SZ_PADDR = 32 val SZ_PDATA = 32 } -class POCIIO extends Bundle +class PociIO extends Bundle { val paddr = UInt(OUTPUT, SZ_PADDR) val pwrite = Bool(OUTPUT) @@ -20,11 +20,10 @@ class POCIIO extends Bundle val pslverr = Bool(INPUT) } -class HASTItoPOCIBridge extends Module -{ +class HastiToPociBridge(implicit p: Parameters) extends HastiModule()(p) { val io = new Bundle { - val in = new HASTISlaveIO - val out = new POCIIO + val in = new HastiSlaveIO + val out = new PociIO } val s_idle :: s_setup :: s_access :: Nil = Enum(UInt(), 3) @@ -62,11 +61,11 @@ class HASTItoPOCIBridge extends Module io.in.hresp := io.out.pslverr } -class POCIBus(amap: Seq[UInt=>Bool]) extends Module +class PociBus(amap: Seq[UInt=>Bool]) extends Module { val io = new Bundle { - val master = new POCIIO().flip - val slaves = Vec(new POCIIO, amap.size) + val master = new PociIO().flip + val slaves = Vec(new PociIO, amap.size) } val psels = PriorityEncoderOH( diff --git a/junctions/src/main/scala/smi.scala b/junctions/src/main/scala/smi.scala index 52d98779..7b9c5537 100644 --- a/junctions/src/main/scala/smi.scala +++ b/junctions/src/main/scala/smi.scala @@ -88,7 +88,7 @@ class SMIArbiter(val n: Int, val dataWidth: Int, val addrWidth: Int) } class SMIIONastiReadIOConverter(val dataWidth: Int, val addrWidth: Int) - (implicit val p: Parameters) extends NastiModule { + (implicit p: Parameters) extends NastiModule()(p) { val io = new Bundle { val ar = Decoupled(new NastiReadAddressChannel).flip val r = Decoupled(new NastiReadDataChannel) @@ -170,7 +170,7 @@ class SMIIONastiReadIOConverter(val dataWidth: Int, val addrWidth: Int) } class SMIIONastiWriteIOConverter(val dataWidth: Int, val addrWidth: Int) - (implicit val p: Parameters) extends NastiModule { + (implicit p: Parameters) extends NastiModule()(p) { val io = new Bundle { val aw = Decoupled(new NastiWriteAddressChannel).flip val w = Decoupled(new NastiWriteDataChannel).flip @@ -251,7 +251,7 @@ class SMIIONastiWriteIOConverter(val dataWidth: Int, val addrWidth: Int) /** Convert Nasti protocol to SMI protocol */ class SMIIONastiIOConverter(val dataWidth: Int, val addrWidth: Int) - (implicit val p: Parameters) extends NastiModule { + (implicit p: Parameters) extends NastiModule()(p) { val io = new Bundle { val nasti = (new NastiIO).flip val smi = new SMIIO(dataWidth, addrWidth) diff --git a/junctions/src/main/scala/util.scala b/junctions/src/main/scala/util.scala index cefe8470..62b1e189 100644 --- a/junctions/src/main/scala/util.scala +++ b/junctions/src/main/scala/util.scala @@ -6,7 +6,7 @@ object bigIntPow2 { def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) } -class ParameterizedBundle(implicit val p: Parameters) extends Bundle { +class ParameterizedBundle(implicit p: Parameters) extends Bundle { override def cloneType = this.getClass.getConstructors.head.newInstance(p).asInstanceOf[this.type] } From 166df221ad2d910e25c0f9173ffc3ba261b6c81a Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 6 Oct 2015 18:14:51 -0700 Subject: [PATCH 4/4] added HasAddrMapParameters --- junctions/src/main/scala/addrmap.scala | 27 ++++++++++++++++++++++++ junctions/src/main/scala/memserdes.scala | 9 -------- junctions/src/main/scala/nasti.scala | 6 ++---- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/junctions/src/main/scala/addrmap.scala b/junctions/src/main/scala/addrmap.scala index f37111c9..8e6dea4e 100644 --- a/junctions/src/main/scala/addrmap.scala +++ b/junctions/src/main/scala/addrmap.scala @@ -5,6 +5,33 @@ package junctions import Chisel._ import scala.collection.mutable.HashMap +case object PAddrBits extends Field[Int] +case object VAddrBits extends Field[Int] +case object PgIdxBits extends Field[Int] +case object PgLevels extends Field[Int] +case object PgLevelBits extends Field[Int] +case object ASIdBits extends Field[Int] +case object PPNBits extends Field[Int] +case object VPNBits extends Field[Int] + +case object GlobalAddrMap extends Field[AddrMap] +case object MMIOBase extends Field[BigInt] + +trait HasAddrMapParameters { + implicit val p: Parameters + + val paddrBits = p(PAddrBits) + val vaddrBits = p(VAddrBits) + val pgIdxBits = p(PgIdxBits) + val ppnBits = p(PPNBits) + val vpnBits = p(VPNBits) + val pgLevels = p(PgLevels) + val pgLevelBits = p(PgLevelBits) + val asIdBits = p(ASIdBits) + + val addrMap = new AddrHashMap(p(GlobalAddrMap)) +} + abstract class MemRegion { def size: BigInt } case class MemSize(size: BigInt, prot: Int) extends MemRegion diff --git a/junctions/src/main/scala/memserdes.scala b/junctions/src/main/scala/memserdes.scala index a439c8a9..2fc8ace1 100644 --- a/junctions/src/main/scala/memserdes.scala +++ b/junctions/src/main/scala/memserdes.scala @@ -4,15 +4,6 @@ package junctions import Chisel._ import scala.math._ -case object PAddrBits extends Field[Int] -case object VAddrBits extends Field[Int] -case object PgIdxBits extends Field[Int] -case object PgLevels extends Field[Int] -case object PgLevelBits extends Field[Int] -case object ASIdBits extends Field[Int] -case object PPNBits extends Field[Int] -case object VPNBits extends Field[Int] - case object MIFAddrBits extends Field[Int] case object MIFDataBits extends Field[Int] case object MIFTagBits extends Field[Int] diff --git a/junctions/src/main/scala/nasti.scala b/junctions/src/main/scala/nasti.scala index 32e25228..f57ff9fc 100644 --- a/junctions/src/main/scala/nasti.scala +++ b/junctions/src/main/scala/nasti.scala @@ -6,8 +6,6 @@ import scala.math.max import scala.collection.mutable.ArraySeq case object NastiKey extends Field[NastiParameters] -case object NastiAddrMap extends Field[AddrMap] -case object MMIOBase extends Field[BigInt] case class NastiParameters(dataBits: Int, addrBits: Int, idBits: Int) @@ -571,9 +569,9 @@ class NastiRecursiveInterconnect( } } -class NastiTopInterconnect(val nMasters: Int, val nSlaves: Int) +class NastiTopInterconnect(val nMasters: Int, val nSlaves: Int, addrMap: AddrMap) (implicit p: Parameters) extends NastiInterconnect { - val temp = Module(new NastiRecursiveInterconnect(nMasters, nSlaves, p(NastiAddrMap))) + val temp = Module(new NastiRecursiveInterconnect(nMasters, nSlaves, addrMap)) temp.io.masters.zip(io.masters).foreach { case (t, i) => t.ar <> i.ar