Skip to content

Commit

Permalink
introduce TCConv
Browse files Browse the repository at this point in the history
  • Loading branch information
Oron Port committed Dec 24, 2024
1 parent 9b13c2c commit 9ce91e5
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 48 deletions.
30 changes: 18 additions & 12 deletions core/src/main/scala/dfhdl/core/DFBits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ object DFBits:
dfc: DFC,
v: ValueOf[W],
check: Arg.Width.CheckNUB[W]
): DFBits[W] =
): DFBits[W] = trydf:
val width = IntParam.forced(v)
check(width.toScalaInt)
ir.DFBits(width.ref).asFE[DFBits[W]]
Expand Down Expand Up @@ -445,17 +445,13 @@ object DFBits:
def conv(dfType: DFBits[LW], value: V)(using dfc: DFC): Out =
import Ops.resizeBits
val dfVal = ic(value)
(dfType.asIR: ir.DFType) match
case ir.DFNothing =>
dfVal.nameInDFCPosition.asValTP[DFBits[LW], ic.OutP]
case _ =>
if (dfVal.hasTag[DFVal.TruncateTag] && dfType.widthInt < dfVal.widthInt)
dfVal.resizeBits(dfType.widthIntParam).asValTP[DFBits[LW], ic.OutP]
else if (dfVal.hasTag[DFVal.ExtendTag] && dfType.widthInt > dfVal.widthInt)
dfVal.resizeBits(dfType.widthIntParam).asValTP[DFBits[LW], ic.OutP]
else
check(dfType.widthInt, dfVal.widthInt)
dfVal.nameInDFCPosition.asValTP[DFBits[LW], ic.OutP]
if (dfVal.hasTag[DFVal.TruncateTag] && dfType.widthInt < dfVal.widthInt)
dfVal.resizeBits(dfType.widthIntParam).asValTP[DFBits[LW], ic.OutP]
else if (dfVal.hasTag[DFVal.ExtendTag] && dfType.widthInt > dfVal.widthInt)
dfVal.resizeBits(dfType.widthIntParam).asValTP[DFBits[LW], ic.OutP]
else
check(dfType.widthInt, dfVal.widthInt)
dfVal.nameInDFCPosition.asValTP[DFBits[LW], ic.OutP]
end conv
end DFBitsFromCandidate
given DFBitsFromSEV[LW <: IntP, T <: BitOrBool, V <: SameElementsVector[T]]: TC[DFBits[LW], V]
Expand All @@ -466,6 +462,16 @@ object DFBits:
.asConstOf[DFBits[LW]]
end TC

object TCConv:
import DFVal.TCConv
given DFBitsFromCandidateConv[V, IC <: Candidate[V]](using
ic: IC
): TCConv[DFBits[Int], V] with
type OutP = ic.OutP
def apply(value: V)(using DFC): Out =
val dfVal = ic(value)
dfVal.nameInDFCPosition.asValTP[DFBits[Int], ic.OutP]

object Compare:
import DFVal.Compare
given DFBitsCompareCandidate[LW <: IntP, R, IC <: Candidate[R], Op <: FuncOp, C <: Boolean](
Expand Down
43 changes: 27 additions & 16 deletions core/src/main/scala/dfhdl/core/DFDecimal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ object DFDecimal:
ValueOf[W],
ValueOf[F],
ValueOf[N]
)(using DFC, Width.CheckNUB[S, W]): DFDecimal[S, W, F, N] =
)(using DFC, Width.CheckNUB[S, W]): DFDecimal[S, W, F, N] = trydf:
DFDecimal(valueOf[S], IntParam[W](valueOf[W]), valueOf[F], valueOf[N])
object Extensions:
extension [S <: Boolean, W <: IntP, F <: Int, N <: NativeType](dfType: DFDecimal[S, W, F, N])
Expand Down Expand Up @@ -576,6 +576,8 @@ object DFDecimal:
`LS >= RS`(dfType.signed, dfVal.dfType.signed)
dfVal
end TC
object TCConv:
export DFXInt.Val.TCConv.given
object Compare:
export DFXInt.Val.Compare.given
object Ops:
Expand Down Expand Up @@ -713,31 +715,40 @@ object DFXInt:
given [LS <: Boolean, LW <: IntP, LN <: NativeType, R, IC <: Candidate[R]](using
ic: IC
)(using
check: TCCheck[LS, LW, ic.OutSMask, ic.OutWMask],
lsigned: OptionalGiven[ValueOf[LS]]
check: TCCheck[LS, LW, ic.OutSMask, ic.OutWMask]
): TC[DFXInt[LS, LW, LN], R] with
type OutP = ic.OutP
def conv(dfType: DFXInt[LS, LW, LN], value: R)(using dfc: DFC): Out =
import Ops.resize
import DFUInt.Val.Ops.signed
val rhs = ic(value)
(dfType.asIR: ir.DFType) match
case ir.DFNothing =>
val signCheck = summon[`LS >= RS`.Check[Boolean, Boolean]]
signCheck(lsigned.get.value, rhs.dfType.signed)
if (lsigned.get.value != rhs.dfType.signed.value)
rhs.asValOf[DFUInt[Int]].signed.asValTP[DFXInt[LS, LW, LN], ic.OutP]
else rhs.asValTP[DFXInt[LS, LW, LN], ic.OutP]
case _ =>
val (rhsSigned, rhsWidth) = rhs.getActualSignedWidth
if (!rhs.hasTag[DFVal.TruncateTag] || dfType.signed != rhsSigned)
check(dfType.signed, dfType.widthInt, rhsSigned, rhsWidth)
DFXInt.Val.Ops.toDFXIntOf(rhs)(dfType).asValTP[DFXInt[LS, LW, LN], ic.OutP]
end match
val (rhsSigned, rhsWidth) = rhs.getActualSignedWidth
if (!rhs.hasTag[DFVal.TruncateTag] || dfType.signed != rhsSigned)
check(dfType.signed, dfType.widthInt, rhsSigned, rhsWidth)
DFXInt.Val.Ops.toDFXIntOf(rhs)(dfType).asValTP[DFXInt[LS, LW, LN], ic.OutP]
end conv
end given
end TC

