Skip to content

Commit 082a749

Browse files
author
Oron Port
committed
preparing for <> operator change and adapting to DFVal value class removal changes
1 parent f5ef519 commit 082a749

File tree

11 files changed

+87
-64
lines changed

11 files changed

+87
-64
lines changed

core/src/main/scala/dfhdl/core/DFC.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import scala.annotation.Annotation
99
import scala.annotation.implicitNotFound
1010
import ir.annotation.HWAnnotation
1111

12+
@implicitNotFound(
13+
"Missing local design context.\nEither this operation is not supported in global context or `using DFC` is missing."
14+
)
1215
final case class DFC(
1316
nameOpt: Option[String],
1417
position: Position,

core/src/main/scala/dfhdl/core/DFType.scala

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -101,34 +101,6 @@ object DFType:
101101
type Supported = DFTypeAny | FieldsOrTuple | DFEncoding | DFOpaqueA | Byte | Int | Long |
102102
Boolean | Double | String | Object | Unit
103103

104-
given evPortVarConstructor[
105-
T <: Supported,
106-
A,
107-
C,
108-
I,
109-
P,
110-
M <: Modifier[A, C, I, P]
111-
](using
112-
tc: DFType.TC[T],
113-
checkLocal: AssertGiven[DFC.Scope.Local, "Port/Variable declarations cannot be global"],
114-
ck: DFC.Scope,
115-
dt: DomainType
116-
): ExactOp2Aux["<>", DFC, Any, T, M, DFVal[
117-
tc.Type,
118-
Modifier[A & ck.type & dt.type, C, I, P]
119-
]] = new ExactOp2["<>", DFC, Any, T, M]:
120-
type Out = DFVal[tc.Type, Modifier[A & ck.type & dt.type, C, I, P]]
121-
def apply(t: T, modifier: M)(using DFC): Out = trydf {
122-
if (modifier.value.isPort)
123-
dfc.owner.asIR match
124-
case _: ir.DFDomainOwner =>
125-
case _ =>
126-
throw new IllegalArgumentException(
127-
"Ports can only be directly owned by a design, a domain or an interface."
128-
)
129-
DFVal.Dcl(tc(t), modifier.asInstanceOf[Modifier[A & ck.type & dt.type, C, I, P]])
130-
}(using dfc, CTName("Port/Variable constructor"))
131-
end evPortVarConstructor
132104
object Ops:
133105
extension [T <: Supported](t: T)
134106
infix def <>[A, C, I, P](modifier: Modifier[A, C, I, P])(using
@@ -163,6 +135,11 @@ object DFType:
163135
]
164136
object TC extends TCLP:
165137
type Aux[T, OT <: DFTypeAny] = TC[T] { type Type = OT }
138+
def apply[T, OT <: DFTypeAny](value: OT): Aux[T, OT] =
139+
new TC[T]:
140+
type Type = OT
141+
def apply(t: T)(using DFC): Type = value
142+
166143
given ofDFType[T <: DFTypeAny]: TC[T] with
167144
type Type = T
168145
def apply(t: T)(using DFC): Type = t
@@ -206,25 +183,16 @@ object DFType:
206183
)
207184
val clsTpe = compPrefix.select(clsSym)
208185
clsTpe.asType match
209-
case '[t & DFEncoding] =>
210-
'{
211-
new TC[T]:
212-
type Type = DFEnum[t & DFEncoding]
213-
def apply(t: T)(using DFC): Type = summonInline[DFEnum[t & DFEncoding]]
214-
}
215-
case '[t & DFStruct.Fields] =>
216-
'{
217-
new TC[T]:
218-
type Type = DFStruct[t & DFStruct.Fields]
219-
def apply(t: T)(using DFC): Type =
220-
summonInline[DFStruct[t & DFStruct.Fields]]
221-
}
222-
case '[t & DFOpaque.Abstract] =>
186+
case '[DFEncoding] =>
187+
val clsType = clsTpe.asTypeOf[DFEncoding]
188+
'{ apply[T, DFEnum[clsType.Underlying]](summonInline[DFEnum[clsType.Underlying]]) }
189+
case '[DFStruct.Fields] =>
190+
val clsType = clsTpe.asTypeOf[DFStruct.Fields]
191+
'{ apply[T, DFStruct[clsType.Underlying]](summonInline[DFStruct[clsType.Underlying]]) }
192+
case '[DFOpaque.Abstract] =>
193+
val clsType = clsTpe.asTypeOf[DFOpaque.Abstract]
223194
'{
224-
new TC[T]:
225-
type Type = DFOpaque[t & DFOpaque.Abstract]
226-
def apply(t: T)(using DFC): Type =
227-
summonInline[DFOpaque[t & DFOpaque.Abstract]]
195+
apply[T, DFOpaque[clsType.Underlying]](summonInline[DFOpaque[clsType.Underlying]])
228196
}
229197
case _ =>
230198
val badTypeStr = clsTpe.show

core/src/main/scala/dfhdl/core/DFVal.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ import dfhdl.platforms.resources.Resource
1616

