From 5d96dfb1d9fed07fc48d7e72d8a572dc604b471a Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 3 Sep 2020 15:36:14 -0700 Subject: [PATCH] update BasicBusBlocker - convert to chisel3 - upstream factory helper from sifive-blocks - improve detail of scaladoc comments --- .../scala/devices/tilelink/BusBlocker.scala | 58 ++++++++++++++----- .../scala/devices/tilelink/ClockBlocker.scala | 2 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/main/scala/devices/tilelink/BusBlocker.scala b/src/main/scala/devices/tilelink/BusBlocker.scala index eddd38bf2f..44c88e3720 100644 --- a/src/main/scala/devices/tilelink/BusBlocker.scala +++ b/src/main/scala/devices/tilelink/BusBlocker.scala @@ -2,32 +2,44 @@ package freechips.rocketchip.devices.tilelink -import Chisel._ +import chisel3._ import freechips.rocketchip.config.Parameters -import freechips.rocketchip.diplomacy._ -import freechips.rocketchip.regmapper._ -import freechips.rocketchip.tilelink._ -import freechips.rocketchip.util._ - -/** BasicBusBlocker uses a single bit register to control whether - * accesses of all types are allowed to proceed or bypassed to - * a /dev/null device. It has a second bit register to report - * whether any requests are pending on either path. - */ +import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp, SimpleDevice} +import freechips.rocketchip.regmapper.{RegField, RegFieldDesc} +import freechips.rocketchip.tilelink.{TLFragmenter, TLRegisterNode, TLBusWrapper, TLNameNode, TLNode} +/** Parameterize a BasicBusBlocker. + * + * @param controlAddress Base address for the device's control registers. + * @param controlBeatBytes Datapath width of control port. + * @param blockedBeatBytes Datapath width of tilelink channel being blocked. (Used to set internal error device width.) + * @param deadlock If true, backpressure all requests while `allow` is false. If false, return error responses while `allow` is false. + */ case class BasicBusBlockerParams( controlAddress: BigInt, controlBeatBytes: Int, - deviceBeatBytes: Int, + blockedBeatBytes: Int, deadlock: Boolean = false) +{ + val controlSize = 0x1000 +} +/** BasicBusBlocker is an adapter device that allows for software control and monitoring of TL transaction progress. + * + * The device uses one register to control whether any accesses are allowed to proceed along their original route, + * or are instead bypassed to an internal /dev/null device that rejects the transaction in some way. + * The device uses a second register to report whether any requests are outstanding beyond the blocker, + * i.e. a transaction is ongoing pending a response from some outward device. + * The device defaults to allowing transactions to proceed, i.e. `allow` defaults to `TRUE`. + * Even when `allow` is set to `FALSE`, responses to previously-outstanding transactions are still able to drain. + */ class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters) - extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock) + extends TLBusBypassBase(params.blockedBeatBytes, params.deadlock) { val device = new SimpleDevice("basic-bus-blocker", Seq("sifive,basic-bus-blocker0")) val controlNode = TLRegisterNode( - address = Seq(AddressSet(params.controlAddress, 0xFFF)), + address = Seq(AddressSet(params.controlAddress, params.controlSize-1)), device = device, beatBytes = params.controlBeatBytes) @@ -46,3 +58,21 @@ class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters) bar.module.io.bypass := !allow } } + +object BasicBusBlocker { + def apply(blockerAddr: BigInt, controlBus: TLBusWrapper, beatBytes: Int, name: String)(implicit p: Parameters): TLNode = { + apply(Some(blockerAddr), controlBus, beatBytes, name) + } + + /** This factory optionally creates a BasicBusBlocker with its control port attached to the specified external bus. + * + * It returns the datapath node for use in some chain of connections whose traffic is to be blocked. + */ + def apply(blockerAddrOpt: Option[BigInt], controlBus: TLBusWrapper, beatBytes: Int, name: String)(implicit p: Parameters): TLNode = { + blockerAddrOpt.map { a => + val bus_blocker = LazyModule(new BasicBusBlocker(BasicBusBlockerParams(a, controlBus.beatBytes, beatBytes))) + controlBus.coupleTo(s"bus_blocker_for_$name") { bus_blocker.controlNode := TLFragmenter(controlBus) := _ } + bus_blocker.node + } .getOrElse { TLNameNode(name) } + } +} diff --git a/src/main/scala/devices/tilelink/ClockBlocker.scala b/src/main/scala/devices/tilelink/ClockBlocker.scala index 6db8768940..58e5a71996 100644 --- a/src/main/scala/devices/tilelink/ClockBlocker.scala +++ b/src/main/scala/devices/tilelink/ClockBlocker.scala @@ -16,7 +16,7 @@ import freechips.rocketchip.util._ */ class TLClockBlocker(params: BasicBusBlockerParams)(implicit p: Parameters) - extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock) + extends TLBusBypassBase(params.blockedBeatBytes, params.deadlock) { val device = new SimpleDevice("clock-blocker", Seq("sifive,clock-blocker0"))