@@ -62,6 +62,8 @@ object constraints:
62
62
sealed abstract class Constraint extends HWAnnotation derives ReadWriter
63
63
sealed abstract class GlobalConstraint extends Constraint derives ReadWriter
64
64
sealed abstract class SigConstraint extends Constraint derives ReadWriter :
65
+ def merge (that : SigConstraint ): Option [SigConstraint ] =
66
+ if (this == that) Some (this ) else None
65
67
val bitIdx : ConfigN [Int ]
66
68
final case class Device (name : String , properties : Map [String , String ]) extends GlobalConstraint
67
69
derives CanEqual , ReadWriter :
@@ -72,6 +74,31 @@ object constraints:
72
74
val props = properties.map { case (k, v) => s """ " $k" -> " $v" """ }.mkString(" , " )
73
75
s """ @device(" $name" ${props.emptyOr(" , " + _)}) """
74
76
77
+ extension [T ](configN : ConfigN [T ])
78
+ def merge (that : ConfigN [T ]): ConfigN [T ] =
79
+ (configN, that) match
80
+ case (None , None ) => None
81
+ case (t : T @ unchecked, None ) => t
82
+ case (None , t : T @ unchecked) => t
83
+ case (t1 : T @ unchecked, t2 : T @ unchecked) if t1 equals t2 => t1
84
+ case x => throw new IllegalArgumentException (" Constraint merge error: " + x)
85
+ extension (list : List [SigConstraint ])
86
+ def merge : List [SigConstraint ] =
87
+ list.foldLeft(List .empty[SigConstraint ]) { (acc, cs) =>
88
+ var merged = false
89
+ val newAcc = acc.map { next =>
90
+ if (merged) next
91
+ else cs.merge(next) match
92
+ case Some (mergedCs) =>
93
+ merged = true
94
+ mergedCs
95
+ case None => next
96
+ }
97
+ if (merged) newAcc
98
+ else cs :: newAcc
99
+ }.reverse
100
+ end extension
101
+
75
102
private def csParam [T ](name : String , value : ConfigN [T ])(using printer : Printer ): String =
76
103
value match
77
104
case None => " "
@@ -93,6 +120,20 @@ object constraints:
93
120
protected def `prot_=~` (that : HWAnnotation )(using MemberGetSet ): Boolean = this == that
94
121
lazy val getRefs : List [DFRef .TwoWayAny ] = Nil
95
122
def copyWithNewRefs (using RefGen ): this .type = this
123
+ override def merge (that : SigConstraint ): Option [SigConstraint ] =
124
+ that match
125
+ case that : IO if bitIdx == that.bitIdx =>
126
+ Some (
127
+ IO (
128
+ bitIdx = bitIdx,
129
+ loc = loc.merge(that.loc),
130
+ standard = standard.merge(that.standard),
131
+ slewRate = slewRate.merge(that.slewRate),
132
+ driveStrength = driveStrength.merge(that.driveStrength),
133
+ pullMode = pullMode.merge(that.pullMode)
134
+ )
135
+ )
136
+ case _ => None
96
137
def codeString (using Printer ): String =
97
138
val params = List (
98
139
csParam(" bitIdx" , bitIdx),
0 commit comments