Skip to main content

# Naming Cookbook

- I still have _T signals, can this be fixed?
- I have so many wires with the same name, like `x`, `x_1` and `x_2`. How can I make them easier to understand?
- How can I get better names for code generated by `when` clauses?
- I still see _GEN signals, can this be fixed?
- How do I make my modules have more stable names instead of 'Module_1' and 'Module_42'?
- How would I write my own `typeName` for my data types?
- I don't want to override `typeName` over and over! Is there any easy way to generate a `typeName`?
- Can I name my bundles in FIRRTL, so I don't generate extremely long bundle types?
- Why do I keep seeing _stripped suffixing everywhere in my FIRRTL? I didn't specify that in my `aliasName`.
- I want to add some hardware or assertions, but each time I do all the signal names get bumped!
- I want to force a signal (or instance) name to something, how do I do that?
- How can I omit the prefix in certain parts of the code?
- I am still not getting the name I want. For example, inlining an instance changes my name!

### I still have _T signals, can this be fixed?​

See the next answer!

### I have so many wires with the same name, like `x`, `x_1` and `x_2`. How can I make them easier to understand?​

Signals with `_T` names or names that Chisel has to uniquify often are intermediate values generated within loops, function calls, or `when` predicates. They can also be consumed by verification statements like `assert` or `prints`. In these cases, the compiler plugin often can't find a good prefix for the generated intermediate signals and can't name them at all or has to make up a unique name for them.

We recommend you manually insert calls to `prefix` to clarify these cases:

    import chisel3.experimental.prefix
    class ExamplePrefix extends Module {

      Seq.tabulate(2) { i =>
        Seq.tabulate(2) { j =>
          prefix(s"loop_${i}_${j}"){
            val x = WireInit((i*0x10+j).U(8.W))
            dontTouch(x)
          }
        }
      }
    }

    // Generated by CIRCT firtool-1.76.0
    module ExamplePrefix(
      input clock,
            reset
    );

      wire [7:0] loop_0_0_x = 8'h0;
      wire [7:0] loop_0_1_x = 8'h1;
      wire [7:0] loop_1_0_x = 8'h10;
      wire [7:0] loop_1_1_x = 8'h11;
    endmodule

### How can I get better names for code generated by `when` clauses?​

The `prefix` API can help with code inside `when` clauses:

    class ExampleWhenPrefix extends Module {

      val in = IO(Input(UInt(4.W)))
      val out = IO(Output(UInt(4.W)))

      out := DontCare

      Seq.tabulate(2) { i =>
        val j = i + 1
        prefix(s"clause_${j}") {
          when (in === j.U) {
            val foo = Reg(UInt(4.W))
            foo := in + j.U(4.W)
            out := foo
          }
        }
      }
    }

    // Generated by CIRCT firtool-1.76.0
    module ExampleWhenPrefix(
      input        clock,
                   reset,
      input  [3:0] in,
      output [3:0] out
    );

      reg [3:0] clause_1_foo;
      reg [3:0] clause_2_foo;
      always @(posedge clock) begin
        clause_1_foo <= in + 4'h1;
        clause_2_foo <= in + 4'h2;
      end // always @(posedge)
      assign out = in == 4'h2 ? clause_2_foo : clause_1_foo;
    endmodule

### I still see _GEN signals, can this be fixed?​

`_GEN` signals are usually generated from the FIRRTL compiler, rather than the Chisel library. We are working on renaming these signals with more context-dependent names, but it is a work in progress. Thanks for caring!

### How do I make my modules have more stable names instead of 'Module_1' and 'Module_42'?​

This is an example of the module instability problem, which results from several modules all sharing the exact same name. To fix this, you must add more specificity to your `Module`'s name to avoid these name collisions.

This can be done by leveraging the `desiredName` and `typeName` APIs. `desiredName` is for indicating the names of `Modules` (e.g. influenced by the parameters passed in), and `typeName` is useful for modules which are type-parameterized by subclasses of `Data`. Overriding `desiredName` can reduce or even eliminate name collisions. For instance, suppose your module looks like the following:

    class MyModule[T <: Data](gen: T) extends Module {
      // ...
    }

We can override `desiredName` of the module to include the type name of the `gen` parameter like so:

    class MyModule[T <: Data](gen: T) extends Module {
      override def desiredName = s"MyModule_${gen.typeName}"
    }

Any instances of your `MyModule` will now have Verilog module names containing the type parameter.

    val foo = Module(new MyModule(UInt(4.W))) // MyModule_UInt4 // MyModule_UInt4
    val bar = Module(new MyModule(Vec(3, UInt(4.W)))) // MyModule_Vec3_UInt4

Note that all base Chisel util modules, like `Queue`, already implement `desiredName` like this:

    val fooQueue = Module(new Queue(UInt(8.W), 4)) // Verilog module would be named 'Queue4_UInt8' // Verilog module would be named 'Queue4_UInt8'
    val barQueue = Module(new Queue(SInt(12.W), 3)) // ... and 'Queue3_SInt12' // ... and 'Queue3_SInt12'
    val bazQueue = Module(new Queue(Bool(), 16)) // ... and 'Queue16_Bool'

