summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authormergify[bot]2021-11-21 05:45:01 +0000
committerGitHub2021-11-21 05:45:01 +0000
commit7adc8063570994dc87a9bfe151b6800d45e26bbc (patch)
treea69854ddb53c1b6540d78e3eb2b50d589168ccfe /src/main
parentaadd08e1e88947b615749be139ce36f4fbbbedf0 (diff)
parent0a8bc71dde53f45672eb249454262a6a31c27e93 (diff)
Merge branch 'master' into update/sbt-mdoc-2.2.24
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/chisel3/aop/Select.scala178
-rw-r--r--src/main/scala/chisel3/aop/injecting/InjectingAspect.scala2
-rw-r--r--src/main/scala/chisel3/compatibility.scala1
-rw-r--r--src/main/scala/chisel3/util/Arbiter.scala13
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala95
-rw-r--r--src/main/scala/chisel3/util/Valid.scala18
-rw-r--r--src/main/scala/chisel3/util/random/PRNG.scala13
7 files changed, 264 insertions, 56 deletions
diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala
index 9c7320ce..8f5a2577 100644
--- a/src/main/scala/chisel3/aop/Select.scala
+++ b/src/main/scala/chisel3/aop/Select.scala
@@ -6,10 +6,12 @@ import chisel3._
import chisel3.internal.{HasId}
import chisel3.experimental.BaseModule
import chisel3.experimental.FixedPoint
-import chisel3.internal.firrtl._
+import chisel3.internal.firrtl.{Definition => DefinitionIR, _}
+import chisel3.experimental.hierarchy._
import chisel3.internal.PseudoModule
import chisel3.internal.BaseModule.ModuleClone
import firrtl.annotations.ReferenceTarget
+import scala.reflect.runtime.universe.TypeTag
import scala.collection.mutable
import chisel3.internal.naming.chiselName
@@ -22,7 +24,6 @@ object Select {
/** Return just leaf components of expanded node
*
* @param d Component to find leafs if aggregate typed. Intermediate fields/indicies are not included
- * @return
*/
def getLeafs(d: Data): Seq[Data] = d match {
case r: Record => r.getElements.flatMap(getLeafs)
@@ -33,7 +34,6 @@ object Select {
/** Return all expanded components, including intermediate aggregate nodes
*
* @param d Component to find leafs if aggregate typed. Intermediate fields/indicies ARE included
- * @return
*/
def getIntermediateAndLeafs(d: Data): Seq[Data] = d match {
case r: Record => r +: r.getElements.flatMap(getIntermediateAndLeafs)
@@ -41,15 +41,156 @@ object Select {
case other => Seq(other)
}
+ /** Selects all instances/modules directly instantiated within given definition
+ *
+ * @param parent
+ */
+ def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = {
+ check(parent)
+ implicit val mg = new chisel3.internal.MacroGenerated{}
+ parent.proto._component.get match {
+ case d: DefModule => d.commands.collect {
+ case d: DefInstance =>
+ d.id match {
+ case p: chisel3.internal.BaseModule.IsClone[_] =>
+ parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
+ case other: BaseModule =>
+ parent._lookup { x => other }
+ }
+ }
+ case other => Nil
+ }
+ }
+
+ /** Selects all Instances of instances/modules directly instantiated within given module, of provided type
+ *
+ * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+ * @param parent hierarchy which instantiates the returned Definitions
+ */
+ def instancesOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = {
+ check(parent)
+ implicit val mg = new chisel3.internal.MacroGenerated{}
+ parent.proto._component.get match {
+ case d: DefModule => d.commands.flatMap {
+ case d: DefInstance =>
+ d.id match {
+ case p: chisel3.internal.BaseModule.IsClone[_] =>
+ val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] }
+ if(i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
+ case other: BaseModule =>
+ val i = parent._lookup { x => other }
+ if(i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None
+ }
+ case other => None
+ }
+ case other => Nil
+ }
+ }
+
+ /** Selects all Instances directly and indirectly instantiated within given root hierarchy, of provided type
+ *
+ * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+ * @param root top of the hierarchy to search for instances/modules of given type
+ */
+ def allInstancesOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = {
+ val soFar = if(root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil
+ val allLocalInstances = instancesIn(root)
+ soFar ++ (allLocalInstances.flatMap(allInstancesOf[T]))
+ }
+
+ /** Selects the Definitions of all instances/modules directly instantiated within given module
+ *
+ * @param parent
+ */
+ def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = {
+ type DefType = Definition[BaseModule]
+ implicit val mg = new chisel3.internal.MacroGenerated{}
+ check(parent)
+ val defs = parent.proto._component.get match {
+ case d: DefModule => d.commands.collect {
+ case i: DefInstance =>
+ i.id match {
+ case p: chisel3.internal.BaseModule.IsClone[_] =>
+ parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] }
+ case other: BaseModule =>
+ parent._lookup { x => other.toDefinition }
+ }
+ }
+ case other => Nil
+ }
+ val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { case ((set, list), definition: Definition[BaseModule]) =>
+ if(set.contains(definition)) (set, list) else (set + definition, definition +: list)
+ }
+ defList.reverse
+ }
+
+
+ /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type
+ *
+ * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class.
+ * @param parent hierarchy which instantiates the returned Definitions
+ */
+ def definitionsOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = {
+ check(parent)
+ implicit val mg = new chisel3.internal.MacroGenerated{}
+ type DefType = Definition[T]
+ val defs = parent.proto._component.get match {
+ case d: DefModule => d.commands.flatMap {
+ case d: DefInstance =>
+ d.id match {
+ case p: chisel3.internal.BaseModule.IsClone[_] =>
+ val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] }
+ if(d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
+ case other: BaseModule =>
+ val d = parent._lookup { x => other.toDefinition }
+ if(d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None
+ }
+ case other => None
+ }
+ }
+ val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { case ((set, list), definition: Definition[T]) =>
+ if(set.contains(definition)) (set, list) else (set + definition, definition +: list)
+ }
+ defList.reverse
+ }
+
+ /** Selects all Definition's directly and indirectly instantiated within given root hierarchy, of provided type
+ *
+ * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class, i.e.
+ * a class defined within another class.
+ * @param root top of the hierarchy to search for definitions of given type
+ */
+ def allDefinitionsOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = {
+ type DefType = Definition[T]
+ val allDefSet = mutable.HashSet[Definition[BaseModule]]()
+ val defSet = mutable.HashSet[DefType]()
+ val defList = mutable.ArrayBuffer[DefType]()
+ def rec(hier: Definition[BaseModule]): Unit = {
+ if(hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) {
+ defSet += hier.asInstanceOf[DefType]
+ defList += hier.asInstanceOf[DefType]
+ }
+ allDefSet += hier
+ val allDefs = definitionsIn(hier)
+ allDefs.collect {
+ case d if !allDefSet.contains(d) => rec(d)
+ }
+ }
+ rec(root.toDefinition)
+ defList.toList
+ }
+
/** Collects all components selected by collector within module and all children modules it instantiates
* directly or indirectly
* Accepts a collector function, rather than a collector partial function (see [[collectDeep]])
+ *
+ * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
+ *
* @param module Module to collect components, as well as all children module it directly and indirectly instantiates
* @param collector Collector function to pick, given a module, which components to collect
* @param tag Required for generics to work, should ignore this
* @tparam T Type of the component that will be collected
- * @return
*/
def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = {
check(module)
@@ -63,11 +204,13 @@ object Select {
/** Collects all components selected by collector within module and all children modules it instantiates
* directly or indirectly
* Accepts a collector partial function, rather than a collector function (see [[getDeep]])
+ *
+ * @note This API will not work with the new experimental hierarchy package. Instead, use allInstancesOf or allDefinitionsOf.
+ *
* @param module Module to collect components, as well as all children module it directly and indirectly instantiates
* @param collector Collector partial function to pick, given a module, which components to collect
* @param tag Required for generics to work, should ignore this
* @tparam T Type of the component that will be collected
- * @return
*/
def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = {
check(module)
@@ -78,9 +221,11 @@ object Select {
myItems ++ deepChildrenItems
}
- /** Selects all instances directly instantiated within given module
+ /** Selects all modules directly instantiated within given module
+ *
+ * @note This API will not work with the new experimental hierarchy package. Instead, use instancesIn or definitionsIn.
+ *
* @param module
- * @return
*/
def instances(module: BaseModule): Seq[BaseModule] = {
check(module)
@@ -88,7 +233,7 @@ object Select {
case d: DefModule => d.commands.flatMap {
case i: DefInstance => i.id match {
case m: ModuleClone[_] if !m._madeFromDefinition => None
- case _: PseudoModule => throw new Exception("Aspect APIs are currently incompatible with Definition/Instance")
+ case _: PseudoModule => throw new Exception("instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!")
case other => Some(other)
}
case _ => None
@@ -99,7 +244,6 @@ object Select {
/** Selects all registers directly instantiated within given module
* @param module
- * @return
*/
def registers(module: BaseModule): Seq[Data] = {
check(module)
@@ -111,7 +255,6 @@ object Select {
/** Selects all ios directly contained within given module
* @param module
- * @return
*/
def ios(module: BaseModule): Seq[Data] = {
check(module)
@@ -120,7 +263,6 @@ object Select {
/** Selects all SyncReadMems directly contained within given module
* @param module
- * @return
*/
def syncReadMems(module: BaseModule): Seq[SyncReadMem[_]] = {
check(module)
@@ -131,7 +273,6 @@ object Select {
/** Selects all Mems directly contained within given module
* @param module
- * @return
*/
def mems(module: BaseModule): Seq[Mem[_]] = {
check(module)
@@ -142,7 +283,6 @@ object Select {
/** Selects all arithmetic or logical operators directly instantiated within given module
* @param module
- * @return
*/
def ops(module: BaseModule): Seq[(String, Data)] = {
check(module)
@@ -155,7 +295,6 @@ object Select {
* The kind of operators are contained in [[chisel3.internal.firrtl.PrimOp]]
* @param opKind the kind of operator, e.g. "mux", "add", or "bits"
* @param module
- * @return
*/
def ops(opKind: String)(module: BaseModule): Seq[Data] = {
check(module)
@@ -166,7 +305,6 @@ object Select {
/** Selects all wires in a module
* @param module
- * @return
*/
def wires(module: BaseModule): Seq[Data] = {
check(module)
@@ -177,7 +315,6 @@ object Select {
/** Selects all memory ports, including their direction and memory
* @param module
- * @return
*/
def memPorts(module: BaseModule): Seq[(Data, MemPortDirection, MemBase[_])] = {
check(module)
@@ -189,7 +326,6 @@ object Select {
/** Selects all memory ports of a given direction, including their memory
* @param dir The direction of memory ports to select
* @param module
- * @return
*/
def memPorts(dir: MemPortDirection)(module: BaseModule): Seq[(Data, MemBase[_])] = {
check(module)
@@ -200,7 +336,6 @@ object Select {
/** Selects all components who have been set to be invalid, even if they are later connected to
* @param module
- * @return
*/
def invalids(module: BaseModule): Seq[Data] = {
check(module)
@@ -211,7 +346,6 @@ object Select {
/** Selects all components who are attached to a given signal, within a module
* @param module
- * @return
*/
def attachedTo(module: BaseModule)(signal: Data): Set[Data] = {
check(module)
@@ -226,7 +360,6 @@ object Select {
* E.g. if signal = io.foo.bar, connectionsTo will return all connections to io, io.foo, and io.bar
* @param module
* @param signal
- * @return
*/
def connectionsTo(module: BaseModule)(signal: Data): Seq[PredicatedConnect] = {
check(module)
@@ -237,7 +370,7 @@ object Select {
var seenDef = isPort
searchWhens(module, (cmd: Command, preds) => {
cmd match {
- case cmd: Definition if cmd.id.isInstanceOf[Data] =>
+ case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] =>
val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data])
if(x.contains(signal)) prePredicates = preds
case Connect(_, loc@Node(d: Data), exp) =>
@@ -263,7 +396,6 @@ object Select {
/** Selects all stop statements, and includes the predicates surrounding the stop statement
*
* @param module
- * @return
*/
def stops(module: BaseModule): Seq[Stop] = {
val stops = mutable.ArrayBuffer[Stop]()
@@ -279,7 +411,6 @@ object Select {
/** Selects all printf statements, and includes the predicates surrounding the printf statement
*
* @param module
- * @return
*/
def printfs(module: BaseModule): Seq[Printf] = {
val printfs = mutable.ArrayBuffer[Printf]()
@@ -297,6 +428,7 @@ object Select {
require(module.isClosed, "Can't use Selector on modules that have not finished construction!")
require(module._component.isDefined, "Can't use Selector on modules that don't have components!")
}
+ private def check(hierarchy: Hierarchy[BaseModule]): Unit = check(hierarchy.proto)
// Given a loc, return all subcomponents of id that could be assigned to in connect
private def getEffected(a: Arg): Seq[Data] = a match {
diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
index 1a476f61..dc7e6487 100644
--- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
+++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala
@@ -43,7 +43,7 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule](
injection: M => Unit
) extends Aspect[T] {
final def toAnnotation(top: T): AnnotationSeq = {
- val moduleNames = Select.collectDeep(top) { case i => i.name }.toSeq
+ val moduleNames = Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map{i => i.toTarget.module }.toSeq
toAnnotation(selectRoots(top), top.name, moduleNames)
}
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala
index ffbb7e27..d1e7b4f1 100644
--- a/src/main/scala/chisel3/compatibility.scala
+++ b/src/main/scala/chisel3/compatibility.scala
@@ -637,6 +637,7 @@ package object Chisel {
final def toUInt(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions)
+ final def toBools(implicit compileOptions: CompileOptions): Seq[Bool] = a.do_asBools(DeprecatedSourceInfo, compileOptions)
}
}
diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala
index 135700fa..b68acae1 100644
--- a/src/main/scala/chisel3/util/Arbiter.scala
+++ b/src/main/scala/chisel3/util/Arbiter.scala
@@ -10,6 +10,7 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because
/** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs
* (selects) at most one.
+ * @groupdesc Signals The actual hardware fields of the Bundle
*
* @param gen data type
* @param n number of inputs
@@ -17,8 +18,20 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because
class ArbiterIO[T <: Data](private val gen: T, val n: Int) extends Bundle {
// See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs.
+/** Input data, one per potential sender
+ *
+ * @group Signals
+ */
val in = Flipped(Vec(n, Decoupled(gen)))
+/** Output data after arbitration
+ *
+ * @group Signals
+ */
val out = Decoupled(gen)
+/** One-Hot vector indicating which output was chosen
+ *
+ * @group Signals
+ */
val chosen = Output(UInt(log2Ceil(n).W))
}
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index 060a684c..4b8b3eeb 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -16,6 +16,7 @@ import chisel3.internal.naming._ // can't use chisel3_ version because of compi
* while the consumer uses the flipped interface (inputs bits).
* The actual semantics of ready/valid are enforced via the use of concrete subclasses.
* @param gen the type of data to be wrapped in Ready/Valid
+ * @groupdesc Signals The actual hardware fields of the Bundle
*/
abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle
{
@@ -26,8 +27,19 @@ abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle
case _ => gen
}
+/** Indicates that the consumer is ready to accept the data this cycle
+ * @group Signals
+ */
val ready = Input(Bool())
+
+/** Indicates that the producer has put valid data in 'bits'
+ * @group Signals
+ */
val valid = Output(Bool())
+
+/** The data to be transferred when ready and valid are asserted at the same cycle
+ * @group Signals
+ */
val bits = Output(genType)
}
@@ -121,6 +133,7 @@ object Decoupled
* Additionally, once 'valid' is raised it will never be lowered until after
* 'ready' has also been raised.
* @param gen the type of data to be wrapped in IrrevocableIO
+ * @groupdesc Signals The actual hardware fields of the Bundle
*/
class IrrevocableIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen)
@@ -161,6 +174,7 @@ object DeqIO {
* @param gen The type of data to queue
* @param entries The max number of entries in the queue.
* @param hasFlush A boolean for whether the generated Queue is flushable
+ * @groupdesc Signals The hardware fields of the Bundle
*/
class QueueIO[T <: Data](private val gen: T, val entries: Int, val hasFlush: Boolean = false) extends Bundle
{ // See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs.
@@ -169,13 +183,21 @@ class QueueIO[T <: Data](private val gen: T, val entries: Int, val hasFlush: Boo
* but internally, the queue implementation itself sits on the other side
* of the interface so uses the flipped instance.
*/
- /** I/O to enqueue data (client is producer, and Queue object is consumer), is [[Chisel.DecoupledIO]] flipped. */
+ /** I/O to enqueue data (client is producer, and Queue object is consumer), is [[Chisel.DecoupledIO]] flipped.
+ * @group Signals
+ */
val enq = Flipped(EnqIO(gen))
- /** I/O to dequeue data (client is consumer and Queue object is producer), is [[Chisel.DecoupledIO]]*/
+ /** I/O to dequeue data (client is consumer and Queue object is producer), is [[Chisel.DecoupledIO]]
+ * @group Signals
+ */
val deq = Flipped(DeqIO(gen))
- /** The current amount of data in the queue */
+ /** The current amount of data in the queue
+ * @group Signals
+ */
val count = Output(UInt(log2Ceil(entries + 1).W))
- /** When asserted, reset the enqueue and dequeue pointers, effectively flushing the queue (Optional IO for a flushable Queue)*/
+ /** When asserted, reset the enqueue and dequeue pointers, effectively flushing the queue (Optional IO for a flushable Queue)
+ * @group Signals
+ */
val flush = if (hasFlush) Some(Input(Bool())) else None
}
@@ -227,7 +249,7 @@ class Queue[T <: Data](val gen: T,
val full = ptr_match && maybe_full
val do_enq = WireDefault(io.enq.fire)
val do_deq = WireDefault(io.deq.fire)
- val flush = io.flush.getOrElse(false.B)
+ val flush = io.flush.getOrElse(false.B)
// when flush is high, empty the queue
// Semantically, any enqueues happen before the flush.
@@ -285,20 +307,26 @@ class Queue[T <: Data](val gen: T,
}
}
-/** Factory for a generic hardware queue.
- *
- * @param enq input (enqueue) interface to the queue, also determines width of queue elements
- * @param entries depth (number of elements) of the queue
- *
- * @return output (dequeue) interface from the queue
- *
- * @example {{{
- * consumer.io.in <> Queue(producer.io.out, 16)
- * }}}
- */
+/** Factory for a generic hardware queue. */
object Queue
{
- /** Create a queue and supply a DecoupledIO containing the product. */
+ /** Create a [[Queue]] and supply a [[DecoupledIO]] containing the product.
+ *
+ * @param enq input (enqueue) interface to the queue, also determines type of queue elements.
+ * @param entries depth (number of elements) of the queue
+ * @param pipe True if a single entry queue can run at full throughput (like a pipeline). The `ready` signals are
+ * combinationally coupled.
+ * @param flow True if the inputs can be consumed on the same cycle (the inputs "flow" through the queue immediately).
+ * The `valid` signals are coupled.
+ * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element.
+ * @param flush Optional [[Bool]] signal, if defined, the [[Queue.hasFlush]] will be true, and connect correspond
+ * signal to [[Queue]] instance.
+ * @return output (dequeue) interface from the queue.
+ *
+ * @example {{{
+ * consumer.io.in <> Queue(producer.io.out, 16)
+ * }}}
+ */
@chiselName
def apply[T <: Data](
enq: ReadyValidIO[T],
@@ -306,7 +334,7 @@ object Queue
pipe: Boolean = false,
flow: Boolean = false,
useSyncReadMem: Boolean = false,
- hasFlush: Boolean = false): DecoupledIO[T] = {
+ flush: Option[Bool] = None): DecoupledIO[T] = {
if (entries == 0) {
val deq = Wire(new DecoupledIO(chiselTypeOf(enq.bits)))
deq.valid := enq.valid
@@ -314,7 +342,8 @@ object Queue
enq.ready := deq.ready
deq
} else {
- val q = Module(new Queue(chiselTypeOf(enq.bits), entries, pipe, flow, useSyncReadMem, hasFlush))
+ val q = Module(new Queue(chiselTypeOf(enq.bits), entries, pipe, flow, useSyncReadMem, flush.isDefined))
+ q.io.flush.zip(flush).foreach(f => f._1 := f._2)
q.io.enq.valid := enq.valid // not using <> so that override is allowed
q.io.enq.bits := enq.bits
enq.ready := q.io.enq.ready
@@ -322,10 +351,25 @@ object Queue
}
}
- /** Create a queue and supply a IrrevocableIO containing the product.
- * Casting from Decoupled is safe here because we know the Queue has
- * Irrevocable semantics; we didn't want to change the return type of
- * apply() for backwards compatibility reasons.
+ /** Create a queue and supply a [[IrrevocableIO]] containing the product.
+ * Casting from [[DecoupledIO]] is safe here because we know the [[Queue]] has
+ * Irrevocable semantics.
+ * we didn't want to change the return type of apply() for backwards compatibility reasons.
+ *
+ * @param enq [[DecoupledIO]] signal to enqueue.
+ * @param entries The max number of entries in the queue
+ * @param pipe True if a single entry queue can run at full throughput (like a pipeline). The ''ready'' signals are
+ * combinationally coupled.
+ * @param flow True if the inputs can be consumed on the same cycle (the inputs "flow" through the queue immediately).
+ * The ''valid'' signals are coupled.
+ * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element.
+ * @param flush Optional [[Bool]] signal, if defined, the [[Queue.hasFlush]] will be true, and connect correspond
+ * signal to [[Queue]] instance.
+ * @return a [[DecoupledIO]] signal which should connect to the dequeue signal.
+ *
+ * @example {{{
+ * consumer.io.in <> Queue(producer.io.out, 16)
+ * }}}
*/
@chiselName
def irrevocable[T <: Data](
@@ -333,8 +377,9 @@ object Queue
entries: Int = 2,
pipe: Boolean = false,
flow: Boolean = false,
- useSyncReadMem: Boolean = false): IrrevocableIO[T] = {
- val deq = apply(enq, entries, pipe, flow, useSyncReadMem)
+ useSyncReadMem: Boolean = false,
+ flush: Option[Bool] = None): IrrevocableIO[T] = {
+ val deq = apply(enq, entries, pipe, flow, useSyncReadMem, flush)
require(entries > 0, "Zero-entry queues don't guarantee Irrevocability")
val irr = Wire(new IrrevocableIO(chiselTypeOf(deq.bits)))
irr.bits := deq.bits
diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala
index 4d348014..5d80502a 100644
--- a/src/main/scala/chisel3/util/Valid.scala
+++ b/src/main/scala/chisel3/util/Valid.scala
@@ -17,12 +17,17 @@ import chisel3._
* @tparam T the type of the data
* @param gen some data
* @see [[Valid$ Valid factory]] for concrete examples
+ * @groupdesc Signals The actual hardware fields of the Bundle
*/
class Valid[+T <: Data](gen: T) extends Bundle {
- /** A bit that will be asserted when `bits` is valid */
+ /** A bit that will be asserted when `bits` is valid
+ * @group Signals
+ */
val valid = Output(Bool())
- /** Some data */
+ /** The data to be transferred, qualified by `valid`
+ * @group Signals
+ */
val bits = Output(gen)
/** True when `valid` is asserted
@@ -173,13 +178,18 @@ class Pipe[T <: Data](val gen: T, val latency: Int = 1)(implicit compileOptions:
/** Interface for [[Pipe]]s composed of a [[Valid]] input and [[Valid]] output
* @define notAQueue
+ * @groupdesc Signals Hardware fields of the Bundle
*/
class PipeIO extends Bundle {
- /** [[Valid]] input */
+ /** [[Valid]] input
+ * @group Signals
+ */
val enq = Input(Valid(gen))
- /** [[Valid]] output. Data will appear here `latency` cycles after being valid at `enq`. */
+ /** [[Valid]] output. Data will appear here `latency` cycles after being valid at `enq`.
+ * @group Signals
+ */
val deq = Output(Valid(gen))
}
diff --git a/src/main/scala/chisel3/util/random/PRNG.scala b/src/main/scala/chisel3/util/random/PRNG.scala
index 9b42acf1..3a44385a 100644
--- a/src/main/scala/chisel3/util/random/PRNG.scala
+++ b/src/main/scala/chisel3/util/random/PRNG.scala
@@ -7,16 +7,23 @@ import chisel3.util.Valid
/** Pseudo Random Number Generators (PRNG) interface
* @param n the width of the LFSR
+ * @groupdesc Signals The actual hardware fields of the Bundle
*/
class PRNGIO(val n: Int) extends Bundle {
- /** A [[chisel3.util.Valid Valid]] interface that can be used to set the seed (internal PRNG state) */
+ /** A [[chisel3.util.Valid Valid]] interface that can be used to set the seed (internal PRNG state)
+ * @group Signals
+ */
val seed: Valid[Vec[Bool]] = Input(Valid(Vec(n, Bool())))
- /** When asserted, the PRNG will increment by one */
+ /** When asserted, the PRNG will increment by one
+ * @group Signals
+ */
val increment: Bool = Input(Bool())
- /** The current state of the PRNG */
+ /** The current state of the PRNG
+ * @group Signals
+ */
val out: Vec[Bool] = Output(Vec(n, Bool()))
}