Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
7757da5
add `FALL_THROUGH` loop tagging
Feb 8, 2026
4374cb4
Enhance documentation for `FALL_THROUGH` loop tagging to clarify its …
Feb 8, 2026
1b75fb0
update dependencies
Feb 8, 2026
f012d41
add `fallThrough` condition method for step blocks
Feb 8, 2026
87b6e40
reenable refCheck
Feb 8, 2026
407a02d
update DropRTProcess stage to handle fallThrough blocks
Feb 9, 2026
1f9c03e
update DropRTWaits stage to start stage numbering from 0 and add supp…
Feb 10, 2026
9f97878
Add getOwnerProcessBlock method to DFMember for retrieving owning Pro…
Feb 10, 2026
d8cd496
Refactor Bind unapply method to use hasTagOf for clarity and improve …
Feb 10, 2026
ff1e8ca
1. add checks for forbidden named values except for iterators and bin…
Feb 10, 2026
595762a
Update DFC initialization in MetaDesign to include position from posi…
Feb 10, 2026
066be30
add DFHDL DFVal ident wrapper for trivial `val y = x` ident expressio…
Feb 11, 2026
37e63ac
reenable RT process named variables, to be handled in a new stage
Feb 11, 2026
193e821
fix ExplicitNamedVars stage for a simple named ident use-case
Feb 16, 2026
1e1922c
patch `RefFilter.All` needs to be a case object
Feb 16, 2026
d809e60
Refactor DFVal read dependencies to use a type alias for improved cla…
Feb 17, 2026
3d7b8e9
fix and expand patching edge cases
Feb 17, 2026
d20b5c9
add shortFilePath to MetaContext
Feb 17, 2026
8e5527c
fix comment
Feb 18, 2026
e3dcf3c
Add initial step definition for RT processes without leading steps, w…
Feb 19, 2026
5290ba1
fix rt-process while loop internal step block detection
Mar 20, 2026
eaed3c7
fix rt-process for loop internal step blocks and introduce `PosKey` c…
Mar 20, 2026
cd63116
fix: missing for loop naming
Mar 20, 2026
834264a
Enhance step naming in DropRTWaits stage to support explicit naming f…
Mar 20, 2026
feb4016
enhance FSMs so that step names can be repeated in different scopes
Mar 21, 2026
e8fd877
Refine nested step naming conventions in DropRTWaits stage to prevent…
Mar 21, 2026
f7baa5f
first claude instructions and skills
Mar 21, 2026
07af0ec
introduce FlattenStepBlock stage
Mar 22, 2026
d3d7532
updates to new-stage skill
Mar 22, 2026
448f1aa
update DropRTProcess to depend on FlattenStepBlocks and the tests to …
Mar 22, 2026
55c0d66
add documentation for DropRTProcess and fix the width of the enumerat…
Mar 22, 2026
f28da13
better support while running through sbtn
Mar 22, 2026
f9e52af
add DropRTProcess to dependencies in ToED stage
Mar 22, 2026
ebb6cec
enhance documentation for new stage creation with lessons learned and…
Mar 22, 2026
c72f2db
add instructions for creating or modifying compiler stages in Claude …
Mar 22, 2026
c0cc28e
update DropLocalDcls documenation
Mar 23, 2026
e3c944f
add ExplicitNamedVars and DropLocalDcls to dependencies in FlattenSte…
Mar 23, 2026
2635739
enhance SimplifyRTOps with detailed transformation rules and add test…
Mar 23, 2026
e5a9d82
enhance new-stage documentation with additional transformation patter…
Mar 23, 2026
ef36f1c
enhance FlattenStepBlocks with improved handling of inter-step statem…
Mar 23, 2026
89eeadc
enhance new-stage documentation to clarify contributions for both add…
Mar 23, 2026
17e54d9
enhance DropRTWaits to handle empty while loops and add corresponding…
Mar 23, 2026
0064ba2
enhance SanityCheck to validate ownership consistency in conditional …
Mar 23, 2026
7ed981d
enhance DropRTWaits to maintain ownership structure in if/else blocks…
Mar 23, 2026
f792683
enhance SimplifyRTOps to refine for loop transformation rules and add…
Mar 23, 2026
a6aa29e
enhance DropUnreferencedAnons to remove unreferenced DFRange instance…
Mar 23, 2026
d8a5ae2
fix caching of relative step goto calls
Mar 23, 2026
d845529
wip params
Mar 25, 2026
8c076f0
design parameters partially working after claude unique workarounds. …
Mar 25, 2026
6624d5f
new runtime solution for design parameters. still some problematic st…
Mar 25, 2026
888127e
refactor SanityCheck to improve violation reporting and hierarchy dis…
Mar 25, 2026
ace1e95
internal handling of patch global member references
Mar 26, 2026
e22c524
fix GlobalizePortVectorParams class name to have Spec
Mar 26, 2026
f3a0250
wip GlobalizePortVectorParams
Mar 26, 2026
1272244
GlobalizePortVectorParams working
Mar 26, 2026
dca953f
fix ordering after design parameter change
Mar 26, 2026
7f74168
remove redundant named value in RT process elaboration test
Mar 27, 2026
489061d
finish refactoring of design parameters. all tests green
Mar 27, 2026
ae5deb2
update skill after changed
Mar 27, 2026
7d0d242
enhance patching logic to support concatenation of additions with Bef…
Mar 28, 2026
f55e791
wip: better design deduplication
Mar 29, 2026
16f454a
fix last stage errors after better design deduplication. still have e…
Mar 29, 2026
70723b7
wip
Mar 29, 2026
2bed647
wip
Mar 29, 2026
be5c3cb
fix duplication logic to recursively handle nested design instances i…
Mar 30, 2026
488ee5a
zero members in deduplication. all tests are green.
Mar 30, 2026
5468e7d
refactor duplication logic to compute domain blocks and ports in a si…
Mar 30, 2026
7787105
update skills
Mar 30, 2026
c87cee6
bump versions for scalafmt and dependencies to latest stable releases
Mar 30, 2026
3196613
remove redundant global files inclusion when empty
Mar 30, 2026
d0002a3
further removal of redundant package inclusion and option to rename t…
Mar 30, 2026
e0af931
add some info about processes
Mar 30, 2026
dd334c2
remove unused signal lint-off comments and clean up code
Mar 30, 2026
a76e6a2
docs: address knowledge gaps from UART translation tickets
soronpo Mar 31, 2026
d60007c
docs: recommend enums for FSM matching, use UInt.until for width comp…
soronpo Mar 31, 2026
03976e2
define unique case for local system verilog enumeration
Mar 31, 2026
31891d3
Merge branch 'training' of https://github.com/DFiantHDL/dfhdl_by_agen…
Mar 31, 2026
ff5e021
docs: dynamic indexing, UInt slicing, FSM patterns, OUT init, auto-li…
soronpo Mar 31, 2026
c6e3324
docs: type conversions, shift ops, Bit operators, enum unique case, B…
soronpo Apr 1, 2026
5b62b09
fix and improve logical operators for Verilog.
Apr 1, 2026
454ec72
docs: clarify terminology for Bit/Boolean operators in DFHDL
Apr 1, 2026
5daa657
clarify keyword workaround
Apr 1, 2026
9eaabce
fix explicit named vars for ED domains
Apr 1, 2026
fdafbac
fix vector of Bit to/from Bits conversion
Apr 1, 2026
0923c36
remove redundant def/pkg files from comparison
Apr 1, 2026
a28bbdc
clarifying bits initialization or assignment with integers
Apr 1, 2026
adc1a87
update all admonitions to the new style
Apr 1, 2026
e79ba9c
More clarification on the naming collisions with scala keywords
Apr 2, 2026
e9f73d0
missing closing block
Apr 2, 2026
275f5f6
better placement of admonition
Apr 2, 2026
ff70d8d
docs: clarifying more conversions
Apr 2, 2026
6b0fc69
docs: no need for escaping `|` values in code segments in tables
Apr 2, 2026
cd81632
docs: move and improve documentation on `rising` and `falling` operat…
Apr 2, 2026
f6a9fbd
docs: document the arithmetic operations and their constraints
Apr 3, 2026
d1c2e1c
feat: auto-promote anonymous arithmetic to carry ops on wider assignment
Apr 3, 2026
ba9a871
docs: wip unifying operation sections
Apr 3, 2026
8fd9987
docs: overhaul of the type-system document
Apr 3, 2026
20f674b
docs: define how Bits can be used in arithmetic
Apr 3, 2026
f0e6334
docs: add physical operations
Apr 3, 2026
ef2b601
docs: add more operation examples
Apr 3, 2026
e646a26
docs: clarification on using clog2
Apr 3, 2026
1c61d16
docs: add guidance for multi-file scala-cli projects
Apr 3, 2026
97cae07
docs: wip verilog transitioning chapter
Apr 3, 2026
93b70c8
docs: improved FSM example
Apr 3, 2026
8eed180
docs: bounded and unbounded types and signatures
Apr 3, 2026
c7668af
docs: document Selection `.sel` operation
Apr 3, 2026
8e85c2d
docs: fix confusing example
Apr 3, 2026
c198db3
fix: parameterized bit selection
Apr 3, 2026
af57708
docs: provide unbounded bits and parametric dependency example
Apr 3, 2026
fc2d578
docs: improve shift example
Apr 3, 2026
98153eb
docs: removed problematic type examples, since there is much more inf…
Apr 3, 2026
88cf299
docs: parametric Bits constants, dynamic index truncation, Int bits s…
soronpo Apr 3, 2026
c8d6a78
docs: reduction ops, Bits comparisons, part-select, signed arithmetic…
soronpo Apr 3, 2026
dd04f98
docs: emphasize state machine with reset
Apr 3, 2026
4a2bb29
fix: prevent wrong alias reduction. fixes https://github.com/DFiantHD…
Apr 4, 2026
099f99a
fix: proper signed parameterized literal generation in verilog. fixes…
Apr 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
992 changes: 992 additions & 0 deletions .claude/commands/ir-reference.md

