Skip to content

[Bug] @targetName is rejected on a top-level design class, so a module cannot be emitted under a name other than its Scala class name #454

Description

@soronpo

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions