Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
c3a86da
add fork-join support, local blocks via `locally`, and `DropForkJoins…
Jun 7, 2026
b184a9c
fix flaky iverilog execution
Jun 7, 2026
4befd13
update to Scala 3.8.4 and munit update
Jun 7, 2026
9f4b401
add support for RT process fork-join-all, and disable lowering of for…
Jun 8, 2026
96d5706
minimize references to process.forever
Jun 8, 2026
ad1b459
prepare for Scala 3.9.0
Jun 9, 2026
d9a8966
improve error positioning and messaging in more nested error cases
Jun 9, 2026
2fef908
add checks for error positioning
Jun 9, 2026
6933ade
fix runtime positions
Jun 10, 2026
7970d27
Migrate RT clk/rst domain analyses and 3 stages to hierarchical DB
Jun 13, 2026
fbee335
Add hierarchical new_magnetConnectionMap (cross-design magnet matching)
Jun 13, 2026
6845e71
Migrate magnet stages off the flat DB
Jun 13, 2026
e72a8f0
Remove the rebindGetSet knob from HierarchyStage
Jun 13, 2026
49f6479
Migrate DropTimedRTWaits off flat resolvedClkRstMap; drop dead isDepe…
Jun 13, 2026
3cce0fb
Split DB.check into representation-aware subDBCheck + rootDBCheck
Jun 13, 2026
c95a661
Add hierarchical new_circularDerivedDomainsCheck (Step 2b)
Jun 13, 2026
95e4e61
Add hierarchical new_domainClkRateCheck (Step 2b)
Jun 13, 2026
220b449
Add hierarchical new_waitCheck (Step 2b)
Jun 13, 2026
0ede1f5
Add hierarchical new_portLocationCheck + new_portResourceDirCheck (St…
Jun 13, 2026
1567c3e
Add hierarchical new_checkDanglingPorts (Step 2b complete)
Jun 13, 2026
16b873e
Run the hierarchical rootDBCheck on the root; flip call sites (Step 2c)
Jun 13, 2026
2754643
Delete dead flat SanityCheck methods (Step 3a)
Jun 13, 2026
e76798b
Remove the flat<->hierarchical equivalence gate (Step 3b)
Jun 13, 2026
7deb2b9
Merge resolvedClkRstMap; delete the flat clk/rst analysis chain (Step…
Jun 13, 2026
d66beae
Drop the new_ prefix from the hierarchical analyses (Step 3d)
Jun 13, 2026
b240594
Delete the flat MagnetMap.get; rename getHierarchical->get (Step 3d)
Jun 13, 2026
e8d5ead
Polish now-self-referential analysis/check comments (Step 3d)
Jun 13, 2026
aed6baa
Build oldToNew once per SanityCheck call (Step 3e)
Jun 13, 2026
06650fd
Run SanityCheck structural checks per sub-DB
Jun 13, 2026
a0d8609
Make PrintCodeString a BundleStage and the printers hierarchical-DB c…
Jun 13, 2026
04889b9
migrate DropDesignDefs to GlobalStage
Jun 14, 2026
d93c436
migrate DropStructsVecs to GlobalStage
Jun 14, 2026
de9623a
migrate LocalToDesignParams to HierarchyStage
Jun 14, 2026
cbb3af0
fix iverilog crash in version scan
Jun 14, 2026
2169a3a
migrate UniqueNames to GlobalStage
Jun 14, 2026
7f5005d
migrate UniqueDesigns to GlobalStage + actually share duplicates
Jun 14, 2026
31c317a
remove DuplicateTag reference in NVC producedFiles
Jun 14, 2026
dfffac6
disable caching in FullCompileSpec
Jun 14, 2026
cbd4e7d
Unify DFDesignInst.designRef with child block ownerRef (subDBs key)
Jun 14, 2026
acb6850
Remove legacy DuplicateTag
Jun 14, 2026
71b7390
Run the stage pipeline natively on the hierarchical DB
Jun 14, 2026
f30f9e5
Replace GPVP re-normalization with a lightweight global-closure repair
Jun 14, 2026
1f4b890
Drop the DFDesignInst.getAllRefs override; use getAllRefs in the clos…
Jun 14, 2026
5273a87
make flat<->hierarchy DB transformations lazy and turn off infinite l…
Jun 15, 2026
5353d5d
Remove the unused DFInterfaceOwner skeleton
Jun 15, 2026
4c9ea6d
Remove dead match branches left by DFInterfaceOwner removal
Jun 15, 2026
2826378
Add DFInterface/DFView IR types and InstMode.Interface
Jun 16, 2026
fa1c99d
Add basic Interface frontend trait and HasConstParams
Jun 16, 2026
4a4d71c
Generalize plugin design handling to containers; keep interfaces non-top
Jun 16, 2026
2733f8b
Collapse Interface to a single ED-based class
Jun 16, 2026
0f89f9b
Basic Interface frontend compiles
Jun 17, 2026
1fd1240
Require interface ports and params to be `protected`
Jun 17, 2026
1205368
change DFInterface type to have reference instead of name of the inte…
Jun 17, 2026
3c3d09c
Protect against anonymous Interface class instances
Jun 17, 2026
118a0ff
Add Interfaces user-guide chapter
Jun 17, 2026
62d397e
Reject init/initFile inside an Interface
Jun 17, 2026
5d049d4
Document anchored-direction ports and projection terminals
Jun 18, 2026
3bf2d7a
Rename projection terminal VIEW to ASIS in interfaces chapter
Jun 18, 2026
dee8bea
Model anchored ports and view projections in the IR
Jun 18, 2026
40bb26e
Support INOUT in views and simplify interface/view comparison
Jun 18, 2026
062a64a
Document INOUT anchored ports and view.inout in interfaces chapter
Jun 18, 2026
ca81326
Detect interface scope for init via ambient given, not modifier A
Jun 18, 2026
a2482f0
Introduce opaque StaticRef for design-block structural keys
Jun 18, 2026
2aa729d
Merge branch 'main' of https://github.com/DFiantHDL/DFiant into inter…
Jun 18, 2026
d9dd642
actuall fix DB serialization infinite loop
Jun 18, 2026
9fc0af5
add missing `into` on `StaticRef`
Jun 18, 2026
f7a3eed
prepare for Scala 3.10.x: change export of compiletime.ops.string int…
Jun 18, 2026
b10fc17
add missing unique keyword to verilog printer
Jun 18, 2026
1cc9357
fix Verilator tool execution regression
Jun 18, 2026
661bccc
make external tool Ctrl+C cancellation robust and immediate
Jun 18, 2026
711d4d3
fix potential crash when reporting errors
Jun 18, 2026
5c8168f
docs: temporarily hide interfaces docs
Jun 18, 2026
c64d8b8
docs: DFHDL v0.20.0 under Scala 3.8.4
Jun 18, 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
38 changes: 28 additions & 10 deletions .claude/commands/ir-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ DFMember (sealed)
│ ├── DFDesignBlock — module / design definition
│ ├── DomainBlock — clock-domain grouping
│ ├── ProcessBlock — always / process block
│ ├── ForkBlock — fork-join (forkJoin/forkJoinAny/forkJoinNone); join mode
│ ├── LocalBlock — local statement block (locally:); a fork branch when owned by ForkBlock
│ ├── StepBlock — FSM step
│ ├── DFConditional.Block — if / match clause
│ │ ├── DFIfElseBlock
Expand All @@ -49,7 +51,6 @@ DFMember (sealed)
├── DFConditional.Header — if / match header expression
│ ├── DFIfHeader
│ └── DFMatchHeader
├── DFInterfaceOwner — interface abstraction
└── DFRange — for-loop range
```

