Merge branch 'master' of github.com:ucb-bar/rocket-chip into monitor
This commit is contained in:
		@@ -419,7 +419,7 @@ tests and benchmarks.
 | 
			
		||||
 | 
			
		||||
By now, you probably figured out that all generated files have a configuration
 | 
			
		||||
name attached, e.g. DefaultConfig. Take a look at
 | 
			
		||||
src/main/scala/Configs.scala. Search for NSets and NWays defined in
 | 
			
		||||
src/main/scala/rocketchip/Configs.scala. Search for NSets and NWays defined in
 | 
			
		||||
BaseConfig. You can change those numbers to get a Rocket core with different
 | 
			
		||||
cache parameters. For example, by changing L1I, NWays to 4, you will get
 | 
			
		||||
a 32KB 4-way set-associative L1 instruction cache rather than a 16KB 2-way
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import uncore.devices._
 | 
			
		||||
import uncore.converters._
 | 
			
		||||
import rocket._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import rocketchip.{GlobalAddrMap, NCoreplexExtClients}
 | 
			
		||||
import scala.math.max
 | 
			
		||||
import scala.collection.mutable.{LinkedHashSet, ListBuffer}
 | 
			
		||||
import DefaultTestSuites._
 | 
			
		||||
@@ -122,12 +123,12 @@ class BaseCoreplexConfig extends Config (
 | 
			
		||||
      case NPerfEvents => 0
 | 
			
		||||
      case FastLoadWord => true
 | 
			
		||||
      case FastLoadByte => false
 | 
			
		||||
      case FastJAL => false
 | 
			
		||||
      case XLen => 64
 | 
			
		||||
      case FPUKey => Some(FPUConfig())
 | 
			
		||||
      case MulDivKey => Some(MulDivConfig(mulUnroll = 8, mulEarlyOut = true, divEarlyOut = true))
 | 
			
		||||
      case MulDivKey => Some(MulDivConfig(mulUnroll = 8, mulEarlyOut = (site(XLen) > 32), divEarlyOut = true))
 | 
			
		||||
      case UseAtomics => true
 | 
			
		||||
      case UseCompressed => true
 | 
			
		||||
      case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), 0)
 | 
			
		||||
      case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
 | 
			
		||||
      case NCustomMRWCSRs => 0
 | 
			
		||||
      case ResetVector => BigInt(0x1000)
 | 
			
		||||
