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

Add NoChiselNamePrefix to ignore instances in @chiselName #1383

Merged
merged 1 commit into from
Mar 23, 2020
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
56 changes: 56 additions & 0 deletions chiselFrontend/src/main/scala/chisel3/experimental/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,63 @@ package object experimental { // scalastyle:ignore object.name

class dump extends chisel3.internal.naming.dump // scalastyle:ignore class.name
class treedump extends chisel3.internal.naming.treedump // scalastyle:ignore class.name
/** Experimental macro for naming Chisel hardware values
*
* By default, Chisel uses reflection for naming which only works for public fields of `Bundle`
* and `Module` classes. Applying this macro annotation to a `class` or `object` enables Chisel
* to name any hardware values within the annotated `class` or `object.
*
* @example {{{
* import chisel3._
* import chisel3.experimental.chiselName
*
* @chiselName
* class MyModule extends Module {
* val io = IO(new Bundle {
* val in = Input(UInt(8.W))
* val out = Output(UInt(8.W))
* })
* def createReg(): Unit = {
* // @chiselName allows Chisel to name this Reg
* val myReg = RegInit(io.in)
* io.out := myReg
* }
* createReg()
* }
jackkoenig marked this conversation as resolved.
Show resolved Hide resolved
* }}}
*/
class chiselName extends chisel3.internal.naming.chiselName // scalastyle:ignore class.name
/** Do not name instances of this type in [[chiselName]]
*
* By default, `chiselName` will include `val` names of instances of annotated classes as a
* prefix in final naming. Mixing in this trait to a `class`, `object`, or anonymous `class`
* instances will exclude the `val` name from `chiselName` naming.
*
* @example {{{
* import chisel3._
* import chisel3.experimental.{chiselName, NoChiselNamePrefix}
*
* // Note that this is not a Module
* @chiselName
* class Counter(w: Int) {
* val myReg = RegInit(0.U(w.W))
* myReg := myReg + 1.U
* }
*
* @chiselName
* class MyModule extends Module {
* val io = IO(new Bundle {
* val out = Output(UInt(8.W))
* })
* // Name of myReg will be "counter0_myReg"
* val counter0 = new Counter(8)
* // Name of myReg will be "myReg"
* val counter1 = new Counter(8) with NoChiselNamePrefix
* io.out := counter0.myReg + counter1.myReg
* }
* }}}
*/
trait NoChiselNamePrefix

object BundleLiterals {
implicit class AddBundleLiteralConstructor[T <: Bundle](x: T) {
Expand Down
2 changes: 2 additions & 0 deletions chiselFrontend/src/main/scala/chisel3/internal/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// This file contains part of the implementation of the naming static annotation system.

package chisel3.internal.naming
import chisel3.experimental.NoChiselNamePrefix

import scala.collection.mutable.Stack
import scala.collection.mutable.ListBuffer
Expand Down Expand Up @@ -88,6 +89,7 @@ class NamingContext extends NamingContextInterface {
def name[T](obj: T, name: String): T = {
assert(!closed, "Can't name elements after name_prefix called")
obj match {
case _: NoChiselNamePrefix => // Don't name things with NoChiselNamePrefix
case ref: AnyRef => items += ((ref, name))
case _ =>
}
Expand Down
32 changes: 32 additions & 0 deletions src/test/scala/chiselTests/NamingAnnotationTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,32 @@ class PartialNamedModule extends NamedModuleTester {
val test = innerNamedFunction()
}

@chiselName
class NoChiselNamePrefixTester extends NamedModuleTester {
@chiselName
class NoChiselNamePrefixClass extends chisel3.experimental.NoChiselNamePrefix {
val a = expectName(1.U +& 2.U, "a")
}
val inst = new NoChiselNamePrefixClass
@chiselName
class NormalClass {
val b = 1.U +& 2.U
}
val foo = new NormalClass
expectName(foo.b, "foo_b")
val bar = new NormalClass with chisel3.experimental.NoChiselNamePrefix
expectName(bar.b, "b")

// Check that we're not matching by name but actual type
trait NoChiselNamePrefix
@chiselName
class FakeNoChiselNamePrefix extends NoChiselNamePrefix {
val c = 1.U +& 2.U
}
val fizz = new FakeNoChiselNamePrefix
expectName(fizz.c, "fizz_c")
}


/** A simple test that checks the recursive function val naming annotation both compiles and
* generates the expected names.
Expand Down Expand Up @@ -240,4 +266,10 @@ class NamingAnnotationSpec extends ChiselPropSpec {
property("NonBuilderFunction should run outside a Builder context") {
NonNamedHelper.NonBuilderFunction() should be (2)
}

property("NoChiselNamePrefix should prevent prefixing when using @chiselName") {
var module: NoChiselNamePrefixTester = null
elaborate { module = new NoChiselNamePrefixTester; module }
assert(module.getNameFailures().isEmpty)
}
}