Skip to content

Commit 9d70aac

Browse files
author
Oron Port
committed
add referencial comparison to Meta and HWAnnotation
1 parent 48cef76 commit 9d70aac

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ object DFVal:
404404
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
405405
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
406406
def copyWithNewRefs(using RefGen): this.type = copy(
407+
meta = meta.copyWithNewRefs,
407408
dfType = dfType.copyWithNewRefs,
408409
ownerRef = ownerRef.copyAsNewRef
409410
).asInstanceOf[this.type]
@@ -441,6 +442,7 @@ object DFVal:
441442
lazy val getRefs: List[DFRef.TwoWayAny] = dfValRef :: defaultRef :: dfType.getRefs
442443
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
443444
def copyWithNewRefs(using RefGen): this.type = copy(
445+
meta = meta.copyWithNewRefs,
444446
dfType = dfType.copyWithNewRefs,
445447
ownerRef = ownerRef.copyAsNewRef,
446448
dfValRef = dfValRef.copyAsNewRef,
@@ -490,6 +492,7 @@ object DFVal:
490492
lazy val getRefs: List[DFRef.TwoWayAny] = dfType.getRefs
491493
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
492494
def copyWithNewRefs(using RefGen): this.type = copy(
495+
meta = meta.copyWithNewRefs,
493496
dfType = dfType.copyWithNewRefs,
494497
ownerRef = ownerRef.copyAsNewRef
495498
).asInstanceOf[this.type]
@@ -520,6 +523,7 @@ object DFVal:
520523
lazy val getRefs: List[DFRef.TwoWayAny] = dfType.getRefs ++ initRefList
521524
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
522525
def copyWithNewRefs(using RefGen): this.type = copy(
526+
meta = meta.copyWithNewRefs,
523527
dfType = dfType.copyWithNewRefs,
524528
ownerRef = ownerRef.copyAsNewRef,
525529
initRefList = initRefList.map(_.copyAsNewRef)
@@ -574,6 +578,7 @@ object DFVal:
574578
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
575579
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
576580
def copyWithNewRefs(using RefGen): this.type = copy(
581+
meta = meta.copyWithNewRefs,
577582
dfType = dfType.copyWithNewRefs,
578583
ownerRef = ownerRef.copyAsNewRef,
579584
args = args.map(_.copyAsNewRef)
@@ -613,6 +618,7 @@ object DFVal:
613618
lazy val getRefs: List[DFRef.TwoWayAny] = designInstRef :: dfType.getRefs
614619
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
615620
def copyWithNewRefs(using RefGen): this.type = copy(
621+
meta = meta.copyWithNewRefs,
616622
dfType = dfType.copyWithNewRefs,
617623
ownerRef = ownerRef.copyAsNewRef,
618624
designInstRef = designInstRef.copyAsNewRef
@@ -682,6 +688,7 @@ object DFVal:
682688
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
683689
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
684690
def copyWithNewRefs(using RefGen): this.type = copy(
691+
meta = meta.copyWithNewRefs,
685692
dfType = dfType.copyWithNewRefs,
686693
ownerRef = ownerRef.copyAsNewRef,
687694
relValRef = relValRef.copyAsNewRef
@@ -721,6 +728,7 @@ object DFVal:
721728
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
722729
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
723730
def copyWithNewRefs(using RefGen): this.type = copy(
731+
meta = meta.copyWithNewRefs,
724732
dfType = dfType.copyWithNewRefs,
725733
ownerRef = ownerRef.copyAsNewRef,
726734
relValRef = relValRef.copyAsNewRef,
@@ -788,6 +796,7 @@ object DFVal:
788796
def updateDFType(dfType: DFType): this.type = this
789797
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
790798
def copyWithNewRefs(using RefGen): this.type = copy(
799+
meta = meta.copyWithNewRefs,
791800
dfType = dfType.copyWithNewRefs,
792801
ownerRef = ownerRef.copyAsNewRef,
793802
relValRef = relValRef.copyAsNewRef,
@@ -844,6 +853,7 @@ object DFVal:
844853
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
845854
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
846855
def copyWithNewRefs(using RefGen): this.type = copy(
856+
meta = meta.copyWithNewRefs,
847857
dfType = dfType.copyWithNewRefs,
848858
ownerRef = ownerRef.copyAsNewRef,
849859
relValRef = relValRef.copyAsNewRef,
@@ -892,6 +902,7 @@ object DFVal:
892902
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
893903
def copyWithoutGlobalCtx: this.type = copy().asInstanceOf[this.type]
894904
def copyWithNewRefs(using RefGen): this.type = copy(
905+
meta = meta.copyWithNewRefs,
895906
dfType = dfType.copyWithNewRefs,
896907
ownerRef = ownerRef.copyAsNewRef,
897908
relValRef = relValRef.copyAsNewRef
@@ -919,6 +930,7 @@ final case class DFRange(
919930
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
920931
lazy val getRefs: List[DFRef.TwoWayAny] = List(startRef, endRef, stepRef)
921932
def copyWithNewRefs(using RefGen): this.type = copy(
933+
meta = meta.copyWithNewRefs,
922934
startRef = startRef.copyAsNewRef,
923935
endRef = endRef.copyAsNewRef,
924936
stepRef = stepRef.copyAsNewRef,
@@ -948,6 +960,7 @@ final case class DFNet(
948960
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
949961
lazy val getRefs: List[DFRef.TwoWayAny] = List(lhsRef, rhsRef)
950962
def copyWithNewRefs(using RefGen): this.type = copy(
963+
meta = meta.copyWithNewRefs,
951964
lhsRef = lhsRef.copyAsNewRef,
952965
rhsRef = rhsRef.copyAsNewRef,
953966
ownerRef = ownerRef.copyAsNewRef
@@ -1028,6 +1041,7 @@ final case class StepBlock(
10281041
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
10291042
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
10301043
def copyWithNewRefs(using RefGen): this.type = copy(
1044+
meta = meta.copyWithNewRefs,
10311045
ownerRef = ownerRef.copyAsNewRef
10321046
).asInstanceOf[this.type]
10331047
end StepBlock
@@ -1054,6 +1068,7 @@ final case class Goto(
10541068
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
10551069
lazy val getRefs: List[DFRef.TwoWayAny] = List(stepRef)
10561070
def copyWithNewRefs(using RefGen): this.type = copy(
1071+
meta = meta.copyWithNewRefs,
10571072
stepRef = stepRef.copyAsNewRef,
10581073
ownerRef = ownerRef.copyAsNewRef
10591074
).asInstanceOf[this.type]
@@ -1093,6 +1108,7 @@ final case class DFInterfaceOwner(
10931108
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
10941109
lazy val getRefs: List[DFRef.TwoWayAny] = domainType.getRefs
10951110
def copyWithNewRefs(using RefGen): this.type = copy(
1111+
meta = meta.copyWithNewRefs,
10961112
domainType = domainType.copyWithNewRefs,
10971113
ownerRef = ownerRef.copyAsNewRef
10981114
).asInstanceOf[this.type]
@@ -1125,6 +1141,7 @@ final case class ProcessBlock(
11251141
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
11261142
lazy val getRefs: List[DFRef.TwoWayAny] = sensitivity.getRefs
11271143
def copyWithNewRefs(using RefGen): this.type = copy(
1144+
meta = meta.copyWithNewRefs,
11281145
sensitivity = sensitivity.copyWithNewRefs,
11291146
ownerRef = ownerRef.copyAsNewRef
11301147
).asInstanceOf[this.type]
@@ -1187,6 +1204,7 @@ object DFConditional:
11871204
lazy val getRefs: List[DFRef.TwoWayAny] = selectorRef :: dfType.getRefs
11881205
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
11891206
def copyWithNewRefs(using RefGen): this.type = copy(
1207+
meta = meta.copyWithNewRefs,
11901208
dfType = dfType.copyWithNewRefs,
11911209
selectorRef = selectorRef.copyAsNewRef,
11921210
ownerRef = ownerRef.copyAsNewRef
@@ -1213,6 +1231,7 @@ object DFConditional:
12131231
lazy val getRefs: List[DFRef.TwoWayAny] =
12141232
List(guardRef, prevBlockOrHeaderRef) ++ pattern.getRefs
12151233
def copyWithNewRefs(using RefGen): this.type = copy(
1234+
meta = meta.copyWithNewRefs,
12161235
pattern = pattern.copyWithNewRefs,
12171236
guardRef = guardRef.copyAsNewRef,
12181237
prevBlockOrHeaderRef = prevBlockOrHeaderRef.copyAsNewRef,
@@ -1326,6 +1345,7 @@ object DFConditional:
13261345
false
13271346
def updateDFType(dfType: DFType): this.type = copy(dfType = dfType).asInstanceOf[this.type]
13281347
def copyWithNewRefs(using RefGen): this.type = copy(
1348+
meta = meta.copyWithNewRefs,
13291349
dfType = dfType.copyWithNewRefs,
13301350
ownerRef = ownerRef.copyAsNewRef
13311351
).asInstanceOf[this.type]
@@ -1348,6 +1368,7 @@ object DFConditional:
13481368
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
13491369
lazy val getRefs: List[DFRef.TwoWayAny] = List(guardRef, prevBlockOrHeaderRef)
13501370
def copyWithNewRefs(using RefGen): this.type = copy(
1371+
meta = meta.copyWithNewRefs,
13511372
guardRef = guardRef.copyAsNewRef,
13521373
prevBlockOrHeaderRef = prevBlockOrHeaderRef.copyAsNewRef,
13531374
ownerRef = ownerRef.copyAsNewRef
@@ -1376,6 +1397,7 @@ object DFLoop:
13761397
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
13771398
lazy val getRefs: List[DFRef.TwoWayAny] = List(iteratorRef, rangeRef)
13781399
def copyWithNewRefs(using RefGen): this.type = copy(
1400+
meta = meta.copyWithNewRefs,
13791401
iteratorRef = iteratorRef.copyAsNewRef,
13801402
rangeRef = rangeRef.copyAsNewRef,
13811403
ownerRef = ownerRef.copyAsNewRef
@@ -1400,6 +1422,7 @@ object DFLoop:
14001422
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
14011423
lazy val getRefs: List[DFRef.TwoWayAny] = List(guardRef)
14021424
def copyWithNewRefs(using RefGen): this.type = copy(
1425+
meta = meta.copyWithNewRefs,
14031426
guardRef = guardRef.copyAsNewRef,
14041427
ownerRef = ownerRef.copyAsNewRef
14051428
).asInstanceOf[this.type]
@@ -1429,6 +1452,7 @@ final case class DFDesignBlock(
14291452
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
14301453
lazy val getRefs: List[DFRef.TwoWayAny] = domainType.getRefs
14311454
def copyWithNewRefs(using RefGen): this.type = copy(
1455+
meta = meta.copyWithNewRefs,
14321456
domainType = domainType.copyWithNewRefs,
14331457
ownerRef = ownerRef.copyAsNewRef
14341458
).asInstanceOf[this.type]
@@ -1492,6 +1516,7 @@ final case class DomainBlock(
14921516
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
14931517
lazy val getRefs: List[DFRef.TwoWayAny] = domainType.getRefs
14941518
def copyWithNewRefs(using RefGen): this.type = copy(
1519+
meta = meta.copyWithNewRefs,
14951520
domainType = domainType.copyWithNewRefs,
14961521
ownerRef = ownerRef.copyAsNewRef
14971522
).asInstanceOf[this.type]
@@ -1590,6 +1615,7 @@ final case class Wait(
15901615
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
15911616
lazy val getRefs: List[DFRef.TwoWayAny] = List(triggerRef)
15921617
def copyWithNewRefs(using RefGen): this.type = copy(
1618+
meta = meta.copyWithNewRefs,
15931619
triggerRef = triggerRef.copyAsNewRef,
15941620
ownerRef = ownerRef.copyAsNewRef
15951621
).asInstanceOf[this.type]
@@ -1616,6 +1642,7 @@ final case class TextOut(
16161642
protected def setTags(tags: DFTags): this.type = copy(tags = tags).asInstanceOf[this.type]
16171643
lazy val getRefs: List[DFRef.TwoWayAny] = op.getRefs ++ msgArgs
16181644
def copyWithNewRefs(using RefGen): this.type = copy(
1645+
meta = meta.copyWithNewRefs,
16191646
op = op.copyWithNewRefs,
16201647
msgArgs = msgArgs.map(_.copyAsNewRef),
16211648
ownerRef = ownerRef.copyAsNewRef

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ final case class Meta(
88
position: Position,
99
docOpt: Option[String],
1010
annotations: List[HWAnnotation]
11-
) derives CanEqual, ReadWriter:
11+
) extends HasRefCompare[Meta] derives CanEqual, ReadWriter:
1212
val isAnonymous: Boolean = nameOpt.isEmpty
1313
val name: String =
1414
nameOpt.getOrElse(s"anon${this.hashString}")
@@ -21,8 +21,14 @@ final case class Meta(
2121
def removeAnnotation(annotation: HWAnnotation) = setAnnotations(
2222
annotations.filterNot(_ == annotation)
2323
)
24-
def =~(that: Meta): Boolean =
25-
this.nameOpt == that.nameOpt && this.docOpt == that.docOpt && this.annotations == that.annotations
24+
protected def `prot_=~`(that: Meta)(using MemberGetSet): Boolean =
25+
this.nameOpt == that.nameOpt && this.docOpt == that.docOpt &&
26+
this.annotations.lazyZip(that.annotations).forall(_ =~ _)
27+
lazy val getRefs: List[DFRef.TwoWayAny] =
28+
annotations.flatMap(_.getRefs)
29+
def copyWithNewRefs(using RefGen): this.type = copy(
30+
annotations = annotations.map(_.copyWithNewRefs)
31+
).asInstanceOf[this.type]
2632
end Meta
2733

2834
object Meta:

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import upickle.default.*
55
import dfhdl.internals.StableEnum
66

77
object annotation:
8-
sealed abstract class HWAnnotation extends Product, Serializable, HasCodeString derives CanEqual
8+
sealed abstract class HWAnnotation extends HasRefCompare[HWAnnotation], Product, Serializable,
9+
HasCodeString derives CanEqual
910

1011
object HWAnnotation:
1112
given ReadWriter[HWAnnotation] = ReadWriter.merge(
@@ -17,6 +18,9 @@ object annotation:
1718

1819
enum Unused extends HWAnnotation derives ReadWriter:
1920
case Quiet, Keep, Prune
21+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
22+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
23+
def copyWithNewRefs(using RefGen): this.type = this
2024
def codeString(using Printer): String =
2125
this match
2226
case Quiet => "@hw.annotation.unused.quiet"
@@ -25,6 +29,9 @@ object annotation:
2529

2630
case object Pure extends HWAnnotation:
2731
given ReadWriter[Pure.type] = macroRW
32+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
33+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
34+
def copyWithNewRefs(using RefGen): this.type = this
2835
def codeString(using Printer): String = "@hw.annotation.pure"
2936

3037
/** Flattening Mode:
@@ -36,6 +43,9 @@ object annotation:
3643
case Transparent
3744
case Prefix(sep: String)
3845
case Suffix(sep: String)
46+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
47+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
48+
def copyWithNewRefs(using RefGen): this.type = this
3949
def codeString(using Printer): String =
4050
"@hw.annotation.flattenMode." + (
4151
this match
@@ -48,13 +58,15 @@ object annotation:
4858
end annotation
4959

5060
object constraints:
51-
sealed abstract class Constraint extends annotation.HWAnnotation derives ReadWriter
61+
import annotation.HWAnnotation
62+
sealed abstract class Constraint extends HWAnnotation derives ReadWriter
5263
sealed abstract class SigConstraint extends Constraint derives ReadWriter:
5364
val bitIdx: ConfigN[Int]
5465
final case class Device(name: String, properties: Map[String, String]) extends Constraint
5566
derives CanEqual, ReadWriter:
56-
def this(name: String, properties: (String, String)*) =
57-
this(name, properties.toMap)
67+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
68+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
69+
def copyWithNewRefs(using RefGen): this.type = this
5870
def codeString(using Printer): String =
5971
val props = properties.map { case (k, v) => s""""$k" -> "$v"""" }.mkString(", ")
6072
s"""@device("$name"${props.emptyOr(", " + _)})"""
@@ -76,6 +88,9 @@ object constraints:
7688
driveStrength: ConfigN[Int] = None,
7789
pullMode: ConfigN[IO.PullMode] = None
7890
) extends SigConstraint derives CanEqual, ReadWriter:
91+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
92+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
93+
def copyWithNewRefs(using RefGen): this.type = this
7994
def codeString(using Printer): String =
8095
val params = List(
8196
csParam("bitIdx", bitIdx),
@@ -105,6 +120,9 @@ object constraints:
105120
maxFreqMinPeriod: ConfigN[RateNumber] = None
106121
) extends SigConstraint
107122
derives CanEqual, ReadWriter:
123+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
124+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
125+
def copyWithNewRefs(using RefGen): this.type = this
108126
def codeString(using Printer): String =
109127
val params = List(
110128
csParam("bitIdx", bitIdx),
@@ -115,6 +133,9 @@ object constraints:
115133
final case class Clock(
116134
rate: RateNumber
117135
) extends Constraint derives CanEqual, ReadWriter:
136+
protected def `prot_=~`(that: HWAnnotation)(using MemberGetSet): Boolean = this == that
137+
lazy val getRefs: List[DFRef.TwoWayAny] = Nil
138+
def copyWithNewRefs(using RefGen): this.type = this
118139
def codeString(using Printer): String =
119140
s"""@timing.clock(${csParam("rate", rate)})"""
120141
end Timing

0 commit comments

Comments
 (0)