From 8cef2ae1354b1be33d01a60140df9c29644ca7d1 Mon Sep 17 00:00:00 2001 From: Richard Yan Date: Fri, 8 Sep 2023 14:25:37 -0700 Subject: [PATCH] integrate vortex as tile --- src/main/resources/csrc/softfloat | 1 + src/main/resources/vsrc/vortex | 1 + src/main/scala/rocket/VortexCore.scala | 224 +++++++++++++++++++++++++ src/main/scala/tile/VortexTile.scala | 217 ++++++++++++++++++++++++ 4 files changed, 443 insertions(+) create mode 120000 src/main/resources/csrc/softfloat create mode 160000 src/main/resources/vsrc/vortex create mode 100644 src/main/scala/rocket/VortexCore.scala create mode 100644 src/main/scala/tile/VortexTile.scala diff --git a/src/main/resources/csrc/softfloat b/src/main/resources/csrc/softfloat new file mode 120000 index 0000000..2d11ed1 --- /dev/null +++ b/src/main/resources/csrc/softfloat @@ -0,0 +1 @@ +../../../../hardfloat/berkeley-softfloat-3/source \ No newline at end of file diff --git a/src/main/resources/vsrc/vortex b/src/main/resources/vsrc/vortex new file mode 160000 index 0000000..2dbc5bf --- /dev/null +++ b/src/main/resources/vsrc/vortex @@ -0,0 +1 @@ +Subproject commit 2dbc5bffcd60edd9bb6a204f0e5ee0e238f9d60c diff --git a/src/main/scala/rocket/VortexCore.scala b/src/main/scala/rocket/VortexCore.scala new file mode 100644 index 0000000..f628cbb --- /dev/null +++ b/src/main/scala/rocket/VortexCore.scala @@ -0,0 +1,224 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package rocket + +import chisel3._ +import chisel3.util._ +import chisel3.experimental._ +import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.tile._ +import freechips.rocketchip.util._ +import freechips.rocketchip.scie._ +import tile.VortexTile + +class Vortex(tile: VortexTile)(implicit p: Parameters) + extends BlackBox with HasBlackBoxResource { + // addResource("/vsrc/vortex/hw/unit_tests/generic_queue/testbench.v") + // addResource("/vsrc/vortex/hw/unit_tests/VX_divide_tb.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_256x19_wm0/rf2_256x19_wm0_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_256x19_wm0/rf2_256x19_wm0.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_32x19_wm0/rf2_32x19_wm0.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_32x19_wm0/rf2_32x19_wm0_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_32x128_wm1/rf2_32x128_wm1_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_32x128_wm1/rf2_32x128_wm1.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_32x128_wm1/vsim/rf2_32x128_wm1_tb.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_256x128_wm1/rf2_256x128_wm1_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_256x128_wm1/rf2_256x128_wm1.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_128x128_wm1/rf2_128x128_wm1.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpm/rf2_128x128_wm1/rf2_128x128_wm1_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpc/rf2_32x128_wm1/rf2_32x128_wm1_rtl.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpc/rf2_32x128_wm1/rf2_32x128_wm1.v") + addResource("/vsrc/vortex/hw/syn/synopsys/models/memory/cln28hpc/rf2_32x128_wm1/vsim/rf2_32x128_wm1_tb.v") + // addResource("/vsrc/vortex/hw/syn/modelsim/vortex_tb.v") + addResource("/vsrc/vortex/hw/rtl/VX_dispatch.sv") + addResource("/vsrc/vortex/hw/rtl/VX_issue.sv") + // addResource("/vsrc/vortex/hw/rtl/cache/VX_shared_mem.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_core_rsp_merge.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_tag_access.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_core_req_bank_sel.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_bank.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_cache.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_data_access.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_cache_define.vh") + addResource("/vsrc/vortex/hw/rtl/cache/VX_flush_ctrl.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_nc_bypass.sv") + addResource("/vsrc/vortex/hw/rtl/cache/VX_miss_resrv.sv") + addResource("/vsrc/vortex/hw/rtl/VX_warp_sched.sv") + // addResource("/vsrc/vortex/hw/rtl/Vortex.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_sat.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_stride.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_lerp.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_addr.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_mem.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_format.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_sampler.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_unit.sv") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_define.vh") + addResource("/vsrc/vortex/hw/rtl/tex_unit/VX_tex_wrap.sv") + addResource("/vsrc/vortex/hw/rtl/VX_scope.vh") + addResource("/vsrc/vortex/hw/rtl/VX_fpu_unit.sv") + addResource("/vsrc/vortex/hw/rtl/VX_scoreboard.sv") + addResource("/vsrc/vortex/hw/rtl/VX_writeback.sv") + addResource("/vsrc/vortex/hw/rtl/VX_muldiv.sv") + addResource("/vsrc/vortex/hw/rtl/VX_decode.sv") + addResource("/vsrc/vortex/hw/rtl/VX_ibuffer.sv") + // addResource("/vsrc/vortex/hw/rtl/VX_cluster.sv") + addResource("/vsrc/vortex/hw/rtl/VX_icache_stage.sv") + addResource("/vsrc/vortex/hw/rtl/VX_gpu_unit.sv") + addResource("/vsrc/vortex/hw/rtl/VX_trace_instr.vh") + addResource("/vsrc/vortex/hw/rtl/VX_gpu_types.vh") + addResource("/vsrc/vortex/hw/rtl/VX_config.vh") + addResource("/vsrc/vortex/hw/rtl/libs/VX_mux.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_lzc.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_fifo_queue.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_scope.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_scan.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_find_first.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_multiplier.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_bits_remove.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_pipe_register.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_onehot_mux.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_priority_encoder.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_reset_relay.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_popcount.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_bits_insert.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_skid_buffer.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_fixed_arbiter.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_shift_register.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_index_buffer.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_onehot_encoder.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_matrix_arbiter.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_divider.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_dp_ram.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_axi_adapter.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_elastic_buffer.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_rr_arbiter.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_stream_arbiter.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_bypass_buffer.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_sp_ram.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_stream_demux.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_pending_size.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_index_queue.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_serial_div.sv") + addResource("/vsrc/vortex/hw/rtl/libs/VX_fair_arbiter.sv") + addResource("/vsrc/vortex/hw/rtl/VX_define.vh") + addResource("/vsrc/vortex/hw/rtl/VX_csr_data.sv") + addResource("/vsrc/vortex/hw/rtl/VX_cache_arb.sv") + addResource("/vsrc/vortex/hw/rtl/VX_ipdom_stack.sv") + addResource("/vsrc/vortex/hw/rtl/VX_gpr_stage.sv") + addResource("/vsrc/vortex/hw/rtl/VX_execute.sv") + addResource("/vsrc/vortex/hw/rtl/VX_fetch.sv") + addResource("/vsrc/vortex/hw/rtl/VX_alu_unit.sv") + addResource("/vsrc/vortex/hw/rtl/VX_mem_arb.sv") + addResource("/vsrc/vortex/hw/rtl/VX_platform.vh") + addResource("/vsrc/vortex/hw/rtl/VX_commit.sv") + addResource("/vsrc/vortex/hw/rtl/VX_smem_arb.sv") + addResource("/vsrc/vortex/hw/rtl/VX_pipeline.sv") + addResource("/vsrc/vortex/hw/rtl/VX_lsu_unit.sv") + // addResource("/vsrc/vortex/hw/rtl/VX_mem_unit.sv") + addResource("/vsrc/vortex/hw/rtl/VX_csr_unit.sv") + // addResource("/vsrc/vortex/hw/rtl/Vortex_axi.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_div.sv") + addResource("/vsrc/vortex/hw/VX_config.h") + addResource("/vsrc/vortex/sim/common/rvfloats.h") + addResource("/vsrc/vortex/sim/common/rvfloats.cpp") + addResource("/csrc/softfloat.a") + addResource("/csrc/softfloat/include/internals.h") + addResource("/csrc/softfloat/include/primitives.h") + addResource("/csrc/softfloat/include/primitiveTypes.h") + addResource("/csrc/softfloat/include/softfloat.h") + addResource("/csrc/softfloat/include/softfloat_types.h") + addResource("/csrc/softfloat/RISCV/specialize.h") + addResource("/vsrc/vortex/hw/dpi/float_dpi.cpp") + addResource("/vsrc/vortex/hw/dpi/float_dpi.vh") + addResource("/vsrc/vortex/hw/dpi/util_dpi.cpp") + addResource("/vsrc/vortex/hw/dpi/util_dpi.vh") + addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fpu_dpi.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_rounding.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/stratix10/dspba_delay_ver.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/stratix10/acl_fsqrt.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/stratix10/acl_fdiv.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/stratix10/acl_fmadd.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/arria10/dspba_delay_ver.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/arria10/acl_fsqrt.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/arria10/acl_fdiv.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/altera/arria10/acl_fmadd.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_class.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fpu_fpnew.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_cvt.sv") + addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fpu_define.vh") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_fma.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_ncomp.sv") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fpu_fpga.sv") + addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fpu_types.vh") + // addResource("/vsrc/vortex/hw/rtl/fp_cores/VX_fp_sqrt.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_icache_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_dcache_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_tex_csr_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_join_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_ifetch_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_perf_cache_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_perf_memsys_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_gpr_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_decode_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_writeback_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_gpu_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_perf_pipeline_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_gpr_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_cmt_to_csr_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_ifetch_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_alu_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_csr_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_ibuffer_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_branch_ctl_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_dcache_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_icache_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_lsu_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_wstall_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_mem_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_fpu_to_csr_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_commit_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_tex_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_warp_ctl_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_tex_rsp_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_fetch_to_csr_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_perf_tex_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_mem_req_if.sv") + addResource("/vsrc/vortex/hw/rtl/interfaces/VX_fpu_req_if.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/vortex_afu.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/ccip_std_afu.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/vortex_afu.vh") + // addResource("/vsrc/vortex/hw/rtl/afu/ccip/local_mem_cfg_pkg.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/ccip/ccip_if_pkg.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/ccip_interface_reg.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/VX_avs_wrapper.sv") + // addResource("/vsrc/vortex/hw/rtl/afu/VX_to_mem.sv") + // addResource("/vsrc/vortex/sim/vlsim/vortex_afu_shim.sv") + addResource("/vsrc/vortex/hw/rtl/VX_pipeline_wrapper.sv") + + + val nTotalRoCCCSRs = 0 + val io = IO(new CoreBundle()(p) { + val clock = Input(Clock()) + val reset = Input(Reset()) + val hartid = Input(UInt(hartIdLen.W)) + val reset_vector = Input(UInt(resetVectorLen.W)) + val interrupts = Input(new CoreInterrupts()) + val imem = new Bundle { + val a = tile.imemNode.out.head._1.a.cloneType + val d = Flipped(tile.imemNode.out.head._1.d.cloneType) + } + val dmem = new Bundle { + val a = tile.dmemNode.out.head._1.a.cloneType + val d = Flipped(tile.dmemNode.out.head._1.d.cloneType) + } + val fpu = Flipped(new FPUCoreIO()) + //val rocc = Flipped(new RoCCCoreIO(nTotalRoCCCSRs)) + //val trace = Output(new TraceBundle) + //val bpwatch = Output(Vec(coreParams.nBreakpoints, new BPWatch(coreParams.retireWidth))) + val cease = Output(Bool()) + val wfi = Output(Bool()) + val traceStall = Input(Bool()) + }) +} diff --git a/src/main/scala/tile/VortexTile.scala b/src/main/scala/tile/VortexTile.scala new file mode 100644 index 0000000..63a4235 --- /dev/null +++ b/src/main/scala/tile/VortexTile.scala @@ -0,0 +1,217 @@ +// See LICENSE.SiFive for license details. +// See LICENSE.Berkeley for license details. + +package tile + +import chisel3._ +import org.chipsalliance.cde.config._ +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.rocket._ +import freechips.rocketchip.subsystem.TileCrossingParamsLike +import freechips.rocketchip.util._ +import freechips.rocketchip.prci.ClockSinkParameters +import freechips.rocketchip.tile._ +import rocket.Vortex + +import scala.collection.mutable.ListBuffer + +case class RocketTileBoundaryBufferParams(force: Boolean = false) + +case class VortexTileParams( + core: RocketCoreParams = RocketCoreParams(), + icache: Option[ICacheParams] = Some(ICacheParams( + nSets = 64, + nWays = 4, + rowBits = 128, + nTLBSets = 1, + nTLBWays = 32, + nTLBBasePageSectors = 4, + nTLBSuperpages = 4, + cacheIdBits = 0, + blockBytes = 64, + latency = 2, + fetchBytes = 4 + )), + dcache: Option[DCacheParams] = Some(DCacheParams( + // TODO + )), + btb: Option[BTBParams] = None, // Some(BTBParams()), + dataScratchpadBytes: Int = 0, + name: Option[String] = Some("vortex_tile"), + hartId: Int = 0, + beuAddr: Option[BigInt] = None, + blockerCtrlAddr: Option[BigInt] = None, + clockSinkParams: ClockSinkParameters = ClockSinkParameters(), + boundaryBuffers: Option[RocketTileBoundaryBufferParams] = None + ) extends InstantiableTileParams[VortexTile] { + require(icache.isDefined) + require(dcache.isDefined) + def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): VortexTile = { + new VortexTile(this, crossing, lookup) + } +} + +class VortexTile private( + val vortexParams: VortexTileParams, + crossing: ClockCrossingType, + lookup: LookupByHartIdImpl, + q: Parameters) + extends BaseTile(vortexParams, crossing, lookup, q) + with SinksExternalInterrupts + with SourcesExternalNotifications +{ + // Private constructor ensures altered LazyModule.p is used implicitly + def this(params: VortexTileParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) = + this(params, crossing.crossingType, lookup, p) + + val intOutwardNode = IntIdentityNode() + val slaveNode = TLIdentityNode() + val masterNode = visibilityNode + + // val dmemDevice = new SimpleDevice("dtim", Seq("sifive,dtim0")) + /*val dmemNode = TLManagerNode(Seq(TLSlavePortParameters.v1( + Seq(TLSlaveParameters.v1( + address = AddressSet.misaligned(tileParams.dcache.get.scratch.getOrElse(0), + tileParams.dcache.get.nSets * tileParams.dcache.get.blockBytes), + resources = dmemDevice.reg("mem"), + regionType = RegionType.IDEMPOTENT, + executable = true, + supportsArithmetic = /*if (usingAtomics) TransferSizes(4, coreDataBytes) else*/ TransferSizes.none, + supportsLogical = /*if (usingAtomics) TransferSizes(4, coreDataBytes) else*/ TransferSizes.none, + supportsPutPartial = TransferSizes(1, lazyCoreParamsView.coreDataBytes), + supportsPutFull = TransferSizes(1, lazyCoreParamsView.coreDataBytes), + supportsGet = TransferSizes(1, lazyCoreParamsView.coreDataBytes), + fifoId = Some(0))), // requests handled in FIFO order + beatBytes = lazyCoreParamsView.coreDataBytes, + minLatency = 1)))*/ + + val imemNode = TLClientNode(Seq(TLMasterPortParameters.v1( + clients = Seq(TLMasterParameters.v1( + sourceId = IdRange(0, 1 << 8), // TODO magic number + name = s"Vortex Core I-Mem" + )) + ))) + + val dmemNode = TLClientNode(Seq(TLMasterPortParameters.v1( + clients = Seq(TLMasterParameters.v1( + sourceId = IdRange(0, 1 << 8), // TODO magic number + name = s"Vortex Core D-Mem" + )) + ))) + + tlMasterXbar.node := imemNode + tlMasterXbar.node := dmemNode + + val bus_error_unit = vortexParams.beuAddr map { a => + val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a))) + intOutwardNode := beu.intNode + connectTLSlave(beu.node, xBytes) + beu + } + + val tile_master_blocker = + tileParams.blockerCtrlAddr + .map(BasicBusBlockerParams(_, xBytes, masterPortBeatBytes, deadlock = true)) + .map(bp => LazyModule(new BasicBusBlocker(bp))) + + tile_master_blocker.foreach(lm => connectTLSlave(lm.controlNode, xBytes)) + + // TODO: this doesn't block other masters, e.g. RoCCs + tlOtherMastersNode := tile_master_blocker.map { _.node := tlMasterXbar.node } getOrElse { tlMasterXbar.node } + masterNode :=* tlOtherMastersNode + DisableMonitors { implicit p => tlSlaveXbar.node :*= slaveNode } + + val dtimProperty = Nil //Seq(dmemDevice.asProperty).flatMap(p => Map("sifive,dtim" -> p)) + + val itimProperty = Nil //frontend.icache.itimProperty.toSeq.flatMap(p => Map("sifive,itim" -> p)) + + val beuProperty = bus_error_unit.map(d => Map( + "sifive,buserror" -> d.device.asProperty)).getOrElse(Nil) + + val cpuDevice: SimpleDevice = new SimpleDevice("cpu", Seq("sifive,vortex0", "riscv")) { + override def parent = Some(ResourceAnchors.cpus) + override def describe(resources: ResourceBindings): Description = { + val Description(name, mapping) = super.describe(resources) + Description(name, mapping ++ cpuProperties ++ nextLevelCacheProperty + ++ tileProperties ++ dtimProperty ++ itimProperty ++ beuProperty) + } + } + + ResourceBinding { + Resource(cpuDevice, "reg").bind(ResourceAddress(staticIdForMetadataUseOnly)) + } + + override lazy val module = new VortexTileModuleImp(this) + + override def makeMasterBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = (vortexParams.boundaryBuffers, crossing) match { + case (Some(RocketTileBoundaryBufferParams(true )), _) => TLBuffer() + case (Some(RocketTileBoundaryBufferParams(false)), _: RationalCrossing) => TLBuffer(BufferParams.none, BufferParams.flow, BufferParams.none, BufferParams.flow, BufferParams(1)) + case _ => TLBuffer(BufferParams.none) + } + + override def makeSlaveBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = (vortexParams.boundaryBuffers, crossing) match { + case (Some(RocketTileBoundaryBufferParams(true )), _) => TLBuffer() + case (Some(RocketTileBoundaryBufferParams(false)), _: RationalCrossing) => TLBuffer(BufferParams.flow, BufferParams.none, BufferParams.none, BufferParams.none, BufferParams.none) + case _ => TLBuffer(BufferParams.none) + } +} + +class VortexTileModuleImp(outer: VortexTile) extends BaseTileModuleImp(outer) { + Annotated.params(this, outer.vortexParams) + + val core = Module(new Vortex(outer)(outer.p)) + + core.io.clock := clock + core.io.reset := reset + + // reset vector is connected in the Frontend to s2_pc + core.io.reset_vector := DontCare + + // Report when the tile has ceased to retire instructions; for now the only cause is clock gating + outer.reportCease(outer.vortexParams.core.clockGate.option( + core.io.cease)) + + outer.reportWFI(Some(core.io.wfi)) + + outer.decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector + + outer.bus_error_unit.foreach { beu => + core.io.interrupts.buserror.get := beu.module.io.interrupt + } + + core.io.interrupts.nmi.foreach { nmi => nmi := outer.nmiSinkNode.bundle } + + // Pass through various external constants and reports that were bundle-bridged into the tile + // outer.traceSourceNode.bundle <> core.io.trace + core.io.traceStall := outer.traceAuxSinkNode.bundle.stall + // outer.bpwatchSourceNode.bundle <> core.io.bpwatch + core.io.hartid := outer.hartIdSinkNode.bundle + require(core.io.hartid.getWidth >= outer.hartIdSinkNode.bundle.getWidth, + s"core hartid wire (${core.io.hartid.getWidth}b) truncates external hartid wire (${outer.hartIdSinkNode.bundle.getWidth}b)") + + val (i_tl_out, _) = outer.imemNode.out.head + val (d_tl_out, _) = outer.dmemNode.out.head + + core.io.imem.a <> i_tl_out.a + core.io.imem.d <> i_tl_out.d + core.io.dmem.a <> d_tl_out.a + core.io.dmem.d <> d_tl_out.d + + core.io.fpu := DontCare + + // TODO eliminate this redundancy + // val h = dcachePorts.size + //val c = core.dcacheArbPorts + // val o = outer.nDCachePorts + // require(h == c, s"port list size was $h, core expected $c") + // require(h == o, s"port list size was $h, outer counted $o") + // TODO figure out how to move the below into their respective mix-ins + // dcacheArb.io.requestor <> dcachePorts.toSeq +} + +trait HasFpuOpt { this: RocketTileModuleImp => + val fpuOpt = outer.tileParams.core.fpu.map(params => Module(new FPU(params)(outer.p))) +}