From 2eb17fdc8f4431aab624b71a0589d03e424daf0b Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Sun, 30 Oct 2022 23:26:44 -0400 Subject: [PATCH 1/6] Add MFC Deprecation String Message, NFC Add a deprecation string that can be used for marking things that are deprecated due to the MLIR-based FIRRTL Compiler (MFC) migration. Do not use this anywhere (yet). Signed-off-by: Schuyler Eldridge --- core/src/main/scala/chisel3/package.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala index 8702468344a..caf2b9906d7 100644 --- a/core/src/main/scala/chisel3/package.scala +++ b/core/src/main/scala/chisel3/package.scala @@ -385,4 +385,7 @@ package object chisel3 { // Connection exceptions. case class BiConnectException(message: String) extends ChiselException(message) case class MonoConnectException(message: String) extends ChiselException(message) + + final val deprecatedMFCMessage = + "this feature will not be supported as part of the migration to the MLIR-based FIRRTL Compiler (MFC). For more information about this migration, please see the Chisel ROADMAP.md." } From 005665832100f51348e28dedaafea47cbf360243 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Sun, 30 Oct 2022 23:28:28 -0400 Subject: [PATCH 2/6] Deprecated Fixed Point Types and Functions Signed-off-by: Schuyler Eldridge --- core/src/main/scala/chisel3/Bits.scala | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala index 70704e01e49..69c77096a12 100644 --- a/core/src/main/scala/chisel3/Bits.scala +++ b/core/src/main/scala/chisel3/Bits.scala @@ -1400,12 +1400,15 @@ package experimental { /** Chisel types that have binary points support retrieving * literal values as `Double` or `BigDecimal` */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") trait HasBinaryPoint { self: Bits => + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def binaryPoint: BinaryPoint /** Return the [[Double]] value of this instance if it is a Literal * @note this method may throw an exception if the literal value won't fit in a Double */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def litToDoubleOption: Option[Double] = { litOption match { case Some(bigInt: BigInt) => @@ -1416,11 +1419,13 @@ package experimental { /** Return the double value of this instance assuming it is a literal (convenience method) */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def litToDouble: Double = litToDoubleOption.get /** Return the [[BigDecimal]] value of this instance if it is a Literal * @note this method may throw an exception if the literal value won't fit in a BigDecimal */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def litToBigDecimalOption: Option[BigDecimal] = { litOption match { case Some(bigInt: BigInt) => @@ -1432,6 +1437,7 @@ package experimental { /** Return the [[BigDecimal]] value of this instance assuming it is a literal (convenience method) * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def litToBigDecimal: BigDecimal = litToBigDecimalOption.get } @@ -1449,6 +1455,7 @@ package experimental { * @define expandingWidth @note The width of the returned $coll is `width of this` + `1`. * @define constantWidth @note The width of the returned $coll is unchanged, i.e., `width of this`. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) extends Bits(width) with Num[FixedPoint] @@ -1825,19 +1832,23 @@ package experimental { * Factory and convenience methods for the FixedPoint class * IMPORTANT: The API provided here is experimental and may change in the future. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") object FixedPoint extends NumObject { import FixedPoint.Implicits._ /** Create an FixedPoint type with inferred width. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(): FixedPoint = apply(Width(), BinaryPoint()) /** Create an FixedPoint type or port with fixed width. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint) /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigInt(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = { apply(value, width, binaryPoint) } @@ -1845,6 +1856,7 @@ package experimental { /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = { apply(value, Width(), binaryPoint) } @@ -1852,6 +1864,7 @@ package experimental { /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint = if (width == -1) { apply(value, Width(), BinaryPoint(binaryPoint)) @@ -1862,6 +1875,7 @@ package experimental { /** Create an FixedPoint literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint): FixedPoint = { fromBigInt( toBigInt(value, binaryPoint.get), @@ -1873,6 +1887,7 @@ package experimental { /** Create an FixedPoint literal with inferred width from BigDecimal. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigDecimal(value: BigDecimal, width: Width, binaryPoint: BinaryPoint): FixedPoint = { fromBigInt( toBigInt(value, binaryPoint.get), @@ -1882,6 +1897,7 @@ package experimental { } /** Create an FixedPoint port with specified width and binary position. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = { val lit = FPLit(value, width, binaryPoint) val newLiteral = new FixedPoint(lit.width, lit.binaryPoint) @@ -1889,23 +1905,30 @@ package experimental { lit.bindLitArg(newLiteral) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") object Implicits { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromDoubleToLiteral(double: Double) { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def F(binaryPoint: BinaryPoint): FixedPoint = { FixedPoint.fromDouble(double, Width(), binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = { FixedPoint.fromDouble(double, width, binaryPoint) } } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromBigDecimalToLiteral(bigDecimal: BigDecimal) { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def F(binaryPoint: BinaryPoint): FixedPoint = { FixedPoint.fromBigDecimal(bigDecimal, Width(), binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = { FixedPoint.fromBigDecimal(bigDecimal, width, binaryPoint) } From 576e0c4171033fea9cf43418687881ef5a26f647 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Sun, 30 Oct 2022 23:28:58 -0400 Subject: [PATCH 3/6] Deprecate Interval Types and Methods Signed-off-by: Schuyler Eldridge --- core/src/main/scala/chisel3/Bits.scala | 62 +++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala index 69c77096a12..c0fe8b24f53 100644 --- a/core/src/main/scala/chisel3/Bits.scala +++ b/core/src/main/scala/chisel3/Bits.scala @@ -1953,11 +1953,13 @@ package experimental { * * @param range a range specifies min, max and binary point */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") sealed class Interval private[chisel3] (val range: chisel3.internal.firrtl.IntervalRange) extends Bits(range.getWidth) with Num[Interval] with HasBinaryPoint { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") override def toString: String = { litOption match { case Some(value) => s"Interval$width($value)" @@ -1965,9 +1967,11 @@ package experimental { } } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") private[chisel3] override def cloneTypeWidth(w: Width): this.type = new Interval(range).asInstanceOf[this.type] + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def toType: String = { val zdec1 = """([+\-]?[0-9]\d*)(\.[0-9]*[1-9])(0*)""".r val zdec2 = """([+\-]?[0-9]\d*)(\.0*)""".r @@ -2003,8 +2007,10 @@ package experimental { private[chisel3] override def typeEquivalent(that: Data): Boolean = that.isInstanceOf[Interval] && this.width == that.width + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def binaryPoint: BinaryPoint = range.binaryPoint + @deprecated(deprecatedMFCMessage, "Chisel 3.6") override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { that match { case _: Interval | DontCare => super.connect(that) @@ -2012,6 +2018,7 @@ package experimental { } } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def unary_- : Interval = macro SourceInfoTransform.noArg @deprecated( @@ -2020,6 +2027,7 @@ package experimental { ) final def unary_-(dummy: Int*): Interval = macro SourceInfoTransform.noArgDummy + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def unary_-% : Interval = macro SourceInfoTransform.noArg @deprecated( @@ -2052,15 +2060,19 @@ package experimental { throwException(s"mod is illegal on Interval types") /** add (width +1) operator */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def +&(that: Interval): Interval = macro SourceInfoTransform.thatArg /** add (no growth) operator */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def +%(that: Interval): Interval = macro SourceInfoTransform.thatArg /** subtract (width +1) operator */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def -&(that: Interval): Interval = macro SourceInfoTransform.thatArg /** subtract (no growth) operator */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def -%(that: Interval): Interval = macro SourceInfoTransform.thatArg def do_+&(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { @@ -2079,8 +2091,11 @@ package experimental { throwException(s"Non-growing subtraction is not supported on Intervals: ${sourceInfo}, try squeeze") } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def &(that: Interval): Interval = macro SourceInfoTransform.thatArg + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def |(that: Interval): Interval = macro SourceInfoTransform.thatArg + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def ^(that: Interval): Interval = macro SourceInfoTransform.thatArg def do_&(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = @@ -2090,6 +2105,7 @@ package experimental { def do_^(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = throwException(s"Xor is illegal between $this and $that") + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def setPrecision(that: Int): Interval = macro SourceInfoTransform.thatArg // Precision change changes range -- see firrtl PrimOps (requires floor) @@ -2105,6 +2121,7 @@ package experimental { * @param that how many bits to shift binary point * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def increasePrecision(that: Int): Interval = macro SourceInfoTransform.thatArg def do_increasePrecision(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { @@ -2120,6 +2137,7 @@ package experimental { * @param that number of bits to move binary point * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def decreasePrecision(that: Int): Interval = macro SourceInfoTransform.thatArg def do_decreasePrecision(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { @@ -2142,8 +2160,11 @@ package experimental { override def do_>=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) - final def !=(that: Interval): Bool = macro SourceInfoTransform.thatArg + @deprecated(deprecatedMFCMessage, "Chisel 3.6") + final def !=(that: Interval): Bool = macro SourceInfoTransform.thatArg + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def =/=(that: Interval): Bool = macro SourceInfoTransform.thatArg + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def ===(that: Interval): Bool = macro SourceInfoTransform.thatArg def do_!=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = @@ -2188,6 +2209,7 @@ package experimental { * @param that * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def squeeze(that: Interval): Interval = macro SourceInfoTransform.thatArg def do_squeeze(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { val other = that @@ -2204,6 +2226,7 @@ package experimental { * @param that an UInt whose properties determine the squeezing * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def squeeze(that: UInt): Interval = macro SourceInfoTransform.thatArg def do_squeeze(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { that.widthOption match { @@ -2222,6 +2245,7 @@ package experimental { * @param that an SInt whose properties determine the squeezing * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def squeeze(that: SInt): Interval = macro SourceInfoTransform.thatArg def do_squeeze(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { that.widthOption match { @@ -2240,6 +2264,7 @@ package experimental { * @param that an Interval whose properties determine the squeezing * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def squeeze(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg def do_squeeze(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { val intervalLitOpt = Interval.getSmallestLegalLit(that) @@ -2256,6 +2281,7 @@ package experimental { * @param that * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def wrap(that: Interval): Interval = macro SourceInfoTransform.thatArg def do_wrap(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { @@ -2271,6 +2297,7 @@ package experimental { * @param that an UInt whose properties determine the wrap * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def wrap(that: UInt): Interval = macro SourceInfoTransform.thatArg def do_wrap(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { that.widthOption match { @@ -2288,6 +2315,7 @@ package experimental { * @param that an SInt whose properties determine the bounds of the wrap * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def wrap(that: SInt): Interval = macro SourceInfoTransform.thatArg def do_wrap(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { that.widthOption match { @@ -2308,6 +2336,7 @@ package experimental { * @param that an Interval whose properties determine the bounds of the wrap * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def wrap(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg def do_wrap(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { (that.lowerBound, that.upperBound) match { @@ -2325,6 +2354,7 @@ package experimental { * @param that an Interval whose properties determine the clipping * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def clip(that: Interval): Interval = macro SourceInfoTransform.thatArg def do_clip(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { binop(sourceInfo, Interval(this.range.clip(that.range)), ClipOp, that) @@ -2336,6 +2366,7 @@ package experimental { * @param that an UInt whose width determines the clipping * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def clip(that: UInt): Interval = macro SourceInfoTransform.thatArg def do_clip(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { require(that.widthKnown, "UInt clip width must be known") @@ -2349,6 +2380,7 @@ package experimental { * @param that an SInt whose width determines the clipping * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def clip(that: SInt): Interval = macro SourceInfoTransform.thatArg def do_clip(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { require(that.widthKnown, "SInt clip width must be known") @@ -2364,6 +2396,7 @@ package experimental { * @param that an SInt whose width determines the clipping * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") final def clip(that: IntervalRange): Interval = macro SourceInfoTransform.thatArg def do_clip(that: IntervalRange)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { (that.lowerBound, that.upperBound) match { @@ -2432,12 +2465,15 @@ package experimental { * Factory and convenience methods for the Interval class * IMPORTANT: The API provided here is experimental and may change in the future. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") object Interval extends NumObject { /** Create an Interval type with inferred width and binary point. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(): Interval = Interval(range"[?,?]") /** Create an Interval type with specified width. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(binaryPoint: BinaryPoint): Interval = { val binaryPointString = binaryPoint match { case KnownBinaryPoint(value) => s"$value" @@ -2447,9 +2483,11 @@ package experimental { } /** Create an Interval type with specified width. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(width: Width): Interval = Interval(width, 0.BP) /** Create an Interval type with specified width and binary point */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(width: Width, binaryPoint: BinaryPoint): Interval = { Interval(IntervalRange(width, binaryPoint)) } @@ -2457,11 +2495,13 @@ package experimental { /** Create an Interval type with specified range. * @param range defines the properties */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(range: IntervalRange): Interval = { new Interval(range) } /** Creates a Interval connected to a Interval literal with the value zero */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def Zero: Interval = Lit(0, 1.W, 0.BP) /** Creates an Interval zero that supports the given range @@ -2472,6 +2512,7 @@ package experimental { * @param range * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def Zero(range: IntervalRange): Interval = Lit(0, range) /** Make an interval from this BigInt, the BigInt is treated as bits @@ -2482,6 +2523,7 @@ package experimental { * @param binaryPoint * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigInt(value: BigInt, width: Width = Width(), binaryPoint: BinaryPoint = 0.BP): Interval = { Interval.Lit(value, Width(), binaryPoint) } @@ -2489,6 +2531,7 @@ package experimental { /** Create an Interval literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromDouble( value: Double, dummy: PrivateType = PrivateObject, @@ -2505,6 +2548,7 @@ package experimental { /** Create an Interval literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def fromBigDecimal( value: Double, dummy: PrivateType = PrivateObject, @@ -2559,6 +2603,7 @@ package experimental { * @param range use to figure low number * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def getSmallestLegalLit(range: IntervalRange): Option[Interval] = { val bp = range.binaryPoint range.lowerBound match { @@ -2578,6 +2623,7 @@ package experimental { * @param range use to figure low number * @return */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def getLargestLegalLit(range: IntervalRange): Option[Interval] = { val bp = range.binaryPoint range.upperBound match { @@ -2597,46 +2643,60 @@ package experimental { * val y = 7.5.I(4.BP) * }}} */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") object Implicits { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromBigIntToLiteralInterval(bigInt: BigInt) { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I: Interval = { Interval.Lit(bigInt, width = Width(), 0.BP) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(binaryPoint: BinaryPoint): Interval = { Interval.Lit(bigInt, width = Width(), binaryPoint = binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(width: Width, binaryPoint: BinaryPoint): Interval = { Interval.Lit(bigInt, width, binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(range: IntervalRange): Interval = { Interval.Lit(bigInt, range) } } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromIntToLiteralInterval(int: Int) extends fromBigIntToLiteralInterval(int) + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromLongToLiteralInterval(long: Long) extends fromBigIntToLiteralInterval(long) + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromBigDecimalToLiteralInterval(bigDecimal: BigDecimal) { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I: Interval = { Interval.Lit(Interval.toBigInt(bigDecimal, 0.BP), width = Width(), 0.BP) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(binaryPoint: BinaryPoint): Interval = { Interval.Lit(Interval.toBigInt(bigDecimal, binaryPoint), width = Width(), binaryPoint = binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(width: Width, binaryPoint: BinaryPoint): Interval = { Interval.Lit(Interval.toBigInt(bigDecimal, binaryPoint), width, binaryPoint) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def I(range: IntervalRange): Interval = { Interval.Lit(Interval.toBigInt(bigDecimal, range.binaryPoint), range) } } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") implicit class fromDoubleToLiteralInterval(double: Double) extends fromBigDecimalToLiteralInterval(BigDecimal(double)) } From c001f5ff02be2c440e8d22b2f302550591ca4b8c Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Sun, 30 Oct 2022 23:34:22 -0400 Subject: [PATCH 4/6] Deprecate EnumAnnotations Deprecate all EnumAnnotations as these are not supported by the MLIR-based FIRRTL Compiler. These will reappear as enumerated types in FIRRTL in the future. Signed-off-by: Schuyler Eldridge --- core/src/main/scala/chisel3/StrongEnum.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/scala/chisel3/StrongEnum.scala b/core/src/main/scala/chisel3/StrongEnum.scala index 3c9f41053b0..cd4c58e89ce 100644 --- a/core/src/main/scala/chisel3/StrongEnum.scala +++ b/core/src/main/scala/chisel3/StrongEnum.scala @@ -13,6 +13,7 @@ import chisel3.internal.sourceinfo._ import chisel3.internal.{throwException, Binding, Builder, ChildBinding, ConstrainedBinding, InstanceId} import firrtl.annotations._ +@deprecated(deprecatedMFCMessage, "Chisel 3.6") object EnumAnnotations { /** An annotation for strong enum instances that are ''not'' inside of Vecs @@ -20,10 +21,12 @@ object EnumAnnotations { * @param target the enum instance being annotated * @param enumTypeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'') */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumComponentAnnotation(target: Named, enumTypeName: String) extends SingleTargetAnnotation[Named] { def duplicate(n: Named): EnumComponentAnnotation = this.copy(target = n) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumComponentChiselAnnotation(target: InstanceId, enumTypeName: String) extends ChiselAnnotation { def toFirrtl: EnumComponentAnnotation = EnumComponentAnnotation(target.toNamed, enumTypeName) } @@ -48,11 +51,13 @@ object EnumAnnotations { * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'') * @param fields a list of all chains of elements leading from the Vec instance to its inner enum fields. */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]]) extends SingleTargetAnnotation[Named] { def duplicate(n: Named): EnumVecAnnotation = this.copy(target = n) } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]]) extends ChiselAnnotation { override def toFirrtl: EnumVecAnnotation = EnumVecAnnotation(target.toNamed, typeName, fields) @@ -63,8 +68,10 @@ object EnumAnnotations { * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'') * @param definition a map describing which integer values correspond to which enum names */ + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumDefAnnotation(typeName: String, definition: Map[String, BigInt]) extends NoTargetAnnotation + @deprecated(deprecatedMFCMessage, "Chisel 3.6") case class EnumDefChiselAnnotation(typeName: String, definition: Map[String, BigInt]) extends ChiselAnnotation { override def toFirrtl: Annotation = EnumDefAnnotation(typeName, definition) } From 33e84d6d85a8d29a0753490c40b30f1817dad09e Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Sun, 30 Oct 2022 23:38:44 -0400 Subject: [PATCH 5/6] Deprecate ChiselAnnotation Deprecate ChiselAnnotation as custom annotations will not be supported as part of the migration to the MLIR-based FIRRTL Compiler. Signed-off-by: Schuyler Eldridge --- core/src/main/scala/chisel3/Annotation.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/Annotation.scala b/core/src/main/scala/chisel3/Annotation.scala index c350fb308ad..b56acdc652a 100644 --- a/core/src/main/scala/chisel3/Annotation.scala +++ b/core/src/main/scala/chisel3/Annotation.scala @@ -4,7 +4,7 @@ package chisel3.experimental import scala.language.existentials import chisel3.internal.{Builder, InstanceId, LegacyModule} -import chisel3.{CompileOptions, Data, RawModule} +import chisel3.{deprecatedMFCMessage, CompileOptions, Data, RawModule} import firrtl.Transform import firrtl.annotations._ import firrtl.options.Unserializable @@ -14,6 +14,7 @@ import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation} * * Defines a conversion to a corresponding FIRRTL Annotation */ +@deprecated(deprecatedMFCMessage, "Chisel 3.6") trait ChiselAnnotation { /** Conversion to FIRRTL Annotation */ @@ -24,6 +25,7 @@ trait ChiselAnnotation { * * Defines a conversion to corresponding FIRRTL Annotation(s) */ +@deprecated(deprecatedMFCMessage, "Chisel 3.6") trait ChiselMultiAnnotation { def toFirrtl: Seq[Annotation] } @@ -34,14 +36,18 @@ trait ChiselMultiAnnotation { * Automatic Transform instantiation is *not* supported when the Circuit and Annotations are serialized before invoking * FIRRTL. */ +@deprecated(deprecatedMFCMessage, "Chisel 3.6") trait RunFirrtlTransform extends ChiselAnnotation { def transformClass: Class[_ <: Transform] } +@deprecated(deprecatedMFCMessage, "Chisel 3.6") object annotate { + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(anno: ChiselAnnotation): Unit = { Builder.annotations += anno } + @deprecated(deprecatedMFCMessage, "Chisel 3.6") def apply(annos: ChiselMultiAnnotation): Unit = { Builder.newAnnotations += annos } From 5afef6b2dc8e192c2115f5c35722fe687fd50efb Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 31 Oct 2022 00:22:12 -0400 Subject: [PATCH 6/6] Remove ChiselAnnotation from Docs Remove usages of ChiselAnnotation from documentation (since this is now deprecated). Signed-off-by: Schuyler Eldridge --- docs/src/appendix/experimental-features.md | 43 ------- docs/src/cookbooks/hierarchy.md | 91 ------------- docs/src/explanations/annotations.md | 141 --------------------- 3 files changed, 275 deletions(-) delete mode 100644 docs/src/explanations/annotations.md diff --git a/docs/src/appendix/experimental-features.md b/docs/src/appendix/experimental-features.md index a85704c2a13..e81cd817b22 100644 --- a/docs/src/appendix/experimental-features.md +++ b/docs/src/appendix/experimental-features.md @@ -271,49 +271,6 @@ class InitMemInline(memoryFile: String = "") extends Module { The default is to use `$readmemh` (which assumes all numbers in the file are in ascii hex), but to use ascii binary there is an optional `hexOrBinary` argument which can be set to `MemoryLoadFileType.Hex` or `MemoryLoadFileType.Binary`. You will need to add an additional import. -By default, the inline initialization will generate the memory `readmem` statements inside an `ifndef SYNTHESIS` block, which suits ASIC workflow. - -Some synthesis tools (like Synplify and Yosys) define `SYNTHESIS` so the `readmem` statement is not read when inside this block. - -To control this, one can use the `MemoryNoSynthInit` and `MemorySynthInit` annotations from `firrtl.annotations`. The former which is the default setting when no annotation is present generates `readmem` inside the block. Using the latter, the statement are generated outside the `ifndef` block so it can be used by FPGA synthesis tools. - -Below an example for initialization suited for FPGA workflows: - -```scala mdoc:silent -import chisel3._ -import chisel3.util.experimental.loadMemoryFromFileInline -import chisel3.experimental.{annotate, ChiselAnnotation} -import firrtl.annotations.MemorySynthInit - -class InitMemInlineFPGA(memoryFile: String = "") extends Module { - val width: Int = 32 - val io = IO(new Bundle { - val enable = Input(Bool()) - val write = Input(Bool()) - val addr = Input(UInt(10.W)) - val dataIn = Input(UInt(width.W)) - val dataOut = Output(UInt(width.W)) - }) - - // Notice the annotation below - annotate(new ChiselAnnotation { - override def toFirrtl = - MemorySynthInit - }) - - val mem = SyncReadMem(1024, UInt(width.W)) - if (memoryFile.trim().nonEmpty) { - loadMemoryFromFileInline(mem, memoryFile) - } - io.dataOut := DontCare - when(io.enable) { - val rdwrPort = mem(io.addr) - when (io.write) { rdwrPort := io.dataIn } - .otherwise { io.dataOut := rdwrPort } - } -} -``` - #### SystemVerilog Bind Initialization Chisel can also initialize memories by generating a SV bind module with `readmemh` or `readmemb` statements by using the function `loadMemoryFromFile` from `chisel3.util.experimental`. diff --git a/docs/src/cookbooks/hierarchy.md b/docs/src/cookbooks/hierarchy.md index b8d2db63177..49fa31ac62a 100644 --- a/docs/src/cookbooks/hierarchy.md +++ b/docs/src/cookbooks/hierarchy.md @@ -217,94 +217,3 @@ There are seven hierarchy-specific functions, which (with the exception of `ios` - `definitionsOf[type]`: Return definitions of all instances of provided `type` directly instantiated locally within `parent` - `allDefinitionsOf[type]`: Return all definitions of instances of provided `type` directly and indirectly instantiated, locally and deeply, starting from `root` - `ios`: Returns all the I/Os of the provided definition or instance. - -To demonstrate this, consider the following. We mock up an example where we are using the `Select.allInstancesOf` and `Select.allDefinitionsOf` to annotate instances and the definition of `EmptyModule`. When converting the `ChiselAnnotation` to firrtl's `Annotation`, we print out the resulting `Target`. As shown, despite `EmptyModule` actually only being elaborated once, we still provide different targets depending on how the instance or definition is selected. - -```scala mdoc:reset -import chisel3._ -import chisel3.experimental.hierarchy.{Definition, Instance, Hierarchy, instantiable, public} -import firrtl.annotations.{IsModule, NoTargetAnnotation} -case object EmptyAnnotation extends NoTargetAnnotation -case class MyChiselAnnotation(m: Hierarchy[RawModule], tag: String) extends experimental.ChiselAnnotation { - def toFirrtl = { - println(tag + ": " + m.toTarget) - EmptyAnnotation - } -} - -@instantiable -class EmptyModule extends Module { - println("Elaborating EmptyModule!") -} - -@instantiable -class TwoEmptyModules extends Module { - val definition = Definition(new EmptyModule) - val i0 = Instance(definition) - val i1 = Instance(definition) -} - -class Top extends Module { - val definition = Definition(new TwoEmptyModules) - val instance = Instance(definition) - aop.Select.allInstancesOf[EmptyModule](instance).foreach { i => - experimental.annotate(MyChiselAnnotation(i, "instance")) - } - aop.Select.allDefinitionsOf[EmptyModule](instance).foreach { d => - experimental.annotate(MyChiselAnnotation(d, "definition")) - } -} -``` -```scala mdoc:passthrough -println("```") -val x = chisel3.stage.ChiselStage.emitFirrtl(new Top) -println("```") -``` - -You can also use `Select.ios` on either a `Definition` or an `Instance` to annotate the I/Os appropriately: - -```scala mdoc -case class MyIOAnnotation(m: Data, tag: String) extends experimental.ChiselAnnotation { - def toFirrtl = { - println(tag + ": " + m.toTarget) - EmptyAnnotation - } -} - -@instantiable -class InOutModule extends Module { - @public val in = IO(Input(Bool())) - @public val out = IO(Output(Bool())) - out := in -} - -@instantiable -class TwoInOutModules extends Module { - val in = IO(Input(Bool())) - val out = IO(Output(Bool())) - val definition = Definition(new InOutModule) - val i0 = Instance(definition) - val i1 = Instance(definition) - i0.in := in - i1.in := i0.out - out := i1.out -} - -class InOutTop extends Module { - val definition = Definition(new TwoInOutModules) - val instance = Instance(definition) - aop.Select.allInstancesOf[InOutModule](instance).foreach { i => - aop.Select.ios(i).foreach { io => - experimental.annotate(MyIOAnnotation(io, "instance io")) - }} - aop.Select.allDefinitionsOf[InOutModule](instance).foreach { d => - aop.Select.ios(d).foreach {io => - experimental.annotate(MyIOAnnotation(io, "definition io")) - }} -} -``` -```scala mdoc:passthrough -println("```") -val y = chisel3.stage.ChiselStage.emitFirrtl(new InOutTop) -println("```") -``` \ No newline at end of file diff --git a/docs/src/explanations/annotations.md b/docs/src/explanations/annotations.md deleted file mode 100644 index 510ebca5278..00000000000 --- a/docs/src/explanations/annotations.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -layout: docs -title: "Annotations" -section: "chisel3" ---- - -# Annotations - -`Annotation`s are metadata containers associated with zero or more "things" in a FIRRTL circuit. -Commonly, `Annotation`s are used to communicate information from Chisel to a specific, custom FIRRTL `Transform`. -In this way `Annotation`s can be viewed as the "arguments" that a specific `Transform` consumes. - -This article focuses on the approach to building a basic library that contains `Annotation`s and `Transform`s. - -### Imports -We need a few basic imports to reference the components we need. - -```scala mdoc:silent -import chisel3._ -import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} -import chisel3.internal.InstanceId - -import firrtl._ -import firrtl.annotations.{Annotation, SingleTargetAnnotation} -import firrtl.annotations.{CircuitTarget, ModuleTarget, InstanceTarget, ReferenceTarget, Target} -``` - -### Define an `Annotation` and a `Transform` - -First, define an `Annotation` that contains a string associated with a `Target` thing in the Chisel circuit. -This `InfoAnnotation` extends [`SingleTargetAnnotation`](https://www.chisel-lang.org/api/firrtl/1.2.0/firrtl/annotations/SingleTargetAnnotation.html), an `Annotation` associated with *one* thing in a FIRRTL circuit: - -```scala mdoc:silent -/** An annotation that contains some string information */ -case class InfoAnnotation(target: Target, info: String) extends SingleTargetAnnotation[Target] { - def duplicate(newTarget: Target) = this.copy(target = newTarget) -} -``` - -Second, define a `Transform` that consumes this `InfoAnnotation`. -This `InfoTransform` simply reads all annotations, prints any `InfoAnnotation`s it finds, and removes them. - -```scala mdoc:invisible -object Issue1228 { - /* Workaround for https://github.com/freechipsproject/firrtl/pull/1228 */ - abstract class Transform extends firrtl.Transform { - override def name: String = this.getClass.getName - } -} -import Issue1228.Transform -``` - -```scala mdoc:silent -/** A transform that reads InfoAnnotations and prints information about them */ -class InfoTransform() extends Transform with DependencyAPIMigration { - - override def prerequisites = firrtl.stage.Forms.HighForm - - override def execute(state: CircuitState): CircuitState = { - println("Starting transform 'IdentityTransform'") - - val annotationsx = state.annotations.flatMap{ - case InfoAnnotation(a: CircuitTarget, info) => - println(s" - Circuit '${a.serialize}' annotated with '$info'") - None - case InfoAnnotation(a: ModuleTarget, info) => - println(s" - Module '${a.serialize}' annotated with '$info'") - None - case InfoAnnotation(a: InstanceTarget, info) => - println(s" - Instance '${a.serialize}' annotated with '$info'") - None - case InfoAnnotation(a: ReferenceTarget, info) => - println(s" - Component '${a.serialize} annotated with '$info''") - None - case a => - Some(a) - } - - state.copy(annotations = annotationsx) - } -} -``` - -> Note: `inputForm` and `outputForm` will be deprecated in favor of a new dependency API that allows transforms to specify their dependencies more specifically than with circuit forms. -> Full backwards compatibility for `inputForm` and `outputForm` will be maintained, however. - -### Create a Chisel API/Annotator - -Now, define a Chisel API to annotate Chisel things with this `InfoAnnotation`. -This is commonly referred to as an "annotator". - -Here, define an object, `InfoAnnotator` with a method `info` that generates `InfoAnnotation`s. -This uses the `chisel3.experimental.annotate` passed an anonymous `ChiselAnnotation` object. -The need for this `ChiselAnnotation` (which is different from an actual FIRRTL `Annotation`) is that no FIRRTL circuit exists at the time the `info` method is called. -This is delaying the generation of the `InfoAnnotation` until the full circuit is available. - -This annotator also mixes in the `RunFirrtlTransform` trait (abstract in the `transformClass` method) because this annotator, whenever used, should result in the FIRRTL compiler running the custom `InfoTransform`. - -```scala mdoc:silent -object InfoAnnotator { - def info(component: InstanceId, info: String): Unit = { - annotate(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = InfoAnnotation(component.toTarget, info) - def transformClass = classOf[InfoTransform] - }) - } -} -``` - -> Note: there are a number of different approaches to writing an annotator. -> You could use a trait that you mix into a `Module`, an object (like is done above), or any other software approach. -> The specific choice of how you implement this is up to you! - -### Using the Chisel API - -Now, we can use the method `InfoAnnotation.info` to create annotations that associate strings with specific things in a FIRRTL circuit. -Below is a Chisel `Module`, `ModC`, where both the actual module is annotated as well as an output. - -```scala mdoc:silent -class ModC(widthC: Int) extends Module { - val io = IO(new Bundle { - val in = Input(UInt(widthC.W)) - val out = Output(UInt(widthC.W)) - }) - io.out := io.in - - InfoAnnotator.info(this, s"ModC($widthC)") - - InfoAnnotator.info(io.out, s"ModC(ignore param)") -} -``` - -### Running the Compilation - -Compiling this circuit to Verilog will then result in the `InfoTransform` running and the added `println`s showing information about the components annotated. - -```scala mdoc:compile-only -import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation} - -(new ChiselStage).execute(Array.empty, Seq(ChiselGeneratorAnnotation(() => new ModC(4)))) -```