Headerless TileLinkIO and arbiters
This commit is contained in:
parent
002f1a1b39
commit
a1f04386f7
@ -60,7 +60,7 @@ class SCRIO extends HTIFBundle {
|
|||||||
class HTIFModuleIO extends HTIFBundle {
|
class HTIFModuleIO extends HTIFBundle {
|
||||||
val host = new HostIO
|
val host = new HostIO
|
||||||
val cpu = Vec.fill(nCores){new HTIFIO}.flip
|
val cpu = Vec.fill(nCores){new HTIFIO}.flip
|
||||||
val mem = new TileLinkIO
|
val mem = new HeaderlessUncachedTileLinkIO
|
||||||
val scr = new SCRIO
|
val scr = new SCRIO
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,19 +195,16 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
|
|||||||
|
|
||||||
val init_addr = addr.toUInt >> UInt(offsetBits-3)
|
val init_addr = addr.toUInt >> UInt(offsetBits-3)
|
||||||
io.mem.acquire.valid := state === state_mem_rreq || state === state_mem_wreq
|
io.mem.acquire.valid := state === state_mem_rreq || state === state_mem_wreq
|
||||||
io.mem.acquire.bits.payload := Mux(cmd === cmd_writemem,
|
io.mem.acquire.bits := Mux(cmd === cmd_writemem,
|
||||||
PutBlock(
|
PutBlock(
|
||||||
addr_block = init_addr,
|
addr_block = init_addr,
|
||||||
addr_beat = cnt,
|
addr_beat = cnt,
|
||||||
client_xact_id = UInt(0),
|
client_xact_id = UInt(0),
|
||||||
data = mem_req_data),
|
data = mem_req_data),
|
||||||
GetBlock(addr_block = init_addr))
|
GetBlock(addr_block = init_addr))
|
||||||
io.mem.acquire.bits.payload.data := mem_req_data
|
|
||||||
io.mem.finish.valid := (state === state_mem_finish) && mem_needs_ack
|
io.mem.finish.valid := (state === state_mem_finish) && mem_needs_ack
|
||||||
io.mem.finish.bits.payload.manager_xact_id := mem_gxid
|
io.mem.finish.bits.payload.manager_xact_id := mem_gxid
|
||||||
io.mem.finish.bits.header.dst := mem_gsrc
|
io.mem.finish.bits.header.dst := mem_gsrc
|
||||||
io.mem.probe.ready := Bool(false)
|
|
||||||
io.mem.release.valid := Bool(false)
|
|
||||||
|
|
||||||
val pcr_reset = UInt(pcr_RESET)(pcr_addr.getWidth-1,0)
|
val pcr_reset = UInt(pcr_RESET)(pcr_addr.getWidth-1,0)
|
||||||
val pcrReadData = Reg(Bits(width = io.cpu(0).pcr_rep.bits.getWidth))
|
val pcrReadData = Reg(Bits(width = io.cpu(0).pcr_rep.bits.getWidth))
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package uncore
|
package uncore
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
|
import scala.reflect.ClassTag
|
||||||
|
|
||||||
// Parameters exposed to the top-level design, set based on
|
// Parameters exposed to the top-level design, set based on
|
||||||
// external requirements or design space exploration
|
// external requirements or design space exploration
|
||||||
@ -290,7 +291,6 @@ object Probe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Release extends ClientToManagerChannel
|
class Release extends ClientToManagerChannel
|
||||||
with HasCacheBlockAddress
|
with HasCacheBlockAddress
|
||||||
with HasClientTransactionId
|
with HasClientTransactionId
|
||||||
@ -420,6 +420,42 @@ object TileLinkIOWrapper {
|
|||||||
def apply(tl: TileLinkIO) = tl
|
def apply(tl: TileLinkIO) = tl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This version of TileLinkIO does not contain network headers for packets
|
||||||
|
// that originate in the Clients (i.e. Acquire and Release). These headers
|
||||||
|
// are provided in the top-level that instantiates the clients and network.
|
||||||
|
// By eliding the header subbundles within the clients we can enable
|
||||||
|
// hierarchical P&R while minimizing unconnected port errors in GDS.
|
||||||
|
class HeaderlessUncachedTileLinkIO extends TLBundle {
|
||||||
|
val acquire = new DecoupledIO(new Acquire)
|
||||||
|
val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip
|
||||||
|
val finish = new DecoupledIO(new LogicalNetworkIO(new Finish))
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeaderlessTileLinkIO extends HeaderlessUncachedTileLinkIO {
|
||||||
|
val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip
|
||||||
|
val release = new DecoupledIO(new Release)
|
||||||
|
}
|
||||||
|
|
||||||
|
class HeaderlessTileLinkIOWrapper extends TLModule {
|
||||||
|
val io = new Bundle {
|
||||||
|
val in = new HeaderlessUncachedTileLinkIO().flip
|
||||||
|
val out = new HeaderlessTileLinkIO
|
||||||
|
}
|
||||||
|
io.out.acquire <> io.in.acquire
|
||||||
|
io.out.grant <> io.in.grant
|
||||||
|
io.out.finish <> io.in.finish
|
||||||
|
io.out.probe.ready := Bool(false)
|
||||||
|
io.out.release.valid := Bool(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
object HeaderlessTileLinkIOWrapper {
|
||||||
|
def apply(utl: HeaderlessUncachedTileLinkIO): HeaderlessTileLinkIO = {
|
||||||
|
val conv = Module(new HeaderlessTileLinkIOWrapper)
|
||||||
|
conv.io.in <> utl
|
||||||
|
conv.io.out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract trait HasArbiterTypes {
|
abstract trait HasArbiterTypes {
|
||||||
val arbN: Int
|
val arbN: Int
|
||||||
type ManagerSourcedWithId = ManagerToClientChannel with HasClientTransactionId
|
type ManagerSourcedWithId = ManagerToClientChannel with HasClientTransactionId
|
||||||
@ -428,6 +464,7 @@ abstract trait HasArbiterTypes {
|
|||||||
HasClientTransactionId with
|
HasClientTransactionId with
|
||||||
HasTileLinkData
|
HasTileLinkData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility functions for constructing TileLinkIO arbiters
|
// Utility functions for constructing TileLinkIO arbiters
|
||||||
abstract class TileLinkArbiterLike(val arbN: Int) extends TLModule
|
abstract class TileLinkArbiterLike(val arbN: Int) extends TLModule
|
||||||
with HasArbiterTypes {
|
with HasArbiterTypes {
|
||||||
@ -438,34 +475,65 @@ abstract class TileLinkArbiterLike(val arbN: Int) extends TLModule
|
|||||||
def managerSourcedClientXactId(in: ManagerSourcedWithId): Bits
|
def managerSourcedClientXactId(in: ManagerSourcedWithId): Bits
|
||||||
def arbIdx(in: ManagerSourcedWithId): UInt
|
def arbIdx(in: ManagerSourcedWithId): UInt
|
||||||
|
|
||||||
def hookupClientSource[M <: ClientSourcedWithIdAndData]
|
def hookupClientSource[M <: ClientSourcedWithIdAndData : ClassTag]
|
||||||
(ins: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
(clts: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
||||||
out: DecoupledIO[LogicalNetworkIO[M]]) {
|
mngr: DecoupledIO[LogicalNetworkIO[M]]) {
|
||||||
def hasData(m: LogicalNetworkIO[M]) = m.payload.hasMultibeatData()
|
def hasData(m: LogicalNetworkIO[M]) = m.payload.hasMultibeatData()
|
||||||
val arb = Module(new LockingRRArbiter(out.bits.clone, arbN, params(TLDataBeats), Some(hasData _)))
|
val arb = Module(new LockingRRArbiter(mngr.bits.clone, arbN, params(TLDataBeats), Some(hasData _)))
|
||||||
out <> arb.io.out
|
clts.zipWithIndex.zip(arb.io.in).map{ case ((req, id), arb) => {
|
||||||
ins.zipWithIndex.zip(arb.io.in).map{ case ((req,id), arb) => {
|
|
||||||
arb.valid := req.valid
|
arb.valid := req.valid
|
||||||
arb.bits := req.bits
|
arb.bits := req.bits
|
||||||
arb.bits.payload.client_xact_id := clientSourcedClientXactId(req.bits.payload, id)
|
arb.bits.payload.client_xact_id := clientSourcedClientXactId(req.bits.payload, id)
|
||||||
req.ready := arb.ready
|
req.ready := arb.ready
|
||||||
}}
|
}}
|
||||||
|
arb.io.out <> mngr
|
||||||
}
|
}
|
||||||
|
|
||||||
def hookupManagerSource[M <: ManagerSourcedWithId]
|
def hookupClientSourceHeaderless[M <: ClientSourcedWithIdAndData : ClassTag]
|
||||||
(ins: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
(clts: Seq[DecoupledIO[M]],
|
||||||
out: DecoupledIO[LogicalNetworkIO[M]]) {
|
mngr: DecoupledIO[M]) {
|
||||||
out.ready := Bool(false)
|
def hasData(m: M) = m.hasMultibeatData()
|
||||||
|
val arb = Module(new LockingRRArbiter(mngr.bits.clone, arbN, params(TLDataBeats), Some(hasData _)))
|
||||||
|
clts.zipWithIndex.zip(arb.io.in).map{ case ((req, id), arb) => {
|
||||||
|
arb.valid := req.valid
|
||||||
|
arb.bits := req.bits
|
||||||
|
arb.bits.client_xact_id := clientSourcedClientXactId(req.bits, id)
|
||||||
|
req.ready := arb.ready
|
||||||
|
}}
|
||||||
|
arb.io.out <> mngr
|
||||||
|
}
|
||||||
|
|
||||||
|
def hookupFinish[M <: LogicalNetworkIO[Finish] : ClassTag]
|
||||||
|
(clts: Seq[DecoupledIO[M]],
|
||||||
|
mngr: DecoupledIO[M]) {
|
||||||
|
val arb = Module(new RRArbiter(mngr.bits.clone, arbN))
|
||||||
|
arb.io.in zip clts map { case (arb, req) => arb <> req }
|
||||||
|
arb.io.out <> mngr
|
||||||
|
}
|
||||||
|
|
||||||
|
def hookupManagerSourceWithId[M <: ManagerSourcedWithId]
|
||||||
|
(clts: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
||||||
|
mngr: DecoupledIO[LogicalNetworkIO[M]]) {
|
||||||
|
mngr.ready := Bool(false)
|
||||||
for (i <- 0 until arbN) {
|
for (i <- 0 until arbN) {
|
||||||
ins(i).valid := Bool(false)
|
clts(i).valid := Bool(false)
|
||||||
when (arbIdx(out.bits.payload) === UInt(i)) {
|
when (arbIdx(mngr.bits.payload) === UInt(i)) {
|
||||||
ins(i).valid := out.valid
|
clts(i).valid := mngr.valid
|
||||||
out.ready := ins(i).ready
|
mngr.ready := clts(i).ready
|
||||||
}
|
}
|
||||||
ins(i).bits := out.bits
|
clts(i).bits := mngr.bits
|
||||||
ins(i).bits.payload.client_xact_id := managerSourcedClientXactId(out.bits.payload)
|
clts(i).bits.payload.client_xact_id :=
|
||||||
|
managerSourcedClientXactId(mngr.bits.payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def hookupManagerSourceBroadcast[M <: ManagerToClientChannel]
|
||||||
|
(clts: Seq[DecoupledIO[LogicalNetworkIO[M]]],
|
||||||
|
mngr: DecoupledIO[LogicalNetworkIO[M]]) {
|
||||||
|
clts.map{ _.valid := mngr.valid }
|
||||||
|
clts.map{ _.bits := mngr.bits }
|
||||||
|
mngr.ready := clts.map(_.ready).reduce(_||_)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class UncachedTileLinkIOArbiter(n: Int)
|
abstract class UncachedTileLinkIOArbiter(n: Int)
|
||||||
@ -474,13 +542,9 @@ abstract class UncachedTileLinkIOArbiter(n: Int)
|
|||||||
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
val in = Vec.fill(n){new UncachedTileLinkIO}.flip
|
||||||
val out = new UncachedTileLinkIO
|
val out = new UncachedTileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
||||||
hookupManagerSource(io.in.map(_.grant), io.out.grant)
|
hookupFinish(io.in.map(_.finish), io.out.finish)
|
||||||
|
hookupManagerSourceWithId(io.in.map(_.grant), io.out.grant)
|
||||||
val finish_arb = Module(new RRArbiter(new LogicalNetworkIO(new Finish), n))
|
|
||||||
io.out.finish <> finish_arb.io.out
|
|
||||||
finish_arb.io.in zip io.in map { case (arb, req) => arb <> req.finish }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) {
|
abstract class TileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) {
|
||||||
@ -488,18 +552,11 @@ abstract class TileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) {
|
|||||||
val in = Vec.fill(n){new TileLinkIO}.flip
|
val in = Vec.fill(n){new TileLinkIO}.flip
|
||||||
val out = new TileLinkIO
|
val out = new TileLinkIO
|
||||||
}
|
}
|
||||||
|
|
||||||
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
hookupClientSource(io.in.map(_.acquire), io.out.acquire)
|
||||||
hookupClientSource(io.in.map(_.release), io.out.release)
|
hookupClientSource(io.in.map(_.release), io.out.release)
|
||||||
hookupManagerSource(io.in.map(_.grant), io.out.grant)
|
hookupFinish(io.in.map(_.finish), io.out.finish)
|
||||||
|
hookupManagerSourceBroadcast(io.in.map(_.probe), io.out.probe)
|
||||||
io.in.map{ _.probe.valid := io.out.probe.valid }
|
hookupManagerSourceWithId(io.in.map(_.grant), io.out.grant)
|
||||||
io.in.map{ _.probe.bits := io.out.probe.bits }
|
|
||||||
io.out.probe.ready := io.in.map(_.probe.ready).reduce(_||_)
|
|
||||||
|
|
||||||
val finish_arb = Module(new RRArbiter(new LogicalNetworkIO(new Finish), n))
|
|
||||||
io.out.finish <> finish_arb.io.out
|
|
||||||
finish_arb.io.in zip io.in map { case (arb, req) => arb <> req.finish }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends the port index of the arbiter to the client_xact_id
|
// Appends the port index of the arbiter to the client_xact_id
|
||||||
|
Loading…
Reference in New Issue
Block a user