refactor NASTI to not use param; new AddrMap class
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								junctions/src/main/scala/util.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								junctions/src/main/scala/util.scala
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user