1
0

Merge remote-tracking branch 'origin/master' into HEAD

This commit is contained in:
Megan Wachs 2017-10-09 09:48:38 -07:00
commit 9efe1c448e
23 changed files with 265 additions and 119 deletions

View File

@ -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))
} }
}) })

View File

@ -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)

View File

@ -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
} }

View File

@ -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)

View File

@ -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")

View File

@ -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,14 +372,34 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
if (usingFPU) if (usingFPU)
read_mapping ++= fp_csrs read_mapping ++= fp_csrs
for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0)) if (coreParams.haveBasicCounters) {
zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) { read_mapping += CSRs.mcycle -> reg_cycle
read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN read_mapping += CSRs.minstret -> reg_instret
read_mapping += (i + CSR.firstMHPC) -> c // mhpmcounterN
if (usingUser) read_mapping += (i + CSR.firstHPC) -> c // hpmcounterN for (((e, c), i) <- (reg_hpmevent.padTo(CSR.nHPM, UInt(0))
zip reg_hpmcounter.map(x => x: UInt).padTo(CSR.nHPM, UInt(0))) zipWithIndex) {
read_mapping += (i + CSR.firstHPE) -> e // mhpmeventN
read_mapping += (i + CSR.firstMHPC) -> c // mhpmcounterN
if (usingUser) read_mapping += (i + CSR.firstHPC) -> c // hpmcounterN
if (xLen == 32) {
read_mapping += (i + CSR.firstMHPCH) -> c // mhpmcounterNh
if (usingUser) read_mapping += (i + CSR.firstHPCH) -> c // hpmcounterNh
}
}
if (usingUser) {
read_mapping += CSRs.mcounteren -> reg_mcounteren
read_mapping += CSRs.cycle -> reg_cycle
read_mapping += CSRs.instret -> reg_instret
}
if (xLen == 32) { if (xLen == 32) {
read_mapping += (i + CSR.firstMHPCH) -> c // mhpmcounterNh read_mapping += CSRs.mcycleh -> (reg_cycle >> 32)
if (usingUser) read_mapping += (i + CSR.firstHPCH) -> c // hpmcounterNh read_mapping += CSRs.minstreth -> (reg_instret >> 32)
if (usingUser) {
read_mapping += CSRs.cycleh -> (reg_cycle >> 32)
read_mapping += CSRs.instreth -> (reg_instret >> 32)
}
} }
} }
@ -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,7 +609,8 @@ 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')
reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask if (coreParams.misaWritable)
reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask
} }
when (decoded_addr(CSRs.mip)) { when (decoded_addr(CSRs.mip)) {
// MIP should be modified based on the value in reg_mip, not the value // MIP should be modified based on the value in reg_mip, not the value
@ -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) }
} }
writeCounter(CSRs.mcycle, reg_cycle, wdata) if (coreParams.haveBasicCounters) {
writeCounter(CSRs.minstret, reg_instret, wdata) writeCounter(CSRs.mcycle, reg_cycle, 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

View File

@ -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))
} }

View File

@ -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)) }

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ++

View File

@ -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)

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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)