Context
Translating HOG_fpga/src/top.v (Mahmoud-geberty/HOG_fpga), whose Verilog module is named top (an extremely common convention for a design's top-level module). The equivalent knowledge-gap ticket dfhdl_by_agents#82 already documents that a DFHDL design class named top collides with DFHDL's internal @top annotation/detection mechanism, and that renaming the class is the only known workaround (@targetName cannot help either, since it is rejected on a top-level class — DFHDL#454). This ticket is the companion bug report for the error message itself, which #82 did not file separately.
Minimal reproduction (verified against 0.22.0+39-03afffb1-SNAPSHOT)
import dfhdl.*
class top extends EDDesign:
val i = Bit <> IN
val o = Bit <> OUT
o <> i
scala run src/ --scala 3.8.4 \
--dep "io.github.dfianthdl::dfhdl::$V" \
--compiler-plugin "io.github.dfianthdl:::dfhdl-plugin::$V" \
-O -deprecation -M top -- --nocache commit
Full verbatim error text
[error] ./src/top.scala:3:7
[error] Cyclic reference involving class top
[error]
[error] Run with -explain-cyclic for more details.
[error] class top extends EDDesign:
[error] ^
Warning: 1 error found
With -explain-cyclic added, the only extra detail is:
[error] The error occurred while trying to compute the signature of class top
[error] which required to compute the signature of class top
Confirmed fix
Renaming the class only (identical body, identical file otherwise) compiles cleanly:
import dfhdl.*
class topOk extends EDDesign:
val i = Bit <> IN
val o = Bit <> OUT
o <> i
This is the only variable changed between the failing and succeeding runs, isolating the cause to the identifier top itself, not anything about the class body.
Where I expected the error to point vs. where it pointed
I expected either: (a) a normal Scala compile error about the body (there is nothing wrong with the body), or (b) if this is truly a reserved-name collision, a message naming the collision (e.g. "the name top is reserved for the internal @top mechanism; rename the design class"). Instead the position and message both describe a self-referential signature computation ("Cyclic reference ... which required to compute the signature of class top"), which reads as if the class's own member declarations form a genuine dependency cycle. Nothing in the class body is self-referential — the file is 5 lines with no forward references at all.
What I thought the message meant vs. what was actually wrong
I initially assumed I had introduced a real forward-reference cycle (e.g. a val in the class referencing another val defined later, or a parameter default depending on a sibling parameter — a distinct, real limitation I hit and confirmed separately, filed as dfhdl_by_agents#115). I spent several compile/bisect iterations removing and re-adding class members (parameters, port declarations, child instantiations, a multi-branch if/else body) looking for a genuine self-reference in the body, all while the true cause was the bare identifier top used as the class name, unrelated to anything in the body. Only exhaustive bisection — reducing the file to 5 lines and then renaming just the class — revealed the real cause.
Suggested clearer message
Since DFHDL already detects and auto-applies its own @top-related mechanism for the class name top (per dfhdl_by_agents#82), the compiler plugin has enough information at this point to name the actual conflict, e.g.:
error: the design class name `top` conflicts with DFHDL's internal `@top` mechanism.
Rename the class (the generated module name can be restored with `@targetName`,
except this is not currently supported for top-level classes — see DFHDL#454).
That would turn a multi-iteration debugging session into an immediate, actionable fix.
Cross-references
dfhdl_by_agents#82 — the knowledge-gap side (docs should list top as a reserved name).
DFHDL#454 — @targetName rejected on a top-level design class, which forecloses the natural "keep the class name different, restore the module name" workaround.
Version
0.22.0+39-03afffb1-SNAPSHOT
Context
Translating
HOG_fpga/src/top.v(Mahmoud-geberty/HOG_fpga), whose Verilog module is namedtop(an extremely common convention for a design's top-level module). The equivalent knowledge-gap ticketdfhdl_by_agents#82already documents that a DFHDL design class namedtopcollides with DFHDL's internal@topannotation/detection mechanism, and that renaming the class is the only known workaround (@targetNamecannot help either, since it is rejected on a top-level class — DFHDL#454). This ticket is the companion bug report for the error message itself, which #82 did not file separately.Minimal reproduction (verified against
0.22.0+39-03afffb1-SNAPSHOT)Full verbatim error text
With
-explain-cyclicadded, the only extra detail is:Confirmed fix
Renaming the class only (identical body, identical file otherwise) compiles cleanly:
This is the only variable changed between the failing and succeeding runs, isolating the cause to the identifier
topitself, not anything about the class body.Where I expected the error to point vs. where it pointed
I expected either: (a) a normal Scala compile error about the body (there is nothing wrong with the body), or (b) if this is truly a reserved-name collision, a message naming the collision (e.g. "the name
topis reserved for the internal@topmechanism; rename the design class"). Instead the position and message both describe a self-referential signature computation ("Cyclic reference ... which required to compute the signature of class top"), which reads as if the class's own member declarations form a genuine dependency cycle. Nothing in the class body is self-referential — the file is 5 lines with no forward references at all.What I thought the message meant vs. what was actually wrong
I initially assumed I had introduced a real forward-reference cycle (e.g. a
valin the class referencing anothervaldefined later, or a parameter default depending on a sibling parameter — a distinct, real limitation I hit and confirmed separately, filed asdfhdl_by_agents#115). I spent several compile/bisect iterations removing and re-adding class members (parameters, port declarations, child instantiations, a multi-branchif/elsebody) looking for a genuine self-reference in the body, all while the true cause was the bare identifiertopused as the class name, unrelated to anything in the body. Only exhaustive bisection — reducing the file to 5 lines and then renaming just the class — revealed the real cause.Suggested clearer message
Since DFHDL already detects and auto-applies its own
@top-related mechanism for the class nametop(perdfhdl_by_agents#82), the compiler plugin has enough information at this point to name the actual conflict, e.g.:That would turn a multi-iteration debugging session into an immediate, actionable fix.
Cross-references
dfhdl_by_agents#82— the knowledge-gap side (docs should listtopas a reserved name).DFHDL#454—@targetNamerejected on a top-level design class, which forecloses the natural "keep the class name different, restore the module name" workaround.Version
0.22.0+39-03afffb1-SNAPSHOT