70 lines
1.8 KiB
Scala
70 lines
1.8 KiB
Scala
package example
|
|
|
|
import chisel3._
|
|
import chisel3.util._
|
|
import freechips.rocketchip.subsystem.{BaseSubsystem, CacheBlockBytes}
|
|
import freechips.rocketchip.config.{Parameters, Field}
|
|
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, IdRange}
|
|
import testchipip.TLHelper
|
|
|
|
case class InitZeroConfig(base: BigInt, size: BigInt)
|
|
case object InitZeroKey extends Field[InitZeroConfig]
|
|
|
|
class InitZero(implicit p: Parameters) extends LazyModule {
|
|
val node = TLHelper.makeClientNode(
|
|
name = "init-zero", sourceId = IdRange(0, 1))
|
|
|
|
lazy val module = new InitZeroModuleImp(this)
|
|
}
|
|
|
|
class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
|
|
val config = p(InitZeroKey)
|
|
|
|
val (mem, edge) = outer.node.out(0)
|
|
val addrBits = edge.bundle.addressBits
|
|
val blockBytes = p(CacheBlockBytes)
|
|
|
|
require(config.size % blockBytes == 0)
|
|
|
|
val s_init :: s_write :: s_resp :: s_done :: Nil = Enum(4)
|
|
val state = RegInit(s_init)
|
|
|
|
val addr = Reg(UInt(addrBits.W))
|
|
val bytesLeft = Reg(UInt(log2Ceil(config.size+1).W))
|
|
|
|
mem.a.valid := state === s_write
|
|
mem.a.bits := edge.Put(
|
|
fromSource = 0.U,
|
|
toAddress = addr,
|
|
lgSize = log2Ceil(blockBytes).U,
|
|
data = 0.U)._2
|
|
mem.d.ready := state === s_resp
|
|
|
|
when (state === s_init) {
|
|
addr := config.base.U
|
|
bytesLeft := config.size.U
|
|
state := s_write
|
|
}
|
|
|
|
when (edge.done(mem.a)) {
|
|
addr := addr + blockBytes.U
|
|
bytesLeft := bytesLeft - blockBytes.U
|
|
state := s_resp
|
|
}
|
|
|
|
when (mem.d.fire()) {
|
|
state := Mux(bytesLeft === 0.U, s_done, s_write)
|
|
}
|
|
}
|
|
|
|
trait HasPeripheryInitZero { this: BaseSubsystem =>
|
|
implicit val p: Parameters
|
|
|
|
val initZero = LazyModule(new InitZero()(p))
|
|
fbus.fromPort(Some("init-zero"))() := initZero.node
|
|
}
|
|
|
|
trait HasPeripheryInitZeroModuleImp extends LazyModuleImp {
|
|
// Don't need anything here
|
|
}
|