Skip to content

Commit dd2fe0b

Browse files
committed
Add Scala3 sources
1 parent 876f5f6 commit dd2fe0b

33 files changed

+2368
-0
lines changed
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package chisel3
4+
5+
import chisel3.experimental.VecLiterals.AddVecLiteralConstructor
6+
7+
import scala.collection.immutable.{SeqMap, VectorMap}
8+
import scala.collection.mutable.{HashSet, LinkedHashMap}
9+
import chisel3.experimental.{BaseModule, BundleLiteralException, OpaqueType, SourceInfo, VecLiteralException}
10+
import chisel3.internal._
11+
import chisel3.internal.Builder.pushCommand
12+
import chisel3.internal.firrtl._
13+
14+
import java.lang.Math.{floor, log10, pow}
15+
import scala.collection.mutable
16+
17+
/** An abstract class for data types that solely consist of (are an aggregate
18+
* of) other Data objects.
19+
*/
20+
sealed trait Aggregate extends AggregateImpl
21+
22+
/** A vector (array) of [[Data]] elements. Provides hardware versions of various
23+
* collection transformation functions found in software array implementations.
24+
*
25+
* Careful consideration should be given over the use of [[Vec]] vs
26+
* [[scala.collection.immutable.Seq Seq]] or some other Scala collection. In general [[Vec]] only
27+
* needs to be used when there is a need to express the hardware collection in a [[Reg]] or IO
28+
* [[Bundle]] or when access to elements of the array is indexed via a hardware signal.
29+
*
30+
* Example of indexing into a [[Vec]] using a hardware address and where the [[Vec]] is defined in
31+
* an IO [[Bundle]]
32+
*
33+
* {{{
34+
* val io = IO(new Bundle {
35+
* val in = Input(Vec(20, UInt(16.W)))
36+
* val addr = Input(UInt(5.W))
37+
* val out = Output(UInt(16.W))
38+
* })
39+
* io.out := io.in(io.addr)
40+
* }}}
41+
*
42+
* @tparam T type of elements
43+
*
44+
* @note
45+
* - when multiple conflicting assignments are performed on a Vec element, the last one takes effect (unlike Mem, where the result is undefined)
46+
* - Vecs, unlike classes in Scala's collection library, are propagated intact to FIRRTL as a vector type, which may make debugging easier
47+
*/
48+
sealed class Vec[T <: Data] private[chisel3] (gen: => T, length: Int)
49+
extends VecImpl[T](gen, length)
50+
with VecLike[T]
51+
with Aggregate {
52+
53+
override def toString: String = super[VecImpl].toString
54+
55+
def apply(p: UInt)(implicit sourceInfo: SourceInfo): T = do_apply(p)
56+
def do_apply(p: UInt)(implicit sourceInfo: SourceInfo): T = _applyImpl(p)
57+
58+
/** A reduce operation in a tree like structure instead of sequentially
59+
* @example An adder tree
60+
* {{{
61+
* val sumOut = inputNums.reduceTree((a: T, b: T) => (a + b))
62+
* }}}
63+
*/
64+
// def reduceTree(redOp: (T, T) => T): T = macro VecTransform.reduceTreeDefault
65+
66+
/** A reduce operation in a tree like structure instead of sequentially
67+
* @example A pipelined adder tree
68+
* {{{
69+
* val sumOut = inputNums.reduceTree(
70+
* (a: T, b: T) => RegNext(a + b),
71+
* (a: T) => RegNext(a)
72+
* )
73+
* }}}
74+
*/
75+
def reduceTree(
76+
redOp: (T, T) => T,
77+
layerOp: (T) => T = (x: T) => x
78+
)(
79+
implicit sourceInfo: SourceInfo
80+
): T = _reduceTreeImpl(redOp, layerOp)
81+
}
82+
83+
object Vec extends VecFactory
84+
85+
object VecInit extends VecInitImpl with SourceInfoDoc {
86+
87+
/** Creates a new [[Vec]] composed of elements of the input Seq of [[Data]]
88+
* nodes.
89+
*
90+
* @note input elements should be of the same type (this is checked at the
91+
* FIRRTL level, but not at the Scala / Chisel level)
92+
* @note the width of all output elements is the width of the largest input
93+
* element
94+
* @note output elements are connected from the input elements
95+
*/
96+
def apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elts)
97+
98+
/** Creates a new [[Vec]] composed of the input [[Data]] nodes.
99+
*
100+
* @note input elements should be of the same type (this is checked at the
101+
* FIRRTL level, but not at the Scala / Chisel level)
102+
* @note the width of all output elements is the width of the largest input
103+
* element
104+
* @note output elements are connected from the input elements
105+
*/
106+
def apply[T <: Data](elt0: T, elts: T*)(implicit sourceInfo: SourceInfo): Vec[T] = _applyImpl(elt0, elts: _*)
107+
108+
/** Creates a new [[Vec]] of length `n` composed of the results of the given
109+
* function applied over a range of integer values starting from 0.
110+
*
111+
* @param n number of elements in the vector (the function is applied from
112+
* 0 to `n-1`)
113+
* @param gen function that takes in an Int (the index) and returns a
114+
* [[Data]] that becomes the output element
115+
*/
116+
def tabulate[T <: Data](
117+
n: Int
118+
)(gen: (Int) => T
119+
)(
120+
implicit sourceInfo: SourceInfo
121+
): Vec[T] = _tabulateImpl(n)(gen)
122+
123+
/** Creates a new 2D [[Vec]] of length `n by m` composed of the results of the given
124+
* function applied over a range of integer values starting from 0.
125+
*
126+
* @param n number of 1D vectors inside outer vector
127+
* @param m number of elements in each 1D vector (the function is applied from
128+
* 0 to `n-1`)
129+
* @param gen function that takes in an Int (the index) and returns a
130+
* [[Data]] that becomes the output element
131+
*/
132+
def tabulate[T <: Data](
133+
n: Int,
134+
m: Int
135+
)(gen: (Int, Int) => T
136+
)(
137+
implicit sourceInfo: SourceInfo
138+
): Vec[Vec[T]] = _tabulateImpl(n, m)(gen)
139+
140+
/** Creates a new 3D [[Vec]] of length `n by m by p` composed of the results of the given
141+
* function applied over a range of integer values starting from 0.
142+
*
143+
* @param n number of 2D vectors inside outer vector
144+
* @param m number of 1D vectors in each 2D vector
145+
* @param p number of elements in each 1D vector
146+
* @param gen function that takes in an Int (the index) and returns a
147+
* [[Data]] that becomes the output element
148+
*/
149+
def tabulate[T <: Data](
150+
n: Int,
151+
m: Int,
152+
p: Int
153+
)(gen: (Int, Int, Int) => T
154+
)(
155+
implicit sourceInfo: SourceInfo
156+
): Vec[Vec[Vec[T]]] = _tabulateImpl(n, m, p)(gen)
157+
158+
/** Creates a new [[Vec]] of length `n` composed of the result of the given
159+
* function applied to an element of data type T.
160+
*
161+
* @param n number of elements in the vector
162+
* @param gen function that takes in an element T and returns an output
163+
* element of the same type
164+
*/
165+
def fill[T <: Data](n: Int)(gen: => T)(implicit sourceInfo: SourceInfo): Vec[T] = _fillImpl(n)(gen)
166+
167+
/** Creates a new 2D [[Vec]] of length `n by m` composed of the result of the given
168+
* function applied to an element of data type T.
169+
*
170+
* @param n number of inner vectors (rows) in the outer vector
171+
* @param m number of elements in each inner vector (column)
172+
* @param gen function that takes in an element T and returns an output
173+
* element of the same type
174+
*/
175+
def fill[T <: Data](
176+
n: Int,
177+
m: Int
178+
)(gen: => T
179+
)(
180+
implicit sourceInfo: SourceInfo
181+
): Vec[Vec[T]] = _fillImpl(n, m)(gen)
182+
183+
/** Creates a new 3D [[Vec]] of length `n by m by p` composed of the result of the given
184+
* function applied to an element of data type T.
185+
*
186+
* @param n number of 2D vectors inside outer vector
187+
* @param m number of 1D vectors in each 2D vector
188+
* @param p number of elements in each 1D vector
189+
* @param gen function that takes in an element T and returns an output
190+
* element of the same type
191+
*/
192+
def fill[T <: Data](
193+
n: Int,
194+
m: Int,
195+
p: Int
196+
)(gen: => T
197+
)(
198+
implicit sourceInfo: SourceInfo
199+
): Vec[Vec[Vec[T]]] = _fillImpl(n, m, p)(gen)
200+
201+
/** Creates a new [[Vec]] of length `n` composed of the result of the given
202+
* function applied to an element of data type T.
203+
*
204+
* @param start First element in the Vec
205+
* @param len Lenth of elements in the Vec
206+
* @param f Function that applies the element T from previous index and returns the output
207+
* element to the next index
208+
*/
209+
def iterate[T <: Data](
210+
start: T,
211+
len: Int
212+
)(f: (T) => T
213+
)(
214+
implicit sourceInfo: SourceInfo
215+
): Vec[T] = _iterateImpl(start, len)(f)
216+
}
217+
218+
/** A trait for [[Vec]]s containing common hardware generators for collection
219+
* operations.
220+
*/
221+
trait VecLike[T <: Data] extends VecLikeImpl[T] with SourceInfoDoc {
222+
223+
/** Creates a dynamically indexed read or write accessor into the array.
224+
*/
225+
def apply(p: UInt)(implicit sourceInfo: SourceInfo): T
226+
227+
/** Outputs true if p outputs true for every element.
228+
*/
229+
def forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _forallImpl(p)
230+
231+
/** Outputs true if p outputs true for at least one element.
232+
*/
233+
def exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool = _existsImpl(p)
234+
235+
/** Outputs true if the vector contains at least one element equal to x (using
236+
* the === operator).
237+
*/
238+
def contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool = _containsImpl(x)
239+
240+
/** Outputs the number of elements for which p is true.
241+
*/
242+
def count(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _countImpl(p)
243+
244+
/** Outputs the index of the first element for which p outputs true.
245+
*/
246+
def indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _indexWhereImpl(p)
247+
248+
/** Outputs the index of the last element for which p outputs true.
249+
*/
250+
def lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _lastIndexWhereImpl(p)
251+
252+
/** Outputs the index of the element for which p outputs true, assuming that
253+
* the there is exactly one such element.
254+
*
255+
* The implementation may be more efficient than a priority mux, but
256+
* incorrect results are possible if there is not exactly one true element.
257+
*
258+
* @note the assumption that there is only one element for which p outputs
259+
* true is NOT checked (useful in cases where the condition doesn't always
260+
* hold, but the results are not used in those cases)
261+
*/
262+
def onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt = _onlyIndexWhereImpl(p)
263+
}
264+
265+
/** Base class for Aggregates based on key values pairs of String and Data
266+
*
267+
* Record should only be extended by libraries and fairly sophisticated generators.
268+
* RTL writers should use [[Bundle]]. See [[Record#elements]] for an example.
269+
*/
270+
abstract class Record extends Aggregate with RecordImpl

0 commit comments

Comments
 (0)