### How would I write my own `typeName` for my data types?​

If you're using your own user-defined `Bundle`, you can increase the specificity of its own `typeName` by overriding it. All `Data` types have a simple default implementation of `typeName` (which is simply its class name), but you can override this yourself:

    class MyBundle[T <: Data](gen: T, intParam: Int) extends Bundle {
      // Generate a stable typeName for this Bundle. Two 'words' are present
      // in this implementation: the bundle's name plus its integer parameter
      // (something like 'MyBundle9')
      // and the generator's typeName, which itself can be composed of 'words'
      // (something like 'Vec3_UInt4')
      override def typeName = s"MyBundle${intParam}_${gen.typeName}"

      // ...
    }

Now if you use your `MyBundle` in a module like a `Queue`:

    val fooQueue = Module(new Queue(new MyBundle(UInt(4.W), 3), 16)) // Queue16_MyBundle3_UInt4

The suggested pattern for `typeName`, and subsequently `desiredName`, is to fold single integer-like parameters with the name itself (for example, `Queue4`, `UInt3`, `MyBundle9`) to form 'words' and separate these 'words' with underscores (`Queue4_UInt3`, `FooBundle_BarType4`).

`Bundles` that have multiple integer arguments aren't presently addressed by any of the built-in modules, and so implementing a descriptive and sufficiently differentiable `typeName` for such `Bundles` is left as an exercise to the reader. However, integers should not occur with an underscore before them at the very end of the `typeName` (e.g. `MyBundle_1`) because this is the same syntax used for duplicates, and so would cause confusion. Having to disambiguate modules all named `Queue32_MyBundle_4_1`, `Queue32_MyBundle_4_2`, `Queue32_MyBundle_4_3`, and so on would be undesirable, indeed!

### I don't want to override `typeName` over and over! Is there any easy way to generate a `typeName`?​

Yes, with the experimental `HasAutoTypename` trait. This trait can be mixed into your `Bundle`s to automatically generate a tuple-like `typeName` for them, based on the constructor parameters of that `Bundle`. Let's look at the previous examples:

    class MyBundle[T <: Data](gen: T, intParam: Int) extends Bundle {
      override def typeName = s"MyBundle_${gen.typeName}_${intParam}"
      // ...
    }

    new MyBundle(UInt(8.W), 3).typeName
    // res7: String = "MyBundle_UInt<8>_3"

Auto-generated `typeName`s take the form of `{Bundle Name}_{Parameter Value 1}_{Parameter Value 2}_{...}`, and so our `MyBundle` can be equivalently expressed with:

    import chisel3.experimental.HasAutoTypename
    class MyBundle[T <: Data](gen: T, intParam: Int) extends Bundle with HasAutoTypename {
      // ...
      // Note: No `override def typeName` statement here
    }

    new MyBundle(UInt(8.W), 3).typeName
    // res9: String = "MyBundle_UInt<8>_3"

### Can I name my bundles in FIRRTL, so I don't generate extremely long bundle types?​

Yes, using the `HasTypeAlias` trait. FIRRTL has a construct to alias a bundle type with a type alias like so:

    circuit Top :
      type MyBundle = { foo : UInt<8>, bar : UInt<1>}

      module Top :
        //...

These can be automatically emitted from Chisel by mixing `HasTypeAlias` into a user-defined `Record`, and implementing a field named `aliasName` with a `RecordAlias(...)` instance.

    import chisel3.experimental.{HasTypeAlias, RecordAlias}

    class AliasedBundle extends Bundle with HasTypeAlias {
      override def aliasName = RecordAlias("MyAliasedBundle")
      val foo = UInt(8.W)
      val bar = Bool()
    }

Let's see what happens when we generate FIRRTL using this `Bundle`:

    emitFIRRTL(new Module {
      val wire = Wire(new AliasedBundle)
    })
    // res10: String = """FIRRTL version 4.0.0
    // circuit _18_Anon :
    //   type MyAliasedBundle = { foo : UInt<8>, bar : UInt<1>}
    //
    //   public module _18_Anon : @[naming.md 252:28]
    //     input clock : Clock @[naming.md 252:28]
    //     input reset : UInt<1> @[naming.md 252:28]
    //
    //     wire wire : MyAliasedBundle @[naming.md 253:18]
    //
    // """

`HasTypeAlias` also supports nested bundles, too:

    class Child extends Bundle with HasTypeAlias {
      override def aliasName = RecordAlias("ChildBundle")
      val x = UInt(8.W)
    }

    class Parent extends Bundle with HasTypeAlias {
      override def aliasName = RecordAlias("ParentBundle")
      val child = new Child
    }

    emitFIRRTL(new Module {
      val wire = Wire(new Parent)
    })
    // res11: String = """FIRRTL version 4.0.0
    // circuit _22_Anon :
    //   type ChildBundle = { x : UInt<8>}
    //   type ParentBundle = { child : ChildBundle}
    //
    //   public module _22_Anon : @[naming.md 275:28]
    //     input clock : Clock @[naming.md 275:28]
    //     input reset : UInt<1> @[naming.md 275:28]
    //
    //     wire wire : ParentBundle @[naming.md 276:18]
    //
    // """

