diff --git a/generators/example/src/main/scala/ConfigMixins.scala b/generators/example/src/main/scala/ConfigMixins.scala index 313129f2..a829db22 100644 --- a/generators/example/src/main/scala/ConfigMixins.scala +++ b/generators/example/src/main/scala/ConfigMixins.scala @@ -159,3 +159,14 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => { } } }) + +// DOC include start: WithInitZero +class WithInitZero(base: BigInt, size: BigInt) extends Config((site, here, up) => { + case InitZeroKey => InitZeroConfig(base, size) +}) + +class WithInitZeroTop extends Config((site, here, up) => { + case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => + Module(LazyModule(new TopWithInitZero()(p)).module) +}) +// DOC include end: WithInitZero diff --git a/generators/example/src/main/scala/InitZero.scala b/generators/example/src/main/scala/InitZero.scala new file mode 100644 index 00000000..3a90bfcc --- /dev/null +++ b/generators/example/src/main/scala/InitZero.scala @@ -0,0 +1,69 @@ +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 +} diff --git a/generators/example/src/main/scala/RegisterNodeExample.scala b/generators/example/src/main/scala/RegisterNodeExample.scala new file mode 100644 index 00000000..a4e2cb02 --- /dev/null +++ b/generators/example/src/main/scala/RegisterNodeExample.scala @@ -0,0 +1,177 @@ +// DOC include start: MyDeviceController + +import chisel3._ +import chisel3.util._ +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.regmapper._ +import freechips.rocketchip.tilelink.TLRegisterNode + +class MyDeviceController(implicit p: Parameters) extends LazyModule { + val device = new SimpleDevice("my-device", Seq("tutorial,my-device0")) + val node = TLRegisterNode( + address = Seq(AddressSet(0x10028000, 0xfff)), + device = device, + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { + val bigReg = RegInit(0.U(64.W)) + val mediumReg = RegInit(0.U(32.W)) + val smallReg = RegInit(0.U(16.W)) + + val tinyReg0 = RegInit(0.U(4.W)) + val tinyReg1 = RegInit(0.U(4.W)) + + node.regmap( + 0x00 -> Seq(RegField(64, bigReg)), + 0x08 -> Seq(RegField(32, mediumReg)), + 0x0C -> Seq(RegField(16, smallReg)), + 0x0E -> Seq( + RegField(4, tinyReg0), + RegField(4, tinyReg1))) + } +} + +// DOC include end: MyDeviceController + +// DOC include start: MyAXI4DeviceController +import freechips.rocketchip.amba.axi4.AXI4RegisterNode + +class MyAXI4DeviceController(implicit p: Parameters) extends LazyModule { + val node = AXI4RegisterNode( + address = AddressSet(0x10029000, 0xfff), + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { + val bigReg = RegInit(0.U(64.W)) + val mediumReg = RegInit(0.U(32.W)) + val smallReg = RegInit(0.U(16.W)) + + val tinyReg0 = RegInit(0.U(4.W)) + val tinyReg1 = RegInit(0.U(4.W)) + + node.regmap( + 0x00 -> Seq(RegField(64, bigReg)), + 0x08 -> Seq(RegField(32, mediumReg)), + 0x0C -> Seq(RegField(16, smallReg)), + 0x0E -> Seq( + RegField(4, tinyReg0), + RegField(4, tinyReg1))) + } +} +// DOC include end: MyAXI4DeviceController + +class MyQueueRegisters(implicit p: Parameters) extends LazyModule { + val device = new SimpleDevice("my-queue", Seq("tutorial,my-queue0")) + val node = TLRegisterNode( + address = Seq(AddressSet(0x1002A000, 0xfff)), + device = device, + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { +// DOC include start: MyQueueRegisters + // 4-entry 64-bit queue + val queue = Module(new Queue(UInt(64.W), 4)) + + node.regmap( + 0x00 -> Seq(RegField(64, queue.io.deq, queue.io.enq))) +// DOC include end: MyQueueRegisters + } +} + +class MySeparateQueueRegisters(implicit p: Parameters) extends LazyModule { + val device = new SimpleDevice("my-queue", Seq("tutorial,my-queue1")) + val node = TLRegisterNode( + address = Seq(AddressSet(0x1002B000, 0xfff)), + device = device, + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { + val queue = Module(new Queue(UInt(64.W), 4)) + +// DOC include start: MySeparateQueueRegisters + node.regmap( + 0x00 -> Seq(RegField.r(64, queue.io.deq)), + 0x08 -> Seq(RegField.w(64, queue.io.enq))) +// DOC include end: MySeparateQueueRegisters + } +} + +class MyCounterRegisters(implicit p: Parameters) extends LazyModule { + val device = new SimpleDevice("my-counters", Seq("tutorial,my-counters0")) + val node = TLRegisterNode( + address = Seq(AddressSet(0x1002C000, 0xfff)), + device = device, + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { +// DOC include start: MyCounterRegisters + val counter = RegInit(0.U(64.W)) + + def readCounter(ready: Bool): (Bool, UInt) = { + when (ready) { counter := counter - 1.U } + (true.B, counter) + } + + def writeCounter(valid: Bool, bits: UInt): Bool = { + when (valid) { counter := counter + 1.U } + // Ignore bits + true.B + } + + node.regmap( + 0x00 -> Seq(RegField.r(64, readCounter(_))), + 0x08 -> Seq(RegField.w(64, writeCounter(_, _)))) +// DOC include end: MyCounterRegisters + } +} + +class MyCounterReqRespRegisters(implicit p: Parameters) extends LazyModule { + val device = new SimpleDevice("my-counters", Seq("tutorial,my-counters1")) + val node = TLRegisterNode( + address = Seq(AddressSet(0x1002D000, 0xfff)), + device = device, + beatBytes = 8, + concurrency = 1) + + lazy val module = new LazyModuleImp(this) { +// DOC include start: MyCounterReqRespRegisters + val counter = RegInit(0.U(64.W)) + + def readCounter(ivalid: Bool, oready: Bool): (Bool, Bool, UInt) = { + val responding = RegInit(false.B) + + when (ivalid && !responding) { responding := true.B } + + when (responding && oready) { + counter := counter - 1.U + responding := false.B + } + + (!responding, responding, counter) + } + + def writeCounter(ivalid: Bool, oready: Bool, bits: UInt): (Bool, Bool) = { + val responding = RegInit(false.B) + + when (ivalid && !responding) { responding := true.B } + + when (responding && oready) { + counter := counter + 1.U + responding := false.B + } + + (!responding, responding) + } + + node.regmap( + 0x00 -> Seq(RegField.r(64, readCounter(_, _))), + 0x08 -> Seq(RegField.w(64, writeCounter(_, _, _)))) +// DOC include end: MyCounterReqRespRegisters + } +} diff --git a/generators/example/src/main/scala/RocketConfigs.scala b/generators/example/src/main/scala/RocketConfigs.scala index a44fb4d5..cd78b9d2 100644 --- a/generators/example/src/main/scala/RocketConfigs.scala +++ b/generators/example/src/main/scala/RocketConfigs.scala @@ -109,3 +109,13 @@ class Sha3RocketConfig extends Config( new freechips.rocketchip.subsystem.WithInclusiveCache ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.system.BaseConfig) + +// DOC include start: InitZeroRocketConfig +class InitZeroRocketConfig extends Config( + new WithInitZero(0x88000000L, 0x1000L) ++ + new WithInitZeroTop ++ + new WithBootROM ++ + new freechips.rocketchip.subsystem.WithInclusiveCache ++ + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new freechips.rocketchip.system.BaseConfig) +// DOC include end: InitZeroRocketConfig diff --git a/generators/example/src/main/scala/Top.scala b/generators/example/src/main/scala/Top.scala index 4d39a7dd..94bed0de 100644 --- a/generators/example/src/main/scala/Top.scala +++ b/generators/example/src/main/scala/Top.scala @@ -80,3 +80,14 @@ class TopWithDTM(implicit p: Parameters) extends System } class TopWithDTMModule[+L <: TopWithDTM](l: L) extends SystemModule(l) + +//--------------------------------------------------------------------------------------------------------- +// DOC include start: TopWithInitZero +class TopWithInitZero(implicit p: Parameters) extends Top + with HasPeripheryInitZero { + override lazy val module = new TopWithInitZeroModuleImp(this) +} + +class TopWithInitZeroModuleImp(l: TopWithInitZero) extends TopModule(l) + with HasPeripheryInitZeroModuleImp +// DOC include end: TopWithInitZero