summaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/chisel3/compatibility.scala71
-rw-r--r--src/main/scala/chisel3/internal/firrtl/Emitter.scala49
-rw-r--r--src/main/scala/chisel3/package.scala30
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala5
4 files changed, 114 insertions, 41 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
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
index 16b39e35..593052c7 100644
--- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala
+++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
@@ -2,6 +2,7 @@
package chisel3.internal.firrtl
import chisel3._
+import chisel3.core.UserDirection
import chisel3.experimental._
import chisel3.internal.sourceinfo.{NoSourceInfo, SourceLine}
@@ -12,16 +13,50 @@ private[chisel3] object Emitter {
private class Emitter(circuit: Circuit) {
override def toString: String = res.toString
- private def emitPort(e: Port): String =
- s"${e.dir} ${e.id.getRef.name} : ${e.id.toType}"
+ private def emitPort(e: Port): String = {
+ val dir = e.dir match {
+ case UserDirection.Unspecified | UserDirection.Output => "output"
+ case UserDirection.Flip | UserDirection.Input => "input"
+ }
+ s"$dir ${e.id.getRef.name} : ${emitType(e.id)}"
+ }
+
+ private def emitType(d: Data, clearDir: Boolean = false): String = d match {
+ case d: Clock => "Clock"
+ case d: UInt => s"UInt${d.width}"
+ case d: SInt => s"SInt${d.width}"
+ case d: FixedPoint => s"Fixed${d.width}${d.binaryPoint}"
+ case d: Analog => s"Analog${d.width}"
+ case d: Vec[_] => s"${emitType(d.sample_element, clearDir)}[${d.length}]"
+ case d: Record => {
+ val childClearDir = clearDir ||
+ d.userDirection == UserDirection.Input || d.userDirection == UserDirection.Output
+ def eltPort(elt: Data): String = (childClearDir, firrtlUserDirOf(elt)) match {
+ case (true, _) =>
+ s"${elt.getRef.name} : ${emitType(elt, true)}"
+ case (false, UserDirection.Unspecified | UserDirection.Output) =>
+ s"${elt.getRef.name} : ${emitType(elt, false)}"
+ case (false, UserDirection.Flip | UserDirection.Input) =>
+ s"flip ${elt.getRef.name} : ${emitType(elt, false)}"
+ }
+ d.elements.toIndexedSeq.reverse.map(e => eltPort(e._2)).mkString("{", ", ", "}")
+ }
+ }
+
+ private def firrtlUserDirOf(d: Data): UserDirection = d match {
+ case d: Vec[_] =>
+ UserDirection.fromParent(d.userDirection, firrtlUserDirOf(d.sample_element))
+ case d => d.userDirection
+ }
+
private def emit(e: Command, ctx: Component): String = {
val firrtlLine = e match {
case e: DefPrim[_] => s"node ${e.name} = ${e.op.name}(${e.args.map(_.fullName(ctx)).mkString(", ")})"
- case e: DefWire => s"wire ${e.name} : ${e.id.toType}"
- case e: DefReg => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)}"
- case e: DefRegInit => s"reg ${e.name} : ${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
- case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]"
- case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]"
+ case e: DefWire => s"wire ${e.name} : ${emitType(e.id)}"
+ case e: DefReg => s"reg ${e.name} : ${emitType(e.id)}, ${e.clock.fullName(ctx)}"
+ case e: DefRegInit => s"reg ${e.name} : ${emitType(e.id)}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))"
+ case e: DefMemory => s"cmem ${e.name} : ${emitType(e.t)}[${e.size}]"
+ case e: DefSeqMemory => s"smem ${e.name} : ${emitType(e.t)}[${e.size}]"
case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}"
case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}"
case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}"
diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala
index 1899b2ec..d2f11f3d 100644
--- a/src/main/scala/chisel3/package.scala
+++ b/src/main/scala/chisel3/package.scala
@@ -11,11 +11,9 @@ package object chisel3 { // scalastyle:ignore package.object.name
import util.BitPat
- import chisel3.core.{Binding, FlippedBinder}
import chisel3.util._
import chisel3.internal.firrtl.Port
- type Direction = chisel3.core.Direction
val Input = chisel3.core.Input
val Output = chisel3.core.Output
val Flipped = chisel3.core.Flipped
@@ -25,6 +23,15 @@ package object chisel3 { // scalastyle:ignore package.object.name
val Clock = chisel3.core.Clock
type Clock = chisel3.core.Clock
+ implicit class AddDirectionToData[T<:Data](val target: T) extends AnyVal {
+ @deprecated("Input(Data) should be used over Data.asInput", "chisel3")
+ def asInput: T = Input(target)
+ @deprecated("Output(Data) should be used over Data.asOutput", "chisel3")
+ def asOutput: T = Output(target)
+ @deprecated("Flipped(Data) should be used over Data.flip", "chisel3")
+ def flip(): T = Flipped(target)
+ }
+
implicit class fromBitsable[T <: Data](val data: T) {
import chisel3.core.CompileOptions
import chisel3.internal.sourceinfo.SourceInfo
@@ -34,7 +41,7 @@ package object chisel3 { // scalastyle:ignore package.object.name
that.asTypeOf(data)
}
}
-
+
type Aggregate = chisel3.core.Aggregate
val Vec = chisel3.core.Vec
type Vec[T <: Data] = chisel3.core.Vec[T]
@@ -83,10 +90,6 @@ package object chisel3 { // scalastyle:ignore package.object.name
@deprecated("use value.U(width.W)", "chisel3, will be removed by end of 2016")
def apply(value: BigInt, width: Int): UInt = value.asUInt(width.W)
- /** Create a UInt with a specified width - compatibility with Chisel2. */
- @deprecated("use UInt(width.W)", "chisel3, will be removed by end of 2016")
- def apply(dir: Option[Direction] = None, width: Int): UInt = apply(width.W)
-
/** Create a UInt literal with inferred width.- compatibility with Chisel2. */
@deprecated("use value.U", "chisel3, will be removed by end of 2016")
def apply(value: BigInt): UInt = value.asUInt
@@ -188,7 +191,6 @@ package object chisel3 { // 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
@@ -284,10 +286,7 @@ package object chisel3 { // scalastyle:ignore package.object.name
def do_=/= (that: BitPat)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that =/= x // scalastyle:ignore method.name
}
- // Compatibility with existing code.
- val INPUT = chisel3.core.Direction.Input
- val OUTPUT = chisel3.core.Direction.Output
- val NODIR = chisel3.core.Direction.Unspecified
+
type ChiselException = chisel3.internal.ChiselException
// Debugger/Tester access to internal Chisel data structures and methods.
@@ -295,7 +294,6 @@ package object chisel3 { // scalastyle:ignore package.object.name
a.allElements
}
def getModulePorts(m: Module): Seq[Port] = m.getPorts
- def getFirrtlDirection(d: Data): Direction = chisel3.core.Data.getFirrtlDirection(d)
/** Package for experimental features, which may have their API changed, be removed, etc.
*
@@ -342,6 +340,12 @@ package object chisel3 { // scalastyle:ignore package.object.name
type ChiselAnnotation = chisel3.core.ChiselAnnotation
val ChiselAnnotation = chisel3.core.ChiselAnnotation
+ val DataMirror = chisel3.core.DataMirror
+ val requireIsHardware = chisel3.core.requireIsHardware
+ val requireIsChiselType = chisel3.core.requireIsChiselType
+ type Direction = chisel3.core.ActualDirection
+ val Direction = chisel3.core.ActualDirection
+
implicit class ChiselRange(val sc: StringContext) extends AnyVal {
import scala.language.experimental.macros
import internal.firrtl.NumericBound
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index 5de24728..b9e1e7ed 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -6,6 +6,7 @@
package chisel3.util
import chisel3._
+import chisel3.experimental.{DataMirror, Direction}
import chisel3.internal.naming._ // can't use chisel3_ version because of compile order
/** An I/O Bundle containing 'valid' and 'ready' signals that handshake
@@ -88,7 +89,7 @@ object Decoupled
*/
@chiselName
def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = {
- require(irr.bits.flatten forall (_.dir == OUTPUT), "Only safe to cast produced Irrevocable bits to Decoupled.")
+ require(DataMirror.directionOf(irr.bits) == Direction.Output, "Only safe to cast produced Irrevocable bits to Decoupled.")
val d = Wire(new DecoupledIO(irr.bits))
d.bits := irr.bits
d.valid := irr.valid
@@ -122,7 +123,7 @@ object Irrevocable
* @note unsafe (and will error) on the consumer (output) side of an DecoupledIO
*/
def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = {
- require(dec.bits.flatten forall (_.dir == INPUT), "Only safe to cast consumed Decoupled bits to Irrevocable.")
+ require(DataMirror.directionOf(dec.bits) == Direction.Input, "Only safe to cast consumed Decoupled bits to Irrevocable.")
val i = Wire(new IrrevocableIO(dec.bits))
dec.bits := i.bits
dec.valid := i.valid