object TCConv:
import DFVal.TCConv
given [LS <: Boolean, R, IC <: Candidate[R]](using
ic: IC
)(using
checkS: `LS >= RS`.Check[LS, ic.OutSMask],
lsigned: OptionalGiven[ValueOf[LS]]
): TCConv[DFXInt[LS, Int, BitAccurate], R] with
type OutP = ic.OutP
def apply(value: R)(using dfc: DFC): Out =
import DFUInt.Val.Ops.signed
val rhs = ic(value)
checkS(lsigned.get.value, rhs.dfType.signed)
if (lsigned.get.value != rhs.dfType.signed.value)
rhs.asValOf[DFUInt[Int]].signed.asValTP[DFXInt[LS, Int, BitAccurate], ic.OutP]
else rhs.asValTP[DFXInt[LS, Int, BitAccurate], ic.OutP]
end given
end TCConv

object Compare:
import DFVal.Compare
given DFXIntCompare[
Expand Down
32 changes: 26 additions & 6 deletions core/src/main/scala/dfhdl/core/DFTuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object DFTuple:
T <: NonEmptyTuple,
V <: NonEmptyTuple,
O,
TC[T <: DFTypeAny, V] <: TCConv[T, V, O]
TC[T <: DFTypeAny, V] <: TCCommon[T, V, O]
]:
type OutP
def apply(
Expand All @@ -48,15 +48,15 @@ object DFTuple:
T <: NonEmptyTuple,
V <: NonEmptyTuple,
O,
TC[T <: DFTypeAny, V] <: TCConv[T, V, O]
TC[T <: DFTypeAny, V] <: TCCommon[T, V, O]
]: TCZipper[T, V, O, TC] = ${
zipperMacro[T, V, O, TC]
}
def zipperMacro[
T <: NonEmptyTuple,
V <: NonEmptyTuple,
O,
TC[T <: DFTypeAny, V] <: TCConv[T, V, O]
TC[T <: DFTypeAny, V] <: TCCommon[T, V, O]
](using
Quotes,
Type[T],
Expand Down Expand Up @@ -140,11 +140,9 @@ object DFTuple:
def conv(dfType: DFTuple[T], value: R)(using DFC): Out =
val dfVals =
zipper(dfType.fieldList, value.toList)
// reconstructing the Tuple DFType, in case fields could be DFNothing from conversions
val fixedDFType = DFTuple(dfVals.map(_.dfType))
// normally would have used `.asValTP`, but this triggers a compiler crash
// https://github.com/lampepfl/dotty/issues/17326
DFVal.Func(fixedDFType, FuncOp.++, dfVals).asInstanceOf[Out]
DFVal.Func(dfType, FuncOp.++, dfVals).asInstanceOf[Out]
end DFTupleFromTuple
given DFTupleFromDFTuple[
T <: NonEmptyTuple,
Expand All @@ -161,6 +159,28 @@ object DFTuple:
end DFTupleFromDFTuple
end TC

object TCConv:
import DFVal.TCConv
given DFTupleFromTuple[
T <: NonEmptyTuple,
R <: NonEmptyTuple,
Z <: TCZipper[T, R, DFValAny, TCConv]
](using
zipper: Z
): TCConv[DFTuple[T], R] with
type OutP = zipper.OutP
def apply(value: R)(using DFC): Out =
val valueList = value.toList
val dfVals =
zipper(List.fill(valueList.length)(DFNothing), valueList)
// reconstructing the Tuple DFType, since we fed DFNothing to the zipper
val fixedDFType = DFTuple(dfVals.map(_.dfType))
// normally would have used `.asValTP`, but this triggers a compiler crash
// https://github.com/lampepfl/dotty/issues/17326
DFVal.Func(fixedDFType, FuncOp.++, dfVals).asInstanceOf[Out]
end DFTupleFromTuple
end TCConv

object Compare:
import DFVal.Compare
given DFTupleArg[
Expand Down
1 change: 0 additions & 1 deletion core/src/main/scala/dfhdl/core/DFType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ object DFType:
// unlike the other types, this caused issues when defined in DFStruct and exported here.
// there is some kind of Scala compiler bug (unreported) and this is a workaround.
inline given fromFieldsOrTuple[F <: FieldsOrTuple]: DFStruct[F] = ${ DFStruct.dfTypeMacro[F] }
given [T <: DFTypeAny & Singleton](using ValueOf[T]): T = valueOf[T]

given [T <: DFTypeAny]: CanEqual[T, T] = CanEqual.derived

Expand Down
28 changes: 20 additions & 8 deletions core/src/main/scala/dfhdl/core/DFVal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,10 @@ def DFValConversionMacro[T <: DFTypeAny, P, R](
else
val tStr = Expr(s"implicit conversion to type ${TypeRepr.of[T].showDFType}")
'{
given bitsNoType: DFBits[Int] = DFNothing.asInstanceOf[DFBits[Int]]
given uintNoType: DFUInt[Int] = DFNothing.asInstanceOf[DFUInt[Int]]
given sintNoType: DFSInt[Int] = DFNothing.asInstanceOf[DFSInt[Int]]
val tc = compiletime.summonInline[DFVal.TC[T, fromExactInfo.Underlying]]
val tc = compiletime.summonInline[DFVal.TCConv[T, fromExactInfo.Underlying]]
val dfc = compiletime.summonInline[DFC]
trydf {
val dfType = compiletime.summonInline[T]
tc(dfType, ${ fromExactInfo.exactExpr })(using dfc).asValTP[T, P]
tc(${ fromExactInfo.exactExpr })(using dfc).asValTP[T, P]
}(using dfc, CTName($tStr))
}
end if
Expand Down Expand Up @@ -871,7 +867,7 @@ object DFVal extends DFValLP:
end SelectField
end Alias

trait TC[T <: DFTypeAny, R] extends TCConv[T, R, DFValAny]:
trait TC[T <: DFTypeAny, R] extends TCCommon[T, R, DFValAny]:
type OutP
type Out = DFValTP[T, OutP]
final def apply(dfType: T, value: R)(using DFC): Out = trydf:
Expand Down Expand Up @@ -946,6 +942,22 @@ object DFVal extends DFValLP:
export DFOpaque.Val.TC.given
end TC

trait TCConv[T <: DFTypeAny, R] extends TC[T, R]:
type OutP
type Out = DFValTP[T, OutP]
def conv(dfType: T, from: R)(using DFC): Out = apply(from)
def apply(from: R)(using DFC): Out

trait TCConvLP:
given fromTC[T <: DFTypeAny, R, TC <: DFVal.TC[T, R]](using tc: TC, dfType: T): TCConv[T, R]
with
type OutP = tc.OutP
def apply(from: R)(using DFC): Out = tc(dfType, from)
object TCConv extends TCConvLP:
export DFBits.Val.TCConv.given
export DFDecimal.Val.TCConv.given
export DFTuple.Val.TCConv.given

trait TC_Or_OPEN[T <: DFTypeAny, R] extends TC[T, R]
object TC_Or_OPEN:
type Exact[T <: DFTypeAny] = Exact1[DFTypeAny, T, [t <: DFTypeAny] =>> t, DFC, TC_Or_OPEN]
Expand All @@ -956,7 +968,7 @@ object DFVal extends DFValLP:
type OutP = tc.OutP
def conv(dfType: T, from: R)(using DFC): Out = tc(dfType, from)

trait Compare[T <: DFTypeAny, V, Op <: FuncOp, C <: Boolean] extends TCConv[T, V, DFValAny]:
trait Compare[T <: DFTypeAny, V, Op <: FuncOp, C <: Boolean] extends TCCommon[T, V, DFValAny]:
type OutP
type Out = DFValTP[T, OutP]
final protected def func[P1, P2](arg1: DFValTP[?, P1], arg2: DFValTP[?, P2])(using
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/dfhdl/core/DFVector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ object DFVector:
cellType: T,
d: ValueOf[D],
check: VectorLength.CheckNUB[D]
): DFVector[T, Tuple1[D]] =
): DFVector[T, Tuple1[D]] = trydf:
val cellDim = IntParam.fromValue(d)
check(cellDim)
DFVector(cellType, List(cellDim))
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/scala/dfhdl/core/TCCommon.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dfhdl.core
import dfhdl.internals.Exact1
trait TCCommon[T <: DFTypeAny, V, O]
extends Exact1.TC[DFTypeAny, T, [t <: DFTypeAny] =>> t, V, DFC]:
type Out <: O
4 changes: 0 additions & 4 deletions core/src/main/scala/dfhdl/core/TCConv.scala

This file was deleted.

0 comments on commit 9ce91e5

Please sign in to comment.