diff options
| author | Chick Markley | 2019-10-18 19:44:08 -0700 |
|---|---|---|
| committer | Adam Izraelevitz | 2019-10-18 19:44:08 -0700 |
| commit | 7b93b0f8c48e39cc9730cf9f91340cf733dadafe (patch) | |
| tree | 3e9666c29d6c9901f221fed4728d05b9fd75067e /chiselFrontend/src/main/scala/chisel3/package.scala | |
| parent | fafd984a923591841917cd4c3a1f4c823dc485b4 (diff) | |
Interval Data Type Support for Chisel (#1210)
Plan to be released with 3.3.
Breaks experimental Range API.
Adds new Interval type and associated support.
This commit adds the following:
- Renamed Range to IntervalRange to avoid name collision with scala Range
- Changed RangeTransform macro to Return an IntervalRange
- Improved error messages on missing comma or decimal
- Added notational support for binary point
- Some formatting cleanup also
- SIntFactory
- Change to use IntervalRange API
- UIntFactory
- UInt from range has custom width computation
- It does not need to deal with lowerbound extending bit requirements
- Code to handle special case of range"[0,0]" to have a width of 1
- IR.scala
- Removed Bound and other constraint code that was duplicating firrtl stuff
- Added new RangeType
- Added IntervalRange class and object
- RangeSpec
- modified just a bit to handle notational differences
- previous range interpolator returned tuple now returns IntervalRange
- Add IntervalType to emitter
- Added IntervalSpec with many tests
- Added ScalaIntervalSimulatorSpec which tests golden model for Interval
- Added ScalaIntervalSimulator which is a golden model for Interval
- This gold may not have been polished to a high sheen
- Add IntervalLit cases to Converter
- Add Interval PrimOps to IR
- asInterval, wrap, squz, clip, setp, decp, incp
- Add IntervalLit class to IR
- Add Interval to MonoConnect
- Add Interval Type to Bits (in experimental package)
- add conversions to Interval from other types
- Add Interval clone stuff to Data
- Add Literal creation helpers to chisel3 package
- these may move to experimental if I can figure that out
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/package.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/package.scala | 222 |
1 files changed, 122 insertions, 100 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/package.scala b/chiselFrontend/src/main/scala/chisel3/package.scala index 51bcf1fe..3af21d57 100644 --- a/chiselFrontend/src/main/scala/chisel3/package.scala +++ b/chiselFrontend/src/main/scala/chisel3/package.scala @@ -1,118 +1,140 @@ // See LICENSE for license details. +import chisel3.internal.firrtl.BinaryPoint + /** This package contains the main chisel3 API. */ package object chisel3 { // scalastyle:ignore package.object.name import internal.firrtl.{Port, Width} - import internal.sourceinfo.{SourceInfo, VecTransform} - import internal.{Builder, chiselRuntimeDeprecated} + import internal.Builder import scala.language.implicitConversions - /** - * 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. - * - * Implementation note: the empty parameter list (like `U()`) is necessary to prevent - * interpreting calls that have a non-Width parameter as a chained apply, otherwise things like - * `0.asUInt(16)` (instead of `16.W`) compile without error and produce undesired results. - */ - implicit class fromBigIntToLiteral(bigint: BigInt) { - /** Int to Bool conversion, allowing compact syntax like 1.B and 0.B - */ - def B: Bool = bigint match { // scalastyle:ignore method.name - case bigint if bigint == 0 => Bool.Lit(false) - case bigint if bigint == 1 => Bool.Lit(true) - case bigint => Builder.error(s"Cannot convert $bigint to Bool, must be 0 or 1"); Bool.Lit(false) - } - /** Int to UInt conversion, recommended style for constants. - */ - def U: UInt = UInt.Lit(bigint, Width()) // scalastyle:ignore method.name - /** Int to SInt conversion, recommended style for constants. - */ - def S: SInt = SInt.Lit(bigint, Width()) // scalastyle:ignore method.name - /** Int to UInt conversion with specified width, recommended style for constants. - */ - def U(width: Width): UInt = UInt.Lit(bigint, width) // scalastyle:ignore method.name - /** Int to SInt conversion with specified width, recommended style for constants. - */ - def S(width: Width): SInt = SInt.Lit(bigint, width) // scalastyle:ignore method.name - - /** Int to UInt conversion, recommended style for variables. - */ - def asUInt(): UInt = UInt.Lit(bigint, Width()) - /** Int to SInt conversion, recommended style for variables. - */ - def asSInt(): SInt = SInt.Lit(bigint, Width()) - /** Int to UInt conversion with specified width, recommended style for variables. - */ - def asUInt(width: Width): UInt = UInt.Lit(bigint, width) - /** Int to SInt conversion with specified width, recommended style for variables. - */ - def asSInt(width: Width): SInt = SInt.Lit(bigint, 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. + * + * Implementation note: the empty parameter list (like `U()`) is necessary to prevent + * interpreting calls that have a non-Width parameter as a chained apply, otherwise things like + * `0.asUInt(16)` (instead of `16.W`) compile without error and produce undesired results. + */ + implicit class fromBigIntToLiteral(bigint: BigInt) { + /** Int to Bool conversion, allowing compact syntax like 1.B and 0.B + */ + def B: Bool = bigint match { // scalastyle:ignore method.name + case bigint if bigint == 0 => Bool.Lit(false) + case bigint if bigint == 1 => Bool.Lit(true) + case bigint => Builder.error(s"Cannot convert $bigint to Bool, must be 0 or 1"); Bool.Lit(false) + } + /** Int to UInt conversion, recommended style for constants. + */ + def U: UInt = UInt.Lit(bigint, Width()) // scalastyle:ignore method.name + /** Int to SInt conversion, recommended style for constants. + */ + def S: SInt = SInt.Lit(bigint, Width()) // scalastyle:ignore method.name + /** Int to UInt conversion with specified width, recommended style for constants. + */ + def U(width: Width): UInt = UInt.Lit(bigint, width) // scalastyle:ignore method.name + /** Int to SInt conversion with specified width, recommended style for constants. + */ + def S(width: Width): SInt = SInt.Lit(bigint, width) // scalastyle:ignore method.name - implicit class fromIntToLiteral(int: Int) extends fromBigIntToLiteral(int) - implicit class fromLongToLiteral(long: Long) extends fromBigIntToLiteral(long) - - implicit class fromStringToLiteral(str: String) { - /** String to UInt parse, recommended style for constants. - */ - def U: UInt = str.asUInt() // scalastyle:ignore method.name - /** String to UInt parse with specified width, recommended style for constants. - */ - def U(width: Width): UInt = str.asUInt(width) // scalastyle:ignore method.name - - /** String to UInt parse, recommended style for variables. - */ - def asUInt(): UInt = { - val bigInt = parse(str) - UInt.Lit(bigInt, Width(bigInt.bitLength max 1)) - } - /** String to UInt parse with specified width, recommended style for variables. - */ - def asUInt(width: Width): UInt = UInt.Lit(parse(str), width) - - protected def parse(n: String) = { - val (base, num) = n.splitAt(1) - val radix = base match { - case "x" | "h" => 16 - case "d" => 10 - case "o" => 8 - case "b" => 2 - case _ => Builder.error(s"Invalid base $base"); 2 - } - BigInt(num.filterNot(_ == '_'), radix) - } - } + /** Int to UInt conversion, recommended style for variables. + */ + def asUInt(): UInt = UInt.Lit(bigint, Width()) + /** Int to SInt conversion, recommended style for variables. + */ + def asSInt(): SInt = SInt.Lit(bigint, Width()) + /** Int to UInt conversion with specified width, recommended style for variables. + */ + def asUInt(width: Width): UInt = UInt.Lit(bigint, width) + /** Int to SInt conversion with specified width, recommended style for variables. + */ + def asSInt(width: Width): SInt = SInt.Lit(bigint, width) + } - implicit class fromBooleanToLiteral(boolean: Boolean) { - /** Boolean to Bool conversion, recommended style for constants. - */ - def B: Bool = Bool.Lit(boolean) // scalastyle:ignore method.name + implicit class fromIntToLiteral(int: Int) extends fromBigIntToLiteral(int) + implicit class fromLongToLiteral(long: Long) extends fromBigIntToLiteral(long) - /** Boolean to Bool conversion, recommended style for variables. - */ - def asBool(): Bool = Bool.Lit(boolean) + implicit class fromStringToLiteral(str: String) { + /** String to UInt parse, recommended style for constants. + */ + def U: UInt = str.asUInt() // scalastyle:ignore method.name + /** String to UInt parse with specified width, recommended style for constants. + */ + def U(width: Width): UInt = str.asUInt(width) // scalastyle:ignore method.name + + /** String to UInt parse, recommended style for variables. + */ + def asUInt(): UInt = { + val bigInt = parse(str) + UInt.Lit(bigInt, Width(bigInt.bitLength max 1)) + } + /** String to UInt parse with specified width, recommended style for variables. + */ + def asUInt(width: Width): UInt = UInt.Lit(parse(str), width) + + protected def parse(n: String): BigInt = { + val (base, num) = n.splitAt(1) + val radix = base match { + case "x" | "h" => 16 + case "d" => 10 + case "o" => 8 + case "b" => 2 + case _ => Builder.error(s"Invalid base $base"); 2 } + BigInt(num.filterNot(_ == '_'), radix) + } + } - // Fixed Point is experimental for now, but we alias the implicit conversion classes here - // to minimize disruption with existing code. - implicit class fromDoubleToLiteral(double: Double) extends experimental.FixedPoint.Implicits.fromDoubleToLiteral(double) - implicit class fromIntToBinaryPoint(int: Int) extends experimental.FixedPoint.Implicits.fromIntToBinaryPoint(int) + implicit class fromIntToBinaryPoint(int: Int) { + def BP: BinaryPoint = BinaryPoint(int) // scalastyle:ignore method.name + } - implicit class fromIntToWidth(int: Int) { - def W: Width = Width(int) // scalastyle:ignore method.name - } + implicit class fromBooleanToLiteral(boolean: Boolean) { + /** Boolean to Bool conversion, recommended style for constants. + */ + def B: Bool = Bool.Lit(boolean) // scalastyle:ignore method.name + + /** Boolean to Bool conversion, recommended style for variables. + */ + def asBool(): Bool = Bool.Lit(boolean) + } + + // Fixed Point is experimental for now, but we alias the implicit conversion classes here + // to minimize disruption with existing code. + implicit class fromDoubleToLiteral(double: Double) + extends experimental.FixedPoint.Implicits.fromDoubleToLiteral(double) + + // Interval is experimental for now, but we alias the implicit conversion classes here + // to minimize disruption with existing code. + implicit class fromIntToLiteralInterval(int: Int) + extends experimental.Interval.Implicits.fromIntToLiteralInterval(int) + + implicit class fromLongToLiteralInterval(long: Long) + extends experimental.Interval.Implicits.fromLongToLiteralInterval(long) + + implicit class fromBigIntToLiteralInterval(bigInt: BigInt) + extends experimental.Interval.Implicits.fromBigIntToLiteralInterval(bigInt) + + implicit class fromDoubleToLiteralInterval(double: Double) + extends experimental.Interval.Implicits.fromDoubleToLiteralInterval(double) + + implicit class fromBigDecimalToLiteralInterval(bigDecimal: BigDecimal) + extends experimental.Interval.Implicits.fromBigDecimalToLiteralInterval(bigDecimal) + + implicit class fromIntToWidth(int: Int) { + def W: Width = Width(int) // scalastyle:ignore method.name + } val WireInit = WireDefault |
