summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/scala/chisel3/Aggregate.scala2
-rw-r--r--core/src/main/scala/chisel3/Data.scala19
-rw-r--r--core/src/main/scala/chisel3/Module.scala14
-rw-r--r--core/src/main/scala/chisel3/internal/Error.scala8
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/IR.scala2
-rw-r--r--core/src/main/scala/chisel3/internal/package.scala2
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala47
-rw-r--r--src/main/scala/chisel3/util/TransitName.scala76
-rw-r--r--src/main/scala/chisel3/util/Valid.scala54
-rw-r--r--src/main/scala/chisel3/util/experimental/BoringUtils.scala2
10 files changed, 92 insertions, 134 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala
index 2c4f67db..b0be3c24 100644
--- a/core/src/main/scala/chisel3/Aggregate.scala
+++ b/core/src/main/scala/chisel3/Aggregate.scala
@@ -966,7 +966,7 @@ abstract class Record extends Aggregate {
case _ => false
}
- private[chisel3] override def _onModuleClose: Unit = {
+ private[chisel3] def _onModuleClose: Unit = {
// This is usually done during binding, but these must still be set for unbound Records
if (this.binding.isEmpty) {
setElementRefs()
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index 0b05eb69..0beaa3ef 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -824,6 +824,25 @@ abstract class Data extends HasId with NamedComponent {
/** Default pretty printing */
def toPrintable: Printable
+
+ implicit class AsReadOnly[T <: Data](self: T) {
+
+ /** Returns a read-only view of this Data
+ *
+ * It is illegal to connect to the return value of this method.
+ * This Data this method is called on must be a hardware type.
+ */
+ def readOnly: T = {
+ val alreadyReadOnly = self.isLit || self.topBindingOpt.exists(_.isInstanceOf[ReadOnlyBinding])
+ if (alreadyReadOnly) {
+ self
+ } else {
+ self
+ // todo fix when adding dataview
+ // self.viewAsReadOnly(_ => "Cannot connect to read-only value")
+ }
+ }
+ }
}
object Data {
diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala
index 212215ab..4db632bf 100644
--- a/core/src/main/scala/chisel3/Module.scala
+++ b/core/src/main/scala/chisel3/Module.scala
@@ -31,16 +31,16 @@ object Module {
if (Builder.currentModule.isDefined && module._component.isDefined) {
// Class only uses the Definition API, and is not allowed here.
module match {
- case _: Class[_] => throwException("Module() cannot be called on a Class. Please use Definition().")
+ // case _: Class[_] => throwException("Module() cannot be called on a Class. Please use Definition().")
case _ => ()
}
val component = module._component.get
component match {
- case DefClass(_, name, _, _) =>
- Builder.referenceUserContainer match {
- case rm: RawModule => rm.addCommand(DefObject(module, name))
- }
+ // case DefClass(_, name, _, _) =>
+ // Builder.referenceUserContainer match {
+ // case rm: RawModule => rm.addCommand(DefObject(module, name))
+ // }
case _ => pushCommand(DefInstance(module, component.ports))
}
module.initializeInParent()
@@ -169,8 +169,8 @@ abstract class Module extends RawModule {
final val clock: Clock = IO(Input(Clock())).suggestName("clock")
final val reset: Reset = IO(Input(mkReset)).suggestName("reset")
- override protected def implicitClock: Clock = clock
- override protected def implicitReset: Reset = reset
+ protected def implicitClock: Clock = clock
+ protected def implicitReset: Reset = reset
// TODO Delete these
private var _override_clock: Option[Clock] = None
diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala
index 730c9510..69042c3f 100644
--- a/core/src/main/scala/chisel3/internal/Error.scala
+++ b/core/src/main/scala/chisel3/internal/Error.scala
@@ -3,8 +3,10 @@
package chisel3.internal
import scala.annotation.tailrec
-import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
-import scala.util.control.NoStackTrace
+import scala.collection.mutable.{ArrayBuffer, LinkedHashMap, LinkedHashSet}
+import scala.util.Try
+import scala.util.control.{NoStackTrace, NonFatal}
+import scala.util.matching.Regex
import _root_.logger.Logger
object ExceptionHelpers {
@@ -191,7 +193,7 @@ private[chisel3] class ErrorLog(warningsAsErrors: Boolean) {
}
private def warn(m: => String, loc: Option[StackTraceElement]): LogEntry =
- if (warningsAsErrors) new Error(m, loc) else new Warning(m, loc)
+ if (warningsAsErrors) new Error(m, loc) else new Info(m, None)
/** Log a warning message */
def warning(m: => String): Unit = {
diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
index 9fee727c..81a35ddc 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -342,7 +342,7 @@ case class Circuit(
) = Circuit(name, components, annotations, renames, newAnnotations)
}
-case class DefClass(id: Class[_], name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
+// case class DefClass(id: Class[?], name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
object Circuit
extends scala.runtime.AbstractFunction4[String, Seq[Component], Seq[ChiselAnnotation], RenameMap, Circuit] {
def unapply(c: Circuit): Option[(String, Seq[Component], Seq[ChiselAnnotation], RenameMap)] = {
diff --git a/core/src/main/scala/chisel3/internal/package.scala b/core/src/main/scala/chisel3/internal/package.scala
index 25d9129f..2e1448a5 100644
--- a/core/src/main/scala/chisel3/internal/package.scala
+++ b/core/src/main/scala/chisel3/internal/package.scala
@@ -69,7 +69,7 @@ package object internal {
private[chisel3] def _padHandleBool[A <: Bits](
x: A,
width: Int
- )(using Quotes): A = x match {
+ )(using Quotes, quoted.Type[A]): A = x match {
case b: Bool if !b.isLit && width > 1 && Type.of[A] == Type.of[UInt] =>
val _pad = Wire(UInt(width.W))
_pad := b
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index a0d86a75..e6225fc3 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -7,8 +7,7 @@ package chisel3.util
import chisel3._
import chisel3.experimental.{requireIsChiselType, DataMirror, Direction}
-
-import scala.annotation.nowarn
+import chisel3.util.simpleClassName
/** An I/O Bundle containing 'valid' and 'ready' signals that handshake
* the transfer of data stored in the 'bits' subfield.
@@ -20,10 +19,6 @@ import scala.annotation.nowarn
* @groupdesc Signals The actual hardware fields of the Bundle
*/
abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle {
- // Compatibility hack for rocket-chip
- private val genType = (DataMirror.internal.isSynthesizable(gen), chisel3.internal.Builder.currentModule) match {
- case _ => gen
- }
/** Indicates that the consumer is ready to accept the data this cycle
* @group Signals
@@ -38,7 +33,13 @@ abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle {
/** The data to be transferred when ready and valid are asserted at the same cycle
* @group Signals
*/
- val bits = Output(genType)
+ val bits = Output(gen)
+
+ /** A stable typeName for this `ReadyValidIO` and any of its implementations
+ * using the supplied `Data` generator's `typeName`
+ */
+ // todo scala3 fix
+ // override def typeName = s"${simpleClassName(this.getClass)}_${gen.typeName}"
}
object ReadyValidIO {
@@ -49,12 +50,6 @@ object ReadyValidIO {
*/
def fire: Bool = target.ready && target.valid
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- def fire(dummy: Int = 0): Bool = fire
-
/** Push dat onto the output bits of this interface to let the consumer know it has happened.
* @param dat the values to assign to bits.
* @return dat.
@@ -208,12 +203,12 @@ class QueueIO[T <: Data](
* 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 [[chisel3.util.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 [[chisel3.util.DecoupledIO]]
* @group Signals
*/
val deq = Flipped(DeqIO(gen))
@@ -251,17 +246,14 @@ class Queue[T <: Data](
val pipe: Boolean = false,
val flow: Boolean = false,
val useSyncReadMem: Boolean = false,
- val hasFlush: Boolean = false
-) extends Module() {
+ val hasFlush: Boolean = false)
+ extends Module() {
require(entries > -1, "Queue must have non-negative number of entries")
require(entries != 0, "Use companion object Queue.apply for zero entries")
- val genType = {
- requireIsChiselType(gen)
- gen
- }
+ requireIsChiselType(gen)
- val io = IO(new QueueIO(genType, entries, hasFlush))
- val ram = if (useSyncReadMem) SyncReadMem(entries, genType, SyncReadMem.WriteFirst) else Mem(entries, genType)
+ val io = IO(new QueueIO(gen, entries, hasFlush))
+ val ram = if (useSyncReadMem) SyncReadMem(entries, gen, SyncReadMem.WriteFirst) else Mem(entries, gen)
val enq_ptr = Counter(entries)
val deq_ptr = Counter(entries)
val maybe_full = RegInit(false.B)
@@ -325,6 +317,12 @@ class Queue[T <: Data](
Mux(deq_ptr.value > enq_ptr.value, entries.asUInt + ptr_diff, ptr_diff)
)
}
+
+ /** Give this Queue a default, stable desired name using the supplied `Data`
+ * generator's `typeName`
+ */
+ // todo scala3 fix
+ // override def desiredName = s"Queue${entries}_${gen.typeName}"
}
/** Factory for a generic hardware queue. */
@@ -347,7 +345,6 @@ object Queue {
* consumer.io.in <> Queue(producer.io.out, 16)
* }}}
*/
- @nowarn("cat=deprecation&msg=TransitName")
def apply[T <: Data](
enq: ReadyValidIO[T],
entries: Int = 2,
@@ -368,7 +365,7 @@ object Queue {
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
- TransitName(q.io.deq, q)
+ q.io.deq
}
}
diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala
deleted file mode 100644
index 8b509db5..00000000
--- a/src/main/scala/chisel3/util/TransitName.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chisel3.util
-
-import chisel3.internal.HasId
-
-/** The purpose of `TransitName` is to improve the naming of some object created in a different scope by "transiting"
- * the name from the outer scope to the inner scope.
- *
- * Consider the example below. This shows three ways of instantiating `MyModule` and returning the IO. Normally, the
- * instance will be named `MyModule`. However, it would be better if the instance was named using the name of the `val`
- * that user provides for the returned IO. `TransitName` can then be used to "transit" the name ''from'' the IO ''to''
- * the module:
- *
- * {{{
- * /* Assign the IO of a new MyModule instance to value "foo". The instance will be named "MyModule". */
- * val foo = Module(new MyModule).io
- *
- * /* Assign the IO of a new MyModule instance to value "bar". The instance will be named "bar". */
- * val bar = {
- * val x = Module(new MyModule)
- * TransitName(x.io, x) // TransitName returns the first argument
- * }
- *
- * /* Assign the IO of a new MyModule instance to value "baz". The instance will be named "baz_generated". */
- * val baz = {
- * val x = Module(new MyModule)
- * TransitName.withSuffix("_generated")(x.io, x) // TransitName returns the first argument
- * }
- * }}}
- *
- * `TransitName` helps library writers following the [[https://en.wikipedia.org/wiki/Factory_method_pattern Factory
- * Method Pattern]] where modules may be instantiated inside an enclosing scope. For an example of this, see how the
- * [[Queue$ Queue]] factory uses `TransitName` in
- * [[https://github.com/freechipsproject/chisel3/blob/master/src/main/scala/chisel3/util/Decoupled.scala
- * Decoupled.scala]] factory.
- */
-object TransitName {
-
- /** Transit a name from one type to another
- * @param from the thing with a "good" name
- * @param to the thing that will receive the "good" name
- * @return the `from` parameter
- */
- @deprecated(
- "Use suggestName or rely on the naming plugin instead of this function: \n" +
- " val from = {to}\n" +
- " val from = prefix(prefixYouWant){to}",
- "Chisel 3.5.4"
- )
- def apply[T <: HasId](from: T, to: HasId): T = {
- // To transit a name, we need to hook on both the suggestName and autoSeed mechanisms
- from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name) })
- from.addAutoPostnameHook((given_name: String) => { to.autoSeed(given_name) })
- from
- }
-
- /** Transit a name from one type to another ''and add a suffix''
- * @param suffix the suffix to append
- * @param from the thing with a "good" name
- * @param to the thing that will receive the "good" name
- * @return the `from` parameter
- */
- @deprecated(
- "Use suggestName or rely on the naming plugin instead of this function. Use prefix instead of suffix: \n" +
- " val from = prefix(prefixYouWant){to}",
- "Chisel 3.5.4"
- )
- def withSuffix[T <: HasId](suffix: String)(from: T, to: HasId): T = {
- // To transit a name, we need to hook on both the suggestName and autoSeed mechanisms
- from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name + suffix) })
- from.addAutoPostnameHook((given_name: String) => { to.autoSeed(given_name + suffix) })
- from
- }
-
-}
diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala
index 71e6e050..85948f37 100644
--- a/src/main/scala/chisel3/util/Valid.scala
+++ b/src/main/scala/chisel3/util/Valid.scala
@@ -6,8 +6,8 @@
package chisel3.util
import chisel3._
-
-import scala.annotation.nowarn
+import chisel3.experimental.prefix
+import chisel3.util.simpleClassName
/** A [[Bundle]] that adds a `valid` bit to some data. This indicates that the user expects a "valid" interface between
* a producer and a consumer. Here, the producer asserts the `valid` bit when data on the `bits` line contains valid
@@ -38,11 +38,23 @@ class Valid[+T <: Data](gen: T) extends Bundle {
*/
def fire: Bool = valid
- @deprecated(
- "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead",
- "Chisel 3.5"
- )
- def fire(dummy: Int = 0): Bool = valid
+ /** A non-ambiguous name of this `Valid` instance for use in generated Verilog names
+ * Inserts the parameterized generator's typeName, e.g. Valid_UInt4
+ */
+ // todo scala3 fix
+ // override def typeName = s"${simpleClassName(this.getClass)}_${gen.typeName}"
+
+ /** Applies the supplied functor to the bits of this interface, returning a new typed Valid interface.
+ * @param f The function to apply to this Valid's 'bits' with return type B
+ * @return a new Valid of type B
+ */
+ def map[B <: Data](f: T => B): Valid[B] = {
+ val _map_bits = f(bits)
+ val _map = Wire(Valid(chiselTypeOf(_map_bits)))
+ _map.bits := _map_bits
+ _map.valid := valid
+ _map.readOnly
+ }
}
/** Factory for generating "valid" interfaces. A "valid" interface is a data-communicating interface between a producer
@@ -56,8 +68,7 @@ class Valid[+T <: Data](gen: T) extends Bundle {
* }
* }}}
*
- * To convert this to a "valid" interface, you wrap it with a call to the [[Valid$.apply `Valid` companion object's
- * apply method]]:
+ * To convert this to a `valid` interface, you wrap it with a call to the `Valid` companion object's apply method:
* {{{
* val bar = Valid(new MyBundle)
* }}}
@@ -70,7 +81,8 @@ class Valid[+T <: Data](gen: T) extends Bundle {
* }
* }}}
*
- * In addition to adding the `valid` bit, a [[Valid.fire]] method is also added that returns the `valid` bit. This
+ * In addition to adding the `valid` bit, a `Valid.fire` method is also added that returns the `valid` bit. This
+ *
* provides a similarly named interface to [[DecoupledIO]]'s fire.
*
* @see [[Decoupled$ DecoupledIO Factory]]
@@ -118,7 +130,6 @@ object Pipe {
* @param latency the number of pipeline stages
* @return $returnType
*/
- @nowarn("cat=deprecation&msg=TransitName")
def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): Valid[T] = {
require(latency >= 0, "Pipe latency must be greater than or equal to zero!")
if (latency == 0) {
@@ -126,14 +137,12 @@ object Pipe {
out.valid := enqValid
out.bits := enqBits
out
- } else {
- val v = RegNext(enqValid, false.B)
- val b = RegEnable(enqBits, enqValid)
- val out = apply(v, b, latency - 1)
-
- TransitName.withSuffix("Pipe_valid")(out, v)
- TransitName.withSuffix("Pipe_bits")(out, b)
- }
+ } else
+ prefix("pipe") {
+ val v = RegNext(enqValid, false.B)
+ val b = RegEnable(enqBits, enqValid)
+ apply(v, b, latency - 1)
+ }
}
/** Generate a one-stage pipe from an explicit valid bit and some data
@@ -183,6 +192,13 @@ object Pipe {
*/
class Pipe[T <: Data](val gen: T, val latency: Int = 1) extends Module {
+ /** A non-ambiguous name of this `Pipe` for use in generated Verilog names.
+ * Includes the latency cycle count in the name as well as the parameterized
+ * generator's `typeName`, e.g. `Pipe4_UInt4`
+ */
+ // todo scala3 fix
+ // override def desiredName = s"${simpleClassName(this.getClass)}${latency}_${gen.typeName}"
+
/** Interface for [[Pipe]]s composed of a [[Valid]] input and [[Valid]] output
* @define notAQueue
* @groupdesc Signals Hardware fields of the Bundle
diff --git a/src/main/scala/chisel3/util/experimental/BoringUtils.scala b/src/main/scala/chisel3/util/experimental/BoringUtils.scala
index 254f83a4..0bbe000d 100644
--- a/src/main/scala/chisel3/util/experimental/BoringUtils.scala
+++ b/src/main/scala/chisel3/util/experimental/BoringUtils.scala
@@ -4,7 +4,7 @@ package chisel3.util.experimental
import chisel3._
import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform}
-import chisel3.internal.{InstanceId, NamedComponent, Namespace}
+import chisel3.internal.{NamedComponent, Namespace}
import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation}
import firrtl.passes.wiring.{SinkAnnotation, SourceAnnotation, WiringTransform}
import firrtl.annotations.{ComponentName, ModuleName}