1717
import scala.reflect.ClassTag
1818
final class DFVal[+T <: DFTypeAny, +M <: ModifierAny](val irValue: ir.DFVal | DFError)
19-
extends AnyVal
20-
with DFMember[ir.DFVal]
19+
extends DFMember[ir.DFVal]
2120
with Selectable:
2221
type Fields = DFVal.Fields[T @uncheckedVariance, M @uncheckedVariance]
2322

23+
def wait(using DFC): Unit =
24+
trydf { Wait(this.asValOf[DFBoolOrBit]) }
2425
def selectDynamic(name: String)(using DFC): Any = trydf {
2526
val ir.DFStruct(structName, fieldMap) = this.asIR.dfType: @unchecked
2627
val dfType = fieldMap(name)
@@ -1577,6 +1578,7 @@ object ConnectOps:
15771578
L <: DFVal[T, M],
15781579
R
15791580
](using
1581+
skipResource: util.NotGiven[R <:< Resource],
15801582
connectableOnly: ConnectableOnly2[C],
15811583
tc: DFVal.TC_Or_OPEN_Or_Resource[T, R]
15821584
): ExactOp2Aux["<>", DFC, Any, L, R, Unit] = new ExactOp2["<>", DFC, Any, L, R]:

core/src/main/scala/dfhdl/core/DFVector.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ object DFVector:
6363

