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