Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify BaseModule.IO and chisel3.experimental.IO into chisel3.IO #2863

Merged
merged 3 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions core/src/main/scala/chisel3/IO.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package chisel3

import chisel3.internal.requireIsChiselType // Fix ambiguous import
import chisel3.internal.Builder
import chisel3.internal.sourceinfo.SourceInfo

object IO {

/** Constructs a port for the current Module
*
* This must wrap the datatype used to set the io field of any Module.
* i.e. All concrete modules must have defined io in this form:
* [lazy] val io[: io type] = IO(...[: io type])
*
* Items in [] are optional.
*
* The granted iodef must be a chisel type and not be bound to hardware.
*
* Also registers a Data as a port, also performing bindings. Cannot be called once ports are
* requested (so that all calls to ports will return the same information).
* Internal API.
*/
def apply[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
val module = Module.currentModule.get // Impossible to fail
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is this impossible to fail?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It definitely isn't but note that @adkian-sifive just moved this code. It probably was impossible back when the only way to call IO was via protected def defined on Module.

require(!module.isClosed, "Can't add more ports after module close")
val prevId = Builder.idGen.value
val data = iodef // evaluate once (passed by name)
requireIsChiselType(data, "io type")

// Clone the IO so we preserve immutability of data types
// Note: we don't clone if the data is fresh (to avoid unnecessary clones)
val iodefClone =
if (!data.mustClone(prevId)) data
else
try {
data.cloneTypeFull
} catch {
// For now this is going to be just a deprecation so we don't suddenly break everyone's code
case e: AutoClonetypeException =>
Builder.deprecated(e.getMessage, Some(s"${data.getClass}"))
data
}
module.bindIoInPlace(iodefClone)
iodefClone
}
}
43 changes: 3 additions & 40 deletions core/src/main/scala/chisel3/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -200,47 +200,10 @@ abstract class Module(implicit moduleCompileOptions: CompileOptions) extends Raw
}

package experimental {

import chisel3.internal.requireIsChiselType // Fix ambiguous import

object IO {

/** Constructs a port for the current Module
*
* This must wrap the datatype used to set the io field of any Module.
* i.e. All concrete modules must have defined io in this form:
* [lazy] val io[: io type] = IO(...[: io type])
*
* Items in [] are optional.
*
* The granted iodef must be a chisel type and not be bound to hardware.
*
* Also registers a Data as a port, also performing bindings. Cannot be called once ports are
* requested (so that all calls to ports will return the same information).
* Internal API.
*/
@deprecated("chisel3.experimental.IO is deprecated, use chisel3.IO instead", "Chisel 3.5")
def apply[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
val module = Module.currentModule.get // Impossible to fail
require(!module.isClosed, "Can't add more ports after module close")
val prevId = Builder.idGen.value
val data = iodef // evaluate once (passed by name)
requireIsChiselType(data, "io type")

// Clone the IO so we preserve immutability of data types
// Note: we don't clone if the data is fresh (to avoid unnecessary clones)
val iodefClone =
if (!data.mustClone(prevId)) data
else
try {
data.cloneTypeFull
} catch {
// For now this is going to be just a deprecation so we don't suddenly break everyone's code
case e: AutoClonetypeException =>
Builder.deprecated(e.getMessage, Some(s"${data.getClass}"))
data
}
module.bindIoInPlace(iodefClone)
iodefClone
chisel3.IO.apply(iodef)
}
}
}
Expand Down Expand Up @@ -599,7 +562,7 @@ package experimental {
* are problematic.
*/
protected def IO[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
chisel3.experimental.IO.apply(iodef)
chisel3.IO.apply(iodef)
}

//
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/experimental/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ package object experimental {
val ports: Seq[Data] =
gen.elements.toSeq.reverse.map {
case (name, data) =>
val p = IO(coerceDirection(chiselTypeClone(data).asInstanceOf[Data]))
val p = chisel3.IO(coerceDirection(chiselTypeClone(data).asInstanceOf[Data]))
p.suggestName(name)
p

Expand Down