@@ -145,7 +146,7 @@ class BaseCoreplexConfig extends Config (
 | 
			
		||||
            else new MESICoherence(site(L2DirectoryRepresentation))),
 | 
			
		||||
          nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */,
 | 
			
		||||
          nCachingClients = site(NCachedTileLinkPorts),
 | 
			
		||||
          nCachelessClients = site(NExternalClients) + site(NUncachedTileLinkPorts),
 | 
			
		||||
          nCachelessClients = site(NCoreplexExtClients).get + site(NUncachedTileLinkPorts),
 | 
			
		||||
          maxClientXacts = max_int(
 | 
			
		||||
              // L1 cache
 | 
			
		||||
              site(DCacheKey).nMSHRs + 1 /* IOMSHR */,
 | 
			
		||||
@@ -176,7 +177,7 @@ class BaseCoreplexConfig extends Config (
 | 
			
		||||
        TileLinkParameters(
 | 
			
		||||
          coherencePolicy = new MICoherence(
 | 
			
		||||
            new NullRepresentation(site(NBanksPerMemoryChannel))),
 | 
			
		||||
          nManagers = site(GlobalAddrMap).subMap("io").numSlaves,
 | 
			
		||||
          nManagers = site(GlobalAddrMap).get.subMap("io").numSlaves,
 | 
			
		||||
          nCachingClients = 0,
 | 
			
		||||
          nCachelessClients = 1,
 | 
			
		||||
          maxClientXacts = 4,
 | 
			
		||||
@@ -194,7 +195,6 @@ class BaseCoreplexConfig extends Config (
 | 
			
		||||
      case CacheBlockBytes => Dump("CACHE_BLOCK_BYTES", 64)
 | 
			
		||||
      case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes))
 | 
			
		||||
      case EnableL2Logging => false
 | 
			
		||||
      case ExtraCoreplexPorts => (p: Parameters) => new Bundle
 | 
			
		||||
      case RegressionTestNames => LinkedHashSet(
 | 
			
		||||
        "rv64ud-v-fcvt",
 | 
			
		||||
        "rv64ud-p-fdiv",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,45 +24,42 @@ case object BankIdLSB extends Field[Int]
 | 
			
		||||
case object BuildL2CoherenceManager extends Field[(Int, Parameters) => CoherenceAgent]
 | 
			
		||||
/** Function for building some kind of tile connected to a reset signal */
 | 
			
		||||
case object BuildTiles extends Field[Seq[(Bool, Parameters) => Tile]]
 | 
			
		||||
/** A string describing on-chip devices, readable by target software */
 | 
			
		||||
case object ConfigString extends Field[Array[Byte]]
 | 
			
		||||
/** Number of external interrupt sources */
 | 
			
		||||
case object NExtInterrupts extends Field[Int]
 | 
			
		||||
/** Interrupt controller configuration */
 | 
			
		||||
case object PLICKey extends Field[PLICConfig]
 | 
			
		||||
/** The file to read the BootROM contents from */
 | 
			
		||||
case object BootROMFile extends Field[String]
 | 
			
		||||
/** Export an external MMIO slave port */
 | 
			
		||||
case object ExportMMIOPort extends Field[Boolean]
 | 
			
		||||
/** Expose additional TileLink client ports */
 | 
			
		||||
case object NExternalClients extends Field[Int]
 | 
			
		||||
/** Extra top-level ports exported from the coreplex */
 | 
			
		||||
case object ExtraCoreplexPorts extends Field[Parameters => Bundle]
 | 
			
		||||
 | 
			
		||||
trait HasCoreplexParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  lazy val nTiles = p(NTiles)
 | 
			
		||||
  lazy val nMemChannels = p(NMemoryChannels)
 | 
			
		||||
  lazy val nBanksPerMemChannel = p(NBanksPerMemoryChannel)
 | 
			
		||||
  lazy val nBanks = nMemChannels*nBanksPerMemChannel
 | 
			
		||||
  lazy val lsb = p(BankIdLSB)
 | 
			
		||||
  lazy val innerParams = p.alterPartial({ case TLId => "L1toL2" })
 | 
			
		||||
  lazy val outermostParams = p.alterPartial({ case TLId => "Outermost" })
 | 
			
		||||
  lazy val outermostMMIOParams = p.alterPartial({ case TLId => "MMIO_Outermost" })
 | 
			
		||||
  lazy val nExtClients = p(NExternalClients)
 | 
			
		||||
  lazy val exportMMIO = p(ExportMMIOPort)
 | 
			
		||||
  lazy val configString = p(rocketchip.ConfigString).get
 | 
			
		||||
  lazy val globalAddrMap = p(rocketchip.GlobalAddrMap).get
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract class Coreplex(implicit val p: Parameters) extends Module
 | 
			
		||||
case class CoreplexConfig(
 | 
			
		||||
    nTiles: Int,
 | 
			
		||||
    nExtInterrupts: Int,
 | 
			
		||||
    nSlaves: Int,
 | 
			
		||||
    nMemChannels: Int,
 | 
			
		||||
    hasSupervisor: Boolean,
 | 
			
		||||
    hasExtMMIOPort: Boolean)
 | 
			
		||||
{
 | 
			
		||||
  val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract class Coreplex(implicit val p: Parameters, implicit val c: CoreplexConfig) extends Module
 | 
			
		||||
    with HasCoreplexParameters {
 | 
			
		||||
  class CoreplexIO(implicit val p: Parameters) extends Bundle {
 | 
			
		||||
    val mem  = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
 | 
			
		||||
    val ext_clients = Vec(nExtClients, new ClientUncachedTileLinkIO()(innerParams)).flip
 | 
			
		||||
    val mmio = p(ExportMMIOPort).option(new ClientUncachedTileLinkIO()(outermostMMIOParams))
 | 
			
		||||
    val interrupts = Vec(p(NExtInterrupts), Bool()).asInput
 | 
			
		||||
  class CoreplexIO(implicit val p: Parameters, implicit val c: CoreplexConfig) extends Bundle {
 | 
			
		||||
    val master = new Bundle {
 | 
			
		||||
      val mem = Vec(c.nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
 | 
			
		||||
      val mmio = c.hasExtMMIOPort.option(new ClientUncachedTileLinkIO()(outermostMMIOParams))
 | 
			
		||||
    }
 | 
			
		||||
    val slave = Vec(c.nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip
 | 
			
		||||
    val interrupts = Vec(c.nExtInterrupts, Bool()).asInput
 | 
			
		||||
    val debug = new DebugBusIO()(p).flip
 | 
			
		||||
    val rtcTick = Bool(INPUT)
 | 
			
		||||
    val extra = p(ExtraCoreplexPorts)(p)
 | 
			
		||||
    val success: Option[Bool] = hasSuccessFlag.option(Bool(OUTPUT))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -70,16 +67,17 @@ abstract class Coreplex(implicit val p: Parameters) extends Module
 | 
			
		||||
  val io = new CoreplexIO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
class DefaultCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) {
 | 
			
		||||
  // Build a set of Tiles
 | 
			
		||||
  val tileResets = Wire(Vec(nTiles, Bool()))
 | 
			
		||||
  val tileResets = Wire(Vec(tc.nTiles, Bool()))
 | 
			
		||||
  val tileList = p(BuildTiles).zip(tileResets).map {
 | 
			
		||||
    case (tile, rst) => tile(rst, p)
 | 
			
		||||
  }
 | 
			
		||||
  val nCachedPorts = tileList.map(tile => tile.io.cached.size).reduce(_ + _)
 | 
			
		||||
  val nUncachedPorts = tileList.map(tile => tile.io.uncached.size).reduce(_ + _)
 | 
			
		||||
  val nBanks = tc.nMemChannels * nBanksPerMemChannel
 | 
			
		||||
 | 
			
		||||
  printConfigString
 | 
			
		||||
  // Build an uncore backing the Tiles
 | 
			
		||||
  buildUncore(p.alterPartial({
 | 
			
		||||
    case HastiId => "TL"
 | 
			
		||||
    case TLId => "L1toL2"
 | 
			
		||||
@@ -87,25 +85,13 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
    case NUncachedTileLinkPorts => nUncachedPorts
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  def printConfigString(implicit p: Parameters) = {
 | 
			
		||||
    println("Generated Address Map")
 | 
			
		||||
    for (entry <- p(GlobalAddrMap).flatten) {
 | 
			
		||||
      val name = entry.name
 | 
			
		||||
      val start = entry.region.start
 | 
			
		||||
      val end = entry.region.start + entry.region.size - 1
 | 
			
		||||
      println(f"\t$name%s $start%x - $end%x")
 | 
			
		||||
    }
 | 
			
		||||
    println("Generated Configuration String")
 | 
			
		||||
    println(new String(p(ConfigString)))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def buildUncore(implicit p: Parameters) = {
 | 
			
		||||
    // Create a simple L1toL2 NoC between the tiles and the banks of outer memory
 | 
			
		||||
    // Cached ports are first in client list, making sharerToClientId just an indentity function
 | 
			
		||||
    // addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
 | 
			
		||||
    def sharerToClientId(sharerId: UInt) = sharerId
 | 
			
		||||
    def addrToBank(addr: UInt): UInt = if (nBanks == 0) UInt(0) else {
 | 
			
		||||
      val isMemory = p(GlobalAddrMap).isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
 | 
			
		||||
      val isMemory = globalAddrMap.isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
 | 
			
		||||
      Mux(isMemory, addr.extract(lsb + log2Ceil(nBanks) - 1, lsb), UInt(nBanks))
 | 
			
		||||
    }
 | 
			
		||||
    val preBuffering = TileLinkDepths(1,1,2,2,0)
 | 
			
		||||
@@ -124,11 +110,11 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
    // Wire the tiles to the TileLink client ports of the L1toL2 network,
 | 
			
		||||
    // and coherence manager(s) to the other side
 | 
			
		||||
    l1tol2net.io.clients_cached <> tileList.map(_.io.cached).flatten
 | 
			
		||||
    l1tol2net.io.clients_uncached <> tileList.map(_.io.uncached).flatten ++ io.ext_clients
 | 
			
		||||
    l1tol2net.io.clients_uncached <> tileList.map(_.io.uncached).flatten ++ io.slave
 | 
			
		||||
    l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
 | 
			
		||||
 | 
			
		||||
    // Create a converter between TileLinkIO and MemIO for each channel
 | 
			
		||||
    val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, nMemChannels)(outermostParams))
 | 
			
		||||
    val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, tc.nMemChannels)(outermostParams))
 | 
			
		||||
 | 
			
		||||
    val outerTLParams = p.alterPartial({ case TLId => "L2toMC" })
 | 
			
		||||
    val backendBuffering = TileLinkDepths(0,0,0,0,0)
 | 
			
		||||
@@ -138,7 +124,7 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
      TileLinkWidthAdapter(icPort, unwrap.io.out)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    io.mem <> mem_ic.io.out
 | 
			
		||||
    io.master.mem <> mem_ic.io.out
 | 
			
		||||
 | 
			
		||||
    buildMMIONetwork(ClientUncachedTileLinkEnqueuer(mmioManager.io.outer, 1))(
 | 
			
		||||
        p.alterPartial({case TLId => "L2toMMIO"}))
 | 
			
		||||
@@ -151,7 +137,10 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
    rom.order(ByteOrder.LITTLE_ENDIAN)
 | 
			
		||||
 | 
			
		||||
    // for now, have the reset vector jump straight to memory
 | 
			
		||||
    val memBase = (if (p(GlobalAddrMap) contains "mem") p(GlobalAddrMap)("mem") else p(GlobalAddrMap)("io:int:dmem0")).start
 | 
			
		||||
    val memBase = (
 | 
			
		||||
      if (globalAddrMap contains "mem") globalAddrMap("mem")
 | 
			
		||||
      else globalAddrMap("io:int:dmem0")
 | 
			
		||||
    ).start
 | 
			
		||||
    val resetToMemDist = memBase - p(ResetVector)
 | 
			
		||||
    require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
 | 
			
		||||
    val configStringAddr = p(ResetVector).toInt + rom.capacity
 | 
			
		||||
@@ -159,17 +148,17 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
    require(rom.getInt(12) == 0,
 | 
			
		||||
      "Config string address position should not be occupied by code")
 | 
			
		||||
    rom.putInt(12, configStringAddr)
 | 
			
		||||
    rom.array() ++ p(ConfigString).toSeq
 | 
			
		||||
    rom.array() ++ (configString.getBytes.toSeq)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  def buildMMIONetwork(mmio: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val ioAddrMap = p(GlobalAddrMap).subMap("io")
 | 
			
		||||
    val ioAddrMap = globalAddrMap.subMap("io")
 | 
			
		||||
 | 
			
		||||
    val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap))
 | 
			
		||||
    mmioNetwork.io.in.head <> mmio
 | 
			
		||||
 | 
			
		||||
    val plic = Module(new PLIC(p(PLICKey)))
 | 
			
		||||
    val plic = Module(new PLIC(c.plicKey))
 | 
			
		||||
    plic.io.tl <> mmioNetwork.port("int:plic")
 | 
			
		||||
    for (i <- 0 until io.interrupts.size) {
 | 
			
		||||
      val gateway = Module(new LevelGateway)
 | 
			
		||||
@@ -191,25 +180,25 @@ class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
        tile.io.prci <> prci
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i <- 0 until nTiles) {
 | 
			
		||||
    for (i <- 0 until tc.nTiles) {
 | 
			
		||||
      prci.io.interrupts(i).meip := plic.io.harts(plic.cfg.context(i, 'M'))
 | 
			
		||||
      if (p(UseVM))
 | 
			
		||||
        prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
 | 
			
		||||
      prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val tileSlavePorts = (0 until nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)
 | 
			
		||||
    val tileSlavePorts = (0 until tc.nTiles) map (i => s"int:dmem$i") filter (ioAddrMap contains _)
 | 
			
		||||
    for ((t, m) <- (tileList.map(_.io.slave).flatten) zip (tileSlavePorts map (mmioNetwork port _)))
 | 
			
		||||
      t <> ClientUncachedTileLinkEnqueuer(m, 1)
 | 
			
		||||
 | 
			
		||||
    val bootROM = Module(new ROMSlave(makeBootROM()))
 | 
			
		||||
    bootROM.io <> mmioNetwork.port("int:bootrom")
 | 
			
		||||
 | 
			
		||||
    io.mmio.foreach { _ <> mmioNetwork.port("ext") }
 | 
			
		||||
    io.master.mmio.foreach { _ <> mmioNetwork.port("ext") }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class GroundTestCoreplex(topParams: Parameters) extends DefaultCoreplex(topParams) {
 | 
			
		||||
class GroundTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends DefaultCoreplex(tp, tc) {
 | 
			
		||||
  override def hasSuccessFlag = true
 | 
			
		||||
  io.success.get := tileList.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,63 +0,0 @@
 | 
			
		||||
package coreplex
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
import rocket.TileId
 | 
			
		||||
import groundtest._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.agents._
 | 
			
		||||
 | 
			
		||||
case object ExportGroundTestStatus extends Field[Boolean]
 | 
			
		||||
 | 
			
		||||
class DirectGroundTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
  // Not using the debug 
 | 
			
		||||
  io.debug.req.ready := Bool(false)
 | 
			
		||||
  io.debug.resp.valid := Bool(false)
 | 
			
		||||
 | 
			
		||||
  require(!exportMMIO)
 | 
			
		||||
  require(nExtClients == 0)
 | 
			
		||||
  require(nMemChannels == 1)
 | 
			
		||||
  require(nTiles == 1)
 | 
			
		||||
 | 
			
		||||
  val test = p(BuildGroundTest)(outermostParams.alterPartial({
 | 
			
		||||
    case TileId => 0
 | 
			
		||||
    case CacheName => "L1D"
 | 
			
		||||
  }))
 | 
			
		||||
  require(test.io.cache.size == 0)
 | 
			
		||||
  require(test.io.mem.size == nBanksPerMemChannel)
 | 
			
		||||
  require(test.io.ptw.size == 0)
 | 
			
		||||
 | 
			
		||||
  val mem_ic = Module(new TileLinkMemoryInterconnect(
 | 
			
		||||
    nBanksPerMemChannel, nMemChannels)(outermostParams))
 | 
			
		||||
 | 
			
		||||
  mem_ic.io.in <> test.io.mem
 | 
			
		||||
  io.mem <> mem_ic.io.out
 | 
			
		||||
 | 
			
		||||
  if (p(ExportGroundTestStatus)) {
 | 
			
		||||
    val status = io.extra.asInstanceOf[GroundTestStatus]
 | 
			
		||||
 | 
			
		||||
    val s_running :: s_finished :: s_errored :: s_timeout :: Nil = Enum(Bits(), 4)
 | 
			
		||||
    val state = Reg(init = s_running)
 | 
			
		||||
    val error_code = Reg(status.error.bits)
 | 
			
		||||
    val timeout_code = Reg(status.timeout.bits)
 | 
			
		||||
    when (state === s_running) {
 | 
			
		||||
      when (test.io.status.finished) { state := s_finished }
 | 
			
		||||
      when (test.io.status.error.valid) {
 | 
			
		||||
        state := s_errored
 | 
			
		||||
        error_code := test.io.status.error.bits
 | 
			
		||||
      }
 | 
			
		||||
      when (test.io.status.timeout.valid) {
 | 
			
		||||
        state := s_timeout
 | 
			
		||||
        timeout_code := test.io.status.timeout.bits
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    status.finished := (state === s_finished)
 | 
			
		||||
    status.error.valid := (state === s_errored)
 | 
			
		||||
    status.error.bits := error_code
 | 
			
		||||
    status.timeout.valid := (state === s_timeout)
 | 
			
		||||
    status.timeout.bits := timeout_code
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  override def hasSuccessFlag = true
 | 
			
		||||
  io.success.get := test.io.status.finished
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ package coreplex
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import groundtest._
 | 
			
		||||
import rocketchip.{GlobalAddrMap}
 | 
			
		||||
import rocket._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.coherence._
 | 
			
		||||
@@ -24,7 +25,7 @@ class WithComparator extends Config(
 | 
			
		||||
      (p: Parameters) => Module(new ComparatorCore()(p))
 | 
			
		||||
    case ComparatorKey => ComparatorParameters(
 | 
			
		||||
      targets    = Seq("mem", "io:ext:testram").map(name =>
 | 
			
		||||
                    site(GlobalAddrMap)(name).start.longValue),
 | 
			
		||||
                    site(GlobalAddrMap).get(name).start.longValue),
 | 
			
		||||
      width      = 8,
 | 
			
		||||
      operations = 1000,
 | 
			
		||||
      atomics    = site(UseAtomics),
 | 
			
		||||
@@ -54,7 +55,7 @@ class WithMemtest extends Config(
 | 
			
		||||
    }
 | 
			
		||||
    case GeneratorKey => GeneratorParameters(
 | 
			
		||||
      maxRequests = 128,
 | 
			
		||||
      startAddress = site(GlobalAddrMap)("mem").start)
 | 
			
		||||
      startAddress = site(GlobalAddrMap).get("mem").start)
 | 
			
		||||
    case BuildGroundTest =>
 | 
			
		||||
      (p: Parameters) => Module(new GeneratorTest()(p))
 | 
			
		||||
    case _ => throw new CDEMatchError
 | 
			
		||||
@@ -114,7 +115,7 @@ class WithNastiConverterTest extends Config(
 | 
			
		||||
    }
 | 
			
		||||
    case GeneratorKey => GeneratorParameters(
 | 
			
		||||
      maxRequests = 128,
 | 
			
		||||
      startAddress = site(GlobalAddrMap)("mem").start)
 | 
			
		||||
      startAddress = site(GlobalAddrMap).get("mem").start)
 | 
			
		||||
    case BuildGroundTest =>
 | 
			
		||||
      (p: Parameters) => Module(new NastiConverterTest()(p))
 | 
			
		||||
    case _ => throw new CDEMatchError
 | 
			
		||||
@@ -134,7 +135,7 @@ class WithTraceGen extends Config(
 | 
			
		||||
      val nSets = 32 // L2 NSets
 | 
			
		||||
      val nWays = 1
 | 
			
		||||
      val blockOffset = site(CacheBlockOffsetBits)
 | 
			
		||||
      val baseAddr = site(GlobalAddrMap)("mem").start
 | 
			
		||||
      val baseAddr = site(GlobalAddrMap).get("mem").start
 | 
			
		||||
      val nBeats = site(MIFDataBeats)
 | 
			
		||||
      List.tabulate(4 * nWays) { i =>
 | 
			
		||||
        Seq.tabulate(nBeats) { j => (j * 8) + ((i * nSets) << blockOffset) }
 | 
			
		||||
@@ -156,7 +157,7 @@ class WithPCIeMockupTest extends Config(
 | 
			
		||||
      GroundTestTileSettings(1))
 | 
			
		||||
    case GeneratorKey => GeneratorParameters(
 | 
			
		||||
      maxRequests = 128,
 | 
			
		||||
      startAddress = site(GlobalAddrMap)("mem").start)
 | 
			
		||||
      startAddress = site(GlobalAddrMap).get("mem").start)
 | 
			
		||||
    case BuildGroundTest =>
 | 
			
		||||
      (p: Parameters) => p(TileId) match {
 | 
			
		||||
        case 0 => Module(new GeneratorTest()(p))
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,10 @@ import rocket.Tile
 | 
			
		||||
import uncore.tilelink.TLId
 | 
			
		||||
import cde.Parameters
 | 
			
		||||
 | 
			
		||||
class UnitTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
 | 
			
		||||
  require(!exportMMIO)
 | 
			
		||||
  require(nExtClients == 0)
 | 
			
		||||
  require(nMemChannels == 0)
 | 
			
		||||
class UnitTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) {
 | 
			
		||||
  require(!tc.hasExtMMIOPort)
 | 
			
		||||
  require(tc.nSlaves == 0)
 | 
			
		||||
  require(tc.nMemChannels == 0)
 | 
			
		||||
 | 
			
		||||
  io.debug.req.ready := Bool(false)
 | 
			
		||||
  io.debug.resp.valid := Bool(false)
 | 
			
		||||
 
 | 
			
		||||
@@ -176,6 +176,7 @@ class TagMan(val logNumTags : Int) extends Module {
 | 
			
		||||
 | 
			
		||||
class TraceGenerator(id: Int)
 | 
			
		||||
    (implicit p: Parameters) extends L1HellaCacheModule()(p)
 | 
			
		||||
                                with HasAddrMapParameters
 | 
			
		||||
                                with HasTraceGenParams {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val finished = Bool(OUTPUT)
 | 
			
		||||
@@ -197,8 +198,7 @@ class TraceGenerator(id: Int)
 | 
			
		||||
  // Address bag, shared by all cores, taken from module parameters.
 | 
			
		||||
  // In addition, there is a per-core random selection of extra addresses.
 | 
			
		||||
 | 
			
		||||
  val addrHashMap = p(GlobalAddrMap)
 | 
			
		||||
  val baseAddr = addrHashMap("mem").start + 0x01000000
 | 
			
		||||
  val baseAddr = addrMap("mem").start + 0x01000000
 | 
			
		||||
 | 
			
		||||
  val bagOfAddrs = addressBag.map(x => UInt(x, numBitsInWord))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,12 @@ import cde.{Parameters, Field}
 | 
			
		||||
import scala.collection.mutable.HashMap
 | 
			
		||||
 | 
			
		||||
case object PAddrBits extends Field[Int]
 | 
			
		||||
case object GlobalAddrMap extends Field[AddrMap]
 | 
			
		||||
 | 
			
		||||
trait HasAddrMapParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
 | 
			
		||||
  val paddrBits = p(PAddrBits)
 | 
			
		||||
  val addrMap = p(GlobalAddrMap)
 | 
			
		||||
  def addrMap = p(rocketchip.GlobalAddrMap).get
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case class MemAttr(prot: Int, cacheable: Boolean = false)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import junctions._
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
import Util._
 | 
			
		||||
import uncore.util._
 | 
			
		||||
import uncore.agents.PseudoLRU
 | 
			
		||||
 | 
			
		||||
case object BtbKey extends Field[BtbParameters]
 | 
			
		||||
 | 
			
		||||
@@ -180,7 +181,16 @@ class BTB(implicit p: Parameters) extends BtbModule {
 | 
			
		||||
  val updateHits = tagMatch(r_btb_update.bits.pc, updatePageHit)
 | 
			
		||||
  val updateHit = if (updatesOutOfOrder) updateHits.orR else r_btb_update.bits.prediction.valid
 | 
			
		||||
  val updateHitAddr = if (updatesOutOfOrder) OHToUInt(updateHits) else r_btb_update.bits.prediction.bits.entry
 | 
			
		||||
  val nextRepl = Counter(r_btb_update.valid && !updateHit, entries)._1
 | 
			
		||||
 | 
			
		||||
  // we'd prefer PseudoLRU replacement, but it only works for powers of 2
 | 
			
		||||
  val nextRepl =
 | 
			
		||||
    if (!isPow2(entries)) {
 | 
			
		||||
      Counter(r_btb_update.valid && !updateHit, entries)._1
 | 
			
		||||
    } else {
 | 
			
		||||
      val plru = new PseudoLRU(entries)
 | 
			
		||||
      when (hits.orR) { plru.access(OHToUInt(hits)) }
 | 
			
		||||
      plru.replace
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  val useUpdatePageHit = updatePageHit.orR
 | 
			
		||||
  val usePageHit = pageHit.orR
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,10 @@ import uncore.util._
 | 
			
		||||
import junctions.AddrMap
 | 
			
		||||
 | 
			
		||||
class MStatus extends Bundle {
 | 
			
		||||
  val debug = Bool() // not truly part of mstatus, but convenient
 | 
			
		||||
  // not truly part of mstatus, but convenient
 | 
			
		||||
  val debug = Bool()
 | 
			
		||||
  val isa = UInt(width = 32)
 | 
			
		||||
 | 
			
		||||
  val prv = UInt(width = PRV.SZ) // not truly part of mstatus, but convenient
 | 
			
		||||
  val sd = Bool()
 | 
			
		||||
  val zero3 = UInt(width = 31)
 | 
			
		||||
@@ -260,16 +263,18 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
  val cpu_ren = io.rw.cmd =/= CSR.N && !system_insn
 | 
			
		||||
  val cpu_wen = cpu_ren && io.rw.cmd =/= CSR.R
 | 
			
		||||
 | 
			
		||||
  val isa_string = "I" +
 | 
			
		||||
  val isaMaskString =
 | 
			
		||||
    (if (usingMulDiv) "M" else "") +
 | 
			
		||||
    (if (usingAtomics) "A" else "") +
 | 
			
		||||
    (if (usingFPU) "F" else "") +
 | 
			
		||||
    (if (usingFPU && xLen > 32) "D" else "") +
 | 
			
		||||
    (if (usingVM) "S" else "") +
 | 
			
		||||
    (if (usingUser) "U" else "") +
 | 
			
		||||
    (if (usingCompressed) "C" else "") +
 | 
			
		||||
    (if (usingRoCC) "X" else "")
 | 
			
		||||
  val isa = (BigInt(log2Ceil(xLen) - 4) << (xLen-2)) |
 | 
			
		||||
    isa_string.map(x => 1 << (x - 'A')).reduce(_|_)
 | 
			
		||||
  val isaString = "I" + isaMaskString +
 | 
			
		||||
    (if (usingVM) "S" else "") +
 | 
			
		||||
    (if (usingUser) "U" else "")
 | 
			
		||||
  val isaMax = (BigInt(log2Ceil(xLen) - 4) << (xLen-2)) | isaStringToMask(isaString)
 | 
			
		||||
  val reg_misa = Reg(init=UInt(isaMax))
 | 
			
		||||
  val read_mstatus = io.status.asUInt()(xLen-1,0)
 | 
			
		||||
 | 
			
		||||
  val read_mapping = collection.mutable.LinkedHashMap[Int,Bits](
 | 
			
		||||
@@ -281,7 +286,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
    CSRs.mvendorid -> UInt(0),
 | 
			
		||||
    CSRs.mcycle -> reg_cycle,
 | 
			
		||||
    CSRs.minstret -> reg_instret,
 | 
			
		||||
    CSRs.misa -> UInt(isa),
 | 
			
		||||
    CSRs.misa -> reg_misa,
 | 
			
		||||
    CSRs.mstatus -> read_mstatus,
 | 
			
		||||
    CSRs.mtvec -> reg_mtvec,
 | 
			
		||||
    CSRs.mip -> read_mip,
 | 
			
		||||
@@ -394,7 +399,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
  val insn_wfi = do_system_insn && opcode(5)
 | 
			
		||||
 | 
			
		||||
  io.csr_xcpt := (cpu_wen && read_only) ||
 | 
			
		||||
    (cpu_ren && (!priv_sufficient || !addr_valid || (hpm_csr && !hpm_en) || (fp_csr && !io.status.fs.orR))) ||
 | 
			
		||||
    (cpu_ren && (!priv_sufficient || !addr_valid || (hpm_csr && !hpm_en) || (fp_csr && !(io.status.fs.orR && reg_misa('f'-'a'))))) ||
 | 
			
		||||
    (system_insn && !priv_sufficient) ||
 | 
			
		||||
    insn_call || insn_break
 | 
			
		||||
 | 
			
		||||
@@ -422,6 +427,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
  io.status := reg_mstatus
 | 
			
		||||
  io.status.sd := io.status.fs.andR || io.status.xs.andR
 | 
			
		||||
  io.status.debug := reg_debug
 | 
			
		||||
  io.status.isa := reg_misa
 | 
			
		||||
  if (xLen == 32)
 | 
			
		||||
    io.status.sd_rv32 := io.status.sd
 | 
			
		||||
 | 
			
		||||
@@ -439,7 +445,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      reg_dcsr.cause := Mux(reg_singleStepped, 4, Mux(causeIsDebugInt, 3, Mux[UInt](causeIsDebugTrigger, 2, 1)))
 | 
			
		||||
      reg_dcsr.prv := trimPrivilege(reg_mstatus.prv)
 | 
			
		||||
    }.elsewhen (delegate) {
 | 
			
		||||
      reg_sepc := epc
 | 
			
		||||
      reg_sepc := formEPC(epc)
 | 
			
		||||
      reg_scause := cause
 | 
			
		||||
      when (write_badaddr) { reg_sbadaddr := io.badaddr }
 | 
			
		||||
      reg_mstatus.spie := pie
 | 
			
		||||
@@ -447,7 +453,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      reg_mstatus.sie := false
 | 
			
		||||
      new_prv := PRV.S
 | 
			
		||||
    }.otherwise {
 | 
			
		||||
      reg_mepc := epc
 | 
			
		||||
      reg_mepc := formEPC(epc)
 | 
			
		||||
      reg_mcause := cause
 | 
			
		||||
      when (write_badaddr) { reg_mbadaddr := io.badaddr }
 | 
			
		||||
      reg_mstatus.mpie := pie
 | 
			
		||||
@@ -514,6 +520,11 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      if (usingVM || usingFPU) reg_mstatus.fs := Fill(2, new_mstatus.fs.orR)
 | 
			
		||||
      if (usingRoCC) reg_mstatus.xs := Fill(2, new_mstatus.xs.orR)
 | 
			
		||||
    }
 | 
			
		||||
    when (decoded_addr(CSRs.misa)) {
 | 
			
		||||
      val mask = UInt(isaStringToMask(isaMaskString))
 | 
			
		||||
      val f = wdata('f' - 'a')
 | 
			
		||||
      reg_misa := ~(~wdata | (!f << ('d' - 'a'))) & mask | reg_misa & ~mask
 | 
			
		||||
    }
 | 
			
		||||
    when (decoded_addr(CSRs.mip)) {
 | 
			
		||||
      val new_mip = new MIP().fromBits(wdata)
 | 
			
		||||
      if (usingVM) {
 | 
			
		||||
@@ -522,7 +533,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    when (decoded_addr(CSRs.mie))      { reg_mie := wdata & supported_interrupts }
 | 
			
		||||
    when (decoded_addr(CSRs.mepc))     { reg_mepc := ~(~wdata | (coreInstBytes-1)) }
 | 
			
		||||
    when (decoded_addr(CSRs.mepc))     { reg_mepc := formEPC(wdata) }
 | 
			
		||||
    when (decoded_addr(CSRs.mscratch)) { reg_mscratch := wdata }
 | 
			
		||||
    if (p(MtvecWritable))
 | 
			
		||||
      when (decoded_addr(CSRs.mtvec))  { reg_mtvec := wdata >> 2 << 2 }
 | 
			
		||||
@@ -572,7 +583,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      when (decoded_addr(CSRs.sie))      { reg_mie := (reg_mie & ~reg_mideleg) | (wdata & reg_mideleg) }
 | 
			
		||||
      when (decoded_addr(CSRs.sscratch)) { reg_sscratch := wdata }
 | 
			
		||||
      when (decoded_addr(CSRs.sptbr))    { reg_sptbr.ppn := wdata(ppnBits-1,0) }
 | 
			
		||||
      when (decoded_addr(CSRs.sepc))     { reg_sepc := ~(~wdata | (coreInstBytes-1)) }
 | 
			
		||||
      when (decoded_addr(CSRs.sepc))     { reg_sepc := formEPC(wdata) }
 | 
			
		||||
      when (decoded_addr(CSRs.stvec))    { reg_stvec := wdata >> 2 << 2 }
 | 
			
		||||
      when (decoded_addr(CSRs.scause))   { reg_scause := wdata & UInt((BigInt(1) << (xLen-1)) + 31) /* only implement 5 LSBs and MSB */ }
 | 
			
		||||
      when (decoded_addr(CSRs.sbadaddr)) { reg_sbadaddr := wdata(vaddrBitsExtended-1,0) }
 | 
			
		||||
@@ -645,4 +656,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
 | 
			
		||||
      when (decoded_addr(lo)) { ctr := wdata }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  def formEPC(x: UInt) = ~(~x | Cat(!reg_misa('c'-'a'), UInt(1)))
 | 
			
		||||
  def isaStringToMask(s: String) = s.map(x => 1 << (x - 'A')).reduce(_|_)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@ class IntCtrlSigs extends Bundle {
 | 
			
		||||
  val fence_i = Bool()
 | 
			
		||||
  val fence = Bool()
 | 
			
		||||
  val amo = Bool()
 | 
			
		||||
  val dp = Bool()
 | 
			
		||||
 | 
			
		||||
  def default: List[BitPat] =
 | 
			
		||||
                //           jal                                                                 renf1             fence.i
 | 
			
		||||
@@ -50,14 +51,14 @@ class IntCtrlSigs extends Bundle {
 | 
			
		||||
                //   | | | br| | | | s_alu2  |       imm    dw     alu       | mem_cmd   mem_type| | | | div       | 
 | 
			
		||||
                //   | | | | | | | | |       |       |      |      |         | |           |     | | | | | wxd     | fence
 | 
			
		||||
                //   | | | | | | | | |       |       |      |      |         | |           |     | | | | | | csr   | | amo
 | 
			
		||||
                //   | | | | | | | | |       |       |      |      |         | |           |     | | | | | | |     | | |
 | 
			
		||||
                List(N,X,X,X,X,X,X,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, X,X,X,X,X,X,CSR.X,X,X,X)
 | 
			
		||||
                //   | | | | | | | | |       |       |      |      |         | |           |     | | | | | | |     | | | dp
 | 
			
		||||
                List(N,X,X,X,X,X,X,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, X,X,X,X,X,X,CSR.X,X,X,X,X)
 | 
			
		||||
 | 
			
		||||
  def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = {
 | 
			
		||||
    val decoder = DecodeLogic(inst, default, table)
 | 
			
		||||
    val sigs = Seq(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, sel_alu2,
 | 
			
		||||
                   sel_alu1, sel_imm, alu_dw, alu_fn, mem, mem_cmd, mem_type,
 | 
			
		||||
                   rfs1, rfs2, rfs3, wfd, div, wxd, csr, fence_i, fence, amo)
 | 
			
		||||
                   rfs1, rfs2, rfs3, wfd, div, wxd, csr, fence_i, fence, amo, dp)
 | 
			
		||||
    sigs zip decoder map {case(s,d) => s := d}
 | 
			
		||||
    this
 | 
			
		||||
  }
 | 
			
		||||
@@ -66,259 +67,259 @@ class IntCtrlSigs extends Bundle {
 | 
			
		||||
class IDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    BNE->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SNE,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BEQ->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SEQ,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BLT->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BLTU->      List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BGE->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SGE,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BGEU->      List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SGEU,  N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    BNE->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SNE,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    BEQ->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SEQ,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    BLT->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    BLTU->      List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    BGE->       List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SGE,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    BGEU->      List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_X,  FN_SGEU,  N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    JAL->       List(Y,N,N,N,Y,N,N,N,A2_SIZE,A1_PC,  IMM_UJ,DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    JALR->      List(Y,N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    AUIPC->     List(Y,N,N,N,N,N,N,N,A2_IMM, A1_PC,  IMM_U, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    JAL->       List(Y,N,N,N,Y,N,N,N,A2_SIZE,A1_PC,  IMM_UJ,DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    JALR->      List(Y,N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    AUIPC->     List(Y,N,N,N,N,N,N,N,A2_IMM, A1_PC,  IMM_U, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    LB->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_B, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LH->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_H, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LW->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LBU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_BU,N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LHU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_HU,N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SB->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_B, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    SH->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_H, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    SW->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_W, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    LB->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_B, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    LH->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_H, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    LW->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    LBU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_BU,N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    LHU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_HU,N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SB->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_B, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    SH->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_H, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    SW->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_W, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    LUI->       List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    ADDI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLTI ->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLTIU->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    ANDI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_AND,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    ORI->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_OR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    XORI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_XOR,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLLI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRLI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRAI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    ADD->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SUB->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SUB,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLT->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLTU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    AND->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_AND,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    OR->        List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_OR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    XOR->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_XOR,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SL,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRA->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SRA,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LUI->       List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    ADDI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLTI ->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLTIU->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    ANDI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_AND,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    ORI->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_OR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    XORI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_XOR,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLLI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SL,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRLI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRAI->      List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_SRA,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    ADD->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SUB->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SUB,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLT->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLT,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLTU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SLTU,  N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    AND->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_AND,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    OR->        List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_OR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    XOR->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_XOR,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SL,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SR,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRA->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_SRA,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    FENCE->     List(Y,N,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,Y,N),
 | 
			
		||||
    FENCE_I->   List(Y,N,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     Y,M_FLUSH_ALL,MT_X, N,N,N,N,N,N,CSR.N,Y,N,N),
 | 
			
		||||
    FENCE->     List(Y,N,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,Y,N,N),
 | 
			
		||||
    FENCE_I->   List(Y,N,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     Y,M_FLUSH_ALL,MT_X, N,N,N,N,N,N,CSR.N,Y,N,N,N),
 | 
			
		||||
 | 
			
		||||
    SCALL->     List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
 | 
			
		||||
    SBREAK->    List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
 | 
			
		||||
    MRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
 | 
			
		||||
    WFI->       List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
 | 
			
		||||
    CSRRW->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.W,N,N,N),
 | 
			
		||||
    CSRRS->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.S,N,N,N),
 | 
			
		||||
    CSRRC->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.C,N,N,N),
 | 
			
		||||
    CSRRWI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.W,N,N,N),
 | 
			
		||||
    CSRRSI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.S,N,N,N),
 | 
			
		||||
    CSRRCI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.C,N,N,N))
 | 
			
		||||
    SCALL->     List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N),
 | 
			
		||||
    SBREAK->    List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N),
 | 
			
		||||
    MRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N),
 | 
			
		||||
    WFI->       List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N),
 | 
			
		||||
    CSRRW->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.W,N,N,N,N),
 | 
			
		||||
    CSRRS->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.S,N,N,N,N),
 | 
			
		||||
    CSRRC->     List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.C,N,N,N,N),
 | 
			
		||||
    CSRRWI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.W,N,N,N,N),
 | 
			
		||||
    CSRRSI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.S,N,N,N,N),
 | 
			
		||||
    CSRRCI->    List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.C,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    SFENCE_VM-> List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N),
 | 
			
		||||
    SRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N))
 | 
			
		||||
    SFENCE_VM-> List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N),
 | 
			
		||||
    SRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DebugDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    DRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N))
 | 
			
		||||
    DRET->      List(Y,N,N,N,N,N,N,X,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,N,N,N,CSR.I,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class I64Decode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    LD->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    LWU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_WU,N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SD->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_D, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    LD->        List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    LWU->       List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_WU,N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SD->        List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_D, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    ADDIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_ADD,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLLIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SL,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRLIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SR,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRAIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SRA,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    ADDW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_ADD,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SUBW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SUB,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SLLW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SL,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRLW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SR,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    SRAW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SRA,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N))
 | 
			
		||||
    ADDIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_ADD,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLLIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SL,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRLIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SR,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRAIW->     List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,FN_SRA,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    ADDW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_ADD,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SUBW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SUB,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SLLW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SL,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRLW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SR,     N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    SRAW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,FN_SRA,    N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class MDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    MUL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MUL,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    MULH->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULH,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    MULHU->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHU, N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    MULHSU->    List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHSU,N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    MUL->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MUL,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    MULH->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULH,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    MULHU->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHU, N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    MULHSU->    List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_MULHSU,N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    DIV->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIV,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    DIVU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIVU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    REM->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REM,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    REMU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REMU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N))
 | 
			
		||||
    DIV->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIV,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    DIVU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_DIVU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    REM->       List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REM,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    REMU->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,FN_REMU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class M64Decode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    MULW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_MUL,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    MULW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_MUL,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
 | 
			
		||||
    DIVW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIV,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    DIVUW->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIVU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    REMW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REM,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N),
 | 
			
		||||
    REMUW->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REMU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N))
 | 
			
		||||
    DIVW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIV,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    DIVUW->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_DIVU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    REMW->      List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REM,   N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    REMUW->     List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, FN_REMU,  N,M_X,        MT_X, N,N,N,N,Y,Y,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ADecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    AMOADD_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_ADD,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOXOR_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_XOR,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_SWAP,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOAND_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_AND,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOOR_W->   List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_OR,    MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMIN_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MIN,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MINU,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMAX_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAX,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAXU,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOADD_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_ADD,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOXOR_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_XOR,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_SWAP,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOAND_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_AND,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOOR_W->   List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_OR,    MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMIN_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MIN,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MINU,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMAX_W->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAX,   MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAXU,  MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
 | 
			
		||||
    LR_W->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XLR,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    SC_W->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XSC,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y))
 | 
			
		||||
    LR_W->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XLR,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    SC_W->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XSC,      MT_W, N,N,N,N,N,Y,CSR.N,N,N,Y,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class A64Decode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    AMOADD_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_ADD,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_SWAP,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOXOR_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_XOR,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOAND_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_AND,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOOR_D->   List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_OR,    MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMIN_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MIN,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MINU,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMAX_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAX,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAXU,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    AMOADD_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_ADD,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_SWAP,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOXOR_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_XOR,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOAND_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_AND,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOOR_D->   List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_OR,    MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMIN_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MIN,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MINU,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMAX_D->  List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAX,   MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XA_MAXU,  MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
 | 
			
		||||
    LR_D->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XLR,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y),
 | 
			
		||||
    SC_D->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XSC,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y))
 | 
			
		||||
    LR_D->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XLR,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N),
 | 
			
		||||
    SC_D->      List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   Y,M_XSC,      MT_D, N,N,N,N,N,Y,CSR.N,N,N,Y,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class FDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    FSGNJ_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSGNJX_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSGNJN_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMIN_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMAX_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FADD_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSUB_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMUL_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMADD_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMSUB_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FNMADD_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FNMSUB_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCLASS_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FMV_X_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_W_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FEQ_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FLT_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FLE_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FMV_S_X->   List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_S_W->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FLW->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_W, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSW->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_W, N,Y,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FDIV_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSQRT_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N))
 | 
			
		||||
    FSGNJ_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FSGNJX_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FSGNJN_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FMIN_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FMAX_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FADD_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FSUB_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FMUL_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FMADD_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FMSUB_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FNMADD_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FNMSUB_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FCLASS_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FMV_X_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_W_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FEQ_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FLT_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FLE_S->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FMV_S_X->   List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_S_W->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FLW->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_W, N,N,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FSW->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_W, N,Y,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FDIV_S->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FSQRT_S->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    FCVT_S_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_D_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSGNJ_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSGNJX_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSGNJN_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMIN_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMAX_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FADD_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSUB_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMUL_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMADD_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FMSUB_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FNMADD_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FNMSUB_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCLASS_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_W_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FEQ_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FLT_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FLE_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_D_W->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FLD->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_D, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSD->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_D, N,Y,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FDIV_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FSQRT_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N))
 | 
			
		||||
    FCVT_S_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_D_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSGNJ_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSGNJX_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSGNJN_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMIN_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMAX_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FADD_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSUB_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMUL_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMADD_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMSUB_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FNMADD_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FNMSUB_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,Y,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCLASS_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_W_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FEQ_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FLT_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FLE_D->     List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_D_W->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FLD->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD,   Y,M_XRD,      MT_D, N,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSD->       List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,FN_ADD,   Y,M_XWR,      MT_D, N,Y,N,N,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FDIV_D->    List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FSQRT_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,Y,N,Y,N,N,CSR.N,N,N,N,Y))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class F64Decode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    FCVT_L_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_S_L->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N))
 | 
			
		||||
    FCVT_L_S->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_S_L->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class D64Decode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    FMV_X_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_L_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    FMV_D_X->   List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_D_L->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N),
 | 
			
		||||
    FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N))
 | 
			
		||||
    FMV_X_D->   List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_L_D->  List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,A2_X,   A1_X,   IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, Y,N,N,N,N,Y,CSR.N,N,N,N,Y),
 | 
			
		||||
    FMV_D_X->   List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_D_L->  List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,Y),
 | 
			
		||||
    FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X,   A1_RS1, IMM_X, DW_X,  FN_X,     N,M_X,        MT_X, N,N,N,Y,N,N,CSR.N,N,N,N,Y))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class RoCCDecode(implicit val p: Parameters) extends DecodeConstants
 | 
			
		||||
{
 | 
			
		||||
  val table: Array[(BitPat, List[BitPat])] = Array(
 | 
			
		||||
    CUSTOM0->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM0_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM0_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N))
 | 
			
		||||
    CUSTOM0->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM0_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM0_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3->           List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3_RS1->       List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3_RS1_RS2->   List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,N,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD->        List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD_RS1->    List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N),
 | 
			
		||||
    CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,FN_ADD,   N,M_X,        MT_X, N,N,N,N,N,Y,CSR.N,N,N,N,N))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ case object UseAtomics extends Field[Boolean]
 | 
			
		||||