Expand Down Expand Up @@ -372,7 +373,7 @@ type PortByNameSelect.Ref = DFRef.TwoWay[DFDesignInst, PortByNameSelect]

```scala
final case class DFNet(
lhsRef: DFNet.Ref, // DFRef.TwoWay[DFVal | DFInterfaceOwner, DFNet]
lhsRef: DFNet.Ref, // DFRef.TwoWay[DFVal, DFNet]
op: DFNet.Op,
rhsRef: DFNet.Ref,
ownerRef: DFOwner.Ref,
Expand All @@ -396,8 +397,8 @@ DFNet.Assignment(toVal, fromVal) // Assignment or NBAssignment; toVal and from
DFNet.BAssignment(toVal, fromVal) // blocking only (op == Assignment)
DFNet.NBAssignment(toVal, fromVal) // non-blocking only (op == NBAssignment)
DFNet.Connection(toVal, fromVal, swapped)
// toVal: DFVal.Dcl | DFVal.Special | DFInterfaceOwner
// fromVal: DFVal | DFInterfaceOwner
// toVal: DFVal.Dcl | DFVal.PortByNameSelect | DFVal.Special
// fromVal: DFVal
// swapped: Boolean — true if lhs/rhs were physically reversed
```

Expand Down Expand Up @@ -468,7 +469,6 @@ enum InstMode.BlackBox: NA, Files(path), Library(libName, nameSpace), VendorIP(v

**Extension methods:**
```scala
design.isDuplicate // tagged DuplicateTag — has NO members in DB (ports/domains removed)
design.isBlackBox // instMode is BlackBox
design.isVendorIPBlackbox
design.inSimulation // instMode is Simulation
Expand Down Expand Up @@ -511,6 +511,29 @@ final case class ProcessBlock.Sensitivity.List(refs: List[DFVal.Ref]) // proces

---

### ForkBlock & LocalBlock
```scala
final case class ForkBlock(
join: ForkBlock.Join, // All | Any | None
ownerRef: DFOwner.Ref,
meta: Meta,
tags: DFTags
)
enum ForkBlock.Join: All, Any, None // forkJoin / forkJoinAny / forkJoinNone

final case class LocalBlock( // produced by `locally:`
ownerRef: DFOwner.Ref,
meta: Meta,
tags: DFTags
)
```
ED-domain only (for now). A `LocalBlock` whose `getOwner` is a `ForkBlock` is a concurrent
fork branch; elsewhere it is a plain local statement scope. SystemVerilog emits both natively
(`fork…join[_any|_none]`, `begin[: name]…end`); `DropForkJoins` lowers forks to processes +
handshake signals for VHDL/old-Verilog, and `DropLocalBlocks` flattens local blocks for VHDL.

---

### StepBlock
```scala
final case class StepBlock(
Expand Down Expand Up @@ -783,7 +806,6 @@ DFTags.empty

**Built-in tags:**
```scala
case object DuplicateTag // duplicate design instance — NO members in DB
case object IteratorTag // Dcl is a for-loop iterator variable
case object IdentTag // Alias.AsIs is a pure identity (named alias of itself)
case object BindTag // Alias is a pattern-match bind variable
Expand Down Expand Up @@ -863,10 +885,6 @@ db.inSimulation // top has no ports (simulation context)
db.inBuild // top has a device constraint tag
```

**Design duplication properties:**

Duplicate designs (tagged `DuplicateTag`) have **no members** in the DB — their ports, domain blocks, and other members are removed during immutable DB creation.

**Patching:**
```scala
db.patch(patches: List[(DFMember, Patch)]): DB
Expand Down
5 changes: 1 addition & 4 deletions .claude/commands/new-stage.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ DFMember (sealed)
│ ├── StepBlock ─ RT step (FSM state)
│ └── DFConditional.Block ─ if/match/while clause
├── DFConditional.Header ─ if/match/while header
├── DFInterfaceOwner
└── DFRange
```

Expand Down Expand Up @@ -1072,9 +1071,7 @@ abstract class StageSpec(stageCreatesUnrefAnons: Boolean = false)
fails with "wrong number of argument patterns" because `DFForBlock` has multiple fields. Use a
type pattern instead: `case x: DFLoop.DFForBlock`. The same applies to other multi-field IR
case classes that have no dedicated single-argument unapply.
16. **Assuming duplicate designs have members** — designs tagged `DuplicateTag` have **no members**
in the DB (ports, domain blocks, and values are removed during immutable DB creation).
17. **Rewriting nested same-kind constructs in one pass** — if your stage rewrites a construct that
16. **Rewriting nested same-kind constructs in one pass** — if your stage rewrites a construct that
can nest inside another of the same kind (nested `for` loops, steps-in-conditionals nested in
steps, etc.) via a `Move` / `ReplaceWithLast(ChangeRefAndRemove)` plus a body-anchored satellite
patch, doing the outer and inner in one patch list conflicts: the inner appears both in the
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Outputs: Verilog, SystemVerilog, VHDL.

## Build System

**Tool**: SBT 1.12.9 — **Scala**: 3.8.3 (nightly resolver enabled)
**Tool**: SBT 1.12.12 — **Scala**: 3.8.4 (nightly resolver enabled)

```bash
sbtn compile # compile all subprojects
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ commands += DFHDLCommands.docExamplesRefUpdate

// format: off
val projectName = "dfhdl"
val compilerVersion = "3.8.3"
val compilerVersion = "3.8.4"

inThisBuild(
List(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dfhdl.compiler
package analysis
import dfhdl.internals.*
import ir.*
import scala.annotation.tailrec
import scala.collection.mutable
extension (owner: DFOwner)
def members(memberView: MemberView)(using MemberGetSet): List[DFMember] =
Expand All @@ -12,7 +11,6 @@ extension (owner: DFOwner)
val last = owner match
case block: DFDesignBlock => designDB.designMemberTable(block).lastOption
case block: DFBlock => designDB.blockMemberTable(block).lastOption
case _ => designDB.ownerMemberTable(owner).lastOption
last match
// if last member is an owner then we search further
case Some(o: DFOwner) =>
Expand All @@ -22,15 +20,6 @@ extension (owner: DFOwner)
case x => x
end extension

extension (domainOwner: DFDomainOwner)
// true if the domainOwner is dependent at any level of thatDomainOwner's configuration
@tailrec def isDependentOn(thatDomainOwner: DFDomainOwner)(using getSet: MemberGetSet): Boolean =
getSet.designDB.dependentRTDomainOwners.get(domainOwner) match
case Some(dependency) =>
if (dependency == thatDomainOwner) true
else dependency.isDependentOn(thatDomainOwner)
case None => false

extension (design: DFDesignBlock)
// collect all local parameters that are used in IOs
def getIOLocalParams(using getSet: MemberGetSet): List[DFVal.CanBeExpr] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ object StateAnalysis:
given DFBlock = currentBlock
remaining match
case (nextBlock: DFBlock) :: rs if nextBlock.getOwnerBlock == currentBlock => // entering child block
val (updatedSet, updatedScopeMap): (Set[DFVal], AssignMap) = nextBlock match
val (updatedSet, updatedScopeMap) = nextBlock match
case cb: DFConditional.Block =>
cb.guardRef.get match
case dfVal: DFVal => consumeFrom(dfVal, scopeMap, currentSet)
Expand All @@ -167,7 +167,7 @@ object StateAnalysis:
if r.getOwnerBlock == currentBlock && checkedDomain(
currentBlock.getThisOrOwnerDomain.domainType
) => // checking member consumers
val (updatedSet, updatedScopeMap): (Set[DFVal], AssignMap) = r match
val (updatedSet, updatedScopeMap) = r match
case net @ DFNet.Assignment(toVal, fromVal) =>
(consumeFrom(fromVal, scopeMap, currentSet), assignTo(toVal, scopeMap))
case net @ DFNet.Connection(toVal: DFVal, fromVal: DFVal, _) =>
Expand Down
Loading
Loading