From cbac1d259f5f607a516967d677fdcb4087527852 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 22 Jul 2015 12:37:33 -0700 Subject: Set version to 3.0 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6ea399a5..ab40fc33 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ organization := "edu.berkeley.cs" -version := "0.1" +version := "3.0" name := "Chisel" -- cgit v1.2.3 From a21a9dffade89247a2f9b6daf80c373c18098a36 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2015 17:42:48 -0700 Subject: Fix implementation of asSInt --- src/main/scala/Core.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index bcb5a280..32f314d8 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -801,7 +801,7 @@ class UInt(dir: Direction, width: Int) extends Bits(dir, width) with Num[UInt] { } def asSInt(): SInt = { - val x = SInt(width = getWidth + 1) + val x = SInt(width = getWidth) pushCommand(DefPrim(x.defd.cid, x.toType, AsSIntOp, Array(ref), NoLits)) x } -- cgit v1.2.3 From 256266dc134e85f7bd1f1415627607c9b541b843 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2015 18:40:39 -0700 Subject: Clean up Vec; allow <> on Iterable --- src/main/scala/Core.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index 32f314d8..4e4a4671 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -476,9 +476,12 @@ abstract class Aggregate(dirArg: Direction) extends Data(dirArg) { } class Vec[T <: Data](val elts: Iterable[T], dirArg: Direction = NO_DIR) extends Aggregate(dirArg) with VecLike[T] { - val elt0 = elts.head - val self = new ArrayBuffer[T]() - self ++= elts + private val self = elts.toIndexedSeq + private val elt0 = elts.head + + def <> (that: Iterable[T]): Unit = + this <> Vec(that).asInstanceOf[Data] + override def isReg = elt0.isReg override def isFlip = { val isSubFlip = elt0.isFlip -- cgit v1.2.3 From 69e7b73274e1ad6d34fbe1c4a821273580dc4613 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2015 18:40:54 -0700 Subject: Generalize bitSet --- src/main/scala/Core.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index 4e4a4671..facb1e81 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -712,7 +712,7 @@ abstract class Bits(dirArg: Direction, width: Int) extends Element(dirArg, width def andR = (this === Bits(-1)) def xorR = bits_redop(XorReduceOp) - def bitSet(off: BigInt, dat: Bits): Bits = { + def bitSet(off: UInt, dat: Bits): Bits = { val bit = UInt(1, 1) << off this & ~bit | dat.toSInt & bit } -- cgit v1.2.3 From fbb20502008ac74828800e57760ba7edc9c21d60 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2015 18:41:09 -0700 Subject: Add more of ChiselUtil --- src/main/scala/utils.scala | 144 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/src/main/scala/utils.scala b/src/main/scala/utils.scala index a86c81e8..db87e8cc 100644 --- a/src/main/scala/utils.scala +++ b/src/main/scala/utils.scala @@ -411,3 +411,147 @@ object PriorityEncoderOH } def apply(in: Bits): UInt = encode((0 until in.getWidth).map(i => in(i))) } + +class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { + val in = Vec(Decoupled(gen), n).flip + val out = Decoupled(gen) + val chosen = UInt(OUTPUT, log2Up(n)) +} + +object ArbiterCtrl +{ + def apply(request: Seq[Bool]): Seq[Bool] = { + Bool(true) +: (1 until request.length).map(i => !request.slice(0, i).foldLeft(Bool(false))(_ || _)) + } +} + +abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends Module { + require(isPow2(count)) + def grant: Seq[Bool] + val io = new ArbiterIO(gen, n) + val locked = if(count > 1) Reg(init=Bool(false)) else Bool(false) + val lockIdx = if(count > 1) Reg(init=UInt(n-1)) else UInt(n-1) + val chosen = Wire(UInt(width = log2Up(n))) + + for ((g, i) <- grant.zipWithIndex) + io.in(i).ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready + io.out.valid := io.in(chosen).valid + io.out.bits := io.in(chosen).bits + io.chosen := chosen + + if(count > 1){ + val cnt = Reg(init=UInt(0, width = log2Up(count))) + val cnt_next = cnt + UInt(1) + when(io.out.fire()) { + when(needsLock.map(_(io.out.bits)).getOrElse(Bool(true))) { + cnt := cnt_next + when(!locked) { + locked := Bool(true) + lockIdx := Vec(io.in.map{ in => in.fire()}).indexWhere{i: Bool => i} + } + } + when(cnt_next === UInt(0)) { + locked := Bool(false) + } + } + } +} + +class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { + lazy val last_grant = Reg(init=UInt(0, log2Up(n))) + override def grant: Seq[Bool] = { + val ctrl = ArbiterCtrl((0 until n).map(i => io.in(i).valid && UInt(i) > last_grant) ++ io.in.map(_.valid)) + (0 until n).map(i => ctrl(i) && UInt(i) > last_grant || ctrl(i + n)) + } + + var choose = UInt(n-1) + for (i <- n-2 to 0 by -1) + choose = Mux(io.in(i).valid, UInt(i), choose) + for (i <- n-1 to 1 by -1) + choose = Mux(io.in(i).valid && UInt(i) > last_grant, UInt(i), choose) + chosen := Mux(locked, lockIdx, choose) + + when (io.out.fire()) { last_grant := chosen } +} + +class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { + def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) + + var choose = UInt(n-1) + for (i <- n-2 to 0 by -1) { + choose = Mux(io.in(i).valid, UInt(i), choose) + } + chosen := Mux(locked, lockIdx, choose) +} + +/** Hardware module that is used to sequence n producers into 1 consumer. + Producers are chosen in round robin order. + + Example usage: + val arb = new RRArbiter(2, UInt()) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) + +/** Hardware module that is used to sequence n producers into 1 consumer. + Priority is given to lower producer + + Example usage: + val arb = Module(new Arbiter(2, UInt())) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class Arbiter[T <: Data](gen: T, n: Int) extends LockingArbiter[T](gen, n, 1) + +/** linear feedback shift register + */ +object LFSR16 +{ + def apply(increment: Bool = Bool(true)): UInt = + { + val width = 16 + val lfsr = Reg(init=UInt(1, width)) + when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } + lfsr + } +} + +/** A hardware module that delays data coming down the pipeline + by the number of cycles set by the latency parameter. Functionality + is similar to ShiftRegister but this exposes a Pipe interface. + + Example usage: + val pipe = new Pipe(UInt()) + pipe.io.enq <> produce.io.out + consumer.io.in <> pipe.io.deq + */ +object Pipe +{ + def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): ValidIO[T] = { + if (latency == 0) { + val out = Valid(enqBits) + out.valid <> enqValid + out.bits <> enqBits + out + } else { + val v = Reg(Bool(), next=enqValid, init=Bool(false)) + val b = RegEnable(enqBits, enqValid) + apply(v, b, latency-1) + } + } + def apply[T <: Data](enqValid: Bool, enqBits: T): ValidIO[T] = apply(enqValid, enqBits, 1) + def apply[T <: Data](enq: ValidIO[T], latency: Int = 1): ValidIO[T] = apply(enq.valid, enq.bits, latency) +} + +class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module +{ + val io = new Bundle { + val enq = Valid(gen).flip + val deq = Valid(gen) + } + + io.deq <> Pipe(io.enq, latency) +} -- cgit v1.2.3 From 0b69330375e2a8d499d04b32b8c5cf4bc1e8e87b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 23 Jul 2015 13:48:25 -0700 Subject: Clean up flatten/toBits/fromBits/getWidth --- src/main/scala/Core.scala | 35 +++++++++++------------------------ src/main/scala/FP.scala | 4 ++-- src/main/scala/Tester.scala | 2 +- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index facb1e81..1e46e880 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -330,15 +330,14 @@ abstract class Data(dirArg: Direction) extends Id { def setLitValue(x: LitArg) { } def floLitValue: Float = intBitsToFloat(litValue().toInt) def dblLitValue: Double = longBitsToDouble(litValue().toLong) - def getWidth: Int + def getWidth: Int = flatten.map(_.getWidth).reduce(_ + _) def maxWidth(other: Data, amt: BigInt): Int = -1 def sumWidth(amt: BigInt): Int = -1 def sumWidth(other: Data, amt: BigInt): Int = -1 - def flatten: Array[Bits] + def flatten: IndexedSeq[Bits] def fromBits(n: Bits): this.type = { - val res = this.cloneType var i = 0 - val wire = Wire(res) + val wire = Wire(this.cloneType) for (x <- wire.flatten.reverse) { x := n(i + x.getWidth-1, i) i += x.getWidth @@ -349,11 +348,8 @@ abstract class Data(dirArg: Direction) extends Id { val elts = this.flatten.reverse Cat(elts.head, elts.tail:_*).asUInt } - def makeLit(value: BigInt, width: Int): this.type = { - val x = cloneType - x.fromBits(Bits(value, width)) - x - } + def makeLit(value: BigInt, width: Int): this.type = + this.fromBits(Bits(value, width)) def toPort: Port = Port(cid, dir, toType) def collectElts: Unit @@ -513,10 +509,8 @@ class Vec[T <: Data](val elts: Iterable[T], dirArg: Direction = NO_DIR) extends i += 1; } } - override def flatten: Array[Bits] = + override def flatten: IndexedSeq[Bits] = self.map(_.flatten).reduce(_ ++ _) - override def getWidth: Int = - flatten.map(_.getWidth).reduce(_ + _) def collectElts: Unit = { for (i <- 0 until self.size) { @@ -566,7 +560,7 @@ class BitPat(val value: String, val width: Int) extends Data(NO_DIR) { override def setDir(dir: Direction): Unit = { } override def toType: Kind = UIntType(UnknownWidth(), isFlip) override def getWidth: Int = width - override def flatten: Array[Bits] = Array[Bits](Bits(0)) + override def flatten: IndexedSeq[Bits] = throw new Exception("BitPat.flatten") override def cloneType: this.type = new BitPat(value, width).asInstanceOf[this.type] def fromInt(x: BigInt): BitPat = BitPat(x.toString(2), -1).asInstanceOf[this.type] @@ -601,7 +595,7 @@ abstract class Bits(dirArg: Direction, width: Int) extends Element(dirArg, width override def cloneType : this.type = cloneTypeWidth(width) def fromInt(x: BigInt): this.type = makeLit(x, -1) - override def flatten: Array[Bits] = Array[Bits](this) + override def flatten: IndexedSeq[Bits] = IndexedSeq(this) final def apply(x: BigInt): Bool = { val d = new Bool(dir) @@ -642,12 +636,6 @@ abstract class Bits(dirArg: Direction, width: Int) extends Element(dirArg, width def :=(other: Bits) = pushCommand(Connect(this.lref, other.ref)) - override def fromBits(n: Bits): this.type = { - val res = Wire(this.cloneType) - res := n - res.asInstanceOf[this.type] - } - protected[Chisel] def unop(op: PrimOp, width: Int): this.type = { val d = cloneTypeWidth(width) pushCommand(DefPrim(d.defd.cid, d.toType, op, Array(this.ref), NoLits)) @@ -1008,13 +996,12 @@ class Bundle(dirArg: Direction = NO_DIR) extends Aggregate(dirArg) { def toType: BundleType = BundleType(this.toPorts, isFlipVar) - override def flatten: Array[Bits] = { + override def flatten: IndexedSeq[Bits] = { collectElts - elts.map(_.flatten).reduce(_ ++ _) + elts.map(_.flatten).reduce(_ ++ _).toIndexedSeq } - override def getWidth: Int = - flatten.map(_.getWidth).reduce(_ + _) + // This needs to be overhauled, perhaps with a lazy val val elts = ArrayBuffer[Data]() def collectElts: Unit = { elts.clear() diff --git a/src/main/scala/FP.scala b/src/main/scala/FP.scala index 7f2615f3..f7bbaae5 100644 --- a/src/main/scala/FP.scala +++ b/src/main/scala/FP.scala @@ -94,7 +94,7 @@ class Flo(dir: Direction = NO_DIR, val value:Option[Float] = None) extends Eleme } def toType: Kind = FloType(isFlip) def cloneType: this.type = new Flo(dir).asInstanceOf[this.type] - def flatten: Array[Bits] = Array[Bits](toBits) + def flatten: IndexedSeq[Bits] = IndexedSeq(toBits) def fromInt(x: Int): Flo = Flo(x.toFloat).asInstanceOf[this.type] @@ -209,7 +209,7 @@ class Dbl(dir: Direction, val value: Option[Double] = None) extends Element(dir, } def toType: Kind = DblType(isFlip) def cloneType: this.type = new Dbl(dir).asInstanceOf[this.type] - def flatten: Array[Bits] = Array[Bits](toBits) + def flatten: IndexedSeq[Bits] = IndexedSeq(toBits) def fromInt(x: Int): this.type = Dbl(x.toDouble).asInstanceOf[this.type] diff --git a/src/main/scala/Tester.scala b/src/main/scala/Tester.scala index 68fad15d..bdeb0f68 100644 --- a/src/main/scala/Tester.scala +++ b/src/main/scala/Tester.scala @@ -215,7 +215,7 @@ class ManualTester[+T <: Module] longBitsToDouble(peekBits(data).toLong) } - def peek(data: Aggregate /*, off: Int = -1 */): Array[BigInt] = { + def peek(data: Aggregate /*, off: Int = -1 */): IndexedSeq[BigInt] = { data.flatten.map(peek(_)) } -- cgit v1.2.3 From f0ab7874eb88a4b807920b99f15e74ce1d4e7435 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 23 Jul 2015 14:02:58 -0700 Subject: Implement SeqMem in terms of Mem for now --- src/main/scala/Core.scala | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index 1e46e880..b9ce92d6 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -412,32 +412,30 @@ class Mem[T <: Data](val t: T, val n: Int) /* with VecLike[T] */ { // TODO: VEC def read(idx: UInt): T = apply(idx) def write(idx: UInt, data: T): Unit = apply(idx) := data + def write(idx: UInt, data: T, mask: T): Unit = { + // This is totally fucked, but there's no true write mask support yet + val mask1 = mask.toBits + write(idx, t.fromBits((read(idx).toBits & ~mask1) | (data.toBits & mask1))) + } def name = getRefForId(t.cid).name def debugName = t.mod.debugName + "." + getRefForId(t.cid).debugName } object SeqMem { - def apply[T <: Data](t: T, size: Int): SeqMem[T] = { - val mt = t.cloneType - val mem = new SeqMem(mt, size) - pushCommand(DefSeqMemory(mt.defd.cid, mt.toType, size)) - mem - } + def apply[T <: Data](t: T, size: Int): SeqMem[T] = + new SeqMem(t, size) } -class SeqMem[T <: Data](val t: T, val n: Int) /* with VecLike[T] */ { // TODO: VECLIKE - def apply(idx: UInt): T = { - val x = t.cloneType - pushCommand(DefAccessor(x.defd.cid, Alias(t.cid), NO_DIR, idx.ref)) - x - } +// For now, implement SeqMem in terms of Mem +class SeqMem[T <: Data](t: T, n: Int) { + private val mem = Mem(t, n) - def read(idx: UInt): T = apply(idx) - def write(idx: UInt, data: T): Unit = apply(idx) := data + def read(addr: UInt): T = mem.read(Reg(next = addr)) + def read(addr: UInt, enable: Bool): T = mem.read(RegEnable(addr, enable)) - def name = getRefForId(t.cid).name - def debugName = t.mod.debugName + "." + getRefForId(t.cid).debugName + def write(addr: UInt, data: T): Unit = mem.write(addr, data) + def write(addr: UInt, data: T, mask: T): Unit = mem.write(addr, data, mask) } object Vec { @@ -1126,8 +1124,6 @@ abstract class Module(private[Chisel] _reset: Bool = null) extends Id { } case mem: Mem[_] => setRefForId(mem.t.cid, name) - case mem: SeqMem[_] => - setRefForId(mem.t.cid, name) case vec: Vec[_] => setRefForId(vec.cid, name) case data: Data => -- cgit v1.2.3 From f7224a4e9c2d937028f0b0e43ef450c70e5079ae Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 23 Jul 2015 17:00:24 -0700 Subject: FillInterleaved should accept & produce UInts --- src/main/scala/utils.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/utils.scala b/src/main/scala/utils.scala index db87e8cc..8e6ce571 100644 --- a/src/main/scala/utils.scala +++ b/src/main/scala/utils.scala @@ -31,8 +31,8 @@ object isPow2 object FillInterleaved { - def apply(n: Int, in: Bits): Bits = apply(n, in.toBools) - def apply(n: Int, in: Seq[Bool]): Bits = Vec(in.map(Fill(n, _))).toBits + def apply(n: Int, in: UInt): UInt = apply(n, in.toBools) + def apply(n: Int, in: Seq[Bool]): UInt = Vec(in.map(Fill(n, _))).toBits } /** Returns the number of bits set (i.e value is 1) in the input signal. -- cgit v1.2.3 From 40679ea4ba680427959d981547c33c7f00602337 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 23 Jul 2015 17:01:24 -0700 Subject: remove collectElts This probably breaks some stuff. --- src/main/scala/Core.scala | 123 ++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 82 deletions(-) diff --git a/src/main/scala/Core.scala b/src/main/scala/Core.scala index b9ce92d6..94352327 100644 --- a/src/main/scala/Core.scala +++ b/src/main/scala/Core.scala @@ -1,15 +1,17 @@ package Chisel -import scala.collection.mutable.{ArrayBuffer, Stack, HashSet, HashMap} +import scala.collection.mutable.{ArrayBuffer, Stack, HashSet, HashMap, LinkedHashMap} import java.lang.reflect.Modifier._ import java.lang.Double.longBitsToDouble import java.lang.Float.intBitsToFloat class GenSym { - var counter = -1 - def next(name: String): String = { + private var counter = -1 + def nextInt: Int = { counter += 1 - name + "_" + counter + counter } + def next(name: String): String = + name + "_" + nextInt } object Builder { @@ -277,7 +279,9 @@ import Direction._ /// CHISEL FRONT-END abstract class Id { - protected[Chisel] val cid = genSym.next("id") + protected[Chisel] val _id = genSym.nextInt + protected[Chisel] val cid = "id_" + _id + var isDef_ = false def defd: this.type = { isDef_ = true @@ -352,7 +356,6 @@ abstract class Data(dirArg: Direction) extends Id { this.fromBits(Bits(value, width)) def toPort: Port = Port(cid, dir, toType) - def collectElts: Unit var isReg_ = false def isReg = isReg_ def params = if(Driver.parStack.isEmpty) Parameters.empty else Driver.parStack.top @@ -365,7 +368,6 @@ object Wire { throw new Exception("cannot infer type of Init.") val x = mType.cloneType // TODO: COME UP WITH MORE ROBUST WAY TO HANDLE THIS - x.collectElts pushCommand(DefWire(x.defd.cid, x.toType)) if (init != null) pushCommand(Connect(x.lref, init.ref)) @@ -403,7 +405,9 @@ object Mem { } } -class Mem[T <: Data](val t: T, val n: Int) /* with VecLike[T] */ { // TODO: VECLIKE +class Mem[T <: Data](protected[Chisel] val t: T, n: Int) extends VecLike[T] { + def length: Int = n + def apply(idx: Int): T = apply(UInt(idx)) def apply(idx: UInt): T = { val x = t.cloneType pushCommand(DefAccessor(x.defd.cid, Alias(t.cid), NO_DIR, idx.ref)) @@ -443,7 +447,6 @@ object Vec { new Vec((0 until n).map(i => gen.cloneType)) def apply[T <: Data](elts: Iterable[T]): Vec[T] = { val vec = new Vec[T](elts.map(e => elts.head.cloneType)) - vec.collectElts val isDef = true || elts.head.isDef if (vec.isReg) throw new Exception("Vec of Reg Deprecated.") @@ -469,10 +472,13 @@ abstract class Aggregate(dirArg: Direction) extends Data(dirArg) { def cloneTypeWidth(width: Int): this.type = cloneType } -class Vec[T <: Data](val elts: Iterable[T], dirArg: Direction = NO_DIR) extends Aggregate(dirArg) with VecLike[T] { +class Vec[T <: Data](elts: Iterable[T], dirArg: Direction = NO_DIR) extends Aggregate(dirArg) with VecLike[T] { private val self = elts.toIndexedSeq private val elt0 = elts.head + for ((e, i) <- self zipWithIndex) + setIndexForId(cid, e.cid, i) + def <> (that: Iterable[T]): Unit = this <> Vec(that).asInstanceOf[Data] @@ -493,11 +499,8 @@ class Vec[T <: Data](val elts: Iterable[T], dirArg: Direction = NO_DIR) extends self.map(d => d.toPort).toArray def toType: Kind = VectorType(self.size, elt0.toType, isFlipVar) - override def cloneType: this.type = { - val v = Vec(elt0.cloneType, self.size).asInstanceOf[this.type] - v.collectElts - v - } + override def cloneType: this.type = + Vec(elt0.cloneType, self.size).asInstanceOf[this.type] def inits (f: (Int, T, (Int, T, T) => Unit) => Unit) = { var i = 0 def doInit (index: Int, elt: T, init: T) = @@ -510,14 +513,6 @@ class Vec[T <: Data](val elts: Iterable[T], dirArg: Direction = NO_DIR) extends override def flatten: IndexedSeq[Bits] = self.map(_.flatten).reduce(_ ++ _) - def collectElts: Unit = { - for (i <- 0 until self.size) { - val elt = self(i) - setIndexForId(cid, elt.cid, i) - elt.collectElts - } - } - def length: Int = self.size def read(idx: UInt): T = apply(idx) @@ -553,7 +548,6 @@ import Literal._ class BitPat(val value: String, val width: Int) extends Data(NO_DIR) { def cloneTypeWidth(width: Int): this.type = cloneType - def collectElts: Unit = { } override def dir: Direction = NO_DIR override def setDir(dir: Direction): Unit = { } override def toType: Kind = UIntType(UnknownWidth(), isFlip) @@ -579,7 +573,6 @@ object BitPat { } abstract class Element(dirArg: Direction, val width: Int) extends Data(dirArg) { - def collectElts: Unit = { } override def getWidth: Int = width } @@ -859,6 +852,7 @@ class SInt(dir: Direction, width: Int) extends Bits(dir, width) with Num[SInt] { def != (other: SInt): Bool = compop(NotEqualOp, other) def <= (other: SInt): Bool = compop(LessEqOp, other) def >= (other: SInt): Bool = compop(GreaterEqOp, other) + def abs: UInt = Mux(this < SInt(0), (-this).toUInt, this.toUInt) override def pad (other: BigInt): SInt = binop(PadOp, other, other.toInt) @@ -919,31 +913,12 @@ object Bool { object Mux { def apply[T <: Data](cond: Bool, con: T, alt: T): T = { - def genericMux[T <: Data](cond: Bool, con: T, alt: T): T = { - val w = Wire(alt, init = alt) - when (cond) { - w := con - } - w - } - con match { - case tc: Bits => - alt match { - case ta: Bits => - if (tc.isInstanceOf[UInt] != ta.isInstanceOf[UInt]) - error("Unable to have mixed type mux CON " + con + " ALT " + alt) - // println("MUX COND " + cond + " CON(" + con.litValue() + ")'" + con.getWidth + " " + con + " ALT(" + alt.litValue() + ")'" + alt.getWidth + " " + alt) - val rb = tc.cloneTypeWidth(tc.maxWidth(ta, 0)) - pushCommand(DefPrim(rb.defd.cid, rb.toType, MultiplexOp, Array(cond.ref, tc.ref, ta.ref), NoLits)) - rb.asInstanceOf[T] - case _ => - genericMux(cond, con, alt) - } - case _ => - genericMux(cond, con, alt) + val w = Wire(alt, init = alt) + when (cond) { + w := con } + w } - } object Cat { @@ -990,61 +965,46 @@ object Bundle { class Bundle(dirArg: Direction = NO_DIR) extends Aggregate(dirArg) { def toPorts: Array[Port] = - elts.map(d => d.toPort).toArray + elements.map(_._2.toPort).toArray def toType: BundleType = BundleType(this.toPorts, isFlipVar) override def flatten: IndexedSeq[Bits] = { - collectElts - elts.map(_.flatten).reduce(_ ++ _).toIndexedSeq + val sortedElts = elements.values.toIndexedSeq sortWith (_._id < _._id) + sortedElts.map(_.flatten).reduce(_ ++ _) } - // This needs to be overhauled, perhaps with a lazy val - val elts = ArrayBuffer[Data]() - def collectElts: Unit = { - elts.clear() + lazy val elements: LinkedHashMap[String, Data] = { + def isInterface(cls: Class[_], supcls: Class[_]): Boolean = { + if (cls == supcls) true + else if (cls == null || cls == Class.forName("java.lang.Object")) false + else isInterface(cls.getSuperclass, supcls) + } + + val elts = LinkedHashMap[String, Data]() for (m <- getClass.getDeclaredMethods) { val name = m.getName - - val modifiers = m.getModifiers(); - val types = m.getParameterTypes() - var isInterface = false; - var isFound = false; - val rtype = m.getReturnType(); - var c = rtype; - val sc = Class.forName("Chisel.Data"); - do { - if (c == sc) { - isFound = true; isInterface = true; - } else if (c == null || c == Class.forName("java.lang.Object")) { - isFound = true; isInterface = false; - } else { - c = c.getSuperclass(); - } - } while (!isFound); - if (types.length == 0 && !isStatic(modifiers) && isInterface - && !(Bundle.keywords contains name)) { + if (m.getParameterTypes.isEmpty && + !isStatic(m.getModifiers) && + isInterface(m.getReturnType, Class.forName("Chisel.Data")) && + !(Bundle.keywords contains name)) { val obj = m.invoke(this) obj match { case data: Data => setFieldForId(cid, data.cid, name) - data.collectElts - elts += data + elts(name) = data case _ => () } } } - - elts.sortWith { (a, b) => a.cid < b.cid } + elts } override def cloneType : this.type = { try { val constructor = this.getClass.getConstructors.head val res = constructor.newInstance(Array.fill(constructor.getParameterTypes.size)(null):_*) - val rest = res.asInstanceOf[this.type] - rest.collectElts - rest + res.asInstanceOf[this.type] } catch { case npe: java.lang.reflect.InvocationTargetException if npe.getCause.isInstanceOf[java.lang.NullPointerException] => // throwException("Parameterized Bundle " + this.getClass + " needs cloneType method. You are probably using an anonymous Bundle object that captures external state and hence is un-cloneTypeable", npe) @@ -1064,7 +1024,6 @@ object Module { val cmd = popCommands popScope popModule - m.io.collectElts m.setRefs val ports = m.io.toPorts val component = UniqueComponent(m.name, ports, cmd) -- cgit v1.2.3