Skip to content

Commit e6f002e

Browse files
author
Oron Port
committed
global constraint projection
1 parent 1bc6adf commit e6f002e

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

compiler/ir/src/main/scala/dfhdl/compiler/ir/annotation.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ end annotation
6060
object constraints:
6161
import annotation.HWAnnotation
6262
sealed abstract class Constraint extends HWAnnotation derives ReadWriter
63+
sealed abstract class GlobalConstraint extends Constraint derives ReadWriter
6364
sealed abstract class SigConstraint extends Constraint derives ReadWriter:
6465
val bitIdx: ConfigN[Int]
65-
final case class Device(name: String, properties: Map[String, String]) extends Constraint
66+
final case class Device(name: String, properties: Map[String, String]) extends GlobalConstraint
6667
derives CanEqual, ReadWriter:
6768
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
6869
lazy val getRefs: List[DFRef.TwoWayAny] = Nil

core/src/main/scala/dfhdl/hw/annotation.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ object constraints:
6464
sealed abstract class Constraint extends annotation.HWAnnotation:
6565
val isActive: Boolean = true
6666
val asIR: ir.constraints.Constraint
67+
sealed abstract class GlobalConstraint extends Constraint:
68+
val asIR: ir.constraints.GlobalConstraint
6769
sealed abstract class SigConstraint extends Constraint:
6870
val bitIdx: ir.ConfigN[Int]
69-
final case class device(name: String, properties: (String, String)*) extends Constraint:
71+
final case class device(name: String, properties: (String, String)*) extends GlobalConstraint:
7072
val asIR: ir.constraints.Device = ir.constraints.Device(name, properties.toMap)
7173

7274
final case class io(

core/src/main/scala/dfhdl/platforms/resources/ResourceContext.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@ package dfhdl.platforms.resources
22
import dfhdl.internals.*
33
import dfhdl.core.*
44
import scala.annotation.Annotation
5+
import dfhdl.compiler.ir.constraints.Constraint
6+
import scala.collection.mutable.ListBuffer
57

68
trait ResourceContext extends OnCreateEvents, HasDFC, HasClsMetaArgs:
79
final lazy val dfc: DFC = __dfc
810
final lazy val id: String = dfc.nameOpt.get
11+
private var resourceConstraints = ListBuffer[Constraint]()
12+
def getResourceConstraints: List[Constraint] =
13+
resourceConstraints.toList ++ dfc.annotations.collect {
14+
case constraint: Constraint => constraint
15+
}
916
protected def __dfc: DFC =
1017
println("Severe error: missing DFHDL context!\nMake sure you enable the DFHDL compiler plugin.")
1118
sys.exit(1)
@@ -14,5 +21,10 @@ trait ResourceContext extends OnCreateEvents, HasDFC, HasClsMetaArgs:
1421
position: Position,
1522
docOpt: Option[String],
1623
annotations: List[Annotation]
17-
): Unit = {}
24+
): Unit =
25+
annotations.foreach {
26+
case constraint: dfhdl.hw.constraints.Constraint =>
27+
resourceConstraints += constraint.asIR
28+
case _ =>
29+
}
1830
end ResourceContext
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,32 @@
11
package dfhdl.platforms.resources
22
import scala.collection.mutable.ListBuffer
3+
import dfhdl.compiler.ir
4+
35
trait ResourceOwner extends ResourceContext:
46
dfc.mutableDB.ResourceOwnershipContext.enter(this)
57
private val resources = ListBuffer[Resource]()
68
private val children = ListBuffer[ResourceOwner]()
79
private[resources] def getResources: List[Resource] = resources.toList
810
private[resources] def getChildren: List[ResourceOwner] = children.toList
911
private[resources] def addResource(resource: Resource): Unit = resources += resource
12+
// projecting global constraints to the current design (typically this would be
13+
// the top-level design, but we don't limit this for now)
14+
private def projectGlobalConstraints(): Unit =
15+
val globalConstraints = getResourceConstraints.collect {
16+
case constraint: ir.constraints.GlobalConstraint => constraint
17+
}
18+
if (globalConstraints.nonEmpty)
19+
import dfc.getSet
20+
val ownerDesign = dfc.owner.asIR.getThisOrOwnerDesign
21+
val updatedDclMeta =
22+
ownerDesign.dclMeta.copy(annotations = ownerDesign.dclMeta.annotations ++ globalConstraints)
23+
val updatedOwnerDesign = ownerDesign.copy(dclMeta = updatedDclMeta)
24+
dfc.mutableDB.replaceMember(ownerDesign, updatedOwnerDesign)
25+
end if
26+
end projectGlobalConstraints
27+
1028
override def onCreateEnd(thisOwner: Option[This]): Unit =
1129
dfc.mutableDB.ResourceOwnershipContext.exit()
1230
dfc.mutableDB.ResourceOwnershipContext.ownerOpt.foreach(_.children += this)
31+
projectGlobalConstraints()
32+
end ResourceOwner

0 commit comments

Comments
 (0)