1
0

Merge branch 'dse'

Conflicts:
	src/main/scala/htif.scala
	src/main/scala/llc.scala
This commit is contained in:
Henry Cook 2014-09-06 06:16:58 -07:00
commit 5e26b4ab66
7 changed files with 338 additions and 374 deletions

View File

@ -1,75 +1,38 @@
package uncore package uncore
import Chisel._ import Chisel._
trait CacheConfig { case object CacheName extends Field[String]
def sets: Int case object NSets extends Field[Int]
def ways: Int case object NWays extends Field[Int]
def tl: TileLinkConfiguration case object BlockOffBits extends Field[Int]
def as: AddressSpaceConfiguration case object RowBits extends Field[Int]
def dm: Boolean case object WordBits extends Field[Int]
def states: Int case object Replacer extends Field[() => ReplacementPolicy]
def lines: Int
def tagbits: Int abstract trait CacheParameters extends UsesParameters {
def idxbits: Int val paddrBits = params(PAddrBits)
def offbits: Int val vaddrBits = params(VAddrBits)
def untagbits: Int val pgIdxBits = params(PgIdxBits)
def rowbits: Int val nSets = params(NSets)
val blockOffBits = params(BlockOffBits)
val idxBits = log2Up(nSets)
val untagBits = blockOffBits + idxBits
val tagBits = paddrBits - untagBits
val nWays = params(NWays)
val wayBits = log2Up(nWays)
val isDM = nWays == 1
val wordBits = params(WordBits)
val wordBytes = wordBits/8
val wordOffBits = log2Up(wordBytes)
val rowBits = params(RowBits)
val rowWords = rowBits/wordBits
val rowBytes = rowBits/8
val rowOffBits = log2Up(rowBytes)
val refillCycles = params(TLDataBits)/rowBits
} }
case class L2CacheConfig( abstract class CacheBundle extends Bundle with CacheParameters
val sets: Int, val ways: Int, abstract class CacheModule extends Module with CacheParameters
val nrpq: Int, val nsdq: Int,
val nReleaseTransactions: Int,
val nAcquireTransactions: Int,
val tl: TileLinkConfiguration,
val as: AddressSpaceConfiguration)
extends CoherenceAgentConfiguration
with CacheConfig
{
def states = tl.co.nMasterStates
def lines = sets*ways
def dm = ways == 1
def offbits = 0
def lineaddrbits = tl.addrBits
def idxbits = log2Up(sets)
def waybits = log2Up(ways)
def untagbits = offbits + idxbits
def tagbits = lineaddrbits - idxbits
def wordbits = 64
def wordbytes = wordbits/8
def wordoffbits = log2Up(wordbytes)
def rowbits = tl.dataBits
def rowbytes = rowbits/8
def rowoffbits = log2Up(rowbytes)
def refillcycles = tl.dataBits/(rowbits)
def statebits = log2Up(states)
def nTSHRs = nReleaseTransactions + nAcquireTransactions
require(states > 0)
require(isPow2(sets))
require(isPow2(ways)) // TODO: relax this
require(refillcycles == 1) //TODO: relax this?
}
abstract trait CacheBundle extends Bundle {
implicit val cacheconf: CacheConfig
override def clone = this.getClass.getConstructors.head.newInstance(cacheconf).asInstanceOf[this.type]
}
abstract trait L2CacheBundle extends Bundle {
implicit val l2cacheconf: L2CacheConfig
override def clone = this.getClass.getConstructors.head.newInstance(l2cacheconf).asInstanceOf[this.type]
}
trait HasL2Id extends L2CacheBundle {
val id = UInt(width = log2Up(l2cacheconf.nTSHRs))
}
trait HasL2InternalRequestState extends L2CacheBundle {
val tag_match = Bool()
val old_meta = new L2Metadata
val way_en = Bits(width = l2cacheconf.ways)
}
abstract class ReplacementPolicy { abstract class ReplacementPolicy {
def way: UInt def way: UInt
@ -77,54 +40,53 @@ abstract class ReplacementPolicy {
def hit: Unit def hit: Unit
} }
class RandomReplacement(implicit val cacheconf: CacheConfig) extends ReplacementPolicy { class RandomReplacement(ways: Int) extends ReplacementPolicy {
private val replace = Bool() private val replace = Bool()
replace := Bool(false) replace := Bool(false)
val lfsr = LFSR16(replace) val lfsr = LFSR16(replace)
def way = if(cacheconf.dm) UInt(0) else lfsr(log2Up(cacheconf.ways)-1,0) def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0)
def miss = replace := Bool(true) def miss = replace := Bool(true)
def hit = {} def hit = {}
} }
abstract class Metadata(implicit val cacheconf: CacheConfig) extends CacheBundle { abstract class Metadata extends CacheBundle {
val tag = Bits(width = cacheconf.tagbits) val tag = Bits(width = tagBits)
val coh: CoherenceMetadata val coh: CoherenceMetadata
} }
class MetaReadReq(implicit val cacheconf: CacheConfig) extends CacheBundle { class MetaReadReq extends CacheBundle {
val idx = Bits(width = cacheconf.idxbits) val idx = Bits(width = idxBits)
} }
class MetaWriteReq[T <: Metadata](gen: T)(implicit conf: CacheConfig) extends MetaReadReq { class MetaWriteReq[T <: Metadata](gen: T) extends MetaReadReq {
val way_en = Bits(width = conf.ways) val way_en = Bits(width = nWays)
val data = gen.clone val data = gen.clone
override def clone = new MetaWriteReq(gen)(conf).asInstanceOf[this.type] override def clone = new MetaWriteReq(gen).asInstanceOf[this.type]
} }
class MetadataArray[T <: Metadata](makeRstVal: () => T)(implicit conf: CacheConfig) extends Module { class MetadataArray[T <: Metadata](makeRstVal: () => T) extends CacheModule {
implicit val tl = conf.tl
val rstVal = makeRstVal() val rstVal = makeRstVal()
val io = new Bundle { val io = new Bundle {
val read = Decoupled(new MetaReadReq).flip val read = Decoupled(new MetaReadReq).flip
val write = Decoupled(new MetaWriteReq(rstVal.clone)).flip val write = Decoupled(new MetaWriteReq(rstVal.clone)).flip
val resp = Vec.fill(conf.ways){rstVal.clone.asOutput} val resp = Vec.fill(nWays){rstVal.clone.asOutput}
} }
val metabits = rstVal.getWidth val metabits = rstVal.getWidth
val rst_cnt = Reg(init=UInt(0, log2Up(conf.sets+1))) val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1)))
val rst = rst_cnt < UInt(conf.sets) val rst = rst_cnt < UInt(nSets)
val waddr = Mux(rst, rst_cnt, io.write.bits.idx) val waddr = Mux(rst, rst_cnt, io.write.bits.idx)
val wdata = Mux(rst, rstVal, io.write.bits.data).toBits val wdata = Mux(rst, rstVal, io.write.bits.data).toBits
val wmask = Mux(rst, SInt(-1), io.write.bits.way_en) val wmask = Mux(rst, SInt(-1), io.write.bits.way_en)
when (rst) { rst_cnt := rst_cnt+UInt(1) } when (rst) { rst_cnt := rst_cnt+UInt(1) }
val tag_arr = Mem(UInt(width = metabits*conf.ways), conf.sets, seqRead = true) val tag_arr = Mem(UInt(width = metabits*nWays), nSets, seqRead = true)
when (rst || io.write.valid) { when (rst || io.write.valid) {
tag_arr.write(waddr, Fill(conf.ways, wdata), FillInterleaved(metabits, wmask)) tag_arr.write(waddr, Fill(nWays, wdata), FillInterleaved(metabits, wmask))
} }
val tags = tag_arr(RegEnable(io.read.bits.idx, io.read.valid)) val tags = tag_arr(RegEnable(io.read.bits.idx, io.read.valid))
for (w <- 0 until conf.ways) { for (w <- 0 until nWays) {
val m = tags(metabits*(w+1)-1, metabits*w) val m = tags(metabits*(w+1)-1, metabits*w)
io.resp(w) := rstVal.clone.fromBits(m) io.resp(w) := rstVal.clone.fromBits(m)
} }
@ -133,62 +95,68 @@ class MetadataArray[T <: Metadata](makeRstVal: () => T)(implicit conf: CacheConf
io.write.ready := !rst io.write.ready := !rst
} }
abstract trait L2HellaCacheParameters extends CacheParameters
with CoherenceAgentParameters
abstract class L2HellaCacheBundle extends Bundle with L2HellaCacheParameters
abstract class L2HellaCacheModule extends Module with L2HellaCacheParameters
trait HasL2Id extends Bundle with CoherenceAgentParameters {
val id = UInt(width = log2Up(nTransactors))
}
trait HasL2InternalRequestState extends L2HellaCacheBundle {
val tag_match = Bool()
val old_meta = new L2Metadata
val way_en = Bits(width = nWays)
}
object L2Metadata { object L2Metadata {
def apply(tag: Bits, coh: MasterMetadata)(implicit conf: L2CacheConfig) = { def apply(tag: Bits, coh: MasterMetadata) = {
val meta = new L2Metadata val meta = new L2Metadata
meta.tag := tag meta.tag := tag
meta.coh := coh meta.coh := coh
meta meta
} }
} }
class L2Metadata(implicit val l2cacheconf: L2CacheConfig) extends Metadata class L2Metadata extends Metadata with L2HellaCacheParameters {
with L2CacheBundle { val coh = co.masterMetadataOnFlush.clone
val coh = l2cacheconf.tl.co.masterMetadataOnFlush.clone
} }
/* class L2MetaReadReq extends MetaReadReq with HasL2Id {
class L3Metadata(implicit conf: L3CacheConfig) extends Metadata val tag = Bits(width = tagBits)
with L3CacheBundle {
val coh = MixedMetaData(conf.innerTL.co, conf.outerTL.co) ?
}
*/
class L2MetaReadReq(implicit val l2cacheconf: L2CacheConfig) extends MetaReadReq
with HasL2Id {
val tag = Bits(width = l2cacheconf.tagbits)
} }
class L2MetaWriteReq(implicit val l2cacheconf: L2CacheConfig) extends MetaWriteReq[L2Metadata](new L2Metadata) class L2MetaWriteReq extends MetaWriteReq[L2Metadata](new L2Metadata)
with HasL2Id with HasL2Id
class L2MetaResp(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle class L2MetaResp extends L2HellaCacheBundle
with HasL2Id with HasL2Id
with HasL2InternalRequestState with HasL2InternalRequestState
class L2MetadataArray(implicit conf: L2CacheConfig) extends Module { class L2MetadataArray extends L2HellaCacheModule {
implicit val tl = conf.tl
val io = new Bundle { val io = new Bundle {
val read = Decoupled(new L2MetaReadReq).flip val read = Decoupled(new L2MetaReadReq).flip
val write = Decoupled(new L2MetaWriteReq).flip val write = Decoupled(new L2MetaWriteReq).flip
val resp = Valid(new L2MetaResp) val resp = Valid(new L2MetaResp)
} }
val meta = Module(new MetadataArray(() => L2Metadata(UInt(0), tl.co.masterMetadataOnFlush))) val meta = Module(new MetadataArray(() => L2Metadata(UInt(0), co.masterMetadataOnFlush)))
meta.io.read <> io.read meta.io.read <> io.read
meta.io.write <> io.write meta.io.write <> io.write
val s1_clk_en = Reg(next = io.read.fire()) val s1_clk_en = Reg(next = io.read.fire())
val s1_tag = RegEnable(io.read.bits.tag, io.read.valid) val s1_tag = RegEnable(io.read.bits.tag, io.read.valid)
val s1_id = RegEnable(io.read.bits.id, io.read.valid) val s1_id = RegEnable(io.read.bits.id, io.read.valid)
def wayMap[T <: Data](f: Int => T) = Vec((0 until conf.ways).map(f)) def wayMap[T <: Data](f: Int => T) = Vec((0 until nWays).map(f))
val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === s1_tag) val s1_tag_eq_way = wayMap((w: Int) => meta.io.resp(w).tag === s1_tag)
val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && tl.co.isValid(meta.io.resp(w).coh)).toBits val s1_tag_match_way = wayMap((w: Int) => s1_tag_eq_way(w) && co.isValid(meta.io.resp(w).coh)).toBits
val s2_tag_match_way = RegEnable(s1_tag_match_way, s1_clk_en) val s2_tag_match_way = RegEnable(s1_tag_match_way, s1_clk_en)
val s2_tag_match = s2_tag_match_way.orR val s2_tag_match = s2_tag_match_way.orR
val s2_hit_coh = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEnable(meta.io.resp(w).coh, s1_clk_en))) val s2_hit_coh = Mux1H(s2_tag_match_way, wayMap((w: Int) => RegEnable(meta.io.resp(w).coh, s1_clk_en)))
//val s2_hit = s2_tag_match && tl.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === tl.co.newStateOnHit(s2_req.cmd, s2_hit_state) //val s2_hit = s2_tag_match && tl.co.isHit(s2_req.cmd, s2_hit_state) && s2_hit_state === tl.co.newStateOnHit(s2_req.cmd, s2_hit_state)
val replacer = new RandomReplacement val replacer = params(Replacer)()
val s1_replaced_way_en = UIntToOH(replacer.way) val s1_replaced_way_en = UIntToOH(replacer.way)
val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en)) val s2_replaced_way_en = UIntToOH(RegEnable(replacer.way, s1_clk_en))
val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) => val s2_repl_meta = Mux1H(s2_replaced_way_en, wayMap((w: Int) =>
@ -203,23 +171,21 @@ class L2MetadataArray(implicit conf: L2CacheConfig) extends Module {
io.resp.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en) io.resp.bits.way_en := Mux(s2_tag_match, s2_tag_match_way, s2_replaced_way_en)
} }
class L2DataReadReq(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle class L2DataReadReq extends L2HellaCacheBundle with HasL2Id {
with HasL2Id { val way_en = Bits(width = nWays)
val way_en = Bits(width = l2cacheconf.ways) val addr = Bits(width = params(TLAddrBits))
val addr = Bits(width = l2cacheconf.tl.addrBits)
} }
class L2DataWriteReq(implicit l2cacheconf: L2CacheConfig) extends L2DataReadReq { class L2DataWriteReq extends L2DataReadReq {
val wmask = Bits(width = l2cacheconf.tl.writeMaskBits) val wmask = Bits(width = params(TLWriteMaskBits))
val data = Bits(width = l2cacheconf.tl.dataBits) val data = Bits(width = params(TLDataBits))
} }
class L2DataResp(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle class L2DataResp extends Bundle with HasL2Id {
with HasL2Id { val data = Bits(width = params(TLDataBits))
val data = Bits(width = l2cacheconf.tl.dataBits)
} }
class L2DataArray(implicit conf: L2CacheConfig) extends Module { class L2DataArray extends L2HellaCacheModule {
val io = new Bundle { val io = new Bundle {
val read = Decoupled(new L2DataReadReq).flip val read = Decoupled(new L2DataReadReq).flip
val write = Decoupled(new L2DataWriteReq).flip val write = Decoupled(new L2DataWriteReq).flip
@ -228,9 +194,9 @@ class L2DataArray(implicit conf: L2CacheConfig) extends Module {
val waddr = io.write.bits.addr val waddr = io.write.bits.addr
val raddr = io.read.bits.addr val raddr = io.read.bits.addr
val wmask = FillInterleaved(conf.wordbits, io.write.bits.wmask) val wmask = FillInterleaved(wordBits, io.write.bits.wmask)
val resp = (0 until conf.ways).map { w => val resp = (0 until nWays).map { w =>
val array = Mem(Bits(width=conf.rowbits), conf.sets*conf.refillcycles, seqRead = true) val array = Mem(Bits(width=params(RowBits)), nSets*refillCycles, seqRead = true)
when (io.write.bits.way_en(w) && io.write.valid) { when (io.write.bits.way_en(w) && io.write.valid) {
array.write(waddr, io.write.bits.data, wmask) array.write(waddr, io.write.bits.data, wmask)
} }
@ -244,23 +210,11 @@ class L2DataArray(implicit conf: L2CacheConfig) extends Module {
io.write.ready := Bool(true) io.write.ready := Bool(true)
} }
class L2InternalAcquire(implicit val l2cacheconf: L2CacheConfig) extends Acquire()(l2cacheconf.tl) class L2HellaCache(bankId: Int) extends CoherenceAgent with L2HellaCacheParameters {
with HasL2InternalRequestState
class L2InternalRelease(implicit val l2cacheconf: L2CacheConfig) extends Release()(l2cacheconf.tl) require(isPow2(nSets))
with HasL2InternalRequestState require(isPow2(nWays))
require(refillCycles == 1)
class InternalTileLinkIO(implicit val l2cacheconf: L2CacheConfig) extends L2CacheBundle {
implicit val (tl, ln) = (l2cacheconf.tl, l2cacheconf.tl.ln)
val acquire = new DecoupledIO(new LogicalNetworkIO(new L2InternalAcquire))
val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip
val release = new DecoupledIO(new LogicalNetworkIO(new L2InternalRelease))
val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip
val finish = new DecoupledIO(new LogicalNetworkIO(new Finish))
}
class L2HellaCache(bankId: Int)(implicit conf: L2CacheConfig) extends CoherenceAgent {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val tshrfile = Module(new TSHRFile(bankId)) val tshrfile = Module(new TSHRFile(bankId))
val meta = Module(new L2MetadataArray) val meta = Module(new L2MetadataArray)
@ -278,12 +232,11 @@ class L2HellaCache(bankId: Int)(implicit conf: L2CacheConfig) extends CoherenceA
} }
class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module { class TSHRFile(bankId: Int) extends L2HellaCacheModule {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val io = new Bundle { val io = new Bundle {
val inner = (new TileLinkIO).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO val outer = new UncachedTileLinkIO
val incoherent = Vec.fill(ln.nClients){Bool()}.asInput val incoherent = Vec.fill(nClients){Bool()}.asInput
val meta_read = Decoupled(new L2MetaReadReq) val meta_read = Decoupled(new L2MetaReadReq)
val meta_write = Decoupled(new L2MetaWriteReq) val meta_write = Decoupled(new L2MetaWriteReq)
val meta_resp = Valid(new L2MetaResp).flip val meta_resp = Valid(new L2MetaResp).flip
@ -305,10 +258,9 @@ class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
} }
// Create TSHRs for outstanding transactions // Create TSHRs for outstanding transactions
val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions val trackerList = (0 until nReleaseTransactors).map { id =>
val trackerList = (0 until conf.nReleaseTransactions).map { id =>
Module(new L2VoluntaryReleaseTracker(id, bankId)) Module(new L2VoluntaryReleaseTracker(id, bankId))
} ++ (conf.nReleaseTransactions until nTrackers).map { id => } ++ (nReleaseTransactors until nTransactors).map { id =>
Module(new L2AcquireTracker(id, bankId)) Module(new L2AcquireTracker(id, bankId))
} }
@ -373,12 +325,11 @@ class TSHRFile(bankId: Int)(implicit conf: L2CacheConfig) extends Module {
} }
abstract class L2XactTracker()(implicit conf: L2CacheConfig) extends Module { abstract class L2XactTracker extends L2HellaCacheModule {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
val io = new Bundle { val io = new Bundle {
val inner = (new TileLinkIO).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO val outer = new UncachedTileLinkIO
val tile_incoherent = Bits(INPUT, ln.nClients) val tile_incoherent = Bits(INPUT, nClients)
val has_acquire_conflict = Bool(OUTPUT) val has_acquire_conflict = Bool(OUTPUT)
val has_release_conflict = Bool(OUTPUT) val has_release_conflict = Bool(OUTPUT)
val meta_read = Decoupled(new L2MetaReadReq) val meta_read = Decoupled(new L2MetaReadReq)
@ -397,11 +348,11 @@ abstract class L2XactTracker()(implicit conf: L2CacheConfig) extends Module {
} }
class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig) extends L2XactTracker()(conf) { class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
val s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(UInt(), 4) val s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(UInt(), 4)
val state = Reg(init=s_idle) val state = Reg(init=s_idle)
val xact = Reg{ new Release } val xact = Reg{ new Release }
val init_client_id = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_client_id = Reg(init=UInt(0, width = log2Up(nClients)))
val new_meta = Reg(new L2Metadata) val new_meta = Reg(new L2Metadata)
val incoming_rel = io.inner.release.bits val incoming_rel = io.inner.release.bits
@ -460,16 +411,16 @@ Mux(co.messageHasData(xact), s_mem, s_ack)
} }
} }
class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig) extends L2XactTracker()(conf) { class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
val s_idle :: s_probe :: s_mem_read :: s_mem_write :: s_make_grant :: s_busy :: Nil = Enum(UInt(), 6) val s_idle :: s_probe :: s_mem_read :: s_mem_write :: s_make_grant :: s_busy :: Nil = Enum(UInt(), 6)
val state = Reg(init=s_idle) val state = Reg(init=s_idle)
val xact = Reg{ new Acquire } val xact = Reg{ new Acquire }
val init_client_id = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_client_id = Reg(init=UInt(0, width = log2Up(nClients)))
//TODO: Will need id reg for merged release xacts //TODO: Will need id reg for merged release xacts
val init_sharer_cnt = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_sharer_cnt = Reg(init=UInt(0, width = log2Up(nClients)))
val release_count = if (ln.nClients == 1) UInt(0) else Reg(init=UInt(0, width = log2Up(ln.nClients))) val release_count = if(nClients == 1) UInt(0) else Reg(init=UInt(0, width = log2Up(nClients)))
val probe_flags = Reg(init=Bits(0, width = ln.nClients)) val probe_flags = Reg(init=Bits(0, width = nClients))
val curr_p_id = PriorityEncoder(probe_flags) val curr_p_id = PriorityEncoder(probe_flags)
val pending_outer_write = co.messageHasData(xact) val pending_outer_write = co.messageHasData(xact)
@ -480,12 +431,12 @@ class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig
xact.addr, UInt(trackerId), c_rel.payload.data) xact.addr, UInt(trackerId), c_rel.payload.data)
val outer_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId)) val outer_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId))
val probe_initial_flags = Bits(width = ln.nClients) val probe_initial_flags = Bits(width = nClients)
probe_initial_flags := Bits(0) probe_initial_flags := Bits(0)
if (ln.nClients > 1) { if (nClients > 1) {
// issue self-probes for uncached read xacts to facilitate I$ coherence // issue self-probes for uncached read xacts to facilitate I$ coherence
val probe_self = Bool(true) //co.needsSelfProbe(io.inner.acquire.bits.payload) val probe_self = Bool(true) //co.needsSelfProbe(io.inner.acquire.bits.payload)
val myflag = Mux(probe_self, Bits(0), UIntToOH(c_acq.header.src(log2Up(ln.nClients)-1,0))) val myflag = Mux(probe_self, Bits(0), UIntToOH(c_acq.header.src(log2Up(nClients)-1,0)))
probe_initial_flags := ~(io.tile_incoherent | myflag) probe_initial_flags := ~(io.tile_incoherent | myflag)
} }
@ -501,7 +452,7 @@ class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig
io.inner.probe.valid := Bool(false) io.inner.probe.valid := Bool(false)
io.inner.probe.bits.header.src := UInt(bankId) io.inner.probe.bits.header.src := UInt(bankId)
io.inner.probe.bits.header.dst := curr_p_id io.inner.probe.bits.header.dst := curr_p_id
io.inner.probe.bits.payload := Probe(co.getProbeType(xact.a_type, conf.tl.co.masterMetadataOnFlush), io.inner.probe.bits.payload := Probe(co.getProbeType(xact.a_type, co.masterMetadataOnFlush),
xact.addr, xact.addr,
UInt(trackerId)) UInt(trackerId))
@ -525,9 +476,9 @@ class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig
when( io.inner.acquire.valid ) { when( io.inner.acquire.valid ) {
xact := c_acq.payload xact := c_acq.payload
init_client_id := c_acq.header.src init_client_id := c_acq.header.src
init_sharer_cnt := UInt(ln.nClients) // TODO: Broadcast only init_sharer_cnt := UInt(nClients) // TODO: Broadcast only
probe_flags := probe_initial_flags probe_flags := probe_initial_flags
if(ln.nClients > 1) { if(nClients > 1) {
release_count := PopCount(probe_initial_flags) release_count := PopCount(probe_initial_flags)
state := Mux(probe_initial_flags.orR, s_probe, state := Mux(probe_initial_flags.orR, s_probe,
Mux(needs_outer_write, s_mem_write, Mux(needs_outer_write, s_mem_write,
@ -550,7 +501,7 @@ class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig
io.outer.acquire.bits.payload := outer_write_rel io.outer.acquire.bits.payload := outer_write_rel
when(io.outer.acquire.ready) { when(io.outer.acquire.ready) {
io.inner.release.ready := Bool(true) io.inner.release.ready := Bool(true)
if(ln.nClients > 1) release_count := release_count - UInt(1) if(nClients > 1) release_count := release_count - UInt(1)
when(release_count === UInt(1)) { when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write, state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant)) Mux(pending_outer_read, s_mem_read, s_make_grant))
@ -558,7 +509,7 @@ class L2AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: L2CacheConfig
} }
} .otherwise { } .otherwise {
io.inner.release.ready := Bool(true) io.inner.release.ready := Bool(true)
if(ln.nClients > 1) release_count := release_count - UInt(1) if(nClients > 1) release_count := release_count - UInt(1)
when(release_count === UInt(1)) { when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write, state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant)) Mux(pending_outer_read, s_mem_read, s_make_grant))

View File

@ -4,7 +4,23 @@ import Chisel._
import Node._ import Node._
import uncore._ import uncore._
class HostIO(val w: Int) extends Bundle case object HTIFWidth extends Field[Int]
case object HTIFNSCR extends Field[Int]
case object HTIFOffsetBits extends Field[Int]
case object HTIFNCores extends Field[Int]
abstract trait HTIFParameters extends UsesParameters {
val dataBits = params(TLDataBits)
val co = params(TLCoherence)
val w = params(HTIFWidth)
val nSCR = params(HTIFNSCR)
val offsetBits = params(HTIFOffsetBits)
val nCores = params(HTIFNCores)
}
abstract class HTIFBundle extends Bundle with HTIFParameters
class HostIO extends HTIFBundle
{ {
val clk = Bool(OUTPUT) val clk = Bool(OUTPUT)
val clk_edge = Bool(OUTPUT) val clk_edge = Bool(OUTPUT)
@ -20,43 +36,40 @@ class PCRReq extends Bundle
val data = Bits(width = 64) val data = Bits(width = 64)
} }
class HTIFIO(ntiles: Int) extends Bundle class HTIFIO extends HTIFBundle {
{
val reset = Bool(INPUT) val reset = Bool(INPUT)
val id = UInt(INPUT, log2Up(ntiles)) val id = UInt(INPUT, log2Up(nCores))
val pcr_req = Decoupled(new PCRReq).flip val pcr_req = Decoupled(new PCRReq).flip
val pcr_rep = Decoupled(Bits(width = 64)) val pcr_rep = Decoupled(Bits(width = 64))
val ipi_req = Decoupled(Bits(width = log2Up(ntiles))) val ipi_req = Decoupled(Bits(width = log2Up(nCores)))
val ipi_rep = Decoupled(Bool()).flip val ipi_rep = Decoupled(Bool()).flip
val debug_stats_pcr = Bool(OUTPUT) val debug_stats_pcr = Bool(OUTPUT)
// wired directly to stats register // wired directly to stats register
// expected to be used to quickly indicate to testbench to do logging b/c in 'interesting' work // expected to be used to quickly indicate to testbench to do logging b/c in 'interesting' work
} }
class SCRIO(n: Int) extends Bundle class SCRIO extends HTIFBundle {
{ val rdata = Vec.fill(nSCR){Bits(INPUT, 64)}
val rdata = Vec.fill(n){Bits(INPUT, 64)}
val wen = Bool(OUTPUT) val wen = Bool(OUTPUT)
val waddr = UInt(OUTPUT, log2Up(n)) val waddr = UInt(OUTPUT, log2Up(nSCR))
val wdata = Bits(OUTPUT, 64) val wdata = Bits(OUTPUT, 64)
} }
class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: TileLinkConfiguration) extends Module class HTIFModuleIO extends HTIFBundle {
{ val host = new HostIO
implicit val (ln, co) = (conf.ln, conf.co) val cpu = Vec.fill(nCores){new HTIFIO}.flip
val nTiles = ln.nClients-1 // This HTIF is itself a TileLink client
val io = new Bundle {
val host = new HostIO(w)
val cpu = Vec.fill(nTiles){new HTIFIO(nTiles).flip}
val mem = new TileLinkIO val mem = new TileLinkIO
val scr = new SCRIO(nSCR) val scr = new SCRIO
} }
class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
val io = new HTIFModuleIO
io.host.debug_stats_pcr := io.cpu.map(_.debug_stats_pcr).reduce(_||_) io.host.debug_stats_pcr := io.cpu.map(_.debug_stats_pcr).reduce(_||_)
// system is 'interesting' if any tile is 'interesting' // system is 'interesting' if any tile is 'interesting'
val short_request_bits = 64 val short_request_bits = 64
val long_request_bits = short_request_bits + conf.dataBits val long_request_bits = short_request_bits + dataBits
require(short_request_bits % w == 0) require(short_request_bits % w == 0)
val rx_count_w = 13 + log2Up(64) - log2Up(w) // data size field is 12 bits val rx_count_w = 13 + log2Up(64) - log2Up(w) // data size field is 12 bits
@ -92,7 +105,7 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(UInt(), 6) val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(UInt(), 6)
val pcr_addr = addr(io.cpu(0).pcr_req.bits.addr.getWidth-1, 0) val pcr_addr = addr(io.cpu(0).pcr_req.bits.addr.getWidth-1, 0)
val pcr_coreid = addr(log2Up(nTiles)-1+20+1,20) val pcr_coreid = addr(log2Up(nCores)-1+20+1,20)
val pcr_wdata = packet_ram(0) val pcr_wdata = packet_ram(0)
val bad_mem_packet = size(offsetBits-1-3,0).orR || addr(offsetBits-1-3,0).orR val bad_mem_packet = size(offsetBits-1-3,0).orR || addr(offsetBits-1-3,0).orR
@ -114,13 +127,13 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
val mem_acked = Reg(init=Bool(false)) val mem_acked = Reg(init=Bool(false))
val mem_gxid = Reg(Bits()) val mem_gxid = Reg(Bits())
val mem_gsrc = Reg(UInt(width = conf.ln.idBits)) val mem_gsrc = Reg(UInt())
val mem_needs_ack = Reg(Bool()) val mem_needs_ack = Reg(Bool())
when (io.mem.grant.valid) { when (io.mem.grant.valid) {
mem_acked := Bool(true) mem_acked := Bool(true)
mem_gxid := io.mem.grant.bits.payload.master_xact_id mem_gxid := io.mem.grant.bits.payload.master_xact_id
mem_gsrc := io.mem.grant.bits.header.src mem_gsrc := io.mem.grant.bits.header.src
mem_needs_ack := conf.co.requiresAckForGrant(io.mem.grant.bits.payload.g_type) mem_needs_ack := co.requiresAckForGrant(io.mem.grant.bits.payload.g_type)
} }
io.mem.grant.ready := Bool(true) io.mem.grant.ready := Bool(true)
@ -168,8 +181,8 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
} }
var mem_req_data: Bits = null var mem_req_data: Bits = null
for (i <- 0 until conf.dataBits/short_request_bits) { for (i <- 0 until dataBits/short_request_bits) {
val idx = UInt(i, log2Up(conf.dataBits/short_request_bits)) val idx = UInt(i, log2Up(dataBits/short_request_bits))
when (state === state_mem_rresp && io.mem.grant.valid) { when (state === state_mem_rresp && io.mem.grant.valid) {
packet_ram(idx) := io.mem.grant.bits.payload.data((i+1)*short_request_bits-1, i*short_request_bits) packet_ram(idx) := io.mem.grant.bits.payload.data((i+1)*short_request_bits-1, i*short_request_bits)
} }
@ -184,7 +197,7 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
acq_q.io.deq.ready := io.mem.acquire.ready acq_q.io.deq.ready := io.mem.acquire.ready
io.mem.acquire.bits.payload := acq_q.io.deq.bits io.mem.acquire.bits.payload := acq_q.io.deq.bits
io.mem.acquire.bits.payload.data := mem_req_data io.mem.acquire.bits.payload.data := mem_req_data
io.mem.acquire.bits.header.src := UInt(conf.ln.nClients) // By convention HTIF is the client with the largest id io.mem.acquire.bits.header.src := UInt(params(LNClients)) // By convention HTIF is the client with the largest id
io.mem.acquire.bits.header.dst := UInt(0) // DNC; Overwritten outside module io.mem.acquire.bits.header.dst := UInt(0) // DNC; Overwritten outside module
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.master_xact_id := mem_gxid io.mem.finish.bits.payload.master_xact_id := mem_gxid
@ -194,7 +207,7 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
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))
for (i <- 0 until nTiles) { for (i <- 0 until nCores) {
val my_reset = Reg(init=Bool(true)) val my_reset = Reg(init=Bool(true))
val my_ipi = Reg(init=Bool(false)) val my_ipi = Reg(init=Bool(false))
@ -211,7 +224,7 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
} }
cpu.ipi_rep.valid := my_ipi cpu.ipi_rep.valid := my_ipi
cpu.ipi_req.ready := Bool(true) cpu.ipi_req.ready := Bool(true)
for (j <- 0 until nTiles) { for (j <- 0 until nCores) {
when (io.cpu(j).ipi_req.valid && io.cpu(j).ipi_req.bits === UInt(i)) { when (io.cpu(j).ipi_req.valid && io.cpu(j).ipi_req.bits === UInt(i)) {
my_ipi := Bool(true) my_ipi := Bool(true)
} }
@ -239,8 +252,8 @@ class HTIF(w: Int, pcr_RESET: Int, nSCR: Int, offsetBits: Int)(implicit conf: Ti
val scr_rdata = Vec.fill(io.scr.rdata.size){Bits(width = 64)} val scr_rdata = Vec.fill(io.scr.rdata.size){Bits(width = 64)}
for (i <- 0 until scr_rdata.size) for (i <- 0 until scr_rdata.size)
scr_rdata(i) := io.scr.rdata(i) scr_rdata(i) := io.scr.rdata(i)
scr_rdata(0) := UInt(nTiles) scr_rdata(0) := UInt(nCores)
scr_rdata(1) := UInt((BigInt(conf.dataBits/8) << acq_q.io.enq.bits.addr.getWidth) >> 20) scr_rdata(1) := UInt((BigInt(dataBits/8) << acq_q.io.enq.bits.addr.getWidth) >> 20)
io.scr.wen := Bool(false) io.scr.wen := Bool(false)
io.scr.wdata := pcr_wdata io.scr.wdata := pcr_wdata

View File

@ -77,26 +77,26 @@ class BigMem[T <: Data](n: Int, preLatency: Int, postLatency: Int, leaf: Mem[UIn
io.rdata := Mux1H(rdataSel, rdataDeep) io.rdata := Mux1H(rdataSel, rdataDeep)
} }
class LLCDataReq(ways: Int)(implicit conf: MemoryIFConfiguration) extends MemReqCmd class LLCDataReq(ways: Int) extends MemReqCmd
{ {
val way = UInt(width = log2Up(ways)) val way = UInt(width = log2Up(ways))
val isWriteback = Bool() val isWriteback = Bool()
override def clone = new LLCDataReq(ways)(conf).asInstanceOf[this.type] override def clone = new LLCDataReq(ways).asInstanceOf[this.type]
} }
class LLCTagReq(ways: Int)(implicit val conf: MemoryIFConfiguration) extends HasMemAddr class LLCTagReq(ways: Int) extends HasMemAddr
{ {
val way = UInt(width = log2Up(ways)) val way = UInt(width = log2Up(ways))
override def clone = new LLCTagReq(ways)(conf).asInstanceOf[this.type] override def clone = new LLCTagReq(ways).asInstanceOf[this.type]
} }
class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int)(implicit conf: MemoryIFConfiguration) extends Module class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int) extends Module
{ {
val io = new Bundle { val io = new Bundle {
val cpu = Decoupled(new MemReqCmd).flip val cpu = Decoupled(new MemReqCmd).flip
val repl_way = UInt(INPUT, log2Up(ways)) val repl_way = UInt(INPUT, log2Up(ways))
val repl_dirty = Bool(INPUT) val repl_dirty = Bool(INPUT)
val repl_tag = UInt(INPUT, conf.addrBits - log2Up(sets)) val repl_tag = UInt(INPUT, params(MIFAddrBits) - log2Up(sets))
val data = Decoupled(new LLCDataReq(ways)) val data = Decoupled(new LLCDataReq(ways))
val tag = Decoupled(new LLCTagReq(ways)) val tag = Decoupled(new LLCTagReq(ways))
val mem = new MemPipeIO val mem = new MemPipeIO
@ -105,14 +105,14 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int)(im
} }
class MSHR extends Bundle { class MSHR extends Bundle {
val addr = UInt(width = conf.addrBits) val addr = UInt(width = params(MIFAddrBits))
val way = UInt(width = log2Up(ways)) val way = UInt(width = log2Up(ways))
val tag = io.cpu.bits.tag.clone val tag = io.cpu.bits.tag.clone
val refilled = Bool() val refilled = Bool()
val refillCount = UInt(width = log2Up(refill_cycles)) val refillCount = UInt(width = log2Up(refill_cycles))
val requested = Bool() val requested = Bool()
val old_dirty = Bool() val old_dirty = Bool()
val old_tag = UInt(width = conf.addrBits - log2Up(sets)) val old_tag = UInt(width = params(MIFAddrBits) - log2Up(sets))
val wb_busy = Bool() val wb_busy = Bool()
override def clone = new MSHR().asInstanceOf[this.type] override def clone = new MSHR().asInstanceOf[this.type]
@ -188,10 +188,10 @@ class LLCMSHRFile(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int)(im
io.mem_resp_way := mshr(refillId).way io.mem_resp_way := mshr(refillId).way
} }
class LLCWriteback(requestors: Int, refill_cycles: Int)(implicit conf: MemoryIFConfiguration) extends Module class LLCWriteback(requestors: Int, refill_cycles: Int) extends Module
{ {
val io = new Bundle { val io = new Bundle {
val req = Vec.fill(requestors){Decoupled(UInt(width = conf.addrBits)).flip } val req = Vec.fill(requestors){Decoupled(UInt(width = params(MIFAddrBits))).flip }
val data = Vec.fill(requestors){Decoupled(new MemData).flip } val data = Vec.fill(requestors){Decoupled(new MemData).flip }
val mem = new MemPipeIO val mem = new MemPipeIO
} }
@ -237,12 +237,12 @@ class LLCWriteback(requestors: Int, refill_cycles: Int)(implicit conf: MemoryIFC
io.mem.req_data.bits := io.data(who).bits io.mem.req_data.bits := io.data(who).bits
} }
class LLCData(latency: Int, sets: Int, ways: Int, refill_cycles: Int, leaf: Mem[UInt])(implicit conf: MemoryIFConfiguration) extends Module class LLCData(latency: Int, sets: Int, ways: Int, refill_cycles: Int, leaf: Mem[UInt]) extends Module
{ {
val io = new Bundle { val io = new Bundle {
val req = Decoupled(new LLCDataReq(ways)).flip val req = Decoupled(new LLCDataReq(ways)).flip
val req_data = Decoupled(new MemData).flip val req_data = Decoupled(new MemData).flip
val writeback = Decoupled(UInt(width = conf.addrBits)) val writeback = Decoupled(UInt(width = params(MIFAddrBits)))
val writeback_data = Decoupled(new MemData) val writeback_data = Decoupled(new MemData)
val resp = Decoupled(new MemResp) val resp = Decoupled(new MemResp)
val mem_resp = Valid(new MemResp).flip val mem_resp = Valid(new MemResp).flip
@ -250,7 +250,7 @@ class LLCData(latency: Int, sets: Int, ways: Int, refill_cycles: Int, leaf: Mem[
val mem_resp_way = UInt(INPUT, log2Up(ways)) val mem_resp_way = UInt(INPUT, log2Up(ways))
} }
val data = Module(new BigMem(sets*ways*refill_cycles, 1, latency-1, leaf, true)(Bits(width = conf.dataBits))) val data = Module(new BigMem(sets*ways*refill_cycles, 1, latency-1, leaf, true)(Bits(width = params(MIFDataBits))))
class QEntry extends MemResp { class QEntry extends MemResp {
val isWriteback = Bool() val isWriteback = Bool()
override def clone = new QEntry().asInstanceOf[this.type] override def clone = new QEntry().asInstanceOf[this.type]
@ -304,7 +304,7 @@ class LLCData(latency: Int, sets: Int, ways: Int, refill_cycles: Int, leaf: Mem[
io.writeback_data.bits := q.io.deq.bits io.writeback_data.bits := q.io.deq.bits
} }
class MemReqArb(n: Int, refill_cycles: Int)(implicit conf: MemoryIFConfiguration) extends Module class MemReqArb(n: Int, refill_cycles: Int) extends Module
{ {
val io = new Bundle { val io = new Bundle {
val cpu = Vec.fill(n){new MemIO().flip} val cpu = Vec.fill(n){new MemIO().flip}
@ -347,16 +347,16 @@ class MemReqArb(n: Int, refill_cycles: Int)(implicit conf: MemoryIFConfiguration
when (unlock) { lock := Bool(false) } when (unlock) { lock := Bool(false) }
} }
abstract class DRAMSideLLCLike(implicit conf: MemoryIFConfiguration) extends Module { abstract class DRAMSideLLCLike extends Module {
val io = new Bundle { val io = new Bundle {
val cpu = new MemIO().flip val cpu = new MemIO().flip
val mem = new MemPipeIO val mem = new MemPipeIO
} }
} }
class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int, tagLeaf: Mem[UInt], dataLeaf: Mem[UInt])(implicit conf: MemoryIFConfiguration) extends DRAMSideLLCLike class DRAMSideLLC(sets: Int, ways: Int, outstanding: Int, refill_cycles: Int, tagLeaf: Mem[UInt], dataLeaf: Mem[UInt]) extends DRAMSideLLCLike
{ {
val tagWidth = conf.addrBits - log2Up(sets) val tagWidth = params(MIFAddrBits) - log2Up(sets)
val metaWidth = tagWidth + 2 // valid + dirty val metaWidth = tagWidth + 2 // valid + dirty
val memCmdArb = Module(new Arbiter(new MemReqCmd, 2)) val memCmdArb = Module(new Arbiter(new MemReqCmd, 2))
@ -504,8 +504,7 @@ object HellaQueue
} }
} }
class DRAMSideLLCNull(numRequests: Int, refillCycles: Int)(implicit conf: MemoryIFConfiguration) class DRAMSideLLCNull(numRequests: Int, refillCycles: Int) extends DRAMSideLLCLike {
extends DRAMSideLLCLike {
val numEntries = numRequests * refillCycles val numEntries = numRequests * refillCycles
val size = log2Down(numEntries) + 1 val size = log2Down(numEntries) + 1

View File

@ -2,57 +2,58 @@ package uncore
import Chisel._ import Chisel._
import scala.math._ import scala.math._
case class AddressSpaceConfiguration(paddrBits: Int, vaddrBits: Int, pgIdxBits: Int, asidBits: Int, permBits:Int) { case object PAddrBits extends Field[Int]
val ppnBits = paddrBits - pgIdxBits case object VAddrBits extends Field[Int]
val vpnBits = vaddrBits - pgIdxBits case object PgIdxBits extends Field[Int]
case object ASIdBits extends Field[Int]
case object PermBits 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]
case object MIFDataBeats extends Field[Int]
trait HasMemData extends Bundle {
val data = Bits(width = params(MIFDataBits))
} }
case class MemoryIFConfiguration(addrBits: Int, dataBits: Int, tagBits: Int, dataBeats: Int) trait HasMemAddr extends Bundle {
val addr = UInt(width = params(MIFAddrBits))
abstract trait MemoryIFSubBundle extends Bundle {
implicit val conf: MemoryIFConfiguration
override def clone = this.getClass.getConstructors.head.newInstance(conf).asInstanceOf[this.type]
} }
trait HasMemData extends MemoryIFSubBundle { trait HasMemTag extends Bundle {
val data = Bits(width = conf.dataBits) val tag = UInt(width = params(MIFTagBits))
} }
trait HasMemAddr extends MemoryIFSubBundle { class MemReqCmd extends HasMemAddr with HasMemTag {
val addr = UInt(width = conf.addrBits)
}
trait HasMemTag extends MemoryIFSubBundle {
val tag = UInt(width = conf.tagBits)
}
class MemReqCmd(implicit val conf: MemoryIFConfiguration) extends HasMemAddr with HasMemTag {
val rw = Bool() val rw = Bool()
} }
class MemResp(implicit val conf: MemoryIFConfiguration) extends HasMemData with HasMemTag class MemResp extends HasMemData with HasMemTag
class MemData(implicit val conf: MemoryIFConfiguration) extends HasMemData class MemData extends HasMemData
class MemIO(implicit val conf: MemoryIFConfiguration) extends Bundle { class MemIO extends Bundle {
val req_cmd = Decoupled(new MemReqCmd) val req_cmd = Decoupled(new MemReqCmd)
val req_data = Decoupled(new MemData) val req_data = Decoupled(new MemData)
val resp = Decoupled(new MemResp).flip val resp = Decoupled(new MemResp).flip
} }
class MemPipeIO(implicit val conf: MemoryIFConfiguration) extends Bundle { class MemPipeIO extends Bundle {
val req_cmd = Decoupled(new MemReqCmd) val req_cmd = Decoupled(new MemReqCmd)
val req_data = Decoupled(new MemData) val req_data = Decoupled(new MemData)
val resp = Valid(new MemResp).flip val resp = Valid(new MemResp).flip
} }
class MemSerializedIO(w: Int)(implicit val conf: MemoryIFConfiguration) extends Bundle class MemSerializedIO(w: Int) extends Bundle
{ {
val req = Decoupled(Bits(width = w)) val req = Decoupled(Bits(width = w))
val resp = Valid(Bits(width = w)).flip val resp = Valid(Bits(width = w)).flip
} }
class MemSerdes(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module class MemSerdes(w: Int) extends Module
{ {
val io = new Bundle { val io = new Bundle {
val wide = new MemIO().flip val wide = new MemIO().flip
@ -61,6 +62,7 @@ class MemSerdes(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
val abits = io.wide.req_cmd.bits.toBits.getWidth val abits = io.wide.req_cmd.bits.toBits.getWidth
val dbits = io.wide.req_data.bits.toBits.getWidth val dbits = io.wide.req_data.bits.toBits.getWidth
val rbits = io.wide.resp.bits.getWidth val rbits = io.wide.resp.bits.getWidth
val dbeats = params(MIFDataBeats)
val out_buf = Reg(Bits()) val out_buf = Reg(Bits())
val in_buf = Reg(Bits()) val in_buf = Reg(Bits())
@ -68,7 +70,7 @@ class MemSerdes(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
val s_idle :: s_read_addr :: s_write_addr :: s_write_idle :: s_write_data :: Nil = Enum(UInt(), 5) val s_idle :: s_read_addr :: s_write_addr :: s_write_idle :: s_write_data :: Nil = Enum(UInt(), 5)
val state = Reg(init=s_idle) val state = Reg(init=s_idle)
val send_cnt = Reg(init=UInt(0, log2Up((max(abits, dbits)+w-1)/w))) val send_cnt = Reg(init=UInt(0, log2Up((max(abits, dbits)+w-1)/w)))
val data_send_cnt = Reg(init=UInt(0, log2Up(conf.dataBeats))) val data_send_cnt = Reg(init=UInt(0, log2Up(dbeats)))
val adone = io.narrow.req.ready && send_cnt === UInt((abits-1)/w) val adone = io.narrow.req.ready && send_cnt === UInt((abits-1)/w)
val ddone = io.narrow.req.ready && send_cnt === UInt((dbits-1)/w) val ddone = io.narrow.req.ready && send_cnt === UInt((dbits-1)/w)
@ -104,12 +106,12 @@ class MemSerdes(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
} }
when (state === s_write_data && ddone) { when (state === s_write_data && ddone) {
data_send_cnt := data_send_cnt + UInt(1) data_send_cnt := data_send_cnt + UInt(1)
state := Mux(data_send_cnt === UInt(conf.dataBeats-1), s_idle, s_write_idle) state := Mux(data_send_cnt === UInt(dbeats-1), s_idle, s_write_idle)
send_cnt := UInt(0) send_cnt := UInt(0)
} }
val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w))) val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w)))
val data_recv_cnt = Reg(init=UInt(0, log2Up(conf.dataBeats))) val data_recv_cnt = Reg(init=UInt(0, log2Up(dbeats)))
val resp_val = Reg(init=Bool(false)) val resp_val = Reg(init=Bool(false))
resp_val := Bool(false) resp_val := Bool(false)
@ -127,21 +129,22 @@ class MemSerdes(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
io.wide.resp.bits := io.wide.resp.bits.fromBits(in_buf) io.wide.resp.bits := io.wide.resp.bits.fromBits(in_buf)
} }
class MemDesserIO(w: Int)(implicit val conf: MemoryIFConfiguration) extends Bundle { class MemDesserIO(w: Int) extends Bundle {
val narrow = new MemSerializedIO(w).flip val narrow = new MemSerializedIO(w).flip
val wide = new MemIO val wide = new MemIO
} }
class MemDesser(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module // test rig side class MemDesser(w: Int) extends Module // test rig side
{ {
val io = new MemDesserIO(w) val io = new MemDesserIO(w)
val abits = io.wide.req_cmd.bits.toBits.getWidth val abits = io.wide.req_cmd.bits.toBits.getWidth
val dbits = io.wide.req_data.bits.toBits.getWidth val dbits = io.wide.req_data.bits.toBits.getWidth
val rbits = io.wide.resp.bits.getWidth val rbits = io.wide.resp.bits.getWidth
val dbeats = params(MIFDataBeats)
require(dbits >= abits && rbits >= dbits) require(dbits >= abits && rbits >= dbits)
val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w))) val recv_cnt = Reg(init=UInt(0, log2Up((rbits+w-1)/w)))
val data_recv_cnt = Reg(init=UInt(0, log2Up(conf.dataBeats))) val data_recv_cnt = Reg(init=UInt(0, log2Up(dbeats)))
val adone = io.narrow.req.valid && recv_cnt === UInt((abits-1)/w) val adone = io.narrow.req.valid && recv_cnt === UInt((abits-1)/w)
val ddone = io.narrow.req.valid && recv_cnt === UInt((dbits-1)/w) val ddone = io.narrow.req.valid && recv_cnt === UInt((dbits-1)/w)
val rdone = io.narrow.resp.valid && recv_cnt === UInt((rbits-1)/w) val rdone = io.narrow.resp.valid && recv_cnt === UInt((rbits-1)/w)
@ -169,13 +172,13 @@ class MemDesser(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
} }
when (state === s_data && io.wide.req_data.ready) { when (state === s_data && io.wide.req_data.ready) {
state := s_data_recv state := s_data_recv
when (data_recv_cnt === UInt(conf.dataBeats-1)) { when (data_recv_cnt === UInt(dbeats-1)) {
state := s_cmd_recv state := s_cmd_recv
} }
data_recv_cnt := data_recv_cnt + UInt(1) data_recv_cnt := data_recv_cnt + UInt(1)
} }
when (rdone) { // state === s_reply when (rdone) { // state === s_reply
when (data_recv_cnt === UInt(conf.dataBeats-1)) { when (data_recv_cnt === UInt(dbeats-1)) {
state := s_cmd_recv state := s_cmd_recv
} }
recv_cnt := UInt(0) recv_cnt := UInt(0)
@ -189,7 +192,7 @@ class MemDesser(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
io.wide.req_data.valid := state === s_data io.wide.req_data.valid := state === s_data
io.wide.req_data.bits.data := in_buf >> UInt(((rbits+w-1)/w - (dbits+w-1)/w)*w) io.wide.req_data.bits.data := in_buf >> UInt(((rbits+w-1)/w - (dbits+w-1)/w)*w)
val dataq = Module(new Queue(new MemResp, conf.dataBeats)) val dataq = Module(new Queue(new MemResp, dbeats))
dataq.io.enq <> io.wide.resp dataq.io.enq <> io.wide.resp
dataq.io.deq.ready := recv_cnt === UInt((rbits-1)/w) dataq.io.deq.ready := recv_cnt === UInt((rbits-1)/w)
@ -198,18 +201,21 @@ class MemDesser(w: Int)(implicit val conf: MemoryIFConfiguration) extends Module
} }
//Adapter betweewn an UncachedTileLinkIO and a mem controller MemIO //Adapter betweewn an UncachedTileLinkIO and a mem controller MemIO
class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkConfiguration, mifconf: MemoryIFConfiguration) extends Module { class MemIOUncachedTileLinkIOConverter(qDepth: Int) extends Module {
val io = new Bundle { val io = new Bundle {
val uncached = new UncachedTileLinkIO().flip val uncached = new UncachedTileLinkIO().flip
val mem = new MemIO val mem = new MemIO
} }
val co = params(TLCoherence)
require(tlconf.dataBits == mifconf.dataBits*mifconf.dataBeats) val tbits = params(MIFTagBits)
//require(tlconf.clientXactIdBits <= mifconf.tagBits) val dbits = params(MIFDataBits)
val dbeats = params(MIFDataBeats)
require(params(TLDataBits) == dbits*dbeats)
//require(params(TLClientXactIdBits) <= params(MIFTagBits))
val mem_cmd_q = Module(new Queue(new MemReqCmd, qDepth)) val mem_cmd_q = Module(new Queue(new MemReqCmd, qDepth))
val mem_data_q = Module(new Queue(new MemData, qDepth)) val mem_data_q = Module(new Queue(new MemData, qDepth))
val cnt_max = mifconf.dataBeats val cnt_max = dbeats
val cnt_out = Reg(UInt(width = log2Up(cnt_max+1))) val cnt_out = Reg(UInt(width = log2Up(cnt_max+1)))
val active_out = Reg(init=Bool(false)) val active_out = Reg(init=Bool(false))
@ -222,7 +228,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkCon
val cnt_in = Reg(UInt(width = log2Up(cnt_max+1))) val cnt_in = Reg(UInt(width = log2Up(cnt_max+1)))
val active_in = Reg(init=Bool(false)) val active_in = Reg(init=Bool(false))
val buf_in = Reg(Bits()) val buf_in = Reg(Bits())
val tag_in = Reg(UInt(width = mifconf.tagBits)) val tag_in = Reg(UInt(width = tbits))
// Decompose outgoing TL Acquires into MemIO cmd and data // Decompose outgoing TL Acquires into MemIO cmd and data
when(!active_out && io.uncached.acquire.valid) { when(!active_out && io.uncached.acquire.valid) {
@ -232,7 +238,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkCon
buf_out := io.uncached.acquire.bits.payload.data buf_out := io.uncached.acquire.bits.payload.data
tag_out := io.uncached.acquire.bits.payload.client_xact_id tag_out := io.uncached.acquire.bits.payload.client_xact_id
addr_out := io.uncached.acquire.bits.payload.addr addr_out := io.uncached.acquire.bits.payload.addr
has_data := tlconf.co.messageHasData(io.uncached.acquire.bits.payload) has_data := co.messageHasData(io.uncached.acquire.bits.payload)
} }
when(active_out) { when(active_out) {
when(mem_cmd_q.io.enq.fire()) { when(mem_cmd_q.io.enq.fire()) {
@ -240,7 +246,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkCon
} }
when(mem_data_q.io.enq.fire()) { when(mem_data_q.io.enq.fire()) {
cnt_out := cnt_out + UInt(1) cnt_out := cnt_out + UInt(1)
buf_out := buf_out >> UInt(mifconf.dataBits) buf_out := buf_out >> UInt(dbits)
} }
when(cmd_sent_out && (!has_data || cnt_out === UInt(cnt_max))) { when(cmd_sent_out && (!has_data || cnt_out === UInt(cnt_max))) {
active_out := Bool(false) active_out := Bool(false)
@ -264,7 +270,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkCon
when(!active_in && io.mem.resp.valid) { when(!active_in && io.mem.resp.valid) {
active_in := Bool(true) active_in := Bool(true)
cnt_in := UInt(1) cnt_in := UInt(1)
buf_in := io.mem.resp.bits.data << UInt(mifconf.dataBits*(cnt_max-1)) buf_in := io.mem.resp.bits.data << UInt(dbits*(cnt_max-1))
tag_in := io.mem.resp.bits.tag tag_in := io.mem.resp.bits.tag
} }
when(active_in) { when(active_in) {
@ -272,7 +278,7 @@ class MemIOUncachedTileLinkIOConverter(qDepth: Int)(implicit tlconf: TileLinkCon
active_in := Bool(false) active_in := Bool(false)
} }
when(io.mem.resp.fire()) { when(io.mem.resp.fire()) {
buf_in := Cat(io.mem.resp.bits.data, buf_in(cnt_max*mifconf.dataBits-1,mifconf.dataBits)) buf_in := Cat(io.mem.resp.bits.data, buf_in(cnt_max*dbits-1,dbits))
cnt_in := cnt_in + UInt(1) cnt_in := cnt_in + UInt(1)
} }
} }

View File

@ -1,32 +1,35 @@
package uncore package uncore
import Chisel._ import Chisel._
case class PhysicalNetworkConfiguration(nEndpoints: Int, idBits: Int) case object LNMasters extends Field[Int]
case object LNClients extends Field[Int]
case object LNEndpoints extends Field[Int]
class PhysicalHeader(implicit conf: PhysicalNetworkConfiguration) extends Bundle { class PhysicalHeader(n: Int) extends Bundle {
val src = UInt(width = conf.idBits) val src = UInt(width = log2Up(n))
val dst = UInt(width = conf.idBits) val dst = UInt(width = log2Up(n))
} }
class PhysicalNetworkIO[T <: Data](dType: T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle { class PhysicalNetworkIO[T <: Data](n: Int, dType: T) extends Bundle {
val header = new PhysicalHeader val header = new PhysicalHeader(n)
val payload = dType.clone val payload = dType.clone
override def clone = { new PhysicalNetworkIO(dType).asInstanceOf[this.type] } override def clone = new PhysicalNetworkIO(n,dType).asInstanceOf[this.type]
} }
abstract class PhysicalNetwork(conf: PhysicalNetworkConfiguration) extends Module class BasicCrossbarIO[T <: Data](n: Int, dType: T) extends Bundle {
val in = Vec.fill(n){Decoupled(new PhysicalNetworkIO(n,dType))}.flip
class BasicCrossbarIO[T <: Data](dType: T)(implicit conf: PhysicalNetworkConfiguration) extends Bundle { val out = Vec.fill(n){Decoupled(new PhysicalNetworkIO(n,dType))}
val in = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}.flip
val out = Vec.fill(conf.nEndpoints){Decoupled(new PhysicalNetworkIO(dType))}
} }
class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: PhysicalNetworkConfiguration) extends PhysicalNetwork(conf) {
val io = new BasicCrossbarIO(dType)
val rdyVecs = List.fill(conf.nEndpoints)(Vec.fill(conf.nEndpoints)(Bool())) abstract class PhysicalNetwork extends Module
class BasicCrossbar[T <: Data](n: Int, dType: T, count: Int = 1) extends PhysicalNetwork {
val io = new BasicCrossbarIO(n, dType)
val rdyVecs = List.fill(n){Vec.fill(n)(Bool())}
io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => { io.out.zip(rdyVecs).zipWithIndex.map{ case ((out, rdys), i) => {
val rrarb = Module(new LockingRRArbiter(io.in(0).bits, conf.nEndpoints, count)) val rrarb = Module(new LockingRRArbiter(io.in(0).bits, n, count))
(rrarb.io.in, io.in, rdys).zipped.map{ case (arb, in, rdy) => { (rrarb.io.in, io.in, rdys).zipped.map{ case (arb, in, rdy) => {
arb.valid := in.valid && (in.bits.header.dst === UInt(i)) arb.valid := in.valid && (in.bits.header.dst === UInt(i))
arb.bits := in.bits arb.bits := in.bits
@ -34,30 +37,26 @@ class BasicCrossbar[T <: Data](dType: T, count: Int = 1)(implicit conf: Physical
}} }}
out <> rrarb.io.out out <> rrarb.io.out
}} }}
for(i <- 0 until conf.nEndpoints) { for(i <- 0 until n) {
io.in(i).ready := rdyVecs.map(r => r(i)).reduceLeft(_||_) io.in(i).ready := rdyVecs.map(r => r(i)).reduceLeft(_||_)
} }
} }
case class LogicalNetworkConfiguration(idBits: Int, nMasters: Int, nClients: Int) { abstract class LogicalNetwork extends Module
val nEndpoints = nMasters + nClients
class LogicalHeader extends Bundle {
val src = UInt(width = log2Up(params(LNEndpoints)))
val dst = UInt(width = log2Up(params(LNEndpoints)))
} }
abstract class LogicalNetwork[TileLinkType <: Bundle](implicit conf: LogicalNetworkConfiguration) extends Module class LogicalNetworkIO[T <: Data](dType: T) extends Bundle {
class LogicalHeader(implicit conf: LogicalNetworkConfiguration) extends Bundle {
val src = UInt(width = conf.idBits)
val dst = UInt(width = conf.idBits)
}
class LogicalNetworkIO[T <: Data](dType: T)(implicit conf: LogicalNetworkConfiguration) extends Bundle {
val header = new LogicalHeader val header = new LogicalHeader
val payload = dType.clone val payload = dType.clone
override def clone = { new LogicalNetworkIO(dType).asInstanceOf[this.type] } override def clone = { new LogicalNetworkIO(dType).asInstanceOf[this.type] }
} }
object DecoupledLogicalNetworkIOWrapper { object DecoupledLogicalNetworkIOWrapper {
def apply[T <: Data](in: DecoupledIO[T], src: UInt = UInt(0), dst: UInt = UInt(0))(implicit conf: LogicalNetworkConfiguration) = { def apply[T <: Data](in: DecoupledIO[T], src: UInt = UInt(0), dst: UInt = UInt(0)) = {
val out = Decoupled(new LogicalNetworkIO(in.bits.clone)).asDirectionless val out = Decoupled(new LogicalNetworkIO(in.bits.clone)).asDirectionless
out.valid := in.valid out.valid := in.valid
out.bits.payload := in.bits out.bits.payload := in.bits
@ -69,7 +68,7 @@ object DecoupledLogicalNetworkIOWrapper {
} }
object DecoupledLogicalNetworkIOUnwrapper { object DecoupledLogicalNetworkIOUnwrapper {
def apply[T <: Data](in: DecoupledIO[LogicalNetworkIO[T]])(implicit conf: LogicalNetworkConfiguration) = { def apply[T <: Data](in: DecoupledIO[LogicalNetworkIO[T]]) = {
val out = Decoupled(in.bits.payload.clone).asDirectionless val out = Decoupled(in.bits.payload.clone).asDirectionless
out.valid := in.valid out.valid := in.valid
out.bits := in.bits.payload out.bits := in.bits.payload

View File

@ -1,27 +1,29 @@
package uncore package uncore
import Chisel._ import Chisel._
case class TileLinkConfiguration(co: CoherencePolicyWithUncached, ln: LogicalNetworkConfiguration, addrBits: Int, masterXactIdBits: Int, clientXactIdBits: Int, dataBits: Int, writeMaskBits: Int, wordAddrBits: Int, atomicOpBits: Int) case object TLCoherence extends Field[CoherencePolicyWithUncached]
case object TLAddrBits extends Field[Int]
case object TLMasterXactIdBits extends Field[Int]
case object TLClientXactIdBits extends Field[Int]
case object TLDataBits extends Field[Int]
case object TLWriteMaskBits extends Field[Int]
case object TLWordAddrBits extends Field[Int]
case object TLAtomicOpBits extends Field[Int]
abstract trait TileLinkSubBundle extends Bundle { trait HasPhysicalAddress extends Bundle {
implicit val tlconf: TileLinkConfiguration val addr = UInt(width = params(TLAddrBits))
override def clone = this.getClass.getConstructors.head.newInstance(tlconf).asInstanceOf[this.type]
} }
trait HasPhysicalAddress extends TileLinkSubBundle { trait HasClientTransactionId extends Bundle {
val addr = UInt(width = tlconf.addrBits) val client_xact_id = Bits(width = params(TLClientXactIdBits))
} }
trait HasClientTransactionId extends TileLinkSubBundle { trait HasMasterTransactionId extends Bundle {
val client_xact_id = Bits(width = tlconf.clientXactIdBits) val master_xact_id = Bits(width = params(TLMasterXactIdBits))
} }
trait HasMasterTransactionId extends TileLinkSubBundle { trait HasTileLinkData extends Bundle {
val master_xact_id = Bits(width = tlconf.masterXactIdBits) val data = Bits(width = params(TLDataBits))
}
trait HasTileLinkData extends TileLinkSubBundle {
val data = Bits(width = tlconf.dataBits)
} }
trait SourcedMessage extends Bundle trait SourcedMessage extends Bundle
@ -30,7 +32,7 @@ trait MasterSourcedMessage extends SourcedMessage
object Acquire object Acquire
{ {
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt)(implicit conf: TileLinkConfiguration): Acquire = { def apply(a_type: Bits, addr: UInt, client_xact_id: UInt): Acquire = {
val acq = new Acquire val acq = new Acquire
acq.a_type := a_type acq.a_type := a_type
acq.addr := addr acq.addr := addr
@ -41,42 +43,42 @@ object Acquire
acq.atomic_opcode := Bits(0) acq.atomic_opcode := Bits(0)
acq acq
} }
def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, data: UInt)(implicit conf: TileLinkConfiguration): Acquire = { def apply(a_type: Bits, addr: UInt, client_xact_id: UInt, data: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id) val acq = apply(a_type, addr, client_xact_id)
acq.data := data acq.data := data
acq acq
} }
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, write_mask: Bits, data: UInt)(implicit conf: TileLinkConfiguration): Acquire = { def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, write_mask: Bits, data: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id, data) val acq = apply(a_type, addr, client_xact_id, data)
acq.write_mask := write_mask acq.write_mask := write_mask
acq acq
} }
def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt, data: UInt)(implicit conf: TileLinkConfiguration): Acquire = { def apply(a_type: UInt, addr: UInt, client_xact_id: UInt, subword_addr: UInt, atomic_opcode: UInt, data: UInt): Acquire = {
val acq = apply(a_type, addr, client_xact_id, data) val acq = apply(a_type, addr, client_xact_id, data)
acq.subword_addr := subword_addr acq.subword_addr := subword_addr
acq.atomic_opcode := atomic_opcode acq.atomic_opcode := atomic_opcode
acq acq
} }
def apply(a: Acquire)(implicit conf: TileLinkConfiguration): Acquire = { def apply(a: Acquire): Acquire = {
val acq = new Acquire val acq = new Acquire
acq := a acq := a
acq acq
} }
} }
class Acquire(implicit val tlconf: TileLinkConfiguration) extends ClientSourcedMessage class Acquire extends ClientSourcedMessage
with HasPhysicalAddress with HasPhysicalAddress
with HasClientTransactionId with HasClientTransactionId
with HasTileLinkData { with HasTileLinkData {
val a_type = UInt(width = tlconf.co.acquireTypeWidth) val a_type = UInt(width = params(TLCoherence).acquireTypeWidth)
val write_mask = Bits(width = tlconf.writeMaskBits) val write_mask = Bits(width = params(TLWriteMaskBits))
val subword_addr = Bits(width = tlconf.wordAddrBits) val subword_addr = Bits(width = params(TLWordAddrBits))
val atomic_opcode = Bits(width = tlconf.atomicOpBits) val atomic_opcode = Bits(width = params(TLAtomicOpBits))
} }
object Probe object Probe
{ {
def apply(p_type: UInt, addr: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = { def apply(p_type: UInt, addr: UInt, master_xact_id: UInt) = {
val prb = new Probe val prb = new Probe
prb.p_type := p_type prb.p_type := p_type
prb.addr := addr prb.addr := addr
@ -85,22 +87,22 @@ object Probe
} }
} }
class Probe(implicit val tlconf: TileLinkConfiguration) extends MasterSourcedMessage class Probe extends MasterSourcedMessage
with HasPhysicalAddress with HasPhysicalAddress
with HasMasterTransactionId { with HasMasterTransactionId {
val p_type = UInt(width = tlconf.co.probeTypeWidth) val p_type = UInt(width = params(TLCoherence).probeTypeWidth)
} }
object Release object Release
{ {
def apply(r_type: UInt, addr: UInt, data: UInt)(implicit conf: TileLinkConfiguration) = { def apply(r_type: UInt, addr: UInt, data: UInt): Release = {
val rel = new Release val rel = new Release
rel.r_type := r_type rel.r_type := r_type
rel.addr := addr rel.addr := addr
rel.data := data rel.data := data
rel rel
} }
def apply(r_type: UInt, addr: UInt, client_xact_id: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = { def apply(r_type: UInt, addr: UInt, client_xact_id: UInt, master_xact_id: UInt): Release = {
val rel = new Release val rel = new Release
rel.r_type := r_type rel.r_type := r_type
rel.addr := addr rel.addr := addr
@ -109,24 +111,24 @@ object Release
rel.data := UInt(0) rel.data := UInt(0)
rel rel
} }
def apply(r_type: UInt, addr: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt)(implicit conf: TileLinkConfiguration): Release = { def apply(r_type: UInt, addr: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt): Release = {
val rel = apply(r_type, addr, client_xact_id, master_xact_id) val rel = apply(r_type, addr, client_xact_id, master_xact_id)
rel.data := data rel.data := data
rel rel
} }
} }
class Release(implicit val tlconf: TileLinkConfiguration) extends ClientSourcedMessage class Release extends ClientSourcedMessage
with HasPhysicalAddress with HasPhysicalAddress
with HasClientTransactionId with HasClientTransactionId
with HasMasterTransactionId with HasMasterTransactionId
with HasTileLinkData { with HasTileLinkData {
val r_type = UInt(width = tlconf.co.releaseTypeWidth) val r_type = UInt(width = params(TLCoherence).releaseTypeWidth)
} }
object Grant object Grant
{ {
def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt)(implicit conf: TileLinkConfiguration) = { def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt): Grant = {
val gnt = new Grant val gnt = new Grant
gnt.g_type := g_type gnt.g_type := g_type
gnt.client_xact_id := client_xact_id gnt.client_xact_id := client_xact_id
@ -134,40 +136,35 @@ object Grant
gnt.data := UInt(0) gnt.data := UInt(0)
gnt gnt
} }
def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt)(implicit conf: TileLinkConfiguration): Grant = { def apply(g_type: UInt, client_xact_id: UInt, master_xact_id: UInt, data: UInt): Grant = {
val gnt = apply(g_type, client_xact_id, master_xact_id) val gnt = apply(g_type, client_xact_id, master_xact_id)
gnt.data := data gnt.data := data
gnt gnt
} }
} }
class Grant(implicit val tlconf: TileLinkConfiguration) extends MasterSourcedMessage class Grant extends MasterSourcedMessage
with HasTileLinkData with HasTileLinkData
with HasClientTransactionId with HasClientTransactionId
with HasMasterTransactionId { with HasMasterTransactionId {
val g_type = UInt(width = tlconf.co.grantTypeWidth) val g_type = UInt(width = params(TLCoherence).grantTypeWidth)
} }
class Finish(implicit val tlconf: TileLinkConfiguration) extends ClientSourcedMessage with HasMasterTransactionId class Finish extends ClientSourcedMessage with HasMasterTransactionId
class UncachedTileLinkIO(implicit conf: TileLinkConfiguration) extends Bundle { class UncachedTileLinkIO extends Bundle {
implicit val ln = conf.ln
val acquire = new DecoupledIO(new LogicalNetworkIO(new Acquire)) val acquire = new DecoupledIO(new LogicalNetworkIO(new Acquire))
val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip val grant = new DecoupledIO(new LogicalNetworkIO(new Grant)).flip
val finish = new DecoupledIO(new LogicalNetworkIO(new Finish)) val finish = new DecoupledIO(new LogicalNetworkIO(new Finish))
override def clone = { new UncachedTileLinkIO().asInstanceOf[this.type] }
} }
class TileLinkIO(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIO()(conf) { class TileLinkIO extends UncachedTileLinkIO {
val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip val probe = new DecoupledIO(new LogicalNetworkIO(new Probe)).flip
val release = new DecoupledIO(new LogicalNetworkIO(new Release)) val release = new DecoupledIO(new LogicalNetworkIO(new Release))
override def clone = { new TileLinkIO().asInstanceOf[this.type] }
} }
abstract class TileLinkArbiterLike(val arbN: Int)(implicit conf: TileLinkConfiguration) extends Module { abstract class TileLinkArbiterLike(val arbN: Int) extends Module {
implicit val (ln, co) = (conf.ln, conf.co)
type MasterSourcedWithId = MasterSourcedMessage with HasClientTransactionId type MasterSourcedWithId = MasterSourcedMessage with HasClientTransactionId
type ClientSourcedWithId = ClientSourcedMessage with HasClientTransactionId type ClientSourcedWithId = ClientSourcedMessage with HasClientTransactionId
@ -178,7 +175,7 @@ abstract class TileLinkArbiterLike(val arbN: Int)(implicit conf: TileLinkConfigu
def hookupClientSource[M <: ClientSourcedWithId] def hookupClientSource[M <: ClientSourcedWithId]
(ins: Seq[DecoupledIO[LogicalNetworkIO[M]]], (ins: Seq[DecoupledIO[LogicalNetworkIO[M]]],
out: DecoupledIO[LogicalNetworkIO[M]]) { out: DecoupledIO[LogicalNetworkIO[M]]) {
def hasData(m: LogicalNetworkIO[M]) = co.messageHasData(m.payload) def hasData(m: LogicalNetworkIO[M]) = params(TLCoherence).messageHasData(m.payload)
val arb = Module(new RRArbiter(out.bits.clone, arbN)) val arb = Module(new RRArbiter(out.bits.clone, arbN))
out <> arb.io.out out <> arb.io.out
ins.zipWithIndex.zip(arb.io.in).map{ case ((req,id), arb) => { ins.zipWithIndex.zip(arb.io.in).map{ case ((req,id), arb) => {
@ -205,7 +202,8 @@ abstract class TileLinkArbiterLike(val arbN: Int)(implicit conf: TileLinkConfigu
} }
} }
abstract class UncachedTileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkArbiterLike(n)(conf) { abstract class UncachedTileLinkIOArbiter(n: Int)
extends TileLinkArbiterLike(n) {
val io = new Bundle { val io = new Bundle {
val in = Vec.fill(n){new UncachedTileLinkIO}.flip val in = Vec.fill(n){new UncachedTileLinkIO}.flip
val out = new UncachedTileLinkIO val out = new UncachedTileLinkIO
@ -219,7 +217,7 @@ abstract class UncachedTileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfigur
finish_arb.io.in zip io.in map { case (arb, req) => arb <> req.finish } finish_arb.io.in zip io.in map { case (arb, req) => arb <> req.finish }
} }
abstract class TileLinkIOArbiter(n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkArbiterLike(n)(conf) { abstract class TileLinkIOArbiter(n: Int) extends TileLinkArbiterLike(n) {
val io = new Bundle { val io = new Bundle {
val in = Vec.fill(n){new TileLinkIO}.flip val in = Vec.fill(n){new TileLinkIO}.flip
val out = new TileLinkIO val out = new TileLinkIO
@ -267,9 +265,9 @@ abstract trait UsesNewId {
in.client_xact_id in.client_xact_id
} }
class UncachedTileLinkIOArbiterThatAppendsArbiterId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with AppendsArbiterId class UncachedTileLinkIOArbiterThatAppendsArbiterId(val n: Int) extends UncachedTileLinkIOArbiter(n) with AppendsArbiterId
class UncachedTileLinkIOArbiterThatPassesId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with PassesId class UncachedTileLinkIOArbiterThatPassesId(val n: Int) extends UncachedTileLinkIOArbiter(n) with PassesId
class UncachedTileLinkIOArbiterThatUsesNewId(val n: Int)(implicit conf: TileLinkConfiguration) extends UncachedTileLinkIOArbiter(n)(conf) with UsesNewId class UncachedTileLinkIOArbiterThatUsesNewId(val n: Int) extends UncachedTileLinkIOArbiter(n) with UsesNewId
class TileLinkIOArbiterThatAppendsArbiterId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with AppendsArbiterId class TileLinkIOArbiterThatAppendsArbiterId(val n: Int) extends TileLinkIOArbiter(n) with AppendsArbiterId
class TileLinkIOArbiterThatPassesId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with PassesId class TileLinkIOArbiterThatPassesId(val n: Int) extends TileLinkIOArbiter(n) with PassesId
class TileLinkIOArbiterThatUsesNewId(val n: Int)(implicit conf: TileLinkConfiguration) extends TileLinkIOArbiter(n)(conf) with UsesNewId class TileLinkIOArbiterThatUsesNewId(val n: Int) extends TileLinkIOArbiter(n) with UsesNewId

View File

@ -1,33 +1,34 @@
package uncore package uncore
import Chisel._ import Chisel._
trait CoherenceAgentConfiguration { case object NReleaseTransactors extends Field[Int]
def tl: TileLinkConfiguration case object NAcquireTransactors extends Field[Int]
def nReleaseTransactions: Int case object NClients extends Field[Int]
def nAcquireTransactions: Int
abstract trait CoherenceAgentParameters extends UsesParameters {
val co = params(TLCoherence)
val nReleaseTransactors = params(NReleaseTransactors)
val nAcquireTransactors = params(NAcquireTransactors)
val nTransactors = nReleaseTransactors + nAcquireTransactors
val nClients = params(NClients)
} }
abstract class CoherenceAgent(implicit conf: CoherenceAgentConfiguration) extends Module { abstract class CoherenceAgent extends Module
with CoherenceAgentParameters {
val io = new Bundle { val io = new Bundle {
val inner = (new TileLinkIO()(conf.tl)).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO()(conf.tl) val outer = new UncachedTileLinkIO
val incoherent = Vec.fill(conf.tl.ln.nClients){Bool()}.asInput val incoherent = Vec.fill(nClients){Bool()}.asInput
} }
} }
case class L2CoherenceAgentConfiguration( class L2CoherenceAgent(bankId: Int) extends CoherenceAgent {
val tl: TileLinkConfiguration,
val nReleaseTransactions: Int,
val nAcquireTransactions: Int) extends CoherenceAgentConfiguration
class L2CoherenceAgent(bankId: Int)(implicit conf: CoherenceAgentConfiguration)
extends CoherenceAgent {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co)
// Create SHRs for outstanding transactions // Create SHRs for outstanding transactions
val nTrackers = conf.nReleaseTransactions + conf.nAcquireTransactions val trackerList = (0 until nReleaseTransactors).map(id =>
val trackerList = (0 until conf.nReleaseTransactions).map(id => Module(new VoluntaryReleaseTracker(id, bankId))) ++ Module(new VoluntaryReleaseTracker(id, bankId))) ++
(conf.nReleaseTransactions until nTrackers).map(id => Module(new AcquireTracker(id, bankId))) (nReleaseTransactors until nTransactors).map(id =>
Module(new AcquireTracker(id, bankId)))
// Propagate incoherence flags // Propagate incoherence flags
trackerList.map(_.io.tile_incoherent := io.incoherent.toBits) trackerList.map(_.io.tile_incoherent := io.incoherent.toBits)
@ -85,12 +86,12 @@ class L2CoherenceAgent(bankId: Int)(implicit conf: CoherenceAgentConfiguration)
} }
abstract class XactTracker()(implicit conf: CoherenceAgentConfiguration) extends Module { abstract class XactTracker extends Module {
implicit val (tl, ln, co) = (conf.tl, conf.tl.ln, conf.tl.co) val (co, nClients) = (params(TLCoherence),params(NClients))
val io = new Bundle { val io = new Bundle {
val inner = (new TileLinkIO).flip val inner = (new TileLinkIO).flip
val outer = new UncachedTileLinkIO val outer = new UncachedTileLinkIO
val tile_incoherent = Bits(INPUT, ln.nClients) val tile_incoherent = Bits(INPUT, params(NClients))
val has_acquire_conflict = Bool(OUTPUT) val has_acquire_conflict = Bool(OUTPUT)
val has_release_conflict = Bool(OUTPUT) val has_release_conflict = Bool(OUTPUT)
} }
@ -100,15 +101,13 @@ abstract class XactTracker()(implicit conf: CoherenceAgentConfiguration) extends
val c_gnt = io.inner.grant.bits val c_gnt = io.inner.grant.bits
val c_ack = io.inner.finish.bits val c_ack = io.inner.finish.bits
val m_gnt = io.outer.grant.bits val m_gnt = io.outer.grant.bits
} }
class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentConfiguration) class VoluntaryReleaseTracker(trackerId: Int, bankId: Int) extends XactTracker {
extends XactTracker()(conf) {
val s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(UInt(), 4) val s_idle :: s_mem :: s_ack :: s_busy :: Nil = Enum(UInt(), 4)
val state = Reg(init=s_idle) val state = Reg(init=s_idle)
val xact = Reg{ new Release } val xact = Reg{ new Release }
val init_client_id = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_client_id = Reg(init=UInt(0, width = log2Up(nClients)))
val incoming_rel = io.inner.release.bits val incoming_rel = io.inner.release.bits
io.has_acquire_conflict := Bool(false) io.has_acquire_conflict := Bool(false)
@ -153,17 +152,16 @@ class VoluntaryReleaseTracker(trackerId: Int, bankId: Int)(implicit conf: Cohere
} }
} }
class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentConfiguration) class AcquireTracker(trackerId: Int, bankId: Int) extends XactTracker {
extends XactTracker()(conf) {
val s_idle :: s_probe :: s_mem_read :: s_mem_write :: s_make_grant :: s_busy :: Nil = Enum(UInt(), 6) val s_idle :: s_probe :: s_mem_read :: s_mem_write :: s_make_grant :: s_busy :: Nil = Enum(UInt(), 6)
val state = Reg(init=s_idle) val state = Reg(init=s_idle)
val xact = Reg{ new Acquire } val xact = Reg{ new Acquire }
val init_client_id = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_client_id = Reg(init=UInt(0, width = log2Up(nClients)))
//TODO: Will need id reg for merged release xacts //TODO: Will need id reg for merged release xacts
val init_sharer_cnt = Reg(init=UInt(0, width = log2Up(ln.nClients))) val init_sharer_cnt = Reg(init=UInt(0, width = log2Up(nClients)))
val release_count = if (ln.nClients == 1) UInt(0) else Reg(init=UInt(0, width = log2Up(ln.nClients))) val release_count = if (nClients == 1) UInt(0) else Reg(init=UInt(0, width = log2Up(nClients)))
val probe_flags = Reg(init=Bits(0, width = ln.nClients)) val probe_flags = Reg(init=Bits(0, width = nClients))
val curr_p_id = PriorityEncoder(probe_flags) val curr_p_id = PriorityEncoder(probe_flags)
val pending_outer_write = co.messageHasData(xact) val pending_outer_write = co.messageHasData(xact)
@ -174,12 +172,12 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentC
xact.addr, UInt(trackerId), c_rel.payload.data) xact.addr, UInt(trackerId), c_rel.payload.data)
val outer_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId)) val outer_read = Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId))
val probe_initial_flags = Bits(width = ln.nClients) val probe_initial_flags = Bits(width = nClients)
probe_initial_flags := Bits(0) probe_initial_flags := Bits(0)
if (ln.nClients > 1) { if (nClients > 1) {
// issue self-probes for uncached read xacts to facilitate I$ coherence // issue self-probes for uncached read xacts to facilitate I$ coherence
val probe_self = Bool(true) //co.needsSelfProbe(io.inner.acquire.bits.payload) val probe_self = Bool(true) //co.needsSelfProbe(io.inner.acquire.bits.payload)
val myflag = Mux(probe_self, Bits(0), UIntToOH(c_acq.header.src(log2Up(ln.nClients)-1,0))) val myflag = Mux(probe_self, Bits(0), UIntToOH(c_acq.header.src(log2Up(nClients)-1,0)))
probe_initial_flags := ~(io.tile_incoherent | myflag) probe_initial_flags := ~(io.tile_incoherent | myflag)
} }
@ -219,9 +217,9 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentC
when( io.inner.acquire.valid ) { when( io.inner.acquire.valid ) {
xact := c_acq.payload xact := c_acq.payload
init_client_id := c_acq.header.src init_client_id := c_acq.header.src
init_sharer_cnt := UInt(ln.nClients) // TODO: Broadcast only init_sharer_cnt := UInt(nClients) // TODO: Broadcast only
probe_flags := probe_initial_flags probe_flags := probe_initial_flags
if(ln.nClients > 1) { if(nClients > 1) {
release_count := PopCount(probe_initial_flags) release_count := PopCount(probe_initial_flags)
state := Mux(probe_initial_flags.orR, s_probe, state := Mux(probe_initial_flags.orR, s_probe,
Mux(needs_outer_write, s_mem_write, Mux(needs_outer_write, s_mem_write,
@ -244,7 +242,7 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentC
io.outer.acquire.bits.payload := outer_write_rel io.outer.acquire.bits.payload := outer_write_rel
when(io.outer.acquire.ready) { when(io.outer.acquire.ready) {
io.inner.release.ready := Bool(true) io.inner.release.ready := Bool(true)
if(ln.nClients > 1) release_count := release_count - UInt(1) if(nClients > 1) release_count := release_count - UInt(1)
when(release_count === UInt(1)) { when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write, state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant)) Mux(pending_outer_read, s_mem_read, s_make_grant))
@ -252,7 +250,7 @@ class AcquireTracker(trackerId: Int, bankId: Int)(implicit conf: CoherenceAgentC
} }
} .otherwise { } .otherwise {
io.inner.release.ready := Bool(true) io.inner.release.ready := Bool(true)
if(ln.nClients > 1) release_count := release_count - UInt(1) if(nClients > 1) release_count := release_count - UInt(1)
when(release_count === UInt(1)) { when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write, state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant)) Mux(pending_outer_read, s_mem_read, s_make_grant))