chipsalliance / chipsalliance/chisel

Naming Plugin and Object Pattern

Open
#5,430 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
4.8k
Forks
658
Avg merge
18h 59m
Merged PRs (30d)
14

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:

``` scala
//> 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:

``` 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.

Contributor guide

Open the contributing guide

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.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.