Compilation
Elaboration
Wildcard Arithmetic Value Checking
When arithmetic operations involve wildcard Int values (Scala Int or DFHDL Int parameters), the wildcard Int value adapts to the bit-accurate value's sign and width. The value is then checked to ensure it fits. This check occurs at three levels, depending on when the value becomes known:
-
Scala compile-time: literal Scala integers have known values, and therefore known minimum widths, at compile time. In
+,-and*that minimum counts as an actual width when the other operand's width is also known at compile time, so the result is the wider of the two and a literal that does not fit widens the operation rather than failing (u8 + 1000isUInt[10]). The Scala compiler still reports an error where widening cannot express the result, namely a negative literal on the left of-,/or%with an unsigned operand, which those LHS-dominant operations cannot represent. Elsewhere the literal adapts, and the compiler reports a value that does not fit. -
DFHDL elaboration-time: non-literal Scala integers (e.g.,
val x: Int = computeValue(); u8 + x) and DFHDLIntconstants whose values are resolved during elaboration. These have no statically known width, so they always adapt, as does any literal meeting a parametric width. A DFHDL elaboration error (Scala runtime error) is generated if the value does not fit. -
Synthesis/simulation-time: DFHDL
Intparameters that are set externally or computed in complex generation loops may not be known until synthesis or simulation. Assertions must be added to verify these values at the target platform level. This is a planned future feature (TODO).
Generated Files
Compiling a design emits one file per design, plus up to two shared files.
| File | Contents |
|---|---|
<Design>.sv |
One file per design in the hierarchy |
dfhdl_defs.svh |
DFHDL's own macros and helper definitions. Always emitted, and `included by every design. Public domain, so it can be redistributed with generated output |
<Top>_defs.svh |
Your design's global declarations, named after the top design. Emitted only when something needs to be shared across designs |
| File | Contents |
|---|---|
<Design>.vhd |
One file per design in the hierarchy |
dfhdl_pkg.vhd |
DFHDL's own helper package. Always emitted |
<Top>_pkg.vhd |
Your design's global package, named after the top design. Emitted only when something needs to be shared across designs |
The global definitions file
A declaration goes into <Top>_defs.svh / <Top>_pkg.vhd when more than one design must name it. The common case is an enum appearing in a port type, since the two modules on either side of the connection have to agree on the type:
1 2 3 4 5 6 7 8 9 10 11 | |
| Foo_defs.svh | |
|---|---|
1 2 3 4 5 6 7 | |
| Foo.sv | |
|---|---|
1 2 3 4 5 6 7 8 | |
| Foo_pkg.vhd | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
Had State been used only inside a single design, no <Top>_defs file would be emitted at all and the typedef would sit inside that one module. The placement follows the usage, not the Scala declaration site.