2017-07-23 17:31:04 +02:00
|
|
|
// See LICENSE.SiFive for license details.
|
|
|
|
|
|
|
|
package freechips.rocketchip.coreplex
|
|
|
|
|
|
|
|
import Chisel._
|
|
|
|
import freechips.rocketchip.config.{Field, Parameters}
|
|
|
|
import freechips.rocketchip.devices.tilelink._
|
|
|
|
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
|
|
|
import freechips.rocketchip.diplomacy._
|
|
|
|
import freechips.rocketchip.tile._
|
|
|
|
import freechips.rocketchip.tilelink._
|
|
|
|
import freechips.rocketchip.util._
|
|
|
|
|
2017-09-09 03:33:44 +02:00
|
|
|
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
|
|
|
case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing())
|
2017-07-23 17:31:04 +02:00
|
|
|
|
2017-10-06 09:56:23 +02:00
|
|
|
trait HasRocketTiles extends HasTiles
|
2017-07-23 17:31:04 +02:00
|
|
|
with HasPeripheryBus
|
|
|
|
with HasPeripheryPLIC
|
|
|
|
with HasPeripheryClint
|
|
|
|
with HasPeripheryDebug {
|
|
|
|
val module: HasRocketTilesModuleImp
|
|
|
|
|
|
|
|
private val crossing = p(RocketCrossing)
|
2017-10-06 09:56:23 +02:00
|
|
|
protected val tileParams = p(RocketTilesKey)
|
2017-07-23 17:31:04 +02:00
|
|
|
|
|
|
|
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
|
|
|
// according to the specified type of clock crossing.
|
2017-10-08 02:29:50 +02:00
|
|
|
val tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) =>
|
2017-07-23 17:31:04 +02:00
|
|
|
val pWithExtra = p.alterPartial {
|
2017-08-31 02:57:52 +02:00
|
|
|
case TileKey => tp
|
|
|
|
case BuildRoCC => tp.rocc
|
2017-07-23 17:31:04 +02:00
|
|
|
case SharedMemoryTLEdge => sharedMemoryTLEdge
|
|
|
|
}
|
|
|
|
|
|
|
|
val wrapper = crossing match {
|
|
|
|
case SynchronousCrossing(params) => {
|
2017-10-05 09:31:53 +02:00
|
|
|
val wrapper = LazyModule(new SyncRocketTile(tp)(pWithExtra))
|
2017-09-06 23:40:13 +02:00
|
|
|
sbus.fromSyncTiles(params, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
2017-09-26 22:23:54 +02:00
|
|
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toSyncSlaves(tp.name, tp.externalSlaveBuffers) }
|
2017-07-23 17:31:04 +02:00
|
|
|
wrapper
|
|
|
|
}
|
|
|
|
case AsynchronousCrossing(depth, sync) => {
|
2017-10-05 09:31:53 +02:00
|
|
|
val wrapper = LazyModule(new AsyncRocketTile(tp)(pWithExtra))
|
2017-09-06 23:40:13 +02:00
|
|
|
sbus.fromAsyncTiles(depth, sync, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
2017-09-26 22:23:54 +02:00
|
|
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toAsyncSlaves(sync, tp.name, tp.externalSlaveBuffers) }
|
2017-07-23 17:31:04 +02:00
|
|
|
wrapper
|
|
|
|
}
|
|
|
|
case RationalCrossing(direction) => {
|
2017-10-05 09:31:53 +02:00
|
|
|
val wrapper = LazyModule(new RationalRocketTile(tp)(pWithExtra))
|
2017-09-06 23:40:13 +02:00
|
|
|
sbus.fromRationalTiles(direction, tp.externalMasterBuffers, tp.name) :=* wrapper.masterNode
|
2017-09-26 22:23:54 +02:00
|
|
|
FlipRendering { implicit p => wrapper.slaveNode :*= pbus.toRationalSlaves(tp.name, tp.externalSlaveBuffers) }
|
2017-07-23 17:31:04 +02:00
|
|
|
wrapper
|
|
|
|
}
|
|
|
|
}
|
2017-08-31 02:57:52 +02:00
|
|
|
tp.name.foreach(wrapper.suggestName) // Try to stabilize this name for downstream tools
|
2017-07-23 17:31:04 +02:00
|
|
|
|
|
|
|
// Local Interrupts must be synchronized to the core clock
|
|
|
|
// before being passed into this module.
|
|
|
|
// This allows faster latency for interrupts which are already synchronized.
|
|
|
|
// The CLINT and PLIC outputs interrupts that are synchronous to the periphery clock,
|
|
|
|
// so may or may not need to be synchronized depending on the Tile's crossing type.
|
|
|
|
// Debug interrupt is definitely asynchronous in all cases.
|
|
|
|
val asyncIntXbar = LazyModule(new IntXbar)
|
|
|
|
asyncIntXbar.intnode := debug.intnode // debug
|
|
|
|
wrapper.asyncIntNode := asyncIntXbar.intnode
|
|
|
|
|
|
|
|
val periphIntXbar = LazyModule(new IntXbar)
|
|
|
|
periphIntXbar.intnode := clint.intnode // msip+mtip
|
|
|
|
periphIntXbar.intnode := plic.intnode // meip
|
2017-08-31 02:57:52 +02:00
|
|
|
if (tp.core.useVM) periphIntXbar.intnode := plic.intnode // seip
|
2017-07-23 17:31:04 +02:00
|
|
|
wrapper.periphIntNode := periphIntXbar.intnode
|
|
|
|
|
|
|
|
val coreIntXbar = LazyModule(new IntXbar)
|
|
|
|
lip.foreach { coreIntXbar.intnode := _ } // lip
|
|
|
|
wrapper.coreIntNode := coreIntXbar.intnode
|
|
|
|
|
2017-09-27 21:02:04 +02:00
|
|
|
wrapper.intOutputNode.foreach { case int =>
|
|
|
|
val rocketIntXing = LazyModule(new IntXing(wrapper.outputInterruptXingLatency))
|
2017-09-27 21:46:29 +02:00
|
|
|
FlipRendering { implicit p => rocketIntXing.intnode := int }
|
2017-09-27 21:02:04 +02:00
|
|
|
plic.intnode := rocketIntXing.intnode
|
|
|
|
}
|
2017-09-16 03:49:40 +02:00
|
|
|
|
2017-07-23 17:31:04 +02:00
|
|
|
wrapper
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-08 02:29:50 +02:00
|
|
|
trait HasRocketTilesModuleImp extends HasTilesModuleImp
|
2017-07-23 17:31:04 +02:00
|
|
|
with HasPeripheryDebugModuleImp {
|
2017-10-08 02:29:50 +02:00
|
|
|
val outer: HasRocketTiles
|
2017-07-23 17:31:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|
|
|
with HasRocketTiles {
|
|
|
|
override lazy val module = new RocketCoreplexModule(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
class RocketCoreplexModule[+L <: RocketCoreplex](_outer: L) extends BaseCoreplexModule(_outer)
|
|
|
|
with HasRocketTilesModuleImp
|