### Why do I keep seeing _stripped suffixing everywhere in my FIRRTL? I didn't specify that in my `aliasName`.​

You're using an `Input(...)` or `Output(...)` in conjunction with an aliased `Record` that contains a `Flipped(...)`. These flipped values are stripped by `Input` and `Output` which fundamentally changes the type of the parent `Record`:

    class StrippedBundle extends Bundle with HasTypeAlias {
      override def aliasName = RecordAlias("StrippedBundle")
      val flipped = Flipped(UInt(8.W))
      val normal = UInt(8.W)
    }

    emitFIRRTL(new Module {
      val in = IO(Input(new StrippedBundle))
    })
    // res12: String = """FIRRTL version 4.0.0
    // circuit _26_Anon :
    //   type StrippedBundle_stripped = { flipped : UInt<8>, normal : UInt<8>}
    //
    //   public module _26_Anon : @[naming.md 293:28]
    //     input clock : Clock @[naming.md 293:28]
    //     input reset : UInt<1> @[naming.md 293:28]
    //     input in : StrippedBundle_stripped @[naming.md 294:14]
    //
    //     skip
    //
    // """

Note how the bundle type doesn't contain a `flip flipped : UInt<8>` field, and the alias gains a `"_stripped"` suffix! This `Bundle` type is no longer the same as the one we wrote in Chisel, so we have to distinguish it as such.

By default, the suffix appended to `Record` names is `"_stripped"`. This can be defined by users with an additional string argument passed to `RecordAlias(alias, strippedSuffix)`:

    class CustomStrippedBundle extends Bundle with HasTypeAlias {
      override def aliasName = RecordAlias("StrippedBundle", "Foo")
      val flipped = Flipped(UInt(8.W))
      val normal = UInt(8.W)
    }

    emitFIRRTL(new Module {
      val in = IO(Input(new CustomStrippedBundle))
    })
    // res13: String = """FIRRTL version 4.0.0
    // circuit _30_Anon :
    //   type StrippedBundleFoo = { flipped : UInt<8>, normal : UInt<8>}
    //
    //   public module _30_Anon : @[naming.md 311:28]
    //     input clock : Clock @[naming.md 311:28]
    //     input reset : UInt<1> @[naming.md 311:28]
    //     input in : StrippedBundleFoo @[naming.md 312:14]
    //
    //     skip
    //
    // """

### I want to add some hardware or assertions, but each time I do all the signal names get bumped!​

This is the classic "ECO" problem, and we provide descriptions in explanation. In short, we recommend wrapping all additional logic in a prefix scope, which enables a unique namespace. This should prevent name collisions, which are what triggers all those annoying signal name bumps!

### I want to force a signal (or instance) name to something, how do I do that?​

Use the `.suggestName` method, which is on all classes which subtype `Data`.

### How can I omit the prefix in certain parts of the code?​

You can use the `noPrefix { ... }` to strip the prefix from all signals generated in that scope.

    import chisel3.experimental.noPrefix

    class ExampleNoPrefix extends Module {
      val in = IO(Input(UInt(2.W)))
      val out = IO(Output(UInt(5.W)))

      val add = noPrefix {
        // foo will not get a prefix
        val foo = RegNext(in + 1.U)
        foo + in
      }

      out := add
    }

    // Generated by CIRCT firtool-1.76.0
    module ExampleNoPrefix(
      input        clock,
                   reset,
      input  [1:0] in,
      output [4:0] out
    );

      reg [1:0] foo;
      always @(posedge clock)
        foo <= in + 2'h1;
      assign out = {3'h0, foo + in};
    endmodule

### I am still not getting the name I want. For example, inlining an instance changes my name!​

In cases where a FIRRTL transform renames a signal/instance, you can use the `forcename` API:

    import chisel3.util.experimental.{forceName, InlineInstance}

    class WrapperExample extends Module {
      val in = IO(Input(UInt(3.W)))
      val out = IO(Output(UInt(3.W)))
      val inst = Module(new Wrapper)
      inst.in := in
      out := inst.out
    }
    class Wrapper extends Module with InlineInstance {
      val in = IO(Input(UInt(3.W)))
      val out = IO(Output(UInt(3.W)))
      val inst = Module(new MyLeaf)
      forceName(inst, "inst")
      inst.in := in
      out := inst.out
    }
    class MyLeaf extends Module {
      val in = IO(Input(UInt(3.W)))
      val out = IO(Output(UInt(3.W)))
      out := in
    }

    // Generated by CIRCT firtool-1.76.0
    module MyLeaf(
      input  [2:0] in,
      output [2:0] out
    );

      assign out = in;
    endmodule

    module WrapperExample(
      input        clock,
                   reset,
      input  [2:0] in,
      output [2:0] out
    );

      MyLeaf inst (
        .in  (in),
        .out (out)
      );
    endmodule

This can be used to rename instances and non-aggregate typed signals.