Large diffs are not rendered by default.

1,047 changes: 1,047 additions & 0 deletions .claude/commands/new-stage.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.10.5
version = 3.10.7
runner.dialect = scala3

maxColumn = 100
Expand Down
116 changes: 116 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# DFHDL — Claude Code Guide

> **For contributors and Claude Code users working on the DFHDL project.**
> This file is version-controlled — keep it updated as the project structure evolves.
> Skills for deeper topics live in [.claude/commands/](.claude/commands/).

## Project Overview

**DFHDL (DFiant HDL)** is a dataflow hardware description language embedded as a Scala 3 library. It provides timing-agnostic and device-agnostic hardware design with three levels of abstraction:

- **Dataflow (DF)**: Timing-agnostic, uses dataflow firing rules
- **Register-Transfer (RT)**: Equivalent to Chisel/Amaranth
- **Event-Driven (ED)**: Equivalent to Verilog/VHDL

Outputs: Verilog, SystemVerilog, VHDL.

## Build System

**Tool**: SBT 1.12.2 — **Scala**: 3.8.1 (nightly resolver enabled)

```bash
sbt compile # compile all subprojects
sbt test # run all unit tests
sbt testApps # run simulation/app tests (requires OSS CAD tools)
sbt quickTestSetup # limit test scope to lib/Playground.scala only (fast iteration)
sbt clearSandbox # delete sandbox/ directory
sbt docExamplesRefUpdate # copy generated HDL from sandbox/ to lib/src/test/resources/ref/
```

