diff options
Diffstat (limited to 'src/main/scala/chisel3')
20 files changed, 442 insertions, 252 deletions
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index a0713379..ab51ad25 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -95,7 +95,7 @@ trait BackendCompilationUtilities { /** Generates a Verilator invocation to convert Verilog sources to C++ * simulation sources. * - * The Verilator prefix will be V$dutFile, and running this will generate + * The Verilator prefix will be V\$dutFile, and running this will generate * C++ sources and headers as well as a makefile to compile them. * * @param dutFile name of the DUT .v without the .v extension @@ -119,13 +119,13 @@ trait BackendCompilationUtilities { "-Wno-WIDTH", "-Wno-STMTDLY", "--trace", - "-O0", + "-O1", "--top-module", topModule, "+define+TOP_TYPE=V" + dutFile, s"+define+PRINTF_COND=!$topModule.reset", s"+define+STOP_COND=!$topModule.reset", "-CFLAGS", - s"""-Wno-undefined-bool-conversion -O0 -DTOP_TYPE=V$dutFile -include V$dutFile.h""", + s"""-Wno-undefined-bool-conversion -O1 -DTOP_TYPE=V$dutFile -include V$dutFile.h""", "-Mdir", dir.toString, "--exe", cppHarness.toString) System.out.println(s"${command.mkString(" ")}") // scalastyle:ignore regex diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d0d2ddb4..613385af 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -4,8 +4,11 @@ // moving to the more standard package naming convention chisel3 (lowercase c). package object Chisel { // scalastyle:ignore package.object.name + import chisel3.internal.firrtl.Width + 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 @@ -38,16 +41,109 @@ package object Chisel { // scalastyle:ignore package.object.name val assert = chisel3.core.assert val stop = chisel3.core.stop + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + */ + trait UIntFactory extends chisel3.core.UIntFactory { + /** Create a UInt literal with inferred width. */ + def apply(n: String): UInt = n.asUInt + /** Create a UInt literal with fixed width. */ + def apply(n: String, width: Int): UInt = n.asUInt(width.W) + + /** Create a UInt literal with specified width. */ + def apply(value: BigInt, width: Width): UInt = value.asUInt(width) + + /** Create a UInt literal with fixed width. */ + def apply(value: BigInt, width: Int): UInt = value.asUInt(width.W) + + /** Create a UInt with a specified width - compatibility with Chisel2. */ + // NOTE: This resolves UInt(width = 32) + def apply(dir: Option[Direction] = None, width: Int): UInt = apply(width.W) + /** Create a UInt literal with inferred width.- compatibility with Chisel2. */ + def apply(value: BigInt): UInt = value.asUInt + + /** Create a UInt with a specified direction and width - compatibility with Chisel2. */ + def apply(dir: Direction, width: Int): UInt = apply(dir, width.W) + /** Create a UInt with a specified direction, but unspecified width - compatibility with Chisel2. */ + def apply(dir: Direction): UInt = apply(dir, Width()) + 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 + } + } + + /** Create a UInt with a specified width */ + def width(width: Int): UInt = apply(width.W) + + /** Create a UInt port with specified width. */ + def width(width: Width): UInt = apply(width) + } + + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + */ + trait SIntFactory extends chisel3.core.SIntFactory { + /** Create a SInt type or port with fixed width. */ + def width(width: Int): SInt = apply(width.W) + /** Create an SInt type with specified width. */ + def width(width: Width): SInt = apply(width) + + /** Create an SInt literal with inferred width. */ + def apply(value: BigInt): SInt = value.asSInt + /** Create an SInt literal with fixed width. */ + def apply(value: BigInt, width: Int): SInt = value.asSInt(width.W) + + /** Create an SInt literal with specified width. */ + def apply(value: BigInt, width: Width): SInt = value.asSInt(width) + + def Lit(value: BigInt): SInt = value.asSInt + def Lit(value: BigInt, width: Int): SInt = value.asSInt(width.W) + + /** Create a SInt with a specified width - compatibility with Chisel2. */ + def apply(dir: Option[Direction] = None, width: Int): SInt = apply(width.W) + /** Create a SInt with a specified direction and width - compatibility with Chisel2. */ + def apply(dir: Direction, width: Int): SInt = apply(dir, width.W) + /** Create a SInt with a specified direction, but unspecified width - compatibility with Chisel2. */ + def apply(dir: Direction): SInt = apply(dir, Width()) + 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 + } + } + } + + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + */ + trait BoolFactory extends chisel3.core.BoolFactory { + /** Creates Bool literal. + */ + def apply(x: Boolean): Bool = x.B + + /** Create a UInt with a specified direction and width - compatibility with Chisel2. */ + 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 + } + } + } + type Element = chisel3.core.Element type Bits = chisel3.core.Bits - val Bits = chisel3.core.Bits + object Bits extends UIntFactory type Num[T <: Data] = chisel3.core.Num[T] type UInt = chisel3.core.UInt - val UInt = chisel3.core.UInt + object UInt extends UIntFactory type SInt = chisel3.core.SInt - val SInt = chisel3.core.SInt + object SInt extends SIntFactory type Bool = chisel3.core.Bool - val Bool = chisel3.core.Bool + object Bool extends BoolFactory val Mux = chisel3.core.Mux type BlackBox = chisel3.core.BlackBox @@ -68,53 +164,45 @@ package object Chisel { // scalastyle:ignore package.object.name val when = chisel3.core.when type WhenContext = chisel3.core.WhenContext - import chisel3.internal.firrtl.Width - /** - * These implicit classes allow one to convert scala.Int|scala.BigInt to - * Chisel.UInt|Chisel.SInt by calling .asUInt|.asSInt on them, respectively. - * The versions .asUInt(width)|.asSInt(width) are also available to explicitly - * mark a width for the new literal. - * - * Also provides .asBool to scala.Boolean and .asUInt to String - * - * Note that, for stylistic reasons, one should avoid extracting immediately - * after this call using apply, ie. 0.asUInt(1)(0) due to potential for - * confusion (the 1 is a bit length and the 0 is a bit extraction position). - * Prefer storing the result and then extracting from it. - */ - implicit class fromIntToLiteral(val x: Int) extends AnyVal { - def U: UInt = UInt(BigInt(x), Width()) // scalastyle:ignore method.name - def S: SInt = SInt(BigInt(x), Width()) // scalastyle:ignore method.name - - def asUInt(): UInt = UInt(x, Width()) - def asSInt(): SInt = SInt(x, Width()) - def asUInt(width: Int): UInt = UInt(x, width) - def asSInt(width: Int): SInt = SInt(x, width) - } + implicit class fromBigIntToLiteral(val x: BigInt) extends chisel3.core.fromBigIntToLiteral(x) + implicit class fromtIntToLiteral(val x: Int) extends chisel3.core.fromIntToLiteral(x) + implicit class fromtLongToLiteral(val x: Long) extends chisel3.core.fromLongToLiteral(x) + implicit class fromStringToLiteral(val x: String) extends chisel3.core.fromStringToLiteral(x) + implicit class fromBooleanToLiteral(val x: Boolean) extends chisel3.core.fromBooleanToLiteral(x) + implicit class fromIntToWidth(val x: Int) extends chisel3.core.fromIntToWidth(x) - implicit class fromBigIntToLiteral(val x: BigInt) extends AnyVal { - def U: UInt = UInt(x, Width()) // scalastyle:ignore method.name - def S: SInt = SInt(x, Width()) // scalastyle:ignore method.name + type BackendCompilationUtilities = chisel3.BackendCompilationUtilities + val Driver = chisel3.Driver + val ImplicitConversions = chisel3.util.ImplicitConversions - def asUInt(): UInt = UInt(x, Width()) - def asSInt(): SInt = SInt(x, Width()) - def asUInt(width: Int): UInt = UInt(x, width) - def asSInt(width: Int): SInt = SInt(x, width) - } - implicit class fromStringToLiteral(val x: String) extends AnyVal { - def U: UInt = UInt(x) // scalastyle:ignore method.name - } - implicit class fromBooleanToLiteral(val x: Boolean) extends AnyVal { - def B: Bool = Bool(x) // scalastyle:ignore method.name + // Deprecated as of Chisel3 + object chiselMain { + import java.io.File + + def apply[T <: Module](args: Array[String], gen: () => T): Unit = + Predef.assert(false, "No more chiselMain in Chisel3") + + def run[T <: Module] (args: Array[String], gen: () => T): Unit = { + val circuit = Driver.elaborate(gen) + Driver.parseArgs(args) + val output_file = new File(Driver.targetDir + "/" + circuit.name + ".fir") + Driver.dumpFirrtl(circuit, Option(output_file)) + } } + @deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3") + object debug { // scalastyle:ignore object.name + def apply (arg: Data): Data = arg + } - type BackendCompilationUtilities = chisel3.BackendCompilationUtilities - val Driver = chisel3.Driver - val ImplicitConversions = chisel3.util.ImplicitConversions - val chiselMain = chisel3.compatibility.chiselMain - val throwException = chisel3.compatibility.throwException - val debug = chisel3.compatibility.debug + // Deprecated as of Chsiel3 + @throws(classOf[Exception]) + object throwException { + def apply(s: String, t: Throwable = null) = { + val xcpt = new Exception(s, t) + throw xcpt + } + } object testers { // scalastyle:ignore object.name type BasicTester = chisel3.testers.BasicTester @@ -162,7 +250,62 @@ package object Chisel { // scalastyle:ignore package.object.name type Queue[T <: Data] = chisel3.util.Queue[T] val Queue = chisel3.util.Queue - val Enum = chisel3.util.Enum + object Enum extends chisel3.util.Enum { + /** Returns n unique values of the specified type. Can be used with unpacking to define enums. + * + * nodeType must be of UInt type (note that Bits() creates a UInt) with unspecified width. + * + * @example {{{ + * val state_on :: state_off :: Nil = Enum(UInt(), 2) + * val current_state = UInt() + * switch (current_state) { + * is (state_on) { + * ... + * } + * if (state_off) { + * ... + * } + * } + * }}} + */ + def apply[T <: Bits](nodeType: T, n: Int): List[T] = { + require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") + require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") + apply(n).asInstanceOf[List[T]] + } + + /** An old Enum API that returns a map of symbols to UInts. + * + * Unlike the new list-based Enum, which can be unpacked into vals that the compiler + * understands and can check, map accesses can't be compile-time checked and typos may not be + * caught until runtime. + * + * Despite being deprecated, this is not to be removed from the compatibility layer API. + * Deprecation is only to nag users to do something safer. + */ + @deprecated("Use list-based Enum", "not soon enough") + def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = { + require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") + require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") + (l zip createValues(l.length)).toMap.asInstanceOf[Map[Symbol, T]] + } + + /** An old Enum API that returns a map of symbols to UInts. + * + * Unlike the new list-based Enum, which can be unpacked into vals that the compiler + * understands and can check, map accesses can't be compile-time checked and typos may not be + * caught until runtime. + * + * Despite being deprecated, this is not to be removed from the compatibility layer API. + * Deprecation is only to nag users to do something safer. + */ + @deprecated("Use list-based Enum", "not soon enough") + def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = { + require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") + require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") + (l zip createValues(l.length)).toMap.asInstanceOf[Map[Symbol, T]] + } + } val LFSR16 = chisel3.util.LFSR16 diff --git a/src/main/scala/chisel3/compatibility/Main.scala b/src/main/scala/chisel3/compatibility/Main.scala deleted file mode 100644 index a41599a3..00000000 --- a/src/main/scala/chisel3/compatibility/Main.scala +++ /dev/null @@ -1,19 +0,0 @@ -// See LICENSE for license details. - -package chisel3.compatibility - -import java.io.File - -import chisel3._ - -@deprecated("chiselMain doesn't exist in Chisel3", "3.0") object chiselMain { - def apply[T <: Module](args: Array[String], gen: () => T): Unit = - Predef.assert(false, "No more chiselMain in Chisel3") - - def run[T <: Module] (args: Array[String], gen: () => T): Unit = { - val circuit = Driver.elaborate(gen) - Driver.parseArgs(args) - val output_file = new File(Driver.targetDir + "/" + circuit.name + ".fir") - Driver.dumpFirrtl(circuit, Option(output_file)) - } -} diff --git a/src/main/scala/chisel3/compatibility/debug.scala b/src/main/scala/chisel3/compatibility/debug.scala deleted file mode 100644 index d9f6e4b0..00000000 --- a/src/main/scala/chisel3/compatibility/debug.scala +++ /dev/null @@ -1,10 +0,0 @@ -// See LICENSE for license details. - -package chisel3.compatibility - -import chisel3.core._ - -@deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3") -object debug { // scalastyle:ignore object.name - def apply (arg: Data): Data = arg -} diff --git a/src/main/scala/chisel3/compatibility/throwException.scala b/src/main/scala/chisel3/compatibility/throwException.scala deleted file mode 100644 index 3e8b33e6..00000000 --- a/src/main/scala/chisel3/compatibility/throwException.scala +++ /dev/null @@ -1,14 +0,0 @@ -// See LICENSE for license details. - -package chisel3.compatibility - -import chisel3._ - -@deprecated("throwException doesn't exist in Chisel3", "3.0.0") -@throws(classOf[Exception]) -object throwException { - def apply(s: String, t: Throwable = null) = { - val xcpt = new Exception(s, t) - throw xcpt - } -} diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 0793fd7d..42bc6c30 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.experimental._ import chisel3.internal.sourceinfo.{NoSourceInfo, SourceLine} private[chisel3] object Emitter { @@ -31,7 +32,7 @@ private class Emitter(circuit: Circuit) { "\"" + printf.format(fmt) + "\"") ++ args printfArgs mkString ("printf(", ", ", ")") case e: DefInvalid => s"${e.arg.fullName(ctx)} is invalid" - case e: DefInstance => s"inst ${e.name} of ${e.id.modName}" + case e: DefInstance => s"inst ${e.name} of ${e.id.name}" case w: WhenBegin => indent() s"when ${w.pred.fullName(ctx)} :" @@ -39,14 +40,18 @@ private class Emitter(circuit: Circuit) { unindent() s"skip" } - e.sourceInfo match { - case SourceLine(filename, line, col) => s"${firrtlLine} @[${filename} ${line}:${col}]" - case _: NoSourceInfo => firrtlLine - } + firrtlLine + e.sourceInfo.makeMessage(" " + _) } - // Map of Module FIRRTL definition to FIRRTL name, if it has been emitted already. - private val defnMap = collection.mutable.HashMap[(String, String), Component]() + private def emitParam(name: String, p: Param): String = { + val str = p match { + case IntParam(value) => value.toString + case DoubleParam(value) => value.toString + case StringParam(str) => "\"" + str + "\"" + case RawParam(str) => "'" + str + "'" + } + s"parameter $name = $str" + } /** Generates the FIRRTL module declaration. */ @@ -64,12 +69,13 @@ private class Emitter(circuit: Circuit) { body ++= newline + emitPort(p) body ++= newline - m.id match { - case _: BlackBox => - // TODO: BlackBoxes should be empty, but funkiness in Module() means - // it's not for now. Eventually, this should assert out. - case _: Module => for (cmd <- m.commands) { - body ++= newline + emit(cmd, m) + m match { + case bb: DefBlackBox => + // Firrtl extmodule can overrule name + body ++= newline + s"defname = ${bb.id.desiredName}" + body ++= newline + (bb.params map { case (n, p) => emitParam(n, p) } mkString newline) + case mod: DefModule => for (cmd <- mod.commands) { + body ++= newline + emit(cmd, mod) } } body ++= newline @@ -83,17 +89,10 @@ private class Emitter(circuit: Circuit) { */ private def emit(m: Component): String = { // Generate the body. - val defn = moduleDefn(m) - - defnMap get (m.id.desiredName, defn) match { - case Some(duplicate) => - m.id setModName duplicate.name - "" - case None => - defnMap((m.id.desiredName, defn)) = m - m.id setModName m.name - moduleDecl(m) + defn - } + val sb = new StringBuilder + sb.append(moduleDecl(m)) + sb.append(moduleDefn(m)) + sb.result } private var indentLevel = 0 diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index e0364868..e4e64b89 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -1,10 +1,10 @@ // See LICENSE for license details. package object chisel3 { // scalastyle:ignore package.object.name - import scala.language.experimental.macros + import scala.language.implicitConversions import internal.firrtl.Width - import internal.sourceinfo.{SourceInfo, SourceInfoTransform} + import util.BitPat import chisel3.core.{Binding, FlippedBinder} @@ -31,16 +31,109 @@ package object chisel3 { // scalastyle:ignore package.object.name type Element = chisel3.core.Element type Bits = chisel3.core.Bits - val Bits = chisel3.core.Bits + + // Some possible regex replacements for the literal specifier deprecation: + // (note: these are not guaranteed to handle all edge cases! check all replacements!) + // Bool\((true|false)\) + // => $1.B + // UInt\(width\s*=\s*(\d+|[_a-zA-Z][_0-9a-zA-Z]*)\) + // => UInt($1.W) + // (UInt|SInt|Bits).width\((\d+|[_a-zA-Z][_0-9a-zA-Z]*)\) + // => $1($2.W) + // (U|S)Int\((-?\d+|0[xX][0-9a-fA-F]+)\) + // => $2.$1 + // UInt\((\d+|0[xX][0-9a-fA-F]+),\s*(?:width\s*=)?\s*(\d+|[_a-zA-Z][_0-9a-zA-Z]*)\) + // => $1.U($2.W) + // (UInt|SInt|Bool)\(([_a-zA-Z][_0-9a-zA-Z]*)\) + // => $2.as$1 + // (UInt|SInt)\(([_a-zA-Z][_0-9a-zA-Z]*),\s*(?:width\s*=)?\s*(\d+|[_a-zA-Z][_0-9a-zA-Z]*)\) + // => $2.as$1($3.W) + + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + * These will be removed very soon. It's recommended you port your code ASAP. + */ + trait UIntFactory extends chisel3.core.UIntFactory { + /** Create a UInt literal with inferred width. */ + @deprecated("use n.U", "chisel3, will be removed by end of 2016") + def apply(n: String): UInt = n.asUInt + /** Create a UInt literal with fixed width. */ + @deprecated("use n.U(width.W)", "chisel3, will be removed by end of 2016") + def apply(n: String, width: Int): UInt = n.asUInt(width.W) + + /** Create a UInt literal with specified width. */ + @deprecated("use value.U(width)", "chisel3, will be removed by end of 2016") + def apply(value: BigInt, width: Width): UInt = value.asUInt(width) + + /** Create a UInt literal with fixed width. */ + @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 + + /** Create a UInt with a specified width */ + @deprecated("use UInt(width.W)", "chisel3, will be removed by end of 2016") + def width(width: Int): UInt = apply(width.W) + + /** Create a UInt port with specified width. */ + @deprecated("use UInt(width)", "chisel3, will be removed by end of 2016") + def width(width: Width): UInt = apply(width) + } + + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + * These will be removed very soon. It's recommended you move your code soon. + */ + trait SIntFactory extends chisel3.core.SIntFactory { + /** Create a SInt type or port with fixed width. */ + @deprecated("use SInt(width.W)", "chisel3, will be removed by end of 2016") + def width(width: Int): SInt = apply(width.W) + /** Create an SInt type with specified width. */ + @deprecated("use SInt(width)", "chisel3, will be removed by end of 2016") + def width(width: Width): SInt = apply(width) + + /** Create an SInt literal with inferred width. */ + @deprecated("use value.S", "chisel3, will be removed by end of 2016") + def apply(value: BigInt): SInt = value.asSInt + /** Create an SInt literal with fixed width. */ + @deprecated("use value.S(width.W)", "chisel3, will be removed by end of 2016") + def apply(value: BigInt, width: Int): SInt = value.asSInt(width.W) + + /** Create an SInt literal with specified width. */ + @deprecated("use value.S(width)", "chisel3, will be removed by end of 2016") + def apply(value: BigInt, width: Width): SInt = value.asSInt(width) + + @deprecated("use value.S", "chisel3, will be removed by end of 2016") + def Lit(value: BigInt): SInt = value.asSInt + + @deprecated("use value.S(width)", "chisel3, will be removed by end of 2016") + def Lit(value: BigInt, width: Int): SInt = value.asSInt(width.W) + } + + /** This contains literal constructor factory methods that are deprecated as of Chisel3. + * These will be removed very soon. It's recommended you move your code soon. + */ + trait BoolFactory extends chisel3.core.BoolFactory { + /** Creates Bool literal. + */ + @deprecated("use x.B", "chisel3, will be removed by end of 2016") + def apply(x: Boolean): Bool = x.B + } + + object Bits extends UIntFactory type Num[T <: Data] = chisel3.core.Num[T] type UInt = chisel3.core.UInt - val UInt = chisel3.core.UInt + object UInt extends UIntFactory type SInt = chisel3.core.SInt - val SInt = chisel3.core.SInt + object SInt extends SIntFactory type FixedPoint = chisel3.core.FixedPoint val FixedPoint = chisel3.core.FixedPoint type Bool = chisel3.core.Bool - val Bool = chisel3.core.Bool + object Bool extends BoolFactory val Mux = chisel3.core.Mux type BlackBox = chisel3.core.BlackBox @@ -113,50 +206,18 @@ package object chisel3 { // scalastyle:ignore package.object.name implicit def string2Printable(str: String): Printable = PString(str) - /** - * These implicit classes allow one to convert scala.Int|scala.BigInt to - * Chisel.UInt|Chisel.SInt by calling .asUInt|.asSInt on them, respectively. - * The versions .asUInt(width)|.asSInt(width) are also available to explicitly - * mark a width for the new literal. - * - * Also provides .asBool to scala.Boolean and .asUInt to String - * - * Note that, for stylistic reasons, one should avoid extracting immediately - * after this call using apply, ie. 0.asUInt(1)(0) due to potential for - * confusion (the 1 is a bit length and the 0 is a bit extraction position). - * Prefer storing the result and then extracting from it. - */ - implicit class fromIntToLiteral(val x: Int) extends AnyVal { - def U: UInt = UInt(BigInt(x), Width()) // scalastyle:ignore method.name - def S: SInt = SInt(BigInt(x), Width()) // scalastyle:ignore method.name - - def asUInt(): UInt = UInt(x, Width()) - def asSInt(): SInt = SInt(x, Width()) - def asUInt(width: Int): UInt = UInt(x, width) - def asSInt(width: Int): SInt = SInt(x, width) - } - - implicit class fromBigIntToLiteral(val x: BigInt) extends AnyVal { - def U: UInt = UInt(x, Width()) // scalastyle:ignore method.name - def S: SInt = SInt(x, Width()) // scalastyle:ignore method.name - - def asUInt(): UInt = UInt(x, Width()) - def asSInt(): SInt = SInt(x, Width()) - def asUInt(width: Int): UInt = UInt(x, width) - def asSInt(width: Int): SInt = SInt(x, width) - } - implicit class fromStringToLiteral(val x: String) extends AnyVal { - def U: UInt = UInt(x) // scalastyle:ignore method.name - } - implicit class fromBooleanToLiteral(val x: Boolean) extends AnyVal { - def B: Bool = Bool(x) // scalastyle:ignore method.name - } + implicit class fromBigIntToLiteral(val x: BigInt) extends chisel3.core.fromBigIntToLiteral(x) + implicit class fromtIntToLiteral(val x: Int) extends chisel3.core.fromIntToLiteral(x) + implicit class fromtLongToLiteral(val x: Long) extends chisel3.core.fromLongToLiteral(x) + implicit class fromStringToLiteral(val x: String) extends chisel3.core.fromStringToLiteral(x) + implicit class fromBooleanToLiteral(val x: Boolean) extends chisel3.core.fromBooleanToLiteral(x) + implicit class fromDoubleToLiteral(val x: Double) extends chisel3.core.fromDoubleToLiteral(x) + implicit class fromIntToWidth(val x: Int) extends chisel3.core.fromIntToWidth(x) - implicit class fromDoubleToLiteral(val x: Double) extends AnyVal { - def F(binaryPoint: Int): FixedPoint = FixedPoint.fromDouble(x, binaryPoint = binaryPoint) - } + implicit class fromUIntToBitPatComparable(val x: UInt) { + import scala.language.experimental.macros + import internal.sourceinfo.{SourceInfo, SourceInfoTransform} - implicit class fromUIntToBitPatComparable(val x: UInt) extends AnyVal { final def === (that: BitPat): Bool = macro SourceInfoTransform.thatArg @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3") final def != (that: BitPat): Bool = macro SourceInfoTransform.thatArg @@ -179,4 +240,43 @@ package object chisel3 { // scalastyle:ignore package.object.name } 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. + * + * Because its contents won't necessarily have the same level of stability and support as + * non-experimental, you must explicitly import this package to use its contents. + */ + object experimental { + type Param = chisel3.core.Param + type IntParam = chisel3.core.IntParam + val IntParam = chisel3.core.IntParam + type DoubleParam = chisel3.core.DoubleParam + val DoubleParam = chisel3.core.DoubleParam + type StringParam = chisel3.core.StringParam + val StringParam = chisel3.core.StringParam + type RawParam = chisel3.core.RawParam + val RawParam = chisel3.core.RawParam + + // Implicit conversions for BlackBox Parameters + implicit def fromIntToIntParam(x: Int): IntParam = IntParam(BigInt(x)) + implicit def fromLongToIntParam(x: Long): IntParam = IntParam(BigInt(x)) + implicit def fromBigIntToIntParam(x: BigInt): IntParam = IntParam(x) + implicit def fromDoubleToDoubleParam(x: Double): DoubleParam = DoubleParam(x) + implicit def fromStringToStringParam(x: String): StringParam = StringParam(x) + + implicit class ChiselRange(val sc: StringContext) extends AnyVal { + import scala.language.experimental.macros + import internal.firrtl.NumericBound + + /** Specifies a range using mathematical range notation. Variables can be interpolated using + * standard string interpolation syntax. + * @example {{{ + * UInt(range"[0, 2)") + * UInt(range"[0, \$myInt)") + * UInt(range"[0, \${myInt + 2})") + * }}} + */ + def range(args: Any*): (NumericBound[Int], NumericBound[Int]) = macro chisel3.internal.RangeTransform.apply + } + } } diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala index 76b9a2e9..83f3c796 100644 --- a/src/main/scala/chisel3/testers/TesterDriver.scala +++ b/src/main/scala/chisel3/testers/TesterDriver.scala @@ -14,7 +14,7 @@ object TesterDriver extends BackendCompilationUtilities { throw new FileNotFoundException(s"Resource '$name'") } val out = new FileOutputStream(file) - Iterator.continually(in.read).takeWhile(-1 !=).foreach(out.write) + Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write) out.close() } diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 89bb644a..d755b620 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -18,7 +18,7 @@ import chisel3.core.ExplicitCompileOptions.NotStrict class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { val in = Flipped(Vec(n, Decoupled(gen))) val out = Decoupled(gen) - val chosen = Output(UInt.width(log2Up(n))) + val chosen = Output(UInt(log2Up(n).W)) } /** Arbiter Control determining which producer has access @@ -26,8 +26,8 @@ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { private object ArbiterCtrl { def apply(request: Seq[Bool]): Seq[Bool] = request.length match { case 0 => Seq() - case 1 => Seq(Bool(true)) - case _ => Bool(true) +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) + case 1 => Seq(true.B) + case _ => true.B +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) } } @@ -43,8 +43,8 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo if (count > 1) { val lockCount = Counter(count) val lockIdx = Reg(UInt()) - val locked = lockCount.value =/= UInt(0) - val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(Bool(true)) + val locked = lockCount.value =/= 0.U + val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(true.B) when (io.out.fire() && wantsLock) { lockIdx := io.chosen @@ -53,7 +53,7 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo when (locked) { io.chosen := lockIdx } for ((in, (g, i)) <- io.in zip grant.zipWithIndex) - in.ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready + in.ready := Mux(locked, lockIdx === i.asUInt, g) && io.out.ready } else { for ((in, g) <- io.in zip grant) in.ready := g && io.out.ready @@ -63,7 +63,7 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) - lazy val grantMask = (0 until n).map(UInt(_) > lastGrant) + lazy val grantMask = (0 until n).map(_.asUInt > lastGrant) lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } override def grant: Seq[Bool] = { @@ -71,20 +71,20 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) } - override lazy val choice = Wire(init=UInt(n-1)) + override lazy val choice = Wire(init=(n-1).asUInt) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt(i) } + when (io.in(i).valid) { choice := i.asUInt } for (i <- n-1 to 1 by -1) - when (validMask(i)) { choice := UInt(i) } + when (validMask(i)) { choice := i.asUInt } } class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) - override lazy val choice = Wire(init=UInt(n-1)) + override lazy val choice = Wire(init=(n-1).asUInt) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt(i) } + when (io.in(i).valid) { choice := i.asUInt } } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -112,11 +112,11 @@ class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) class Arbiter[T <: Data](gen: T, n: Int) extends Module { val io = IO(new ArbiterIO(gen, n)) - io.chosen := UInt(n-1) + io.chosen := (n-1).asUInt io.out.bits := io.in(n-1).bits for (i <- n-2 to 0 by -1) { when (io.in(i).valid) { - io.chosen := UInt(i) + io.chosen := i.asUInt io.out.bits := io.in(i).bits } } diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index e58258c7..9c9909cd 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -57,7 +57,7 @@ object BitPat { */ def bitPatToUInt(x: BitPat): UInt = { require(x.mask == (BigInt(1) << x.getWidth) - 1) - UInt(x.value, x.getWidth) + x.value.asUInt(x.getWidth.W) } /** Allows UInts to be used where a BitPat is expected, useful for when an diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index 289d27b1..22326972 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -38,10 +38,10 @@ object Fill { */ def apply(n: Int, x: UInt): UInt = { n match { - case 0 => UInt.width(0) + case 0 => UInt(0.W) case 1 => x case _ if x.isWidthKnown && x.getWidth == 1 => - Mux(x.toBool, UInt((BigInt(1) << n) - 1, n), UInt(0, n)) + Mux(x.toBool, ((BigInt(1) << n) - 1).asUInt(n.W), 0.U(n.W)) case _ if n > 1 => val p2 = Array.ofDim[UInt](log2Up(n + 1)) p2(0) = x @@ -61,7 +61,7 @@ object Reverse { // This esoterica improves simulation performance var res = in var shift = length >> 1 - var mask = UInt((BigInt(1) << length) - 1, length) + var mask = ((BigInt(1) << length) - 1).asUInt(length.W) do { mask = mask ^ (mask(length-shift-1,0) << shift) res = ((res >> shift) & mask) | ((res(length-shift-1,0) << shift) & ~mask) diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index d478e10e..a422b5fe 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -10,15 +10,15 @@ import chisel3._ object Log2 { /** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt. * - * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3) + * @note The result is truncated, so e.g. Log2(13.U) === 3.U */ def apply(x: Bits, width: Int): UInt = { if (width < 2) { - UInt(0) + 0.U } else if (width == 2) { x(1) } else if (width <= divideAndConquerThreshold) { - Mux(x(width-1), UInt(width-1), apply(x, width-1)) + Mux(x(width-1), (width-1).asUInt, apply(x, width-1)) } else { val mid = 1 << (log2Ceil(width) - 1) val hi = x(width-1, mid) @@ -30,7 +30,7 @@ object Log2 { /** Returns the base-2 integer logarithm of an UInt. * - * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3) + * @note The result is truncated, so e.g. Log2(13.U) === 3.U */ def apply(x: Bits): UInt = apply(x, x.getWidth) diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index ba66d667..6d59eaaf 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -12,7 +12,7 @@ import chisel3._ */ class Counter(val n: Int) { require(n >= 0) - val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) + val value = if (n > 1) Reg(init=0.U(log2Up(n).W)) else 0.U /** Increment the counter, returning whether the counter currently is at the * maximum and will wrap. The incremented value is registered and will be @@ -20,14 +20,14 @@ class Counter(val n: Int) { */ def inc(): Bool = { if (n > 1) { - val wrap = value === UInt(n-1) - value := value + UInt(1) + val wrap = value === (n-1).asUInt + value := value + 1.U if (!isPow2(n)) { - when (wrap) { value := UInt(0) } + when (wrap) { value := 0.U } } wrap } else { - Bool(true) + true.B } } } @@ -46,9 +46,9 @@ object Counter * maximum and the condition is true). * * @example {{{ - * val countOn = Bool(true) // increment counter every clock cycle + * val countOn = true.B // increment counter every clock cycle * val (counterValue, counterWrap) = Counter(countOn, 4) - * when (counterValue === UInt(3)) { + * when (counterValue === 3.U) { * ... * } * }}} diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index c9d57759..fcda6943 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -32,7 +32,7 @@ object ReadyValidIO { * @return dat. */ def enq(dat: T): T = { - target.valid := Bool(true) + target.valid := true.B target.bits := dat dat } @@ -40,7 +40,7 @@ object ReadyValidIO { /** Indicate no enqueue occurs. Valid is set to false, and all bits are set to zero. */ def noenq(): Unit = { - target.valid := Bool(false) + target.valid := false.B // We want the type from the following, not any existing binding. target.bits := target.bits.cloneType.fromBits(0.asUInt) } @@ -51,14 +51,14 @@ object ReadyValidIO { * @return the data for this device, */ def deq(): T = { - target.ready := Bool(true) + target.ready := true.B target.bits } /** Indicate no dequeue occurs. Ready is set to false */ def nodeq(): Unit = { - target.ready := Bool(false) + target.ready := false.B } } } @@ -144,7 +144,7 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ val deq = EnqIO(gen) /** The current amount of data in the queue */ - val count = Output(UInt.width(log2Up(entries + 1))) + val count = Output(UInt(log2Up(entries + 1).W)) override def cloneType = new QueueIO(gen, entries).asInstanceOf[this.type] } @@ -177,7 +177,7 @@ extends Module(override_reset=override_reset) { val ram = Mem(entries, gen) val enq_ptr = Counter(entries) val deq_ptr = Counter(entries) - val maybe_full = Reg(init=Bool(false)) + val maybe_full = Reg(init=false.B) val ptr_match = enq_ptr.value === deq_ptr.value val empty = ptr_match && !maybe_full @@ -201,16 +201,16 @@ extends Module(override_reset=override_reset) { io.deq.bits := ram(deq_ptr.value) if (flow) { - when (io.enq.valid) { io.deq.valid := Bool(true) } + when (io.enq.valid) { io.deq.valid := true.B } when (empty) { io.deq.bits := io.enq.bits - do_deq := Bool(false) - when (io.deq.ready) { do_enq := Bool(false) } + do_deq := false.B + when (io.deq.ready) { do_enq := false.B } } } if (pipe) { - when (io.deq.ready) { io.enq.ready := Bool(true) } + when (io.deq.ready) { io.enq.ready := true.B } } val ptr_diff = enq_ptr.value - deq_ptr.value @@ -219,9 +219,9 @@ extends Module(override_reset=override_reset) { } else { io.count := Mux(ptr_match, Mux(maybe_full, - UInt(entries), UInt(0)), + entries.asUInt, 0.U), Mux(deq_ptr.value > enq_ptr.value, - UInt(entries) + ptr_diff, ptr_diff)) + entries.asUInt + ptr_diff, ptr_diff)) } } @@ -230,7 +230,7 @@ extends Module(override_reset=override_reset) { * @param enq input (enqueue) interface to the queue, also determines width of queue elements * @param entries depth (number of elements) of the queue * - * @returns output (dequeue) interface from the queue + * @return output (dequeue) interface from the queue * * @example {{{ * consumer.io.in <> Queue(producer.io.out, 16) diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 55b595ee..45aee62a 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -7,15 +7,15 @@ package chisel3.util import chisel3._ -object Enum { +trait Enum { /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ - private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] = - (0 until n).map(x => nodeType.fromInt(x, log2Up(n))) + protected def createValues(n: Int): Seq[UInt] = + (0 until n).map(_.U(log2Up(n).W)) - /** Returns n unique values of the specified type. Can be used with unpacking to define enums. + /** Returns n unique UInt values, use with unpacking to specify an enumeration. * * @example {{{ - * val state_on :: state_off :: Nil = Enum(UInt(), 2) + * val state_on :: state_off :: Nil = Enum(2) * val current_state = UInt() * switch (current_state) { * is (state_on) { @@ -26,28 +26,15 @@ object Enum { * } * } * }}} - * */ - def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList - - /** Returns a map of the input symbols to unique values of the specified type. - * - * @example {{{ - * val states = Enum(UInt(), 'on, 'off) - * val current_state = UInt() - * switch (current_state) { - * is (states('on)) { - * ... - * } - * if (states('off)) { - * .. - * } - * } - * }}} - */ - def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap + def apply(n: Int): List[UInt] = createValues(n).toList +} - /** Returns a map of the input symbols to unique values of the specified type. - */ - def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap +object Enum extends Enum { + @deprecated("use Enum(n)", "chisel3, will be removed soon") + def apply[T <: Bits](nodeType: T, n: Int): List[T] = { + require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums") + require(!nodeType.widthKnown, "Bit width may no longer be specified for enums") + apply(n).asInstanceOf[List[T]] + } } diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 4d816a19..712975a7 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -4,7 +4,11 @@ package chisel3.util import chisel3._ +import scala.language.implicitConversions + object ImplicitConversions { - implicit def intToUInt(x: Int): UInt = UInt(x) - implicit def booleanToBool(x: Boolean): Bool = Bool(x) + // The explicit fromIntToLiteral resolves an ambiguous conversion between fromIntToLiteral and + // UInt.asUInt. + implicit def intToUInt(x: Int): UInt = chisel3.core.fromIntToLiteral(x).asUInt + implicit def booleanToBool(x: Boolean): Bool = x.asBool } diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index fedbf194..83dc907d 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -15,9 +15,9 @@ object LFSR16 { * * @param increment optional control to gate when the LFSR updates. */ - def apply(increment: Bool = Bool(true)): UInt = { + def apply(increment: Bool = true.B): UInt = { val width = 16 - val lfsr = Reg(init=UInt(1, width)) + val lfsr = Reg(init=1.U(width.W)) when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } lfsr } diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 53ba8c3d..7dd0c68b 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -35,7 +35,7 @@ object OHToUInt { * Multiple bits may be high in the input. */ object PriorityEncoder { - def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) + def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(_.asUInt)) def apply(in: Bits): UInt = apply(in.toBools) } @@ -44,9 +44,9 @@ object PriorityEncoder { object UIntToOH { def apply(in: UInt, width: Int = -1): UInt = if (width == -1) { - UInt(1) << in + 1.U << in } else { - (UInt(1) << in(log2Up(width)-1,0))(width-1,0) + (1.U << in(log2Up(width)-1,0))(width-1,0) } } @@ -55,8 +55,8 @@ object UIntToOH { */ object PriorityEncoderOH { private def encode(in: Seq[Bool]): UInt = { - val outs = Seq.tabulate(in.size)(i => UInt(BigInt(1) << i, in.size)) - PriorityMux(in :+ Bool(true), outs :+ UInt(0, in.size)) + val outs = Seq.tabulate(in.size)(i => (BigInt(1) << i).asUInt(in.size.W)) + PriorityMux(in :+ true.B, outs :+ 0.U(in.size.W)) } def apply(in: Seq[Bool]): Seq[Bool] = { val enc = encode(in) diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 713a3b2e..00005e3a 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -53,12 +53,10 @@ object ShiftRegister * @param n number of cycles to delay * @param en enable the shift */ - def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = { + def apply[T <: Data](in: T, n: Int, en: Bool = true.B): T = { // The order of tests reflects the expected use cases. - if (n == 1) { - RegEnable(in, en) - } else if (n != 0) { - RegNext(apply(in, n-1, en)) + if (n != 0) { + RegEnable(apply(in, n-1, en), en) } else { in } diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 3d153a2a..0229b7f8 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -41,7 +41,7 @@ object Pipe out.bits <> enqBits out } else { - val v = Reg(Bool(), next=enqValid, init=Bool(false)) + val v = Reg(Bool(), next=enqValid, init=false.B) val b = RegEnable(enqBits, enqValid) apply(v, b, latency-1) } @@ -52,10 +52,12 @@ object Pipe class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module { - val io = IO(new Bundle { + class PipeIO extends Bundle { val enq = Input(Valid(gen)) val deq = Output(Valid(gen)) - }) + } + + val io = IO(new PipeIO) io.deq <> Pipe(io.enq, latency) } |
