diff options
| author | Jack | 2022-04-26 02:53:08 +0000 |
|---|---|---|
| committer | Jack | 2022-04-26 02:53:08 +0000 |
| commit | 3a6cc75d72cbf890bbd45a002c31d16abfc6896d (patch) | |
| tree | 298a39cbdbcd7e89953d75dbd840884f29ff7699 /core/src/main/scala/chisel3/Aggregate.scala | |
| parent | be1ac06bf20c6c3d84c8ce5b0a50e2980e546e7e (diff) | |
| parent | d5a964f6e7beea1f38f9623224fc65e2397e1fe7 (diff) | |
Merge branch '3.5.x' into 3.5-release
Diffstat (limited to 'core/src/main/scala/chisel3/Aggregate.scala')
| -rw-r--r-- | core/src/main/scala/chisel3/Aggregate.scala | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 06ae36f3..cc5b83d9 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -14,6 +14,7 @@ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ +import java.lang.Math.{floor, log10, pow} import scala.collection.mutable class AliasedAggregateFieldException(message: String) extends ChiselException(message) @@ -381,11 +382,30 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend compileOptions: CompileOptions ): T = { require(!isEmpty, "Cannot apply reduction on a vec of size 0") - var curLayer: Seq[T] = this - while (curLayer.length > 1) { - curLayer = curLayer.grouped(2).map(x => if (x.length == 1) layerOp(x(0)) else redOp(x(0), x(1))).toSeq + + def recReduce[T](s: Seq[T], op: (T, T) => T, lop: (T) => T): T = { + + val n = s.length + n match { + case 1 => lop(s(0)) + case 2 => op(s(0), s(1)) + case _ => + val m = pow(2, floor(log10(n - 1) / log10(2))).toInt // number of nodes in next level, will be a power of 2 + val p = 2 * m - n // number of nodes promoted + + val l = s.take(p).map(lop) + val r = s + .drop(p) + .grouped(2) + .map { + case Seq(a, b) => op(a, b) + } + .toVector + recReduce(l ++ r, op, lop) + } } - curLayer(0) + + recReduce(this, redOp, layerOp) } /** Creates a Vec literal of this type with specified values. this must be a chisel type. |
