Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Naming Plugin and Object Pattern

Open
#5,430 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
54/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
scala
Domain
compilers

Research direction

Start with the Foo and Bar reproducer in the issue and compare their emitted SystemVerilog, focusing on how the naming plugin derives the register name for RegNext(io.a). Trace the object-pattern prefix("io") handling and verify that Bar's register receives the same io_ prefix as Foo, producing io_b_REG.

Written by the indexing model from the issue text.

Description

I've been using a pattern of wrapping hardware in an object to provide namespacing. This has been useful because it enables a direct conversion of an anonymous bundle pattern like val io = IO(new Bundle { }) to something which is more amenable to adding domain information. However, this pattern doesn't work correctly with the naming plugin.

Consider:

//> using repository https://central.sonatype.com/repository/maven-snapshots
//> using scala 2.13.18
//> using dep org.chipsalliance::chisel:7.13.0+23-b2a0e030-SNAPSHOT
//> using plugin org.chipsalliance:::chisel-plugin:7.13.0+23-b2a0e030-SNAPSHOT
//> using options -unchecked -deprecation -language:reflectiveCalls -feature -Xcheckinit
//> using options -Xfatal-warnings -Ywarn-dead-code -Ywarn-unused -Ymacro-annotations

import chisel3._
import chisel3.experimental.prefix
import circt.stage.ChiselStage

class Foo extends Module {
  val io = IO {
    new Bundle {
      val a = Input(Bool())
      val b = Output(Bool())
    }
  }

  io.b := RegNext(io.a)
}

class Bar extends Module {
  object io {
    val a = IO(Input(Bool()))
    val b = IO(Output(Bool()))
  }
  prefix("io")(io)

  io.b := RegNext(io.a)
}

object Main extends App {
  println(
    ChiselStage.emitSystemVerilog(
      gen = new Foo,
      firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info", "-default-layer-specialization=enable")
    )
  )
  println(
    ChiselStage.emitSystemVerilog(
      gen = new Bar,
      firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info", "-default-layer-specialization=enable")
    )
  )
}

The above produces the following Verilog:

// Generated by CIRCT firtool-1.151.0
module Foo(
  input  clock,
         reset,
         io_a,
  output io_b
);

  reg io_b_REG;
  always @(posedge clock)
    io_b_REG <= io_a;
  assign io_b = io_b_REG;
endmodule


// Generated by CIRCT firtool-1.151.0
module Bar(
  input  clock,
         reset,
         io_a,
  output io_b
);

  reg b_REG;
  always @(posedge clock)
    b_REG <= io_a;
  assign io_b = b_REG;
endmodule

It seems like these should produce the same thing. Given that b has a prefix of io_. However, this doesn't get used when determining the name of the register with the object pattern.

Dominant language
Scala
Stars
4.8k
Forks
662
Avg merge
1d 23h
Merged PRs (30d)
9

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from chipsalliance/chisel

All issues in chipsalliance/chisel

Similar issues

More Scala issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.