Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utils: add source locators #2496

Merged
merged 18 commits into from
Apr 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/Mem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ sealed class SyncReadMem[T <: Data] private[chisel3] (t: T, n: BigInt, val readU
def do_read(idx: UInt, en: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
_read_impl(idx, en, Builder.forcedClock, true)

def read(idx: UInt, en: Bool, clock: Clock): T = macro SourceInfoTransform.xyzArg
def read(idx: UInt, en: Bool, clock: Clock): T = macro SourceInfoTransform.idxEnClockArg

/** @group SourceInfoTransformMacro */
def do_read(idx: UInt, en: Bool, clock: Clock)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,58 @@ class SourceInfoTransform(val c: Context) extends AutoSourceTransform {
q"$thisObj.$doFuncTerm($x, $y)($implicitSourceInfo, $implicitCompileOptions)"
}

def xyzArg(idx: c.Tree, en: c.Tree, clock: c.Tree): c.Tree = {
def nxArg(n: c.Tree, x: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($n, $x)($implicitSourceInfo, $implicitCompileOptions)"
}

def idxEnClockArg(idx: c.Tree, en: c.Tree, clock: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($idx, $en, $clock)($implicitSourceInfo, $implicitCompileOptions)"
}

def xEnArg(x: c.Tree, en: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($x, $en)($implicitSourceInfo, $implicitCompileOptions)"
}

def arArg(a: c.Tree, r: c.Tree*): c.Tree = {
q"$thisObj.$doFuncTerm($a, ..$r)($implicitSourceInfo, $implicitCompileOptions)"
}

def rArg(r: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($r)($implicitSourceInfo, $implicitCompileOptions)"
}

def nInArg(n: c.Tree, in: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($n, $in)($implicitSourceInfo, $implicitCompileOptions)"
}

def nextEnableArg(next: c.Tree, enable: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($next, $enable)($implicitSourceInfo, $implicitCompileOptions)"
}

def nextInitEnableArg(next: c.Tree, init: c.Tree, enable: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($next, $init, $enable)($implicitSourceInfo, $implicitCompileOptions)"
}

def inNArg(in: c.Tree, n: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($in, $n)($implicitSourceInfo, $implicitCompileOptions)"
}

def inNEnArg(in: c.Tree, n: c.Tree, en: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($in, $n, $en)($implicitSourceInfo, $implicitCompileOptions)"
}

def inNResetEnArg(in: c.Tree, n: c.Tree, reset: c.Tree, en: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($in, $n, $reset, $en)($implicitSourceInfo, $implicitCompileOptions)"
}

def inNResetDataArg(in: c.Tree, n: c.Tree, resetData: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($in, $n, $resetData)($implicitSourceInfo, $implicitCompileOptions)"
}

def inNResetDataEnArg(in: c.Tree, n: c.Tree, resetData: c.Tree, en: c.Tree): c.Tree = {
q"$thisObj.$doFuncTerm($in, $n, $resetData, $en)($implicitSourceInfo, $implicitCompileOptions)"
}

}

// Workaround for https://github.com/sbt/sbt/issues/3966
Expand Down
88 changes: 64 additions & 24 deletions src/main/scala/chisel3/util/Bitwise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package chisel3.util

import chisel3._
import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform}
import scala.language.experimental.macros

/** Creates repetitions of each bit of the input in order.
*
Expand All @@ -24,13 +26,29 @@ object FillInterleaved {
*
* Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
*/
def apply(n: Int, in: UInt): UInt = apply(n, in.asBools)
def apply(n: Int, in: UInt): UInt = macro SourceInfoTransform.nInArg

/** @group SourceInfoTransformMacro */
def do_apply(n: Int, in: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
mwachs5 marked this conversation as resolved.
Show resolved Hide resolved
_apply_impl(n, in.asBools)

/** Creates n repetitions of each bit of x in order.
*
* Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times)
*/
def apply(n: Int, in: Seq[Bool]): UInt = Cat(in.map(Fill(n, _)).reverse)
def apply(n: Int, in: Seq[Bool]): UInt = macro SourceInfoTransform.nInArg

/** @group SourceInfoTransformMacro */
def do_apply(n: Int, in: Seq[Bool])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
_apply_impl(n, in)

private def _apply_impl(
n: Int,
in: Seq[Bool]
)(
implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions
): UInt = Cat(in.map(Fill(n, _)).reverse)
}

/** Returns the number of bits set (value is 1 or true) in the input signal.
Expand All @@ -45,9 +63,23 @@ object FillInterleaved {
* }}}
*/
object PopCount {
def apply(in: Iterable[Bool]): UInt = SeqUtils.count(in.toSeq)

def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_)))
def apply(in: Iterable[Bool]): UInt = macro SourceInfoTransform.inArg

