CacheTest.scala 5.1 KB
Newer Older
Z
Zihao Yu 已提交
1 2 3 4 5 6 7 8 9
package top

import device._
import utils._

import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils

Z
Zihao Yu 已提交
10 11 12 13 14 15
// To run the following cache random test, do the following:
// * uncomment the following class
// * comment the NOOPSimTop class in noop/src/test/scala/top/NOOPSim.scala
// * define the macro CACHE_TEST in noop/src/test/csrc/emu.h:141
// * run 'make cache' under noop/

16
/*
Z
Zihao Yu 已提交
17 18 19 20 21 22 23 24 25
class NOOPSimTop extends Module {
  val io = IO(new Bundle{
    val difftest = new DiffTestIO
  })

  val memBase = 0x80000000L
  val cacheSizeKB = 1 // Bytes
  val memSizeB = 4096 // Bytes
  val NRmemBlock = memSizeB / 8
26
  val printCnt = 100000
Z
Zihao Yu 已提交
27 28 29 30 31 32

  val Name = "dcache"
  val in = WireInit(0.U.asTypeOf(new SimpleBusUC(userBits = 33)))
  val cohIn = WireInit(0.U.asTypeOf(new SimpleBusUC))
  val mmioOut = WireInit(0.U.asTypeOf(new SimpleBusUC))

33
  val cacheOut = Cache(in, mmioOut, "b00".U)(CacheConfig(name = Name, totalSize = cacheSizeKB, userBits = 33, ways = 4))
Z
Zihao Yu 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
  val mem = Module(new AXI4RAM(memByte = memSizeB, useBlackBox = false))
  mem.io.in <> cacheOut.mem.toAXI4()
  cacheOut.coh <> cohIn

  def addrInRange(x: UInt) = (x >= memBase.U) && x < (memBase + memSizeB).U

  val perfCntHit = WireInit(false.B)
  BoringUtils.addSink(perfCntHit, "perfCntCondM" + Name + "Hit")

  val s_init_req :: s_init_resp :: s_test :: Nil = Enum(3)
  val state = RegInit(s_init_req)

  val initCnt = Counter(NRmemBlock)
  switch (state) {
    is (s_init_req) {
      when (in.req.fire()) { state := s_init_resp }
    }
    is (s_init_resp) {
      when (in.resp.fire()) {
        val wrap = initCnt.inc()
        state := Mux(wrap, s_test, s_init_req)
55 56 57 58
        when (wrap) {
          printf("One '.' for handling %d requests from CPU, and one '@' for handling %d coherence requests\n",
            printCnt.U, printCnt.U)
        }
Z
Zihao Yu 已提交
59 60 61 62 63 64 65 66 67 68
      }
    }
  }

  val initAddr = memBase.U + initCnt.value * 8.U
  val initWmask = 0xff.U
  val initCmd = SimpleBusCmd.write

  val randBundle = new Bundle {
    val isWrite = Bool()
Z
Zihao Yu 已提交
69
    val readyChoose = UInt(2.W)
Z
Zihao Yu 已提交
70 71
    val wmask = UInt(8.W)
    val addr = UInt(log2Up(NRmemBlock).W)
72
    val cohChoose = UInt(1.W)
73
    val cohAddr = UInt(log2Up(NRmemBlock).W)
Z
Zihao Yu 已提交
74
    val cohReadyChoose = UInt(2.W)
Z
Zihao Yu 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88
  }
  val rand = LFSR64(true.B).asTypeOf(randBundle)
  val randAddr = memBase.U + rand.addr * 8.U
  val randWmask = rand.wmask
  val randCmd = Mux(rand.isWrite, SimpleBusCmd.write, SimpleBusCmd.read)

  val addr = Mux(state === s_test, randAddr, initAddr)
  val wmask = Mux(state === s_test, randWmask, initWmask)
  val cmd = Mux(state === s_test, randCmd, initCmd)
  val wdata = Fill(2, addr)
  val user = Cat(addr, Mux(state === s_test, rand.isWrite, true.B))
  in.req.bits.apply(addr = addr, size = "b11".U, user = user,
    wdata = wdata, wmask = wmask, cmd = cmd)
  in.req.valid := (state === s_init_req) || (state === s_test)
Z
Zihao Yu 已提交
89
  in.resp.ready := rand.readyChoose =/= 0.U
Z
Zihao Yu 已提交
90

91 92 93 94 95 96 97 98
  val cohInflight = RegInit(false.B)
  when (cohIn.resp.fire()) {
    val resp = cohIn.resp.bits
    val isProbeEnd = resp.isProbeMiss() || (resp.cmd === SimpleBusCmd.readLast)
    when (isProbeEnd) { cohInflight := false.B }
  }
  when (cohIn.req.fire()) { cohInflight := true.B }

99 100
  cohIn.req.bits.apply(addr = rand.cohAddr * 8.U + memBase.U, size = "b11".U,
    wdata = 0.U, wmask = 0.U, cmd = SimpleBusCmd.probe)
101
  cohIn.req.valid := (state === s_test) && rand.cohChoose === 0.U && !cohInflight
Z
Zihao Yu 已提交
102
  cohIn.resp.ready := rand.cohReadyChoose =/= 0.U
103

104 105
  when (Counter((state === s_test) && in.resp.fire(), printCnt)._2) { printf(".") }
  when (Counter((state === s_test) && cohIn.req.fire(), printCnt)._2) { printf("@") }
Z
Zihao Yu 已提交
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

  Debug(false) {
    when (in.req.fire()) { printf(p"${GTimer()},[in.req] ${in.req.bits}\n") }
  }

  def checkData(addr: UInt, data: UInt): Bool = data === Fill(2, addr)
  def checkDataMask(addr: UInt, data: UInt): Bool = {
    val mask = "hffffffc0".U
    (data & Fill(2, mask)) === Fill(2, addr & mask)
  }

  assert(!(cacheOut.mem.req.valid && !addrInRange(cacheOut.mem.req.bits.addr)),
    "bad addr = %x", cacheOut.mem.req.bits.addr)

  // check rdata from cache
  when (in.resp.valid && !in.resp.bits.user.get(0)) {
    val addr = in.resp.bits.user.get(32,1)
    assert(checkData(addr, in.resp.bits.rdata), "%d: bad rdata = %x at addr = %x",
      GTimer(), in.resp.bits.rdata, addr)
  }

  // check wdata to mem
  when (cacheOut.mem.req.valid && cacheOut.mem.req.bits.isWrite()) {
    val addr = cacheOut.mem.req.bits.addr(31,0)
    assert(checkDataMask(addr, cacheOut.mem.req.bits.wdata), "%d: bad wdata = %x at addr = %x",
      GTimer(), cacheOut.mem.req.bits.wdata, addr)
  }

134 135 136 137 138 139 140 141 142 143 144
  // check rdata from cohIn
  val cohAddr = RegEnable(cohIn.req.bits.addr(31,0), cohIn.req.fire())
  when (cohIn.resp.valid) {
    val resp = cohIn.resp.bits
    val isRead = resp.cmd === SimpleBusCmd.readLast || resp.cmd === SimpleBusCmd.read
    val isProbeResp = resp.isProbeHit() || resp.isProbeMiss()
    assert(isRead || isProbeResp)
    assert(!(isRead && !checkDataMask(cohAddr, cohIn.resp.bits.rdata)), "%d: bad rdata = %x at addr = %x",
      GTimer(), cohIn.resp.bits.rdata, cohAddr)
  }

Z
Zihao Yu 已提交
145 146 147 148
  // only use to keep consistent with NOOPSimTop
  io.difftest := DontCare
  dontTouch(io.difftest)
}
149
*/