## Subproject Structure

Dependencies flow left to right:

```
internals → plugin → compiler_ir → core → compiler_stages → lib → platforms
→ ips
```

| Subproject | SBT name | Directory | Purpose |
|---|---|---|---|
| internals | `internals` | `internals/` | Core utilities: BitVector, MetaContext, DiskCache, etc. |
| plugin | `plugin` | `plugin/` | Scala 3 compiler plugin (9 phases) |
| compiler_ir | `compiler_ir` | `compiler/ir/` | IR/AST data structures, type system |
| core | `core` | `core/` | HDL language abstractions (DFVal, DFType, Design) |
| compiler_stages | `compiler_stages` | `compiler/stages/` | 50+ transformation stages for code generation |
| lib | `lib` | `lib/` | Standard library: arithmetic, memory, ALU, crypto |
| platforms | `platforms` | `platforms/` | FPGA board wrappers (Apache 2.0 licensed) |
| ips | `ips` | `ips/` | IP cores library |

## Compiler Plugin Phases

Located in `plugin/src/main/scala/plugin/`:

1. `PreTyperPhase` — pre-typing transformations
2. `TopAnnotPhase` — top-level annotation processing
3. `MetaContextPlacerPhase` — places meta-context markers
4. `LoopFSMPhase` — loop-to-FSM transformations
5. `CustomControlPhase` — custom control flow
6. `DesignDefsPhase` — design definition processing
7. `MetaContextDelegatePhase` — meta-context delegation
8. `MetaContextGenPhase` — meta-context code generation
9. `OnCreateEventsPhase` — on-create event handling

