dual core gemmini, unpeg gemmini size and smem width
This commit is contained in:
@@ -26,7 +26,6 @@ EXTRA_SIM_PREPROC_DEFINES += \
|
|||||||
+define+GBAR_ENABLE \
|
+define+GBAR_ENABLE \
|
||||||
+define+GBAR_CLUSTER_ENABLE \
|
+define+GBAR_CLUSTER_ENABLE \
|
||||||
+define+NUM_FPU_BLOCKS=2 \
|
+define+NUM_FPU_BLOCKS=2 \
|
||||||
+define+EXT_T_DISABLE \
|
|
||||||
+define+FPU_FPNEW \
|
+define+FPU_FPNEW \
|
||||||
+define+SMEM_LOG_SIZE=17
|
+define+SMEM_LOG_SIZE=17
|
||||||
|
|
||||||
|
|||||||
Submodule src/main/resources/vsrc/vortex updated: a47389fc0e...1833e8a176
@@ -49,7 +49,7 @@ class StallingPipe[T <: Data](val gen: T, val latency: Int = 1) extends Module {
|
|||||||
* names. Includes the latency cycle count in the name as well as the
|
* names. Includes the latency cycle count in the name as well as the
|
||||||
* parameterized generator's `typeName`, e.g. `Pipe4_UInt4`
|
* parameterized generator's `typeName`, e.g. `Pipe4_UInt4`
|
||||||
*/
|
*/
|
||||||
override def desiredName = s"${simpleClassName(this.getClass)}${latency}_${gen.typeName}"
|
// override def desiredName = s"${simpleClassName(this.getClass)}${latency}_${gen.typeName}"
|
||||||
|
|
||||||
class StallingPipeIO extends Bundle {
|
class StallingPipeIO extends Bundle {
|
||||||
val stall = Input(Bool())
|
val stall = Input(Bool())
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
package radiance.subsystem
|
package radiance.subsystem
|
||||||
|
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
import freechips.rocketchip.diplomacy.BigIntHexContext
|
|
||||||
import org.chipsalliance.cde.config._
|
import org.chipsalliance.cde.config._
|
||||||
import freechips.rocketchip.rocket._
|
import freechips.rocketchip.rocket._
|
||||||
import freechips.rocketchip.tile._
|
import freechips.rocketchip.tile._
|
||||||
@@ -24,10 +23,6 @@ case class RadianceSharedMemKey(address: BigInt,
|
|||||||
serializeUnaligned: Boolean = true)
|
serializeUnaligned: Boolean = true)
|
||||||
case object RadianceSharedMemKey extends Field[Option[RadianceSharedMemKey]](None)
|
case object RadianceSharedMemKey extends Field[Option[RadianceSharedMemKey]](None)
|
||||||
|
|
||||||
case class RadianceGemminiKey(tileSize: Int,
|
|
||||||
slaveAddress: BigInt)
|
|
||||||
case object RadianceGemminiKey extends Field[Option[RadianceGemminiKey]](None)
|
|
||||||
|
|
||||||
case class RadianceFrameBufferKey(baseAddress: BigInt,
|
case class RadianceFrameBufferKey(baseAddress: BigInt,
|
||||||
width: Int,
|
width: Int,
|
||||||
size: Int,
|
size: Int,
|
||||||
@@ -92,38 +87,40 @@ class WithRadianceGemmini(location: HierarchicalLocation,
|
|||||||
if (idOffset == 0) {
|
if (idOffset == 0) {
|
||||||
println("******WARNING****** gemmini tile id is 0! radiance tiles in the same cluster needs to be before gemmini")
|
println("******WARNING****** gemmini tile id is 0! radiance tiles in the same cluster needs to be before gemmini")
|
||||||
}
|
}
|
||||||
|
val numPrevGemminis = prev.map(_.tileParams).map {
|
||||||
|
case _: GemminiTileParams => 1
|
||||||
|
case _ => 0
|
||||||
|
}.sum
|
||||||
val smKey = site(RadianceSharedMemKey).get
|
val smKey = site(RadianceSharedMemKey).get
|
||||||
val gemmini = GemminiTileParams(gemminiConfig = GemminiFPConfigs.FP32DefaultConfig.copy(
|
val tileParams = GemminiTileParams(
|
||||||
has_training_convs = false,
|
gemminiConfig = GemminiFPConfigs.FP32DefaultConfig.copy(
|
||||||
has_max_pool = false,
|
has_training_convs = false,
|
||||||
use_tl_ext_mem = true,
|
has_max_pool = false,
|
||||||
sp_singleported = false,
|
use_tl_ext_mem = true,
|
||||||
spad_read_delay = 4,
|
sp_singleported = false,
|
||||||
use_shared_ext_mem = true,
|
spad_read_delay = 4,
|
||||||
acc_sub_banks = 1,
|
use_shared_ext_mem = true,
|
||||||
has_normalizations = false,
|
acc_sub_banks = 1,
|
||||||
meshRows = dim,
|
has_normalizations = false,
|
||||||
meshColumns = dim,
|
meshRows = dim,
|
||||||
tile_latency = 0,
|
meshColumns = dim,
|
||||||
dma_maxbytes = site(CacheBlockBytes),
|
tile_latency = 0,
|
||||||
dma_buswidth = dim * 32,
|
dma_maxbytes = site(CacheBlockBytes),
|
||||||
tl_ext_mem_base = smKey.address,
|
dma_buswidth = dim * 32,
|
||||||
sp_banks = smKey.numBanks,
|
tl_ext_mem_base = smKey.address,
|
||||||
sp_capacity = CapacityInKilobytes(smKey.size >> 10),
|
sp_banks = smKey.numBanks,
|
||||||
acc_capacity = CapacityInKilobytes(accSizeInKB),
|
sp_capacity = CapacityInKilobytes(smKey.size >> 10),
|
||||||
))
|
acc_capacity = CapacityInKilobytes(accSizeInKB),
|
||||||
List.tabulate(1)(i => GemminiTileAttachParams(
|
),
|
||||||
gemmini.copy(tileId = i + idOffset),
|
tileId = idOffset,
|
||||||
|
tileSize = tileSize,
|
||||||
|
slaveAddress = smKey.address + smKey.size + 0x3000 + 0x100 * numPrevGemminis
|
||||||
|
)
|
||||||
|
Seq(GemminiTileAttachParams(
|
||||||
|
tileParams,
|
||||||
crossing
|
crossing
|
||||||
)) ++ prev
|
)) ++ prev
|
||||||
}
|
}
|
||||||
case RadianceGemminiKey => {
|
|
||||||
val smKey = site(RadianceSharedMemKey).get
|
|
||||||
Some(RadianceGemminiKey(
|
|
||||||
tileSize = tileSize,
|
|
||||||
slaveAddress = smKey.address + smKey.size + 0x3000
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
def this(location: HierarchicalLocation = InSubsystem, dim: Int, accSizeInKB: Int, tileSize: Int) =
|
def this(location: HierarchicalLocation = InSubsystem, dim: Int, accSizeInKB: Int, tileSize: Int) =
|
||||||
this(location, RocketCrossingParams(
|
this(location, RocketCrossingParams(
|
||||||
|
|||||||
@@ -2,13 +2,17 @@ package radiance.tile;
|
|||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.SourceInfo
|
import chisel3.experimental.SourceInfo
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import freechips.rocketchip.diplomacy.BigIntHexContext
|
||||||
import org.chipsalliance.cde.config.Parameters
|
import org.chipsalliance.cde.config.Parameters
|
||||||
import org.chipsalliance.diplomacy._
|
import org.chipsalliance.diplomacy._
|
||||||
import org.chipsalliance.diplomacy.nodes._
|
import org.chipsalliance.diplomacy.nodes._
|
||||||
|
|
||||||
class AccBundle() extends Bundle {
|
class AccBundle extends Bundle {
|
||||||
val cmd = Output(Valid(UInt(32.W)))
|
val cmd = Output(Valid(UInt(32.W)))
|
||||||
val status = Input(UInt(1.W))
|
val status = Input(UInt(1.W))
|
||||||
|
|
||||||
|
def dest(): UInt = { cmd.bits(7, 5) }
|
||||||
|
def masked(): UInt = { cmd.bits & x"ffffff1f".U }
|
||||||
}
|
}
|
||||||
|
|
||||||
case class NullParams()
|
case class NullParams()
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import freechips.rocketchip.tile._
|
|||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import gemmini._
|
import gemmini._
|
||||||
import org.chipsalliance.cde.config.Parameters
|
import org.chipsalliance.cde.config.Parameters
|
||||||
import radiance.subsystem.{GPUMemParams, GPUMemory, RadianceGemminiKey}
|
import radiance.subsystem.{GPUMemParams, GPUMemory}
|
||||||
|
|
||||||
case class GemminiCoreParams(
|
case class GemminiCoreParams(
|
||||||
useVM: Boolean = false,
|
useVM: Boolean = false,
|
||||||
@@ -61,7 +61,9 @@ case class GemminiCoreParams(
|
|||||||
|
|
||||||
case class GemminiTileParams(
|
case class GemminiTileParams(
|
||||||
tileId: Int = 0,
|
tileId: Int = 0,
|
||||||
gemminiConfig: GemminiArrayConfig[Float, Float, Float]
|
gemminiConfig: GemminiArrayConfig[Float, Float, Float],
|
||||||
|
tileSize: Int = 4,
|
||||||
|
slaveAddress: BigInt
|
||||||
) extends InstantiableTileParams[GemminiTile] {
|
) extends InstantiableTileParams[GemminiTile] {
|
||||||
def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(
|
def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(
|
||||||
implicit p: Parameters
|
implicit p: Parameters
|
||||||
@@ -100,7 +102,7 @@ class GemminiTile private (
|
|||||||
lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
lookup: LookupByHartIdImpl)(implicit p: Parameters) =
|
||||||
this(params, crossing.crossingType, lookup, p)
|
this(params, crossing.crossingType, lookup, p)
|
||||||
|
|
||||||
val cpuDevice: SimpleDevice = new SimpleDevice("gemmini", Nil)
|
val cpuDevice: SimpleDevice = new SimpleDevice(s"gemmini${tileId}", Nil)
|
||||||
|
|
||||||
val intOutwardNode = None
|
val intOutwardNode = None
|
||||||
val slaveNode = TLIdentityNode()
|
val slaveNode = TLIdentityNode()
|
||||||
@@ -127,11 +129,9 @@ class GemminiTile private (
|
|||||||
|
|
||||||
require(!gemmini.config.sp_singleported, "external scratchpad must be dual ported")
|
require(!gemmini.config.sp_singleported, "external scratchpad must be dual ported")
|
||||||
|
|
||||||
val configKey = p(RadianceGemminiKey).get
|
|
||||||
|
|
||||||
val regDevice = new SimpleDevice("gemmini-cmd-reg", Seq(s"gemmini-cmd-reg"))
|
val regDevice = new SimpleDevice("gemmini-cmd-reg", Seq(s"gemmini-cmd-reg"))
|
||||||
val regNode = TLRegisterNode(
|
val regNode = TLRegisterNode(
|
||||||
address = Seq(AddressSet(configKey.slaveAddress, 0xfff)),
|
address = Seq(AddressSet(gemminiParams.slaveAddress, 0xff)),
|
||||||
device = regDevice,
|
device = regDevice,
|
||||||
beatBytes = 8,
|
beatBytes = 8,
|
||||||
concurrency = 1)
|
concurrency = 1)
|
||||||
@@ -187,7 +187,7 @@ class GemminiTileModuleImp(outer: GemminiTile) extends BaseTileModuleImp(outer)
|
|||||||
|
|
||||||
ciscInst := 0.U.asTypeOf(ciscInstT)
|
ciscInst := 0.U.asTypeOf(ciscInstT)
|
||||||
|
|
||||||
val tileSize = outer.configKey.tileSize
|
val tileSize = outer.gemminiParams.tileSize
|
||||||
val (boundsInst, spadQuartile) = if (tileSize == 4) {
|
val (boundsInst, spadQuartile) = if (tileSize == 4) {
|
||||||
(ciscInstT.Lit(_.inst -> 0x1220b07b.U, _.rs1 -> 0.U, _.rs2 -> x"4_00040004".U), 0x80)
|
(ciscInstT.Lit(_.inst -> 0x1220b07b.U, _.rs1 -> 0.U, _.rs2 -> x"4_00040004".U), 0x80)
|
||||||
} else if (tileSize == 8) {
|
} else if (tileSize == 8) {
|
||||||
|
|||||||
@@ -46,14 +46,10 @@ class RadianceCluster (
|
|||||||
// val numLsuLanes = 4 // FIXME: hardcoded
|
// val numLsuLanes = 4 // FIXME: hardcoded
|
||||||
|
|
||||||
// must toSeq here, otherwise Iterable is lazy and will break diplomacy
|
// must toSeq here, otherwise Iterable is lazy and will break diplomacy
|
||||||
val gemminis = leafTiles.values.filter(_.isInstanceOf[GemminiTile]).toSeq.asInstanceOf[Seq[GemminiTile]]
|
val gemminiTiles = leafTiles.values.filter(_.isInstanceOf[GemminiTile]).toSeq.asInstanceOf[Seq[GemminiTile]]
|
||||||
require(gemminis.size == 1, "there should be one and only one gemmini per cluster")
|
val gemminis = gemminiTiles.map(_.gemmini)
|
||||||
val gemmini = gemminis.head.gemmini
|
val gemminiConfigs = gemminis.map(_.config)
|
||||||
val gemminiTile = gemminis.head
|
|
||||||
// val gemminiConfig = thisClusterParams.gemminiConfig.get // TODO: handle None gracefully
|
// val gemminiConfig = thisClusterParams.gemminiConfig.get // TODO: handle None gracefully
|
||||||
val gemminiConfig = gemmini.config
|
|
||||||
|
|
||||||
val max_write_width_bytes = gemminiConfig.dma_buswidth / 8
|
|
||||||
|
|
||||||
val radianceTiles = leafTiles.values.filter(_.isInstanceOf[RadianceTile]).toSeq.asInstanceOf[Seq[RadianceTile]]
|
val radianceTiles = leafTiles.values.filter(_.isInstanceOf[RadianceTile]).toSeq.asInstanceOf[Seq[RadianceTile]]
|
||||||
|
|
||||||
@@ -67,9 +63,6 @@ class RadianceCluster (
|
|||||||
//
|
//
|
||||||
// **************************************
|
// **************************************
|
||||||
|
|
||||||
// TODO: parametrize bank configuration
|
|
||||||
// TODO: move rw split node to separate file
|
|
||||||
// TODO: stride by word
|
|
||||||
val unified_mem_read_node = TLIdentityNode()
|
val unified_mem_read_node = TLIdentityNode()
|
||||||
val unified_mem_write_node = TLIdentityNode()
|
val unified_mem_write_node = TLIdentityNode()
|
||||||
|
|
||||||
@@ -81,15 +74,17 @@ class RadianceCluster (
|
|||||||
val smem_depth = smem_key.size / smem_width / smem_banks
|
val smem_depth = smem_key.size / smem_width / smem_banks
|
||||||
val smem_subbanks = smem_width / wordSize
|
val smem_subbanks = smem_width / wordSize
|
||||||
val smem_size = smem_width * smem_depth * smem_banks
|
val smem_size = smem_width * smem_depth * smem_banks
|
||||||
assert(gemminiConfig.sp_banks == smem_banks)
|
|
||||||
assert(gemminiConfig.sp_width / 8 == smem_width)
|
|
||||||
assert(gemminiConfig.sp_bank_entries == smem_depth)
|
|
||||||
|
|
||||||
VecInit(Seq(0.U, 1.U)).reduceTree(_ +& _)
|
gemminiConfigs.foreach { config =>
|
||||||
|
assert(smem_banks == config.sp_banks && isPow2(smem_banks / config.sp_banks)) // TODO: should allow >=
|
||||||
|
assert(smem_width >= (config.sp_width / 8) && isPow2(smem_width / (config.sp_width / 8)))
|
||||||
|
assert(smem_size == config.sp_capacity.asInstanceOf[CapacityInKilobytes].kilobytes * 1024)
|
||||||
|
}
|
||||||
|
|
||||||
val stride_by_word = true
|
val stride_by_word = true
|
||||||
val filter_aligned = true
|
val filter_aligned = true
|
||||||
val disable_monitors = true // otherwise it generate 1k+ different tl monitors
|
val disable_monitors = true // otherwise it generate 1k+ different tl monitors
|
||||||
val serialize_unaligned = false
|
val serialize_unaligned = true
|
||||||
|
|
||||||
def guard_monitors[T](callback: Parameters => T)(implicit p: Parameters): Unit = {
|
def guard_monitors[T](callback: Parameters => T)(implicit p: Parameters): Unit = {
|
||||||
if (disable_monitors) {
|
if (disable_monitors) {
|
||||||
@@ -186,26 +181,27 @@ class RadianceCluster (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stride_by_word) {
|
if (stride_by_word) {
|
||||||
// ask if you need to deal with this, it's not supposed to be readable
|
def dist_and_duplicate(nodes: Seq[TLNode], suffix: String): Seq[Seq[TLNode]] = {
|
||||||
|
val word_fanout_nodes = gemminis.zip(nodes).zipWithIndex.map { case ((gemmini, node), gemmini_idx) =>
|
||||||
|
val sp_width_bytes = gemmini.config.sp_width / 8
|
||||||
|
val sp_subbanks = sp_width_bytes / wordSize
|
||||||
|
val dist = DistributorNode(from = sp_width_bytes, to = wordSize)
|
||||||
|
guard_monitors { implicit p =>
|
||||||
|
dist := TLBuffer(BufferParams(1, false, true), BufferParams(0)) := node
|
||||||
|
}
|
||||||
|
val fanout = Seq.fill(sp_subbanks) {
|
||||||
|
connect_xbar_name(dist, Some(s"spad_g${gemmini_idx}_fanout_$suffix"))
|
||||||
|
}
|
||||||
|
Seq.fill(smem_width / sp_width_bytes)(fanout).flatten // smem wider than spad, duplicate masters
|
||||||
|
}
|
||||||
|
// (gemmini, word) => (word, gemmini)
|
||||||
|
word_fanout_nodes.transpose
|
||||||
|
}
|
||||||
|
|
||||||
val spad_read_nodes = Seq.fill(smem_banks) {
|
val spad_read_nodes = Seq.fill(smem_banks)(dist_and_duplicate(gemminis.map(_.spad_read_nodes), "r"))
|
||||||
val r_dist = DistributorNode(from = smem_width, to = wordSize)
|
val spad_write_nodes = Seq.fill(smem_banks)(dist_and_duplicate(gemminis.map(_.spad_write_nodes), "w"))
|
||||||
guard_monitors { implicit p => r_dist := TLBuffer(BufferParams(1, false, true), BufferParams(0)) := gemmini.spad_read_nodes }
|
val spad_sp_write_nodes_single_bank = dist_and_duplicate(gemminis.map(_.spad.spad_writer.node), "ws")
|
||||||
Seq.fill(smem_subbanks) { connect_one(r_dist, TLIdentityNode.apply) }
|
val spad_sp_write_nodes = Seq.fill(smem_banks)(spad_sp_write_nodes_single_bank) // executed only once
|
||||||
}
|
|
||||||
val spad_write_nodes = Seq.fill(smem_banks) {
|
|
||||||
val w_dist = DistributorNode(from = smem_width, to = wordSize)
|
|
||||||
guard_monitors { implicit p => w_dist := TLBuffer(BufferParams(1, false, true), BufferParams(0)) := gemmini.spad_write_nodes }
|
|
||||||
Seq.fill(smem_subbanks) { connect_one(w_dist, TLIdentityNode.apply) }
|
|
||||||
/* Seq.fill(smem_subbanks) {
|
|
||||||
val buf = TLBuffer(BufferParams(1, false, true), BufferParams(0))
|
|
||||||
buf := w_dist
|
|
||||||
buf
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
val ws_dist = DistributorNode(from = smem_width, to = wordSize)
|
|
||||||
guard_monitors { implicit p => ws_dist := gemmini.spad.spad_writer.node } // this is the dma write node
|
|
||||||
val spad_sp_write_nodes = Seq.fill(smem_subbanks) { connect_xbar(ws_dist) }
|
|
||||||
|
|
||||||
val (uniform_r_nodes, uniform_w_nodes, nonuniform_r_nodes, nonuniform_w_nodes):
|
val (uniform_r_nodes, uniform_w_nodes, nonuniform_r_nodes, nonuniform_w_nodes):
|
||||||
(Seq[Seq[Seq[TLNode]]], Seq[Seq[Seq[TLNode]]], Seq[TLNode], Seq[TLNode]) = if (filter_aligned) {
|
(Seq[Seq[Seq[TLNode]]], Seq[Seq[Seq[TLNode]]], Seq[TLNode], Seq[TLNode]) = if (filter_aligned) {
|
||||||
@@ -252,11 +248,11 @@ class RadianceCluster (
|
|||||||
}
|
}
|
||||||
|
|
||||||
val uniform_r_nodes: Seq[Seq[Seq[TLNode]]] = spad_read_nodes.map { rb =>
|
val uniform_r_nodes: Seq[Seq[Seq[TLNode]]] = spad_read_nodes.map { rb =>
|
||||||
(rb zip f_aligned.head).map { case (rw, fa) => Seq(rw) ++ fa }
|
(rb zip f_aligned.head).map { case (rw, fa) => rw ++ fa }
|
||||||
}
|
}
|
||||||
val uniform_w_nodes: Seq[Seq[Seq[TLNode]]] = spad_write_nodes.map { wb =>
|
val uniform_w_nodes: Seq[Seq[Seq[TLNode]]] = (spad_write_nodes zip spad_sp_write_nodes).map { case (wb, wsb) =>
|
||||||
(wb lazyZip spad_sp_write_nodes lazyZip f_aligned.last).map {
|
(wb lazyZip wsb lazyZip f_aligned.last).map {
|
||||||
case (ww, sw, fa) => Seq(ww, sw) ++ fa
|
case (ww, wsw, fa) => ww ++ wsw ++ fa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,11 +263,9 @@ class RadianceCluster (
|
|||||||
} else {
|
} else {
|
||||||
val splitter_nodes = radiance_smem_fanout.map { connect_one(_, RWSplitterNode.apply) }
|
val splitter_nodes = radiance_smem_fanout.map { connect_one(_, RWSplitterNode.apply) }
|
||||||
// these nodes access an entire line simultaneously
|
// these nodes access an entire line simultaneously
|
||||||
val uniform_r_nodes: Seq[Seq[Seq[TLNode]]] = spad_read_nodes.map { rb =>
|
val uniform_r_nodes: Seq[Seq[Seq[TLNode]]] = spad_read_nodes
|
||||||
rb.map { rw => Seq(rw) }
|
val uniform_w_nodes: Seq[Seq[Seq[TLNode]]] = (spad_write_nodes zip spad_sp_write_nodes).map { case (wb, wsb) =>
|
||||||
}
|
(wb zip wsb).map { case (ww, wsw) => ww ++ wsw }
|
||||||
val uniform_w_nodes: Seq[Seq[Seq[TLNode]]] = spad_write_nodes.map { wb =>
|
|
||||||
(wb zip spad_sp_write_nodes).map { case (ww, sw) => Seq(ww, sw) }
|
|
||||||
}
|
}
|
||||||
// these nodes are random access
|
// these nodes are random access
|
||||||
val nonuniform_r_nodes: Seq[TLNode] = splitter_nodes.map(connect_xbar_name(_, Some("rad_unaligned_r")))
|
val nonuniform_r_nodes: Seq[TLNode] = splitter_nodes.map(connect_xbar_name(_, Some("rad_unaligned_r")))
|
||||||
@@ -302,9 +296,11 @@ class RadianceCluster (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unified_mem_read_node :=* TLWidthWidget(smem_width) :=* gemmini.spad_read_nodes
|
gemminis.foreach { gemmini =>
|
||||||
unified_mem_write_node :=* TLWidthWidget(smem_width) :=* gemmini.spad_write_nodes
|
unified_mem_read_node :=* TLWidthWidget(smem_width) :=* gemmini.spad_read_nodes
|
||||||
unified_mem_write_node := gemmini.spad.spad_writer.node // this is the dma write node
|
unified_mem_write_node :=* TLWidthWidget(smem_width) :=* gemmini.spad_write_nodes
|
||||||
|
unified_mem_write_node := gemmini.spad.spad_writer.node // this is the dma write node
|
||||||
|
}
|
||||||
|
|
||||||
val splitter_node = RWSplitterNode()
|
val splitter_node = RWSplitterNode()
|
||||||
unified_mem_read_node := TLWidthWidget(smem_width) := splitter_node
|
unified_mem_read_node := TLWidthWidget(smem_width) := splitter_node
|
||||||
@@ -327,14 +323,22 @@ class RadianceCluster (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect tile smem nodes to xbar, and xbar to banks
|
// *******************************************************
|
||||||
// val smem_xbar = TLXbar()
|
// ___ _______ _______ __ _________ ___ __ ____
|
||||||
|
// / _ \/ __/ _ \/ _/ _ \/ // / __/ _ \/ _ | / / / __/
|
||||||
|
// / ___/ _// , _// // ___/ _ / _// , _/ __ |/ /___\ \
|
||||||
|
// /_/ /___/_/|_/___/_/ /_//_/___/_/|_/_/ |_/____/___/
|
||||||
|
//
|
||||||
|
// *******************************************************
|
||||||
|
|
||||||
val radianceAccSlaveNodes = Seq.fill(numCores)(AccSlaveNode())
|
val radianceAccSlaveNodes = Seq.fill(numCores)(AccSlaveNode())
|
||||||
(radianceAccSlaveNodes zip radianceTiles).foreach { case (a, r) => a := r.accMasterNode }
|
(radianceAccSlaveNodes zip radianceTiles).foreach { case (a, r) => a := r.accMasterNode }
|
||||||
val gemminiAccMasterNode = AccMasterNode()
|
val gemminiAccMasterNodes = gemminiTiles.map { tile =>
|
||||||
gemminiTile.accSlaveNode := gemminiAccMasterNode
|
val masterNode = AccMasterNode()
|
||||||
gemminiTile.slaveNode :=* TLWidthWidget(4) :=* clbus.outwardNode
|
tile.accSlaveNode := masterNode
|
||||||
|
masterNode
|
||||||
|
}
|
||||||
|
gemminiTiles.foreach { _.slaveNode :=* TLWidthWidget(4) :=* clbus.outwardNode }
|
||||||
|
|
||||||
val traceTLNode = TLAdapterNode(clientFn = c => c, managerFn = m => m)
|
val traceTLNode = TLAdapterNode(clientFn = c => c, managerFn = m => m)
|
||||||
// printf and perf counter buffer
|
// printf and perf counter buffer
|
||||||
@@ -385,15 +389,19 @@ class RadianceClusterModuleImp(outer: RadianceCluster) extends ClusterModuleImp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val coreAcc = outer.radianceAccSlaveNodes.head.in.head._1
|
val coreAcc = outer.radianceAccSlaveNodes.head.in.head._1
|
||||||
val gemminiAcc = outer.gemminiAccMasterNode.out.head._1
|
val gemminiAccs = outer.gemminiAccMasterNodes.map(_.out.head._1)
|
||||||
dontTouch(gemminiAcc)
|
|
||||||
// val gemminiTileAcc = outer.gemminiTile.accSlaveNode.in.head._1
|
// val gemminiTileAcc = outer.gemminiTile.accSlaveNode.in.head._1
|
||||||
|
|
||||||
// gemminiTileAcc.cmd := gemminiAcc.cmd
|
// gemminiTileAcc.cmd := gemminiAcc.cmd
|
||||||
// gemminiAcc.status := gemminiTileAcc.status
|
// gemminiAcc.status := gemminiTileAcc.status
|
||||||
|
|
||||||
outer.radianceAccSlaveNodes.foreach(_.in.head._1.status := gemminiAcc.status)
|
gemminiAccs.zipWithIndex.foreach { case (g, gi) =>
|
||||||
gemminiAcc.cmd := coreAcc.cmd
|
g.cmd.bits := coreAcc.masked
|
||||||
|
g.cmd.valid := coreAcc.cmd.valid && (coreAcc.dest === gi.U)
|
||||||
|
}
|
||||||
|
|
||||||
|
// this might need some more tweaking (e.g. bitmask instead of or)
|
||||||
|
outer.radianceAccSlaveNodes.foreach(_.in.head._1.status := VecInit(gemminiAccs.map(_.status)).reduceTree(_ | _))
|
||||||
|
|
||||||
(outer.traceTLNode.in.map(_._1) zip outer.traceTLNode.out.map(_._1)).foreach { case (i, o) =>
|
(outer.traceTLNode.in.map(_._1) zip outer.traceTLNode.out.map(_._1)).foreach { case (i, o) =>
|
||||||
o.a <> i.a
|
o.a <> i.a
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ class Vortex(tile: RadianceTile)(implicit p: Parameters)
|
|||||||
|
|
||||||
// tensor core
|
// tensor core
|
||||||
addResource("/vsrc/vortex/hw/rtl/core/VX_tensor_core.sv")
|
addResource("/vsrc/vortex/hw/rtl/core/VX_tensor_core.sv")
|
||||||
addResource("/vsrc/vortex/hw/rtl/core/VX_tensor_ucode.vh")
|
// addResource("/vsrc/vortex/hw/rtl/core/VX_tensor_ucode.vh")
|
||||||
addResource("/vsrc/vortex/hw/rtl/core/VX_uop_sequencer.sv")
|
addResource("/vsrc/vortex/hw/rtl/core/VX_uop_sequencer.sv")
|
||||||
addResource("/vsrc/vortex/hw/rtl/core/VX_reduce_unit.sv")
|
addResource("/vsrc/vortex/hw/rtl/core/VX_reduce_unit.sv")
|
||||||
addResource("/vsrc/vortex/hw/rtl/fpu/VX_tensor_dpu.sv")
|
addResource("/vsrc/vortex/hw/rtl/fpu/VX_tensor_dpu.sv")
|
||||||
|
|||||||
Reference in New Issue
Block a user