Naming Cookbook

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)
      }
    }
  }
}
module ExamplePrefix(
  input   clock,
  input   reset
);
  wire [7:0] loop_0_0_x = 8'h0; // @[naming.md 25:{25,25}]
  wire [7:0] loop_0_1_x = 8'h1; // @[naming.md 25:{25,25}]
  wire [7:0] loop_1_0_x = 8'h10; // @[naming.md 25:{25,25}]
  wire [7:0] loop_1_1_x = 8'h11; // @[naming.md 25:{25,25}]
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
    when (in === j.U) { prefix(s"clause_${j}"){
      val foo = Wire(UInt(4.W))
      foo := in +& j.U(4.W)
      out := foo
    }}
  }
}
module ExampleWhenPrefix(
  input        clock,
  input        reset,
  input  [3:0] in,
  output [3:0] out
);
  wire [4:0] _clause_1_foo_T = in + 4'h1; // @[naming.md 53:17]
  wire [3:0] clause_1_foo = _clause_1_foo_T[3:0]; // @[naming.md 52:21 53:11]
  wire [4:0] _clause_2_foo_T = in + 4'h2; // @[naming.md 53:17]
  wire [3:0] clause_2_foo = _clause_2_foo_T[3:0]; // @[naming.md 52:21 53:11]
  assign out = in == 4'h2 ? clause_2_foo : clause_1_foo; // @[naming.md 51:23 54:11]
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!

My module names are super unstable - I change one thing and Queue_1 becomes Queue_42. Help!

This is the infamous Queue instability problem. In general, these cases are best solved at the source - the module itself! If you overwrite desiredName to include parameter information (see the explanation for more info), then this can avoid this problem permanantly. We’ve done this with some Chisel utilities with great results!

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()))

  val add = noPrefix { in + in + in }

  out := add
}
module ExampleNoPrefix(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] _T_1 = in + in; // @[naming.md 76:27]
  assign out = _T_1 + in; // @[naming.md 76:32]
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
}
module MyLeaf(
  input  [2:0] in,
  output [2:0] out
);
  assign out = in; // @[naming.md 116:7]
endmodule
module WrapperExample(
  input        clock,
  input        reset,
  input  [2:0] in,
  output [2:0] out
);
  wire [2:0] inst_in;
  wire [2:0] inst_out;
  wire [2:0] inst_in; // @[naming.md 106:20]
  wire [2:0] inst_out; // @[naming.md 106:20]
  MyLeaf inst ( // @[naming.md 106:20]
    .in(inst_in),
    .out(inst_out)
  );
  assign inst_out = inst_out; // @[naming.md 109:7]
  assign inst_in = inst_in; // @[naming.md 108:11]
  assign out = inst_out; // @[naming.md 99:7]
  assign inst_in = in; // @[naming.md 98:11]
endmodule

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