1
0
rocket-chip/src/main/scala/uncore/devices/Clint.scala

95 lines
2.5 KiB
Scala
Raw Normal View History

// See LICENSE.SiFive for license details.
package uncore.devices
import Chisel._
import junctions._
import junctions.NastiConstants._
import regmapper._
2016-10-29 06:20:49 +02:00
import diplomacy._
import uncore.tilelink2._
import uncore.util._
import util._
2016-09-16 07:06:39 +02:00
import scala.math.{min,max}
import config._
Heterogeneous Tiles (#550) Fundamental new features: * Added tile package: This package is intended to hold components re-usable across different types of tile. Will be the future location of TL2-RoCC accelerators and new diplomatic versions of intra-tile interfaces. * Adopted [ModuleName]Params convention: Code base was very inconsistent about what to name case classes that provide parameters to modules. Settled on calling them [ModuleName]Params to distinguish them from config.Parameters and config.Config. So far applied mostly only to case classes defined within rocket and tile. * Defined RocketTileParams: A nested case class containing case classes for all the components of a tile (L1 caches and core). Allows all such parameters to vary per-tile. * Defined RocketCoreParams: All the parameters that can be varied per-core. * Defined L1CacheParams: A trait defining the parameters common to L1 caches, made concrete in different derived case classes. * Defined RocketTilesKey: A sequence of RocketTileParams, one for every tile to be created. * Provided HeterogeneousDualCoreConfig: An example of making a heterogeneous chip with two cores, one big and one little. * Changes to legacy code: ReplacementPolicy moved to package util. L1Metadata moved to package tile. Legacy L2 cache agent removed because it can no longer share the metadata array implementation with the L1. Legacy GroundTests on life support. Additional changes that got rolled in along the way: * rocket: Fix critical path through BTB for I$ index bits > pgIdxBits * coreplex: tiles connected via :=* * groundtest: updated to use TileParams * tilelink: cache cork requirements are relaxed to allow more cacheless masters
2017-02-09 22:59:09 +01:00
import tile.XLen
2016-10-29 06:20:49 +02:00
object ClintConsts
{
def msipOffset(hart: Int) = hart * msipBytes
def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes
def timeOffset = 0xbff8
2016-06-28 08:05:48 +02:00
def msipBytes = 4
def timecmpBytes = 8
def size = 0x10000
def timeWidth = 64
def regWidth = 32
def ints = 2
2016-06-28 08:05:48 +02:00
}
case class ClintParams(baseAddress: BigInt = 0x02000000)
{
def address = AddressSet(baseAddress, ClintConsts.size-1)
}
class CoreplexLocalInterrupter(nTiles: Int, params: ClintParams)(implicit p: Parameters) extends LazyModule
{
import ClintConsts._
2016-06-28 08:05:48 +02:00
// clint0 => at most 4095 devices
val device = new SimpleDevice("clint", Seq("riscv,clint0")) {
override val alwaysExtended = true
}
val node = TLRegisterNode(
address = Seq(params.address),
device = device,
beatBytes = p(XLen)/8)
2016-06-28 08:05:48 +02:00
val intnode = IntNexusNode(
numSourcePorts = 0 to 1024,
numSinkPorts = 0 to 0,
sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(ints, Seq(Resource(device, "int"))))) },
sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) })
lazy val module = new LazyModuleImp(this) {
val io = new Bundle {
val rtcTick = Bool(INPUT)
val int = intnode.bundleOut
val in = node.bundleIn
}
val time = Seq.fill(timeWidth/regWidth)(Reg(init=UInt(0, width = regWidth)))
when (io.rtcTick) {
val newTime = time.asUInt + UInt(1)
for ((reg, i) <- time zip (0 until timeWidth by regWidth))
reg := newTime >> i
}
val timecmp = Seq.fill(nTiles) { Seq.fill(timeWidth/regWidth)(Reg(UInt(width = regWidth))) }
val ipi = Seq.fill(nTiles) { RegInit(UInt(0, width = 1)) }
io.int.zipWithIndex.foreach { case (int, i) =>
int(0) := ipi(i)(0) // msip
int(1) := time.asUInt >= timecmp(i).asUInt // mtip
}
/* 0000 msip hart 0
* 0004 msip hart 1
* 4000 mtimecmp hart 0 lo
* 4004 mtimecmp hart 0 hi
* 4008 mtimecmp hart 1 lo
* 400c mtimecmp hart 1 hi
* bff8 mtime lo
* bffc mtime hi
*/
def makeRegFields(s: Seq[UInt]) = s.map(r => RegField(regWidth, r))
node.regmap(
0 -> makeRegFields(ipi),
timecmpOffset(0) -> makeRegFields(timecmp.flatten),
timeOffset -> makeRegFields(time))
}
}