Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
commit
9efe1c448e
@ -45,7 +45,7 @@ class WithNBigCores(n: Int) extends Config((site, here, up) => {
|
|||||||
icache = Some(ICacheParams(
|
icache = Some(ICacheParams(
|
||||||
rowBits = site(SystemBusKey).beatBits,
|
rowBits = site(SystemBusKey).beatBits,
|
||||||
blockBytes = site(CacheBlockBytes))))
|
blockBytes = site(CacheBlockBytes))))
|
||||||
List.fill(n)(big) ++ up(RocketTilesKey, site)
|
List.tabulate(n)(i => big.copy(hartid = i))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ class WithNSmallCores(n: Int) extends Config((site, here, up) => {
|
|||||||
nWays = 1,
|
nWays = 1,
|
||||||
nTLBEntries = 4,
|
nTLBEntries = 4,
|
||||||
blockBytes = site(CacheBlockBytes))))
|
blockBytes = site(CacheBlockBytes))))
|
||||||
List.fill(n)(small) ++ up(RocketTilesKey, site)
|
List.tabulate(n)(i => small.copy(hartid = i))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ class WithNTinyCores(n: Int) extends Config((site, here, up) => {
|
|||||||
nWays = 1,
|
nWays = 1,
|
||||||
nTLBEntries = 4,
|
nTLBEntries = 4,
|
||||||
blockBytes = site(CacheBlockBytes))))
|
blockBytes = site(CacheBlockBytes))))
|
||||||
List.fill(n)(tiny) ++ up(RocketTilesKey, site)
|
List.tabulate(n)(i => tiny.copy(hartid = i))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
private val crossing = p(RocketCrossing)
|
private val crossing = p(RocketCrossing)
|
||||||
private val tileParams = p(RocketTilesKey)
|
private val tileParams = p(RocketTilesKey)
|
||||||
val nRocketTiles = tileParams.size
|
val nRocketTiles = tileParams.size
|
||||||
|
val hartIdList = tileParams.map(_.hartid)
|
||||||
|
|
||||||
// Handle interrupts to be routed directly into each tile
|
// Handle interrupts to be routed directly into each tile
|
||||||
// TODO: figure out how to merge the localIntNodes and coreIntXbar below
|
// TODO: figure out how to merge the localIntNodes and coreIntXbar below
|
||||||
@ -34,8 +35,8 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
|
|
||||||
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
||||||
// according to the specified type of clock crossing.
|
// according to the specified type of clock crossing.
|
||||||
val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex
|
val wiringTuple = localIntNodes.zip(tileParams)
|
||||||
val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case ((lip, tp), i) =>
|
val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case (lip, tp) =>
|
||||||
val pWithExtra = p.alterPartial {
|
val pWithExtra = p.alterPartial {
|
||||||
case TileKey => tp
|
case TileKey => tp
|
||||||
case BuildRoCC => tp.rocc
|
case BuildRoCC => tp.rocc
|
||||||
@ -44,19 +45,19 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
|
|
||||||
val wrapper = crossing match {
|
val wrapper = crossing match {
|
||||||
case SynchronousCrossing(params) => {
|
case SynchronousCrossing(params) => {
|
||||||
val wrapper = LazyModule(new SyncRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case AsynchronousCrossing(depth, sync) => {
|
case AsynchronousCrossing(depth, sync) => {
|
||||||
val wrapper = LazyModule(new AsyncRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) }
|
||||||
wrapper
|
wrapper
|
||||||
}
|
}
|
||||||
case RationalCrossing(direction) => {
|
case RationalCrossing(direction) => {
|
||||||
val wrapper = LazyModule(new RationalRocketTile(tp, i)(pWithExtra))
|
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
||||||
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
||||||
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) }
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) }
|
||||||
wrapper
|
wrapper
|
||||||
@ -108,8 +109,12 @@ trait HasRocketTilesModuleImp extends LazyModuleImp
|
|||||||
with HasPeripheryDebugModuleImp {
|
with HasPeripheryDebugModuleImp {
|
||||||
val outer: HasRocketTiles
|
val outer: HasRocketTiles
|
||||||
|
|
||||||
// TODO make this less gross and/or support tiles with differently sized reset vectors
|
def resetVectorBits: Int = {
|
||||||
def resetVectorBits: Int = outer.paddrBits
|
// Consider using the minimum over all widths, rather than enforcing homogeneity
|
||||||
|
val vectors = outer.rocket_tiles.map(_.module.io.reset_vector)
|
||||||
|
require(vectors.tail.forall(_.getWidth == vectors.head.getWidth))
|
||||||
|
vectors.head.getWidth
|
||||||
|
}
|
||||||
val rocket_tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedRocketTileInputs()(p.alterPartial {
|
val rocket_tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedRocketTileInputs()(p.alterPartial {
|
||||||
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
||||||
})))
|
})))
|
||||||
@ -123,7 +128,7 @@ trait HasRocketTilesModuleImp extends LazyModuleImp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default values for tile inputs; may be overriden in other traits
|
// Default values for tile inputs; may be overriden in other traits
|
||||||
rocket_tile_inputs.zipWithIndex.foreach { case(wire, i) =>
|
rocket_tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
||||||
wire.clock := clock
|
wire.clock := clock
|
||||||
wire.reset := reset
|
wire.reset := reset
|
||||||
wire.hartid := UInt(i)
|
wire.hartid := UInt(i)
|
||||||
|
@ -125,5 +125,4 @@ trait HasSystemBus extends HasInterruptBus {
|
|||||||
val sbus = LazyModule(new SystemBus(sbusParams))
|
val sbus = LazyModule(new SystemBus(sbusParams))
|
||||||
|
|
||||||
def sharedMemoryTLEdge: TLEdge = sbus.busView
|
def sharedMemoryTLEdge: TLEdge = sbus.busView
|
||||||
def paddrBits: Int = sbus.busView.bundle.addressBits
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
|
|||||||
|
|
||||||
val a_opcodes = Vec(AccessAck, AccessAck, AccessAckData, AccessAckData, AccessAckData, HintAck, Grant)
|
val a_opcodes = Vec(AccessAck, AccessAck, AccessAckData, AccessAckData, AccessAckData, HintAck, Grant)
|
||||||
da.bits.opcode := a_opcodes(a.bits.opcode)
|
da.bits.opcode := a_opcodes(a.bits.opcode)
|
||||||
da.bits.param := UInt(0)
|
da.bits.param := UInt(0) // toT, but error grants must be handled transiently (ie: you don't keep permissions)
|
||||||
da.bits.size := a.bits.size
|
da.bits.size := a.bits.size
|
||||||
da.bits.source := a.bits.source
|
da.bits.source := a.bits.source
|
||||||
da.bits.sink := UInt(0)
|
da.bits.sink := UInt(0)
|
||||||
@ -70,7 +70,7 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
|
|||||||
dc.valid := c.valid && c_last
|
dc.valid := c.valid && c_last
|
||||||
|
|
||||||
dc.bits.opcode := ReleaseAck
|
dc.bits.opcode := ReleaseAck
|
||||||
dc.bits.param := Vec(toN, toN, toB)(c.bits.param)
|
dc.bits.param := Vec(toB, toN, toN)(c.bits.param)
|
||||||
dc.bits.size := c.bits.size
|
dc.bits.size := c.bits.size
|
||||||
dc.bits.source := c.bits.source
|
dc.bits.source := c.bits.source
|
||||||
dc.bits.sink := UInt(0)
|
dc.bits.sink := UInt(0)
|
||||||
|
@ -6,11 +6,33 @@ import Chisel.log2Ceil
|
|||||||
import scala.collection.immutable.{ListMap,SortedMap}
|
import scala.collection.immutable.{ListMap,SortedMap}
|
||||||
|
|
||||||
sealed trait ResourceValue
|
sealed trait ResourceValue
|
||||||
|
|
||||||
|
/** Permission of an address space.
|
||||||
|
* @param r readable.
|
||||||
|
* @param w writable.
|
||||||
|
* @param x executable.
|
||||||
|
* @param c cacheable.
|
||||||
|
*/
|
||||||
case class ResourcePermissions(r: Boolean, w: Boolean, x: Boolean, c: Boolean) // Not part of DTS
|
case class ResourcePermissions(r: Boolean, w: Boolean, x: Boolean, c: Boolean) // Not part of DTS
|
||||||
|
|
||||||
|
/** An address space description.
|
||||||
|
* @param address the address space.
|
||||||
|
* @param permissions the permission attributes of this space. See [[freechips.rocketchip.diplomacy.ResourcePermissions]].
|
||||||
|
*/
|
||||||
final case class ResourceAddress(address: Seq[AddressSet], permissions: ResourcePermissions) extends ResourceValue
|
final case class ResourceAddress(address: Seq[AddressSet], permissions: ResourcePermissions) extends ResourceValue
|
||||||
|
|
||||||
|
/** A mapped address space (eg: when map a device to a bus).
|
||||||
|
* @param address the address space.
|
||||||
|
* @param offset the address offset of the mapped device (eg: base address of the bus).
|
||||||
|
* @param permissions the permission attributes of this space. See [[freechips.rocketchip.diplomacy.ResourcePermissions]].
|
||||||
|
*/
|
||||||
final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt, permissions: ResourcePermissions) extends ResourceValue
|
final case class ResourceMapping(address: Seq[AddressSet], offset: BigInt, permissions: ResourcePermissions) extends ResourceValue
|
||||||
final case class ResourceInt(value: BigInt) extends ResourceValue
|
final case class ResourceInt(value: BigInt) extends ResourceValue
|
||||||
final case class ResourceString(value: String) extends ResourceValue
|
final case class ResourceString(value: String) extends ResourceValue
|
||||||
|
|
||||||
|
/** A reference pointing to another device in DTS (eg: interrupt to interrupt controller).
|
||||||
|
* @param value the label (String) of the device.
|
||||||
|
*/
|
||||||
final case class ResourceReference(value: String) extends ResourceValue
|
final case class ResourceReference(value: String) extends ResourceValue
|
||||||
final case class ResourceMap(value: Map[String, Seq[ResourceValue]], labels: Seq[String] = Nil) extends ResourceValue
|
final case class ResourceMap(value: Map[String, Seq[ResourceValue]], labels: Seq[String] = Nil) extends ResourceValue
|
||||||
|
|
||||||
@ -21,12 +43,17 @@ case class ResourceBindings(map: Map[String, Seq[Binding]])
|
|||||||
def apply(key: String): Seq[Binding] = map.getOrElse(key, Nil)
|
def apply(key: String): Seq[Binding] = map.getOrElse(key, Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A serializable description of a device.
|
||||||
|
* @param name the resolved name of this device. See [[freechips.rocketchip.diplomacy.DeviceRegName]].
|
||||||
|
* @param mapping the property map of this device.
|
||||||
|
*/
|
||||||
case class Description(name: String, mapping: Map[String, Seq[ResourceValue]])
|
case class Description(name: String, mapping: Map[String, Seq[ResourceValue]])
|
||||||
|
|
||||||
abstract class Device
|
abstract class Device
|
||||||
{
|
{
|
||||||
def describe(resources: ResourceBindings): Description
|
def describe(resources: ResourceBindings): Description
|
||||||
|
|
||||||
|
/** make sure all derived devices have an unique label */
|
||||||
val label = "L" + Device.index.toString
|
val label = "L" + Device.index.toString
|
||||||
Device.index = Device.index + 1
|
Device.index = Device.index + 1
|
||||||
}
|
}
|
||||||
@ -36,9 +63,12 @@ object Device
|
|||||||
private var index: Int = 0
|
private var index: Int = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A trait for devices that generate interrupts. */
|
||||||
trait DeviceInterrupts
|
trait DeviceInterrupts
|
||||||
{
|
{
|
||||||
this: Device =>
|
this: Device =>
|
||||||
|
|
||||||
|
/** Whether to always use the expanded interrupt description in DTS: "interrupts-extended" */
|
||||||
val alwaysExtended = false
|
val alwaysExtended = false
|
||||||
def describeInterrupts(resources: ResourceBindings): Map[String, Seq[ResourceValue]] = {
|
def describeInterrupts(resources: ResourceBindings): Map[String, Seq[ResourceValue]] = {
|
||||||
val int = resources("int")
|
val int = resources("int")
|
||||||
@ -64,6 +94,7 @@ trait DeviceInterrupts
|
|||||||
def int = Seq(Resource(this, "int"))
|
def int = Seq(Resource(this, "int"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A trait for resolving the name of a device. */
|
||||||
trait DeviceRegName
|
trait DeviceRegName
|
||||||
{
|
{
|
||||||
this: Device =>
|
this: Device =>
|
||||||
@ -94,14 +125,18 @@ trait DeviceRegName
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A simple device descriptor for devices that may support interrupts and address spaces.
|
||||||
|
* @param devname the base device named used in device name generation.
|
||||||
|
* @param devcompat a list of compatible devices. See device tree property "compatible".
|
||||||
|
*/
|
||||||
class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
|
class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with DeviceInterrupts with DeviceRegName
|
||||||
{
|
{
|
||||||
def describe(resources: ResourceBindings): Description = {
|
def describe(resources: ResourceBindings): Description = {
|
||||||
val name = describeName(devname, resources)
|
val name = describeName(devname, resources) // the generated device name in device tree
|
||||||
val int = describeInterrupts(resources)
|
val int = describeInterrupts(resources) // interrupt description
|
||||||
|
|
||||||
def optDef(x: String, seq: Seq[ResourceValue]) = if (seq.isEmpty) None else Some(x -> seq)
|
def optDef(x: String, seq: Seq[ResourceValue]) = if (seq.isEmpty) None else Some(x -> seq)
|
||||||
val compat = optDef("compatible", devcompat.map(ResourceString(_)))
|
val compat = optDef("compatible", devcompat.map(ResourceString(_))) // describe the list of compatiable devices
|
||||||
|
|
||||||
val reg = resources.map.filterKeys(regFilter)
|
val reg = resources.map.filterKeys(regFilter)
|
||||||
val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
|
val (named, bulk) = reg.partition { case (k, v) => regName(k).isDefined }
|
||||||
@ -114,13 +149,18 @@ class SimpleDevice(devname: String, devcompat: Seq[String]) extends Device with
|
|||||||
require (false, s"DTS device $name has $k = $seq, must be a single ResourceAddress!")
|
require (false, s"DTS device $name has $k = $seq, must be a single ResourceAddress!")
|
||||||
}
|
}
|
||||||
|
|
||||||
val names = optDef("reg-names", named.map(x => ResourceString(regName(x._1).get)).toList)
|
val names = optDef("reg-names", named.map(x => ResourceString(regName(x._1).get)).toList) // names of the named address space
|
||||||
val regs = optDef("reg", (named ++ bulk).flatMap(_._2.map(_.value)).toList)
|
val regs = optDef("reg", (named ++ bulk).flatMap(_._2.map(_.value)).toList) // address ranges of all spaces (named and bulk)
|
||||||
|
|
||||||
Description(name, ListMap() ++ compat ++ int ++ names ++ regs)
|
Description(name, ListMap() ++ compat ++ int ++ names ++ regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A simple bus
|
||||||
|
* @param devname the base device named used in device name generation.
|
||||||
|
* @param devcompat a list of compatible devices. See device tree property "compatible".
|
||||||
|
* @param offset the base address of this bus.
|
||||||
|
*/
|
||||||
class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) extends SimpleDevice(devname, devcompat ++ Seq("simple-bus"))
|
class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) extends SimpleDevice(devname, devcompat ++ Seq("simple-bus"))
|
||||||
{
|
{
|
||||||
override def describe(resources: ResourceBindings): Description = {
|
override def describe(resources: ResourceBindings): Description = {
|
||||||
@ -147,6 +187,7 @@ class SimpleBus(devname: String, devcompat: Seq[String], offset: BigInt = 0) ext
|
|||||||
def ranges = Seq(Resource(this, "ranges"))
|
def ranges = Seq(Resource(this, "ranges"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A generic memory block. */
|
||||||
class MemoryDevice extends Device with DeviceRegName
|
class MemoryDevice extends Device with DeviceRegName
|
||||||
{
|
{
|
||||||
override val prefix = ""
|
override val prefix = ""
|
||||||
@ -169,12 +210,13 @@ case class Resource(owner: Device, key: String)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The resource binding scope for a LazyModule that generates a device tree (currently Coreplex only). */
|
||||||
trait BindingScope
|
trait BindingScope
|
||||||
{
|
{
|
||||||
this: LazyModule =>
|
this: LazyModule =>
|
||||||
|
|
||||||
private val parentScope = BindingScope.find(parent)
|
private val parentScope = BindingScope.find(parent)
|
||||||
protected[diplomacy] var resourceBindingFns: Seq[() => Unit] = Nil
|
protected[diplomacy] var resourceBindingFns: Seq[() => Unit] = Nil // callback functions to resolve resource binding during elaboration
|
||||||
protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
|
protected[diplomacy] var resourceBindings: Seq[(Resource, Option[Device], ResourceValue)] = Nil
|
||||||
|
|
||||||
private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue])
|
private case class ExpandedValue(path: Seq[String], labels: Seq[String], value: Seq[ResourceValue])
|
||||||
@ -208,6 +250,7 @@ trait BindingScope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generate the device tree. */
|
||||||
def bindingTree: ResourceMap = {
|
def bindingTree: ResourceMap = {
|
||||||
eval
|
eval
|
||||||
val map: Map[Device, ResourceBindings] =
|
val map: Map[Device, ResourceBindings] =
|
||||||
@ -232,6 +275,9 @@ object BindingScope
|
|||||||
|
|
||||||
object ResourceBinding
|
object ResourceBinding
|
||||||
{
|
{
|
||||||
|
/** Add a resource callback function to the callback list BindingScope.resourceBindingFns.
|
||||||
|
* @param block the callback function to be added.
|
||||||
|
*/
|
||||||
def apply(block: => Unit) {
|
def apply(block: => Unit) {
|
||||||
val scope = BindingScope.find()
|
val scope = BindingScope.find()
|
||||||
require (scope.isDefined, "ResourceBinding must be called from within a BindingScope")
|
require (scope.isDefined, "ResourceBinding must be called from within a BindingScope")
|
||||||
|
@ -63,7 +63,7 @@ class DCSR extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MIP(implicit p: Parameters) extends CoreBundle()(p)
|
class MIP(implicit p: Parameters) extends CoreBundle()(p)
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
||||||
val zero2 = Bool()
|
val zero2 = Bool()
|
||||||
val debug = Bool() // keep in sync with CSR.debugIntCause
|
val debug = Bool() // keep in sync with CSR.debugIntCause
|
||||||
@ -144,7 +144,7 @@ object CSR
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PerfCounterIO(implicit p: Parameters) extends CoreBundle
|
class PerfCounterIO(implicit p: Parameters) extends CoreBundle
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val eventSel = UInt(OUTPUT, xLen)
|
val eventSel = UInt(OUTPUT, xLen)
|
||||||
val inc = UInt(INPUT, log2Ceil(1+retireWidth))
|
val inc = UInt(INPUT, log2Ceil(1+retireWidth))
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ class TracedInstruction(implicit p: Parameters) extends CoreBundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val interrupts = new TileInterrupts().asInput
|
val interrupts = new TileInterrupts().asInput
|
||||||
val hartid = UInt(INPUT, hartIdLen)
|
val hartid = UInt(INPUT, hartIdLen)
|
||||||
val rw = new Bundle {
|
val rw = new Bundle {
|
||||||
@ -190,7 +190,6 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
|||||||
val evec = UInt(OUTPUT, vaddrBitsExtended)
|
val evec = UInt(OUTPUT, vaddrBitsExtended)
|
||||||
val exception = Bool(INPUT)
|
val exception = Bool(INPUT)
|
||||||
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
val retire = UInt(INPUT, log2Up(1+retireWidth))
|
||||||
val custom_mrw_csrs = Vec(nCustomMrwCsrs, UInt(INPUT, xLen))
|
|
||||||
val cause = UInt(INPUT, xLen)
|
val cause = UInt(INPUT, xLen)
|
||||||
val pc = UInt(INPUT, vaddrBitsExtended)
|
val pc = UInt(INPUT, vaddrBitsExtended)
|
||||||
val badaddr = UInt(INPUT, vaddrBitsExtended)
|
val badaddr = UInt(INPUT, vaddrBitsExtended)
|
||||||
@ -208,7 +207,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Parameters) extends CoreModule()(p)
|
class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Parameters) extends CoreModule()(p)
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val io = new CSRFileIO
|
val io = new CSRFileIO
|
||||||
|
|
||||||
val reset_mstatus = Wire(init=new MStatus().fromBits(0))
|
val reset_mstatus = Wire(init=new MStatus().fromBits(0))
|
||||||
@ -223,7 +222,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
reset_dcsr.xdebugver := 1
|
reset_dcsr.xdebugver := 1
|
||||||
reset_dcsr.prv := PRV.M
|
reset_dcsr.prv := PRV.M
|
||||||
val reg_dcsr = Reg(init=reset_dcsr)
|
val reg_dcsr = Reg(init=reset_dcsr)
|
||||||
val reg_debugint = Reg(Bool())
|
|
||||||
|
|
||||||
val (supported_interrupts, delegable_interrupts) = {
|
val (supported_interrupts, delegable_interrupts) = {
|
||||||
val sup = Wire(new MIP)
|
val sup = Wire(new MIP)
|
||||||
@ -305,13 +303,17 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
val hpm_mask = reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren)
|
val hpm_mask = reg_mcounteren & Mux((!usingVM).B || reg_mstatus.prv === PRV.S, delegable_counters.U, reg_scounteren)
|
||||||
|
|
||||||
val mip = Wire(init=reg_mip)
|
val mip = Wire(init=reg_mip)
|
||||||
|
mip.lip := (io.interrupts.lip: Seq[Bool])
|
||||||
|
mip.mtip := io.interrupts.mtip
|
||||||
|
mip.msip := io.interrupts.msip
|
||||||
|
mip.meip := io.interrupts.meip
|
||||||
// seip is the OR of reg_mip.seip and the actual line from the PLIC
|
// seip is the OR of reg_mip.seip and the actual line from the PLIC
|
||||||
io.interrupts.seip.foreach { mip.seip := reg_mip.seip || RegNext(_) }
|
io.interrupts.seip.foreach { mip.seip := reg_mip.seip || RegNext(_) }
|
||||||
mip.rocc := io.rocc_interrupt
|
mip.rocc := io.rocc_interrupt
|
||||||
val read_mip = mip.asUInt & supported_interrupts
|
val read_mip = mip.asUInt & supported_interrupts
|
||||||
|
|
||||||
val pending_interrupts = read_mip & reg_mie
|
val pending_interrupts = read_mip & reg_mie
|
||||||
val d_interrupts = reg_debugint << CSR.debugIntCause
|
val d_interrupts = io.interrupts.debug << CSR.debugIntCause
|
||||||
val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
|
val m_interrupts = Mux(reg_mstatus.prv <= PRV.S || (reg_mstatus.prv === PRV.M && reg_mstatus.mie), pending_interrupts & ~reg_mideleg, UInt(0))
|
||||||
val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0))
|
val s_interrupts = Mux(reg_mstatus.prv < PRV.S || (reg_mstatus.prv === PRV.S && reg_mstatus.sie), pending_interrupts & reg_mideleg, UInt(0))
|
||||||
val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts))
|
val (anyInterrupt, whichInterrupt) = chooseInterrupt(Seq(s_interrupts, m_interrupts, d_interrupts))
|
||||||
@ -343,8 +345,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
CSRs.mimpid -> UInt(0),
|
CSRs.mimpid -> UInt(0),
|
||||||
CSRs.marchid -> UInt(0),
|
CSRs.marchid -> UInt(0),
|
||||||
CSRs.mvendorid -> UInt(0),
|
CSRs.mvendorid -> UInt(0),
|
||||||
CSRs.mcycle -> reg_cycle,
|
|
||||||
CSRs.minstret -> reg_instret,
|
|
||||||
CSRs.misa -> reg_misa,
|
CSRs.misa -> reg_misa,
|
||||||
CSRs.mstatus -> read_mstatus,
|
CSRs.mstatus -> read_mstatus,
|
||||||
CSRs.mtvec -> reg_mtvec,
|
CSRs.mtvec -> reg_mtvec,
|
||||||
@ -372,6 +372,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
if (usingFPU)
|
if (usingFPU)
|
||||||
read_mapping ++= fp_csrs
|
read_mapping ++= fp_csrs
|
||||||
|
|
||||||
|
if (coreParams.haveBasicCounters) {
|
||||||
|
read_mapping += CSRs.mcycle -> reg_cycle
|
||||||
|
read_mapping += CSRs.minstret -> reg_instret
|
||||||
|
|
||||||
for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0))
|
for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0))
|
||||||
zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) {
|
zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) {
|
||||||
read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN
|
read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN
|
||||||
@ -383,6 +387,22 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usingUser) {
|
||||||
|
read_mapping += CSRs.mcounteren -> reg_mcounteren
|
||||||
|
read_mapping += CSRs.cycle -> reg_cycle
|
||||||
|
read_mapping += CSRs.instret -> reg_instret
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xLen == 32) {
|
||||||
|
read_mapping += CSRs.mcycleh -> (reg_cycle >> 32)
|
||||||
|
read_mapping += CSRs.minstreth -> (reg_instret >> 32)
|
||||||
|
if (usingUser) {
|
||||||
|
read_mapping += CSRs.cycleh -> (reg_cycle >> 32)
|
||||||
|
read_mapping += CSRs.instreth -> (reg_instret >> 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (usingVM) {
|
if (usingVM) {
|
||||||
val read_sie = reg_mie & reg_mideleg
|
val read_sie = reg_mie & reg_mideleg
|
||||||
val read_sip = read_mip & reg_mideleg
|
val read_sip = read_mip & reg_mideleg
|
||||||
@ -412,21 +432,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
read_mapping += CSRs.medeleg -> reg_medeleg
|
read_mapping += CSRs.medeleg -> reg_medeleg
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usingUser) {
|
|
||||||
read_mapping += CSRs.mcounteren -> reg_mcounteren
|
|
||||||
read_mapping += CSRs.cycle -> reg_cycle
|
|
||||||
read_mapping += CSRs.instret -> reg_instret
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xLen == 32) {
|
|
||||||
read_mapping += CSRs.mcycleh -> (reg_cycle >> 32)
|
|
||||||
read_mapping += CSRs.minstreth -> (reg_instret >> 32)
|
|
||||||
if (usingUser) {
|
|
||||||
read_mapping += CSRs.cycleh -> (reg_cycle >> 32)
|
|
||||||
read_mapping += CSRs.instreth -> (reg_instret >> 32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val pmpCfgPerCSR = xLen / new PMPConfig().getWidth
|
val pmpCfgPerCSR = xLen / new PMPConfig().getWidth
|
||||||
def pmpCfgIndex(i: Int) = (xLen / 32) * (i / pmpCfgPerCSR)
|
def pmpCfgIndex(i: Int) = (xLen / 32) * (i / pmpCfgPerCSR)
|
||||||
if (reg_pmp.nonEmpty) {
|
if (reg_pmp.nonEmpty) {
|
||||||
@ -438,13 +443,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
|
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i <- 0 until nCustomMrwCsrs) {
|
|
||||||
val addr = 0xff0 + i
|
|
||||||
require(addr < (1 << CSR.ADDRSZ))
|
|
||||||
require(!read_mapping.contains(addr), "custom MRW CSR address " + i + " is already in use")
|
|
||||||
read_mapping += addr -> io.custom_mrw_csrs(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) }
|
val decoded_addr = read_mapping map { case (k, v) => k -> (io.rw.addr === k) }
|
||||||
val wdata = readModifyWriteCSR(io.rw.cmd, io.rw.rdata, io.rw.wdata)
|
val wdata = readModifyWriteCSR(io.rw.cmd, io.rw.rdata, io.rw.wdata)
|
||||||
|
|
||||||
@ -511,7 +509,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive")
|
assert(PopCount(insn_ret :: insn_call :: insn_break :: io.exception :: Nil) <= 1, "these conditions must be mutually exclusive")
|
||||||
|
|
||||||
when (insn_wfi && !io.singleStep && !reg_debug) { reg_wfi := true }
|
when (insn_wfi && !io.singleStep && !reg_debug) { reg_wfi := true }
|
||||||
when (pending_interrupts.orR || exception || reg_debugint) { reg_wfi := false }
|
when (pending_interrupts.orR || exception || io.interrupts.debug) { reg_wfi := false }
|
||||||
assert(!reg_wfi || io.retire === UInt(0))
|
assert(!reg_wfi || io.retire === UInt(0))
|
||||||
|
|
||||||
when (io.retire(0) || exception) { reg_singleStepped := true }
|
when (io.retire(0) || exception) { reg_singleStepped := true }
|
||||||
@ -611,6 +609,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
when (decoded_addr(CSRs.misa)) {
|
when (decoded_addr(CSRs.misa)) {
|
||||||
val mask = UInt(isaStringToMask(isaMaskString), xLen)
|
val mask = UInt(isaStringToMask(isaMaskString), xLen)
|
||||||
val f = wdata('f' - 'a')
|
val f = wdata('f' - 'a')
|
||||||
|
if (coreParams.misaWritable)
|
||||||
reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask
|
reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask
|
||||||
}
|
}
|
||||||
when (decoded_addr(CSRs.mip)) {
|
when (decoded_addr(CSRs.mip)) {
|
||||||
@ -637,8 +636,10 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
writeCounter(i + CSR.firstMHPC, c, wdata)
|
writeCounter(i + CSR.firstMHPC, c, wdata)
|
||||||
when (decoded_addr(i + CSR.firstHPE)) { e := perfEventSets.maskEventSelector(wdata) }
|
when (decoded_addr(i + CSR.firstHPE)) { e := perfEventSets.maskEventSelector(wdata) }
|
||||||
}
|
}
|
||||||
|
if (coreParams.haveBasicCounters) {
|
||||||
writeCounter(CSRs.mcycle, reg_cycle, wdata)
|
writeCounter(CSRs.mcycle, reg_cycle, wdata)
|
||||||
writeCounter(CSRs.minstret, reg_instret, wdata)
|
writeCounter(CSRs.minstret, reg_instret, wdata)
|
||||||
|
}
|
||||||
|
|
||||||
if (usingFPU) {
|
if (usingFPU) {
|
||||||
when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata }
|
when (decoded_addr(CSRs.fflags)) { reg_fflags := wdata }
|
||||||
@ -721,12 +722,6 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_mip.lip := (io.interrupts.lip: Seq[Bool])
|
|
||||||
reg_mip.mtip := io.interrupts.mtip
|
|
||||||
reg_mip.msip := io.interrupts.msip
|
|
||||||
reg_mip.meip := io.interrupts.meip
|
|
||||||
reg_debugint := io.interrupts.debug
|
|
||||||
|
|
||||||
if (!usingVM) {
|
if (!usingVM) {
|
||||||
reg_mideleg := 0
|
reg_mideleg := 0
|
||||||
reg_medeleg := 0
|
reg_medeleg := 0
|
||||||
|
@ -384,7 +384,7 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
|||||||
val a_size = mtSize(s2_req.typ)
|
val a_size = mtSize(s2_req.typ)
|
||||||
val a_data = Fill(beatWords, pstore1_data)
|
val a_data = Fill(beatWords, pstore1_data)
|
||||||
val acquire = if (edge.manager.anySupportAcquireB) {
|
val acquire = if (edge.manager.anySupportAcquireB) {
|
||||||
edge.Acquire(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb
|
edge.AcquireBlock(UInt(0), acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb
|
||||||
} else {
|
} else {
|
||||||
Wire(new TLBundleA(edge.bundle))
|
Wire(new TLBundleA(edge.bundle))
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,6 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer)
|
|||||||
val icache = outer.icache.module
|
val icache = outer.icache.module
|
||||||
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
|
require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes)
|
||||||
|
|
||||||
val fetchBytes = coreInstBytes * fetchWidth
|
|
||||||
val tlb = Module(new TLB(true, log2Ceil(fetchBytes), nTLBEntries))
|
val tlb = Module(new TLB(true, log2Ceil(fetchBytes), nTLBEntries))
|
||||||
val fq = withReset(reset || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp, 5, flow = true)) }
|
val fq = withReset(reset || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp, 5, flow = true)) }
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ class MSHR(id: Int)(implicit edge: TLEdgeOut, p: Parameters) extends L1HellaCach
|
|||||||
io.wb_req.bits.voluntary := Bool(true)
|
io.wb_req.bits.voluntary := Bool(true)
|
||||||
|
|
||||||
io.mem_acquire.valid := state === s_refill_req && grantackq.io.enq.ready
|
io.mem_acquire.valid := state === s_refill_req && grantackq.io.enq.ready
|
||||||
io.mem_acquire.bits := edge.Acquire(
|
io.mem_acquire.bits := edge.AcquireBlock(
|
||||||
fromSource = UInt(id),
|
fromSource = UInt(id),
|
||||||
toAddress = Cat(io.tag, req_idx) << blockOffBits,
|
toAddress = Cat(io.tag, req_idx) << blockOffBits,
|
||||||
lgSize = lgCacheBlockBytes,
|
lgSize = lgCacheBlockBytes,
|
||||||
|
@ -127,7 +127,7 @@ class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p)
|
class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p)
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val prv = UInt(INPUT, PRV.SZ)
|
val prv = UInt(INPUT, PRV.SZ)
|
||||||
val pmp = Vec(nPMPs, new PMP).asInput
|
val pmp = Vec(nPMPs, new PMP).asInput
|
||||||
|
@ -24,7 +24,7 @@ class PTWResp(implicit p: Parameters) extends CoreBundle()(p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p)
|
class TLBPTWIO(implicit p: Parameters) extends CoreBundle()(p)
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val req = Decoupled(new PTWReq)
|
val req = Decoupled(new PTWReq)
|
||||||
val resp = Valid(new PTWResp).flip
|
val resp = Valid(new PTWResp).flip
|
||||||
val ptbr = new PTBR().asInput
|
val ptbr = new PTBR().asInput
|
||||||
@ -37,7 +37,7 @@ class PTWPerfEvents extends Bundle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p)
|
class DatapathPTWIO(implicit p: Parameters) extends CoreBundle()(p)
|
||||||
with HasRocketCoreParameters {
|
with HasCoreParameters {
|
||||||
val ptbr = new PTBR().asInput
|
val ptbr = new PTBR().asInput
|
||||||
val sfence = Valid(new SFenceReq).flip
|
val sfence = Valid(new SFenceReq).flip
|
||||||
val status = new MStatus().asInput
|
val status = new MStatus().asInput
|
||||||
|
@ -23,7 +23,8 @@ case class RocketCoreParams(
|
|||||||
nBreakpoints: Int = 1,
|
nBreakpoints: Int = 1,
|
||||||
nPMPs: Int = 8,
|
nPMPs: Int = 8,
|
||||||
nPerfCounters: Int = 0,
|
nPerfCounters: Int = 0,
|
||||||
nCustomMRWCSRs: Int = 0,
|
haveBasicCounters: Boolean = true,
|
||||||
|
misaWritable: Boolean = true,
|
||||||
nL2TLBEntries: Int = 0,
|
nL2TLBEntries: Int = 0,
|
||||||
mtvecInit: Option[BigInt] = Some(BigInt(0)),
|
mtvecInit: Option[BigInt] = Some(BigInt(0)),
|
||||||
mtvecWritable: Boolean = true,
|
mtvecWritable: Boolean = true,
|
||||||
@ -46,12 +47,6 @@ trait HasRocketCoreParameters extends HasCoreParameters {
|
|||||||
|
|
||||||
val fastLoadWord = rocketParams.fastLoadWord
|
val fastLoadWord = rocketParams.fastLoadWord
|
||||||
val fastLoadByte = rocketParams.fastLoadByte
|
val fastLoadByte = rocketParams.fastLoadByte
|
||||||
val nBreakpoints = rocketParams.nBreakpoints
|
|
||||||
val nPMPs = rocketParams.nPMPs
|
|
||||||
val nPerfCounters = rocketParams.nPerfCounters
|
|
||||||
val nCustomMrwCsrs = rocketParams.nCustomMRWCSRs
|
|
||||||
val mtvecInit = rocketParams.mtvecInit
|
|
||||||
val mtvecWritable = rocketParams.mtvecWritable
|
|
||||||
|
|
||||||
val mulDivParams = rocketParams.mulDiv.getOrElse(MulDivParams()) // TODO ask andrew about this
|
val mulDivParams = rocketParams.mulDiv.getOrElse(MulDivParams()) // TODO ask andrew about this
|
||||||
|
|
||||||
|
@ -63,9 +63,6 @@ class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new BaseCo
|
|||||||
class DualCoreConfig extends Config(
|
class DualCoreConfig extends Config(
|
||||||
new WithNBigCores(2) ++ new BaseConfig)
|
new WithNBigCores(2) ++ new BaseConfig)
|
||||||
|
|
||||||
class HeterogeneousDualCoreConfig extends Config(
|
|
||||||
new WithNSmallCores(1) ++ new WithNBigCores(1) ++ new BaseConfig)
|
|
||||||
|
|
||||||
class TinyConfig extends Config(
|
class TinyConfig extends Config(
|
||||||
new WithNMemoryChannels(0) ++
|
new WithNMemoryChannels(0) ++
|
||||||
new WithStatelessBridge ++
|
new WithStatelessBridge ++
|
||||||
|
@ -25,7 +25,14 @@ trait CoreParams {
|
|||||||
val retireWidth: Int
|
val retireWidth: Int
|
||||||
val instBits: Int
|
val instBits: Int
|
||||||
val nLocalInterrupts: Int
|
val nLocalInterrupts: Int
|
||||||
|
val nPMPs: Int
|
||||||
|
val nBreakpoints: Int
|
||||||
|
val nPerfCounters: Int
|
||||||
|
val haveBasicCounters: Boolean
|
||||||
|
val misaWritable: Boolean
|
||||||
val nL2TLBEntries: Int
|
val nL2TLBEntries: Int
|
||||||
|
val mtvecInit: Option[BigInt]
|
||||||
|
val mtvecWritable: Boolean
|
||||||
val jumpInFrontend: Boolean
|
val jumpInFrontend: Boolean
|
||||||
val tileControlAddr: Option[BigInt]
|
val tileControlAddr: Option[BigInt]
|
||||||
|
|
||||||
@ -47,12 +54,19 @@ trait HasCoreParameters extends HasTileParameters {
|
|||||||
val fetchWidth = coreParams.fetchWidth
|
val fetchWidth = coreParams.fetchWidth
|
||||||
val decodeWidth = coreParams.decodeWidth
|
val decodeWidth = coreParams.decodeWidth
|
||||||
|
|
||||||
|
val fetchBytes = coreParams.fetchBytes
|
||||||
val coreInstBits = coreParams.instBits
|
val coreInstBits = coreParams.instBits
|
||||||
val coreInstBytes = coreInstBits/8
|
val coreInstBytes = coreInstBits/8
|
||||||
val coreDataBits = xLen max fLen
|
val coreDataBits = xLen max fLen
|
||||||
val coreDataBytes = coreDataBits/8
|
val coreDataBytes = coreDataBits/8
|
||||||
val coreMaxAddrBits = paddrBits max vaddrBitsExtended
|
val coreMaxAddrBits = paddrBits max vaddrBitsExtended
|
||||||
|
|
||||||
|
val nBreakpoints = coreParams.nBreakpoints
|
||||||
|
val nPMPs = coreParams.nPMPs
|
||||||
|
val nPerfCounters = coreParams.nPerfCounters
|
||||||
|
val mtvecInit = coreParams.mtvecInit
|
||||||
|
val mtvecWritable = coreParams.mtvecWritable
|
||||||
|
|
||||||
val coreDCacheReqTagBits = 6
|
val coreDCacheReqTagBits = 6
|
||||||
val dcacheReqTagBits = coreDCacheReqTagBits + log2Ceil(dcacheArbPorts)
|
val dcacheReqTagBits = coreDCacheReqTagBits + log2Ceil(dcacheArbPorts)
|
||||||
|
|
||||||
|
@ -542,7 +542,72 @@ class FPToFP(val latency: Int)(implicit p: Parameters) extends FPUModule()(p) {
|
|||||||
io.out <> Pipe(in.valid, mux, latency-1)
|
io.out <> Pipe(in.valid, mux, latency-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MulAddRecFNPipe(latency: Int, expWidth: Int, sigWidth: Int) extends Module
|
||||||
|
{
|
||||||
|
require(latency<=2)
|
||||||
|
|
||||||
|
val io = new Bundle {
|
||||||
|
val validin = Bool(INPUT)
|
||||||
|
val op = Bits(INPUT, 2)
|
||||||
|
val a = Bits(INPUT, expWidth + sigWidth + 1)
|
||||||
|
val b = Bits(INPUT, expWidth + sigWidth + 1)
|
||||||
|
val c = Bits(INPUT, expWidth + sigWidth + 1)
|
||||||
|
val roundingMode = UInt(INPUT, 3)
|
||||||
|
val detectTininess = UInt(INPUT, 1)
|
||||||
|
val out = Bits(OUTPUT, expWidth + sigWidth + 1)
|
||||||
|
val exceptionFlags = Bits(OUTPUT, 5)
|
||||||
|
val validout = Bool(OUTPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
val mulAddRecFNToRaw_preMul =
|
||||||
|
Module(new hardfloat.MulAddRecFNToRaw_preMul(expWidth, sigWidth))
|
||||||
|
val mulAddRecFNToRaw_postMul =
|
||||||
|
Module(new hardfloat.MulAddRecFNToRaw_postMul(expWidth, sigWidth))
|
||||||
|
|
||||||
|
mulAddRecFNToRaw_preMul.io.op := io.op
|
||||||
|
mulAddRecFNToRaw_preMul.io.a := io.a
|
||||||
|
mulAddRecFNToRaw_preMul.io.b := io.b
|
||||||
|
mulAddRecFNToRaw_preMul.io.c := io.c
|
||||||
|
|
||||||
|
val mulAddResult =
|
||||||
|
(mulAddRecFNToRaw_preMul.io.mulAddA *
|
||||||
|
mulAddRecFNToRaw_preMul.io.mulAddB) +&
|
||||||
|
mulAddRecFNToRaw_preMul.io.mulAddC
|
||||||
|
|
||||||
|
val valid_stage0 = Wire(Bool())
|
||||||
|
val roundingMode_stage0 = Wire(UInt(width=3))
|
||||||
|
val detectTininess_stage0 = Wire(UInt(width=1))
|
||||||
|
|
||||||
|
val postmul_regs = if(latency>0) 1 else 0
|
||||||
|
mulAddRecFNToRaw_postMul.io.fromPreMul := Pipe(io.validin, mulAddRecFNToRaw_preMul.io.toPostMul, postmul_regs).bits
|
||||||
|
mulAddRecFNToRaw_postMul.io.mulAddResult := Pipe(io.validin, mulAddResult, postmul_regs).bits
|
||||||
|
mulAddRecFNToRaw_postMul.io.roundingMode := Pipe(io.validin, io.roundingMode, postmul_regs).bits
|
||||||
|
roundingMode_stage0 := Pipe(io.validin, io.roundingMode, postmul_regs).bits
|
||||||
|
detectTininess_stage0 := Pipe(io.validin, io.detectTininess, postmul_regs).bits
|
||||||
|
valid_stage0 := Pipe(io.validin, false.B, postmul_regs).valid
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
val roundRawFNToRecFN = Module(new hardfloat.RoundRawFNToRecFN(expWidth, sigWidth, 0))
|
||||||
|
|
||||||
|
val round_regs = if(latency==2) 1 else 0
|
||||||
|
roundRawFNToRecFN.io.invalidExc := Pipe(valid_stage0, mulAddRecFNToRaw_postMul.io.invalidExc, round_regs).bits
|
||||||
|
roundRawFNToRecFN.io.in := Pipe(valid_stage0, mulAddRecFNToRaw_postMul.io.rawOut, round_regs).bits
|
||||||
|
roundRawFNToRecFN.io.roundingMode := Pipe(valid_stage0, roundingMode_stage0, round_regs).bits
|
||||||
|
roundRawFNToRecFN.io.detectTininess := Pipe(valid_stage0, detectTininess_stage0, round_regs).bits
|
||||||
|
io.validout := Pipe(valid_stage0, false.B, round_regs).valid
|
||||||
|
|
||||||
|
roundRawFNToRecFN.io.infiniteExc := Bool(false)
|
||||||
|
|
||||||
|
io.out := roundRawFNToRecFN.io.out
|
||||||
|
io.exceptionFlags := roundRawFNToRecFN.io.exceptionFlags
|
||||||
|
}
|
||||||
|
|
||||||
class FPUFMAPipe(val latency: Int, val t: FType)(implicit p: Parameters) extends FPUModule()(p) {
|
class FPUFMAPipe(val latency: Int, val t: FType)(implicit p: Parameters) extends FPUModule()(p) {
|
||||||
|
require(latency>0)
|
||||||
|
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Valid(new FPInput).flip
|
val in = Valid(new FPInput).flip
|
||||||
val out = Valid(new FPResult)
|
val out = Valid(new FPResult)
|
||||||
@ -560,7 +625,8 @@ class FPUFMAPipe(val latency: Int, val t: FType)(implicit p: Parameters) extends
|
|||||||
when (!(cmd_fma || cmd_addsub)) { in.in3 := zero }
|
when (!(cmd_fma || cmd_addsub)) { in.in3 := zero }
|
||||||
}
|
}
|
||||||
|
|
||||||
val fma = Module(new hardfloat.MulAddRecFN(t.exp, t.sig))
|
val fma = Module(new MulAddRecFNPipe((latency-1) min 2, t.exp, t.sig))
|
||||||
|
fma.io.validin := valid
|
||||||
fma.io.op := in.fmaCmd
|
fma.io.op := in.fmaCmd
|
||||||
fma.io.roundingMode := in.rm
|
fma.io.roundingMode := in.rm
|
||||||
fma.io.detectTininess := hardfloat.consts.tininess_afterRounding
|
fma.io.detectTininess := hardfloat.consts.tininess_afterRounding
|
||||||
@ -571,7 +637,8 @@ class FPUFMAPipe(val latency: Int, val t: FType)(implicit p: Parameters) extends
|
|||||||
val res = Wire(new FPResult)
|
val res = Wire(new FPResult)
|
||||||
res.data := sanitizeNaN(fma.io.out, t)
|
res.data := sanitizeNaN(fma.io.out, t)
|
||||||
res.exc := fma.io.exceptionFlags
|
res.exc := fma.io.exceptionFlags
|
||||||
io.out := Pipe(valid, res, latency-1)
|
|
||||||
|
io.out := Pipe(fma.io.validout, res, (latency-3) max 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
|
class FPU(cfg: FPUParams)(implicit p: Parameters) extends FPUModule()(p) {
|
||||||
|
@ -22,13 +22,14 @@ case class RocketTileParams(
|
|||||||
trace: Boolean = false,
|
trace: Boolean = false,
|
||||||
hcfOnUncorrectable: Boolean = false,
|
hcfOnUncorrectable: Boolean = false,
|
||||||
name: Option[String] = Some("tile"),
|
name: Option[String] = Some("tile"),
|
||||||
|
hartid: Int = 0,
|
||||||
externalMasterBuffers: Int = 0,
|
externalMasterBuffers: Int = 0,
|
||||||
externalSlaveBuffers: Int = 0) extends TileParams {
|
externalSlaveBuffers: Int = 0) extends TileParams {
|
||||||
require(icache.isDefined)
|
require(icache.isDefined)
|
||||||
require(dcache.isDefined)
|
require(dcache.isDefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p: Parameters) extends BaseTile(rocketParams)(p)
|
class RocketTile(val rocketParams: RocketTileParams)(implicit p: Parameters) extends BaseTile(rocketParams)(p)
|
||||||
with HasExternalInterrupts
|
with HasExternalInterrupts
|
||||||
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
with HasLazyRoCC // implies CanHaveSharedFPU with CanHavePTW with HasHellaCache
|
||||||
with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend
|
with CanHaveScratchpad { // implies CanHavePTW with HasHellaCache with HasICacheFrontend
|
||||||
@ -39,6 +40,7 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
|
|||||||
private def ofStr(x: String) = Seq(ResourceString(x))
|
private def ofStr(x: String) = Seq(ResourceString(x))
|
||||||
private def ofRef(x: Device) = Seq(ResourceReference(x.label))
|
private def ofRef(x: Device) = Seq(ResourceReference(x.label))
|
||||||
|
|
||||||
|
val hartid = rocketParams.hartid
|
||||||
val cpuDevice = new Device {
|
val cpuDevice = new Device {
|
||||||
def describe(resources: ResourceBindings): Description = {
|
def describe(resources: ResourceBindings): Description = {
|
||||||
val block = p(CacheBlockBytes)
|
val block = p(CacheBlockBytes)
|
||||||
@ -179,8 +181,8 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
|||||||
ptw.io.requestor <> ptwPorts
|
ptw.io.requestor <> ptwPorts
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends LazyModule {
|
abstract class RocketTileWrapper(rtp: RocketTileParams)(implicit p: Parameters) extends LazyModule {
|
||||||
val rocket = LazyModule(new RocketTile(rtp, hartid))
|
val rocket = LazyModule(new RocketTile(rtp))
|
||||||
val asyncIntNode : IntInwardNode
|
val asyncIntNode : IntInwardNode
|
||||||
val periphIntNode : IntInwardNode
|
val periphIntNode : IntInwardNode
|
||||||
val coreIntNode : IntInwardNode
|
val coreIntNode : IntInwardNode
|
||||||
@ -226,7 +228,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams, hartid: Int)(implicit p:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class SyncRocketTile(rtp: RocketTileParams)(implicit p: Parameters) extends RocketTileWrapper(rtp) {
|
||||||
val masterNode = optionalMasterBuffer(rocket.masterNode)
|
val masterNode = optionalMasterBuffer(rocket.masterNode)
|
||||||
val slaveNode = optionalSlaveBuffer(rocket.slaveNode)
|
val slaveNode = optionalSlaveBuffer(rocket.slaveNode)
|
||||||
|
|
||||||
@ -246,7 +248,7 @@ class SyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters)
|
|||||||
def outputInterruptXingLatency = 0
|
def outputInterruptXingLatency = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class AsyncRocketTile(rtp: RocketTileParams)(implicit p: Parameters) extends RocketTileWrapper(rtp) {
|
||||||
val source = LazyModule(new TLAsyncCrossingSource)
|
val source = LazyModule(new TLAsyncCrossingSource)
|
||||||
source.node :=* rocket.masterNode
|
source.node :=* rocket.masterNode
|
||||||
val masterNode = source.node
|
val masterNode = source.node
|
||||||
@ -272,7 +274,7 @@ class AsyncRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters
|
|||||||
def outputInterruptXingLatency = 3
|
def outputInterruptXingLatency = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
class RationalRocketTile(rtp: RocketTileParams, hartid: Int)(implicit p: Parameters) extends RocketTileWrapper(rtp, hartid) {
|
class RationalRocketTile(rtp: RocketTileParams)(implicit p: Parameters) extends RocketTileWrapper(rtp) {
|
||||||
val source = LazyModule(new TLRationalCrossingSource)
|
val source = LazyModule(new TLRationalCrossingSource)
|
||||||
source.node :=* optionalMasterBuffer(rocket.masterNode)
|
source.node :=* optionalMasterBuffer(rocket.masterNode)
|
||||||
val masterNode = source.node
|
val masterNode = source.node
|
||||||
|
@ -51,8 +51,8 @@ class Atomics(params: TLBundleParameters) extends Module
|
|||||||
UInt(3), // LogicalData
|
UInt(3), // LogicalData
|
||||||
UInt(0), // Get
|
UInt(0), // Get
|
||||||
UInt(0), // Hint
|
UInt(0), // Hint
|
||||||
UInt(0), // Acquire
|
UInt(0), // AcquireBlock
|
||||||
UInt(0)))( // Overwrite
|
UInt(0)))( // AcquirePerm
|
||||||
io.a.opcode))
|
io.a.opcode))
|
||||||
|
|
||||||
// Only the masked bytes can be modified
|
// Only the masked bytes can be modified
|
||||||
|
@ -176,6 +176,11 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
|||||||
t.probe := (if (caches.size == 0) UInt(0) else Mux(a_cache.orR(), UInt(caches.size-1), UInt(caches.size)))
|
t.probe := (if (caches.size == 0) UInt(0) else Mux(a_cache.orR(), UInt(caches.size-1), UInt(caches.size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val acq_perms = MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array(
|
||||||
|
TLPermissions.NtoB -> TLPermissions.toB,
|
||||||
|
TLPermissions.NtoT -> TLPermissions.toN,
|
||||||
|
TLPermissions.BtoT -> TLPermissions.toN))
|
||||||
|
|
||||||
when (in.a.fire() && a_first) {
|
when (in.a.fire() && a_first) {
|
||||||
probe_todo := ~a_cache // probe all but the cache who poked us
|
probe_todo := ~a_cache // probe all but the cache who poked us
|
||||||
probe_line := in.a.bits.address >> lineShift
|
probe_line := in.a.bits.address >> lineShift
|
||||||
@ -188,10 +193,8 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
|
|||||||
TLMessages.Hint -> MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array(
|
TLMessages.Hint -> MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array(
|
||||||
TLHints.PREFETCH_READ -> TLPermissions.toB,
|
TLHints.PREFETCH_READ -> TLPermissions.toB,
|
||||||
TLHints.PREFETCH_WRITE -> TLPermissions.toN)),
|
TLHints.PREFETCH_WRITE -> TLPermissions.toN)),
|
||||||
TLMessages.Acquire -> MuxLookup(in.a.bits.param, Wire(UInt(width = 2)), Array(
|
TLMessages.AcquireBlock -> acq_perms,
|
||||||
TLPermissions.NtoB -> TLPermissions.toB,
|
TLMessages.AcquirePerm -> acq_perms))
|
||||||
TLPermissions.NtoT -> TLPermissions.toN,
|
|
||||||
TLPermissions.BtoT -> TLPermissions.toN))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The outer TL connections may not be cached
|
// The outer TL connections may not be cached
|
||||||
@ -236,7 +239,7 @@ class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferles
|
|||||||
when (io.in_a.fire() && io.in_a_first) {
|
when (io.in_a.fire() && io.in_a_first) {
|
||||||
assert (idle)
|
assert (idle)
|
||||||
sent_d := Bool(false)
|
sent_d := Bool(false)
|
||||||
got_e := io.in_a.bits.opcode =/= TLMessages.Acquire
|
got_e := io.in_a.bits.opcode =/= TLMessages.AcquireBlock && io.in_a.bits.opcode =/= TLMessages.AcquirePerm
|
||||||
opcode := io.in_a.bits.opcode
|
opcode := io.in_a.bits.opcode
|
||||||
param := io.in_a.bits.param
|
param := io.in_a.bits.param
|
||||||
size := io.in_a.bits.size
|
size := io.in_a.bits.size
|
||||||
@ -271,7 +274,7 @@ class TLBroadcastTracker(id: Int, lineBytes: Int, probeCountBits: Int, bufferles
|
|||||||
i_data.bits.data := io.in_a.bits.data
|
i_data.bits.data := io.in_a.bits.data
|
||||||
|
|
||||||
val probe_done = count === UInt(0)
|
val probe_done = count === UInt(0)
|
||||||
val acquire = opcode === TLMessages.Acquire
|
val acquire = opcode === TLMessages.AcquireBlock || opcode === TLMessages.AcquirePerm
|
||||||
|
|
||||||
val transform = MuxLookup(param, Wire(UInt(width = 2)), Array(
|
val transform = MuxLookup(param, Wire(UInt(width = 2)), Array(
|
||||||
TLPermissions.NtoB -> TRANSFORM_B,
|
TLPermissions.NtoB -> TRANSFORM_B,
|
||||||
|
@ -22,7 +22,8 @@ object TLMessages
|
|||||||
def LogicalData = UInt(3) // . . => AccessAckData
|
def LogicalData = UInt(3) // . . => AccessAckData
|
||||||
def Get = UInt(4) // . . => AccessAckData
|
def Get = UInt(4) // . . => AccessAckData
|
||||||
def Hint = UInt(5) // . . => HintAck
|
def Hint = UInt(5) // . . => HintAck
|
||||||
def Acquire = UInt(6) // . => Grant[Data]
|
def AcquireBlock = UInt(6) // . => Grant[Data]
|
||||||
|
def AcquirePerm = UInt(7) // . => Grant[Data]
|
||||||
def Probe = UInt(6) // . => ProbeAck[Data]
|
def Probe = UInt(6) // . => ProbeAck[Data]
|
||||||
def AccessAck = UInt(0) // . .
|
def AccessAck = UInt(0) // . .
|
||||||
def AccessAckData = UInt(1) // . .
|
def AccessAckData = UInt(1) // . .
|
||||||
@ -36,7 +37,7 @@ object TLMessages
|
|||||||
def ReleaseAck = UInt(6) // .
|
def ReleaseAck = UInt(6) // .
|
||||||
def GrantAck = UInt(0) // .
|
def GrantAck = UInt(0) // .
|
||||||
|
|
||||||
def isA(x: UInt) = x <= Acquire
|
def isA(x: UInt) = x <= AcquirePerm
|
||||||
def isB(x: UInt) = x <= Probe
|
def isB(x: UInt) = x <= Probe
|
||||||
def isC(x: UInt) = x <= ReleaseData
|
def isC(x: UInt) = x <= ReleaseData
|
||||||
def isD(x: UInt) = x <= ReleaseAck
|
def isD(x: UInt) = x <= ReleaseAck
|
||||||
|
@ -47,7 +47,8 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
val a_a = Wire(out.a)
|
val a_a = Wire(out.a)
|
||||||
val a_d = Wire(in.d)
|
val a_d = Wire(in.d)
|
||||||
val isPut = in.a.bits.opcode === PutFullData || in.a.bits.opcode === PutPartialData
|
val isPut = in.a.bits.opcode === PutFullData || in.a.bits.opcode === PutPartialData
|
||||||
val toD = in.a.bits.opcode === Acquire && in.a.bits.param === TLPermissions.BtoT
|
val toD = (in.a.bits.opcode === AcquireBlock && in.a.bits.param === TLPermissions.BtoT) ||
|
||||||
|
(in.a.bits.opcode === AcquirePerm)
|
||||||
in.a.ready := Mux(toD, a_d.ready, a_a.ready)
|
in.a.ready := Mux(toD, a_d.ready, a_a.ready)
|
||||||
|
|
||||||
a_a.valid := in.a.valid && !toD
|
a_a.valid := in.a.valid && !toD
|
||||||
@ -55,7 +56,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, UInt(1), UInt(0))
|
a_a.bits.source := in.a.bits.source << 1 | Mux(isPut, UInt(1), UInt(0))
|
||||||
|
|
||||||
// Transform Acquire into Get
|
// Transform Acquire into Get
|
||||||
when (in.a.bits.opcode === Acquire) {
|
when (in.a.bits.opcode === AcquireBlock || in.a.bits.opcode === AcquirePerm) {
|
||||||
a_a.bits.opcode := Get
|
a_a.bits.opcode := Get
|
||||||
a_a.bits.param := UInt(0)
|
a_a.bits.param := UInt(0)
|
||||||
a_a.bits.source := in.a.bits.source << 1 | UInt(1)
|
a_a.bits.source := in.a.bits.source << 1 | UInt(1)
|
||||||
@ -100,10 +101,7 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
|
|||||||
|
|
||||||
when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
|
when (out.d.bits.opcode === AccessAckData && out.d.bits.source(0)) {
|
||||||
d_d.bits.opcode := GrantData
|
d_d.bits.opcode := GrantData
|
||||||
// On Grant error, you do NOT get the permissions you asked for.
|
d_d.bits.param := TLPermissions.toT
|
||||||
// We only enter this case from NtoT or NtoB, so that means use toN.
|
|
||||||
// (the BtoT case was handled by a_d)
|
|
||||||
d_d.bits.param := Mux(out.d.bits.error, TLPermissions.toN, TLPermissions.toT)
|
|
||||||
}
|
}
|
||||||
when (out.d.bits.opcode === AccessAck && !out.d.bits.source(0)) {
|
when (out.d.bits.opcode === AccessAck && !out.d.bits.source(0)) {
|
||||||
d_d.bits.opcode := ReleaseAck
|
d_d.bits.opcode := ReleaseAck
|
||||||
|
@ -271,11 +271,25 @@ class TLEdgeOut(
|
|||||||
extends TLEdge(client, manager, params, sourceInfo)
|
extends TLEdge(client, manager, params, sourceInfo)
|
||||||
{
|
{
|
||||||
// Transfers
|
// Transfers
|
||||||
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
def AcquireBlock(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
||||||
require (manager.anySupportAcquireB)
|
require (manager.anySupportAcquireB)
|
||||||
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
||||||
val a = Wire(new TLBundleA(bundle))
|
val a = Wire(new TLBundleA(bundle))
|
||||||
a.opcode := TLMessages.Acquire
|
a.opcode := TLMessages.AcquireBlock
|
||||||
|
a.param := growPermissions
|
||||||
|
a.size := lgSize
|
||||||
|
a.source := fromSource
|
||||||
|
a.address := toAddress
|
||||||
|
a.mask := mask(toAddress, lgSize)
|
||||||
|
a.data := UInt(0)
|
||||||
|
(legal, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
def AcquirePerm(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
||||||
|
require (manager.anySupportAcquireB)
|
||||||
|
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
||||||
|
val a = Wire(new TLBundleA(bundle))
|
||||||
|
a.opcode := TLMessages.AcquirePerm
|
||||||
a.param := growPermissions
|
a.param := growPermissions
|
||||||
a.size := lgSize
|
a.size := lgSize
|
||||||
a.source := fromSource
|
a.source := fromSource
|
||||||
|
@ -37,14 +37,25 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
|
|||||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||||
val mask = edge.full_mask(bundle)
|
val mask = edge.full_mask(bundle)
|
||||||
|
|
||||||
when (bundle.opcode === TLMessages.Acquire) {
|
when (bundle.opcode === TLMessages.AcquireBlock) {
|
||||||
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries Acquire type unsupported by manager" + extra)
|
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries AcquireBlock type unsupported by manager" + extra)
|
||||||
assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries Acquire from a client which does not support Probe" + extra)
|
assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries AcquireBlock from a client which does not support Probe" + extra)
|
||||||
assert (source_ok, "'A' channel Acquire carries invalid source ID" + extra)
|
assert (source_ok, "'A' channel AcquireBlock carries invalid source ID" + extra)
|
||||||
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel Acquire smaller than a beat" + extra)
|
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel AcquireBlock smaller than a beat" + extra)
|
||||||
assert (is_aligned, "'A' channel Acquire address not aligned to size" + extra)
|
assert (is_aligned, "'A' channel AcquireBlock address not aligned to size" + extra)
|
||||||
assert (TLPermissions.isGrow(bundle.param), "'A' channel Acquire carries invalid grow param" + extra)
|
assert (TLPermissions.isGrow(bundle.param), "'A' channel AcquireBlock carries invalid grow param" + extra)
|
||||||
assert (~bundle.mask === UInt(0), "'A' channel Acquire contains invalid mask" + extra)
|
assert (~bundle.mask === UInt(0), "'A' channel AcquireBlock contains invalid mask" + extra)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (bundle.opcode === TLMessages.AcquirePerm) {
|
||||||
|
assert (edge.manager.supportsAcquireBSafe(edge.address(bundle), bundle.size), "'A' channel carries AcquirePerm type unsupported by manager" + extra)
|
||||||
|
assert (edge.client.supportsProbe(edge.source(bundle), bundle.size), "'A' channel carries AcquirePerm from a client which does not support Probe" + extra)
|
||||||
|
assert (source_ok, "'A' channel AcquirePerm carries invalid source ID" + extra)
|
||||||
|
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'A' channel AcquirePerm smaller than a beat" + extra)
|
||||||
|
assert (is_aligned, "'A' channel AcquirePerm address not aligned to size" + extra)
|
||||||
|
assert (TLPermissions.isGrow(bundle.param), "'A' channel AcquirePerm carries invalid grow param" + extra)
|
||||||
|
assert (bundle.param =/= TLPermissions.NtoB, "'A' channel AcquirePerm requests NtoB" + extra)
|
||||||
|
assert (~bundle.mask === UInt(0), "'A' channel AcquirePerm contains invalid mask" + extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (bundle.opcode === TLMessages.Get) {
|
when (bundle.opcode === TLMessages.Get) {
|
||||||
|
@ -116,7 +116,7 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
|||||||
|
|
||||||
when (a_fire) {
|
when (a_fire) {
|
||||||
// Record the request so we can handle it's response
|
// Record the request so we can handle it's response
|
||||||
assert (a.opcode =/= TLMessages.Acquire)
|
assert (a.opcode =/= TLMessages.AcquireBlock && a.opcode =/= TLMessages.AcquirePerm)
|
||||||
|
|
||||||
// Mark the operation as valid
|
// Mark the operation as valid
|
||||||
valid(a.source) := Bool(true)
|
valid(a.source) := Bool(true)
|
||||||
|
Loading…
Reference in New Issue
Block a user