2014-09-13 00:31:38 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
2014-04-23 01:55:35 +02:00
|
|
|
package uncore
|
|
|
|
import Chisel._
|
|
|
|
|
2014-08-23 10:19:36 +02:00
|
|
|
case object CacheName extends Field[String]
|
2014-08-08 21:21:57 +02:00
|
|
|
case object NSets extends Field[Int]
|
|
|
|
case object NWays extends Field[Int]
|
2014-08-12 03:35:49 +02:00
|
|
|
case object BlockOffBits extends Field[Int]
|
2014-08-08 21:21:57 +02:00
|
|
|
case object RowBits extends Field[Int]
|
|
|
|
case object WordBits extends Field[Int]
|
|
|
|
case object Replacer extends Field[() => ReplacementPolicy]
|
2014-05-07 10:51:46 +02:00
|
|
|
|
2014-08-12 03:35:49 +02:00
|
|
|
abstract trait CacheParameters extends UsesParameters {
|
|
|
|
val paddrBits = params(PAddrBits)
|
|
|
|
val vaddrBits = params(VAddrBits)
|
|
|
|
val pgIdxBits = params(PgIdxBits)
|
|
|
|
val nSets = params(NSets)
|
|
|
|
val blockOffBits = params(BlockOffBits)
|
|
|
|
val idxBits = log2Up(nSets)
|
|
|
|
val untagBits = blockOffBits + idxBits
|
|
|
|
val tagBits = paddrBits - untagBits
|
2014-08-12 23:55:44 +02:00
|
|
|
val nWays = params(NWays)
|
2014-08-12 03:35:49 +02:00
|
|
|
val wayBits = log2Up(nWays)
|
|
|
|
val isDM = nWays == 1
|
2014-08-12 23:55:44 +02:00
|
|
|
val wordBits = params(WordBits)
|
|
|
|
val wordBytes = wordBits/8
|
|
|
|
val wordOffBits = log2Up(wordBytes)
|
|
|
|
val rowBits = params(RowBits)
|
2014-08-12 03:35:49 +02:00
|
|
|
val rowWords = rowBits/wordBits
|
2014-08-12 23:55:44 +02:00
|
|
|
val rowBytes = rowBits/8
|
2014-08-12 03:35:49 +02:00
|
|
|
val rowOffBits = log2Up(rowBytes)
|
|
|
|
val refillCycles = params(TLDataBits)/rowBits
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract class CacheBundle extends Bundle with CacheParameters
|
|
|
|
abstract class CacheModule extends Module with CacheParameters
|
|
|
|
|
2014-04-23 01:55:35 +02:00
|
|
|
abstract class ReplacementPolicy {
|
|
|
|
def way: UInt
|
|
|
|
def miss: Unit
|
|
|
|
def hit: Unit
|
|
|
|
}
|
|
|
|
|
2014-08-08 21:21:57 +02:00
|
|
|
class RandomReplacement(ways: Int) extends ReplacementPolicy {
|
2014-04-23 01:55:35 +02:00
|
|
|
private val replace = Bool()
|
|
|
|
replace := Bool(false)
|
|
|
|
val lfsr = LFSR16(replace)
|
|
|
|
|
2014-08-08 21:21:57 +02:00
|
|
|
def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0)
|
2014-04-23 01:55:35 +02:00
|
|
|
def miss = replace := Bool(true)
|
|
|
|
def hit = {}
|
|
|
|
}
|
|
|
|
|
2014-08-12 03:35:49 +02:00
|
|
|
abstract class Metadata extends CacheBundle {
|
|
|
|
val tag = Bits(width = tagBits)
|
2014-05-28 22:35:08 +02:00
|
|
|
val coh: CoherenceMetadata
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
|
|
|
|
2014-08-12 03:35:49 +02:00
|
|
|
class MetaReadReq extends CacheBundle {
|
|
|
|
val idx = Bits(width = idxBits)
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
|
|
|
|
2014-08-08 21:21:57 +02:00
|
|
|
class MetaWriteReq[T <: Metadata](gen: T) extends MetaReadReq {
|
2014-08-12 03:35:49 +02:00
|
|
|
val way_en = Bits(width = nWays)
|
2014-05-01 10:44:59 +02:00
|
|
|
val data = gen.clone
|
2014-08-08 21:21:57 +02:00
|
|
|
override def clone = new MetaWriteReq(gen).asInstanceOf[this.type]
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
|
|
|
|
2014-08-12 03:35:49 +02:00
|
|
|
class MetadataArray[T <: Metadata](makeRstVal: () => T) extends CacheModule {
|
2014-05-28 22:35:08 +02:00
|
|
|
val rstVal = makeRstVal()
|
2014-04-23 01:55:35 +02:00
|
|
|
val io = new Bundle {
|
2014-04-24 01:24:20 +02:00
|
|
|
val read = Decoupled(new MetaReadReq).flip
|
2014-05-06 21:59:45 +02:00
|
|
|
val write = Decoupled(new MetaWriteReq(rstVal.clone)).flip
|
2014-08-12 03:35:49 +02:00
|
|
|
val resp = Vec.fill(nWays){rstVal.clone.asOutput}
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
2014-05-06 21:59:45 +02:00
|
|
|
val metabits = rstVal.getWidth
|
2014-08-12 03:35:49 +02:00
|
|
|
val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1)))
|
|
|
|
val rst = rst_cnt < UInt(nSets)
|
2014-05-28 22:35:08 +02:00
|
|
|
val waddr = Mux(rst, rst_cnt, io.write.bits.idx)
|
|
|
|
val wdata = Mux(rst, rstVal, io.write.bits.data).toBits
|
|
|
|
val wmask = Mux(rst, SInt(-1), io.write.bits.way_en)
|
2014-04-23 01:55:35 +02:00
|
|
|
when (rst) { rst_cnt := rst_cnt+UInt(1) }
|
|
|
|
|
2014-08-12 03:35:49 +02:00
|
|
|
val tag_arr = Mem(UInt(width = metabits*nWays), nSets, seqRead = true)
|
2014-04-23 01:55:35 +02:00
|
|
|
when (rst || io.write.valid) {
|
2014-08-12 03:35:49 +02:00
|
|
|
tag_arr.write(waddr, Fill(nWays, wdata), FillInterleaved(metabits, wmask))
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
|
|
|
|
2014-05-28 22:35:08 +02:00
|
|
|
val tags = tag_arr(RegEnable(io.read.bits.idx, io.read.valid))
|
2014-08-12 03:35:49 +02:00
|
|
|
for (w <- 0 until nWays) {
|
2014-05-28 22:35:08 +02:00
|
|
|
val m = tags(metabits*(w+1)-1, metabits*w)
|
2014-05-06 21:59:45 +02:00
|
|
|
io.resp(w) := rstVal.clone.fromBits(m)
|
2014-04-23 01:55:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
io.read.ready := !rst && !io.write.valid // so really this could be a 6T RAM
|
|
|
|
io.write.ready := !rst
|
|
|
|
}
|