Summary
@targetName works on a port or variable, where it sets the emitted HDL name. On a design class it is rejected outright by the Scala compiler, so there is no way to emit a module under a name different from its Scala class name.
This matters for Verilog/VHDL translation, where the natural goal is to keep Scala naming style on the Scala side (class DataPath) while emitting the original module name (data_path). Today the only route is to spell the Scala class in the original HDL style.
Reproduction
DFHDL version: 0.22.0+38-ba527c30-SNAPSHOT (scala-cli / Scala 3.8.4, JVM 25). Backend: verilog.
import dfhdl.*
import scala.annotation.targetName
@targetName("data_path")
class DataPath(
val WIDTH: Int <> CONST = 8
) extends EDDesign:
val o = Bits(WIDTH) <> OUT
o <> all(0)
end DataPath
class p9 extends EDDesign:
val o = Bits(8) <> OUT
val u_dp = new DataPath(8)
o <> u_dp.o
end p9
Full verbatim output:
[error] ./src/p9.scala:6:7
[error] @targetName annotation not allowed on top-level class DataPath
[error] class DataPath(
[error] ^
Warning: 1 error found
Error compiling project (Scala 3.8.4, JVM (25))
Compilation failed
The rejection comes from Scala itself, not from DFHDL: @targetName sets the name a definition carries in the generated bytecode, and a top-level class's bytecode name is fixed by its source name and file. So this is not a matter of DFHDL reading the annotation differently, and any fix would need a DFHDL-side mechanism.
Contrast: the same annotation on a port works
import dfhdl.*
import scala.annotation.targetName
class filter(
val WIDTH: Int <> CONST = 8
) extends EDDesign:
@targetName("data_out")
val dataOut = Bits(WIDTH) <> OUT
dataOut <> all(0)
end filter
emits, as expected:
module filter#(parameter int WIDTH = 8)(
output logic [WIDTH - 1:0] data_out
);
`include "dfhdl_defs.svh"
assign data_out = {WIDTH{1'b0}};
endmodule
So the annotation is honored for values but has no counterpart for designs.
Suggested fix
Provide a DFHDL-side way to set a design's emitted module name independently of its Scala class name. A dedicated annotation (for example @hdlName("data_path")) would avoid the top-level restriction entirely, since it would be read by DFHDL's elaboration rather than by the Scala backend. Honoring @targetName where Scala does allow it (a nested class) would only cover part of the case, since translated designs are normally top-level.
Documentation note
docs/user-guide/naming/index.md currently documents @targetName on a design class as a working way to preserve an original lowercase module name. That documentation describes the intended behavior and is being kept as-is pending this issue; it does not reflect what the compiler accepts today.
Summary
@targetNameworks on a port or variable, where it sets the emitted HDL name. On a design class it is rejected outright by the Scala compiler, so there is no way to emit a module under a name different from its Scala class name.This matters for Verilog/VHDL translation, where the natural goal is to keep Scala naming style on the Scala side (
class DataPath) while emitting the original module name (data_path). Today the only route is to spell the Scala class in the original HDL style.Reproduction
DFHDL version:
0.22.0+38-ba527c30-SNAPSHOT(scala-cli / Scala 3.8.4, JVM 25). Backend: verilog.Full verbatim output:
The rejection comes from Scala itself, not from DFHDL:
@targetNamesets the name a definition carries in the generated bytecode, and a top-level class's bytecode name is fixed by its source name and file. So this is not a matter of DFHDL reading the annotation differently, and any fix would need a DFHDL-side mechanism.Contrast: the same annotation on a port works
emits, as expected:
So the annotation is honored for values but has no counterpart for designs.
Suggested fix
Provide a DFHDL-side way to set a design's emitted module name independently of its Scala class name. A dedicated annotation (for example
@hdlName("data_path")) would avoid the top-level restriction entirely, since it would be read by DFHDL's elaboration rather than by the Scala backend. Honoring@targetNamewhere Scala does allow it (a nested class) would only cover part of the case, since translated designs are normally top-level.Documentation note
docs/user-guide/naming/index.mdcurrently documents@targetNameon a design class as a working way to preserve an original lowercase module name. That documentation describes the intended behavior and is being kept as-is pending this issue; it does not reflect what the compiler accepts today.