/** @group SourceInfoTransformMacro */
def do_apply(in: Iterable[Bool])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = _apply_impl(
in.toSeq
)

def apply(in: Bits): UInt = macro SourceInfoTransform.inArg

/** @group SourceInfoTransformMacro */
def do_apply(in: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = _apply_impl(
(0 until in.getWidth).map(in(_))
)

private def _apply_impl(in: Iterable[Bool])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.count(in.toSeq)
}

/** Create repetitions of the input using a tree fanout topology.
Expand All @@ -65,7 +97,10 @@ object Fill {
* Output data-equivalent to x ## x ## ... ## x (n repetitions).
* @throws java.lang.IllegalArgumentException if `n` is less than zero
*/
def apply(n: Int, x: UInt): UInt = {
def apply(n: Int, x: UInt): UInt = macro SourceInfoTransform.nxArg

/** @group SourceInfoTransformMacro */
def do_apply(n: Int, x: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
n match {
case _ if n < 0 => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.")
case 0 => UInt(0.W)
Expand All @@ -92,24 +127,29 @@ object Fill {
* }}}
*/
object Reverse {
private def doit(in: UInt, length: Int): UInt = length match {
case _ if length < 0 => throw new IllegalArgumentException(s"length (=$length) must be nonnegative integer.")
case _ if length <= 1 => in
case _ if isPow2(length) && length >= 8 && length <= 64 =>
// This esoterica improves simulation performance
var res = in
var shift = length >> 1
var mask = ((BigInt(1) << length) - 1).asUInt(length.W)
do {
mask = mask ^ (mask(length - shift - 1, 0) << shift)
res = ((res >> shift) & mask) | ((res(length - shift - 1, 0) << shift) & ~mask)
shift = shift >> 1
} while (shift > 0)
res
case _ =>
val half = (1 << log2Ceil(length)) / 2
Cat(doit(in(half - 1, 0), half), doit(in(length - 1, half), length - half))
}

def apply(in: UInt): UInt = doit(in, in.getWidth)
private def doit(in: UInt, length: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
length match {
case _ if length < 0 => throw new IllegalArgumentException(s"length (=$length) must be nonnegative integer.")
case _ if length <= 1 => in
case _ if isPow2(length) && length >= 8 && length <= 64 =>
// This esoterica improves simulation performance
var res = in
var shift = length >> 1
var mask = ((BigInt(1) << length) - 1).asUInt(length.W)
do {
mask = mask ^ (mask(length - shift - 1, 0) << shift)
res = ((res >> shift) & mask) | ((res(length - shift - 1, 0) << shift) & ~mask)
shift = shift >> 1
} while (shift > 0)
res
case _ =>
val half = (1 << log2Ceil(length)) / 2
Cat(doit(in(half - 1, 0), half), doit(in(length - 1, half), length - half))
}

def apply(in: UInt): UInt = macro SourceInfoTransform.inArg

/** @group SourceInfoTransformMacro */
def do_apply(in: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = doit(in, in.getWidth)
}
18 changes: 16 additions & 2 deletions src/main/scala/chisel3/util/Cat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

package chisel3.util

import scala.language.experimental.macros

import chisel3._
import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform}

/** Concatenates elements of the input, in order, together.
*
Expand All @@ -19,7 +22,11 @@ object Cat {
/** Concatenates the argument data elements, in argument order, together. The first argument
* forms the most significant bits, while the last argument forms the least significant bits.
*/
def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList)
def apply[T <: Bits](a: T, r: T*): UInt = macro SourceInfoTransform.arArg

/** @group SourceInfoTransformMacro */
def do_apply[T <: Bits](a: T, r: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
_apply_impl(a :: r.toList)

/** Concatenates the data elements of the input sequence, in reverse sequence order, together.
* The first element of the sequence forms the most significant bits, while the last element
Expand All @@ -28,5 +35,12 @@ object Cat {
* Equivalent to r(0) ## r(1) ## ... ## r(n-1).
* @note This returns a `0.U` if applied to a zero-element `Vec`.
*/
def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse)
def apply[T <: Bits](r: Seq[T]): UInt = macro SourceInfoTransform.rArg

/** @group SourceInfoTransformMacro */
def do_apply[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
_apply_impl(r)

private def _apply_impl[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.asUInt(r.reverse)
}
Loading