6464
object Ops:
6565
extension [T <: DFType.Supported, D <: IntP](t: T)(using tc: DFType.TC[T])
66-
infix def X(
66+
def X(
6767
cellDim: IntParam[D]
6868
)(using
6969
dfc: DFCG

core/src/main/scala/dfhdl/core/Design.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ trait Design extends Container, HasClsMetaArgs:
6262

6363
def customTopChecks(): Unit = {}
6464
private def handleResourceConstraints(): Unit =
65-
import dfhdl.{<>, OUT, NOTHING}
65+
import dfhdl.{OUT, NOTHING}
6666
import ir.constraints.{IO, SigConstraint}
6767
import dfhdl.platforms.resources.*
6868
import dfhdl.platforms.devices.Pin
@@ -83,9 +83,11 @@ trait Design extends Container, HasClsMetaArgs:
8383
else (IO(pullMode = unusedPullMode) :: constraints).merge
8484
val updatedAnnotations = ir.annotation.Unused.Keep :: updatedConstraints
8585
val port =
86-
DFBit.<>(OUT)(using dfc.setName(s"Pin_${pinID}_unused").setAnnotations(updatedAnnotations))
87-
if (driveZero) port <> DFVal.Const(DFBit, Some(false), named = false)
88-
else port <> NOTHING(DFBit)(using dfc.anonymize)
86+
DFVal.Dcl(DFBit, OUT)(using
87+
dfc.setName(s"Pin_${pinID}_unused").setAnnotations(updatedAnnotations)
88+
)
89+
if (driveZero) port.connect(DFVal.Const(DFBit, Some(false), named = false))
90+
else port.connect(NOTHING(DFBit)(using dfc.anonymize))
8991
end addUnusedPinPort
9092
val usedPinIDs: Set[String] =
9193
dfc.mutableDB.ResourceOwnershipContext

core/src/main/scala/dfhdl/core/Modifier.scala

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dfhdl.core
2-
import dfhdl.compiler.ir.DFVal.Modifier as IRModifier
2+
import dfhdl.compiler.ir
3+
import ir.DFVal.Modifier as IRModifier
34
import dfhdl.internals.*
45

56
//A: Access, C: Connectivity, I: Initialization, P: Parameteric (Const or not)
@@ -43,6 +44,35 @@ object Modifier:
4344
object INOUT extends DclPort[PortINOUT](IRModifier(IRModifier.INOUT, IRModifier.Ordinary))
4445
type CONST = Modifier[Any, Any, Any, dfhdl.core.CONST]
4546
extension (modifier: ModifierAny) def asIR: IRModifier = modifier.value
47+
48+
given evPortVarConstructor[
49+
T <: DFType.Supported,
50+
A,
51+
C,
52+
I,
53+
P,
54+
M <: Modifier[A, C, I, P]
55+
](using
56+
tc: DFType.TC[T],
57+
checkLocal: AssertGiven[DFC.Scope.Local, "Port/Variable declarations cannot be global"],
58+
ck: DFC.Scope,
59+
dt: DomainType
60+
): ExactOp2Aux["<>", DFC, Any, T, M, DFVal[
61+
tc.Type,
62+
Modifier[A & ck.type & dt.type, C, I, P]
63+
]] = new ExactOp2["<>", DFC, Any, T, M]:
64+
type Out = DFVal[tc.Type, Modifier[A & ck.type & dt.type, C, I, P]]
65+
def apply(t: T, modifier: M)(using DFC): Out = trydf {
66+
if (modifier.value.isPort)
67+
dfc.owner.asIR match
68+
case _: ir.DFDomainOwner =>
69+
case _ =>
70+
throw new IllegalArgumentException(
71+
"Ports can only be directly owned by a design, a domain or an interface."
72+
)
73+
DFVal.Dcl(tc(t), modifier.asInstanceOf[Modifier[A & ck.type & dt.type, C, I, P]])
74+
}(using dfc, CTName("Port/Variable constructor"))
75+
end evPortVarConstructor
4676
end Modifier
4777

4878
sealed trait VAL

core/src/main/scala/dfhdl/core/Wait.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ object Wait:
3232
// with our own wait method, so we need to extend this in the Container trait, instead
3333
// of relying on export like the rest of the core API.
3434
trait ContainerOps:
35-
extension (lhs: DFConstOf[DFTime]) final def wait(using DFC): Wait = trydf { Wait(lhs) }
36-
extension (lhs: Cycles) final def wait(using DFC, CYInRT): Wait = trydf { Wait(lhs) }
35+
final def wait(lhs: DFConstOf[DFTime])(using DFC): Unit = trydf { Wait(lhs) }
36+
final def wait(lhs: Cycles)(using DFC, CYInRT): Unit = trydf { Wait(lhs) }
3737
inline def java_wait(): Unit = this.wait()
3838
inline def java_wait(timeoutMillis: Long): Unit = this.wait(timeoutMillis)
3939
inline def java_wait(timeoutMillis: Long, nanos: Int): Unit = this.wait(timeoutMillis, nanos)

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,21 @@ private trait ResourceLP:
6666

6767
object Resource extends ResourceLP:
6868
@implicitNotFound("Cannot connect the resource ${R} with ${T}")
69-
trait CanConnect[R <: Resource, T]:
69+
trait CanConnect[-R <: Resource, -T]:
7070
def connect(resource1: R, resource2: T)(using DFC): Unit
7171
given [R <: Resource, T <: Resource](using R =:= T): CanConnect[R, T] with
7272
def connect(resource1: R, resource2: T)(using DFC): Unit =
7373
resource1.connectFrom(resource2)
7474
resource2.connectFrom(resource1)
7575

76+
given [R <: Resource, T <: Resource | DFValAny | RTDomainContainer](using
77+
cc: CanConnect[R, T]
78+
): ExactOp2Aux["<>", DFC, Any, R, T, Unit] =
79+
new ExactOp2["<>", DFC, Any, R, T]:
80+
type Out = Unit
81+
def apply(resource1: R, resourceOrValue: T)(using DFC): Out =
82+
cc.connect(resource1, resourceOrValue)
83+
end given
7684
object Ops:
7785
extension [R <: Resource](resource: R)
7886
def <>[T <: Resource](that: T)(using dfc: DFC, cc: CanConnect[R, T]): Unit =

internals/src/main/scala/dfhdl/internals/Exact.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,29 +320,29 @@ private def exactOp2Macro[Op, Ctx, OutUB](
320320
import quotes.reflect.*
321321
val lhsExactInfo = lhs.exactInfo
322322
val rhsExactInfo = rhs.exactInfo
323-
Expr.summon[ExactOp2[
323+
Expr.summonOrError[ExactOp2[
324324
Op,
325325
Ctx,
326326
OutUB,
327327
lhsExactInfo.Underlying,
328328
rhsExactInfo.Underlying
329329
]] match
330-
case Some(expr) => '{
330+
case Right(expr) => '{
331331
$expr(${ lhsExactInfo.exactExpr }, ${ rhsExactInfo.exactExpr })(using $ctx)
332332
}
333-
case None =>
333+
case Left(msg) =>
334334
if (bothWays.value.get)
335-
Expr.summon[ExactOp2[
335+
Expr.summonOrError[ExactOp2[
336336
Op,
337337
Ctx,
338338
OutUB,
339339
rhsExactInfo.Underlying,
340340
lhsExactInfo.Underlying
341341
]] match
342-
case Some(expr) => '{
342+
case Right(expr) => '{
343343
$expr(${ rhsExactInfo.exactExpr }, ${ lhsExactInfo.exactExpr })(using $ctx)
344344
}
345-
case None =>
345+
case Left(msg) =>
346346
IsGiven.controlledMacroError("Unsupported argument types for this operation.")
347347
else
348348
IsGiven.controlledMacroError("Unsupported argument types for this operation.")

internals/src/main/scala/dfhdl/internals/helpers.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ extension [T](lhs: Iterable[T])
6363
lhs.groupBy(new Unique(_)).values.map(_.toList)
6464
end extension
6565

66+
extension (exprObject: Expr.type)(using Quotes)
67+
def summonOrError[T: Type]: Either[String, Expr[T]] =
68+
import quotes.reflect.*
69+
Implicits.search(TypeRepr.of[T]) match
70+
case iss: ImplicitSearchSuccess =>
71+
Right(iss.tree.asExprOf[T])
72+
case isf: ImplicitSearchFailure =>
73+
Left(isf.explanation)
74+
end extension
75+
6676
extension (using quotes: Quotes)(tpe: quotes.reflect.TypeRepr)
6777
def asTypeOf[T <: AnyKind]: Type[T] =
6878
import quotes.reflect.*

0 commit comments

Comments
 (0)