The plugin is applied to `core`, `compiler_stages`, `lib`, `platforms`, and `ips` via `pluginUseSettings` / `pluginTestUseSettings`.

## Testing

**Framework**: munit 1.2.2

- **Stage tests**: `compiler/stages/src/test/scala/StagesSpec/` — tests each compiler stage
- **Doc example tests**: `lib/src/test/scala/docExamples/` — validates documentation examples
- **Arithmetic tests**: `lib/src/test/scala/ArithSpec/`
- **AES tests**: `lib/src/test/scala/AES/`
- **Base class**: `DesignSpec` — provides `assertCodeString()` and `assertElaborationErrors()`
- **Playground**: `lib/src/test/scala/Playground.scala` — used for quick local iteration via `quickTestSetup`

Generated HDL reference files live in `lib/src/test/resources/ref/`. Update them with `sbt docExamplesRefUpdate` after intentional output changes.

`testApps` auto-detects installed simulation tools (ghdl, nvc, verilator, iverilog, questa, vivado) and runs the AES cipher simulation against all available tool/dialect combinations.

## Code Conventions

- **Formatting**: scalafmt 3.10.6, max 100 columns, Scala 3 dialect
- Optional braces removed (`removeOptionalBraces = oldSyntaxToo`)
- End markers inserted for blocks ≥ 15 lines
- Run `scalafmt` before committing
- **Compiler flags**: `-language:strictEquality`, `-unchecked`, `-feature`, `-preview`, `-deprecation`
- **Implicit conversions**: only enabled in `internals` and `compiler_ir` via `implicitConversionSettings`
- **Naming**: `DF`-prefixed types (e.g., `DFVal`, `DFType`), `DFC` for context; stage names follow `Drop*`, `Add*`, `Connect*`, `Break*` patterns
- **Package root**: `dfhdl.*`

## Key Files

| File | Purpose |
|---|---|
| `build.sbt` | Multi-project build definition |
| `project/DFHDLCommands.scala` | Custom SBT commands |
| `.scalafmt.conf` | Code formatting rules |
| `mkdocs.yml` | Documentation site config |
| `sandbox/` | Generated output during tests/apps (gitignored, cleared by `clearSandbox`) |
| `lib/src/test/resources/ref/` | Reference HDL output snapshots for regression tests |

## External Simulation Tools (for `testApps`)

CI installs these via OSS CAD Suite:
- **Verilog**: verilator, iverilog (sv2005 skipped for iverilog), questa, vivado
- **VHDL**: ghdl, nvc, questa, vivado (v2008 skipped for vivado)

## Claude Instructions

- When asked to **create a new compiler stage** or **modify an existing compiler stage**, always invoke the `/new-stage` skill before doing any work.

## Licenses

