Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update BasicBusBlocker (chisel3, scala-doc, factory) #2630

Merged
merged 1 commit into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 44 additions & 14 deletions src/main/scala/devices/tilelink/BusBlocker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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) }
}
}
2 changes: 1 addition & 1 deletion src/main/scala/devices/tilelink/ClockBlocker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"))

Expand Down