Skip to content

Commit

Permalink
MixedVec: clarify dynamic indexing of heterogeneous elements
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardcwang committed Jul 27, 2018
1 parent 360d940 commit 010a49b
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
11 changes: 7 additions & 4 deletions src/main/scala/chisel3/util/MixedVec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,21 @@ final class MixedVec[T <: Data](private val eltsIn: Seq[T]) extends Record with

/**
* Dynamically (via a mux) retrieve the element at the given index.
* This is implemented via a mux with the width of the widest element in this MixedVec.
* For example, a MixedVec of type Seq(UInt(4.W), UInt(8.W)) will create an 8-bit mux for this operation.
* Note: it is up to the user to process the resultant UInt (e.g. unflatten, etc).
*
* @param index Index with which to retrieve.
* @return Retrieved index.
* @param index Index to retrieve. If the index is out of range, it will return the first element.
* @return Retrieved index as a UInt with the width of the widest element.
*/
def apply(index: UInt): T = {
def apply(index: UInt): UInt = {
requireIsHardware(index, "index must be hardware")

if (length < 1) {
throw new IndexOutOfBoundsException("Collection is empty")
}

MuxLookup(index, elts.head, elts.zipWithIndex.map { case (el, el_index) => el_index.U -> el })
MuxLookup(index, elts.head.asUInt, elts.zipWithIndex.map { case (el, el_index) => el_index.U -> el.asUInt })
}

/** Strong bulk connect, assigning elements in this MixedVec from elements in a Seq.
Expand Down
64 changes: 61 additions & 3 deletions src/test/scala/chiselTests/MixedVecSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class MixedVecZeroEntryTester extends BasicTester {
stop()
}

class MixedVecDynamicIndexTester(n: Int) extends BasicTester {
class MixedVecUIntDynamicIndexTester(n: Int) extends BasicTester {
val wire = Wire(MixedVec(Seq.fill(n) { UInt() }))

val (cycle, done) = Counter(true.B, n)
Expand All @@ -92,6 +92,60 @@ class MixedVecDynamicIndexTester(n: Int) extends BasicTester {
when (done) { stop() }
}

class MixedVecTestBundle extends Bundle {
val x = UInt(8.W)
val y = UInt(8.W)
}

class MixedVecSmallTestBundle extends Bundle {
val x = UInt(3.W)
val y = UInt(3.W)
}

class MixedVecDynamicIndexTester extends BasicTester {
val wire = Wire(MixedVec(Seq(UInt(8.W), SInt(8.W), Bool(), new MixedVecTestBundle, new MixedVecSmallTestBundle)))

val val0 = 163.U(8.W)
val val1 = (-96).S(8.W)
val val2 = true.B
val val3 = 126.U(8.W)
val val4 = 6.U(3.W)

wire(0) := val0
wire(1) := val1
wire(2) := val2
val wire3 = wire(3).asInstanceOf[MixedVecTestBundle]
wire3.x := val3
wire3.y := val3
val wire4 = wire(4).asInstanceOf[MixedVecSmallTestBundle]
wire4.x := val4
wire4.y := val4

val (cycle, done) = Counter(true.B, wire.length)
val currentData = wire(cycle)

when(cycle === 0.U) {
assert(currentData === val0)
} .elsewhen(cycle === 1.U) {
// We need to trim the width appropriately before calling asSInt
assert(currentData(7, 0).asSInt === val1)
} .elsewhen(cycle === 2.U) {
assert(currentData === val2.asUInt)
} .elsewhen(cycle === 3.U) {
val currentBundle = currentData.asTypeOf(new MixedVecTestBundle)
assert(currentBundle.x === val3)
assert(currentBundle.y === val3)
} .otherwise {
val currentBundle = currentData.asTypeOf(new MixedVecSmallTestBundle)
assert(currentBundle.x === val4)
assert(currentBundle.y === val4)
}

when(done) {
stop()
}
}

class MixedVecFromVecTester extends BasicTester {
val wire = Wire(MixedVec(Vec(3, UInt(8.W))))
wire := MixedVecWireInit(Seq(20.U, 40.U, 80.U))
Expand Down Expand Up @@ -210,8 +264,12 @@ class MixedVecSpec extends ChiselPropSpec {
assertTesterPasses { new MixedVecZeroEntryTester }
}

property("MixedVecs should be dynamically indexable") {
assertTesterPasses{ new MixedVecDynamicIndexTester(4) }
property("MixedVecs of UInts should be dynamically indexable") {
assertTesterPasses{ new MixedVecUIntDynamicIndexTester(4) }
}

property("MixedVecs in general should be dynamically indexable") {
assertTesterPasses{ new MixedVecDynamicIndexTester }
}

property("MixedVecs should be creatable from Vecs") {
Expand Down

0 comments on commit 010a49b

Please sign in to comment.