1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
// See LICENSE for license details.
package chisel3.util
import chisel3._
import chisel3.core.{Data, requireIsChiselType, requireIsHardware}
import chisel3.internal.naming.chiselName
import scala.collection.immutable.ListMap
object MixedVecInit {
/**
* Construct a new wire with the given bound values.
* This is analogous to [[chisel3.core.VecInit]].
* @param vals Values to create a MixedVec with and assign
* @return MixedVec with given values assigned
*/
def apply[T <: Data](vals: Seq[T]): MixedVec[T] = {
// Create a wire of this type.
val hetVecWire = Wire(MixedVec(vals.map(_.cloneTypeFull)))
// Assign the given vals to this new wire.
for ((a, b) <- hetVecWire.zip(vals)) {
a := b
}
hetVecWire
}
/**
* Construct a new wire with the given bound values.
* This is analogous to [[chisel3.core.VecInit]].
* @return MixedVec with given values assigned
*/
def apply[T <: Data](val0: T, vals: T*): MixedVec[T] = apply(val0 +: vals.toSeq)
}
object MixedVec {
/**
* Create a MixedVec from that holds the given types.
* @param eltsIn Element types. Must be Chisel types.
* @return MixedVec with the given types.
*/
def apply[T <: Data](eltsIn: Seq[T]): MixedVec[T] = new MixedVec(eltsIn)
/**
* Create a MixedVec from that holds the given types.
* The types passed to this constructor must be Chisel types.
* @return MixedVec with the given types.
*/
def apply[T <: Data](val0: T, vals: T*): MixedVec[T] = new MixedVec(val0 +: vals.toSeq)
/**
* Create a new MixedVec from an unbound MixedVec type.
* @return MixedVec with the given types.
*/
def apply[T <: Data](mixedVec: MixedVec[T]): MixedVec[T] = new MixedVec(mixedVec.elts)
/**
* Create a MixedVec from the type of the given Vec.
* For example, given a Vec(2, UInt(8.W)), this creates MixedVec(Seq.fill(2){UInt(8.W)}).
* @param vec Vec to use as template
* @return MixedVec analogous to the given Vec.
*/
def apply[T <: Data](vec: Vec[T]): MixedVec[T] = {
MixedVec(Seq.fill(vec.length)(vec.sample_element))
}
}
/**
* A hardware array of elements that can hold values of different types/widths,
* unlike Vec which can only hold elements of the same type/width.
*
* @param eltsIn Element types. Must be Chisel types.
*
* @example {{{
* val v = Wire(MixedVec(Seq(UInt(8.W), UInt(16.W), UInt(32.W))))
* v(0) := 100.U(8.W)
* v(1) := 10000.U(16.W)
* v(2) := 101.U(32.W)
* }}}
*/
@chiselName
final class MixedVec[T <: Data](private val eltsIn: Seq[T]) extends Record with collection.IndexedSeq[T] {
// We want to create MixedVec only with Chisel types.
if (compileOptions.declaredTypeMustBeUnbound) {
eltsIn.foreach(e => requireIsChiselType(e))
}
// Clone the inputs so that we have our own references.
private val elts: IndexedSeq[T] = eltsIn.map(_.cloneTypeFull).toIndexedSeq
/**
* Statically (elaboration-time) retrieve the element at the given index.
* @param index Index with which to retrieve.
* @return Retrieved index.
*/
def apply(index: Int): T = elts(index)
/** Strong bulk connect, assigning elements in this MixedVec from elements in a Seq.
*
* @note the lengths of this and that must match
*/
def :=(that: Seq[T]): Unit = {
require(this.length == that.length)
for ((a, b) <- this zip that)
a := b
}
/**
* Get the length of this MixedVec.
* @return Number of elements in this MixedVec.
*/
def length: Int = elts.length
override val elements = ListMap(elts.zipWithIndex.map { case (element, index) => (index.toString, element) }: _*)
// Need to re-clone again since we could have been bound since object creation.
override def cloneType: this.type = MixedVec(elts.map(_.cloneTypeFull)).asInstanceOf[this.type]
// IndexedSeq has its own hashCode/equals that we must not use
override def hashCode: Int = super[Record].hashCode
override def equals(that: Any): Boolean = super[Record].equals(that)
}
|