2
2
*/
3
3
package dfhdl .hw
4
4
5
- import dfhdl .compiler .printing .Printer
5
+ import dfhdl .compiler .printing .{ Printer , HasCodeString }
6
6
import scala .annotation .StaticAnnotation
7
7
import dfhdl .internals .HasTypeName
8
8
import scala .annotation .Annotation
9
9
import upickle .default .*
10
10
import dfhdl .internals .StableEnum
11
+ import dfhdl .compiler .ir .ConfigN
11
12
12
13
object annotation :
13
- sealed abstract class HWAnnotation extends StaticAnnotation , Product , Serializable
14
+ sealed abstract class HWAnnotation extends StaticAnnotation , Product , Serializable , HasCodeString
14
15
derives CanEqual :
15
16
val isActive : Boolean
16
- def codeString (using Printer ): String
17
17
18
18
extension (annotList : List [Annotation ])
19
19
def getActiveHWAnnotations : List [HWAnnotation ] = annotList.collect {
@@ -23,7 +23,8 @@ object annotation:
23
23
given ReadWriter [HWAnnotation ] = ReadWriter .merge(
24
24
summon[ReadWriter [unused]],
25
25
summon[ReadWriter [pure]],
26
- summon[ReadWriter [flattenMode]]
26
+ summon[ReadWriter [flattenMode]],
27
+ summon[ReadWriter [constraints.Constraint ]]
27
28
)
28
29
29
30
sealed trait unused extends HWAnnotation derives ReadWriter
@@ -32,24 +33,24 @@ object annotation:
32
33
*/
33
34
final case class quiet (isActive : Boolean ) extends unused :
34
35
def this () = this (true )
35
- def codeString (using Printer ): String = " unused.quiet"
36
+ def codeString (using Printer ): String = " @hw.annotation. unused.quiet"
36
37
37
38
/** `keep` suppresses the unused warning, and also attempts to keep the tagged value.
38
39
*/
39
40
final case class keep (isActive : Boolean ) extends unused :
40
41
def this () = this (true )
41
- def codeString (using Printer ): String = " unused.keep"
42
+ def codeString (using Printer ): String = " @hw.annotation. unused.keep"
42
43
43
44
/** `prune` removes all the redundant paths until and including the tagged value.
44
45
*/
45
46
final case class prune (isActive : Boolean ) extends unused :
46
47
def this () = this (true )
47
- def codeString (using Printer ): String = " unused.prune"
48
+ def codeString (using Printer ): String = " @hw.annotation. unused.prune"
48
49
end unused
49
50
50
51
final case class pure (isActive : Boolean ) extends HWAnnotation derives ReadWriter :
51
52
def this () = this (true )
52
- def codeString (using Printer ): String = " pure"
53
+ def codeString (using Printer ): String = " @hw.annotation. pure"
53
54
54
55
/** Flattening Mode:
55
56
* - transparent: $memberName
@@ -62,10 +63,61 @@ object annotation:
62
63
case suffix(sep : String )
63
64
val isActive : Boolean = true
64
65
def codeString (using Printer ): String =
65
- this match
66
- case transparent() => " flattenMode.transparent()"
67
- case prefix(sep) => s """ flattenMode.prefix(" $sep") """
68
- case suffix(sep) => s """ flattenMode.suffix(" $sep") """
66
+ " @hw.annotation.flattenMode." + (
67
+ this match
68
+ case transparent() => " transparent()"
69
+ case prefix(sep) => s """ prefix(" $sep") """
70
+ case suffix(sep) => s """ suffix(" $sep") """
71
+ )
69
72
object flattenMode :
70
73
val defaultPrefixUnderscore = flattenMode.prefix(" _" )
71
74
end annotation
75
+
76
+ object constraints :
77
+ sealed abstract class Constraint extends annotation.HWAnnotation :
78
+ val isActive : Boolean = true
79
+ object Constraint :
80
+ given ReadWriter [Constraint ] = ReadWriter .merge(
81
+ summon[ReadWriter [io.IOConstraints ]]
82
+ )
83
+
84
+ object io :
85
+ enum IOStandard extends StableEnum , HasCodeString derives CanEqual , ReadWriter :
86
+ case LVCMOS33 , LVCMOS25 , LVCMOS18
87
+ def codeString (using Printer ): String = " IOStandard." + this .toString
88
+ enum SlewRate extends StableEnum , HasCodeString derives CanEqual , ReadWriter :
89
+ case SLOW , FAST
90
+ def codeString (using Printer ): String = " SlewRate." + this .toString
91
+ enum PullMode extends StableEnum , HasCodeString derives CanEqual , ReadWriter :
92
+ case UP , DOWN
93
+ def codeString (using Printer ): String = " PullMode." + this .toString
94
+
95
+ final case class IOConstraints (
96
+ bitIdx : ConfigN [Int ] = None ,
97
+ loc : ConfigN [String ] = None ,
98
+ standard : ConfigN [IOStandard ] = None ,
99
+ slewRate : ConfigN [SlewRate ] = None ,
100
+ driveStrength : ConfigN [Int ] = None ,
101
+ pullMode : ConfigN [PullMode ] = None
102
+ ) extends Constraint derives ReadWriter :
103
+ def codeString (using Printer ): String =
104
+ def byName [T ](name : String , value : ConfigN [T ]): String =
105
+ value match
106
+ case None => " "
107
+ case cs : HasCodeString => s " $name = ${cs.codeString}"
108
+ case str : String => s " $name = \" $str\" "
109
+ case _ => s " $name = ${value}"
110
+ val params = List (
111
+ byName(" bitIdx" , bitIdx),
112
+ byName(" loc" , loc),
113
+ byName(" standard" , standard),
114
+ byName(" slewRate" , slewRate),
115
+ byName(" driveStrength" , driveStrength),
116
+ byName(" pullMode" , pullMode)
117
+ ).filter(_.nonEmpty).mkString(" , " )
118
+ s """ @IOConstraints( $params) """
119
+ end codeString
120
+ end IOConstraints
121
+ end io
122
+
123
+ end constraints
0 commit comments