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
124
125
126
127
128
129
130
131
132
133
|
// SPDX-License-Identifier: Apache-2.0
package chisel3.util
import chisel3._
import chisel3.internal.requireIsChiselType
import scala.collection.immutable.ListMap
/**
* Create a MixedVec wire with default values as specified, and type of each element inferred from
* those default values.
*
* This is analogous to [[VecInit]].
* @return MixedVec with given values assigned
*
* @example {{{
* MixedVecInit(Seq(100.U(8.W), 10000.U(16.W), 101.U(32.W)))
* }}}
*/
object MixedVecInit {
/**
* Create a MixedVec wire from a Seq of values.
*/
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
}
/**
* Create a MixedVec wire from a varargs list of values.
*/
def apply[T <: Data](val0: T, vals: T*): MixedVec[T] = apply(val0 +: vals.toSeq)
}
/**
* Create a MixedVec type, given element types. Inputs must be Chisel types which have no value
* (not hardware types).
*
* @return MixedVec with the given types.
*/
object MixedVec {
/**
* Create a MixedVec type from a Seq of Chisel types.
*/
def apply[T <: Data](eltsIn: Seq[T]): MixedVec[T] = new MixedVec(eltsIn)
/**
* Create a MixedVec type from a varargs list of Chisel types.
*/
def apply[T <: Data](val0: T, vals: T*): MixedVec[T] = new MixedVec(val0 +: vals.toSeq)
/**
* Create a new MixedVec type from an unbound MixedVec type.
*/
def apply[T <: Data](mixedVec: MixedVec[T]): MixedVec[T] = new MixedVec(mixedVec.elts)
/**
* Create a MixedVec type from the type of the given Vec.
*
* @example {{{
* MixedVec(Vec(2, UInt(8.W))) = MixedVec(Seq.fill(2){UInt(8.W)})
* }}}
*/
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)
* }}}
*/
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.
eltsIn.foreach(e => requireIsChiselType(e))
// In Scala 2.13, this is protected in IndexedSeq, must override as public because it's public in
// Record
override def className: String = "MixedVec"
// 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)
}
|