Skip to content

Commit

Permalink
Add NoChiselNamePrefix to ignore instances in @chiselName (#1383)
Browse files Browse the repository at this point in the history
Add trait chisel3.experimental.NoChiselNamePrefix which causes
@chiselName to skip naming of the instance effectively preventing it
from prefixing any vals inside the instance. It can be applied to
classes such that all instances of that class have this property, or to
individual instances (via creating an anonymous class inline).

Also add basic ScalaDoc for NoChiselNamePrefix and chiselName.
  • Loading branch information
jackkoenig authored Mar 23, 2020
1 parent 5d269ce commit 1d81119
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 0 deletions.
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()
* }
* }}}
*/
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)
}
}

0 comments on commit 1d81119

Please sign in to comment.