1
0
rocket-chip/uncore/src/main/scala/cache.scala

99 lines
3.0 KiB
Scala
Raw Normal View History

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]
case object NSets extends Field[Int]
case object NWays extends Field[Int]
case object BlockOffBits extends Field[Int]
case object RowBits extends Field[Int]
case object WordBits extends Field[Int]
case object Replacer extends Field[() => ReplacementPolicy]
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)
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)
val rowWords = rowBits/wordBits
2014-08-12 23:55:44 +02:00
val rowBytes = rowBits/8
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
}
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)
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 = {}
}
abstract class Metadata extends CacheBundle {
val tag = Bits(width = tagBits)
val coh: CoherenceMetadata
2014-04-23 01:55:35 +02:00
}
class MetaReadReq extends CacheBundle {
val idx = Bits(width = idxBits)
2014-04-23 01:55:35 +02:00
}
class MetaWriteReq[T <: Metadata](gen: T) extends MetaReadReq {
val way_en = Bits(width = nWays)
2014-05-01 10:44:59 +02:00
val data = gen.clone
override def clone = new MetaWriteReq(gen).asInstanceOf[this.type]
2014-04-23 01:55:35 +02:00
}
class MetadataArray[T <: Metadata](makeRstVal: () => T) extends CacheModule {
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
val write = Decoupled(new MetaWriteReq(rstVal.clone)).flip
val resp = Vec.fill(nWays){rstVal.clone.asOutput}
2014-04-23 01:55:35 +02:00
}
val metabits = rstVal.getWidth
val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1)))
val rst = rst_cnt < UInt(nSets)
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) }
val tag_arr = Mem(UInt(width = metabits*nWays), nSets, seqRead = true)
2014-04-23 01:55:35 +02:00
when (rst || io.write.valid) {
tag_arr.write(waddr, Fill(nWays, wdata), FillInterleaved(metabits, wmask))
2014-04-23 01:55:35 +02:00
}
val tags = tag_arr(RegEnable(io.read.bits.idx, io.read.valid))
for (w <- 0 until nWays) {
val m = tags(metabits*(w+1)-1, metabits*w)
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
}