1
0
rocket-chip/groundtest/src/main/scala/generator.scala

191 lines
5.8 KiB
Scala
Raw Normal View History

2015-10-27 05:37:35 +01:00
package groundtest
import Chisel._
import uncore.tilelink._
import uncore.devices.NTiles
import uncore.constants._
2015-10-27 05:37:35 +01:00
import junctions._
2015-10-30 20:49:57 +01:00
import rocket._
2015-10-27 05:37:35 +01:00
import scala.util.Random
import cde.{Parameters, Field}
case object MaxGenerateRequests extends Field[Int]
2016-05-03 03:25:02 +02:00
case object GeneratorStartAddress extends Field[BigInt]
2015-10-27 05:37:35 +01:00
trait HasGeneratorParameters extends HasGroundTestParameters {
2015-10-27 05:37:35 +01:00
implicit val p: Parameters
val nGens = p(NTiles) * (nUncached + nCached)
2015-11-10 23:39:56 +01:00
val genTimeout = 4096
val maxRequests = p(MaxGenerateRequests)
val startAddress = p(GeneratorStartAddress)
val genWordBits = 32
val genWordBytes = genWordBits / 8
val wordOffset = log2Up(genWordBytes)
val wordSize = MT_WU
2016-05-03 03:25:02 +02:00
require(startAddress % BigInt(genWordBytes) == 0)
2015-11-10 23:39:56 +01:00
}
class UncachedTileLinkGenerator(id: Int)
(implicit p: Parameters) extends TLModule()(p) with HasGeneratorParameters {
2015-10-27 05:37:35 +01:00
private val tlBlockOffset = tlBeatAddrBits + tlByteAddrBits
val io = new Bundle {
2015-10-28 00:42:31 +01:00
val mem = new ClientUncachedTileLinkIO
val finished = Bool(OUTPUT)
}
2015-10-27 05:37:35 +01:00
val (s_start :: s_put :: s_get :: s_finished :: Nil) = Enum(Bits(), 4)
val state = Reg(init = s_start)
val (req_cnt, req_wrap) = Counter(io.mem.grant.fire(), maxRequests)
2015-10-27 05:37:35 +01:00
val sending = Reg(init = Bool(false))
when (state === s_start) {
sending := Bool(true)
state := s_put
}
when (io.mem.acquire.fire()) { sending := Bool(false) }
when (io.mem.grant.fire()) { sending := Bool(true) }
when (req_wrap) { state := Mux(state === s_put, s_get, s_finished) }
2015-10-27 05:37:35 +01:00
2015-11-10 23:39:56 +01:00
val timeout = Timer(genTimeout, io.mem.acquire.fire(), io.mem.grant.fire())
assert(!timeout, s"Uncached generator ${id} timed out waiting for grant")
2015-10-27 05:37:35 +01:00
io.finished := (state === s_finished)
val part_of_full_addr =
if (log2Ceil(nGens) > 0) {
Cat(UInt(id, log2Ceil(nGens)),
UInt(0, wordOffset))
} else {
UInt(0, wordOffset)
}
val full_addr = UInt(startAddress) + Cat(req_cnt, part_of_full_addr)
val addr_block = full_addr >> UInt(tlBlockOffset)
val addr_beat = full_addr(tlBlockOffset - 1, tlByteAddrBits)
val addr_byte = full_addr(tlByteAddrBits - 1, 0)
val data_prefix = Cat(UInt(id, log2Up(nGens)), req_cnt)
val word_data = Wire(UInt(width = genWordBits))
word_data := Cat(data_prefix, full_addr)
val beat_data = Fill(tlDataBits / genWordBits, word_data)
val wshift = Cat(beatOffset(full_addr), UInt(0, wordOffset))
val wmask = Fill(genWordBits / 8, Bits(1, 1)) << wshift
2015-10-27 05:37:35 +01:00
val put_acquire = Put(
2015-10-27 05:37:35 +01:00
client_xact_id = UInt(0),
addr_block = addr_block,
addr_beat = addr_beat,
data = beat_data,
wmask = Some(wmask),
alloc = Bool(false))
2015-10-27 05:37:35 +01:00
val get_acquire = Get(
2015-10-27 05:37:35 +01:00
client_xact_id = UInt(0),
addr_block = addr_block,
addr_beat = addr_beat,
addr_byte = addr_byte,
operand_size = wordSize,
alloc = Bool(false))
2015-10-27 05:37:35 +01:00
io.mem.acquire.valid := sending && !io.finished
2015-10-28 00:42:31 +01:00
io.mem.acquire.bits := Mux(state === s_put, put_acquire, get_acquire)
io.mem.grant.ready := !sending && !io.finished
2015-10-27 05:37:35 +01:00
def wordFromBeat(addr: UInt, dat: UInt) = {
val shift = Cat(beatOffset(addr), UInt(0, wordOffset + 3))
(dat >> shift)(genWordBits - 1, 0)
}
assert(!io.mem.grant.valid || state =/= s_get ||
wordFromBeat(full_addr, io.mem.grant.bits.data) === word_data,
2015-10-30 20:49:57 +01:00
s"Get received incorrect data in uncached generator ${id}")
def beatOffset(addr: UInt) = // TODO zero-width
if (tlByteAddrBits > wordOffset) addr(tlByteAddrBits - 1, wordOffset)
else UInt(0)
2015-10-27 05:37:35 +01:00
}
2015-10-28 00:42:31 +01:00
2015-10-30 20:49:57 +01:00
class HellaCacheGenerator(id: Int)
(implicit p: Parameters) extends L1HellaCacheModule()(p) with HasGeneratorParameters {
2015-10-30 20:49:57 +01:00
val io = new Bundle {
val finished = Bool(OUTPUT)
val mem = new HellaCacheIO
}
2015-11-19 07:54:05 +01:00
val timeout = Timer(genTimeout, io.mem.req.fire(), io.mem.resp.valid)
2015-11-10 23:39:56 +01:00
assert(!timeout, s"Cached generator ${id} timed out waiting for response")
2015-10-30 20:49:57 +01:00
val (s_start :: s_write :: s_read :: s_finished :: Nil) = Enum(Bits(), 4)
val state = Reg(init = s_start)
val sending = Reg(init = Bool(false))
val (req_cnt, req_wrap) = Counter(io.mem.resp.valid, maxRequests)
2015-10-30 20:49:57 +01:00
val part_of_req_addr =
if (log2Ceil(nGens) > 0) {
Cat(UInt(id, log2Ceil(nGens)),
UInt(0, wordOffset))
} else {
UInt(0, wordOffset)
}
val req_addr = UInt(startAddress) + Cat(req_cnt, part_of_req_addr)
val req_data = Cat(UInt(id, log2Up(nGens)), req_addr)
2015-10-30 20:49:57 +01:00
io.mem.req.valid := sending && !io.finished
2015-10-30 20:49:57 +01:00
io.mem.req.bits.addr := req_addr
io.mem.req.bits.data := req_data
io.mem.req.bits.typ := wordSize
2015-10-30 20:49:57 +01:00
io.mem.req.bits.cmd := Mux(state === s_write, M_XWR, M_XRD)
io.mem.req.bits.tag := UInt(0)
when (state === s_start) { sending := Bool(true); state := s_write }
when (io.mem.req.fire()) { sending := Bool(false) }
when (io.mem.resp.valid) { sending := Bool(true) }
2015-10-30 20:49:57 +01:00
when (req_wrap) { state := Mux(state === s_write, s_read, s_finished) }
2015-10-30 20:49:57 +01:00
io.finished := (state === s_finished)
def data_match(recv: Bits, expected: Bits): Bool = {
val recv_resized = Wire(Bits(width = genWordBits))
val exp_resized = Wire(Bits(width = genWordBits))
recv_resized := recv
exp_resized := expected
recv_resized === exp_resized
}
2015-10-30 20:49:57 +01:00
assert(!io.mem.resp.valid || !io.mem.resp.bits.has_data ||
data_match(io.mem.resp.bits.data, req_data),
2015-10-30 20:49:57 +01:00
s"Received incorrect data in cached generator ${id}")
}
2015-11-19 07:54:05 +01:00
2015-11-19 05:53:36 +01:00
class GeneratorTest(id: Int)(implicit p: Parameters)
extends GroundTest()(p) with HasGeneratorParameters {
2015-11-19 05:53:36 +01:00
val totalGens = nUncached + nCached
2015-11-19 07:54:05 +01:00
val cached = List.tabulate(nCached) { i =>
val realId = id * totalGens + i
Module(new HellaCacheGenerator(realId))
2015-11-19 07:54:05 +01:00
}
val uncached = List.tabulate(nUncached) { i =>
val realId = id * totalGens + nCached + i
Module(new UncachedTileLinkGenerator(realId))
2015-11-19 07:54:05 +01:00
}
io.cache <> cached.map(_.io.mem)
io.mem <> uncached.map(_.io.mem)
val gen_finished = cached.map(_.io.finished) ++ uncached.map(_.io.finished)
2015-11-19 07:54:05 +01:00
io.finished := gen_finished.reduce(_ && _)
}