aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/MemUtils.scala
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-10-17 18:53:19 -0700
committerAngie Wang2016-10-17 18:53:19 -0700
commit85baeda249e59c7d9d9f159aaf29ff46d685cf02 (patch)
treecfb5f4a6a0a80f9033275de6e5e36b9d5b96faad /src/main/scala/firrtl/passes/MemUtils.scala
parent7d08b9a1486fef0459481f6e542464a29fbe1db5 (diff)
Reorganized memory blackboxing (#336)
* Reorganized memory blackboxing Moved to new package memlib Added comments Moved utility functions around Removed unused AnnotateValidMemConfigs.scala * Fixed tests to pass * Use DefAnnotatedMemory instead of AppendableInfo * Broke passes up into simpler passes AnnotateMemMacros -> (ToMemIR, ResolveMaskGranularity) UpdateDuplicateMemMacros -> (RenameAnnotatedMemoryPorts, ResolveMemoryReference) * Fixed to make tests run * Minor changes from code review * Removed vim comments and renamed ReplSeqMem
Diffstat (limited to 'src/main/scala/firrtl/passes/MemUtils.scala')
-rw-r--r--src/main/scala/firrtl/passes/MemUtils.scala50
1 files changed, 33 insertions, 17 deletions
diff --git a/src/main/scala/firrtl/passes/MemUtils.scala b/src/main/scala/firrtl/passes/MemUtils.scala
index 92673433..8cd58afb 100644
--- a/src/main/scala/firrtl/passes/MemUtils.scala
+++ b/src/main/scala/firrtl/passes/MemUtils.scala
@@ -43,39 +43,55 @@ object seqCat {
}
}
+/** Given an expression, return an expression consisting of all sub-expressions
+ * concatenated (or flattened).
+ */
object toBits {
def apply(e: Expression): Expression = e match {
- case ex @ (_: WRef | _: WSubField | _: WSubIndex) => hiercat(ex, ex.tpe)
+ case ex @ (_: WRef | _: WSubField | _: WSubIndex) => hiercat(ex)
case t => error("Invalid operand expression for toBits!")
}
- private def hiercat(e: Expression, dt: Type): Expression = dt match {
+ private def hiercat(e: Expression): Expression = e.tpe match {
case t: VectorType => seqCat((0 until t.size) map (i =>
- hiercat(WSubIndex(e, i, t.tpe, UNKNOWNGENDER),t.tpe)))
+ hiercat(WSubIndex(e, i, t.tpe, UNKNOWNGENDER))))
case t: BundleType => seqCat(t.fields map (f =>
- hiercat(WSubField(e, f.name, f.tpe, UNKNOWNGENDER), f.tpe)))
+ hiercat(WSubField(e, f.name, f.tpe, UNKNOWNGENDER))))
case t: GroundType => e
case t => error("Unknown type encountered in toBits!")
}
}
-// TODO: make easier to understand
+/** Given a mask, return a bitmask corresponding to the desired datatype.
+ * Requirements:
+ * - The mask type and datatype must be equivalent, except any ground type in
+ * datatype must be matched by a 1-bit wide UIntType.
+ * - The mask must be a reference, subfield, or subindex
+ * The bitmask is a series of concatenations of the single mask bit over the
+ * length of the corresponding ground type, e.g.:
+ *{{{
+ * wire mask: {x: UInt<1>, y: UInt<1>}
+ * wire data: {x: UInt<2>, y: SInt<2>}
+ * // this would return:
+ * cat(cat(mask.x, mask.x), cat(mask.y, mask.y))
+ * }}}
+ */
object toBitMask {
- def apply(e: Expression, dataType: Type): Expression = e match {
- case ex @ (_: WRef | _: WSubField | _: WSubIndex) => hiermask(ex, ex.tpe, dataType)
+ def apply(mask: Expression, dataType: Type): Expression = mask match {
+ case ex @ (_: WRef | _: WSubField | _: WSubIndex) => hiermask(ex, dataType)
case t => error("Invalid operand expression for toBits!")
}
- private def hiermask(e: Expression, maskType: Type, dataType: Type): Expression =
- (maskType, dataType) match {
+ private def hiermask(mask: Expression, dataType: Type): Expression =
+ (mask.tpe, dataType) match {
case (mt: VectorType, dt: VectorType) =>
seqCat((0 until mt.size).reverse map { i =>
- hiermask(WSubIndex(e, i, mt.tpe, UNKNOWNGENDER), mt.tpe, dt.tpe)
+ hiermask(WSubIndex(mask, i, mt.tpe, UNKNOWNGENDER), dt.tpe)
})
case (mt: BundleType, dt: BundleType) =>
seqCat((mt.fields zip dt.fields) map { case (mf, df) =>
- hiermask(WSubField(e, mf.name, mf.tpe, UNKNOWNGENDER), mf.tpe, df.tpe)
+ hiermask(WSubField(mask, mf.name, mf.tpe, UNKNOWNGENDER), df.tpe)
})
- case (mt: UIntType, dt: GroundType) =>
- seqCat(List.fill(bitWidth(dt).intValue)(e))
+ case (UIntType(width), dt: GroundType) if width == IntWidth(BigInt(1)) =>
+ seqCat(List.fill(bitWidth(dt).intValue)(mask))
case (mt, dt) => error("Invalid type for mask component!")
}
}
@@ -153,7 +169,7 @@ object createSubField {
}
object connectFields {
- def apply(lref: Expression, lname: String, rref: Expression, rname: String) =
+ def apply(lref: Expression, lname: String, rref: Expression, rname: String): Connect =
Connect(NoInfo, createSubField(lref, lname), createSubField(rref, rname))
}
@@ -166,14 +182,14 @@ object MemPortUtils {
type Memories = collection.mutable.ArrayBuffer[DefMemory]
type Modules = collection.mutable.ArrayBuffer[DefModule]
- def defaultPortSeq(mem: DefMemory) = Seq(
+ def defaultPortSeq(mem: DefMemory): Seq[Field] = Seq(
Field("addr", Default, UIntType(IntWidth(ceilLog2(mem.depth) max 1))),
Field("en", Default, BoolType),
Field("clk", Default, ClockType)
)
// Todo: merge it with memToBundle
- def memType(mem: DefMemory) = {
+ def memType(mem: DefMemory): Type = {
val rType = BundleType(defaultPortSeq(mem) :+
Field("data", Flip, mem.dataType))
val wType = BundleType(defaultPortSeq(mem) ++ Seq(
@@ -190,7 +206,7 @@ object MemPortUtils {
(mem.readwriters map (Field(_, Flip, rwType))))
}
- def memPortField(s: DefMemory, p: String, f: String) = {
+ def memPortField(s: DefMemory, p: String, f: String): Expression = {
val mem = WRef(s.name, memType(s), MemKind, UNKNOWNGENDER)
val t1 = field_type(mem.tpe, p)
val t2 = field_type(t1, f)