From 2c000a99da986759232c63c48188b03f319df81e Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Thu, 8 Sep 2016 02:08:57 -0700 Subject: [PATCH 01/12] compartmentalize Top into periphery traits --- src/main/scala/rocketchip/Configs.scala | 1 - src/main/scala/rocketchip/Periphery.scala | 276 ++++++++++++++++++ src/main/scala/rocketchip/RocketChip.scala | 307 -------------------- src/main/scala/rocketchip/TestHarness.scala | 3 +- src/main/scala/rocketchip/Top.scala | 51 ++++ 5 files changed, 328 insertions(+), 310 deletions(-) create mode 100644 src/main/scala/rocketchip/Periphery.scala delete mode 100644 src/main/scala/rocketchip/RocketChip.scala create mode 100644 src/main/scala/rocketchip/Top.scala diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 68681874..9d8e83d8 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -165,7 +165,6 @@ class BasePlatformConfig extends Config ( 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 }}) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala new file mode 100644 index 00000000..3e7eab1d --- /dev/null +++ b/src/main/scala/rocketchip/Periphery.scala @@ -0,0 +1,276 @@ +// 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]] +/** 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 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 PeripheryInterrupt extends LazyModule { + implicit val p: Parameters +} + +trait PeripheryInterruptBundle { + implicit val p: Parameters + val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput +} + +trait PeripheryInterruptModule { + implicit val p: Parameters + val outer: PeripheryInterrupt + val io: PeripheryInterruptBundle + val coreplex: Coreplex + + val interrupts_periphery = Vec(p(NExtPeripheryInterrupts), Bool()) + var interrupts_cnt = 0 + + // This places the Periphery Interrupts at Bits [0...] + // External 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 <> (interrupts_periphery ++ io.interrupts) +} + +///// + +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.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.mem) foreach { case (ahb, mem) => + ahb <> PeripheryUtils.convertTLtoAHB(mem, atomics = false)(outermostParams) + } + + (io.mem_tl zip coreplex.io.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 +} + +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 + coreplex.io.ext_clients.head <> conv.io.tl + require(p(NExternalClients) == 1, "external devices can't slave ports. wait for tilelink2!") + } +} diff --git a/src/main/scala/rocketchip/RocketChip.scala b/src/main/scala/rocketchip/RocketChip.scala deleted file mode 100644 index 4efb143f..00000000 --- a/src/main/scala/rocketchip/RocketChip.scala +++ /dev/null @@ -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) - } -} diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index 7d91c3c6..0d014800 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -11,7 +11,7 @@ class TestHarness(implicit p: Parameters) extends Module { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = Module(new Top(p)) + val dut = uncore.tilelink2.LazyModule(new ExampleTop(p)).module // This test harness isn't especially flexible yet require(dut.io.mem_clk.isEmpty) @@ -24,7 +24,6 @@ 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 diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala new file mode 100644 index 00000000..28192a5c --- /dev/null +++ b/src/main/scala/rocketchip/Top.scala @@ -0,0 +1,51 @@ +// See LICENSE for license details. + +package rocketchip + +import Chisel._ +import cde.{Parameters} +import junctions._ +import uncore.tilelink._ +import uncore.tilelink2.{LazyModule, LazyModuleImp} +import rocket.Util._ +import coreplex._ + + +/** Base Top with no Periphery */ + +abstract class BaseTop(val p: Parameters) extends LazyModule + +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 coreplex = p(BuildCoreplex)(p) + val outer: L = l + 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 = p(ExportMMIOPort).option( + Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).subMap("io:ext"))( + p.alterPartial({ case TLId => "L2toMMIO" })))) + mmioNetwork.foreach { _.io.in.head <> coreplex.io.mmio.get } +} + + +/** Example Top with Periphery */ + +class ExampleTop(p: Parameters) extends BaseTop(p) + with PeripheryDebug with PeripheryInterrupt + with PeripheryMasterMem with PeripheryMasterMMIO with PeripherySlave { + lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, _))) +} + +class ExampleTopBundle(p: Parameters, c: Coreplex) extends BaseTopBundle(p, c) + with PeripheryDebugBundle with PeripheryInterruptBundle + 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 PeripheryInterruptModule + with PeripheryMasterMemModule with PeripheryMasterMMIOModule with PeripherySlaveModule From bb3f514e8db4fc00b434c3584bad81e7f7f56796 Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Sat, 10 Sep 2016 23:39:29 -0700 Subject: [PATCH 02/12] now able to add periphery devices through traits Unfortunately, I had to touch a lot of code, which weren't quite possible to split up into multiple commits. This commit gets rid of the "extra" infrastructure to add periphery devices into Top. --- src/main/scala/coreplex/Configs.scala | 7 +- src/main/scala/coreplex/Coreplex.scala | 87 +++---- .../scala/coreplex/DirectGroundTest.scala | 63 ----- src/main/scala/coreplex/TestConfigs.scala | 11 +- src/main/scala/coreplex/UnitTest.scala | 6 +- src/main/scala/groundtest/TraceGen.scala | 4 +- src/main/scala/junctions/addrmap.scala | 3 +- src/main/scala/rocketchip/Configs.scala | 229 +++++------------- src/main/scala/rocketchip/Devices.scala | 68 ------ src/main/scala/rocketchip/Generator.scala | 2 +- src/main/scala/rocketchip/Periphery.scala | 107 ++++++-- src/main/scala/rocketchip/TestConfigs.scala | 68 +----- src/main/scala/rocketchip/TestHarness.scala | 8 +- src/main/scala/rocketchip/Top.scala | 74 ++++-- src/main/scala/rocketchip/Utils.scala | 149 ++++++++++++ 15 files changed, 414 insertions(+), 472 deletions(-) delete mode 100644 src/main/scala/coreplex/DirectGroundTest.scala delete mode 100644 src/main/scala/rocketchip/Devices.scala create mode 100644 src/main/scala/rocketchip/Utils.scala diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 2edddade..129df866 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -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._ @@ -127,7 +128,6 @@ class BaseCoreplexConfig extends Config ( case MulDivKey => Some(MulDivConfig(mulUnroll = 8, mulEarlyOut = true, 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 +145,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 +176,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 +194,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", diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index d4b47cf7..0f882603 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -14,6 +14,8 @@ import rocket.Util._ import java.nio.{ByteBuffer,ByteOrder} import java.nio.file.{Files, Paths} +/** Function for building Coreplex */ +case object BuildCoreplex extends Field[(Parameters, CoreplexConfig) => Coreplex] /** Number of memory channels */ case object NMemoryChannels extends Field[Int] /** Number of banks per memory channel */ @@ -24,24 +26,11 @@ 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 @@ -49,20 +38,31 @@ trait HasCoreplexParameters { 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, + 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(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 +70,16 @@ 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(_ + _) - printConfigString + // Build an uncore backing the Tiles buildUncore(p.alterPartial({ case HastiId => "TL" case TLId => "L1toL2" @@ -87,25 +87,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,7 +112,7 @@ 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 @@ -138,7 +126,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 +139,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 +150,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 +182,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(_&&_) } diff --git a/src/main/scala/coreplex/DirectGroundTest.scala b/src/main/scala/coreplex/DirectGroundTest.scala deleted file mode 100644 index 98880f15..00000000 --- a/src/main/scala/coreplex/DirectGroundTest.scala +++ /dev/null @@ -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 -} diff --git a/src/main/scala/coreplex/TestConfigs.scala b/src/main/scala/coreplex/TestConfigs.scala index 9c291a4c..3f435478 100644 --- a/src/main/scala/coreplex/TestConfigs.scala +++ b/src/main/scala/coreplex/TestConfigs.scala @@ -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)) diff --git a/src/main/scala/coreplex/UnitTest.scala b/src/main/scala/coreplex/UnitTest.scala index 8451a8cb..66b2e0e3 100644 --- a/src/main/scala/coreplex/UnitTest.scala +++ b/src/main/scala/coreplex/UnitTest.scala @@ -6,9 +6,9 @@ import rocket.Tile import uncore.tilelink.TLId import cde.Parameters -class UnitTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) { - require(!exportMMIO) - require(nExtClients == 0) +class UnitTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) { + require(!tc.hasExtMMIOPort) + require(tc.nSlaves == 0) require(nMemChannels == 0) io.debug.req.ready := Bool(false) diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala index d8888304..140424a6 100644 --- a/src/main/scala/groundtest/TraceGen.scala +++ b/src/main/scala/groundtest/TraceGen.scala @@ -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)) diff --git a/src/main/scala/junctions/addrmap.scala b/src/main/scala/junctions/addrmap.scala index aae062b4..b3f1722a 100644 --- a/src/main/scala/junctions/addrmap.scala +++ b/src/main/scala/junctions/addrmap.scala @@ -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) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 9d8e83d8..2068e1e1 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -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,156 +18,66 @@ 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 _ => 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 _ => throw new CDEMatchError - }}) + }) class BaseConfig extends Config(new BaseCoreplexConfig ++ new BasePlatformConfig) class DefaultConfig extends Config(new WithBlockingL1 ++ new BaseConfig) @@ -178,7 +89,6 @@ class DefaultBufferlessConfig extends Config( class FPGAConfig extends Config ( (pname,site,here) => pname match { case NAcquireTransactors => 4 - case ExportGroundTestStatus => true case _ => throw new CDEMatchError } ) @@ -269,35 +179,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 diff --git a/src/main/scala/rocketchip/Devices.scala b/src/main/scala/rocketchip/Devices.scala deleted file mode 100644 index c86e2813..00000000 --- a/src/main/scala/rocketchip/Devices.scala +++ /dev/null @@ -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) {} -} diff --git a/src/main/scala/rocketchip/Generator.scala b/src/main/scala/rocketchip/Generator.scala index 390ac353..ec0d6a39 100644 --- a/src/main/scala/rocketchip/Generator.scala +++ b/src/main/scala/rocketchip/Generator.scala @@ -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 } diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 3e7eab1d..50fa150f 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -37,17 +37,10 @@ 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 - **/ +/** Specifies the number of external interrupts */ 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 RTCPeriod extends Field[Int] @@ -122,29 +115,30 @@ trait PeripheryDebugModule { ///// -trait PeripheryInterrupt extends LazyModule { +trait PeripheryExtInterrupts extends LazyModule { implicit val p: Parameters + val pInterrupts: RangeManager + + pInterrupts.add("ext", p(NExtTopInterrupts)) } -trait PeripheryInterruptBundle { +trait PeripheryExtInterruptsBundle { implicit val p: Parameters val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput } -trait PeripheryInterruptModule { +trait PeripheryExtInterruptsModule { implicit val p: Parameters - val outer: PeripheryInterrupt - val io: PeripheryInterruptBundle + val outer: PeripheryExtInterrupts + val io: PeripheryExtInterruptsBundle val coreplex: Coreplex - val interrupts_periphery = Vec(p(NExtPeripheryInterrupts), Bool()) - var interrupts_cnt = 0 - - // This places the Periphery Interrupts at Bits [0...] - // External 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 <> (interrupts_periphery ++ io.interrupts) + { + val r = outer.pInterrupts.range("ext") + ((r._1 until r._2) zipWithIndex) foreach { case (c, i) => + coreplex.io.interrupts(c) := io.interrupts(i) + } + } } ///// @@ -169,7 +163,7 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { val coreplex: Coreplex // Abuse the fact that zip takes the shorter of the two lists - ((io.mem_axi zip coreplex.io.mem) zipWithIndex) foreach { case ((axi, mem), idx) => + ((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") @@ -179,11 +173,11 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { ) } - (io.mem_ahb zip coreplex.io.mem) foreach { case (ahb, mem) => + (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.mem) foreach { case (tl, mem) => + (io.mem_tl zip coreplex.io.master.mem) foreach { case (tl, mem) => tl <> ClientUncachedTileLinkEnqueuer(mem, 2)(outermostParams) } } @@ -245,6 +239,9 @@ trait PeripheryMasterMMIOModule extends HasPeripheryParameters { 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 { @@ -270,7 +267,65 @@ trait PeripherySlaveModule extends HasPeripheryParameters { } val conv = Module(new TileLinkIONastiIOConverter()(innerParams)) conv.io.nasti <> arb.io.slave - coreplex.io.ext_clients.head <> conv.io.tl - require(p(NExternalClients) == 1, "external devices can't slave ports. wait for tilelink2!") + + 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 } } diff --git a/src/main/scala/rocketchip/TestConfigs.scala b/src/main/scala/rocketchip/TestConfigs.scala index 368bb77a..6f1c7b05 100644 --- a/src/main/scala/rocketchip/TestConfigs.scala +++ b/src/main/scala/rocketchip/TestConfigs.scala @@ -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) diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index 0d014800..bb69e697 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -7,11 +7,13 @@ import cde.{Parameters, Field} import rocket.Util._ import junctions._ -class TestHarness(implicit p: Parameters) extends Module { +case object BuildExampleTop extends Field[Parameters => ExampleTop] + +class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapParameters { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = uncore.tilelink2.LazyModule(new ExampleTop(p)).module + val dut = p(BuildExampleTop)(p).module // This test harness isn't especially flexible yet require(dut.io.mem_clk.isEmpty) @@ -29,7 +31,7 @@ class TestHarness(implicit p: Parameters) extends Module { 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 diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index 28192a5c..efdff602 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -3,49 +3,93 @@ package rocketchip import Chisel._ -import cde.{Parameters} +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]] /** Base Top with no Periphery */ - -abstract class BaseTop(val p: Parameters) extends LazyModule +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 coreplex = p(BuildCoreplex)(p) +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, + hasSupervisor = p(UseVM), + hasExtMMIOPort = !(outer.pDevices.get.isEmpty && p(ExtMMIOPorts).isEmpty) + ) + + p(NCoreplexExtClients).assign(outer.pBusMasters.sum) + p(GlobalAddrMap).assign(GenerateGlobalAddrMap(p, outer.pDevices.get)) + p(ConfigString).assign(GenerateConfigString(p, c, outer.pDevices.get)) + + 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 = p(ExportMMIOPort).option( - Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).subMap("io:ext"))( + 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.mmio.get } + mmioNetwork.foreach { _.io.in.head <> coreplex.io.master.mmio.get } } - /** Example Top with Periphery */ - class ExampleTop(p: Parameters) extends BaseTop(p) - with PeripheryDebug with PeripheryInterrupt + with PeripheryDebug with PeripheryExtInterrupts with PeripheryMasterMem with PeripheryMasterMMIO with PeripherySlave { - lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, _))) + 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 PeripheryInterruptBundle + 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 PeripheryInterruptModule +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 diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala new file mode 100644 index 00000000..1f4765a2 --- /dev/null +++ b/src/main/scala/rocketchip/Utils.scala @@ -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 + } +} From fea31c7061b52862bdcd326124291a9ee5ef206f Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Sat, 10 Sep 2016 23:39:44 -0700 Subject: [PATCH 03/12] let GlobalAddrMap and ConfigString overridable --- src/main/scala/rocketchip/Top.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index efdff602..daa6a5ea 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -40,9 +40,12 @@ class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, 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(GenerateGlobalAddrMap(p, outer.pDevices.get)) - p(ConfigString).assign(GenerateConfigString(p, c, outer.pDevices.get)) + p(GlobalAddrMap).assign(genGlobalAddrMap) + p(ConfigString).assign(genConfigString) println("Generated Address Map") for (entry <- p(GlobalAddrMap).get.flatten) { From 9d9f90646d9f3898375a1d1a052aaf132f83d711 Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Fri, 9 Sep 2016 15:12:05 -0700 Subject: [PATCH 04/12] allow configuration of simulation memory latency --- src/main/scala/rocketchip/Configs.scala | 1 + src/main/scala/rocketchip/TestHarness.scala | 29 ++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 2068e1e1..37ad9047 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -74,6 +74,7 @@ class BasePlatformConfig extends Config( 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 } } diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index bb69e697..15fe6c7c 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -8,6 +8,7 @@ import rocket.Util._ import junctions._ 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 { @@ -33,8 +34,14 @@ class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapPara if (dut.io.mem_axi.nonEmpty) { 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)) { @@ -65,7 +72,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapPara } -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 } @@ -82,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)) @@ -102,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 @@ -114,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) } @@ -167,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) +} From f3cdeb08c6009cedc102322d3810d9160c3fd7a3 Mon Sep 17 00:00:00 2001 From: Howard Mao Date: Mon, 12 Sep 2016 12:40:10 -0700 Subject: [PATCH 05/12] pass nMemChannels to coreplex through CoreplexConfig --- src/main/scala/coreplex/Coreplex.scala | 10 ++++------ src/main/scala/coreplex/UnitTest.scala | 2 +- src/main/scala/rocketchip/Top.scala | 3 +++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 0f882603..70d1343b 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -14,8 +14,6 @@ import rocket.Util._ import java.nio.{ByteBuffer,ByteOrder} import java.nio.file.{Files, Paths} -/** Function for building Coreplex */ -case object BuildCoreplex extends Field[(Parameters, CoreplexConfig) => Coreplex] /** Number of memory channels */ case object NMemoryChannels extends Field[Int] /** Number of banks per memory channel */ @@ -31,9 +29,7 @@ case object BootROMFile extends Field[String] trait HasCoreplexParameters { implicit val p: Parameters - 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" }) @@ -46,6 +42,7 @@ case class CoreplexConfig( nTiles: Int, nExtInterrupts: Int, nSlaves: Int, + nMemChannels: Int, hasSupervisor: Boolean, hasExtMMIOPort: Boolean) { @@ -56,7 +53,7 @@ abstract class Coreplex(implicit val p: Parameters, implicit val c: CoreplexConf with HasCoreplexParameters { class CoreplexIO(implicit val p: Parameters, implicit val c: CoreplexConfig) extends Bundle { val master = new Bundle { - val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams)) + 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 @@ -78,6 +75,7 @@ class DefaultCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, } 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 // Build an uncore backing the Tiles buildUncore(p.alterPartial({ @@ -116,7 +114,7 @@ class DefaultCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, 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) diff --git a/src/main/scala/coreplex/UnitTest.scala b/src/main/scala/coreplex/UnitTest.scala index 66b2e0e3..0e91d697 100644 --- a/src/main/scala/coreplex/UnitTest.scala +++ b/src/main/scala/coreplex/UnitTest.scala @@ -9,7 +9,7 @@ import cde.Parameters class UnitTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) { require(!tc.hasExtMMIOPort) require(tc.nSlaves == 0) - require(nMemChannels == 0) + require(tc.nMemChannels == 0) io.debug.req.ready := Bool(false) io.debug.resp.valid := Bool(false) diff --git a/src/main/scala/rocketchip/Top.scala b/src/main/scala/rocketchip/Top.scala index daa6a5ea..1e031ee1 100644 --- a/src/main/scala/rocketchip/Top.scala +++ b/src/main/scala/rocketchip/Top.scala @@ -16,6 +16,8 @@ import coreplex._ 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 { @@ -36,6 +38,7 @@ class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle](val p: Parameters, l: L, 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) ) From beb141a20b67aa40dd52c2ca3abf8c6dedbdcff6 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 12 Sep 2016 12:00:04 -0700 Subject: [PATCH 06/12] Allow M, A, D, C extensions to be disabled in misa register --- src/main/scala/rocket/csr.scala | 37 ++- src/main/scala/rocket/idecode.scala | 377 ++++++++++++++-------------- src/main/scala/rocket/rocket.scala | 10 +- 3 files changed, 221 insertions(+), 203 deletions(-) diff --git a/src/main/scala/rocket/csr.scala b/src/main/scala/rocket/csr.scala index adba031f..e75edb47 100644 --- a/src/main/scala/rocket/csr.scala +++ b/src/main/scala/rocket/csr.scala @@ -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(_|_) } diff --git a/src/main/scala/rocket/idecode.scala b/src/main/scala/rocket/idecode.scala index 2d186b2c..b58ba86d 100644 --- a/src/main/scala/rocket/idecode.scala +++ b/src/main/scala/rocket/idecode.scala @@ -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)) } diff --git a/src/main/scala/rocket/rocket.scala b/src/main/scala/rocket/rocket.scala index 47f33244..d02e683e 100644 --- a/src/main/scala/rocket/rocket.scala +++ b/src/main/scala/rocket/rocket.scala @@ -241,8 +241,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) @@ -385,7 +389,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) { 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 From 96185e4b1606c5a9770edeb7ba36abfdad89d8c6 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 12 Sep 2016 12:01:04 -0700 Subject: [PATCH 07/12] tighten an assert condition dcache.s1_kill is a don't-care if dcache.req.valid wasn't previously high --- src/main/scala/rocket/rocket.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/rocket.scala b/src/main/scala/rocket/rocket.scala index d02e683e..9dfbe977 100644 --- a/src/main/scala/rocket/rocket.scala +++ b/src/main/scala/rocket/rocket.scala @@ -632,7 +632,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 } From 266a2f24bd5825d415b9624db11699cf477dd6f9 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 12 Sep 2016 16:50:08 -0700 Subject: [PATCH 08/12] Disable Mul early out by default if XLen == 32 With a default unroll of 8, it doesn't help performance, but costs area. --- src/main/scala/coreplex/Configs.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 129df866..8fc63706 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -125,7 +125,7 @@ class BaseCoreplexConfig extends Config ( case FastLoadByte => 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 DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen)) From 88440ebf89625bab300c5a2a02aba6a14723470e Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 12 Sep 2016 16:52:03 -0700 Subject: [PATCH 09/12] Use PseudoLRU in BTB when possible (for powers of two) --- src/main/scala/rocket/btb.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/scala/rocket/btb.scala b/src/main/scala/rocket/btb.scala index 2f305850..26e805d3 100644 --- a/src/main/scala/rocket/btb.scala +++ b/src/main/scala/rocket/btb.scala @@ -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 From a10d058e1a2dd98a9ab6ecf62d1b92018cab4212 Mon Sep 17 00:00:00 2001 From: Colin Schmidt Date: Mon, 12 Sep 2016 18:25:35 -0700 Subject: [PATCH 10/12] fix warnings in verilog source (#274) --- vsrc/DebugTransportModuleJtag.v | 4 ++-- vsrc/jtag_vpi.v | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/vsrc/DebugTransportModuleJtag.v b/vsrc/DebugTransportModuleJtag.v index 0c8a07b0..7c9b81c7 100755 --- a/vsrc/DebugTransportModuleJtag.v +++ b/vsrc/DebugTransportModuleJtag.v @@ -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}; diff --git a/vsrc/jtag_vpi.v b/vsrc/jtag_vpi.v index c7eb55d7..50afac9b 100644 --- a/vsrc/jtag_vpi.v +++ b/vsrc/jtag_vpi.v @@ -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; From 2979badf75badef2c1305cc1122b056dc9a60ff0 Mon Sep 17 00:00:00 2001 From: roman3017 Date: Sun, 11 Sep 2016 18:26:56 -0700 Subject: [PATCH 11/12] Update README.md Fixed path to Configs.scala --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f784d648..ba690fcb 100644 --- a/README.md +++ b/README.md @@ -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 From 61cbe6164d9a10a661884938740d4cd5520548c8 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 13 Sep 2016 02:32:00 -0700 Subject: [PATCH 12/12] Add option to execute JAL from decode stage This is particularly helpful for designs that don't have a BTB, but it becomes the critical path for designs with RVC. Caveat emptor. --- src/main/scala/coreplex/Configs.scala | 1 + src/main/scala/rocket/rocket.scala | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 8fc63706..2594cdf6 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -123,6 +123,7 @@ 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 = (site(XLen) > 32), divEarlyOut = true)) diff --git a/src/main/scala/rocket/rocket.scala b/src/main/scala/rocket/rocket.scala index 9dfbe977..0992b83e 100644 --- a/src/main/scala/rocket/rocket.scala +++ b/src/main/scala/rocket/rocket.scala @@ -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 @@ -385,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 = !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 @@ -576,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")