diff options
| author | Richard Lin | 2017-06-26 18:35:46 -0700 |
|---|---|---|
| committer | GitHub | 2017-06-26 18:35:46 -0700 |
| commit | aaee58d374dc3f3a088856da13a6a59ecffb2cac (patch) | |
| tree | 790828de9a9fbb1dfd26635eebaf27668a4cc8df /src/main/scala/chisel3/compatibility.scala | |
| parent | 91850ec917a432e9e3db588e7711c8a82801eb49 (diff) | |
Directions internals mega-refactor (#617)
Part 1 of mega-change in #578
Major notes:
- Input(...) and Output(...) now (effectively) recursively override their elements' directions
- Nodes given userDirection (Input, Output, Flip - what the user assigned to _that_ node) and actualDirection (Input, Output, None, but also Bidirectional and BidirectionalFlip for mostly Aggregates), because of the above (since a higher-level Input(...) can override the locally specified user direction).
- DataMirror (node reflection APIs) added to chisel3.experimental. This provides ways to query the user given direction of a node as well as the actual direction.
- checkSynthesizable replaced with requireIsHardware and requireIsChiselType and made available in chisel3.experimental.
Internal changes notes:
- toType moved into Emitter, this makes the implementation cleaner especially considering that Vec types can't be flipped in FIRRTL. This also more clearly separates Chisel frontend from FIRRTL emission.
- Direction separated from Bindings, both are now fields in Data, and all nodes are given hierarchical directions (Aggregates may be Bidirectional). The actualDirection at the Element (leaf) level should be the same as binding directions previously.
- Bindings are hierarchical, children (of a, for example, Bundle) have a ChildBinding that points to their parent. This is different than the previous scheme where Bindings only applied at the Element (leaf) level.
- Lots of small misc clean up.
Future PRs will address other parts of #578, including stricter direction checks that aren't a side-effect of this internal refactor, stricter checks and splitting of binding operations (Wire vs. WireInit), and node operations not introduced here (getType and deprecation of chiselCloneType). Since those shouldn't mess with internals, those should be much smaller.
Diffstat (limited to 'src/main/scala/chisel3/compatibility.scala')
| -rw-r--r-- | src/main/scala/chisel3/compatibility.scala | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d64b3bb5..b9357bbd 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -12,21 +12,43 @@ package object Chisel { // scalastyle:ignore package.object.name import scala.annotation.compileTimeOnly implicit val defaultCompileOptions = chisel3.core.ExplicitCompileOptions.NotStrict - type Direction = chisel3.core.Direction - val INPUT = chisel3.core.Direction.Input - val OUTPUT = chisel3.core.Direction.Output - val NODIR = chisel3.core.Direction.Unspecified + abstract class Direction + case object INPUT extends Direction + case object OUTPUT extends Direction + case object NODIR extends Direction + object Flipped { def apply[T<:Data](target: T): T = chisel3.core.Flipped[T](target) } - // TODO: Possibly move the AddDirectionToData class here? + + implicit class AddDirectionToData[T<:Data](val target: T) extends AnyVal { + def asInput: T = chisel3.core.Input(target) + def asOutput: T = chisel3.core.Output(target) + def flip(): T = chisel3.core.Flipped(target) + } + implicit class AddDirMethodToData[T<:Data](val target: T) extends AnyVal { + import chisel3.core.{DataMirror, ActualDirection, UserDirection} def dir: Direction = { - target match { - case e: Element => e.dir - case _ => chisel3.core.Direction.Unspecified + DataMirror.isSynthesizable(target) match { + case true => target match { + case e: Element => DataMirror.directionOf(e) match { + case ActualDirection.Unspecified => NODIR + case ActualDirection.Output => OUTPUT + case ActualDirection.Input => INPUT + case dir => throw new RuntimeException(s"Unexpected element direction '$dir'") + } + case _ => NODIR + } + case false => DataMirror.userDirectionOf(target) match { // returns local direction only + case UserDirection.Unspecified => NODIR + case UserDirection.Input => INPUT + case UserDirection.Output => OUTPUT + case dir => throw new RuntimeException(s"Unexpected element direction '$dir'") + } } + } } @@ -34,7 +56,18 @@ package object Chisel { // scalastyle:ignore package.object.name type Data = chisel3.core.Data val Wire = chisel3.core.Wire - val Clock = chisel3.core.Clock + object Clock { + def apply(): Clock = new Clock + + def apply(dir: Direction): Clock = { + val result = apply() + dir match { + case INPUT => chisel3.core.Input(result) + case OUTPUT => chisel3.core.Output(result) + case _ => result + } + } + } type Clock = chisel3.core.Clock // Implicit conversion to allow fromBits because it's being deprecated in chisel3 @@ -94,9 +127,9 @@ package object Chisel { // scalastyle:ignore package.object.name def apply(dir: Direction, width: Width): UInt = { val result = apply(width) dir match { - case chisel3.core.Direction.Input => chisel3.core.Input(result) - case chisel3.core.Direction.Output => chisel3.core.Output(result) - case chisel3.core.Direction.Unspecified => result + case INPUT => chisel3.core.Input(result) + case OUTPUT => chisel3.core.Output(result) + case NODIR => result } } @@ -135,9 +168,9 @@ package object Chisel { // scalastyle:ignore package.object.name def apply(dir: Direction, width: Width): SInt = { val result = apply(width) dir match { - case chisel3.core.Direction.Input => chisel3.core.Input(result) - case chisel3.core.Direction.Output => chisel3.core.Output(result) - case chisel3.core.Direction.Unspecified => result + case INPUT => chisel3.core.Input(result) + case OUTPUT => chisel3.core.Output(result) + case NODIR => result } } } @@ -153,9 +186,9 @@ package object Chisel { // scalastyle:ignore package.object.name def apply(dir: Direction): Bool = { val result = apply() dir match { - case chisel3.core.Direction.Input => chisel3.core.Input(result) - case chisel3.core.Direction.Output => chisel3.core.Output(result) - case chisel3.core.Direction.Unspecified => result + case INPUT => chisel3.core.Input(result) + case OUTPUT => chisel3.core.Output(result) + case NODIR => result } } } @@ -210,6 +243,7 @@ package object Chisel { // scalastyle:ignore package.object.name } } } + val Module = chisel3.core.Module type Module = CompatibilityModule @@ -249,7 +283,6 @@ package object Chisel { // scalastyle:ignore package.object.name chisel3.core.Reg(t) } if (next ne null) { - Binding.checkSynthesizable(next, s"'next' ($next)") // TODO: move into connect? reg := next } reg |