- Main library (`internals`, `plugin`, `compiler_ir`, `core`, `compiler_stages`, `lib`, `ips`): **LGPL v3.0**
- `platforms/`: **Apache 2.0**
10 changes: 5 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ lazy val platforms = project
lazy val dependencies =
new {
private val scodecV = "1.2.4"
private val munitV = "1.2.2"
private val airframelogV = "2025.1.27"
private val oslibV = "0.11.7"
private val scallopV = "5.3.0"
private val upickleV = "4.4.2"
private val munitV = "1.2.4"
private val airframelogV = "2026.1.4"
private val oslibV = "0.11.8"
private val scallopV = "6.0.0"
private val upickleV = "4.4.3"

val scodec = "org.scodec" %% "scodec-bits" % scodecV
val munit = "org.scalameta" %% "munit" % munitV % Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ object StrippedPortByNameSelect:
object DefaultOfDesignParam:
def unapply(dfVal: DFVal)(using MemberGetSet): Option[DFVal.DesignParam] =
dfVal.originMembers.collectFirst {
case dp: DFVal.DesignParam if dp.defaultRef.get == dfVal => dp
case dp: DFVal.DesignParam if dp.defaultValRef.get == dfVal => dp
}

object OpaqueActual:
Expand All @@ -84,8 +84,7 @@ object AsOpaque:

object Bind:
def unapply(alias: DFVal.Alias)(using MemberGetSet): Option[DFVal] =
if (alias.getTagOf[BindTag].isDefined)
Some(alias.relValRef.get)
if (alias.hasTagOf[BindTag]) Some(alias.relValRef.get)
else None

object ClkEdge:
Expand Down Expand Up @@ -200,6 +199,8 @@ extension (member: DFMember)
def originMembersNoTypeRef(using MemberGetSet): Set[DFMember] =
getSet.designDB.originMemberTableNoTypeRef.getOrElse(member, Set())

type DFValReadDep = TextOut | DFNet | DFVal | DFConditional.Block

extension (dfVal: DFVal)
def getPartialAliases(using MemberGetSet): Set[DFVal.Alias.Partial] =
dfVal.originMembers.flatMap {
Expand Down Expand Up @@ -234,8 +235,8 @@ extension (dfVal: DFVal)
dfVal.originMembers.view
.collect { case dfVal: DFVal => dfVal }
.exists(dfVal => cond(dfVal) || dfVal.existsInComposedReadDeps(cond))
def getReadDeps(using MemberGetSet): Set[TextOut | DFNet | DFVal | DFConditional.Block] =
val fromRefs: Set[TextOut | DFNet | DFVal | DFConditional.Block] =
def getReadDeps(using MemberGetSet): Set[DFValReadDep] =
val fromRefs: Set[DFValReadDep] =
dfVal.originMembersNoTypeRef.flatMap {
case net: DFNet =>
net match
Expand All @@ -260,12 +261,13 @@ extension (dfVal: DFVal)
.toSet ++ fromRefs
case _ => fromRefs
end getReadDeps
def isReferencedByAnyDcl(using MemberGetSet): Boolean =
def isReferencedByAnyDclOrDesign(using MemberGetSet): Boolean =
dfVal.originMembers.view.exists {
case _: DFVal.Dcl => true
case DclConst() => true
case dfVal: DFVal => dfVal.isReferencedByAnyDcl
case _ => false
case _: DFVal.Dcl => true
case DclConst() => true
case _: DFDesignBlock => true
case dfVal: DFVal => dfVal.isReferencedByAnyDclOrDesign
case _ => false
}

@tailrec private def flatName(member: DFVal, suffix: String)(using MemberGetSet): String =
Expand Down Expand Up @@ -415,11 +417,12 @@ extension (origVal: DFVal)
forceIncludeOrigVal: Boolean
)(using MemberGetSet): List[DFVal] =
if (origVal.isAnonymous && !origVal.isGlobal || forceIncludeOrigVal)
origVal :: origVal.getRefs.map(_.get).view
.flatMap {
case dfVal: DFVal => dfVal.collectRelMembersRecur(false)
case _ => Nil
}.toList
origVal ::
origVal.getRefs.map(_.get).view
.flatMap {
case dfVal: DFVal => dfVal.collectRelMembersRecur(false)
case _ => Nil
}.toList
else Nil
@targetName("collectRelMembersDFVal")
def collectRelMembers(includeOrigVal: Boolean)(using MemberGetSet): List[DFVal] =
Expand Down
Loading
Loading