diff options
| author | Angie Wang | 2016-10-23 19:32:18 -0700 |
|---|---|---|
| committer | Donggyu | 2016-10-23 19:32:18 -0700 |
| commit | de45e93c43201c5b757d681fb922a57564462a08 (patch) | |
| tree | 0593b4e4d846ab2a205ca7ef4f6f66606775c023 /src/main/scala/firrtl/passes/MemUtils.scala | |
| parent | bcf73fb70969e5629a693c18f1f2ee7b37f14a76 (diff) | |
Fix bitmask (#346)
* toBitMask cat direction should be consistent with data
* minor comment updates
* moved remaining mem passes/utils to memlib
* changed again so that data, mask are consistent. data element 0, bit 0 = LSB (on RHS) when concatenated
Diffstat (limited to 'src/main/scala/firrtl/passes/MemUtils.scala')
| -rw-r--r-- | src/main/scala/firrtl/passes/MemUtils.scala | 215 |
1 files changed, 0 insertions, 215 deletions
diff --git a/src/main/scala/firrtl/passes/MemUtils.scala b/src/main/scala/firrtl/passes/MemUtils.scala deleted file mode 100644 index 8cd58afb..00000000 --- a/src/main/scala/firrtl/passes/MemUtils.scala +++ /dev/null @@ -1,215 +0,0 @@ -/* - Copyright (c) 2014 - 2016 The Regents of the University of - California (Regents). All Rights Reserved. Redistribution and use in - source and binary forms, with or without modification, are permitted - provided that the following conditions are met: - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - two paragraphs of disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - two paragraphs of disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of the Regents nor the names of its contributors - may be used to endorse or promote products derived from this - software without specific prior written permission. - IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, - ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF - ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION - TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR - MODIFICATIONS. - */ - -package firrtl.passes - -import firrtl._ -import firrtl.ir._ -import firrtl.Utils._ -import firrtl.PrimOps._ - -object seqCat { - def apply(args: Seq[Expression]): Expression = args.length match { - case 0 => error("Empty Seq passed to seqcat") - case 1 => args.head - case 2 => DoPrim(PrimOps.Cat, args, Nil, UIntType(UnknownWidth)) - case _ => - val (high, low) = args splitAt (args.length / 2) - DoPrim(PrimOps.Cat, Seq(seqCat(high), seqCat(low)), Nil, UIntType(UnknownWidth)) - } -} - -/** 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) - case t => error("Invalid operand expression for toBits!") - } - 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)))) - case t: BundleType => seqCat(t.fields map (f => - hiercat(WSubField(e, f.name, f.tpe, UNKNOWNGENDER)))) - case t: GroundType => e - case t => error("Unknown type encountered in toBits!") - } -} - -/** 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(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(mask: Expression, dataType: Type): Expression = - (mask.tpe, dataType) match { - case (mt: VectorType, dt: VectorType) => - seqCat((0 until mt.size).reverse map { i => - 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(mask, mf.name, mf.tpe, UNKNOWNGENDER), df.tpe) - }) - 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!") - } -} - -object getWidth { - def apply(t: Type): Width = t match { - case t: GroundType => t.width - case _ => error("No width!") - } - def apply(e: Expression): Width = apply(e.tpe) -} - -object bitWidth { - def apply(dt: Type): BigInt = widthOf(dt) - private def widthOf(dt: Type): BigInt = dt match { - case t: VectorType => t.size * bitWidth(t.tpe) - case t: BundleType => t.fields.map(f => bitWidth(f.tpe)).foldLeft(BigInt(0))(_+_) - case GroundType(IntWidth(width)) => width - case t => error("Unknown type encountered in bitWidth!") - } -} - -object fromBits { - def apply(lhs: Expression, rhs: Expression): Statement = { - val fbits = lhs match { - case ex @ (_: WRef | _: WSubField | _: WSubIndex) => getPart(ex, ex.tpe, rhs, 0) - case _ => error("Invalid LHS expression for fromBits!") - } - Block(fbits._2) - } - private def getPartGround(lhs: Expression, - lhst: Type, - rhs: Expression, - offset: BigInt): (BigInt, Seq[Statement]) = { - val intWidth = bitWidth(lhst) - val sel = DoPrim(PrimOps.Bits, Seq(rhs), Seq(offset + intWidth - 1, offset), UnknownType) - (offset + intWidth, Seq(Connect(NoInfo, lhs, sel))) - } - private def getPart(lhs: Expression, - lhst: Type, - rhs: Expression, - offset: BigInt): (BigInt, Seq[Statement]) = - lhst match { - case t: VectorType => (0 until t.size foldRight (offset, Seq[Statement]())) { - case (i, (curOffset, stmts)) => - val subidx = WSubIndex(lhs, i, t.tpe, UNKNOWNGENDER) - val (tmpOffset, substmts) = getPart(subidx, t.tpe, rhs, curOffset) - (tmpOffset, stmts ++ substmts) - } - case t: BundleType => (t.fields foldRight (offset, Seq[Statement]())) { - case (f, (curOffset, stmts)) => - val subfield = WSubField(lhs, f.name, f.tpe, UNKNOWNGENDER) - val (tmpOffset, substmts) = getPart(subfield, f.tpe, rhs, curOffset) - (tmpOffset, stmts ++ substmts) - } - case t: GroundType => getPartGround(lhs, t, rhs, offset) - case t => error("Unknown type encountered in fromBits!") - } -} - -object createMask { - def apply(dt: Type): Type = dt match { - case t: VectorType => VectorType(apply(t.tpe), t.size) - case t: BundleType => BundleType(t.fields map (f => f copy (tpe=apply(f.tpe)))) - case t: GroundType => BoolType - } -} - -object createRef { - def apply(n: String, t: Type = UnknownType, k: Kind = ExpKind) = WRef(n, t, k, UNKNOWNGENDER) -} - -object createSubField { - def apply(exp: Expression, n: String) = WSubField(exp, n, field_type(exp.tpe, n), UNKNOWNGENDER) -} - -object connectFields { - def apply(lref: Expression, lname: String, rref: Expression, rname: String): Connect = - Connect(NoInfo, createSubField(lref, lname), createSubField(rref, rname)) -} - -object flattenType { - def apply(t: Type) = UIntType(IntWidth(bitWidth(t))) -} - -object MemPortUtils { - type MemPortMap = collection.mutable.HashMap[String, Expression] - type Memories = collection.mutable.ArrayBuffer[DefMemory] - type Modules = collection.mutable.ArrayBuffer[DefModule] - - 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): Type = { - val rType = BundleType(defaultPortSeq(mem) :+ - Field("data", Flip, mem.dataType)) - val wType = BundleType(defaultPortSeq(mem) ++ Seq( - Field("data", Default, mem.dataType), - Field("mask", Default, createMask(mem.dataType)))) - val rwType = BundleType(defaultPortSeq(mem) ++ Seq( - Field("rdata", Flip, mem.dataType), - Field("wmode", Default, BoolType), - Field("wdata", Default, mem.dataType), - Field("wmask", Default, createMask(mem.dataType)))) - BundleType( - (mem.readers map (Field(_, Flip, rType))) ++ - (mem.writers map (Field(_, Flip, wType))) ++ - (mem.readwriters map (Field(_, Flip, rwType)))) - } - - 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) - WSubField(WSubField(mem, p, t1, UNKNOWNGENDER), f, t2, UNKNOWNGENDER) - } -} |