case object UseCompressed extends Field[Boolean]
 | 
			
		||||
case object FastLoadWord extends Field[Boolean]
 | 
			
		||||
case object FastLoadByte extends Field[Boolean]
 | 
			
		||||
case object FastJAL extends Field[Boolean]
 | 
			
		||||
case object CoreInstBits extends Field[Int]
 | 
			
		||||
case object NCustomMRWCSRs extends Field[Int]
 | 
			
		||||
case object MtvecWritable extends Field[Boolean]
 | 
			
		||||
@@ -47,6 +48,7 @@ trait HasCoreParameters extends HasAddrMapParameters {
 | 
			
		||||
  val usingRoCC = !p(BuildRoCC).isEmpty
 | 
			
		||||
  val fastLoadWord = p(FastLoadWord)
 | 
			
		||||
  val fastLoadByte = p(FastLoadByte)
 | 
			
		||||
  val fastJAL = p(FastJAL)
 | 
			
		||||
  val nBreakpoints = p(NBreakpoints)
 | 
			
		||||
  val nPerfCounters = p(NPerfCounters)
 | 
			
		||||
  val nPerfEvents = p(NPerfEvents)
 | 
			
		||||
@@ -205,8 +207,9 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
  val wb_reg_rs2 = Reg(Bits())
 | 
			
		||||
  val take_pc_wb = Wire(Bool())
 | 
			
		||||
 | 
			
		||||
  val take_pc_id = Wire(Bool())
 | 
			
		||||
  val take_pc_mem_wb = take_pc_wb || take_pc_mem
 | 
			
		||||
  val take_pc = take_pc_mem_wb
 | 
			
		||||
  val take_pc = take_pc_mem_wb || take_pc_id
 | 
			
		||||
 | 
			
		||||
  // decode stage
 | 
			
		||||
  val ibuf = Module(new IBuf)
 | 
			
		||||
@@ -228,6 +231,8 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
  val rf = new RegFile(31, xLen)
 | 
			
		||||
  val id_rs = id_raddr.map(rf.read _)
 | 
			
		||||
  val ctrl_killd = Wire(Bool())
 | 
			
		||||
  val id_npc = (ibuf.io.pc.asSInt + ImmGen(IMM_UJ, id_inst(0))).asUInt
 | 
			
		||||
  take_pc_id := Bool(fastJAL) && !ctrl_killd && id_ctrl.jal
 | 
			
		||||
 | 
			
		||||
  val csr = Module(new CSRFile)
 | 
			
		||||
  val id_csr_en = id_ctrl.csr =/= CSR.N
 | 
			
		||||
@@ -241,8 +246,12 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
  val id_csr_flush = id_system_insn || (id_csr_en && !id_csr_ren && !DecodeLogic(id_csr_addr, safe_csrs.map(UInt(_)), (legal_csrs -- safe_csrs).toList.map(UInt(_))))
 | 
			
		||||
 | 
			
		||||
  val id_illegal_insn = !id_ctrl.legal ||
 | 
			
		||||
    id_ctrl.fp && !csr.io.status.fs.orR ||
 | 
			
		||||
    id_ctrl.rocc && !csr.io.status.xs.orR
 | 
			
		||||
    id_ctrl.div && !csr.io.status.isa('m'-'a') ||
 | 
			
		||||
    id_ctrl.amo && !csr.io.status.isa('a'-'a') ||
 | 
			
		||||
    id_ctrl.fp && !(csr.io.status.fs.orR && csr.io.status.isa('f'-'a')) ||
 | 
			
		||||
    id_ctrl.dp && !csr.io.status.isa('d'-'a') ||
 | 
			
		||||
    ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') ||
 | 
			
		||||
    id_ctrl.rocc && !(csr.io.status.xs.orR && csr.io.status.isa('x'-'a'))
 | 
			
		||||
  // stall decode for fences (now, for AMO.aq; later, for AMO.rl and FENCE)
 | 
			
		||||
  val id_amo_aq = id_inst(0)(26)
 | 
			
		||||
  val id_amo_rl = id_inst(0)(25)
 | 
			
		||||
@@ -381,14 +390,14 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
  val mem_br_taken = mem_reg_wdata(0)
 | 
			
		||||
  val mem_br_target = mem_reg_pc.asSInt +
 | 
			
		||||
    Mux(mem_ctrl.branch && mem_br_taken, ImmGen(IMM_SB, mem_reg_inst),
 | 
			
		||||
    Mux(mem_ctrl.jal, ImmGen(IMM_UJ, mem_reg_inst),
 | 
			
		||||
    Mux(Bool(!fastJAL) && mem_ctrl.jal, ImmGen(IMM_UJ, mem_reg_inst),
 | 
			
		||||
    Mux(mem_reg_rvc, SInt(2), SInt(4))))
 | 
			
		||||
  val mem_npc = (Mux(mem_ctrl.jalr, encodeVirtualAddress(mem_reg_wdata, mem_reg_wdata).asSInt, mem_br_target) & SInt(-2)).asUInt
 | 
			
		||||
  val mem_wrong_npc = Mux(ex_pc_valid, mem_npc =/= ex_reg_pc, Mux(ibuf.io.inst(0).valid, mem_npc =/= ibuf.io.pc, Bool(true)))
 | 
			
		||||
  val mem_npc_misaligned = if (usingCompressed) Bool(false) else mem_npc(1)
 | 
			
		||||
  val mem_npc_misaligned = !csr.io.status.isa('c'-'a') && mem_npc(1)
 | 
			
		||||
  val mem_int_wdata = Mux(!mem_reg_xcpt && (mem_ctrl.jalr ^ mem_npc_misaligned), mem_br_target, mem_reg_wdata.asSInt).asUInt
 | 
			
		||||
  val mem_cfi = mem_ctrl.branch || mem_ctrl.jalr || mem_ctrl.jal
 | 
			
		||||
  val mem_cfi_taken = (mem_ctrl.branch && mem_br_taken) || mem_ctrl.jalr || mem_ctrl.jal
 | 
			
		||||
  val mem_cfi_taken = (mem_ctrl.branch && mem_br_taken) || mem_ctrl.jalr || (Bool(!fastJAL) && mem_ctrl.jal)
 | 
			
		||||
  val mem_misprediction =
 | 
			
		||||
    if (p(BtbKey).nEntries == 0) mem_cfi_taken
 | 
			
		||||
    else mem_wrong_npc
 | 
			
		||||
@@ -572,20 +581,21 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
    id_ctrl.rocc && rocc_blocked || // reduce activity while RoCC is busy
 | 
			
		||||
    id_do_fence ||
 | 
			
		||||
    csr.io.csr_stall
 | 
			
		||||
  ctrl_killd := !ibuf.io.inst(0).valid || ibuf.io.inst(0).bits.replay || take_pc || ctrl_stalld || csr.io.interrupt
 | 
			
		||||
  ctrl_killd := !ibuf.io.inst(0).valid || ibuf.io.inst(0).bits.replay || take_pc_mem_wb || ctrl_stalld || csr.io.interrupt
 | 
			
		||||
 | 
			
		||||
  io.imem.req.valid := take_pc
 | 
			
		||||
  io.imem.req.bits.speculative := !take_pc_wb
 | 
			
		||||
  io.imem.req.bits.pc :=
 | 
			
		||||
    Mux(wb_xcpt || csr.io.eret, csr.io.evec, // exception or [m|s]ret
 | 
			
		||||
    Mux(replay_wb,              wb_reg_pc,   // replay
 | 
			
		||||
                                mem_npc))    // mispredicted branch
 | 
			
		||||
    Mux(wb_xcpt || csr.io.eret,        csr.io.evec, // exception or [m|s]ret
 | 
			
		||||
    Mux(replay_wb,                     wb_reg_pc,   // replay
 | 
			
		||||
    Mux(take_pc_mem || Bool(!fastJAL), mem_npc,     // branch misprediction
 | 
			
		||||
                                       id_npc)))    // JAL
 | 
			
		||||
  io.imem.flush_icache := wb_reg_valid && wb_ctrl.fence_i && !io.dmem.s2_nack
 | 
			
		||||
  io.imem.flush_tlb := csr.io.fatc
 | 
			
		||||
 | 
			
		||||
  ibuf.io.inst(0).ready := !ctrl_stalld || csr.io.interrupt
 | 
			
		||||
 | 
			
		||||
  io.imem.btb_update.valid := (mem_reg_replay && mem_reg_btb_hit) || (mem_reg_valid && !take_pc_wb && (mem_cfi_taken || !mem_cfi) && mem_wrong_npc)
 | 
			
		||||
  io.imem.btb_update.valid := (mem_reg_replay && mem_reg_btb_hit) || (mem_reg_valid && !take_pc_wb && (((mem_cfi_taken || !mem_cfi) && mem_wrong_npc) || (Bool(fastJAL) && mem_ctrl.jal && !mem_reg_btb_hit)))
 | 
			
		||||
  io.imem.btb_update.bits.isValid := !mem_reg_replay && mem_cfi
 | 
			
		||||
  io.imem.btb_update.bits.isJump := mem_ctrl.jal || mem_ctrl.jalr
 | 
			
		||||
  io.imem.btb_update.bits.isReturn := mem_ctrl.jalr && mem_reg_inst(19,15) === BitPat("b00??1")
 | 
			
		||||
@@ -628,7 +638,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) {
 | 
			
		||||
  io.dmem.invalidate_lr := wb_xcpt
 | 
			
		||||
  io.dmem.s1_data := Mux(mem_ctrl.fp, io.fpu.store_data, mem_reg_rs2)
 | 
			
		||||
  io.dmem.s1_kill := killm_common || mem_breakpoint
 | 
			
		||||
  when (mem_xcpt && !io.dmem.s1_kill) {
 | 
			
		||||
  when (mem_ctrl.mem && mem_xcpt && !io.dmem.s1_kill) {
 | 
			
		||||
    assert(io.dmem.xcpt.asUInt.orR) // make sure s1_kill is exhaustive
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import rocket._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import uncore.agents._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.tilelink2.{LazyModule}
 | 
			
		||||
import uncore.devices._
 | 
			
		||||
import uncore.converters._
 | 
			
		||||
import coreplex._
 | 
			
		||||
@@ -17,157 +18,67 @@ import scala.collection.immutable.HashMap
 | 
			
		||||
import DefaultTestSuites._
 | 
			
		||||
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
 | 
			
		||||
 | 
			
		||||
class BasePlatformConfig extends Config (
 | 
			
		||||
  topDefinitions = { (pname,site,here) => 
 | 
			
		||||
    type PF = PartialFunction[Any,Any]
 | 
			
		||||
    def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
 | 
			
		||||
    lazy val internalIOAddrMap: AddrMap = {
 | 
			
		||||
      val entries = collection.mutable.ArrayBuffer[AddrMapEntry]()
 | 
			
		||||
      entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX)))
 | 
			
		||||
      entries += AddrMapEntry("bootrom", MemSize(4096, MemAttr(AddrMapProt.RX)))
 | 
			
		||||
      entries += AddrMapEntry("plic", MemRange(0x40000000, 0x4000000, MemAttr(AddrMapProt.RW)))
 | 
			
		||||
      entries += AddrMapEntry("prci", MemSize(0x4000000, MemAttr(AddrMapProt.RW)))
 | 
			
		||||
      if (site(DataScratchpadSize) > 0) { // TODO heterogeneous tiles
 | 
			
		||||
        require(site(NTiles) == 1) // TODO relax this
 | 
			
		||||
        require(site(NMemoryChannels) == 0) // TODO allow both scratchpad & DRAM
 | 
			
		||||
        entries += AddrMapEntry("dmem0", MemRange(0x80000000L, site[Int](DataScratchpadSize), MemAttr(AddrMapProt.RWX)))
 | 
			
		||||
      }
 | 
			
		||||
      new AddrMap(entries)
 | 
			
		||||
    }
 | 
			
		||||
    lazy val externalAddrMap = new AddrMap(
 | 
			
		||||
      site(ExtraDevices).addrMapEntries ++ site(ExtMMIOPorts),
 | 
			
		||||
      start = BigInt("50000000", 16),
 | 
			
		||||
      collapse = true)
 | 
			
		||||
    lazy val globalAddrMap = {
 | 
			
		||||
      val memBase = 0x80000000L
 | 
			
		||||
      val memSize = site(ExtMemSize)
 | 
			
		||||
 | 
			
		||||
      val intern = AddrMapEntry("int", internalIOAddrMap)
 | 
			
		||||
      val extern = AddrMapEntry("ext", externalAddrMap)
 | 
			
		||||
      val io = AddrMapEntry("io", AddrMap((intern +: site(ExportMMIOPort).option(extern).toSeq):_*))
 | 
			
		||||
      val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true)))
 | 
			
		||||
      val addrMap = AddrMap((io +: (site(NMemoryChannels) > 0).option(mem).toSeq):_*)
 | 
			
		||||
 | 
			
		||||
      Dump("MEM_BASE", memBase)
 | 
			
		||||
      addrMap
 | 
			
		||||
    }
 | 
			
		||||
    def makeConfigString() = {
 | 
			
		||||
      val addrMap = globalAddrMap
 | 
			
		||||
      val plicAddr = addrMap("io:int:plic").start
 | 
			
		||||
      val prciAddr = addrMap("io:int:prci").start
 | 
			
		||||
      val plicInfo = site(PLICKey)
 | 
			
		||||
      val xLen = site(XLen)
 | 
			
		||||
      val res = new StringBuilder
 | 
			
		||||
      res append  "plic {\n"
 | 
			
		||||
      res append s"  priority 0x${plicAddr.toString(16)};\n"
 | 
			
		||||
      res append s"  pending 0x${(plicAddr + plicInfo.pendingBase).toString(16)};\n"
 | 
			
		||||
      res append s"  ndevs ${plicInfo.nDevices};\n"
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      res append  "rtc {\n"
 | 
			
		||||
      res append s"  addr 0x${(prciAddr + PRCI.time).toString(16)};\n"
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      if (addrMap contains "mem") {
 | 
			
		||||
        res append  "ram {\n"
 | 
			
		||||
        res append  "  0 {\n"
 | 
			
		||||
        res append s"    addr 0x${addrMap("mem").start.toString(16)};\n"
 | 
			
		||||
        res append s"    size 0x${addrMap("mem").size.toString(16)};\n"
 | 
			
		||||
        res append  "  };\n"
 | 
			
		||||
        res append  "};\n"
 | 
			
		||||
      }
 | 
			
		||||
      res append  "core {\n"
 | 
			
		||||
      for (i <- 0 until site(NTiles)) { // TODO heterogeneous tiles
 | 
			
		||||
        val isa = {
 | 
			
		||||
          val m = if (site(MulDivKey).nonEmpty) "m" else ""
 | 
			
		||||
          val a = if (site(UseAtomics)) "a" else ""
 | 
			
		||||
          val f = if (site(FPUKey).nonEmpty) "f" else ""
 | 
			
		||||
          val d = if (site(FPUKey).nonEmpty && site(XLen) > 32) "d" else ""
 | 
			
		||||
          val s = if (site(UseVM)) "s" else ""
 | 
			
		||||
          s"rv${site(XLen)}i$m$a$f$d$s"
 | 
			
		||||
class BasePlatformConfig extends Config(
 | 
			
		||||
  topDefinitions = {
 | 
			
		||||
    val configString = new GlobalVariable[String]
 | 
			
		||||
    val globalAddrMap = new GlobalVariable[AddrMap]
 | 
			
		||||
    val nCoreplexExtClients = new GlobalVariable[Int]
 | 
			
		||||
    (pname,site,here) =>  {
 | 
			
		||||
      type PF = PartialFunction[Any,Any]
 | 
			
		||||
      def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
 | 
			
		||||
      lazy val innerDataBits = 64
 | 
			
		||||
      lazy val innerDataBeats = (8 * site(CacheBlockBytes)) / innerDataBits
 | 
			
		||||
      pname match {
 | 
			
		||||
        //Memory Parameters
 | 
			
		||||
        case MIFTagBits => Dump("MIF_TAG_BITS", 5)
 | 
			
		||||
        case MIFDataBits => Dump("MIF_DATA_BITS", 64)
 | 
			
		||||
        case MIFAddrBits => Dump("MIF_ADDR_BITS",
 | 
			
		||||
                                 site(PAddrBits) - site(CacheBlockOffsetBits))
 | 
			
		||||
        case MIFDataBeats => site(CacheBlockBytes) * 8 / site(MIFDataBits)
 | 
			
		||||
        case NastiKey => {
 | 
			
		||||
          Dump("MEM_STRB_BITS", site(MIFDataBits) / 8)
 | 
			
		||||
          NastiParameters(
 | 
			
		||||
            dataBits = Dump("MEM_DATA_BITS", site(MIFDataBits)),
 | 
			
		||||
            addrBits = Dump("MEM_ADDR_BITS", site(PAddrBits)),
 | 
			
		||||
            idBits = Dump("MEM_ID_BITS", site(MIFTagBits)))
 | 
			
		||||
        }
 | 
			
		||||
        res append s"  $i {\n"
 | 
			
		||||
        res append  "    0 {\n"
 | 
			
		||||
        res append s"      isa $isa;\n"
 | 
			
		||||
        res append s"      timecmp 0x${(prciAddr + PRCI.timecmp(i)).toString(16)};\n"
 | 
			
		||||
        res append s"      ipi 0x${(prciAddr + PRCI.msip(i)).toString(16)};\n"
 | 
			
		||||
        res append s"      plic {\n"
 | 
			
		||||
        res append s"        m {\n"
 | 
			
		||||
        res append s"         ie 0x${(plicAddr + plicInfo.enableAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
        res append s"         thresh 0x${(plicAddr + plicInfo.threshAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
        res append s"         claim 0x${(plicAddr + plicInfo.claimAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
        res append s"        };\n"
 | 
			
		||||
        if (site(UseVM)) {
 | 
			
		||||
          res append s"        s {\n"
 | 
			
		||||
          res append s"         ie 0x${(plicAddr + plicInfo.enableAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
          res append s"         thresh 0x${(plicAddr + plicInfo.threshAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
          res append s"         claim 0x${(plicAddr + plicInfo.claimAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
          res append s"        };\n"
 | 
			
		||||
        }
 | 
			
		||||
        res append  "      };\n"
 | 
			
		||||
        res append  "    };\n"
 | 
			
		||||
        res append  "  };\n"
 | 
			
		||||
        case BuildCoreplex =>
 | 
			
		||||
          (p: Parameters, c: CoreplexConfig) => Module(new DefaultCoreplex(p, c))
 | 
			
		||||
        case NExtTopInterrupts => 2
 | 
			
		||||
        // Note that PLIC asserts that this is > 0.
 | 
			
		||||
        case AsyncDebugBus => false
 | 
			
		||||
        case IncludeJtagDTM => false
 | 
			
		||||
        case AsyncMMIOChannels => false
 | 
			
		||||
        case ExtMMIOPorts => Nil
 | 
			
		||||
        case NExtMMIOAXIChannels => 0
 | 
			
		||||
        case NExtMMIOAHBChannels => 0
 | 
			
		||||
        case NExtMMIOTLChannels  => 0
 | 
			
		||||
        case AsyncBusChannels => false
 | 
			
		||||
        case NExtBusAXIChannels => 0
 | 
			
		||||
        case NCoreplexExtClients => nCoreplexExtClients
 | 
			
		||||
        case HastiId => "Ext"
 | 
			
		||||
        case HastiKey("TL") =>
 | 
			
		||||
          HastiParameters(
 | 
			
		||||
            addrBits = site(PAddrBits),
 | 
			
		||||
            dataBits = site(TLKey(site(TLId))).dataBits / site(TLKey(site(TLId))).dataBeats)
 | 
			
		||||
        case HastiKey("Ext") =>
 | 
			
		||||
          HastiParameters(
 | 
			
		||||
            addrBits = site(PAddrBits),
 | 
			
		||||
            dataBits = site(XLen))
 | 
			
		||||
        case AsyncMemChannels => false
 | 
			
		||||
        case NMemoryChannels => Dump("N_MEM_CHANNELS", 1)
 | 
			
		||||
        case TMemoryChannels => BusType.AXI
 | 
			
		||||
        case ExtMemSize => Dump("MEM_SIZE", 0x10000000L)
 | 
			
		||||
        case ConfigString => configString
 | 
			
		||||
        case GlobalAddrMap => globalAddrMap
 | 
			
		||||
        case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock
 | 
			
		||||
        case BuildExampleTop =>
 | 
			
		||||
          (p: Parameters) => uncore.tilelink2.LazyModule(new ExampleTop(p))
 | 
			
		||||
        case SimMemLatency => 0
 | 
			
		||||
        case _ => throw new CDEMatchError
 | 
			
		||||
      }
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      res append (site(ExtraDevices).makeConfigString(addrMap))
 | 
			
		||||
      res append '\u0000'
 | 
			
		||||
      res.toString.getBytes
 | 
			
		||||
    }
 | 
			
		||||
    lazy val innerDataBits = 64
 | 
			
		||||
    lazy val innerDataBeats = (8 * site(CacheBlockBytes)) / innerDataBits
 | 
			
		||||
    pname match {
 | 
			
		||||
      //Memory Parameters
 | 
			
		||||
      case MIFTagBits => Dump("MIF_TAG_BITS", 5)
 | 
			
		||||
      case MIFDataBits => Dump("MIF_DATA_BITS", 64)
 | 
			
		||||
      case MIFAddrBits => Dump("MIF_ADDR_BITS",
 | 
			
		||||
                               site(PAddrBits) - site(CacheBlockOffsetBits))
 | 
			
		||||
      case MIFDataBeats => site(CacheBlockBytes) * 8 / site(MIFDataBits)
 | 
			
		||||
      case NastiKey => {
 | 
			
		||||
        Dump("MEM_STRB_BITS", site(MIFDataBits) / 8)
 | 
			
		||||
        NastiParameters(
 | 
			
		||||
          dataBits = Dump("MEM_DATA_BITS", site(MIFDataBits)),
 | 
			
		||||
          addrBits = Dump("MEM_ADDR_BITS", site(PAddrBits)),
 | 
			
		||||
          idBits = Dump("MEM_ID_BITS", site(MIFTagBits)))
 | 
			
		||||
      }
 | 
			
		||||
      case BuildCoreplex => (p: Parameters) => Module(new DefaultCoreplex(p))
 | 
			
		||||
      case NExtTopInterrupts => 2
 | 
			
		||||
      case NExtPeripheryInterrupts => site(ExtraDevices).nInterrupts
 | 
			
		||||
      // Note that PLIC asserts that this is > 0.
 | 
			
		||||
      case NExtInterrupts => site(NExtTopInterrupts) + site(NExtPeripheryInterrupts)
 | 
			
		||||
      case AsyncDebugBus => false
 | 
			
		||||
      case IncludeJtagDTM => false
 | 
			
		||||
      case AsyncMMIOChannels => false
 | 
			
		||||
      case ExtraDevices => new EmptyDeviceBlock
 | 
			
		||||
      case ExtraTopPorts => (p: Parameters) => new Bundle
 | 
			
		||||
      case ExtMMIOPorts => Nil
 | 
			
		||||
      case NExtMMIOAXIChannels => 0
 | 
			
		||||
      case NExtMMIOAHBChannels => 0
 | 
			
		||||
      case NExtMMIOTLChannels  => 0
 | 
			
		||||
      case ExportMMIOPort => !externalAddrMap.isEmpty
 | 
			
		||||
      case AsyncBusChannels => false
 | 
			
		||||
      case NExtBusAXIChannels => 0
 | 
			
		||||
      case NExternalClients => (if (site(NExtBusAXIChannels) > 0) 1 else 0) +
 | 
			
		||||
                                site(ExtraDevices).nClientPorts
 | 
			
		||||
      case ConnectExtraPorts =>
 | 
			
		||||
        (out: Bundle, in: Bundle, p: Parameters) => out <> in
 | 
			
		||||
 | 
			
		||||
      case HastiId => "Ext"
 | 
			
		||||
      case HastiKey("TL") =>
 | 
			
		||||
        HastiParameters(
 | 
			
		||||
          addrBits = site(PAddrBits),
 | 
			
		||||
          dataBits = site(TLKey(site(TLId))).dataBits / site(TLKey(site(TLId))).dataBeats)
 | 
			
		||||
      case HastiKey("Ext") =>
 | 
			
		||||
        HastiParameters(
 | 
			
		||||
          addrBits = site(PAddrBits),
 | 
			
		||||
          dataBits = site(XLen))
 | 
			
		||||
      case AsyncMemChannels => false
 | 
			
		||||
      case NMemoryChannels => Dump("N_MEM_CHANNELS", 1)
 | 
			
		||||
      case TMemoryChannels => BusType.AXI
 | 
			
		||||
      case ExtMemSize => Dump("MEM_SIZE", 0x10000000L)
 | 
			
		||||
      case ConfigString => makeConfigString()
 | 
			
		||||
      case GlobalAddrMap => globalAddrMap
 | 
			
		||||
      case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock
 | 
			
		||||
      case RTCTick => (p: Parameters, t_io: Bundle, p_io:Bundle) => Counter(p(RTCPeriod)).inc() 
 | 
			
		||||
      case _ => throw new CDEMatchError
 | 
			
		||||
  }})
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
class BaseConfig extends Config(new BaseCoreplexConfig ++ new BasePlatformConfig)
 | 
			
		||||
class DefaultConfig extends Config(new WithBlockingL1 ++ new BaseConfig)
 | 
			
		||||
@@ -179,7 +90,6 @@ class DefaultBufferlessConfig extends Config(
 | 
			
		||||
class FPGAConfig extends Config (
 | 
			
		||||
  (pname,site,here) => pname match {
 | 
			
		||||
    case NAcquireTransactors => 4
 | 
			
		||||
    case ExportGroundTestStatus => true
 | 
			
		||||
    case _ => throw new CDEMatchError
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
@@ -270,35 +180,12 @@ class TinyConfig extends Config(
 | 
			
		||||
  new WithSmallCores ++ new WithRV32 ++
 | 
			
		||||
  new WithStatelessBridge ++ new BaseConfig)
 | 
			
		||||
 | 
			
		||||
class WithTestRAM extends Config(
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
    case ExtraDevices => {
 | 
			
		||||
      class TestRAMDevice extends DeviceBlock {
 | 
			
		||||
        val ramSize = 0x1000
 | 
			
		||||
        def nClientPorts = 0
 | 
			
		||||
        def addrMapEntries = Seq(
 | 
			
		||||
          AddrMapEntry("testram", MemSize(ramSize, MemAttr(AddrMapProt.RW))))
 | 
			
		||||
        def builder(
 | 
			
		||||
          mmioPorts: HashMap[String, ClientUncachedTileLinkIO],
 | 
			
		||||
          clientPorts: Seq[ClientUncachedTileLinkIO],
 | 
			
		||||
          interrupts: Seq[Bool],
 | 
			
		||||
          extra: Bundle, p: Parameters) {
 | 
			
		||||
          val testram = Module(new TileLinkTestRAM(ramSize)(p))
 | 
			
		||||
          testram.io <> mmioPorts("testram")
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      new TestRAMDevice
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
class WithAsyncDebug extends Config (
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
     case AsyncDebugBus => true
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class WithJtagDTM extends Config (
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
     case IncludeJtagDTM => true
 | 
			
		||||
 
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
package rocketchip
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import scala.collection.immutable.HashMap
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
 | 
			
		||||
case object ExtraTopPorts extends Field[Parameters => Bundle]
 | 
			
		||||
case object ExtraDevices extends Field[DeviceBlock]
 | 
			
		||||
 | 
			
		||||
abstract class DeviceBlock {
 | 
			
		||||
  /** How many client ports will the devices use */
 | 
			
		||||
  def nClientPorts: Int
 | 
			
		||||
  /** Address map entries for all of the devices */
 | 
			
		||||
  def addrMapEntries: Seq[AddrMapEntry]
 | 
			
		||||
  /**
 | 
			
		||||
   * The total number of interrupt signals coming 
 | 
			
		||||
   *  from all the devices                       */
 | 
			
		||||
  def nInterrupts : Int = 0
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The function that elaborates all the extra devices and connects them
 | 
			
		||||
   * to the TileLink ports and extra top-level ports.
 | 
			
		||||
   *
 | 
			
		||||
   * @param mmioPorts A hashmap for the mmio ports.
 | 
			
		||||
   *    Use the names specified in addrMapEntries to get
 | 
			
		||||
   *    the mmio port for each device.
 | 
			
		||||
   * @param clientPorts All the client ports available for the devices
 | 
			
		||||
   * @param interrupts External interrupts from Periphery to Coreplex 
 | 
			
		||||
   * @param extra The extra top-level IO bundle
 | 
			
		||||
   * @param p The CDE parameters for the devices
 | 
			
		||||
   */
 | 
			
		||||
  def builder(
 | 
			
		||||
    mmioPorts: HashMap[String, ClientUncachedTileLinkIO],
 | 
			
		||||
    clientPorts: Seq[ClientUncachedTileLinkIO],
 | 
			
		||||
    interrupts : Seq[Bool],
 | 
			
		||||
    extra: Bundle, p: Parameters): Unit
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create the config string entry for this device that goes into the
 | 
			
		||||
   * Boot ROM. You generally won't need to override this
 | 
			
		||||
   *
 | 
			
		||||
   * @param fullAddrMap The full global address map
 | 
			
		||||
   */
 | 
			
		||||
  def makeConfigString(fullAddrMap: AddrMap): String = {
 | 
			
		||||
    addrMapEntries.map { entry =>
 | 
			
		||||
      val region = fullAddrMap("io:ext:" + entry.name)
 | 
			
		||||
      s"${entry.name} {\n" +
 | 
			
		||||
      s"  addr 0x${region.start.toString(16)};\n" +
 | 
			
		||||
      s"  size 0x${region.size.toString(16)}; \n" +
 | 
			
		||||
       "}\n"
 | 
			
		||||
    }.mkString
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class EmptyDeviceBlock extends DeviceBlock {
 | 
			
		||||
  def nClientPorts = 0
 | 
			
		||||
  def addrMapEntries = Seq.empty
 | 
			
		||||
 | 
			
		||||
  def builder(
 | 
			
		||||
    mmioPorts: HashMap[String, ClientUncachedTileLinkIO],
 | 
			
		||||
    clientPorts: Seq[ClientUncachedTileLinkIO],
 | 
			
		||||
    interrupts : Seq[Bool], 
 | 
			
		||||
    extra: Bundle, p: Parameters) {}
 | 
			
		||||
}
 | 
			
		||||
@@ -82,5 +82,5 @@ object RocketChipGenerator extends Generator {
 | 
			
		||||
  writeOutputFile(td, s"$longName.prm", ParameterDump.getDump) // Parameters flagged with Dump()
 | 
			
		||||
  writeOutputFile(td, s"${names.configs}.knb", world.getKnobs) // Knobs for DSE
 | 
			
		||||
  writeOutputFile(td, s"${names.configs}.cst", world.getConstraints) // Constraints for DSE
 | 
			
		||||
  writeOutputFile(td, s"${names.configs}.cfg", params(ConfigString).toString) // String for software
 | 
			
		||||
  writeOutputFile(td, s"${names.configs}.cfg", params(ConfigString).get) // String for software
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										331
									
								
								src/main/scala/rocketchip/Periphery.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								src/main/scala/rocketchip/Periphery.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,331 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
package rocketchip
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.tilelink2.{LazyModule, LazyModuleImp}
 | 
			
		||||
import uncore.converters._
 | 
			
		||||
import uncore.devices._
 | 
			
		||||
import uncore.util._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import coreplex._
 | 
			
		||||
 | 
			
		||||
/** Options for memory bus interface */
 | 
			
		||||
object BusType {
 | 
			
		||||
  sealed trait EnumVal
 | 
			
		||||
  case object AXI extends EnumVal
 | 
			
		||||
  case object AHB extends EnumVal
 | 
			
		||||
  case object TL  extends EnumVal
 | 
			
		||||
  val busTypes = Seq(AXI, AHB, TL)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Memory channel controls */
 | 
			
		||||
case object TMemoryChannels extends Field[BusType.EnumVal]
 | 
			
		||||
/** External MMIO controls */
 | 
			
		||||
case object NExtMMIOAXIChannels extends Field[Int]
 | 
			
		||||
case object NExtMMIOAHBChannels extends Field[Int]
 | 
			
		||||
case object NExtMMIOTLChannels  extends Field[Int]
 | 
			
		||||
/** External Bus controls */
 | 
			
		||||
case object NExtBusAXIChannels extends Field[Int]
 | 
			
		||||
/** Async configurations */
 | 
			
		||||
case object AsyncBusChannels extends Field[Boolean]
 | 
			
		||||
case object AsyncDebugBus extends Field[Boolean]
 | 
			
		||||
case object AsyncMemChannels extends Field[Boolean]
 | 
			
		||||
case object AsyncMMIOChannels extends Field[Boolean]
 | 
			
		||||
/** External address map settings */
 | 
			
		||||
case object ExtMMIOPorts extends Field[Seq[AddrMapEntry]]
 | 
			
		||||
/** Specifies the size of external memory */
 | 
			
		||||
case object ExtMemSize extends Field[Long]
 | 
			
		||||
/** Specifies the number of external interrupts */
 | 
			
		||||
case object NExtTopInterrupts extends Field[Int]
 | 
			
		||||
/** Source of RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra  **/
 | 
			
		||||
case object RTCPeriod extends Field[Int]
 | 
			
		||||
 | 
			
		||||
object PeripheryUtils {
 | 
			
		||||
  def addQueueAXI(source: NastiIO)(implicit p: Parameters) = {
 | 
			
		||||
    val sink = Wire(new NastiIO)
 | 
			
		||||
    sink.ar  <> Queue(source.ar, 1)
 | 
			
		||||
    sink.aw  <> Queue(source.aw, 1)
 | 
			
		||||
    sink.w   <> Queue(source.w)
 | 
			
		||||
    source.r <> Queue(sink.r)
 | 
			
		||||
    source.b <> Queue(sink.b, 1)
 | 
			
		||||
    sink
 | 
			
		||||
  }
 | 
			
		||||
  def convertTLtoAXI(tl: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val bridge = Module(new NastiIOTileLinkIOConverter())
 | 
			
		||||
    bridge.io.tl <> tl
 | 
			
		||||
    addQueueAXI(bridge.io.nasti)
 | 
			
		||||
  }
 | 
			
		||||
  def convertTLtoAHB(tl: ClientUncachedTileLinkIO, atomics: Boolean)(implicit p: Parameters) = {
 | 
			
		||||
    val bridge = Module(new AHBBridge(atomics))
 | 
			
		||||
    bridge.io.tl <> tl
 | 
			
		||||
    bridge.io.ahb
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Utility trait for quick access to some relevant parameters */
 | 
			
		||||
trait HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  lazy val tMemChannels = p(TMemoryChannels)
 | 
			
		||||
  lazy val nMemChannels = p(NMemoryChannels)
 | 
			
		||||
  lazy val nMemAXIChannels = if (tMemChannels == BusType.AXI) nMemChannels else 0
 | 
			
		||||
  lazy val nMemAHBChannels = if (tMemChannels == BusType.AHB) nMemChannels else 0
 | 
			
		||||
  lazy val nMemTLChannels  = if (tMemChannels == BusType.TL)  nMemChannels else 0
 | 
			
		||||
  lazy val innerParams = p.alterPartial({ case TLId => "L1toL2" })
 | 
			
		||||
  lazy val innerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" })
 | 
			
		||||
  lazy val outermostParams = p.alterPartial({ case TLId => "Outermost" })
 | 
			
		||||
  lazy val outermostMMIOParams = p.alterPartial({ case TLId => "MMIO_Outermost" })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryDebug extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryDebugBundle {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT))
 | 
			
		||||
  val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT))
 | 
			
		||||
  val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip)
 | 
			
		||||
  val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryDebugModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryDebug
 | 
			
		||||
  val io: PeripheryDebugBundle
 | 
			
		||||
  val coreplex: Coreplex
 | 
			
		||||
 | 
			
		||||
  if (p(IncludeJtagDTM)) {
 | 
			
		||||
    // JtagDTMWithSync is a wrapper which
 | 
			
		||||
    // handles the synchronization as well.
 | 
			
		||||
    val dtm = Module (new JtagDTMWithSync()(p))
 | 
			
		||||
    dtm.io.jtag <> io.jtag.get
 | 
			
		||||
    coreplex.io.debug <> dtm.io.debug
 | 
			
		||||
  } else {
 | 
			
		||||
    coreplex.io.debug <>
 | 
			
		||||
      (if (p(AsyncDebugBus)) AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get)
 | 
			
		||||
      else io.debug.get)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryExtInterrupts extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val pInterrupts: RangeManager
 | 
			
		||||
 | 
			
		||||
  pInterrupts.add("ext", p(NExtTopInterrupts))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryExtInterruptsBundle {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryExtInterruptsModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryExtInterrupts
 | 
			
		||||
  val io: PeripheryExtInterruptsBundle
 | 
			
		||||
  val coreplex: Coreplex
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    val r = outer.pInterrupts.range("ext")
 | 
			
		||||
    ((r._1 until r._2) zipWithIndex) foreach { case (c, i) =>
 | 
			
		||||
      coreplex.io.interrupts(c) := io.interrupts(i)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMem extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMemBundle extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val mem_clk = p(AsyncMemChannels).option(Vec(nMemChannels, Clock(INPUT)))
 | 
			
		||||
  val mem_rst = p(AsyncMemChannels).option(Vec(nMemChannels, Bool (INPUT)))
 | 
			
		||||
  val mem_axi = Vec(nMemAXIChannels, new NastiIO)
 | 
			
		||||
  val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
 | 
			
		||||
  val mem_tl = Vec(nMemTLChannels, new ClientUncachedTileLinkIO()(outermostParams))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMemModule extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryMasterMem
 | 
			
		||||
  val io: PeripheryMasterMemBundle
 | 
			
		||||
  val coreplex: Coreplex
 | 
			
		||||
 | 
			
		||||
  // Abuse the fact that zip takes the shorter of the two lists
 | 
			
		||||
  ((io.mem_axi zip coreplex.io.master.mem) zipWithIndex) foreach { case ((axi, mem), idx) =>
 | 
			
		||||
    val axi_sync = PeripheryUtils.convertTLtoAXI(mem)(outermostParams)
 | 
			
		||||
    axi_sync.ar.bits.cache := UInt("b0011")
 | 
			
		||||
    axi_sync.aw.bits.cache := UInt("b0011")
 | 
			
		||||
    axi <> (
 | 
			
		||||
      if (!p(AsyncMemChannels)) axi_sync
 | 
			
		||||
      else AsyncNastiTo(io.mem_clk.get(idx), io.mem_rst.get(idx), axi_sync)
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  (io.mem_ahb zip coreplex.io.master.mem) foreach { case (ahb, mem) =>
 | 
			
		||||
    ahb <> PeripheryUtils.convertTLtoAHB(mem, atomics = false)(outermostParams)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  (io.mem_tl zip coreplex.io.master.mem) foreach { case (tl, mem) =>
 | 
			
		||||
    tl <> ClientUncachedTileLinkEnqueuer(mem, 2)(outermostParams)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMMIO extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMMIOBundle extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val mmio_clk = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Clock(INPUT)))
 | 
			
		||||
  val mmio_rst = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Bool (INPUT)))
 | 
			
		||||
  val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO)
 | 
			
		||||
  val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO)
 | 
			
		||||
  val mmio_tl = Vec(p(NExtMMIOTLChannels), new ClientUncachedTileLinkIO()(outermostMMIOParams))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryMasterMMIOModule extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryMasterMMIO
 | 
			
		||||
  val io: PeripheryMasterMMIOBundle
 | 
			
		||||
  val mmioNetwork: Option[TileLinkRecursiveInterconnect]
 | 
			
		||||
 | 
			
		||||
  val mmio_ports = p(ExtMMIOPorts) map { port =>
 | 
			
		||||
    TileLinkWidthAdapter(mmioNetwork.get.port(port.name), "MMIO_Outermost")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val mmio_axi_start = 0
 | 
			
		||||
  val mmio_axi_end   = mmio_axi_start + p(NExtMMIOAXIChannels)
 | 
			
		||||
  val mmio_ahb_start = mmio_axi_end
 | 
			
		||||
  val mmio_ahb_end   = mmio_ahb_start + p(NExtMMIOAHBChannels)
 | 
			
		||||
  val mmio_tl_start  = mmio_ahb_end
 | 
			
		||||
  val mmio_tl_end    = mmio_tl_start  + p(NExtMMIOTLChannels)
 | 
			
		||||
  require (mmio_tl_end == mmio_ports.size)
 | 
			
		||||
 | 
			
		||||
  for (i <- 0 until mmio_ports.size) {
 | 
			
		||||
    if (mmio_axi_start <= i && i < mmio_axi_end) {
 | 
			
		||||
      val idx = i-mmio_axi_start
 | 
			
		||||
      val axi_sync = PeripheryUtils.convertTLtoAXI(mmio_ports(i))(outermostMMIOParams)
 | 
			
		||||
      io.mmio_axi(idx) <> (
 | 
			
		||||
        if (!p(AsyncMMIOChannels)) axi_sync
 | 
			
		||||
        else AsyncNastiTo(io.mmio_clk.get(idx), io.mmio_rst.get(idx), axi_sync)
 | 
			
		||||
      )
 | 
			
		||||
    } else if (mmio_ahb_start <= i && i < mmio_ahb_end) {
 | 
			
		||||
      val idx = i-mmio_ahb_start
 | 
			
		||||
      io.mmio_ahb(idx) <> PeripheryUtils.convertTLtoAHB(mmio_ports(i), atomics = true)(outermostMMIOParams)
 | 
			
		||||
    } else if (mmio_tl_start <= i && i < mmio_tl_end) {
 | 
			
		||||
      val idx = i-mmio_tl_start
 | 
			
		||||
      io.mmio_tl(idx) <> ClientUncachedTileLinkEnqueuer(mmio_ports(i), 2)(outermostMMIOParams)
 | 
			
		||||
    } else {
 | 
			
		||||
      require(false, "Unconnected external MMIO port")
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripherySlave extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val pBusMasters: RangeManager
 | 
			
		||||
 | 
			
		||||
  if (p(NExtBusAXIChannels) > 0) pBusMasters.add("ext", 1) // NExtBusAXIChannels are arbitrated into one TL port
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripherySlaveBundle extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val bus_clk = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Clock(INPUT)))
 | 
			
		||||
  val bus_rst = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Bool (INPUT)))
 | 
			
		||||
  val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripherySlaveModule extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripherySlave
 | 
			
		||||
  val io: PeripherySlaveBundle
 | 
			
		||||
  val coreplex: Coreplex
 | 
			
		||||
 | 
			
		||||
  if (p(NExtBusAXIChannels) > 0) {
 | 
			
		||||
    val arb = Module(new NastiArbiter(p(NExtBusAXIChannels)))
 | 
			
		||||
    ((io.bus_axi zip arb.io.master) zipWithIndex) foreach { case ((bus, port), idx) =>
 | 
			
		||||
      port <> (
 | 
			
		||||
        if (!p(AsyncBusChannels)) bus
 | 
			
		||||
        else AsyncNastiFrom(io.bus_clk.get(idx), io.bus_rst.get(idx), bus)
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
    val conv = Module(new TileLinkIONastiIOConverter()(innerParams))
 | 
			
		||||
    conv.io.nasti <> arb.io.slave
 | 
			
		||||
 | 
			
		||||
    val r = outer.pBusMasters.range("ext")
 | 
			
		||||
    require(r._2 - r._1 == 1, "RangeManager should return 1 slot")
 | 
			
		||||
    coreplex.io.slave(r._1) <> conv.io.tl
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestRAM extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val pDevices: ResourceManager[AddrMapEntry]
 | 
			
		||||
 | 
			
		||||
  val ramSize = 0x1000
 | 
			
		||||
  pDevices.add(AddrMapEntry("testram", MemSize(ramSize, MemAttr(AddrMapProt.RW))))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestRAMBundle {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestRAMModule extends HasPeripheryParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryTestRAM
 | 
			
		||||
  val io: PeripheryTestRAMBundle
 | 
			
		||||
  val mmioNetwork: Option[TileLinkRecursiveInterconnect]
 | 
			
		||||
 | 
			
		||||
  val testram = Module(new TileLinkTestRAM(outer.ramSize)(innerMMIOParams))
 | 
			
		||||
  testram.io <> mmioNetwork.get.port("testram")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestBusMaster extends LazyModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val pBusMasters: RangeManager
 | 
			
		||||
  val pDevices: ResourceManager[AddrMapEntry]
 | 
			
		||||
 | 
			
		||||
  pBusMasters.add("busmaster", 1)
 | 
			
		||||
  pDevices.add(AddrMapEntry("busmaster", MemSize(4096, MemAttr(AddrMapProt.RW))))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestBusMasterBundle {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trait PeripheryTestBusMasterModule {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  val outer: PeripheryTestBusMaster
 | 
			
		||||
  val io: PeripheryTestBusMasterBundle
 | 
			
		||||
  val mmioNetwork: Option[TileLinkRecursiveInterconnect]
 | 
			
		||||
  val coreplex: Coreplex
 | 
			
		||||
 | 
			
		||||
  val busmaster = Module(new groundtest.ExampleBusMaster()(p))
 | 
			
		||||
  busmaster.io.mmio <> mmioNetwork.get.port("busmaster")
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    val r = outer.pBusMasters.range("busmaster")
 | 
			
		||||
    require(r._2 - r._1 == 1, "RangeManager should return 1 slot")
 | 
			
		||||
    coreplex.io.slave(r._1) <> busmaster.io.mem
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,307 +0,0 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
package rocketchip
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.devices._
 | 
			
		||||
import uncore.util._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import uncore.converters._
 | 
			
		||||
import uncore.coherence.{InnerTLId, OuterTLId}
 | 
			
		||||
import rocket._
 | 
			
		||||
import coreplex._
 | 
			
		||||
import scala.collection.immutable.HashMap
 | 
			
		||||
 | 
			
		||||
/** Top-level parameters of RocketChip, values set in e.g. PublicConfigs.scala */
 | 
			
		||||
 | 
			
		||||
/** Options for memory bus interface */
 | 
			
		||||
object BusType {
 | 
			
		||||
  sealed trait EnumVal
 | 
			
		||||
  case object AXI extends EnumVal
 | 
			
		||||
  case object AHB extends EnumVal
 | 
			
		||||
  case object TL  extends EnumVal
 | 
			
		||||
  val busTypes = Seq(AXI, AHB, TL)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Memory channel controls */
 | 
			
		||||
case object TMemoryChannels extends Field[BusType.EnumVal]
 | 
			
		||||
/** External MMIO controls */
 | 
			
		||||
case object NExtMMIOAXIChannels extends Field[Int]
 | 
			
		||||
case object NExtMMIOAHBChannels extends Field[Int]
 | 
			
		||||
case object NExtMMIOTLChannels  extends Field[Int]
 | 
			
		||||
/** External Bus controls */
 | 
			
		||||
case object NExtBusAXIChannels extends Field[Int]
 | 
			
		||||
/** Async configurations */
 | 
			
		||||
case object AsyncBusChannels extends Field[Boolean]
 | 
			
		||||
case object AsyncDebugBus extends Field[Boolean]
 | 
			
		||||
case object AsyncMemChannels extends Field[Boolean]
 | 
			
		||||
case object AsyncMMIOChannels extends Field[Boolean]
 | 
			
		||||
/** External address map settings */
 | 
			
		||||
case object ExtMMIOPorts extends Field[Seq[AddrMapEntry]]
 | 
			
		||||
/** Function for building Coreplex */
 | 
			
		||||
case object BuildCoreplex extends Field[Parameters => Coreplex]
 | 
			
		||||
/** Function for connecting coreplex extra ports to top-level extra ports */
 | 
			
		||||
case object ConnectExtraPorts extends Field[(Bundle, Bundle, Parameters) => Unit]
 | 
			
		||||
/** Specifies the size of external memory */
 | 
			
		||||
case object ExtMemSize extends Field[Long]
 | 
			
		||||
/** Specifies the actual sorce of External Interrupts as Top and Periphery.
 | 
			
		||||
  *  NExtInterrupts = NExtTopInterrupts + NExtPeripheryInterrupts 
 | 
			
		||||
  **/
 | 
			
		||||
case object NExtTopInterrupts extends Field[Int]
 | 
			
		||||
case object NExtPeripheryInterrupts extends Field[Int]
 | 
			
		||||
/** Source of  RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra  **/
 | 
			
		||||
case object RTCTick extends Field[(Parameters, Bundle, Bundle) => Bool]
 | 
			
		||||
case object RTCPeriod extends Field[Int]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Utility trait for quick access to some relevant parameters */
 | 
			
		||||
trait HasTopLevelParameters {
 | 
			
		||||
  implicit val p: Parameters
 | 
			
		||||
  lazy val tMemChannels = p(TMemoryChannels)
 | 
			
		||||
  lazy val nMemChannels = p(NMemoryChannels)
 | 
			
		||||
  lazy val nMemAXIChannels = if (tMemChannels == BusType.AXI) nMemChannels else 0
 | 
			
		||||
  lazy val nMemAHBChannels = if (tMemChannels == BusType.AHB) nMemChannels else 0
 | 
			
		||||
  lazy val nMemTLChannels  = if (tMemChannels == BusType.TL)  nMemChannels else 0
 | 
			
		||||
  lazy val innerParams = p.alterPartial({ case TLId => "L1toL2" })
 | 
			
		||||
  lazy val outermostParams = p.alterPartial({ case TLId => "Outermost" })
 | 
			
		||||
  lazy val outermostMMIOParams = p.alterPartial({ case TLId => "MMIO_Outermost" })
 | 
			
		||||
  lazy val exportMMIO = p(ExportMMIOPort)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class MemBackupCtrlIO extends Bundle {
 | 
			
		||||
  val en = Bool(INPUT)
 | 
			
		||||
  val in_valid = Bool(INPUT)
 | 
			
		||||
  val out_ready = Bool(INPUT)
 | 
			
		||||
  val out_valid = Bool(OUTPUT)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Top-level io for the chip */
 | 
			
		||||
class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
 | 
			
		||||
    with HasTopLevelParameters
 | 
			
		||||
 | 
			
		||||
class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
 | 
			
		||||
  val mem_clk = p(AsyncMemChannels).option(Vec(nMemChannels, Clock(INPUT)))
 | 
			
		||||
  val mem_rst = p(AsyncMemChannels).option(Vec(nMemChannels, Bool (INPUT)))
 | 
			
		||||
  val mem_axi = Vec(nMemAXIChannels, new NastiIO)
 | 
			
		||||
  val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
 | 
			
		||||
  val mem_tl  = Vec(nMemTLChannels,  new ClientUncachedTileLinkIO()(outermostParams))
 | 
			
		||||
  val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput
 | 
			
		||||
  val bus_clk = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Clock(INPUT)))
 | 
			
		||||
  val bus_rst = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Bool (INPUT)))
 | 
			
		||||
  val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip
 | 
			
		||||
  val mmio_clk = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Clock(INPUT)))
 | 
			
		||||
  val mmio_rst = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Bool (INPUT)))
 | 
			
		||||
  val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO)
 | 
			
		||||
  val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO)
 | 
			
		||||
  val mmio_tl  = Vec(p(NExtMMIOTLChannels),  new ClientUncachedTileLinkIO()(outermostMMIOParams))
 | 
			
		||||
  val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT))
 | 
			
		||||
  val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT))
 | 
			
		||||
  val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip)
 | 
			
		||||
  val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip)
 | 
			
		||||
  val extra = p(ExtraTopPorts)(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object TopUtils {
 | 
			
		||||
  // Connect two Nasti interfaces with queues in-between
 | 
			
		||||
  def connectNasti(outer: NastiIO, inner: NastiIO)(implicit p: Parameters) {
 | 
			
		||||
    val mifDataBeats = p(MIFDataBeats)
 | 
			
		||||
    outer.ar <> Queue(inner.ar, 1)
 | 
			
		||||
    outer.aw <> Queue(inner.aw, 1)
 | 
			
		||||
    outer.w  <> Queue(inner.w)
 | 
			
		||||
    inner.r  <> Queue(outer.r)
 | 
			
		||||
    inner.b  <> Queue(outer.b, 1)
 | 
			
		||||
  }
 | 
			
		||||
  def connectTilelinkNasti(nasti: NastiIO, tl: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val conv = Module(new NastiIOTileLinkIOConverter())
 | 
			
		||||
    conv.io.tl <> tl
 | 
			
		||||
    TopUtils.connectNasti(nasti, conv.io.nasti)
 | 
			
		||||
  }
 | 
			
		||||
  def connectTilelinkAhb(ahb: HastiMasterIO, tl: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val bridge = Module(new AHBBridge(true))
 | 
			
		||||
    bridge.io.tl <> tl
 | 
			
		||||
    bridge.io.ahb
 | 
			
		||||
  }
 | 
			
		||||
  def connectTilelink(
 | 
			
		||||
      outer: ClientUncachedTileLinkIO, inner: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    outer.acquire <> Queue(inner.acquire)
 | 
			
		||||
    inner.grant <> Queue(outer.grant)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Top-level module for the chip */
 | 
			
		||||
//TODO: Remove this wrapper once multichannel DRAM controller is provided
 | 
			
		||||
class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
 | 
			
		||||
  implicit val p = topParams
 | 
			
		||||
 | 
			
		||||
  val coreplex = p(BuildCoreplex)(p)
 | 
			
		||||
  val periphery = Module(new Periphery()(innerParams))
 | 
			
		||||
 | 
			
		||||
  val io = new TopIO {
 | 
			
		||||
    val success = coreplex.hasSuccessFlag.option(Bool(OUTPUT))
 | 
			
		||||
  }
 | 
			
		||||
  io.success zip coreplex.io.success map { case (x, y) => x := y }
 | 
			
		||||
 | 
			
		||||
  if (exportMMIO) { periphery.io.mmio_in.get <> coreplex.io.mmio.get }
 | 
			
		||||
  periphery.io.mem_in <> coreplex.io.mem
 | 
			
		||||
  coreplex.io.ext_clients <> periphery.io.clients_out
 | 
			
		||||
 | 
			
		||||
  if (p(IncludeJtagDTM)) {
 | 
			
		||||
    // JtagDTMWithSync  is a wrapper which
 | 
			
		||||
    // handles the synchronization as well.
 | 
			
		||||
    val jtag_dtm = Module (new JtagDTMWithSync()(p))
 | 
			
		||||
    jtag_dtm.io.jtag  <> io.jtag.get
 | 
			
		||||
    coreplex.io.debug <> jtag_dtm.io.debug
 | 
			
		||||
  } else {
 | 
			
		||||
    coreplex.io.debug <>
 | 
			
		||||
    (if (p(AsyncDebugBus))
 | 
			
		||||
      AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get)
 | 
			
		||||
    else io.debug.get)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def asyncAxiTo(clocks: Seq[Clock], resets: Seq[Bool], inner_axis: Seq[NastiIO]): Seq[NastiIO] =
 | 
			
		||||
    (clocks, resets, inner_axis).zipped.map {
 | 
			
		||||
      case (clk, rst, in_axi) => AsyncNastiTo(clk, rst, in_axi)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  def asyncAxiFrom(clocks: Seq[Clock], resets: Seq[Bool], outer_axis: Seq[NastiIO]): Seq[NastiIO] =
 | 
			
		||||
    (clocks, resets, outer_axis).zipped.map {
 | 
			
		||||
      case (clk, rst, out_axi) => AsyncNastiFrom(clk, rst, out_axi)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  io.mmio_axi <>
 | 
			
		||||
    (if (p(AsyncMMIOChannels))
 | 
			
		||||
      asyncAxiTo(io.mmio_clk.get, io.mmio_rst.get, periphery.io.mmio_axi)
 | 
			
		||||
    else periphery.io.mmio_axi)
 | 
			
		||||
  io.mmio_ahb <> periphery.io.mmio_ahb
 | 
			
		||||
  io.mmio_tl <> periphery.io.mmio_tl
 | 
			
		||||
 | 
			
		||||
  io.mem_axi <>
 | 
			
		||||
    (if (p(AsyncMemChannels))
 | 
			
		||||
      asyncAxiTo(io.mem_clk.get, io.mem_rst.get, periphery.io.mem_axi)
 | 
			
		||||
    else periphery.io.mem_axi)
 | 
			
		||||
  io.mem_ahb <> periphery.io.mem_ahb
 | 
			
		||||
  io.mem_tl <> periphery.io.mem_tl
 | 
			
		||||
 | 
			
		||||
  periphery.io.bus_axi <>
 | 
			
		||||
    (if (p(AsyncBusChannels))
 | 
			
		||||
      asyncAxiFrom(io.bus_clk.get, io.bus_rst.get, io.bus_axi)
 | 
			
		||||
    else io.bus_axi)
 | 
			
		||||
 | 
			
		||||
  // This places the Periphery Interrupts at Bits [0...]
 | 
			
		||||
  // Top-level interrupts are at the higher Bits.
 | 
			
		||||
  // This may have some implications for prioritization of the interrupts,
 | 
			
		||||
  // but PLIC could do some internal swizzling in the future.
 | 
			
		||||
  coreplex.io.interrupts <> (periphery.io.interrupts ++ io.interrupts)
 | 
			
		||||
 | 
			
		||||
  io.extra <> periphery.io.extra
 | 
			
		||||
 | 
			
		||||
  coreplex.io.rtcTick := p(RTCTick)(p, io.extra, periphery.io.extra)
 | 
			
		||||
 | 
			
		||||
  p(ConnectExtraPorts)(io.extra, coreplex.io.extra, p)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Periphery(implicit val p: Parameters) extends Module
 | 
			
		||||
    with HasTopLevelParameters {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val mem_in  = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams)).flip
 | 
			
		||||
    val clients_out = Vec(p(NExternalClients), new ClientUncachedTileLinkIO()(innerParams))
 | 
			
		||||
    val mmio_in = exportMMIO.option(new ClientUncachedTileLinkIO()(outermostMMIOParams).flip)
 | 
			
		||||
    val mem_axi = Vec(nMemAXIChannels, new NastiIO)
 | 
			
		||||
    val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
 | 
			
		||||
    val mem_tl  = Vec(nMemTLChannels,  new ClientUncachedTileLinkIO()(outermostParams))
 | 
			
		||||
    val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip
 | 
			
		||||
    val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO)
 | 
			
		||||
    val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO)
 | 
			
		||||
    val mmio_tl  = Vec(p(NExtMMIOTLChannels),  new ClientUncachedTileLinkIO()(outermostMMIOParams))
 | 
			
		||||
    val interrupts = Vec(p(NExtPeripheryInterrupts), Bool()).asOutput
 | 
			
		||||
    val extra = p(ExtraTopPorts)(p)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (io.bus_axi.size > 0) {
 | 
			
		||||
    val conv = Module(new TileLinkIONastiIOConverter)
 | 
			
		||||
    val arb = Module(new NastiArbiter(io.bus_axi.size))
 | 
			
		||||
    arb.io.master <> io.bus_axi
 | 
			
		||||
    conv.io.nasti <> arb.io.slave
 | 
			
		||||
    io.clients_out.head <> conv.io.tl
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def connectExternalMMIO(ports: Seq[ClientUncachedTileLinkIO])(implicit p: Parameters) {
 | 
			
		||||
    val mmio_axi_start = 0
 | 
			
		||||
    val mmio_axi_end   = mmio_axi_start + p(NExtMMIOAXIChannels)
 | 
			
		||||
    val mmio_ahb_start = mmio_axi_end
 | 
			
		||||
    val mmio_ahb_end   = mmio_ahb_start + p(NExtMMIOAHBChannels)
 | 
			
		||||
    val mmio_tl_start  = mmio_ahb_end
 | 
			
		||||
    val mmio_tl_end    = mmio_tl_start  + p(NExtMMIOTLChannels)
 | 
			
		||||
    require (mmio_tl_end == ports.size)
 | 
			
		||||
 | 
			
		||||
    for (i <- 0 until ports.size) {
 | 
			
		||||
      if (mmio_axi_start <= i && i < mmio_axi_end) {
 | 
			
		||||
        TopUtils.connectTilelinkNasti(io.mmio_axi(i-mmio_axi_start), ports(i))
 | 
			
		||||
      } else if (mmio_ahb_start <= i && i < mmio_ahb_end) {
 | 
			
		||||
        val ahbBridge = Module(new AHBBridge(true))
 | 
			
		||||
        io.mmio_ahb(i-mmio_ahb_start) <> ahbBridge.io.ahb
 | 
			
		||||
        ahbBridge.io.tl <> ports(i)
 | 
			
		||||
      } else if (mmio_tl_start <= i && i < mmio_tl_end) {
 | 
			
		||||
        TopUtils.connectTilelink(io.mmio_tl(i-mmio_tl_start), ports(i))
 | 
			
		||||
      } else {
 | 
			
		||||
        require(false, "Unconnected external MMIO port")
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def buildMMIONetwork(implicit p: Parameters) = {
 | 
			
		||||
    val extAddrMap = p(GlobalAddrMap).subMap("io:ext")
 | 
			
		||||
 | 
			
		||||
    val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, extAddrMap))
 | 
			
		||||
    mmioNetwork.io.in.head <> io.mmio_in.get
 | 
			
		||||
 | 
			
		||||
    val extraDevices = p(ExtraDevices)
 | 
			
		||||
 | 
			
		||||
    val deviceMMIO = HashMap.newBuilder[String, ClientUncachedTileLinkIO]
 | 
			
		||||
    for ((entry, i) <- extraDevices.addrMapEntries.zipWithIndex)
 | 
			
		||||
      deviceMMIO += (entry.name -> mmioNetwork.port(entry.name))
 | 
			
		||||
 | 
			
		||||
    val deviceClients = if (io.bus_axi.size > 0) io.clients_out.tail else io.clients_out
 | 
			
		||||
    require(deviceClients.size == extraDevices.nClientPorts)
 | 
			
		||||
 | 
			
		||||
    val buildParams = p.alterPartial({
 | 
			
		||||
      case InnerTLId => "L2toMMIO" // Device MMIO port
 | 
			
		||||
      case OuterTLId => "L1toL2"   // Device client port
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    extraDevices.builder(deviceMMIO.result(), deviceClients,
 | 
			
		||||
                         io.interrupts, io.extra, buildParams)
 | 
			
		||||
 | 
			
		||||
    val ext = p(ExtMMIOPorts).map(
 | 
			
		||||
      port => TileLinkWidthAdapter(mmioNetwork.port(port.name), "MMIO_Outermost"))
 | 
			
		||||
    connectExternalMMIO(ext)(outermostMMIOParams)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (exportMMIO) {
 | 
			
		||||
    buildMMIONetwork(p.alterPartial({case TLId => "L2toMMIO"}))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for ((nasti, tl) <- io.mem_axi zip io.mem_in) {
 | 
			
		||||
    TopUtils.connectTilelinkNasti(nasti, tl)(outermostParams)
 | 
			
		||||
    // Memory cache type should be normal non-cacheable bufferable
 | 
			
		||||
    // TODO why is this happening here?  Would 0000 (device) be OK instead?
 | 
			
		||||
    nasti.ar.bits.cache := UInt("b0011")
 | 
			
		||||
    nasti.aw.bits.cache := UInt("b0011")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Abuse the fact that zip takes the shorter of the two lists
 | 
			
		||||
  for ((ahb, tl) <- io.mem_ahb zip io.mem_in) {
 | 
			
		||||
    val bridge = Module(new AHBBridge(false)) // no atomics
 | 
			
		||||
    ahb <> bridge.io.ahb
 | 
			
		||||
    bridge.io.tl <> tl
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for ((mem_tl, tl) <- io.mem_tl zip io.mem_in) {
 | 
			
		||||
    TopUtils.connectTilelink(mem_tl, tl)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +26,7 @@ class WithUnitTest extends Config(
 | 
			
		||||
        DefaultTestSuites.groundtest32
 | 
			
		||||
      TestGeneration.addSuite(groundtest("p"))
 | 
			
		||||
      TestGeneration.addSuite(DefaultTestSuites.emptyBmarks)
 | 
			
		||||
      (p: Parameters) => Module(new UnitTestCoreplex(p))
 | 
			
		||||
      (p: Parameters, c: CoreplexConfig) => Module(new UnitTestCoreplex(p, c))
 | 
			
		||||
    }
 | 
			
		||||
    case UnitTests => (testParams: Parameters) =>
 | 
			
		||||
      JunctionsUnitTests(testParams) ++ UncoreUnitTests(testParams)
 | 
			
		||||
@@ -42,7 +42,8 @@ class UnitTestConfig extends Config(new WithUnitTest ++ new BaseConfig)
 | 
			
		||||
 | 
			
		||||
class WithGroundTest extends Config(
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
    case BuildCoreplex => (p: Parameters) => Module(new GroundTestCoreplex(p))
 | 
			
		||||
    case BuildCoreplex =>
 | 
			
		||||
      (p: Parameters, c: CoreplexConfig) => Module(new GroundTestCoreplex(p, c))
 | 
			
		||||
    case TLKey("L1toL2") => {
 | 
			
		||||
      val useMEI = site(NTiles) <= 1 && site(NCachedTileLinkPorts) <= 1
 | 
			
		||||
      TileLinkParameters(
 | 
			
		||||
@@ -51,7 +52,7 @@ class WithGroundTest extends Config(
 | 
			
		||||
          else new MESICoherence(site(L2DirectoryRepresentation))),
 | 
			
		||||
        nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1,
 | 
			
		||||
        nCachingClients = site(NCachedTileLinkPorts),
 | 
			
		||||
        nCachelessClients = site(NExternalClients) + site(NUncachedTileLinkPorts),
 | 
			
		||||
        nCachelessClients = site(NCoreplexExtClients).get + site(NUncachedTileLinkPorts),
 | 
			
		||||
        maxClientXacts = ((site(DCacheKey).nMSHRs + 1) +:
 | 
			
		||||
                           site(GroundTestKey).map(_.maxXacts))
 | 
			
		||||
                             .reduce(max(_, _)),
 | 
			
		||||
@@ -79,6 +80,8 @@ class WithGroundTest extends Config(
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    case BuildExampleTop =>
 | 
			
		||||
      (p: Parameters) => uncore.tilelink2.LazyModule(new ExampleTopWithTestRAM(p))
 | 
			
		||||
    case FPUKey => None
 | 
			
		||||
    case UseAtomics => false
 | 
			
		||||
    case UseCompressed => false
 | 
			
		||||
@@ -89,7 +92,7 @@ class WithGroundTest extends Config(
 | 
			
		||||
class GroundTestConfig extends Config(new WithGroundTest ++ new BaseConfig)
 | 
			
		||||
 | 
			
		||||
class ComparatorConfig extends Config(
 | 
			
		||||
  new WithTestRAM ++ new WithComparator ++ new GroundTestConfig)
 | 
			
		||||
  new WithComparator ++ new GroundTestConfig)
 | 
			
		||||
class ComparatorL2Config extends Config(
 | 
			
		||||
  new WithAtomics ++ new WithPrefetches ++
 | 
			
		||||
  new WithL2Cache ++ new ComparatorConfig)
 | 
			
		||||
@@ -147,60 +150,3 @@ class MIF32BitMemtestConfig extends Config(
 | 
			
		||||
 | 
			
		||||
class PCIeMockupTestConfig extends Config(
 | 
			
		||||
  new WithPCIeMockupTest ++ new GroundTestConfig)
 | 
			
		||||
 | 
			
		||||
class WithDirectGroundTest extends Config(
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
    case ExportGroundTestStatus => true
 | 
			
		||||
    case BuildCoreplex => (p: Parameters) => Module(new DirectGroundTestCoreplex(p))
 | 
			
		||||
    case ExtraCoreplexPorts => (p: Parameters) =>
 | 
			
		||||
      if (p(ExportGroundTestStatus)) new GroundTestStatus else new Bundle
 | 
			
		||||
    case ExtraTopPorts => (p: Parameters) =>
 | 
			
		||||
      if (p(ExportGroundTestStatus)) new GroundTestStatus else new Bundle
 | 
			
		||||
    case TLKey("Outermost") => site(TLKey("L2toMC")).copy(
 | 
			
		||||
      maxClientXacts = site(GroundTestKey)(0).maxXacts,
 | 
			
		||||
      maxClientsPerPort = site(NBanksPerMemoryChannel),
 | 
			
		||||
      dataBeats = site(MIFDataBeats))
 | 
			
		||||
    case NBanksPerMemoryChannel => site(GroundTestKey)(0).uncached
 | 
			
		||||
    case _ => throw new CDEMatchError
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
class DirectGroundTestConfig extends Config(
 | 
			
		||||
  new WithDirectGroundTest ++ new GroundTestConfig)
 | 
			
		||||
class DirectMemtestConfig extends Config(
 | 
			
		||||
  new WithDirectMemtest ++ new DirectGroundTestConfig)
 | 
			
		||||
class DirectComparatorConfig extends Config(
 | 
			
		||||
  new WithDirectComparator ++ new DirectGroundTestConfig)
 | 
			
		||||
 | 
			
		||||
class DirectMemtestFPGAConfig extends Config(
 | 
			
		||||
  new FPGAConfig ++ new DirectMemtestConfig)
 | 
			
		||||
class DirectComparatorFPGAConfig extends Config(
 | 
			
		||||
  new FPGAConfig ++ new DirectComparatorConfig)
 | 
			
		||||
 | 
			
		||||
class WithBusMasterTest extends Config(
 | 
			
		||||
  (pname, site, here) => pname match {
 | 
			
		||||
    case GroundTestKey => Seq.fill(site(NTiles)) {
 | 
			
		||||
      GroundTestTileSettings(uncached = 1)
 | 
			
		||||
    }
 | 
			
		||||
    case BuildGroundTest =>
 | 
			
		||||
      (p: Parameters) => Module(new BusMasterTest()(p))
 | 
			
		||||
    case ExtraDevices => {
 | 
			
		||||
      class BusMasterDevice extends DeviceBlock {
 | 
			
		||||
        def nClientPorts = 1
 | 
			
		||||
        def addrMapEntries = Seq(
 | 
			
		||||
          AddrMapEntry("busmaster", MemSize(4096, MemAttr(AddrMapProt.RW))))
 | 
			
		||||
        def builder(
 | 
			
		||||
          mmioPorts: HashMap[String, ClientUncachedTileLinkIO],
 | 
			
		||||
          clientPorts: Seq[ClientUncachedTileLinkIO],
 | 
			
		||||
          interrupts : Seq[Bool], 
 | 
			
		||||
          extra: Bundle, p: Parameters) {
 | 
			
		||||
          val busmaster = Module(new ExampleBusMaster()(p))
 | 
			
		||||
          busmaster.io.mmio <> mmioPorts("busmaster")
 | 
			
		||||
          clientPorts.head <> busmaster.io.mem
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      new BusMasterDevice
 | 
			
		||||
    }
 | 
			
		||||
    case _ => throw new CDEMatchError
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
class BusMasterTestConfig extends Config(new WithBusMasterTest ++ new GroundTestConfig)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,11 +7,14 @@ import cde.{Parameters, Field}
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import junctions._
 | 
			
		||||
 | 
			
		||||
class TestHarness(implicit p: Parameters) extends Module {
 | 
			
		||||
case object BuildExampleTop extends Field[Parameters => ExampleTop]
 | 
			
		||||
case object SimMemLatency extends Field[Int]
 | 
			
		||||
 | 
			
		||||
class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapParameters {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val success = Bool(OUTPUT)
 | 
			
		||||
  }
 | 
			
		||||
  val dut = Module(new Top(p))
 | 
			
		||||
  val dut = p(BuildExampleTop)(p).module
 | 
			
		||||
 | 
			
		||||
  // This test harness isn't especially flexible yet
 | 
			
		||||
  require(dut.io.mem_clk.isEmpty)
 | 
			
		||||
@@ -24,16 +27,21 @@ class TestHarness(implicit p: Parameters) extends Module {
 | 
			
		||||
  require(dut.io.mmio_rst.isEmpty)
 | 
			
		||||
  require(dut.io.mmio_ahb.isEmpty)
 | 
			
		||||
  require(dut.io.mmio_tl.isEmpty)
 | 
			
		||||
  require(dut.io.extra.elements.isEmpty)
 | 
			
		||||
 | 
			
		||||
  for (int <- dut.io.interrupts)
 | 
			
		||||
    int := false
 | 
			
		||||
 | 
			
		||||
  if (dut.io.mem_axi.nonEmpty) {
 | 
			
		||||
    val memSize = p(GlobalAddrMap)("mem").size
 | 
			
		||||
    val memSize = addrMap("mem").size
 | 
			
		||||
    require(memSize % dut.io.mem_axi.size == 0)
 | 
			
		||||
    for (axi <- dut.io.mem_axi)
 | 
			
		||||
      Module(new SimAXIMem(memSize / dut.io.mem_axi.size)).io.axi <> axi
 | 
			
		||||
    for (axi <- dut.io.mem_axi) {
 | 
			
		||||
      val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi.size))
 | 
			
		||||
      mem.io.axi.ar <> axi.ar
 | 
			
		||||
      mem.io.axi.aw <> axi.aw
 | 
			
		||||
      mem.io.axi.w  <> axi.w
 | 
			
		||||
      axi.r <> LatencyPipe(mem.io.axi.r, p(SimMemLatency))
 | 
			
		||||
      axi.b <> LatencyPipe(mem.io.axi.b, p(SimMemLatency))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!p(IncludeJtagDTM)) {
 | 
			
		||||
@@ -64,7 +72,7 @@ class TestHarness(implicit p: Parameters) extends Module {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module {
 | 
			
		||||
class SimAXIMem(size: BigInt)(implicit p: Parameters) extends NastiModule()(p) {
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val axi = new NastiIO().flip
 | 
			
		||||
  }
 | 
			
		||||
@@ -81,8 +89,8 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val w = io.axi.w.bits
 | 
			
		||||
  require((size * 8) % w.data.getWidth == 0)
 | 
			
		||||
  val depth = (size * 8) / w.data.getWidth
 | 
			
		||||
  require((size * 8) % nastiXDataBits == 0)
 | 
			
		||||
  val depth = (size * 8) / nastiXDataBits
 | 
			
		||||
  val mem = Mem(depth.toInt, w.data)
 | 
			
		||||
 | 
			
		||||
  val wValid = Reg(init = Bool(false))
 | 
			
		||||
@@ -101,7 +109,7 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module {
 | 
			
		||||
      bValid := true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def row = mem((aw.addr >> log2Ceil(w.data.getWidth/8))(log2Ceil(depth)-1, 0))
 | 
			
		||||
    def row = mem((aw.addr >> log2Ceil(nastiXDataBits/8))(log2Ceil(depth)-1, 0))
 | 
			
		||||
    val mask = FillInterleaved(8, w.strb)
 | 
			
		||||
    val newData = mask & w.data | ~mask & row
 | 
			
		||||
    row := newData
 | 
			
		||||
@@ -113,7 +121,7 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module {
 | 
			
		||||
 | 
			
		||||
  io.axi.r.valid := rValid
 | 
			
		||||
  io.axi.r.bits.id := ar.id
 | 
			
		||||
  io.axi.r.bits.data := mem((ar.addr >> log2Ceil(w.data.getWidth/8))(log2Ceil(depth)-1, 0))
 | 
			
		||||
  io.axi.r.bits.data := mem((ar.addr >> log2Ceil(nastiXDataBits/8))(log2Ceil(depth)-1, 0))
 | 
			
		||||
  io.axi.r.bits.resp := UInt(0)
 | 
			
		||||
  io.axi.r.bits.last := ar.len === UInt(0)
 | 
			
		||||
}
 | 
			
		||||
@@ -166,3 +174,11 @@ class JTAGVPI(implicit val p: Parameters) extends BlackBox {
 | 
			
		||||
    tbsuccess := Bool(false)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object LatencyPipe {
 | 
			
		||||
  def doN[T](n: Int, func: T => T, in: T): T =
 | 
			
		||||
    (0 until n).foldLeft(in)((last, _) => func(last))
 | 
			
		||||
 | 
			
		||||
  def apply[T <: Data](in: DecoupledIO[T], latency: Int): DecoupledIO[T] =
 | 
			
		||||
    doN(latency, (last: DecoupledIO[T]) => Queue(last, 1, pipe=true), in)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								src/main/scala/rocketchip/Top.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/main/scala/rocketchip/Top.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
package rocketchip
 | 
			
		||||
 | 
			
		||||
import Chisel._
 | 
			
		||||
import cde.{Parameters, Field}
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore.tilelink._
 | 
			
		||||
import uncore.tilelink2.{LazyModule, LazyModuleImp}
 | 
			
		||||
import uncore.devices._
 | 
			
		||||
import rocket._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import coreplex._
 | 
			
		||||
 | 
			
		||||
// the following parameters will be refactored properly with TL2
 | 
			
		||||
case object GlobalAddrMap extends Field[GlobalVariable[AddrMap]]
 | 
			
		||||
case object ConfigString extends Field[GlobalVariable[String]]
 | 
			
		||||
case object NCoreplexExtClients extends Field[GlobalVariable[Int]]
 | 
			
		||||
/** Function for building Coreplex */
 | 
			
		||||
case object BuildCoreplex extends Field[(Parameters, CoreplexConfig) => Coreplex]
 | 
			
		||||
 | 
			
		||||
/** Base Top with no Periphery */
 | 
			
		||||
abstract class BaseTop(val p: Parameters) extends LazyModule {
 | 
			
		||||
  // the following variables will be refactored properly with TL2
 | 
			
		||||
  val pInterrupts = new RangeManager
 | 
			
		||||
  val pBusMasters = new RangeManager
 | 
			
		||||
  val pDevices = new ResourceManager[AddrMapEntry]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BaseTopBundle(val p: Parameters, val c: Coreplex) extends ParameterizedBundle()(p) {
 | 
			
		||||
  val success = c.hasSuccessFlag.option(Bool(OUTPUT))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, b: Coreplex => B) extends LazyModuleImp(l) {
 | 
			
		||||
  val outer: L = l
 | 
			
		||||
 | 
			
		||||
  val c = CoreplexConfig(
 | 
			
		||||
    nTiles = p(NTiles),
 | 
			
		||||
    nExtInterrupts = outer.pInterrupts.sum,
 | 
			
		||||
    nSlaves = outer.pBusMasters.sum,
 | 
			
		||||
    nMemChannels = p(NMemoryChannels),
 | 
			
		||||
    hasSupervisor = p(UseVM),
 | 
			
		||||
    hasExtMMIOPort = !(outer.pDevices.get.isEmpty && p(ExtMMIOPorts).isEmpty)
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  def genGlobalAddrMap = GenerateGlobalAddrMap(p, outer.pDevices.get)
 | 
			
		||||
  def genConfigString = GenerateConfigString(p, c, outer.pDevices.get)
 | 
			
		||||
 | 
			
		||||
  p(NCoreplexExtClients).assign(outer.pBusMasters.sum)
 | 
			
		||||
  p(GlobalAddrMap).assign(genGlobalAddrMap)
 | 
			
		||||
  p(ConfigString).assign(genConfigString)
 | 
			
		||||
 | 
			
		||||
  println("Generated Address Map")
 | 
			
		||||
  for (entry <- p(GlobalAddrMap).get.flatten) {
 | 
			
		||||
    val name = entry.name
 | 
			
		||||
    val start = entry.region.start
 | 
			
		||||
    val end = entry.region.start + entry.region.size - 1
 | 
			
		||||
    println(f"\t$name%s $start%x - $end%x")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  println("Generated Configuration String")
 | 
			
		||||
  println(p(ConfigString).get)
 | 
			
		||||
 | 
			
		||||
  val coreplex = p(BuildCoreplex)(p, c)
 | 
			
		||||
  val io: B = b(coreplex)
 | 
			
		||||
 | 
			
		||||
  io.success zip coreplex.io.success map { case (x, y) => x := y }
 | 
			
		||||
  coreplex.io.rtcTick := Counter(p(RTCPeriod)).inc()
 | 
			
		||||
 | 
			
		||||
  val mmioNetwork = c.hasExtMMIOPort.option(
 | 
			
		||||
    Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).get.subMap("io:ext"))(
 | 
			
		||||
      p.alterPartial({ case TLId => "L2toMMIO" }))))
 | 
			
		||||
  mmioNetwork.foreach { _.io.in.head <> coreplex.io.master.mmio.get }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Example Top with Periphery */
 | 
			
		||||
class ExampleTop(p: Parameters) extends BaseTop(p)
 | 
			
		||||
    with PeripheryDebug with PeripheryExtInterrupts
 | 
			
		||||
    with PeripheryMasterMem with PeripheryMasterMMIO with PeripherySlave {
 | 
			
		||||
  override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, _)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ExampleTopBundle(p: Parameters, c: Coreplex) extends BaseTopBundle(p, c)
 | 
			
		||||
    with PeripheryDebugBundle with PeripheryExtInterruptsBundle
 | 
			
		||||
    with PeripheryMasterMemBundle with PeripheryMasterMMIOBundle with PeripherySlaveBundle
 | 
			
		||||
 | 
			
		||||
class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: Coreplex => B) extends BaseTopModule(p, l, b)
 | 
			
		||||
    with PeripheryDebugModule with PeripheryExtInterruptsModule
 | 
			
		||||
    with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule
 | 
			
		||||
 | 
			
		||||
/** Example Top with TestRAM */
 | 
			
		||||
class ExampleTopWithTestRAM(p: Parameters) extends ExampleTop(p)
 | 
			
		||||
    with PeripheryTestRAM {
 | 
			
		||||
  override lazy val module = Module(new ExampleTopWithTestRAMModule(p, this, new ExampleTopWithTestRAMBundle(p, _)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ExampleTopWithTestRAMBundle(p: Parameters, c: Coreplex) extends ExampleTopBundle(p, c)
 | 
			
		||||
    with PeripheryTestRAMBundle
 | 
			
		||||
 | 
			
		||||
class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle](p: Parameters, l: L, b: Coreplex => B) extends ExampleTopModule(p, l, b)
 | 
			
		||||
    with PeripheryTestRAMModule
 | 
			
		||||
							
								
								
									
										149
									
								
								src/main/scala/rocketchip/Utils.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/main/scala/rocketchip/Utils.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
package rocketchip
 | 
			
		||||
 | 
			
		||||
import cde.{Parameters, Dump}
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore.devices._
 | 
			
		||||
import rocket._
 | 
			
		||||
import rocket.Util._
 | 
			
		||||
import coreplex._
 | 
			
		||||
 | 
			
		||||
class RangeManager {
 | 
			
		||||
  private var finalized = false
 | 
			
		||||
  private val l = collection.mutable.HashMap[String, Int]()
 | 
			
		||||
  def add(name: String, element: Int) = { require(!finalized); l += (name -> element) }
 | 
			
		||||
  def rangeMap = {
 | 
			
		||||
    finalized = true
 | 
			
		||||
    l map {
 | 
			
		||||
      var sum = 0
 | 
			
		||||
      x => { sum += x._2; (x._1 -> (sum-x._2, sum)) }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  def range(name: String) = rangeMap(name)
 | 
			
		||||
  def print = {
 | 
			
		||||
    rangeMap map { case (name, (start, end)) =>
 | 
			
		||||
      println(s"${name} on port ${start}-${end-1}")
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  def sum = {
 | 
			
		||||
    finalized = true
 | 
			
		||||
    l.map(_._2).sum
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ResourceManager[T] {
 | 
			
		||||
  private var finalized = false
 | 
			
		||||
  private val l = collection.mutable.ArrayBuffer[T]()
 | 
			
		||||
  def add(element: T) = { require(!finalized); l += element }
 | 
			
		||||
  def add(list: Seq[T]) = { require(!finalized); l ++= list }
 | 
			
		||||
  def get: Seq[T] = { finalized = true; l }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class GlobalVariable[T] {
 | 
			
		||||
  private var assigned = false
 | 
			
		||||
  private var variable: T = _
 | 
			
		||||
  def assign(value: T) = { require(!assigned); assigned = true; variable = value }
 | 
			
		||||
  def get: T = { require(assigned); variable }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object GenerateGlobalAddrMap {
 | 
			
		||||
  def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry]) = {
 | 
			
		||||
    lazy val intIOAddrMap: AddrMap = {
 | 
			
		||||
      val entries = collection.mutable.ArrayBuffer[AddrMapEntry]()
 | 
			
		||||
      entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX)))
 | 
			
		||||
      entries += AddrMapEntry("bootrom", MemSize(4096, MemAttr(AddrMapProt.RX)))
 | 
			
		||||
      entries += AddrMapEntry("plic", MemRange(0x40000000, 0x4000000, MemAttr(AddrMapProt.RW)))
 | 
			
		||||
      entries += AddrMapEntry("prci", MemSize(0x4000000, MemAttr(AddrMapProt.RW)))
 | 
			
		||||
      if (p(DataScratchpadSize) > 0) { // TODO heterogeneous tiles
 | 
			
		||||
        require(p(NTiles) == 1) // TODO relax this
 | 
			
		||||
        require(p(NMemoryChannels) == 0) // TODO allow both scratchpad & DRAM
 | 
			
		||||
        entries += AddrMapEntry("dmem0", MemRange(0x80000000L, BigInt(p(DataScratchpadSize)), MemAttr(AddrMapProt.RWX)))
 | 
			
		||||
      }
 | 
			
		||||
      new AddrMap(entries)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lazy val extIOAddrMap = new AddrMap(
 | 
			
		||||
      pDevicesEntries ++ p(ExtMMIOPorts),
 | 
			
		||||
      start = BigInt("50000000", 16),
 | 
			
		||||
      collapse = true)
 | 
			
		||||
 | 
			
		||||
    val memBase = 0x80000000L
 | 
			
		||||
    val memSize = p(ExtMemSize)
 | 
			
		||||
    Dump("MEM_BASE", memBase)
 | 
			
		||||
 | 
			
		||||
    val intern = AddrMapEntry("int", intIOAddrMap)
 | 
			
		||||
    val extern = AddrMapEntry("ext", extIOAddrMap)
 | 
			
		||||
    val io = AddrMapEntry("io", AddrMap((intern +: (!extIOAddrMap.isEmpty).option(extern).toSeq):_*))
 | 
			
		||||
    val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true)))
 | 
			
		||||
    AddrMap((io +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object GenerateConfigString {
 | 
			
		||||
  def apply(p: Parameters, c: CoreplexConfig, pDevicesEntries: Seq[AddrMapEntry]) = {
 | 
			
		||||
    val addrMap = p(GlobalAddrMap).get
 | 
			
		||||
    val plicAddr = addrMap("io:int:plic").start
 | 
			
		||||
    val prciAddr = addrMap("io:int:prci").start
 | 
			
		||||
    val xLen = p(XLen)
 | 
			
		||||
    val res = new StringBuilder
 | 
			
		||||
    res append  "plic {\n"
 | 
			
		||||
    res append s"  priority 0x${plicAddr.toString(16)};\n"
 | 
			
		||||
    res append s"  pending 0x${(plicAddr + c.plicKey.pendingBase).toString(16)};\n"
 | 
			
		||||
    res append s"  ndevs ${c.plicKey.nDevices};\n"
 | 
			
		||||
    res append  "};\n"
 | 
			
		||||
    res append  "rtc {\n"
 | 
			
		||||
    res append s"  addr 0x${(prciAddr + PRCI.time).toString(16)};\n"
 | 
			
		||||
    res append  "};\n"
 | 
			
		||||
    if (addrMap contains "mem") {
 | 
			
		||||
      res append  "ram {\n"
 | 
			
		||||
      res append  "  0 {\n"
 | 
			
		||||
      res append s"    addr 0x${addrMap("mem").start.toString(16)};\n"
 | 
			
		||||
      res append s"    size 0x${addrMap("mem").size.toString(16)};\n"
 | 
			
		||||
      res append  "  };\n"
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
    }
 | 
			
		||||
    res append  "core {\n"
 | 
			
		||||
    for (i <- 0 until c.nTiles) { // TODO heterogeneous tiles
 | 
			
		||||
      val isa = {
 | 
			
		||||
        val m = if (p(MulDivKey).nonEmpty) "m" else ""
 | 
			
		||||
        val a = if (p(UseAtomics)) "a" else ""
 | 
			
		||||
        val f = if (p(FPUKey).nonEmpty) "f" else ""
 | 
			
		||||
        val d = if (p(FPUKey).nonEmpty && p(XLen) > 32) "d" else ""
 | 
			
		||||
        val s = if (c.hasSupervisor) "s" else ""
 | 
			
		||||
        s"rv${p(XLen)}i$m$a$f$d$s"
 | 
			
		||||
      }
 | 
			
		||||
      res append s"  $i {\n"
 | 
			
		||||
      res append  "    0 {\n"
 | 
			
		||||
      res append s"      isa $isa;\n"
 | 
			
		||||
      res append s"      timecmp 0x${(prciAddr + PRCI.timecmp(i)).toString(16)};\n"
 | 
			
		||||
      res append s"      ipi 0x${(prciAddr + PRCI.msip(i)).toString(16)};\n"
 | 
			
		||||
      res append s"      plic {\n"
 | 
			
		||||
      res append s"        m {\n"
 | 
			
		||||
      res append s"         ie 0x${(plicAddr + c.plicKey.enableAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
      res append s"         thresh 0x${(plicAddr + c.plicKey.threshAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
      res append s"         claim 0x${(plicAddr + c.plicKey.claimAddr(i, 'M')).toString(16)};\n"
 | 
			
		||||
      res append s"        };\n"
 | 
			
		||||
      if (c.hasSupervisor) {
 | 
			
		||||
        res append s"        s {\n"
 | 
			
		||||
        res append s"         ie 0x${(plicAddr + c.plicKey.enableAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
        res append s"         thresh 0x${(plicAddr + c.plicKey.threshAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
        res append s"         claim 0x${(plicAddr + c.plicKey.claimAddr(i, 'S')).toString(16)};\n"
 | 
			
		||||
        res append s"        };\n"
 | 
			
		||||
      }
 | 
			
		||||
      res append  "      };\n"
 | 
			
		||||
      res append  "    };\n"
 | 
			
		||||
      res append  "  };\n"
 | 
			
		||||
    }
 | 
			
		||||
    res append  "};\n"
 | 
			
		||||
    pDevicesEntries foreach { entry =>
 | 
			
		||||
      val region = addrMap("io:ext:" + entry.name)
 | 
			
		||||
      res append s"${entry.name} {\n"
 | 
			
		||||
      res append s"  addr 0x${region.start.toString(16)};\n"
 | 
			
		||||
      res append s"  size 0x${region.size.toString(16)}; \n"
 | 
			
		||||
      res append  "}\n"
 | 
			
		||||
    }
 | 
			
		||||
    res append '\u0000'
 | 
			
		||||
    res.toString
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -125,8 +125,8 @@ module DebugTransportModuleJtag (
 | 
			
		||||
 | 
			
		||||
   assign idcode  = {JTAG_VERSION, JTAG_PART_NUM, JTAG_MANUF_ID, 1'h1};
 | 
			
		||||
 | 
			
		||||
   wire [3:0]                           debugAddrBits = DEBUG_ADDR_BITS;
 | 
			
		||||
   wire [3:0]                           debugVersion = DEBUG_VERSION;
 | 
			
		||||
   wire [3:0]                           debugAddrBits = DEBUG_ADDR_BITS[3:0];
 | 
			
		||||
   wire [3:0]                           debugVersion = DEBUG_VERSION[3:0];
 | 
			
		||||
   
 | 
			
		||||
   assign dtminfo = {24'b0, debugAddrBits, debugVersion};
 | 
			
		||||
   
 | 
			
		||||
 
 | 
			
		||||
@@ -76,10 +76,6 @@ reg [31:0]	data_in;
 | 
			
		||||
 | 
			
		||||
integer		debug;
 | 
			
		||||
 | 
			
		||||
assign		tms_o = tms;
 | 
			
		||||
assign		tck_o = tck;
 | 
			
		||||
assign		tdi_o = tdi;
 | 
			
		||||
 | 
			
		||||
initial
 | 
			
		||||
begin
 | 
			
		||||
	tck		<= #TP 1'b0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user