chipsalliance / chipsalliance/chisel
Naming Plugin and Object Pattern
- 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
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