Skip to content

Commit

Permalink
Merge pull request #145 from DFiantHDL/vector_fix
Browse files Browse the repository at this point in the history
Stability batch (see description)
  • Loading branch information
soronpo committed May 18, 2024
2 parents 2797e9e + 95ffa5f commit 53e26a7
Show file tree
Hide file tree
Showing 33 changed files with 758 additions and 151 deletions.
14 changes: 14 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,26 @@ lazy val internals = project
libraryDependencies ++= commonDependencies
)

def additionalSources(scalaVersion: String, base: File): Seq[File] = {
CrossVersion.partialVersion(scalaVersion) match {
case Some((3, minor)) if minor <= 4 =>
Seq(base / "src" / "main" / "scala-3.4-")
case Some((3, minor)) if minor >= 5 =>
Seq(base / "src" / "main" / "scala-3.5+")
case _ =>
Seq.empty
}
}
lazy val plugin = project
.settings(
name := s"$projectName-plugin",
settings,
crossTarget := target.value / s"scala-${scalaVersion.value}", // workaround for https://github.com/sbt/sbt/issues/5097
crossVersion := CrossVersion.full,
Compile / unmanagedSourceDirectories ++= {
val base = baseDirectory.value
additionalSources(scalaVersion.value, base)
},
libraryDependencies += "org.scala-lang" %% "scala3-compiler" % compilerVersion % "provided"
).dependsOn(internals)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ object DFVal:
object Const:
def unapply(applyIdx: ApplyIdx)(using MemberGetSet): Option[Int] =
applyIdx.relIdx.get match
case DFVal.Const(DFUInt(_), data: Option[BigInt] @unchecked, _, _, _) =>
case DFVal.Const(DFInt32, data: Option[BigInt] @unchecked, _, _, _) =>
data.map(_.toInt)
case _ => None

Expand Down
24 changes: 21 additions & 3 deletions compiler/ir/src/main/scala/dfhdl/compiler/ir/DFType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,24 @@ object DFType:
case dt: T => Some(dt)
case _ => None
end Companion

extension (dfType: DFType)
def decompose[B <: DFType](pf: PartialFunction[DFType, B] = a => a)(using
MemberGetSet
): ListSet[B] =
val deps: Iterable[DFType] = dfType match
case dt: DFStruct =>
dt.fieldMap.values.flatMap(_.decompose(pf))
case dt: DFOpaque =>
dt.actualType.decompose(pf)
case dt: DFVector =>
dt.cellType.decompose(pf)
case _ => Nil
ListSet.from(deps.collect(pf) ++ List(dfType).collect(pf))

end DFType

