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

90 lines
2.9 KiB
Scala
Raw Normal View History

// See LICENSE for license details.
package uncore.devices
import Chisel._
import rocket.Util._
import junctions._
import junctions.NastiConstants._
import uncore.tilelink2._
import uncore.util._
2016-09-16 07:06:39 +02:00
import scala.math.{min,max}
import cde.{Parameters, Field}
/** Number of tiles */
case object NTiles extends Field[Int]
class CoreplexLocalInterrupts extends Bundle {
val mtip = Bool()
val msip = Bool()
}
case class CoreplexLocalInterrupterConfig(beatBytes: Int, address: BigInt = 0x44000000) {
def msipOffset(hart: Int) = hart * msipBytes
def msipAddress(hart: Int) = address + msipOffset(hart)
def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes
def timecmpAddress(hart: Int) = address + timecmpOffset(hart)
def timeOffset = 0xbff8
def timeAddress = address + timeOffset
2016-06-28 08:05:48 +02:00
def msipBytes = 4
def timecmpBytes = 8
def size = 0x10000
2016-06-28 08:05:48 +02:00
}
trait MixCoreplexLocalInterrupterParameters {
val params: (CoreplexLocalInterrupterConfig, Parameters)
val c = params._1
implicit val p = params._2
}
trait CoreplexLocalInterrupterBundle extends Bundle with MixCoreplexLocalInterrupterParameters {
val tiles = Vec(p(NTiles), new CoreplexLocalInterrupts).asOutput
val rtcTick = Bool(INPUT)
}
trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCoreplexLocalInterrupterParameters {
val io: CoreplexLocalInterrupterBundle
2016-06-28 08:05:48 +02:00
val timeWidth = 64
2016-09-16 07:06:39 +02:00
val time = Reg(init=UInt(0, width = timeWidth))
2016-06-28 08:05:48 +02:00
when (io.rtcTick) { time := time + UInt(1) }
val timecmp = Seq.fill(p(NTiles)) { Reg(UInt(width = timeWidth)) }
val ipi = Seq.fill(p(NTiles)) { RegInit(UInt(0, width = 1)) }
for ((tile, i) <- io.tiles zipWithIndex) {
tile.msip := ipi(i)(0)
tile.mtip := time >= timecmp(i)
}
2016-06-28 08:05:48 +02:00
def pad = RegField(8) // each use is a new field
val ipi_fields = ipi.map(r => Seq(RegField(1, r), RegField(7), pad, pad, pad)).flatten
val timecmp_fields = timecmp.map(RegField.bytes(_)).flatten
val time_fields = Seq.fill(c.timeOffset % c.beatBytes)(pad) ++ RegField.bytes(time)
/* 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
*/
val ipi_base = 0
val timecmp_base = c.timecmpOffset(0) / c.beatBytes
val time_base = c.timeOffset / c.beatBytes
regmap((
RegField.split(ipi_fields, ipi_base, c.beatBytes) ++
RegField.split(timecmp_fields, timecmp_base, c.beatBytes) ++
RegField.split(time_fields, time_base, c.beatBytes)):_*)
}
/** Power, Reset, Clock, Interrupt */
// Magic TL2 Incantation to create a TL2 Slave
class CoreplexLocalInterrupter(c: CoreplexLocalInterrupterConfig)(implicit val p: Parameters)
extends TLRegisterRouter(c.address, 0, c.size, None, c.beatBytes, false)(
new TLRegBundle((c, p), _) with CoreplexLocalInterrupterBundle)(
new TLRegModule((c, p), _, _) with CoreplexLocalInterrupterModule)