tilelink: add BasicBusBlocker device
This commit is contained in:
parent
9f8e3d8879
commit
2dbe882e58
@ -9,23 +9,6 @@ import freechips.rocketchip.regmapper._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
case class BusBlockerParams(
|
|
||||||
controlAddress: BigInt,
|
|
||||||
controlBeatBytes: Int,
|
|
||||||
deviceBeatBytes: Int,
|
|
||||||
pmpRegisters: Int)
|
|
||||||
{
|
|
||||||
val page = 4096
|
|
||||||
val pageBits = log2Ceil(page)
|
|
||||||
val size = (((pmpRegisters * 8) + page - 1) / page) * page
|
|
||||||
|
|
||||||
require (pmpRegisters > 0)
|
|
||||||
require (controlAddress > 0)
|
|
||||||
require (controlAddress % size == 0)
|
|
||||||
require (controlBeatBytes > 0 && isPow2(controlBeatBytes))
|
|
||||||
require (deviceBeatBytes > 0 && isPow2(deviceBeatBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
case class DevicePMPParams(addressBits: Int, pageBits: Int)
|
case class DevicePMPParams(addressBits: Int, pageBits: Int)
|
||||||
class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(params)
|
class DevicePMP(params: DevicePMPParams) extends GenericParameterizedBundle(params)
|
||||||
{
|
{
|
||||||
@ -71,6 +54,28 @@ object DevicePMP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** BusBlocker uses a set of DevicePMP registers to control whether
|
||||||
|
* accesses of certain types are allowed to proceed or bypassed to
|
||||||
|
* a /dev/null device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case class BusBlockerParams(
|
||||||
|
controlAddress: BigInt,
|
||||||
|
controlBeatBytes: Int,
|
||||||
|
deviceBeatBytes: Int,
|
||||||
|
pmpRegisters: Int)
|
||||||
|
{
|
||||||
|
val page = 4096
|
||||||
|
val pageBits = log2Ceil(page)
|
||||||
|
val size = (((pmpRegisters * 8) + page - 1) / page) * page
|
||||||
|
|
||||||
|
require (pmpRegisters > 0)
|
||||||
|
require (controlAddress > 0)
|
||||||
|
require (controlAddress % size == 0)
|
||||||
|
require (controlBeatBytes > 0 && isPow2(controlBeatBytes))
|
||||||
|
require (deviceBeatBytes > 0 && isPow2(deviceBeatBytes))
|
||||||
|
}
|
||||||
|
|
||||||
class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBusBypassBase(params.deviceBeatBytes)
|
class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBusBypassBase(params.deviceBeatBytes)
|
||||||
{
|
{
|
||||||
val device = new SimpleDevice("bus-blocker", Seq("sifive,bus-blocker0"))
|
val device = new SimpleDevice("bus-blocker", Seq("sifive,bus-blocker0"))
|
||||||
@ -100,3 +105,37 @@ class BusBlocker(params: BusBlockerParams)(implicit p: Parameters) extends TLBus
|
|||||||
bar.module.io.bypass := !allow
|
bar.module.io.bypass := !allow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case class BasicBusBlockerParams(
|
||||||
|
controlAddress: BigInt,
|
||||||
|
controlBeatBytes: Int,
|
||||||
|
deviceBeatBytes: Int,
|
||||||
|
deadlock: Boolean = false)
|
||||||
|
|
||||||
|
class BasicBusBlocker(params: BasicBusBlockerParams)(implicit p: Parameters)
|
||||||
|
extends TLBusBypassBase(params.deviceBeatBytes, params.deadlock)
|
||||||
|
{
|
||||||
|
val device = new SimpleDevice("basic-bus-blocker", Seq("sifive,basic-bus-blocker0"))
|
||||||
|
|
||||||
|
val controlNode = TLRegisterNode(
|
||||||
|
address = Seq(AddressSet(params.controlAddress, 0xFFF)),
|
||||||
|
device = device,
|
||||||
|
beatBytes = params.controlBeatBytes)
|
||||||
|
|
||||||
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
val allow = RegInit(true.B)
|
||||||
|
val pending = RegNext(bar.module.io.pending)
|
||||||
|
|
||||||
|
controlNode.regmap(
|
||||||
|
0 -> Seq(RegField (32, allow)),
|
||||||
|
4 -> Seq(RegField.r(32, pending)))
|
||||||
|
|
||||||
|
bar.module.io.bypass := !allow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -49,6 +49,7 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
|||||||
lazy val module = new LazyModuleImp(this) {
|
lazy val module = new LazyModuleImp(this) {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val bypass = Bool(INPUT)
|
val bypass = Bool(INPUT)
|
||||||
|
val pending = Bool(OUTPUT)
|
||||||
})
|
})
|
||||||
|
|
||||||
val (in, edge) = node.in(0)
|
val (in, edge) = node.in(0)
|
||||||
@ -60,6 +61,8 @@ class TLBusBypassBar(implicit p: Parameters) extends LazyModule
|
|||||||
val flight = RegInit(UInt(0, width = log2Ceil(3*edge.client.endSourceId+1)))
|
val flight = RegInit(UInt(0, width = log2Ceil(3*edge.client.endSourceId+1)))
|
||||||
val bypass = RegInit(io.bypass) // synchronous reset required
|
val bypass = RegInit(io.bypass) // synchronous reset required
|
||||||
|
|
||||||
|
io.pending := (flight > 0.U)
|
||||||
|
|
||||||
val (a_first, a_last, _) = edge.firstlast(in.a)
|
val (a_first, a_last, _) = edge.firstlast(in.a)
|
||||||
val (b_first, b_last, _) = edge.firstlast(in.b)
|
val (b_first, b_last, _) = edge.firstlast(in.b)
|
||||||
val (c_first, c_last, _) = edge.firstlast(in.c)
|
val (c_first, c_last, _) = edge.firstlast(in.c)
|
||||||
|
Loading…
Reference in New Issue
Block a user