sealed trait ComposedDFType extends DFType
sealed trait NamedDFType extends DFType, NamedGlobal
object NamedDFTypes:
def unapply(dfVal: DFVal)(using MemberGetSet): Option[ListSet[NamedDFType]] =
Expand Down Expand Up @@ -200,7 +216,7 @@ object DFEnum extends DFType.Companion[DFEnum, Option[BigInt]]
final case class DFVector(
cellType: DFType,
cellDims: List[Int]
) extends DFType:
) extends ComposedDFType:
type Data = Vector[Any]
def width(using MemberGetSet): Int = cellType.width * cellDims.product
def createBubbleData(using MemberGetSet): Data = Vector.fill(cellDims.head)(
Expand Down Expand Up @@ -234,7 +250,8 @@ object DFVector extends DFType.Companion[DFVector, Vector[Any]]
// DFOpaque
/////////////////////////////////////////////////////////////////////////////
final case class DFOpaque(protected val name: String, id: DFOpaque.Id, actualType: DFType)
extends NamedDFType:
extends NamedDFType,
ComposedDFType:
type Data = Any
def width(using MemberGetSet): Int = actualType.width
def createBubbleData(using MemberGetSet): Data = actualType.createBubbleData
Expand All @@ -258,7 +275,8 @@ object DFOpaque extends DFType.Companion[DFOpaque, Any]:
final case class DFStruct(
protected val name: String,
fieldMap: ListMap[String, DFType]
) extends NamedDFType:
) extends NamedDFType,
ComposedDFType:
type Data = List[Any]
def getNameForced: String = name
def width(using MemberGetSet): Int = fieldMap.values.map(_.width).sum
Expand Down
2 changes: 1 addition & 1 deletion compiler/ir/src/main/scala/dfhdl/compiler/ir/DataOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def calcFuncData[OT <: DFType](
// bits shifting
case (
op @ (FuncOp.<< | FuncOp.>>),
DFBits(_) :: DFUInt(_) :: Nil,
DFBits(_) :: DFInt32 :: Nil,
(vec: (BitVector, BitVector) @unchecked) :: Some(shift: BigInt) :: Nil
) =>
op match
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ extension (ref: DFRef.TwoWayAny)
def refCodeString(using printer: AbstractValPrinter): String = printer.csRef(ref, false)
def refCodeString(typeCS: Boolean)(using printer: AbstractValPrinter): String =
printer.csRef(ref, typeCS)
def simpleRefCodeString(using printer: AbstractValPrinter): String = printer.csSimpleRef(ref)

extension (intParamRef: IntParamRef)
def refCodeString(typeCS: Boolean)(using printer: AbstractValPrinter): String = intParamRef match
Expand Down Expand Up @@ -152,10 +151,7 @@ protected trait DFValPrinter extends AbstractValPrinter:
case Func.Op.+ | Func.Op.- | Func.Op.`*` if dfVal.dfType.width > argL.get.dfType.width =>
s"${dfVal.op}^"
case op => op.toString
val rhsStr = dfVal.op match
case Func.Op.>> | Func.Op.<< => argR.simpleRefCodeString
case _ => csArgR
s"${csArgL.applyBrackets()} $opStr ${rhsStr.applyBrackets()}"
s"${csArgL.applyBrackets()} $opStr ${csArgR.applyBrackets()}"
// unary/postfix func
case arg :: Nil =>
val csArg = arg.refCodeString(typeCS)
Expand Down Expand Up @@ -240,14 +236,16 @@ protected trait DFValPrinter extends AbstractValPrinter:
s"""d"${printer.csWidthInterp(tWidthParamRef)}'$${${relValStr}}""""
case (DFSInt(tWidthParamRef), DFInt32) =>
s"""sd"${printer.csWidthInterp(tWidthParamRef)}'$${${relValStr}}""""
case (DFInt32, DFUInt(_) | DFSInt(_)) =>
s"${relValStr}.toInt"
case _ =>
throw new IllegalArgumentException("Unsupported alias/conversion")
end match
end csDFValAliasAsIs
def csDFValAliasApplyRange(dfVal: Alias.ApplyRange): String =
s"${dfVal.relValCodeString}(${dfVal.relBitHigh}, ${dfVal.relBitLow})"
def csDFValAliasApplyIdx(dfVal: Alias.ApplyIdx): String =
val relIdxStr = dfVal.relIdx.simpleRefCodeString
val relIdxStr = dfVal.relIdx.refCodeString
s"${dfVal.relValCodeString}($relIdxStr)"
// when the tuple field number exceeds this number, the tuple
// field selections changes from `dv._${idx+1}` to `dv($idx)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,10 @@ protected trait VerilogValPrinter extends AbstractValPrinter:
case DFSInt(_) => ">>>"
case _ => ">>"
case op => op.toString
val rhsStr = dfVal.op match
case Func.Op.>> | Func.Op.<< => argR.simpleRefCodeString
case _ => argR.refCodeString
if (isInfix)
s"${argL.refCodeString.applyBrackets()} $opStr ${rhsStr.applyBrackets()}"
s"${argL.refCodeString.applyBrackets()} $opStr ${argR.refCodeString.applyBrackets()}"
else
s"$opStr(${argL.refCodeString}, ${rhsStr})"
s"$opStr(${argL.refCodeString}, ${argR.refCodeString})"
// unary/postfix func
case arg :: Nil =>
val argStr = arg.refCodeString
Expand Down Expand Up @@ -134,9 +131,9 @@ protected trait VerilogValPrinter extends AbstractValPrinter:
s"${tWidthParamRef.refCodeString.applyBrackets()}'($relValStr)"
case (DFSInt(tWidthParamRef), DFSInt(_) | DFInt32) =>
s"${tWidthParamRef.refCodeString.applyBrackets()}'($relValStr)"
case (DFInt32, DFSInt(_)) => relValStr
case (DFBit, DFBool) => relValStr
case (DFBool, DFBit) => relValStr
case (DFInt32, DFUInt(_) | DFSInt(_)) => relValStr
case (DFBit, DFBool) => relValStr
case (DFBool, DFBit) => relValStr
case (toStruct: DFStruct, _: DFBits) =>
s"${toStruct.getName}'($relValStr)"
case _ => printer.unsupported
Expand All @@ -145,7 +142,7 @@ protected trait VerilogValPrinter extends AbstractValPrinter:
def csDFValAliasApplyRange(dfVal: Alias.ApplyRange): String =
s"${dfVal.relValCodeString}[${dfVal.relBitHigh}:${dfVal.relBitLow}]"
def csDFValAliasApplyIdx(dfVal: Alias.ApplyIdx): String =
val relIdxStr = dfVal.relIdx.simpleRefCodeString
val relIdxStr = dfVal.relIdx.refCodeString
s"${dfVal.relValCodeString}[$relIdxStr]"
// when the tuple field number exceeds this number, the tuple
// field selections changes from `dv._${idx+1}` to `dv($idx)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import dfhdl.internals.*
import DFVal.*
import dfhdl.compiler.ir.ProcessBlock.Sensitivity
import dfhdl.compiler.ir.DFConditional.DFCaseBlock.Pattern

import scala.collection.mutable
import scala.collection.immutable.ListSet
protected trait VHDLOwnerPrinter extends AbstractOwnerPrinter:
type TPrinter <: VHDLPrinter
val useStdSimLibrary: Boolean = true
Expand Down Expand Up @@ -49,15 +50,60 @@ protected trait VHDLOwnerPrinter extends AbstractOwnerPrinter:
end csEntityDcl
def archName(design: DFDesignBlock): String = s"${design.dclName}_arch"
def csArchitectureDcl(design: DFDesignBlock): String =
val localTypeDcls = printer.csLocalTypeDcls(design).emptyOr(x => s"$x\n")
val vectorTypeDcls =
printer.getLocalVectorTypes(design).view.map(printer.csDFVectorDclsLocal)
.mkString("\n").emptyOr(x => s"$x\n")
val structConvFuncs =
getSet.designDB.getLocalNamedDFTypes(design).view
.collect { case dfType: DFStruct => printer.csDFStructConvFuncsBody(dfType) }
.mkString("\n").emptyOr(x => s"$x\n")
val designMembers = design.members(MemberView.Folded)
// collecting all the vhdl named types that are used in conversion to/from bits
val vhdlNamedConvDFTypes = design.members(MemberView.Flattened).view.flatMap {
case alias: DFVal.Alias.AsIs =>
val pf: PartialFunction[DFType, (DFVector | NamedDFType)] = {
case dt: (DFVector | NamedDFType) => dt
}
(alias.dfType, alias.relValRef.get.dfType) match
case (DFBits(_), fromDFType: (NamedDFType | ComposedDFType)) =>
fromDFType.decompose(pf)
case (toDFType: (NamedDFType | ComposedDFType), DFBits(_)) =>
toDFType.decompose(pf)
case _ => None
case _ => None
}.toSet
// the vectors requiring conversion to/from bits
val vectorsConvUsed = vhdlNamedConvDFTypes.collect { case dfType: DFVector =>
printer.getVecDepthAndCellTypeName(dfType)._1
}
// In VHDL the vectors need to be named, and put in dependency order of other named types.
// So first we prepare the vector type declarations in a mutable map and later we remove
// entries that were already placed in the final type printing.
val vectorTypeDcls =
mutable.Map.from(printer.getLocalVectorTypes(design).view.map { (tpName, depth) =>
val dclScope =
if (vectorsConvUsed.contains(tpName)) DclScope.ArchBody else DclScope.TypeOnly
tpName -> printer.csDFVectorDclsLocal(dclScope)(tpName, depth)
})
// collect the local named types, including vectors
val namedDFTypes = ListSet.from(getSet.designDB.designMemberTable(design).view.collect {
case localVar @ DclVar() => localVar.dfType
case localConst @ DclConst() => localConst.dfType
}.flatMap(_.decompose { case dt: (DFVector | NamedDFType) => dt }))
// declarations of the types and relevant functions
val namedTypeConvFuncsDcl = namedDFTypes.view
.flatMap {
// vector types can have different dimensions, but we only need the declaration once
case dfType: DFVector =>
val tpName = printer.getVecDepthAndCellTypeName(dfType)._1
vectorTypeDcls.get(tpName) match
case Some(desc) =>
vectorTypeDcls -= tpName
Some(desc)
case None => None
case dfType: NamedDFType =>
if (vhdlNamedConvDFTypes.contains(dfType))
List(
printer.csNamedDFTypeDcl(dfType, global = false),
printer.csNamedDFTypeConvFuncsBody(dfType)
)
else Some(printer.csNamedDFTypeDcl(dfType, global = false))
}
.mkString("\n").emptyOr(x => s"$x\n")

val dfValDcls =
designMembers.view
.flatMap {
Expand All @@ -70,7 +116,7 @@ protected trait VHDLOwnerPrinter extends AbstractOwnerPrinter:
.toList
.emptyOr(_.mkString("\n"))
val declarations =
s"$localTypeDcls$vectorTypeDcls$structConvFuncs$dfValDcls".emptyOr(v => s"\n${v.hindent}")
s"$namedTypeConvFuncsDcl$dfValDcls".emptyOr(v => s"\n${v.hindent}")
val statements = csDFMembers(designMembers.filter {
case _: DFVal.Dcl => false
case DclConst() => false
Expand Down

0 comments on commit 53e26a7

Please sign in to comment.