diff options
269 files changed, 9155 insertions, 6892 deletions
diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index db354e1f..15cdf428 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -3,7 +3,7 @@ package chisel3 import chisel3.experimental.VecLiterals.AddVecLiteralConstructor -import chisel3.experimental.dataview.{InvalidViewException, isView, reifySingleData} +import chisel3.experimental.dataview.{isView, reifySingleData, InvalidViewException} import scala.collection.immutable.{SeqMap, VectorMap} import scala.collection.mutable.{HashSet, LinkedHashMap} @@ -34,13 +34,16 @@ sealed abstract class Aggregate extends Data { // show groups of names of fields with duplicate id's // The sorts make the displayed order of fields deterministic and matching the order of occurrence in the Bundle. // It's a bit convoluted but happens rarely and makes the error message easier to understand - val dupNames = duplicates.toSeq.sortBy(_._id).map { duplicate => - b.elements - .collect { case x if x._2._id == duplicate._id => x } - .toSeq.sortBy(_._2._id) - .map(_._1).reverse - .mkString("(", ",", ")") - }.mkString(",") + val dupNames = duplicates.toSeq + .sortBy(_._id) + .map { duplicate => + b.elements.collect { case x if x._2._id == duplicate._id => x }.toSeq + .sortBy(_._2._id) + .map(_._1) + .reverse + .mkString("(", ",", ")") + } + .mkString(",") throw new AliasedAggregateFieldException( s"${b.className} contains aliased fields named ${dupNames}" ) @@ -59,9 +62,10 @@ sealed abstract class Aggregate extends Data { direction = ActualDirection.fromChildren(childDirections, resolvedDirection) match { case Some(dir) => dir case None => - val childWithDirections = getElements zip getElements.map(_.direction) + val childWithDirections = getElements.zip(getElements.map(_.direction)) throw MixedDirectionAggregateException( - s"Aggregate '$this' can't have elements that are both directioned and undirectioned: $childWithDirections") + s"Aggregate '$this' can't have elements that are both directioned and undirectioned: $childWithDirections" + ) } } @@ -76,7 +80,7 @@ sealed abstract class Aggregate extends Data { (accumulator, elt.litOption) match { case (Some(accumulator), Some(eltLit)) => val width = elt.width.get - val masked = ((BigInt(1) << width) - 1) & eltLit // also handles the negative case with two's complement + val masked = ((BigInt(1) << width) - 1) & eltLit // also handles the negative case with two's complement Some((accumulator << width) + masked) case (None, _) => None case (_, None) => None @@ -85,8 +89,7 @@ sealed abstract class Aggregate extends Data { topBindingOpt match { case Some(BundleLitBinding(_)) | Some(VecLitBinding(_)) => - getElements - .reverse + getElements.reverse .foldLeft[Option[BigInt]](Some(BigInt(0)))(shiftAdd) case _ => None } @@ -112,8 +115,12 @@ sealed abstract class Aggregate extends Data { SeqUtils.do_asUInt(flatten.map(_.asUInt())) } - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { var i = 0 val bits = if (that.isLit) that else WireDefault(UInt(this.width), that) // handles width padding for (x <- flatten) { @@ -132,6 +139,7 @@ sealed abstract class Aggregate extends Data { } trait VecFactory extends SourceInfoDoc { + /** Creates a new [[Vec]] with `n` entries of the specified data type. * * @note elements are NOT assigned by default and have no value @@ -144,12 +152,18 @@ trait VecFactory extends SourceInfoDoc { } /** Truncate an index to implement modulo-power-of-2 addressing. */ - private[chisel3] def truncateIndex(idx: UInt, n: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { - val w = (n-1).bitLength + private[chisel3] def truncateIndex( + idx: UInt, + n: BigInt + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): UInt = { + val w = (n - 1).bitLength if (n <= 1) 0.U else if (idx.width.known && idx.width.get <= w) idx - else if (idx.width.known) idx(w-1,0) - else (idx | 0.U(w.W))(w-1,0) + else if (idx.width.known) idx(w - 1, 0) + else (idx | 0.U(w.W))(w - 1, 0) } } @@ -179,14 +193,14 @@ trait VecFactory extends SourceInfoDoc { * - when multiple conflicting assignments are performed on a Vec element, the last one takes effect (unlike Mem, where the result is undefined) * - Vecs, unlike classes in Scala's collection library, are propagated intact to FIRRTL as a vector type, which may make debugging easier */ -sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) - extends Aggregate with VecLike[T] { +sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extends Aggregate with VecLike[T] { override def toString: String = { topBindingOpt match { case Some(VecLitBinding(vecLitBinding)) => - val contents = vecLitBinding.zipWithIndex.map { case ((data, lit), index) => - s"$index=$lit" + val contents = vecLitBinding.zipWithIndex.map { + case ((data, lit), index) => + s"$index=$lit" }.mkString(", ") s"${sample_element.cloneType}[$length]($contents)" case _ => stringAccessor(s"${sample_element.cloneType}[$length]") @@ -196,7 +210,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) private[chisel3] override def typeEquivalent(that: Data): Boolean = that match { case that: Vec[T] => this.length == that.length && - (this.sample_element typeEquivalent that.sample_element) + (this.sample_element.typeEquivalent(that.sample_element)) case _ => false } @@ -206,7 +220,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection) sample_element.bind(SampleElementBinding(this), resolvedDirection) - for (child <- getElements) { // assume that all children are the same + for (child <- getElements) { // assume that all children are the same child.bind(ChildBinding(this), resolvedDirection) } @@ -226,12 +240,12 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) } /** - * sample_element 'tracks' all changes to the elements. - * For consistency, sample_element is always used for creating dynamically - * indexed ports and outputing the FIRRTL type. - * - * Needed specifically for the case when the Vec is length 0. - */ + * sample_element 'tracks' all changes to the elements. + * For consistency, sample_element is always used for creating dynamically + * indexed ports and outputing the FIRRTL type. + * + * Needed specifically for the case when the Vec is length 0. + */ private[chisel3] val sample_element: T = gen // allElements current includes sample_element @@ -245,29 +259,33 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) * * @note the length of this Vec must match the length of the input Seq */ - def <> (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = { + def <>(that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = { if (this.length != that.length) { Builder.error("Vec and Seq being bulk connected have different lengths!") } - for ((a, b) <- this zip that) + for ((a, b) <- this.zip(that)) a <> b } // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def <> (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this bulkConnect that.asInstanceOf[Data] + def <>(that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = + this.bulkConnect(that.asInstanceOf[Data]) /** Strong bulk connect, assigning elements in this Vec from elements in a Seq. * * @note the length of this Vec must match the length of the input Seq */ - def := (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = { - require(this.length == that.length, s"Cannot assign to a Vec of length ${this.length} from a Seq of different length ${that.length}") - for ((a, b) <- this zip that) + def :=(that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = { + require( + this.length == that.length, + s"Cannot assign to a Vec of length ${this.length} from a Seq of different length ${that.length}" + ) + for ((a, b) <- this.zip(that)) a := b } // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def := (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this connect that + def :=(that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: CompileOptions): Unit = this.connect(that) /** Creates a dynamically indexed read or write accessor into the array. */ @@ -284,8 +302,9 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) // Views complicate things a bit, but views that correspond exactly to an identical Vec can just forward the // dynamic indexing to the target Vec // In theory, we could still do this forwarding if the sample element were different by deriving a DataView - case Some(target: Vec[T @unchecked]) if this.length == target.length && - this.sample_element.typeEquivalent(target.sample_element) => + case Some(target: Vec[T @unchecked]) + if this.length == target.length && + this.sample_element.typeEquivalent(target.sample_element) => return target.do_apply(p) case _ => throw InvalidViewException("Dynamic indexing of Views is not yet supported") } @@ -296,7 +315,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) // Reconstruct the resolvedDirection (in Aggregate.bind), since it's not stored. // It may not be exactly equal to that value, but the results are the same. val reconstructedResolvedDirection = direction match { - case ActualDirection.Input => SpecifiedDirection.Input + case ActualDirection.Input => SpecifiedDirection.Input case ActualDirection.Output => SpecifiedDirection.Output case ActualDirection.Bidirectional(ActualDirection.Default) | ActualDirection.Unspecified => SpecifiedDirection.Unspecified @@ -331,7 +350,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) def toPrintable: Printable = { val elts = if (length == 0) List.empty[Printable] - else self flatMap (e => List(e.toPrintable, PString(", "))) dropRight 1 + else self.flatMap(e => List(e.toPrintable, PString(", "))).dropRight(1) PString("Vec(") + Printables(elts) + PString(")") } @@ -354,14 +373,17 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) */ def reduceTree(redOp: (T, T) => T, layerOp: (T) => T): T = macro VecTransform.reduceTree - def do_reduceTree(redOp: (T, T) => T, layerOp: (T) => T = (x: T) => x) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : T = { + def do_reduceTree( + redOp: (T, T) => T, + layerOp: (T) => T = (x: T) => x + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { require(!isEmpty, "Cannot apply reduction on a vec of size 0") - var curLayer : Seq[T] = this + var curLayer: Seq[T] = this while (curLayer.length > 1) { - curLayer = curLayer.grouped(2).map( x => - if (x.length == 1) layerOp(x(0)) else redOp(x(0), x(1)) - ).toSeq + curLayer = curLayer.grouped(2).map(x => if (x.length == 1) layerOp(x(0)) else redOp(x(0), x(1))).toSeq } curLayer(0) } @@ -380,16 +402,21 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) * ) * }}} */ - private[chisel3] def _makeLit(elementInitializers: (Int, T)*)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): this.type = { + private[chisel3] def _makeLit( + elementInitializers: (Int, T)* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): this.type = { def checkLiteralConstruction(): Unit = { - val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap { case (k, v) => - if (v.length > 1) { - Some(k, v.length) - } else { - None - } + val dupKeys = elementInitializers.map { x => x._1 }.groupBy(x => x).flatMap { + case (k, v) => + if (v.length > 1) { + Some(k, v.length) + } else { + None + } } if (dupKeys.nonEmpty) { throw new VecLiteralException( @@ -438,79 +465,96 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) // Create the Vec literal binding from litArgs of arguments val vecLitLinkedMap = new mutable.LinkedHashMap[Data, LitArg]() - elementInitializers.sortBy { case (a, _) => a }.foreach { case (fieldIndex, value) => - val field = clone.apply(fieldIndex) - val fieldName = cloneFields.getOrElse(field, - throw new VecLiteralException(s"field $field (with value $value) is not a field," + - s" ensure the field is specified as a function returning a field on an object of class ${this.getClass}," + - s" eg '_.a' to select hypothetical bundle field 'a'") - ) - - val valueBinding = value.topBindingOpt match { - case Some(litBinding: LitBinding) => litBinding - case _ => throw new VecLiteralException(s"field $fieldIndex specified with non-literal value $value") - } + elementInitializers.sortBy { case (a, _) => a }.foreach { + case (fieldIndex, value) => + val field = clone.apply(fieldIndex) + val fieldName = cloneFields.getOrElse( + field, + throw new VecLiteralException( + s"field $field (with value $value) is not a field," + + s" ensure the field is specified as a function returning a field on an object of class ${this.getClass}," + + s" eg '_.a' to select hypothetical bundle field 'a'" + ) + ) - field match { // Get the litArg(s) for this field - case bitField: Bits => - if (!field.typeEquivalent(bitField)) { - throw new VecLiteralException( - s"VecLit: Literal specified at index $fieldIndex ($value) does not match Vec type $sample_element" - ) - } - if (bitField.getWidth > field.getWidth) { - throw new VecLiteralException( - s"VecLit: Literal specified at index $fieldIndex ($value) is too wide for Vec type $sample_element" - ) - } - val litArg = valueBinding match { - case ElementLitBinding(litArg) => litArg - case BundleLitBinding(litMap) => litMap.getOrElse(value, - throw new BundleLiteralException(s"Field $fieldName specified with unspecified value") - ) - case VecLitBinding(litMap) => litMap.getOrElse(value, - throw new VecLiteralException(s"Field $fieldIndex specified with unspecified value")) - } - val adjustedLitArg = litArg.cloneWithWidth(sample_element.width) - vecLitLinkedMap(bitField) = adjustedLitArg + val valueBinding = value.topBindingOpt match { + case Some(litBinding: LitBinding) => litBinding + case _ => throw new VecLiteralException(s"field $fieldIndex specified with non-literal value $value") + } - case recordField: Record => - if (!(recordField.typeEquivalent(value))) { - throw new VecLiteralException(s"field $fieldIndex $recordField specified with non-type-equivalent value $value") - } - // Copy the source BundleLitBinding with fields (keys) remapped to the clone - val remap = getMatchedFields(value, recordField).toMap - valueBinding.asInstanceOf[BundleLitBinding].litMap.map { case (valueField, valueValue) => - vecLitLinkedMap(remap(valueField)) = valueValue - } + field match { // Get the litArg(s) for this field + case bitField: Bits => + if (!field.typeEquivalent(bitField)) { + throw new VecLiteralException( + s"VecLit: Literal specified at index $fieldIndex ($value) does not match Vec type $sample_element" + ) + } + if (bitField.getWidth > field.getWidth) { + throw new VecLiteralException( + s"VecLit: Literal specified at index $fieldIndex ($value) is too wide for Vec type $sample_element" + ) + } + val litArg = valueBinding match { + case ElementLitBinding(litArg) => litArg + case BundleLitBinding(litMap) => + litMap.getOrElse( + value, + throw new BundleLiteralException(s"Field $fieldName specified with unspecified value") + ) + case VecLitBinding(litMap) => + litMap.getOrElse( + value, + throw new VecLiteralException(s"Field $fieldIndex specified with unspecified value") + ) + } + val adjustedLitArg = litArg.cloneWithWidth(sample_element.width) + vecLitLinkedMap(bitField) = adjustedLitArg + + case recordField: Record => + if (!(recordField.typeEquivalent(value))) { + throw new VecLiteralException( + s"field $fieldIndex $recordField specified with non-type-equivalent value $value" + ) + } + // Copy the source BundleLitBinding with fields (keys) remapped to the clone + val remap = getMatchedFields(value, recordField).toMap + valueBinding.asInstanceOf[BundleLitBinding].litMap.map { + case (valueField, valueValue) => + vecLitLinkedMap(remap(valueField)) = valueValue + } - case vecField: Vec[_] => - if (!(vecField typeEquivalent value)) { - throw new VecLiteralException(s"field $fieldIndex $vecField specified with non-type-equivalent value $value") - } - // Copy the source VecLitBinding with vecFields (keys) remapped to the clone - val remap = getMatchedFields(value, vecField).toMap - value.topBinding.asInstanceOf[VecLitBinding].litMap.map { case (valueField, valueValue) => - vecLitLinkedMap(remap(valueField)) = valueValue - } + case vecField: Vec[_] => + if (!(vecField.typeEquivalent(value))) { + throw new VecLiteralException( + s"field $fieldIndex $vecField specified with non-type-equivalent value $value" + ) + } + // Copy the source VecLitBinding with vecFields (keys) remapped to the clone + val remap = getMatchedFields(value, vecField).toMap + value.topBinding.asInstanceOf[VecLitBinding].litMap.map { + case (valueField, valueValue) => + vecLitLinkedMap(remap(valueField)) = valueValue + } - case enumField: EnumType => { - if (!(enumField typeEquivalent value)) { - throw new VecLiteralException(s"field $fieldIndex $enumField specified with non-type-equivalent enum value $value") - } - val litArg = valueBinding match { - case ElementLitBinding(litArg) => litArg - case _ => - throw new VecLiteralException(s"field $fieldIndex $enumField could not bematched with $valueBinding") + case enumField: EnumType => { + if (!(enumField.typeEquivalent(value))) { + throw new VecLiteralException( + s"field $fieldIndex $enumField specified with non-type-equivalent enum value $value" + ) + } + val litArg = valueBinding match { + case ElementLitBinding(litArg) => litArg + case _ => + throw new VecLiteralException(s"field $fieldIndex $enumField could not bematched with $valueBinding") + } + vecLitLinkedMap(field) = litArg } - vecLitLinkedMap(field) = litArg - } - case _ => throw new VecLiteralException(s"unsupported field $fieldIndex of type $field") - } + case _ => throw new VecLiteralException(s"unsupported field $fieldIndex of type $field") + } } - clone.bind(VecLitBinding(VectorMap(vecLitLinkedMap.toSeq:_*))) + clone.bind(VecLitBinding(VectorMap(vecLitLinkedMap.toSeq: _*))) clone } } @@ -519,7 +563,12 @@ object VecInit extends SourceInfoDoc { /** Gets the correct connect operation (directed hardware assign or bulk connect) for element in Vec. */ - private def getConnectOpFromDirectionality[T <: Data](proto: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): (T, T) => Unit = proto.direction match { + private def getConnectOpFromDirectionality[T <: Data]( + proto: T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): (T, T) => Unit = proto.direction match { case ActualDirection.Input | ActualDirection.Output | ActualDirection.Unspecified => // When internal wires are involved, driver / sink must be specified explicitly, otherwise // the system is unable to infer which is driver / sink @@ -557,8 +606,8 @@ object VecInit extends SourceInfoDoc { val vec = Wire(Vec(elts.length, cloneSupertype(elts, "Vec"))) val op = getConnectOpFromDirectionality(vec.head) - - (vec zip elts).foreach{ x => + + (vec.zip(elts)).foreach { x => op(x._1, x._2) } vec @@ -589,7 +638,13 @@ object VecInit extends SourceInfoDoc { def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate /** @group SourceInfoTransformMacro */ - def do_tabulate[T <: Data](n: Int)(gen: (Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = + def do_tabulate[T <: Data]( + n: Int + )(gen: (Int) => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[T] = apply((0 until n).map(i => gen(i))) /** Creates a new 2D [[Vec]] of length `n by m` composed of the results of the given @@ -604,24 +659,31 @@ object VecInit extends SourceInfoDoc { def tabulate[T <: Data](n: Int, m: Int)(gen: (Int, Int) => T): Vec[Vec[T]] = macro VecTransform.tabulate2D /** @group SourceInfoTransformMacro */ - def do_tabulate[T <: Data](n: Int, m: Int)(gen: (Int, Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[Vec[T]] = { + def do_tabulate[T <: Data]( + n: Int, + m: Int + )(gen: (Int, Int) => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[Vec[T]] = { // TODO make this lazy (requires LazyList and cross compilation, beyond the scope of this PR) val elts = Seq.tabulate(n, m)(gen) val flatElts = elts.flatten require(flatElts.nonEmpty, "Vec hardware values are not allowed to be empty") flatElts.foreach(requireIsHardware(_, "vec element")) - + val tpe = cloneSupertype(flatElts, "Vec.tabulate") val myVec = Wire(Vec(n, Vec(m, tpe))) val op = getConnectOpFromDirectionality(myVec.head.head) - for ( - (xs1D, ys1D) <- myVec zip elts; - (x, y) <- xs1D zip ys1D - ) { - op(x, y) + for { + (xs1D, ys1D) <- myVec.zip(elts) + (x, y) <- xs1D.zip(ys1D) + } { + op(x, y) } - myVec + myVec } /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the results of the given @@ -633,39 +695,48 @@ object VecInit extends SourceInfoDoc { * @param gen function that takes in an Int (the index) and returns a * [[Data]] that becomes the output element */ - def tabulate[T <: Data](n: Int, m: Int, p: Int)(gen: (Int, Int, Int) => T): Vec[Vec[Vec[T]]] = macro VecTransform.tabulate3D + def tabulate[T <: Data](n: Int, m: Int, p: Int)(gen: (Int, Int, Int) => T): Vec[Vec[Vec[T]]] = + macro VecTransform.tabulate3D /** @group SourceInfoTransformMacro */ - def do_tabulate[T <: Data](n: Int, m: Int, p: Int)(gen: (Int, Int, Int) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[Vec[Vec[T]]] = { - // TODO make this lazy (requires LazyList and cross compilation, beyond the scope of this PR) + def do_tabulate[T <: Data]( + n: Int, + m: Int, + p: Int + )(gen: (Int, Int, Int) => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[Vec[Vec[T]]] = { + // TODO make this lazy (requires LazyList and cross compilation, beyond the scope of this PR) val elts = Seq.tabulate(n, m, p)(gen) val flatElts = elts.flatten.flatten require(flatElts.nonEmpty, "Vec hardware values are not allowed to be empty") flatElts.foreach(requireIsHardware(_, "vec element")) - + val tpe = cloneSupertype(flatElts, "Vec.tabulate") val myVec = Wire(Vec(n, Vec(m, Vec(p, tpe)))) val op = getConnectOpFromDirectionality(myVec.head.head.head) - - for ( - (xs2D, ys2D) <- myVec zip elts; - (xs1D, ys1D) <- xs2D zip ys2D; - (x, y) <- xs1D zip ys1D - ) { - op(x, y) + + for { + (xs2D, ys2D) <- myVec.zip(elts) + (xs1D, ys1D) <- xs2D.zip(ys2D) + (x, y) <- xs1D.zip(ys1D) + } { + op(x, y) } myVec } /** Creates a new [[Vec]] of length `n` composed of the result of the given - * function applied to an element of data type T. - * - * @param n number of elements in the vector - * @param gen function that takes in an element T and returns an output - * element of the same type - */ + * function applied to an element of data type T. + * + * @param n number of elements in the vector + * @param gen function that takes in an element T and returns an output + * element of the same type + */ def fill[T <: Data](n: Int)(gen: => T): Vec[T] = macro VecTransform.fill /** @group SourceInfoTransformMacro */ @@ -673,49 +744,71 @@ object VecInit extends SourceInfoDoc { apply(Seq.fill(n)(gen)) /** Creates a new 2D [[Vec]] of length `n by m` composed of the result of the given - * function applied to an element of data type T. - * - * @param n number of inner vectors (rows) in the outer vector - * @param m number of elements in each inner vector (column) - * @param gen function that takes in an element T and returns an output - * element of the same type - */ + * function applied to an element of data type T. + * + * @param n number of inner vectors (rows) in the outer vector + * @param m number of elements in each inner vector (column) + * @param gen function that takes in an element T and returns an output + * element of the same type + */ def fill[T <: Data](n: Int, m: Int)(gen: => T): Vec[Vec[T]] = macro VecTransform.fill2D /** @group SourceInfoTransformMacro */ - def do_fill[T <: Data](n: Int, m: Int)(gen: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[Vec[T]] = { + def do_fill[T <: Data]( + n: Int, + m: Int + )(gen: => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[Vec[T]] = { do_tabulate(n, m)((_, _) => gen) } /** Creates a new 3D [[Vec]] of length `n by m by p` composed of the result of the given - * function applied to an element of data type T. - * - * @param n number of 2D vectors inside outer vector - * @param m number of 1D vectors in each 2D vector - * @param p number of elements in each 1D vector - * @param gen function that takes in an element T and returns an output - * element of the same type - */ + * function applied to an element of data type T. + * + * @param n number of 2D vectors inside outer vector + * @param m number of 1D vectors in each 2D vector + * @param p number of elements in each 1D vector + * @param gen function that takes in an element T and returns an output + * element of the same type + */ def fill[T <: Data](n: Int, m: Int, p: Int)(gen: => T): Vec[Vec[Vec[T]]] = macro VecTransform.fill3D /** @group SourceInfoTransformMacro */ - def do_fill[T <: Data](n: Int, m: Int, p: Int)(gen: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[Vec[Vec[T]]] = { + def do_fill[T <: Data]( + n: Int, + m: Int, + p: Int + )(gen: => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[Vec[Vec[T]]] = { do_tabulate(n, m, p)((_, _, _) => gen) } - + /** Creates a new [[Vec]] of length `n` composed of the result of the given - * function applied to an element of data type T. - * - * @param start First element in the Vec - * @param len Lenth of elements in the Vec - * @param f Function that applies the element T from previous index and returns the output - * element to the next index - */ + * function applied to an element of data type T. + * + * @param start First element in the Vec + * @param len Lenth of elements in the Vec + * @param f Function that applies the element T from previous index and returns the output + * element to the next index + */ def iterate[T <: Data](start: T, len: Int)(f: (T) => T): Vec[T] = macro VecTransform.iterate - + /** @group SourceInfoTransformMacro */ - def do_iterate[T <: Data](start: T, len: Int)(f: (T) => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = - apply(Seq.iterate(start, len)(f)) + def do_iterate[T <: Data]( + start: T, + len: Int + )(f: (T) => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[T] = + apply(Seq.iterate(start, len)(f)) } /** A trait for [[Vec]]s containing common hardware generators for collection @@ -737,7 +830,7 @@ trait VecLike[T <: Data] extends IndexedSeq[T] with HasId with SourceInfoDoc { /** @group SourceInfoTransformMacro */ def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = - (this map p).fold(true.B)(_ && _) + (this.map(p)).fold(true.B)(_ && _) /** Outputs true if p outputs true for at least one element. */ @@ -745,7 +838,7 @@ trait VecLike[T <: Data] extends IndexedSeq[T] with HasId with SourceInfoDoc { /** @group SourceInfoTransformMacro */ def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = - (this map p).fold(false.B)(_ || _) + (this.map(p)).fold(false.B)(_ || _) /** Outputs true if the vector contains at least one element equal to x (using * the === operator). @@ -762,12 +855,12 @@ trait VecLike[T <: Data] extends IndexedSeq[T] with HasId with SourceInfoDoc { /** @group SourceInfoTransformMacro */ def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - SeqUtils.count(this map p) + SeqUtils.count(this.map(p)) /** Helper function that appends an index (literal value) to each element, * useful for hardware generators which output an index. */ - private def indexWhereHelper(p: T => Bool) = this map p zip (0 until length).map(i => i.asUInt) + private def indexWhereHelper(p: T => Bool) = this.map(p).zip((0 until length).map(i => i.asUInt)) /** Outputs the index of the first element for which p outputs true. */ @@ -816,19 +909,19 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog // which can cause collisions val _namespace = Namespace.empty - for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk=true)) } + for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk = true)) } } private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = { try { super.bind(target, parentDirection) - } catch { // nasty compatibility mode shim, where anything flies + } catch { // nasty compatibility mode shim, where anything flies case e: MixedDirectionAggregateException if !compileOptions.dontAssumeDirectionality => val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection) direction = resolvedDirection match { case SpecifiedDirection.Unspecified => ActualDirection.Bidirectional(ActualDirection.Default) - case SpecifiedDirection.Flip => ActualDirection.Bidirectional(ActualDirection.Flipped) - case _ => ActualDirection.Bidirectional(ActualDirection.Default) + case SpecifiedDirection.Flip => ActualDirection.Bidirectional(ActualDirection.Flipped) + case _ => ActualDirection.Bidirectional(ActualDirection.Default) } } setElementRefs() @@ -861,67 +954,85 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio val cloneFields = getRecursiveFields(clone, "(bundle root)").toMap // Create the Bundle literal binding from litargs of arguments - val bundleLitMap = elems.map { fn => fn(clone) }.flatMap { case (field, value) => - val fieldName = cloneFields.getOrElse(field, - throw new BundleLiteralException(s"field $field (with value $value) is not a field," + - s" ensure the field is specified as a function returning a field on an object of class ${this.getClass}," + - s" eg '_.a' to select hypothetical bundle field 'a'") - ) - val valueBinding = value.topBindingOpt match { - case Some(litBinding: LitBinding) => litBinding - case _ => throw new BundleLiteralException(s"field $fieldName specified with non-literal value $value") - } + val bundleLitMap = elems.map { fn => fn(clone) }.flatMap { + case (field, value) => + val fieldName = cloneFields.getOrElse( + field, + throw new BundleLiteralException( + s"field $field (with value $value) is not a field," + + s" ensure the field is specified as a function returning a field on an object of class ${this.getClass}," + + s" eg '_.a' to select hypothetical bundle field 'a'" + ) + ) + val valueBinding = value.topBindingOpt match { + case Some(litBinding: LitBinding) => litBinding + case _ => throw new BundleLiteralException(s"field $fieldName specified with non-literal value $value") + } - field match { // Get the litArg(s) for this field - case field: Bits => - if (field.getClass != value.getClass) { // TODO typeEquivalent is too strict because it checks width - throw new BundleLiteralException(s"Field $fieldName $field specified with non-type-equivalent value $value") - } - val litArg = valueBinding match { - case ElementLitBinding(litArg) => litArg - case BundleLitBinding(litMap) => litMap.getOrElse(value, - throw new BundleLiteralException(s"Field $fieldName specified with unspecified value") - ) - case VecLitBinding(litMap) => litMap.getOrElse(value, - throw new VecLiteralException(s"Vec literal $fieldName specified with out literal values") - ) + field match { // Get the litArg(s) for this field + case field: Bits => + if (field.getClass != value.getClass) { // TODO typeEquivalent is too strict because it checks width + throw new BundleLiteralException( + s"Field $fieldName $field specified with non-type-equivalent value $value" + ) + } + val litArg = valueBinding match { + case ElementLitBinding(litArg) => litArg + case BundleLitBinding(litMap) => + litMap.getOrElse( + value, + throw new BundleLiteralException(s"Field $fieldName specified with unspecified value") + ) + case VecLitBinding(litMap) => + litMap.getOrElse( + value, + throw new VecLiteralException(s"Vec literal $fieldName specified with out literal values") + ) - } - Seq(field -> litArg) + } + Seq(field -> litArg) - case field: Record => - if (!(field typeEquivalent value)) { - throw new BundleLiteralException(s"field $fieldName $field specified with non-type-equivalent value $value") - } - // Copy the source BundleLitBinding with fields (keys) remapped to the clone - val remap = getMatchedFields(value, field).toMap - value.topBinding.asInstanceOf[BundleLitBinding].litMap.map { case (valueField, valueValue) => - remap(valueField) -> valueValue - } + case field: Record => + if (!(field.typeEquivalent(value))) { + throw new BundleLiteralException( + s"field $fieldName $field specified with non-type-equivalent value $value" + ) + } + // Copy the source BundleLitBinding with fields (keys) remapped to the clone + val remap = getMatchedFields(value, field).toMap + value.topBinding.asInstanceOf[BundleLitBinding].litMap.map { + case (valueField, valueValue) => + remap(valueField) -> valueValue + } - case vecField: Vec[_] => - if (!(vecField typeEquivalent value)) { - throw new BundleLiteralException(s"field $fieldName $vecField specified with non-type-equivalent value $value") - } - // Copy the source BundleLitBinding with fields (keys) remapped to the clone - val remap = getMatchedFields(value, vecField).toMap - value.topBinding.asInstanceOf[VecLitBinding].litMap.map { case (valueField, valueValue) => - remap(valueField) -> valueValue - } + case vecField: Vec[_] => + if (!(vecField.typeEquivalent(value))) { + throw new BundleLiteralException( + s"field $fieldName $vecField specified with non-type-equivalent value $value" + ) + } + // Copy the source BundleLitBinding with fields (keys) remapped to the clone + val remap = getMatchedFields(value, vecField).toMap + value.topBinding.asInstanceOf[VecLitBinding].litMap.map { + case (valueField, valueValue) => + remap(valueField) -> valueValue + } - case field: EnumType => { - if (!(field typeEquivalent value)) { - throw new BundleLiteralException(s"field $fieldName $field specified with non-type-equivalent enum value $value") - } - val litArg = valueBinding match { - case ElementLitBinding(litArg) => litArg - case _ => - throw new BundleLiteralException(s"field $fieldName $field could not be matched with $valueBinding") + case field: EnumType => { + if (!(field.typeEquivalent(value))) { + throw new BundleLiteralException( + s"field $fieldName $field specified with non-type-equivalent enum value $value" + ) + } + val litArg = valueBinding match { + case ElementLitBinding(litArg) => litArg + case _ => + throw new BundleLiteralException(s"field $fieldName $field could not be matched with $valueBinding") + } + Seq(field -> litArg) } - Seq(field -> litArg) + case _ => throw new BundleLiteralException(s"unsupported field $fieldName of type $field") } - case _ => throw new BundleLiteralException(s"unsupported field $fieldName of type $field") - } } // don't convert to a Map yet to preserve duplicate keys @@ -952,8 +1063,9 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio override def toString: String = { topBindingOpt match { case Some(BundleLitBinding(_)) => - val contents = elements.toList.reverse.map { case (name, data) => - s"$name=$data" + val contents = elements.toList.reverse.map { + case (name, data) => + s"$name=$data" }.mkString(", ") s"$className($contents)" case _ => stringAccessor(s"$className") @@ -968,10 +1080,12 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio private[chisel3] override def typeEquivalent(that: Data): Boolean = that match { case that: Record => this.getClass == that.getClass && - this.elements.size == that.elements.size && - this.elements.forall{case (name, model) => - that.elements.contains(name) && - (that.elements(name) typeEquivalent model)} + this.elements.size == that.elements.size && + this.elements.forall { + case (name, model) => + that.elements.contains(name) && + (that.elements(name).typeEquivalent(model)) + } case _ => false } @@ -990,11 +1104,14 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio private[chisel3] def toPrintableHelper(elts: Seq[(String, Data)]): Printable = { val xs = if (elts.isEmpty) List.empty[Printable] // special case because of dropRight below - else elts flatMap { case (name, data) => - List(PString(s"$name -> "), data.toPrintable, PString(", ")) - } dropRight 1 // Remove trailing ", " + else + elts.flatMap { + case (name, data) => + List(PString(s"$name -> "), data.toPrintable, PString(", ")) + }.dropRight(1) // Remove trailing ", " PString(s"$className(") + Printables(xs) + PString(")") } + /** Default "pretty-print" implementation * Analogous to printing a Map * Results in "`\$className(elt0.name -> elt0.value, ...)`" @@ -1060,15 +1177,18 @@ package experimental { * }}} */ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { - assert(_usingPlugin, "The Chisel compiler plugin is now required for compiling Chisel code. " + - "Please see https://github.com/chipsalliance/chisel3#build-your-own-chisel-projects." + assert( + _usingPlugin, + "The Chisel compiler plugin is now required for compiling Chisel code. " + + "Please see https://github.com/chipsalliance/chisel3#build-your-own-chisel-projects." ) override def className: String = this.getClass.getSimpleName match { - case name if name.startsWith("$anon$") => "AnonymousBundle" // fallback for anonymous Bundle case - case "" => "AnonymousBundle" // ditto, but on other platforms - case name => name + case name if name.startsWith("$anon$") => "AnonymousBundle" // fallback for anonymous Bundle case + case "" => "AnonymousBundle" // ditto, but on other platforms + case name => name } + /** The collection of [[Data]] * * Elements defined earlier in the Bundle are higher order upon @@ -1093,7 +1213,7 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { getBundleField(m) match { case Some(d: Data) => requireIsChiselType(d) - + if (nameMap contains m.getName) { require(nameMap(m.getName) eq d) } else { @@ -1102,21 +1222,25 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { case None => if (!ignoreSeq) { m.invoke(this) match { - case s: scala.collection.Seq[Any] if s.nonEmpty => s.head match { - // Ignore empty Seq() - case d: Data => throwException("Public Seq members cannot be used to define Bundle elements " + - s"(found public Seq member '${m.getName}'). " + - "Either use a Vec if all elements are of the same type, or MixedVec if the elements " + - "are of different types. If this Seq member is not intended to construct RTL, mix in the trait " + - "IgnoreSeqInBundle.") - case _ => // don't care about non-Data Seq - } + case s: scala.collection.Seq[Any] if s.nonEmpty => + s.head match { + // Ignore empty Seq() + case d: Data => + throwException( + "Public Seq members cannot be used to define Bundle elements " + + s"(found public Seq member '${m.getName}'). " + + "Either use a Vec if all elements are of the same type, or MixedVec if the elements " + + "are of different types. If this Seq member is not intended to construct RTL, mix in the trait " + + "IgnoreSeqInBundle." + ) + case _ => // don't care about non-Data Seq + } case _ => // not a Seq } } } } - VectorMap(nameMap.toSeq sortWith { case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) }: _*) + VectorMap(nameMap.toSeq.sortWith { case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) }: _*) } /** @@ -1145,10 +1269,10 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { if (clone.elements(name) eq field) { throw new AutoClonetypeException( s"Automatically cloned $clone has field '$name' aliased with base $this." + - " In the future, this will be solved automatically by the compiler plugin." + - " For now, ensure Chisel types used in the Bundle definition are passed through constructor arguments," + - " or wrapped in Input(...), Output(...), or Flipped(...) if appropriate." + - " As a last resort, you can override cloneType manually." + " In the future, this will be solved automatically by the compiler plugin." + + " For now, ensure Chisel types used in the Bundle definition are passed through constructor arguments," + + " or wrapped in Input(...), Output(...), or Flipped(...) if appropriate." + + " As a last resort, you can override cloneType manually." ) } } @@ -1166,7 +1290,9 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { * @note This is overridden by the compiler plugin (this implementation is never called) */ protected def _cloneTypeImpl: Bundle = { - throwException(s"Internal Error! This should have been implemented by the chisel3-plugin. Please file an issue against chisel3") + throwException( + s"Internal Error! This should have been implemented by the chisel3-plugin. Please file an issue against chisel3" + ) } /** Default "pretty-print" implementation @@ -1177,4 +1303,3 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { */ override def toPrintable: Printable = toPrintableHelper(elements.toList.reverse) } - diff --git a/core/src/main/scala/chisel3/Annotation.scala b/core/src/main/scala/chisel3/Annotation.scala index 545ea480..e08557eb 100644 --- a/core/src/main/scala/chisel3/Annotation.scala +++ b/core/src/main/scala/chisel3/Annotation.scala @@ -15,6 +15,7 @@ import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation} * Defines a conversion to a corresponding FIRRTL Annotation */ trait ChiselAnnotation { + /** Conversion to FIRRTL Annotation */ def toFirrtl: Annotation } @@ -54,7 +55,7 @@ object annotate { * m.io.out * } * - *class AdderTester extends Module + * class AdderTester extends Module * with ConstantPropagationTest { * val io = IO(new Bundle { * val a = Input(UInt(32.W)) @@ -73,12 +74,13 @@ object annotate { */ object doNotDedup { + /** Marks a module to be ignored in Dedup Transform in Firrtl * * @param module The module to be marked * @return Unmodified signal `module` */ - def apply[T <: RawModule](module: T)(implicit compileOptions: CompileOptions): Unit = { + def apply[T <: RawModule](module: T)(implicit compileOptions: CompileOptions): Unit = { annotate(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(module.toNamed) }) } } diff --git a/core/src/main/scala/chisel3/Attach.scala b/core/src/main/scala/chisel3/Attach.scala index 0e005690..5c9cfe53 100644 --- a/core/src/main/scala/chisel3/Attach.scala +++ b/core/src/main/scala/chisel3/Attach.scala @@ -43,4 +43,3 @@ object attach { } } } - diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala index 5ab04d13..8a616d02 100644 --- a/core/src/main/scala/chisel3/Bits.scala +++ b/core/src/main/scala/chisel3/Bits.scala @@ -8,13 +8,11 @@ import chisel3.experimental.{FixedPoint, Interval} import chisel3.internal._ import chisel3.internal.Builder.pushOp import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform, - UIntTransform} +import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform, UIntTransform} import chisel3.internal.firrtl.PrimOp._ import _root_.firrtl.{ir => firrtlir} import _root_.firrtl.{constraint => firrtlconstraint} - /** Exists to unify common interfaces of [[Bits]] and [[Reset]]. * * @note This is a workaround because macros cannot override abstract methods. @@ -27,7 +25,10 @@ private[chisel3] sealed trait ToBoolable extends Element { */ final def asBool: Bool = macro SourceInfoWhiteboxTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asBool(dummy: Int*): Bool = macro SourceInfoWhiteboxTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -82,7 +83,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi /** @group SourceInfoTransformMacro */ def do_head(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { width match { - case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n") + case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n") case UnknownWidth() => } binop(sourceInfo, UInt(Width(n)), HeadOp, n) @@ -217,7 +218,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi /** @group SourceInfoTransformMacro */ def do_pad(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = this.width match { case KnownWidth(w) if w >= that => this - case _ => binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that) + case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that) } /** Bitwise inversion operator @@ -227,11 +228,14 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi */ final def unary_~ : Bits = macro SourceInfoWhiteboxTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_~(dummy: Int*): Bits = macro SourceInfoWhiteboxTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Static left shift operator * @@ -242,10 +246,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi */ // REVIEW TODO: redundant // REVIEW TODO: should these return this.type or Bits? - final def << (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def <<(that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Static left shift operator * @@ -254,10 +258,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * $sumWidthInt * @group Bitwise */ - final def << (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def <<(that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Dynamic left shift operator * @@ -266,10 +270,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * @note The width of the returned $coll is `width of this + pow(2, width of that) - 1`. * @group Bitwise */ - final def << (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def <<(that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Static right shift operator * @@ -279,10 +283,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * @group Bitwise */ // REVIEW TODO: redundant - final def >> (that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def >>(that: BigInt): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Static right shift operator * @@ -291,10 +295,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * $unchangedWidth * @group Bitwise */ - final def >> (that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def >>(that: Int): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Dynamic right shift operator * @@ -304,15 +308,18 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * $unchangedWidth * @group Bitwise */ - final def >> (that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg + final def >>(that: UInt): Bits = macro SourceInfoWhiteboxTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits + def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bits /** Returns the contents of this wire as a [[scala.collection.Seq]] of [[Bool]]. */ final def asBools: Seq[Bool] = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asBools(dummy: Int*): Seq[Bool] = macro SourceInfoWhiteboxTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -326,7 +333,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi */ final def asSInt: SInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asSInt(dummy: Int*): SInt = macro SourceInfoWhiteboxTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -341,7 +351,12 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi final def asFixedPoint(that: BinaryPoint): FixedPoint = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_asFixedPoint(that: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + def do_asFixedPoint( + that: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): FixedPoint = { throwException(s"Cannot call .asFixedPoint on $this") } @@ -360,7 +375,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi final def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { width match { case KnownWidth(1) => this(0) - case _ => throwException(s"can't covert ${this.getClass.getSimpleName}$width to Bool") + case _ => throwException(s"can't covert ${this.getClass.getSimpleName}$width to Bool") } } @@ -371,10 +386,10 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi * $sumWidth * @group Bitwise */ - final def ## (that: Bits): UInt = macro SourceInfoTransform.thatArg + final def ##(that: Bits): UInt = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_## (that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { + def do_##(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { val w = this.width + that.width pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref)) } @@ -401,7 +416,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U override def toString: String = { litOption match { case Some(value) => s"UInt$width($value)" - case _ => stringAccessor(s"UInt$width") + case _ => stringAccessor(s"UInt$width") } } @@ -420,7 +435,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def unary_- : UInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-(dummy: Int*): UInt = macro SourceInfoTransform.noArgDummy /** Unary negation (constant width) @@ -431,21 +449,25 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def unary_-% : UInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_%(dummy: Int*): UInt = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : UInt = 0.U - this + def do_unary_-(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = 0.U - this + /** @group SourceInfoTransformMacro */ - def do_unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = 0.U -% this + def do_unary_-%(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = 0.U -% this - override def do_+ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this +% that - override def do_- (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this -% that - override def do_/ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_+(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this +% that + override def do_-(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this -% that + override def do_/(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width), DivideOp, that) - override def do_% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - binop(sourceInfo, UInt(this.width min that.width), RemOp, that) - override def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_%(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + binop(sourceInfo, UInt(this.width.min(that.width)), RemOp, that) + override def do_*(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width + that.width), TimesOp, that) /** Multiplication operator @@ -456,9 +478,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $singleCycleMul * @group Arithmetic */ - final def * (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def *(that: SInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ - def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = that * this + def do_*(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = that * this /** Addition operator (expanding width) * @@ -467,7 +490,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidthPlusOne * @group Arithmetic */ - final def +& (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def +&(that: UInt): UInt = macro SourceInfoTransform.thatArg /** Addition operator (constant width) * @@ -476,7 +499,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidth * @group Arithmetic */ - final def +% (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def +%(that: UInt): UInt = macro SourceInfoTransform.thatArg /** Subtraction operator (increasing width) * @@ -485,7 +508,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidthPlusOne * @group Arithmetic */ - final def -& (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def -&(that: UInt): UInt = macro SourceInfoTransform.thatArg /** Subtraction operator (constant width) * @@ -494,20 +517,23 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidth * @group Arithmetic */ - final def -% (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def -%(that: UInt): UInt = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_+& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - binop(sourceInfo, UInt((this.width max that.width) + 1), AddOp, that) + def do_+&(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + binop(sourceInfo, UInt((this.width.max(that.width)) + 1), AddOp, that) + /** @group SourceInfoTransformMacro */ - def do_+% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + def do_+%(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = (this +& that).tail(1) + /** @group SourceInfoTransformMacro */ - def do_-& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - (this subtractAsSInt that).asUInt + def do_-&(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + (this.subtractAsSInt(that)).asUInt + /** @group SourceInfoTransformMacro */ - def do_-% (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - (this subtractAsSInt that).tail(1) + def do_-%(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + (this.subtractAsSInt(that)).tail(1) /** Bitwise and operator * @@ -516,7 +542,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidth * @group Bitwise */ - final def & (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def &(that: UInt): UInt = macro SourceInfoTransform.thatArg /** Bitwise or operator * @@ -525,7 +551,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidth * @group Bitwise */ - final def | (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def |(that: UInt): UInt = macro SourceInfoTransform.thatArg /** Bitwise exclusive or (xor) operator * @@ -534,23 +560,25 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * $maxWidth * @group Bitwise */ - final def ^ (that: UInt): UInt = macro SourceInfoTransform.thatArg + final def ^(that: UInt): UInt = macro SourceInfoTransform.thatArg // override def abs: UInt = macro SourceInfoTransform.noArgDummy def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this /** @group SourceInfoTransformMacro */ - def do_& (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that) + def do_&(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitAndOp, that) + /** @group SourceInfoTransformMacro */ - def do_| (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that) + def do_|(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitOrOp, that) + /** @group SourceInfoTransformMacro */ - def do_^ (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that) + def do_^(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitXorOp, that) /** @group SourceInfoTransformMacro */ - def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = unop(sourceInfo, UInt(width = width), BitNotOp) // REVIEW TODO: Can these be defined on Bits? @@ -561,7 +589,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def orR: Bool = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def orR(dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy /** And reduction operator @@ -571,7 +602,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def andR: Bool = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def andR(dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy /** Exclusive or (xor) reduction operator @@ -581,20 +615,29 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def xorR: Bool = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def xorR(dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ def do_orR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = redop(sourceInfo, OrReduceOp) + /** @group SourceInfoTransformMacro */ def do_andR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = redop(sourceInfo, AndReduceOp) + /** @group SourceInfoTransformMacro */ def do_xorR(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = redop(sourceInfo, XorReduceOp) - override def do_< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) - override def do_> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that) - override def do_<= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that) - override def do_>= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) + override def do_<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessOp, that) + override def do_>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterOp, that) + override def do_<=(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessEqOp, that) + override def do_>=(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterEqOp, that) /** Dynamic not equals operator * @@ -602,7 +645,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` * @group Comparison */ - final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: UInt): Bool = macro SourceInfoTransform.thatArg /** Dynamic equals operator * @@ -610,12 +653,15 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U * @return a hardware [[Bool]] asserted if this $coll is equal to `that` * @group Comparison */ - final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg + final def ===(that: UInt): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + def do_=/=(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ - def do_=== (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) + def do_===(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, EqualOp, that) /** Unary not * @@ -624,70 +670,78 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def unary_! : Bool = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") - final def unary_! (dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) + final def unary_!(dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_unary_! (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : Bool = this === 0.U(1.W) + def do_unary_!(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this === 0.U(1.W) - override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, validateShiftAmount(that)) - override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this << castToInt(that, "Shift amount") - override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that) - override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that)) - override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this >> castToInt(that, "Shift amount") - override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = + override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width), DynamicShiftRightOp, that) /** - * Circular shift to the left - * @param that number of bits to rotate - * @return UInt of same width rotated left n bits - */ - final def rotateLeft(that: Int): UInt = macro SourceInfoWhiteboxTransform.thatArg + * Circular shift to the left + * @param that number of bits to rotate + * @return UInt of same width rotated left n bits + */ + final def rotateLeft(that: Int): UInt = macro SourceInfoWhiteboxTransform.thatArg def do_rotateLeft(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = width match { - case _ if (n == 0) => this + case _ if (n == 0) => this case KnownWidth(w) if (w <= 1) => this - case KnownWidth(w) if n >= w => do_rotateLeft(n % w) - case _ if (n < 0) => do_rotateRight(-n) - case _ => tail(n) ## head(n) + case KnownWidth(w) if n >= w => do_rotateLeft(n % w) + case _ if (n < 0) => do_rotateRight(-n) + case _ => tail(n) ## head(n) } /** - * Circular shift to the right - * @param that number of bits to rotate - * @return UInt of same width rotated right n bits - */ - final def rotateRight(that: Int): UInt = macro SourceInfoWhiteboxTransform.thatArg + * Circular shift to the right + * @param that number of bits to rotate + * @return UInt of same width rotated right n bits + */ + final def rotateRight(that: Int): UInt = macro SourceInfoWhiteboxTransform.thatArg def do_rotateRight(n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = width match { - case _ if (n <= 0) => do_rotateLeft(-n) + case _ if (n <= 0) => do_rotateLeft(-n) case KnownWidth(w) if (w <= 1) => this - case KnownWidth(w) if n >= w => do_rotateRight(n % w) - case _ => this(n - 1, 0) ## (this >> n) + case KnownWidth(w) if n >= w => do_rotateRight(n % w) + case _ => this(n - 1, 0) ## (this >> n) } - final def rotateRight(that: UInt): UInt = macro SourceInfoWhiteboxTransform.thatArg + final def rotateRight(that: UInt): UInt = macro SourceInfoWhiteboxTransform.thatArg - private def dynamicShift(n: UInt, staticShift: (UInt,Int) => UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : UInt = - n.asBools().zipWithIndex.foldLeft(this){ - case (in, (en, sh)) => Mux(en, staticShift(in, 1 << sh), in) + private def dynamicShift( + n: UInt, + staticShift: (UInt, Int) => UInt + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): UInt = + n.asBools().zipWithIndex.foldLeft(this) { + case (in, (en, sh)) => Mux(en, staticShift(in, 1 << sh), in) } def do_rotateRight(n: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = dynamicShift(n, _ rotateRight _) - final def rotateLeft(that: UInt): UInt = macro SourceInfoWhiteboxTransform.thatArg + final def rotateLeft(that: UInt): UInt = macro SourceInfoWhiteboxTransform.thatArg def do_rotateLeft(n: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = dynamicShift(n, _ rotateLeft _) - /** Conditionally set or clear a bit * * @param off a dynamic offset @@ -712,7 +766,10 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U */ final def zext: SInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def zext(dummy: Int*): SInt = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -722,44 +779,58 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref)) override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = this - override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + override def do_asFixedPoint( + binaryPoint: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): FixedPoint = { binaryPoint match { case KnownBinaryPoint(value) => val iLit = ILit(value) pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit)) case _ => - throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") + throwException( + s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint" + ) } } - override def do_asInterval(range: IntervalRange = IntervalRange.Unknown) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { + override def do_asInterval( + range: IntervalRange = IntervalRange.Unknown + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Interval = { (range.lower, range.upper, range.binaryPoint) match { case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) => // No mechanism to pass open/close to firrtl so need to handle directly val l = lx match { - case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) case firrtlir.Closed(x) => x } val u = ux match { - case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) case firrtlir.Closed(x) => x } val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp))) case _ => - throwException( - s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") + throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") } } - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { this := that.asUInt } private def subtractAsSInt(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that) + binop(sourceInfo, SInt((this.width.max(that.width)) + 1), SubOp, that) } /** A data type for signed integers, represented as a binary bitvector. Defines arithmetic operations between other @@ -774,12 +845,12 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S override def toString: String = { litOption match { case Some(value) => s"SInt$width($value)" - case _ => stringAccessor(s"SInt$width") + case _ => stringAccessor(s"SInt$width") } } private[chisel3] override def typeEquivalent(that: Data): Boolean = - this.getClass == that.getClass && this.width == that.width // TODO: should this be true for unspecified widths? + this.getClass == that.getClass && this.width == that.width // TODO: should this be true for unspecified widths? private[chisel3] override def cloneTypeWidth(w: Width): this.type = new SInt(w).asInstanceOf[this.type] @@ -792,7 +863,10 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S */ final def unary_- : SInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-(dummy: Int*): SInt = macro SourceInfoTransform.noArgDummy /** Unary negation (constant width) @@ -803,26 +877,31 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S */ final def unary_-% : SInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-%(dummy: Int*): SInt = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S - this + def do_unary_-(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S - this + /** @group SourceInfoTransformMacro */ - def do_unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S -% this + def do_unary_-%(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = 0.S -% this /** add (default - no growth) operator */ - override def do_+ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_+(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this +% that + /** subtract (default - no growth) operator */ - override def do_- (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_-(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this -% that - override def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_*(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width + that.width), TimesOp, that) - override def do_/ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_/(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width + 1), DivideOp, that) - override def do_% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, SInt(this.width min that.width), RemOp, that) + override def do_%(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, SInt(this.width.min(that.width)), RemOp, that) /** Multiplication operator * @@ -832,9 +911,10 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $singleCycleMul * @group Arithmetic */ - final def * (that: UInt): SInt = macro SourceInfoTransform.thatArg + final def *(that: UInt): SInt = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ - def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = { + def do_*(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = { val thatToSInt = that.zext val result = binop(sourceInfo, SInt(this.width + thatToSInt.width), TimesOp, thatToSInt) result.tail(1).asSInt @@ -847,7 +927,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidthPlusOne * @group Arithmetic */ - final def +& (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def +&(that: SInt): SInt = macro SourceInfoTransform.thatArg /** Addition operator (constant width) * @@ -856,7 +936,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidth * @group Arithmetic */ - final def +% (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def +%(that: SInt): SInt = macro SourceInfoTransform.thatArg /** Subtraction operator (increasing width) * @@ -865,7 +945,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidthPlusOne * @group Arithmetic */ - final def -& (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def -&(that: SInt): SInt = macro SourceInfoTransform.thatArg /** Subtraction operator (constant width) * @@ -874,19 +954,22 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidth * @group Arithmetic */ - final def -% (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def -%(that: SInt): SInt = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_+& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, SInt((this.width max that.width) + 1), AddOp, that) + def do_+&(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, SInt((this.width.max(that.width)) + 1), AddOp, that) + /** @group SourceInfoTransformMacro */ - def do_+% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + def do_+%(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = (this +& that).tail(1).asSInt + /** @group SourceInfoTransformMacro */ - def do_-& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, SInt((this.width max that.width) + 1), SubOp, that) + def do_-&(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, SInt((this.width.max(that.width)) + 1), SubOp, that) + /** @group SourceInfoTransformMacro */ - def do_-% (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + def do_-%(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = (this -& that).tail(1).asSInt /** Bitwise and operator @@ -896,7 +979,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidth * @group Bitwise */ - final def & (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def &(that: SInt): SInt = macro SourceInfoTransform.thatArg /** Bitwise or operator * @@ -905,7 +988,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidth * @group Bitwise */ - final def | (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def |(that: SInt): SInt = macro SourceInfoTransform.thatArg /** Bitwise exclusive or (xor) operator * @@ -914,26 +997,32 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * $maxWidth * @group Bitwise */ - final def ^ (that: SInt): SInt = macro SourceInfoTransform.thatArg + final def ^(that: SInt): SInt = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_& (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, UInt(this.width max that.width), BitAndOp, that).asSInt + def do_&(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitAndOp, that).asSInt + /** @group SourceInfoTransformMacro */ - def do_| (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, UInt(this.width max that.width), BitOrOp, that).asSInt + def do_|(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitOrOp, that).asSInt + /** @group SourceInfoTransformMacro */ - def do_^ (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - binop(sourceInfo, UInt(this.width max that.width), BitXorOp, that).asSInt + def do_^(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + binop(sourceInfo, UInt(this.width.max(that.width)), BitXorOp, that).asSInt /** @group SourceInfoTransformMacro */ - def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = unop(sourceInfo, UInt(width = width), BitNotOp).asSInt - override def do_< (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) - override def do_> (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that) - override def do_<= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that) - override def do_>= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) + override def do_<(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessOp, that) + override def do_>(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterOp, that) + override def do_<=(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessEqOp, that) + override def do_>=(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterEqOp, that) /** Dynamic not equals operator * @@ -941,7 +1030,7 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` * @group Comparison */ - final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: SInt): Bool = macro SourceInfoTransform.thatArg /** Dynamic equals operator * @@ -949,12 +1038,15 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S * @return a hardware [[Bool]] asserted if this $coll is equal to `that` * @group Comparison */ - final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg + final def ===(that: SInt): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_=/= (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + def do_=/=(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ - def do_=== (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) + def do_===(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, EqualOp, that) // final def abs(): UInt = macro SourceInfoTransform.noArgDummy @@ -962,42 +1054,55 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S Mux(this < 0.S, -this, this) } - override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, validateShiftAmount(that)) - override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this << castToInt(that, "Shift amount") - override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that) - override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that)) - override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this >> castToInt(that, "Shift amount") - override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = + override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width), DynamicShiftRightOp, that) - override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) + override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp( + DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref) + ) override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = this - override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + override def do_asFixedPoint( + binaryPoint: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): FixedPoint = { binaryPoint match { case KnownBinaryPoint(value) => val iLit = ILit(value) pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit)) case _ => - throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") + throwException( + s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint" + ) } } - override def do_asInterval(range: IntervalRange = IntervalRange.Unknown) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { + override def do_asInterval( + range: IntervalRange = IntervalRange.Unknown + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Interval = { (range.lower, range.upper, range.binaryPoint) match { case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) => // No mechanism to pass open/close to firrtl so need to handle directly val l = lx match { - case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) case firrtlir.Closed(x) => x } val u = ux match { - case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) case firrtlir.Closed(x) => x } //TODO: (chick) Need to determine, what asInterval needs, and why it might need min and max as args -- CAN IT BE UNKNOWN? @@ -1006,21 +1111,29 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp))) case _ => - throwException( - s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") + throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") } } - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ) { this := that.asSInt } } sealed trait Reset extends Element with ToBoolable { + /** Casts this $coll to an [[AsyncReset]] */ final def asAsyncReset: AsyncReset = macro SourceInfoWhiteboxTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asAsyncReset(dummy: Int*): AsyncReset = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -1049,10 +1162,16 @@ final class ResetType(private[chisel3] val width: Width = Width(1)) extends Elem /** Not really supported */ def toPrintable: Printable = PString("Reset") - override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) + override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp( + DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref) + ) - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { this := that } @@ -1091,11 +1210,17 @@ sealed class AsyncReset(private[chisel3] val width: Width = Width(1)) extends El /** Not really supported */ def toPrintable: Printable = PString("AsyncReset") - override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) + override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp( + DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref) + ) // TODO Is this right? - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { this := that.asBool.asAsyncReset } @@ -1121,7 +1246,7 @@ sealed class Bool() extends UInt(1.W) with Reset { override def toString: String = { litToBooleanOption match { case Some(value) => s"Bool($value)" - case _ => stringAccessor("Bool") + case _ => stringAccessor("Bool") } } @@ -1134,7 +1259,7 @@ sealed class Bool() extends UInt(1.W) with Reset { def litToBooleanOption: Option[Boolean] = litOption.map { case intVal if intVal == 1 => true case intVal if intVal == 0 => false - case intVal => throwException(s"Boolean with unexpected literal value $intVal") + case intVal => throwException(s"Boolean with unexpected literal value $intVal") } /** Convert to a [[scala.Boolean]] */ @@ -1149,7 +1274,7 @@ sealed class Bool() extends UInt(1.W) with Reset { * @return the bitwise and of this $coll and `that` * @group Bitwise */ - final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg + final def &(that: Bool): Bool = macro SourceInfoTransform.thatArg /** Bitwise or operator * @@ -1157,7 +1282,7 @@ sealed class Bool() extends UInt(1.W) with Reset { * @return the bitwise or of this $coll and `that` * @group Bitwise */ - final def | (that: Bool): Bool = macro SourceInfoTransform.thatArg + final def |(that: Bool): Bool = macro SourceInfoTransform.thatArg /** Bitwise exclusive or (xor) operator * @@ -1165,20 +1290,22 @@ sealed class Bool() extends UInt(1.W) with Reset { * @return the bitwise xor of this $coll and `that` * @group Bitwise */ - final def ^ (that: Bool): Bool = macro SourceInfoTransform.thatArg + final def ^(that: Bool): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + def do_&(that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitAndOp, that) + /** @group SourceInfoTransformMacro */ - def do_| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + def do_|(that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitOrOp, that) + /** @group SourceInfoTransformMacro */ - def do_^ (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + def do_^(that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = binop(sourceInfo, Bool(), BitXorOp, that) /** @group SourceInfoTransformMacro */ - override def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + override def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = unop(sourceInfo, Bool(), BitNotOp) /** Logical or operator @@ -1188,10 +1315,10 @@ sealed class Bool() extends UInt(1.W) with Reset { * @note this is equivalent to [[Bool!.|(that:chisel3\.Bool)* Bool.|)]] * @group Logical */ - def || (that: Bool): Bool = macro SourceInfoTransform.thatArg + def ||(that: Bool): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_|| (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this | that + def do_||(that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this | that /** Logical and operator * @@ -1200,19 +1327,24 @@ sealed class Bool() extends UInt(1.W) with Reset { * @note this is equivalent to [[Bool!.&(that:chisel3\.Bool)* Bool.&]] * @group Logical */ - def && (that: Bool): Bool = macro SourceInfoTransform.thatArg + def &&(that: Bool): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_&& (that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this & that + def do_&&(that: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this & that /** Reinterprets this $coll as a clock */ def asClock: Clock = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def asClock(dummy: Int*): Clock = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_asClock(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Clock = pushOp(DefPrim(sourceInfo, Clock(), AsClockOp, ref)) + def do_asClock(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Clock = pushOp( + DefPrim(sourceInfo, Clock(), AsClockOp, ref) + ) /** @group SourceInfoTransformMacro */ def do_asAsyncReset(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): AsyncReset = @@ -1261,6 +1393,7 @@ package experimental { */ def litToBigDecimal: BigDecimal = litToBigDecimalOption.get } + /** A sealed class representing a fixed point number that has a bit width and a binary point The width and binary point * may be inferred. * @@ -1275,28 +1408,32 @@ 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`. */ - sealed class FixedPoint private(width: Width, val binaryPoint: BinaryPoint) - extends Bits(width) with Num[FixedPoint] with HasBinaryPoint { + sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) + extends Bits(width) + with Num[FixedPoint] + with HasBinaryPoint { override def toString: String = { litToDoubleOption match { case Some(value) => s"FixedPoint$width$binaryPoint($value)" - case _ => stringAccessor(s"FixedPoint$width$binaryPoint") + case _ => stringAccessor(s"FixedPoint$width$binaryPoint") } } private[chisel3] override def typeEquivalent(that: Data): Boolean = that match { - case that: FixedPoint => this.width == that.width && this.binaryPoint == that.binaryPoint // TODO: should this be true for unspecified widths? + case that: FixedPoint => + this.width == that.width && this.binaryPoint == that.binaryPoint // TODO: should this be true for unspecified widths? case _ => false } private[chisel3] override def cloneTypeWidth(w: Width): this.type = new FixedPoint(w, binaryPoint).asInstanceOf[this.type] - override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match { - case _: FixedPoint|DontCare => super.connect(that) - case _ => this badConnect that - } + override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = + that match { + case _: FixedPoint | DontCare => super.connect(that) + case _ => this.badConnect(that) + } /** Unary negation (expanding width) * @@ -1306,7 +1443,10 @@ package experimental { */ final def unary_- : FixedPoint = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-(dummy: Int*): FixedPoint = macro SourceInfoTransform.noArgDummy /** Unary negation (constant width) @@ -1316,28 +1456,34 @@ package experimental { * @group Arithmetic */ final def unary_-% : FixedPoint = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-%(dummy: Int*): FixedPoint = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ - def do_unary_- (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) - this + def do_unary_-(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + FixedPoint.fromBigInt(0) - this + /** @group SourceInfoTransformMacro */ - def do_unary_-% (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = FixedPoint.fromBigInt(0) -% this + def do_unary_-%(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + FixedPoint.fromBigInt(0) -% this /** add (default - no growth) operator */ - override def do_+ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_+(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = this +% that + /** subtract (default - no growth) operator */ - override def do_- (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_-(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = this -% that - override def do_* (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_*(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that.width, this.binaryPoint + that.binaryPoint), TimesOp, that) - override def do_/ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_/(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"division is illegal on FixedPoint types") - override def do_% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"mod is illegal on FixedPoint types") - /** Multiplication operator * * @param that a hardware [[UInt]] @@ -1346,9 +1492,10 @@ package experimental { * $singleCycleMul * @group Arithmetic */ - final def * (that: UInt): FixedPoint = macro SourceInfoTransform.thatArg + final def *(that: UInt): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ - def do_* (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_*(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that) /** Multiplication operator @@ -1359,9 +1506,10 @@ package experimental { * $singleCycleMul * @group Arithmetic */ - final def * (that: SInt): FixedPoint = macro SourceInfoTransform.thatArg + final def *(that: SInt): FixedPoint = macro SourceInfoTransform.thatArg + /** @group SourceInfoTransformMacro */ - def do_* (that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_*(that: SInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that) /** Addition operator (expanding width) @@ -1371,7 +1519,7 @@ package experimental { * $maxWidthPlusOne * @group Arithmetic */ - final def +& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def +&(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** Addition operator (constant width) * @@ -1380,7 +1528,7 @@ package experimental { * $maxWidth * @group Arithmetic */ - final def +% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def +%(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** Subtraction operator (increasing width) * @@ -1389,7 +1537,7 @@ package experimental { * $maxWidthPlusOne * @group Arithmetic */ - final def -& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def -&(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** Subtraction operator (constant width) * @@ -1398,44 +1546,45 @@ package experimental { * $maxWidth * @group Arithmetic */ - final def -% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def -%(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_+& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + def do_+&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { (this.width, that.width, this.binaryPoint, that.binaryPoint) match { case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) => val thisIntWidth = thisWidth - thisBP val thatIntWidth = thatWidth - thatBP - val newBinaryPoint = thisBP max thatBP - val newWidth = (thisIntWidth max thatIntWidth) + newBinaryPoint + 1 + val newBinaryPoint = thisBP.max(thatBP) + val newWidth = (thisIntWidth.max(thatIntWidth)) + newBinaryPoint + 1 binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), AddOp, that) case _ => - val newBinaryPoint = this.binaryPoint max that.binaryPoint + val newBinaryPoint = this.binaryPoint.max(that.binaryPoint) binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), AddOp, that) } } /** @group SourceInfoTransformMacro */ - def do_+% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = - (this +& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint) + def do_+%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + (this +& that).tail(1).asFixedPoint(this.binaryPoint.max(that.binaryPoint)) + /** @group SourceInfoTransformMacro */ - def do_-& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + def do_-&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { (this.width, that.width, this.binaryPoint, that.binaryPoint) match { case (KnownWidth(thisWidth), KnownWidth(thatWidth), KnownBinaryPoint(thisBP), KnownBinaryPoint(thatBP)) => val thisIntWidth = thisWidth - thisBP val thatIntWidth = thatWidth - thatBP - val newBinaryPoint = thisBP max thatBP - val newWidth = (thisIntWidth max thatIntWidth) + newBinaryPoint + 1 + val newBinaryPoint = thisBP.max(thatBP) + val newWidth = (thisIntWidth.max(thatIntWidth)) + newBinaryPoint + 1 binop(sourceInfo, FixedPoint(newWidth.W, newBinaryPoint.BP), SubOp, that) case _ => - val newBinaryPoint = this.binaryPoint max that.binaryPoint + val newBinaryPoint = this.binaryPoint.max(that.binaryPoint) binop(sourceInfo, FixedPoint(UnknownWidth(), newBinaryPoint), SubOp, that) } } /** @group SourceInfoTransformMacro */ - def do_-% (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = - (this -& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint) + def do_-%(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + (this -& that).tail(1).asFixedPoint(this.binaryPoint.max(that.binaryPoint)) /** Bitwise and operator * @@ -1444,7 +1593,7 @@ package experimental { * $maxWidth * @group Bitwise */ - final def & (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def &(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** Bitwise or operator * @@ -1453,7 +1602,7 @@ package experimental { * $maxWidth * @group Bitwise */ - final def | (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def |(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** Bitwise exclusive or (xor) operator * @@ -1462,38 +1611,45 @@ package experimental { * $maxWidth * @group Bitwise */ - final def ^ (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg + final def ^(that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_& (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_&(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"And is illegal between $this and $that") + /** @group SourceInfoTransformMacro */ - def do_| (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_|(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Or is illegal between $this and $that") + /** @group SourceInfoTransformMacro */ - def do_^ (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_^(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Xor is illegal between $this and $that") final def setBinaryPoint(that: Int): FixedPoint = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = this.binaryPoint match { - case KnownBinaryPoint(value) => - binop(sourceInfo, FixedPoint(this.width + (that - value), KnownBinaryPoint(that)), SetBinaryPoint, that) - case _ => - binop(sourceInfo, FixedPoint(UnknownWidth(), KnownBinaryPoint(that)), SetBinaryPoint, that) - } + def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + this.binaryPoint match { + case KnownBinaryPoint(value) => + binop(sourceInfo, FixedPoint(this.width + (that - value), KnownBinaryPoint(that)), SetBinaryPoint, that) + case _ => + binop(sourceInfo, FixedPoint(UnknownWidth(), KnownBinaryPoint(that)), SetBinaryPoint, that) + } /** @group SourceInfoTransformMacro */ - def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = throwException(s"Not is illegal on $this") - override def do_< (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) - override def do_> (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that) - override def do_<= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that) - override def do_>= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) + override def do_<(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessOp, that) + override def do_>(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterOp, that) + override def do_<=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessEqOp, that) + override def do_>=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterEqOp, that) - final def != (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + final def !=(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg /** Dynamic not equals operator * @@ -1501,7 +1657,7 @@ package experimental { * @return a hardware [[Bool]] asserted if this $coll is not equal to `that` * @group Comparison */ - final def =/= (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg /** Dynamic equals operator * @@ -1509,14 +1665,19 @@ package experimental { * @return a hardware [[Bool]] asserted if this $coll is equal to `that` * @group Comparison */ - final def === (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg + final def ===(that: FixedPoint): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_!= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + def do_!=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ - def do_=/= (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) + def do_=/=(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + /** @group SourceInfoTransformMacro */ - def do_=== (that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) + def do_===(that: FixedPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, EqualOp, that) def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { // TODO: remove this once we have CompileOptions threaded through the macro system. @@ -1524,59 +1685,88 @@ package experimental { Mux(this < 0.F(0.BP), 0.F(0.BP) - this, this) } - override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, validateShiftAmount(that)) - override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = (this << castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint) - override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that) - override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = - binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, validateShiftAmount(that)) - override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + binop( + sourceInfo, + FixedPoint(this.width.shiftRight(that), this.binaryPoint), + ShiftRightOp, + validateShiftAmount(that) + ) + override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = (this >> castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint) - override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = + override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that) - override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) - override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref)) - - override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp( + DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref) + ) + override def do_asSInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = pushOp( + DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref) + ) + + override def do_asFixedPoint( + binaryPoint: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): FixedPoint = { binaryPoint match { case KnownBinaryPoint(value) => val iLit = ILit(value) pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit)) case _ => - throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") + throwException( + s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint" + ) } } - def do_asInterval(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { - throwException(s"cannot call $this.asInterval(binaryPoint=$binaryPoint), you must specify a range") - } - - override def do_asInterval(range: IntervalRange = IntervalRange.Unknown) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { - (range.lower, range.upper, range.binaryPoint) match { - case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) => - // No mechanism to pass open/close to firrtl so need to handle directly - val l = lx match { - case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) - case firrtlir.Closed(x) => x - } - val u = ux match { - case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) - case firrtlir.Closed(x) => x - } - val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get - val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get - pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp))) - case _ => - throwException( - s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") + def do_asInterval( + binaryPoint: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Interval = { + throwException(s"cannot call $this.asInterval(binaryPoint=$binaryPoint), you must specify a range") + } + + override def do_asInterval( + range: IntervalRange = IntervalRange.Unknown + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Interval = { + (range.lower, range.upper, range.binaryPoint) match { + case (lx: firrtlconstraint.IsKnown, ux: firrtlconstraint.IsKnown, KnownBinaryPoint(bp)) => + // No mechanism to pass open/close to firrtl so need to handle directly + val l = lx match { + case firrtlir.Open(x) => x + BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Closed(x) => x + } + val u = ux match { + case firrtlir.Open(x) => x - BigDecimal(1) / BigDecimal(BigInt(1) << bp) + case firrtlir.Closed(x) => x + } + val minBI = (l * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get + val maxBI = (u * BigDecimal(BigInt(1) << bp)).setScale(0, BigDecimal.RoundingMode.FLOOR).toBigIntExact.get + pushOp(DefPrim(sourceInfo, Interval(range), AsIntervalOp, ref, ILit(minBI), ILit(maxBI), ILit(bp))) + case _ => + throwException(s"cannot call $this.asInterval($range), you must specify a known binaryPoint and range") + } } - } - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ) { // TODO: redefine as just asFixedPoint on that, where FixedPoint.asFixedPoint just works. this := (that match { case fp: FixedPoint => fp.asSInt.asFixedPoint(this.binaryPoint) @@ -1610,36 +1800,43 @@ package experimental { def fromBigInt(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = { apply(value, width, binaryPoint) } + /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = { apply(value, Width(), binaryPoint) } + /** Create an FixedPoint literal with inferred width from BigInt. * Use PrivateObject to force users to specify width and binaryPoint by name */ def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint = - if(width == -1) { + if (width == -1) { apply(value, Width(), BinaryPoint(binaryPoint)) - } - else { + } else { apply(value, Width(width), BinaryPoint(binaryPoint)) } + /** Create an FixedPoint literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ def fromDouble(value: Double, width: Width, binaryPoint: BinaryPoint): FixedPoint = { fromBigInt( - toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint + toBigInt(value, binaryPoint.get), + width = width, + binaryPoint = binaryPoint ) } + /** Create an FixedPoint literal with inferred width from BigDecimal. * Use PrivateObject to force users to specify width and binaryPoint by name */ def fromBigDecimal(value: BigDecimal, width: Width, binaryPoint: BinaryPoint): FixedPoint = { fromBigInt( - toBigInt(value, binaryPoint.get), width = width, binaryPoint = binaryPoint + toBigInt(value, binaryPoint.get), + width = width, + binaryPoint = binaryPoint ) } @@ -1651,8 +1848,6 @@ package experimental { lit.bindLitArg(newLiteral) } - - object Implicits { implicit class fromDoubleToLiteral(double: Double) { @@ -1695,12 +1890,14 @@ package experimental { * @param range a range specifies min, max and binary point */ sealed class Interval private[chisel3] (val range: chisel3.internal.firrtl.IntervalRange) - extends Bits(range.getWidth) with Num[Interval] with HasBinaryPoint { + extends Bits(range.getWidth) + with Num[Interval] + with HasBinaryPoint { override def toString: String = { litOption match { case Some(value) => s"Interval$width($value)" - case _ => stringAccessor(s"Interval$width") + case _ => stringAccessor(s"Interval$width") } } @@ -1714,27 +1911,27 @@ package experimental { val int = """([+\-]?[0-9]\d*)""".r def dec2string(v: BigDecimal): String = v.toString match { case zdec1(x, y, z) => x + y - case zdec2(x, y) => x - case other => other + case zdec2(x, y) => x + case other => other } val lowerString = range.lower match { case firrtlir.Open(l) => s"(${dec2string(l)}, " case firrtlir.Closed(l) => s"[${dec2string(l)}, " case firrtlir.UnknownBound => s"[?, " - case _ => s"[?, " + case _ => s"[?, " } val upperString = range.upper match { case firrtlir.Open(u) => s"${dec2string(u)})" case firrtlir.Closed(u) => s"${dec2string(u)}]" case firrtlir.UnknownBound => s"?]" - case _ => s"?]" + case _ => s"?]" } val bounds = lowerString + upperString val pointString = range.binaryPoint match { - case KnownBinaryPoint(i) => "." + i.toString - case _ => "" + case KnownBinaryPoint(i) => "." + i.toString + case _ => "" } "Interval" + bounds + pointString } @@ -1746,19 +1943,25 @@ package experimental { override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { that match { - case _: Interval|DontCare => super.connect(that) - case _ => this badConnect that + case _: Interval | DontCare => super.connect(that) + case _ => this.badConnect(that) } } final def unary_- : Interval = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-(dummy: Int*): Interval = macro SourceInfoTransform.noArgDummy final def unary_-% : Interval = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def unary_-%(dummy: Int*): Interval = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -1772,6 +1975,7 @@ package experimental { /** add (default - growing) operator */ override def do_+(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = this +& that + /** subtract (default - growing) operator */ override def do_-(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = this -& that @@ -1785,10 +1989,13 @@ package experimental { /** add (width +1) operator */ final def +&(that: Interval): Interval = macro SourceInfoTransform.thatArg + /** add (no growth) operator */ final def +%(that: Interval): Interval = macro SourceInfoTransform.thatArg + /** subtract (width +1) operator */ final def -&(that: Interval): Interval = macro SourceInfoTransform.thatArg + /** subtract (no growth) operator */ final def -%(that: Interval): Interval = macro SourceInfoTransform.thatArg @@ -1859,21 +2066,28 @@ package experimental { } /** Returns this wire bitwise-inverted. */ - def do_unary_~ (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = + def do_unary_~(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = throwException(s"Not is illegal on $this") - override def do_< (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) - override def do_> (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that) - override def do_<= (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that) - override def do_>= (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) - - final def != (that: Interval): Bool = macro SourceInfoTransform.thatArg - final def =/= (that: Interval): Bool = macro SourceInfoTransform.thatArg - final def === (that: Interval): Bool = macro SourceInfoTransform.thatArg - - def do_!= (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) - def do_=/= (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) - def do_=== (that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) + override def do_<(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessOp, that) + override def do_>(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterOp, that) + override def do_<=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessEqOp, that) + override def do_>=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterEqOp, that) + + final def !=(that: Interval): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: Interval): Bool = macro SourceInfoTransform.thatArg + final def ===(that: Interval): Bool = macro SourceInfoTransform.thatArg + + def do_!=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + def do_=/=(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + def do_===(that: Interval)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, EqualOp, that) // final def abs(): UInt = macro SourceInfoTransform.noArgDummy @@ -1881,24 +2095,24 @@ package experimental { Mux(this < Interval.Zero, (Interval.Zero - this), this) } - override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = + override def do_<<(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = binop(sourceInfo, Interval(this.range << that), ShiftLeftOp, that) - override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = + override def do_<<(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = do_<<(that.toInt) - override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { + override def do_<<(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { binop(sourceInfo, Interval(this.range << that), DynamicShiftLeftOp, that) } - override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { + override def do_>>(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { binop(sourceInfo, Interval(this.range >> that), ShiftRightOp, that) } - override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = + override def do_>>(that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = do_>>(that.toInt) - override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { + override def do_>>(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Interval = { binop(sourceInfo, Interval(this.range >> that), DynamicShiftRightOp, that) } @@ -1965,13 +2179,12 @@ package experimental { 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) - val intervalLit = intervalLitOpt.getOrElse( + val intervalLit = intervalLitOpt.getOrElse( throwException(s"$this.squeeze($that) requires an Interval range with known lower and upper bounds") ) do_squeeze(intervalLit) } - /** * Wrap the value of this [[Interval]] into the range of a different Interval with a presumably smaller range. * Ignores binary point of argument @@ -2104,14 +2317,20 @@ package experimental { pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref)) } - override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = { + override def do_asFixedPoint( + binaryPoint: BinaryPoint + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): FixedPoint = { binaryPoint match { case KnownBinaryPoint(value) => val iLit = ILit(value) pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit)) case _ => throwException( - s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint") + s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint" + ) } } @@ -2132,8 +2351,12 @@ package experimental { throwException("fromBits INVALID for intervals") } - private[chisel3] override def connectFromBits(that: Bits) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ) { this := that.asInterval(this.range) } } @@ -2146,6 +2369,7 @@ package experimental { * IMPORTANT: The API provided here is experimental and may change in the future. */ object Interval extends NumObject { + /** Create an Interval type with inferred width and binary point. */ def apply(): Interval = Interval(range"[?,?]") @@ -2153,7 +2377,7 @@ package experimental { def apply(binaryPoint: BinaryPoint): Interval = { val binaryPointString = binaryPoint match { case KnownBinaryPoint(value) => s"$value" - case _ => s"" + case _ => s"" } Interval(range"[?,?].$binaryPointString") } @@ -2201,27 +2425,39 @@ package experimental { /** Create an Interval literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ - def fromDouble(value: Double, dummy: PrivateType = PrivateObject, - width: Width, binaryPoint: BinaryPoint): Interval = { + def fromDouble( + value: Double, + dummy: PrivateType = PrivateObject, + width: Width, + binaryPoint: BinaryPoint + ): Interval = { fromBigInt( - toBigInt(value, binaryPoint), width = width, binaryPoint = binaryPoint + toBigInt(value, binaryPoint), + width = width, + binaryPoint = binaryPoint ) } /** Create an Interval literal with inferred width from Double. * Use PrivateObject to force users to specify width and binaryPoint by name */ - def fromBigDecimal(value: Double, dummy: PrivateType = PrivateObject, - width: Width, binaryPoint: BinaryPoint): Interval = { + def fromBigDecimal( + value: Double, + dummy: PrivateType = PrivateObject, + width: Width, + binaryPoint: BinaryPoint + ): Interval = { fromBigInt( - toBigInt(value, binaryPoint), width = width, binaryPoint = binaryPoint + toBigInt(value, binaryPoint), + width = width, + binaryPoint = binaryPoint ) } protected[chisel3] def Lit(value: BigInt, width: Width, binaryPoint: BinaryPoint): Interval = { width match { case KnownWidth(w) => - if(value >= 0 && value.bitLength >= w || value < 0 && value.bitLength > w) { + if (value >= 0 && value.bitLength >= w || value < 0 && value.bitLength > w) { throw new ChiselException( s"Error literal interval value $value is too many bits for specified width $w" ) @@ -2243,7 +2479,7 @@ package experimental { case (firrtlir.Open(l), firrtlir.Closed(u)) => l < bigDecimal && bigDecimal <= u case (firrtlir.Open(l), firrtlir.Open(u)) => l < bigDecimal && bigDecimal < u } - if(! inRange) { + if (!inRange) { throw new ChiselException( s"Error literal interval value $bigDecimal is not contained in specified range $range" ) @@ -2338,9 +2574,7 @@ package experimental { } implicit class fromDoubleToLiteralInterval(double: Double) - extends fromBigDecimalToLiteralInterval(BigDecimal(double)) + extends fromBigDecimalToLiteralInterval(BigDecimal(double)) } } } - - diff --git a/core/src/main/scala/chisel3/BlackBox.scala b/core/src/main/scala/chisel3/BlackBox.scala index ec5de0cd..89c4ccd3 100644 --- a/core/src/main/scala/chisel3/BlackBox.scala +++ b/core/src/main/scala/chisel3/BlackBox.scala @@ -23,6 +23,7 @@ package experimental { case class IntParam(value: BigInt) extends Param case class DoubleParam(value: Double) extends Param case class StringParam(value: String) extends Param + /** Unquoted String */ case class RawParam(value: String) extends Param @@ -85,7 +86,7 @@ package experimental { closeUnboundIds(names) - val firrtlPorts = getModulePorts map {port => Port(port, port.specifiedDirection)} + val firrtlPorts = getModulePorts.map { port => Port(port, port.specifiedDirection) } val component = DefBlackBox(this, name, firrtlPorts, SpecifiedDirection.Unspecified, params) _component = Some(component) _component @@ -137,19 +138,24 @@ package experimental { * @note The parameters API is experimental and may change */ @nowarn("msg=class Port") // delete when Port becomes private -abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param])(implicit compileOptions: CompileOptions) extends BaseBlackBox { +abstract class BlackBox( + val params: Map[String, Param] = Map.empty[String, Param] +)( + implicit compileOptions: CompileOptions) + extends BaseBlackBox { // Find a Record port named "io" for purposes of stripping the prefix private[chisel3] lazy val _io: Record = - this.findPort("io") - .collect { case r: Record => r } // Must be a Record - .getOrElse(null) // null handling occurs in generateComponent + this + .findPort("io") + .collect { case r: Record => r } // Must be a Record + .getOrElse(null) // null handling occurs in generateComponent // Allow access to bindings from the compatibility package protected def _compatIoPortBound() = portsContains(_io) private[chisel3] override def generateComponent(): Option[Component] = { - _compatAutoWrapPorts() // pre-IO(...) compatibility hack + _compatAutoWrapPorts() // pre-IO(...) compatibility hack // Restrict IO to just io, clock, and reset require(_io != null, "BlackBox must have a port named 'io' of type Record!") @@ -159,7 +165,7 @@ abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param require(!_closed, "Can't generate module more than once") _closed = true - val namedPorts = _io.elements.toSeq.reverse // ListMaps are stored in reverse order + val namedPorts = _io.elements.toSeq.reverse // ListMaps are stored in reverse order // There is a risk of user improperly attempting to connect directly with io // Long term solution will be to define BlackBox IO differently as part of @@ -179,7 +185,7 @@ abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param id._onModuleClose } - val firrtlPorts = namedPorts map {namedPort => Port(namedPort._2, namedPort._2.specifiedDirection)} + val firrtlPorts = namedPorts.map { namedPort => Port(namedPort._2, namedPort._2.specifiedDirection) } val component = DefBlackBox(this, name, firrtlPorts, _io.specifiedDirection, params) _component = Some(component) _component diff --git a/core/src/main/scala/chisel3/BoolFactory.scala b/core/src/main/scala/chisel3/BoolFactory.scala index 787f1e5e..1d96659f 100644 --- a/core/src/main/scala/chisel3/BoolFactory.scala +++ b/core/src/main/scala/chisel3/BoolFactory.scala @@ -4,14 +4,14 @@ package chisel3 import chisel3.internal.firrtl.{ULit, Width} - trait BoolFactory { + /** Creates an empty Bool. - */ + */ def apply(): Bool = new Bool() /** Creates Bool literal. - */ + */ protected[chisel3] def Lit(x: Boolean): Bool = { val result = new Bool() val lit = ULit(if (x) 1 else 0, Width(1)) diff --git a/core/src/main/scala/chisel3/Clock.scala b/core/src/main/scala/chisel3/Clock.scala index e4be6558..68174d7c 100644 --- a/core/src/main/scala/chisel3/Clock.scala +++ b/core/src/main/scala/chisel3/Clock.scala @@ -21,10 +21,11 @@ sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element private[chisel3] def typeEquivalent(that: Data): Boolean = this.getClass == that.getClass - override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = that match { - case _: Clock => super.connect(that)(sourceInfo, connectCompileOptions) - case _ => super.badConnect(that)(sourceInfo) - } + override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = + that match { + case _: Clock => super.connect(that)(sourceInfo, connectCompileOptions) + case _ => super.badConnect(that)(sourceInfo) + } override def litOption: Option[BigInt] = None @@ -34,14 +35,23 @@ sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element /** Returns the contents of the clock wire as a [[Bool]]. */ final def asBool: Bool = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asBool(dummy: Int*): Bool = macro SourceInfoTransform.noArgDummy def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this.asUInt.asBool - override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)) - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp( + DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref) + ) + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { this := that.asBool.asClock } } diff --git a/core/src/main/scala/chisel3/CompileOptions.scala b/core/src/main/scala/chisel3/CompileOptions.scala index 3dcc25a8..db773d6e 100644 --- a/core/src/main/scala/chisel3/CompileOptions.scala +++ b/core/src/main/scala/chisel3/CompileOptions.scala @@ -36,7 +36,7 @@ object CompileOptions { } object ExplicitCompileOptions { - case class CompileOptionsClass ( + case class CompileOptionsClass( // Should Record connections require a strict match of fields. // If true and the same fields aren't present in both source and sink, a MissingFieldException, // MissingLeftFieldException, or MissingRightFieldException will be thrown. @@ -52,12 +52,12 @@ object ExplicitCompileOptions { // Require an explicit DontCare assignment to generate a firrtl DefInvalid val explicitInvalidate: Boolean, // Should the reset type of Module be a Bool or a Reset - val inferModuleReset: Boolean - ) extends CompileOptions + val inferModuleReset: Boolean) + extends CompileOptions // Collection of "not strict" connection compile options. // These provide compatibility with existing code. - implicit val NotStrict = new CompileOptionsClass ( + implicit val NotStrict = new CompileOptionsClass( connectFieldsMustMatch = false, declaredTypeMustBeUnbound = false, dontTryConnectionsSwapped = false, @@ -68,13 +68,13 @@ object ExplicitCompileOptions { ) // Collection of "strict" connection compile options, preferred for new code. - implicit val Strict = new CompileOptionsClass ( + implicit val Strict = new CompileOptionsClass( connectFieldsMustMatch = true, declaredTypeMustBeUnbound = true, dontTryConnectionsSwapped = true, dontAssumeDirectionality = true, checkSynthesizable = true, explicitInvalidate = true, - inferModuleReset = true + inferModuleReset = true ) } diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala index 2bca5f98..9e9f5dbb 100644 --- a/core/src/main/scala/chisel3/Data.scala +++ b/core/src/main/scala/chisel3/Data.scala @@ -18,24 +18,28 @@ import scala.util.Try */ sealed abstract class SpecifiedDirection object SpecifiedDirection { + /** Default user direction, also meaning 'not-flipped' */ case object Unspecified extends SpecifiedDirection + /** Node and its children are forced as output */ case object Output extends SpecifiedDirection + /** Node and its children are forced as inputs */ case object Input extends SpecifiedDirection + /** Mainly for containers, children are flipped. */ case object Flip extends SpecifiedDirection def flip(dir: SpecifiedDirection): SpecifiedDirection = dir match { case Unspecified => Flip - case Flip => Unspecified - case Output => Input - case Input => Output + case Flip => Unspecified + case Output => Input + case Input => Output } /** Returns the effective SpecifiedDirection of this node given the parent's effective SpecifiedDirection @@ -43,13 +47,18 @@ object SpecifiedDirection { */ def fromParent(parentDirection: SpecifiedDirection, thisDirection: SpecifiedDirection): SpecifiedDirection = (parentDirection, thisDirection) match { - case (SpecifiedDirection.Output, _) => SpecifiedDirection.Output - case (SpecifiedDirection.Input, _) => SpecifiedDirection.Input + case (SpecifiedDirection.Output, _) => SpecifiedDirection.Output + case (SpecifiedDirection.Input, _) => SpecifiedDirection.Input case (SpecifiedDirection.Unspecified, thisDirection) => thisDirection - case (SpecifiedDirection.Flip, thisDirection) => SpecifiedDirection.flip(thisDirection) + case (SpecifiedDirection.Flip, thisDirection) => SpecifiedDirection.flip(thisDirection) } - private[chisel3] def specifiedDirection[T<:Data](source: T)(dir: SpecifiedDirection)(implicit compileOptions: CompileOptions): T = { + private[chisel3] def specifiedDirection[T <: Data]( + source: T + )(dir: SpecifiedDirection + )( + implicit compileOptions: CompileOptions + ): T = { if (compileOptions.checkSynthesizable) { requireIsChiselType(source) } @@ -67,6 +76,7 @@ object SpecifiedDirection { sealed abstract class ActualDirection object ActualDirection { + /** The object does not exist / is empty and hence has no direction */ case object Empty extends ActualDirection @@ -74,9 +84,11 @@ object ActualDirection { /** Undirectioned, struct-like */ case object Unspecified extends ActualDirection + /** Output element, or container with all outputs (even if forced) */ case object Output extends ActualDirection + /** Input element, or container with all inputs (even if forced) */ case object Input extends ActualDirection @@ -89,19 +101,21 @@ object ActualDirection { def fromSpecified(direction: SpecifiedDirection): ActualDirection = direction match { case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => ActualDirection.Unspecified - case SpecifiedDirection.Output => ActualDirection.Output - case SpecifiedDirection.Input => ActualDirection.Input + case SpecifiedDirection.Output => ActualDirection.Output + case SpecifiedDirection.Input => ActualDirection.Input } /** Determine the actual binding of a container given directions of its children. * Returns None in the case of mixed specified / unspecified directionality. */ - def fromChildren(childDirections: Set[ActualDirection], containerDirection: SpecifiedDirection): - Option[ActualDirection] = { - if (childDirections == Set()) { // Sadly, Scala can't do set matching + def fromChildren( + childDirections: Set[ActualDirection], + containerDirection: SpecifiedDirection + ): Option[ActualDirection] = { + if (childDirections == Set()) { // Sadly, Scala can't do set matching ActualDirection.fromSpecified(containerDirection) match { - case ActualDirection.Unspecified => Some(ActualDirection.Empty) // empty direction if relative / no direction - case dir => Some(dir) // use assigned direction if specified + case ActualDirection.Unspecified => Some(ActualDirection.Empty) // empty direction if relative / no direction + case dir => Some(dir) // use assigned direction if specified } } else if (childDirections == Set(ActualDirection.Unspecified)) { Some(ActualDirection.Unspecified) @@ -109,14 +123,20 @@ object ActualDirection { Some(ActualDirection.Input) } else if (childDirections == Set(ActualDirection.Output)) { Some(ActualDirection.Output) - } else if (childDirections subsetOf - Set(ActualDirection.Output, ActualDirection.Input, - ActualDirection.Bidirectional(ActualDirection.Default), - ActualDirection.Bidirectional(ActualDirection.Flipped))) { + } else if ( + childDirections.subsetOf( + Set( + ActualDirection.Output, + ActualDirection.Input, + ActualDirection.Bidirectional(ActualDirection.Default), + ActualDirection.Bidirectional(ActualDirection.Flipped) + ) + ) + ) { containerDirection match { case SpecifiedDirection.Unspecified => Some(ActualDirection.Bidirectional(ActualDirection.Default)) - case SpecifiedDirection.Flip => Some(ActualDirection.Bidirectional(ActualDirection.Flipped)) - case _ => throw new RuntimeException("Unexpected forced Input / Output") + case SpecifiedDirection.Flip => Some(ActualDirection.Bidirectional(ActualDirection.Flipped)) + case _ => throw new RuntimeException("Unexpected forced Input / Output") } } else { None @@ -130,7 +150,7 @@ package experimental { /** Experimental hardware construction reflection API */ object DataMirror { - def widthOf(target: Data): Width = target.width + def widthOf(target: Data): Width = target.width def specifiedDirectionOf(target: Data): SpecifiedDirection = target.specifiedDirection def directionOf(target: Data): ActualDirection = { requireIsHardware(target, "node requested directionality on") @@ -151,7 +171,7 @@ package experimental { * @param x First Chisel type * @param y Second Chisel type * @return true if the two Chisel types are equal. - **/ + */ def checkTypeEquivalence(x: Data, y: Data): Boolean = x.typeEquivalent(y) /** Returns the ports of a module @@ -210,11 +230,12 @@ package experimental { def fullModulePorts(target: BaseModule): Seq[(String, Data)] = { def getPortNames(name: String, data: Data): Seq[(String, Data)] = Seq(name -> data) ++ (data match { case _: Element => Seq() - case r: Record => r.elements.toSeq flatMap { case (eltName, elt) => getPortNames(s"${name}_${eltName}", elt) } - case v: Vec[_] => v.zipWithIndex flatMap { case (elt, index) => getPortNames(s"${name}_${index}", elt) } + case r: Record => r.elements.toSeq.flatMap { case (eltName, elt) => getPortNames(s"${name}_${eltName}", elt) } + case v: Vec[_] => v.zipWithIndex.flatMap { case (elt, index) => getPortNames(s"${name}_${index}", elt) } }) - modulePorts(target).flatMap { case (name, data) => - getPortNames(name, data).toList + modulePorts(target).flatMap { + case (name, data) => + getPortNames(name, data).toList } } @@ -222,7 +243,7 @@ package experimental { object internal { def isSynthesizable(target: Data): Boolean = target.isSynthesizable // For those odd cases where you need to care about object reference and uniqueness - def chiselTypeClone[T<:Data](target: Data): T = { + def chiselTypeClone[T <: Data](target: Data): T = { target.cloneTypeFull.asInstanceOf[T] } } @@ -236,48 +257,59 @@ package experimental { * - Otherwise: fail */ private[chisel3] object cloneSupertype { - def apply[T <: Data](elts: Seq[T], createdType: String)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): T = { + def apply[T <: Data]( + elts: Seq[T], + createdType: String + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { require(!elts.isEmpty, s"can't create $createdType with no inputs") val filteredElts = elts.filter(_ != DontCare) require(!filteredElts.isEmpty, s"can't create $createdType with only DontCare inputs") if (filteredElts.head.isInstanceOf[Bits]) { - val model: T = filteredElts reduce { (elt1: T, elt2: T) => ((elt1, elt2) match { - case (elt1: Bool, elt2: Bool) => elt1 - case (elt1: Bool, elt2: UInt) => elt2 // TODO: what happens with zero width UInts? - case (elt1: UInt, elt2: Bool) => elt1 // TODO: what happens with zero width UInts? - case (elt1: UInt, elt2: UInt) => - // TODO: perhaps redefine Widths to allow >= op? - if (elt1.width == (elt1.width max elt2.width)) elt1 else elt2 - case (elt1: SInt, elt2: SInt) => if (elt1.width == (elt1.width max elt2.width)) elt1 else elt2 - case (elt1: FixedPoint, elt2: FixedPoint) => { - (elt1.binaryPoint, elt2.binaryPoint, elt1.width, elt2.width) match { - case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), KnownWidth(w1), KnownWidth(w2)) => - val maxBinaryPoint = bp1 max bp2 - val maxIntegerWidth = (w1 - bp1) max (w2 - bp2) - FixedPoint((maxIntegerWidth + maxBinaryPoint).W, (maxBinaryPoint).BP) - case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), _, _) => - FixedPoint(Width(), (bp1 max bp2).BP) - case _ => FixedPoint() + val model: T = filteredElts.reduce { (elt1: T, elt2: T) => + ((elt1, elt2) match { + case (elt1: Bool, elt2: Bool) => elt1 + case (elt1: Bool, elt2: UInt) => elt2 // TODO: what happens with zero width UInts? + case (elt1: UInt, elt2: Bool) => elt1 // TODO: what happens with zero width UInts? + case (elt1: UInt, elt2: UInt) => + // TODO: perhaps redefine Widths to allow >= op? + if (elt1.width == (elt1.width.max(elt2.width))) elt1 else elt2 + case (elt1: SInt, elt2: SInt) => if (elt1.width == (elt1.width.max(elt2.width))) elt1 else elt2 + case (elt1: FixedPoint, elt2: FixedPoint) => { + (elt1.binaryPoint, elt2.binaryPoint, elt1.width, elt2.width) match { + case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), KnownWidth(w1), KnownWidth(w2)) => + val maxBinaryPoint = bp1.max(bp2) + val maxIntegerWidth = (w1 - bp1).max(w2 - bp2) + FixedPoint((maxIntegerWidth + maxBinaryPoint).W, (maxBinaryPoint).BP) + case (KnownBinaryPoint(bp1), KnownBinaryPoint(bp2), _, _) => + FixedPoint(Width(), (bp1.max(bp2)).BP) + case _ => FixedPoint() + } } - } - case (elt1: Interval, elt2: Interval) => - val range = if(elt1.range.width == elt1.range.width.max(elt2.range.width)) elt1.range else elt2.range - Interval(range) - case (elt1, elt2) => - throw new AssertionError( - s"can't create $createdType with heterogeneous types ${elt1.getClass} and ${elt2.getClass}") - }).asInstanceOf[T] } + case (elt1: Interval, elt2: Interval) => + val range = if (elt1.range.width == elt1.range.width.max(elt2.range.width)) elt1.range else elt2.range + Interval(range) + case (elt1, elt2) => + throw new AssertionError( + s"can't create $createdType with heterogeneous types ${elt1.getClass} and ${elt2.getClass}" + ) + }).asInstanceOf[T] + } model.cloneTypeFull - } - else { + } else { for (elt <- filteredElts.tail) { - require(elt.getClass == filteredElts.head.getClass, - s"can't create $createdType with heterogeneous types ${filteredElts.head.getClass} and ${elt.getClass}") - require(elt typeEquivalent filteredElts.head, - s"can't create $createdType with non-equivalent types ${filteredElts.head} and ${elt}") + require( + elt.getClass == filteredElts.head.getClass, + s"can't create $createdType with heterogeneous types ${filteredElts.head.getClass} and ${elt.getClass}" + ) + require( + elt.typeEquivalent(filteredElts.head), + s"can't create $createdType with non-equivalent types ${filteredElts.head} and ${elt}" + ) } filteredElts.head.cloneTypeFull } @@ -288,14 +320,16 @@ private[chisel3] object cloneSupertype { private[chisel3] object getRecursiveFields { def apply(data: Data, path: String): Seq[(Data, String)] = data match { case data: Record => - data.elements.map { case (fieldName, fieldData) => - getRecursiveFields(fieldData, s"$path.$fieldName") + data.elements.map { + case (fieldName, fieldData) => + getRecursiveFields(fieldData, s"$path.$fieldName") }.fold(Seq(data -> path)) { _ ++ _ } case data: Vec[_] => - data.getElements.zipWithIndex.map { case (fieldData, fieldIndex) => - getRecursiveFields(fieldData, path = s"$path($fieldIndex)") + data.getElements.zipWithIndex.map { + case (fieldData, fieldIndex) => + getRecursiveFields(fieldData, path = s"$path($fieldIndex)") }.fold(Seq(data -> path)) { _ ++ _ } @@ -305,13 +339,15 @@ private[chisel3] object getRecursiveFields { def lazily(data: Data, path: String): Seq[(Data, String)] = data match { case data: Record => LazyList(data -> path) ++ - data.elements.view.flatMap { case (fieldName, fieldData) => - getRecursiveFields(fieldData, s"$path.$fieldName") + data.elements.view.flatMap { + case (fieldName, fieldData) => + getRecursiveFields(fieldData, s"$path.$fieldName") } case data: Vec[_] => LazyList(data -> path) ++ - data.getElements.view.zipWithIndex.flatMap { case (fieldData, fieldIndex) => - getRecursiveFields(fieldData, path = s"$path($fieldIndex)") + data.getElements.view.zipWithIndex.flatMap { + case (fieldData, fieldIndex) => + getRecursiveFields(fieldData, path = s"$path($fieldIndex)") } case data: Element => LazyList(data -> path) } @@ -322,21 +358,29 @@ private[chisel3] object getRecursiveFields { private[chisel3] object getMatchedFields { def apply(x: Data, y: Data): Seq[(Data, Data)] = (x, y) match { case (x: Element, y: Element) => - require(x typeEquivalent y) + require(x.typeEquivalent(y)) Seq(x -> y) case (x: Record, y: Record) => - (x.elements zip y.elements).map { case ((xName, xElt), (yName, yElt)) => - require(xName == yName) // assume fields returned in same, deterministic order - getMatchedFields(xElt, yElt) - }.fold(Seq(x -> y)) { - _ ++ _ - } + (x.elements + .zip(y.elements)) + .map { + case ((xName, xElt), (yName, yElt)) => + require(xName == yName) // assume fields returned in same, deterministic order + getMatchedFields(xElt, yElt) + } + .fold(Seq(x -> y)) { + _ ++ _ + } case (x: Vec[_], y: Vec[_]) => - (x.getElements zip y.getElements).map { case (xElt, yElt) => - getMatchedFields(xElt, yElt) - }.fold(Seq(x -> y)) { - _ ++ _ - } + (x.getElements + .zip(y.getElements)) + .map { + case (xElt, yElt) => + getMatchedFields(xElt, yElt) + } + .fold(Seq(x -> y)) { + _ ++ _ + } } } @@ -350,25 +394,25 @@ object chiselTypeOf { } /** -* Input, Output, and Flipped are used to define the directions of Module IOs. -* -* Note that they currently clone their source argument, including its bindings. -* -* Thus, an error will be thrown if these are used on bound Data -*/ + * Input, Output, and Flipped are used to define the directions of Module IOs. + * + * Note that they currently clone their source argument, including its bindings. + * + * Thus, an error will be thrown if these are used on bound Data + */ object Input { - def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + def apply[T <: Data](source: T)(implicit compileOptions: CompileOptions): T = { SpecifiedDirection.specifiedDirection(source)(SpecifiedDirection.Input) } } object Output { - def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + def apply[T <: Data](source: T)(implicit compileOptions: CompileOptions): T = { SpecifiedDirection.specifiedDirection(source)(SpecifiedDirection.Output) } } object Flipped { - def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + def apply[T <: Data](source: T)(implicit compileOptions: CompileOptions): T = { SpecifiedDirection.specifiedDirection(source)(SpecifiedDirection.flip(source.specifiedDirection)) } } @@ -386,8 +430,8 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { @deprecated("pending removal once all instances replaced", "chisel3") private[chisel3] def flatten: IndexedSeq[Element] = { this match { - case elt: Aggregate => elt.getElements.toIndexedSeq flatMap {_.flatten} - case elt: Element => IndexedSeq(elt) + case elt: Aggregate => elt.getElements.toIndexedSeq.flatMap { _.flatten } + case elt: Element => IndexedSeq(elt) case elt => throwException(s"Cannot flatten type ${elt.getClass}") } } @@ -396,13 +440,13 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { topBindingOpt match { // Ports are special in that the autoSeed will keep the first name, not the last name case Some(PortBinding(m)) if hasAutoSeed && Builder.currentModule.contains(m) => this - case _ => super.autoSeed(name) + case _ => super.autoSeed(name) } } // User-specified direction, local at this node only. // Note that the actual direction of this node can differ from child and parent specifiedDirection. - private var _specifiedDirection: SpecifiedDirection = SpecifiedDirection.Unspecified + private var _specifiedDirection: SpecifiedDirection = SpecifiedDirection.Unspecified private[chisel3] def specifiedDirection: SpecifiedDirection = _specifiedDirection private[chisel3] def specifiedDirection_=(direction: SpecifiedDirection) = { if (_specifiedDirection != SpecifiedDirection.Unspecified) { @@ -422,8 +466,8 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { private[chisel3] def _assignCompatibilityExplicitDirection: Unit = { (this, _specifiedDirection) match { case (_: Analog, _) => // nothing to do - case (_, SpecifiedDirection.Unspecified) => _specifiedDirection = SpecifiedDirection.Output - case (_, SpecifiedDirection.Flip) => _specifiedDirection = SpecifiedDirection.Input + case (_, SpecifiedDirection.Unspecified) => _specifiedDirection = SpecifiedDirection.Output + case (_, SpecifiedDirection.Flip) => _specifiedDirection = SpecifiedDirection.Input case (_, SpecifiedDirection.Input | SpecifiedDirection.Output) => // nothing to do } } @@ -503,16 +547,16 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { private[chisel3] def _bindingToString(topBindingOpt: TopBinding): String = topBindingOpt match { - case OpBinding(_, _) => "OpResult" - case MemoryPortBinding(_, _) => "MemPort" - case PortBinding(_) => "IO" - case RegBinding(_, _) => "Reg" - case WireBinding(_, _) => "Wire" - case DontCareBinding() => "(DontCare)" + case OpBinding(_, _) => "OpResult" + case MemoryPortBinding(_, _) => "MemPort" + case PortBinding(_) => "IO" + case RegBinding(_, _) => "Reg" + case WireBinding(_, _) => "Wire" + case DontCareBinding() => "(DontCare)" case ElementLitBinding(litArg) => "(unhandled literal)" - case BundleLitBinding(litMap) => "(unhandled bundle literal)" - case VecLitBinding(litMap) => "(unhandled vec literal)" - case _ => "" + case BundleLitBinding(litMap) => "(unhandled bundle literal)" + case VecLitBinding(litMap) => "(unhandled vec literal)" + case _ => "" } private[chisel3] def earlyName: String = Arg.earlyLocalName(this) @@ -526,13 +570,18 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { private[chisel3] def badConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = throwException(s"cannot connect ${this} and ${that}") - private[chisel3] def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { + private[chisel3] def connect( + that: Data + )( + implicit sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions + ): Unit = { if (connectCompileOptions.checkSynthesizable) { requireIsHardware(this, "data to be connected") requireIsHardware(that, "data to be connected") this.topBinding match { case _: ReadOnlyBinding => throwException(s"Cannot reassign to read-only $this") - case _ => // fine + case _ => // fine } try { MonoConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.referenceUserModule) @@ -543,10 +592,15 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { ) } } else { - this legacyConnect that + this.legacyConnect(that) } } - private[chisel3] def bulkConnect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { + private[chisel3] def bulkConnect( + that: Data + )( + implicit sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions + ): Unit = { if (connectCompileOptions.checkSynthesizable) { requireIsHardware(this, s"data to be bulk-connected") requireIsHardware(that, s"data to be bulk-connected") @@ -554,7 +608,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { case (_: ReadOnlyBinding, _: ReadOnlyBinding) => throwException(s"Both $this and $that are read-only") // DontCare cannot be a sink (LHS) case (_: DontCareBinding, _) => throw BiConnect.DontCareCantBeSink - case _ => // fine + case _ => // fine } try { BiConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.referenceUserModule) @@ -565,7 +619,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { ) } } else { - this legacyConnect that + this.legacyConnect(that) } } @@ -578,7 +632,8 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { val mod = topBindingOpt.flatMap(_.location) topBindingOpt match { case Some(tb: TopBinding) if (mod == Builder.currentModule) => - case Some(pb: PortBinding) if (mod.flatMap(Builder.retrieveParent(_,Builder.currentModule.get)) == Builder.currentModule) => + case Some(pb: PortBinding) + if (mod.flatMap(Builder.retrieveParent(_, Builder.currentModule.get)) == Builder.currentModule) => case Some(_: UnconstrainedBinding) => case _ => throwException(s"operand '$this' is not visible from the current module") @@ -593,7 +648,8 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { requireIsHardware(this) requireVisible() topBindingOpt match { - case Some(binding: ReadOnlyBinding) => throwException(s"internal error: attempted to generate LHS ref to ReadOnlyBinding $binding") + case Some(binding: ReadOnlyBinding) => + throwException(s"internal error: attempted to generate LHS ref to ReadOnlyBinding $binding") case Some(binding: TopBinding) => Node(this) case opt => throwException(s"internal error: unknown binding $opt in generating LHS ref") } @@ -622,12 +678,12 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { case Some(BundleLitBinding(litMap)) => litMap.get(this) match { case Some(litArg) => litArg - case _ => materializeWire() // FIXME FIRRTL doesn't have Bundle literal expressions + case _ => materializeWire() // FIXME FIRRTL doesn't have Bundle literal expressions } case Some(VecLitBinding(litMap)) => litMap.get(this) match { case Some(litArg) => litArg - case _ => materializeWire() // FIXME FIRRTL doesn't have Vec literal expressions + case _ => materializeWire() // FIXME FIRRTL doesn't have Vec literal expressions } case Some(DontCareBinding()) => materializeWire() // FIXME FIRRTL doesn't have a DontCare expression so materialize a Wire @@ -643,15 +699,14 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { } } - // Recursively set the parent of the start Data and any children (eg. in an Aggregate) private[chisel3] def setAllParents(parent: Option[BaseModule]): Unit = { def rec(data: Data): Unit = { data._parent = parent data match { - case _: Element => - case agg: Aggregate => - agg.getElements.foreach(rec) + case _: Element => + case agg: Aggregate => + agg.getElements.foreach(rec) } } rec(this) @@ -675,7 +730,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { * Directionality data is still preserved. */ private[chisel3] def cloneTypeFull: this.type = { - val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings + val clone = this.cloneType.asInstanceOf[this.type] // get a fresh object, without bindings // Only the top-level direction needs to be fixed up, cloneType should do the rest clone.specifiedDirection = specifiedDirection clone @@ -688,7 +743,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { * @param that the $coll to connect to * @group Connect */ - final def := (that: => Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = { + final def :=(that: => Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = { prefix(this) { this.connect(that)(sourceInfo, connectionCompileOptions) } @@ -701,7 +756,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { * @param that the $coll to connect to * @group Connect */ - final def <> (that: => Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = { + final def <>(that: => Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = { prefix(this) { this.bulkConnect(that)(sourceInfo, connectionCompileOptions) } @@ -709,32 +764,42 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { def isLit: Boolean = litOption.isDefined - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def isLit(dummy: Int*): Boolean = isLit - /** - * If this is a literal that is representable as bits, returns the value as a BigInt. - * If not a literal, or not representable as bits (for example, is or contains Analog), returns None. - */ + * If this is a literal that is representable as bits, returns the value as a BigInt. + * If not a literal, or not representable as bits (for example, is or contains Analog), returns None. + */ def litOption: Option[BigInt] - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def litOption(dummy: Int*): Option[BigInt] = litOption /** - * Returns the literal value if this is a literal that is representable as bits, otherwise crashes. - */ + * Returns the literal value if this is a literal that is representable as bits, otherwise crashes. + */ def litValue: BigInt = litOption.get - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def litValue(dummy: Int*): BigInt = litValue /** Returns the width, in bits, if currently known. */ final def getWidth: Int = if (isWidthKnown) width.get else throwException(s"Width of $this is unknown!") + /** Returns whether the width is currently known. */ final def isWidthKnown: Boolean = width.known + /** Returns Some(width) if the width is known, else None. */ final def widthOption: Option[Int] = if (isWidthKnown) Some(getWidth) else None @@ -757,8 +822,12 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { /** Assigns this node from Bits type. Internal implementation for asTypeOf. */ - private[chisel3] def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit + private[chisel3] def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit /** Reinterpret cast to UInt. * @@ -769,7 +838,10 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { */ final def asUInt: UInt = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def asUInt(dummy: Int*): UInt = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -780,6 +852,7 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc { } trait WireFactory { + /** Construct a [[Wire]] from a type template * @param t The template from which to construct this wire */ @@ -819,7 +892,6 @@ trait WireFactory { * // Width of w4.unknown is inferred * // Width of w4.known is set to 8 * }}} - * */ object Wire extends WireFactory @@ -884,7 +956,13 @@ object Wire extends WireFactory */ object WireDefault { - private def applyImpl[T <: Data](t: T, init: Data)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + private def applyImpl[T <: Data]( + t: T, + init: Data + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { implicit val noSourceInfo = UnlocatableSourceInfo val x = Wire(t) requireIsHardware(init, "wire initializer") @@ -897,7 +975,13 @@ object WireDefault { * @param init The default connection to this [[Wire]], can only be [[DontCare]] * @note This is really just a specialized form of `apply[T <: Data](t: T, init: T): T` with [[DontCare]] as `init` */ - def apply[T <: Data](t: T, init: DontCare.type)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + def apply[T <: Data]( + t: T, + init: DontCare.type + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { applyImpl(t, init) } @@ -941,7 +1025,12 @@ final case object DontCare extends Element { def toPrintable: Printable = PString("DONTCARE") - private[chisel3] def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = { + private[chisel3] def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { Builder.error("connectFromBits: DontCare cannot be a connection sink (LHS)") } diff --git a/core/src/main/scala/chisel3/Element.scala b/core/src/main/scala/chisel3/Element.scala index bc006922..401f2bdf 100644 --- a/core/src/main/scala/chisel3/Element.scala +++ b/core/src/main/scala/chisel3/Element.scala @@ -14,8 +14,8 @@ import chisel3.internal._ */ abstract class Element extends Data { private[chisel3] final def allElements: Seq[Element] = Seq(this) - def widthKnown: Boolean = width.known - def name: String = getRef.name + def widthKnown: Boolean = width.known + def name: String = getRef.name private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = { _parent.foreach(_.addId(this)) @@ -26,27 +26,30 @@ abstract class Element extends Data { private[chisel3] override def topBindingOpt: Option[TopBinding] = super.topBindingOpt match { // Translate Bundle lit bindings to Element lit bindings - case Some(BundleLitBinding(litMap)) => litMap.get(this) match { - case Some(litArg) => Some(ElementLitBinding(litArg)) - case _ => Some(DontCareBinding()) - } - case Some(VecLitBinding(litMap)) => litMap.get(this) match { - case Some(litArg) => Some(ElementLitBinding(litArg)) - case _ => Some(DontCareBinding()) - } - case Some(b @ AggregateViewBinding(viewMap, _)) => viewMap.get(this) match { - case Some(elt) => Some(ViewBinding(elt)) - case _ => throwException(s"Internal Error! $this missing from topBinding $b") - } + case Some(BundleLitBinding(litMap)) => + litMap.get(this) match { + case Some(litArg) => Some(ElementLitBinding(litArg)) + case _ => Some(DontCareBinding()) + } + case Some(VecLitBinding(litMap)) => + litMap.get(this) match { + case Some(litArg) => Some(ElementLitBinding(litArg)) + case _ => Some(DontCareBinding()) + } + case Some(b @ AggregateViewBinding(viewMap, _)) => + viewMap.get(this) match { + case Some(elt) => Some(ViewBinding(elt)) + case _ => throwException(s"Internal Error! $this missing from topBinding $b") + } case topBindingOpt => topBindingOpt } private[chisel3] def litArgOption: Option[LitArg] = topBindingOpt match { case Some(ElementLitBinding(litArg)) => Some(litArg) - case _ => None + case _ => None } - override def litOption: Option[BigInt] = litArgOption.map(_.num) + override def litOption: Option[BigInt] = litArgOption.map(_.num) private[chisel3] def litIsForcedWidth: Option[Boolean] = litArgOption.map(_.forcedWidth) private[chisel3] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = { diff --git a/core/src/main/scala/chisel3/Mem.scala b/core/src/main/scala/chisel3/Mem.scala index aeacf052..ff5072ad 100644 --- a/core/src/main/scala/chisel3/Mem.scala +++ b/core/src/main/scala/chisel3/Mem.scala @@ -9,8 +9,7 @@ import firrtl.{ir => fir} import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ -import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, MemTransform} - +import chisel3.internal.sourceinfo.{MemTransform, SourceInfo, SourceInfoTransform, UnlocatableSourceInfo} object Mem { @@ -29,11 +28,17 @@ object Mem { def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T] /** @group SourceInfoTransformMacro */ - def do_apply[T <: Data](size: BigInt, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Mem[T] = { + def do_apply[T <: Data]( + size: BigInt, + t: T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Mem[T] = { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "memory type") } - val mt = t.cloneTypeFull + val mt = t.cloneTypeFull val mem = new Mem(mt, size) mt.bind(MemTypeBinding(mem)) pushCommand(DefMemory(sourceInfo, mem, mt, size)) @@ -45,7 +50,10 @@ object Mem { do_apply(BigInt(size), t)(sourceInfo, compileOptions) } -sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) extends HasId with NamedComponent with SourceInfoDoc { +sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) + extends HasId + with NamedComponent + with SourceInfoDoc { _parent.foreach(_.addId(this)) // REVIEW TODO: make accessors (static/dynamic, read/write) combinations consistent. @@ -107,7 +115,14 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) extends H * * @note this is only allowed if the memory's element data type is a Vec */ - def write(idx: UInt, data: T, mask: Seq[Bool]) (implicit evidence: T <:< Vec[_], compileOptions: CompileOptions): Unit = { + def write( + idx: UInt, + data: T, + mask: Seq[Bool] + )( + implicit evidence: T <:< Vec[_], + compileOptions: CompileOptions + ): Unit = { implicit val sourceInfo = UnlocatableSourceInfo val accessor = makePort(sourceInfo, idx, MemPortDirection.WRITE).asInstanceOf[Vec[Data]] val dataVec = data.asInstanceOf[Vec[Data]] @@ -117,17 +132,22 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) extends H if (accessor.length != mask.length) { Builder.error(s"Mem write mask must contain ${accessor.length} elements (found ${mask.length})") } - for (((cond, port), datum) <- mask zip accessor zip dataVec) - when (cond) { port := datum } + for (((cond, port), datum) <- mask.zip(accessor).zip(dataVec)) + when(cond) { port := datum } } - private def makePort(sourceInfo: SourceInfo, idx: UInt, dir: MemPortDirection)(implicit compileOptions: CompileOptions): T = { + private def makePort( + sourceInfo: SourceInfo, + idx: UInt, + dir: MemPortDirection + )( + implicit compileOptions: CompileOptions + ): T = { requireIsHardware(idx, "memory port index") val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions) val port = pushCommand( - DefMemPort(sourceInfo, - t.cloneTypeFull, Node(this), dir, i.ref, Builder.forcedClock.ref) + DefMemPort(sourceInfo, t.cloneTypeFull, Node(this), dir, i.ref, Builder.forcedClock.ref) ).id // Bind each element of port to being a MemoryPort port.bind(MemoryPortBinding(Builder.forcedUserModule, Builder.currentWhen)) @@ -148,7 +168,6 @@ sealed class Mem[T <: Data] private (t: T, length: BigInt) extends MemBase(t, le object SyncReadMem { - type ReadUnderWrite = fir.ReadUnderWrite.Value val Undefined = fir.ReadUnderWrite.Undefined val ReadFirst = fir.ReadUnderWrite.Old @@ -171,11 +190,18 @@ object SyncReadMem { def apply[T <: Data](size: Int, t: T, ruw: ReadUnderWrite): SyncReadMem[T] = macro MemTransform.apply_ruw[T] /** @group SourceInfoTransformMacro */ - def do_apply[T <: Data](size: BigInt, t: T, ruw: ReadUnderWrite = Undefined)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = { + def do_apply[T <: Data]( + size: BigInt, + t: T, + ruw: ReadUnderWrite = Undefined + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SyncReadMem[T] = { if (compileOptions.declaredTypeMustBeUnbound) { requireIsChiselType(t, "memory type") } - val mt = t.cloneTypeFull + val mt = t.cloneTypeFull val mem = new SyncReadMem(mt, size, ruw) mt.bind(MemTypeBinding(mem)) pushCommand(DefSeqMemory(sourceInfo, mem, mt, size, ruw)) @@ -184,12 +210,25 @@ object SyncReadMem { /** @group SourceInfoTransformMacro */ // Alternate signatures can't use default parameter values - def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = + def do_apply[T <: Data]( + size: Int, + t: T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SyncReadMem[T] = do_apply(BigInt(size), t)(sourceInfo, compileOptions) /** @group SourceInfoTransformMacro */ // Alternate signatures can't use default parameter values - def do_apply[T <: Data](size: Int, t: T, ruw: ReadUnderWrite)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = + def do_apply[T <: Data]( + size: Int, + t: T, + ruw: ReadUnderWrite + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SyncReadMem[T] = do_apply(BigInt(size), t, ruw)(sourceInfo, compileOptions) } @@ -203,7 +242,8 @@ object SyncReadMem { * @note when multiple conflicting writes are performed on a Mem element, the * result is undefined (unlike Vec, where the last assignment wins) */ -sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) extends MemBase[T](t, n) { +sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) + extends MemBase[T](t, n) { def read(x: UInt, en: Bool): T = macro SourceInfoTransform.xEnArg /** @group SourceInfoTransformMacro */ @@ -211,14 +251,14 @@ sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite val a = Wire(UInt()) a := DontCare var port: Option[T] = None - when (enable) { + when(enable) { a := addr port = Some(super.do_read(a)) } port.get } - /** @group SourceInfoTransformMacro*/ + /** @group SourceInfoTransformMacro */ override def do_read(idx: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = do_read(addr = idx, enable = true.B) // note: we implement do_read(addr) for SyncReadMem in terms of do_read(addr, en) in order to ensure that diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index 7ba24585..3611f5dd 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -15,6 +15,7 @@ import _root_.firrtl.annotations.{IsModule, ModuleName, ModuleTarget} import _root_.firrtl.AnnotationSeq object Module extends SourceInfoDoc { + /** A wrapper method that all Module instantiations must be wrapped in * (necessary to help Chisel track internal state). * @@ -25,12 +26,12 @@ object Module extends SourceInfoDoc { def apply[T <: BaseModule](bc: => T): T = macro InstTransform.apply[T] /** @group SourceInfoTransformMacro */ - def do_apply[T <: BaseModule](bc: => T) - (implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): T = { + def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { if (Builder.readyForModuleConstr) { - throwException("Error: Called Module() twice without instantiating a Module." + - sourceInfo.makeMessage(" See " + _)) + throwException( + "Error: Called Module() twice without instantiating a Module." + + sourceInfo.makeMessage(" See " + _) + ) } Builder.readyForModuleConstr = true @@ -38,7 +39,7 @@ object Module extends SourceInfoDoc { val parentWhenStack = Builder.whenStack // Save then clear clock and reset to prevent leaking scope, must be set again in the Module - val (saveClock, saveReset) = (Builder.currentClock, Builder.currentReset) + val (saveClock, saveReset) = (Builder.currentClock, Builder.currentReset) val savePrefix = Builder.getPrefix Builder.clearPrefix() Builder.currentClock = None @@ -49,19 +50,21 @@ object Module extends SourceInfoDoc { // - unset readyForModuleConstr // - reset whenStack to be empty // - set currentClockAndReset - val module: T = bc // bc is actually evaluated here + val module: T = bc // bc is actually evaluated here if (Builder.whenDepth != 0) { throwException("Internal Error! when() scope depth is != 0, this should have been caught!") } if (Builder.readyForModuleConstr) { - throwException("Error: attempted to instantiate a Module, but nothing happened. " + - "This is probably due to rewrapping a Module instance with Module()." + - sourceInfo.makeMessage(" See " + _)) + throwException( + "Error: attempted to instantiate a Module, but nothing happened. " + + "This is probably due to rewrapping a Module instance with Module()." + + sourceInfo.makeMessage(" See " + _) + ) } Builder.currentModule = parent // Back to parent! Builder.whenStack = parentWhenStack - Builder.currentClock = saveClock // Back to clock and reset scope + Builder.currentClock = saveClock // Back to clock and reset scope Builder.currentReset = saveReset // Only add the component if the module generates one @@ -84,17 +87,22 @@ object Module extends SourceInfoDoc { /** Returns the implicit Clock */ def clock: Clock = Builder.forcedClock + /** Returns the implicit Reset */ def reset: Reset = Builder.forcedReset + /** Returns the current Module */ def currentModule: Option[BaseModule] = Builder.currentModule - private[chisel3] def do_pseudo_apply[T <: BaseModule](bc: => T) - (implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): T = { + private[chisel3] def do_pseudo_apply[T <: BaseModule]( + bc: => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { val parent = Builder.currentModule - val module: T = bc // bc is actually evaluated here + val module: T = bc // bc is actually evaluated here module } @@ -150,12 +158,12 @@ abstract class Module(implicit moduleCompileOptions: CompileOptions) extends Raw } } - package experimental { import chisel3.internal.requireIsChiselType // Fix ambiguous import object IO { + /** Constructs a port for the current Module * * This must wrap the datatype used to set the io field of any Module. @@ -170,20 +178,21 @@ package experimental { * requested (so that all calls to ports will return the same information). * Internal API. */ - def apply[T<:Data](iodef: T): T = { + def apply[T <: Data](iodef: T): T = { val module = Module.currentModule.get // Impossible to fail require(!module.isClosed, "Can't add more ports after module close") requireIsChiselType(iodef, "io type") // Clone the IO so we preserve immutability of data types - val iodefClone = try { - iodef.cloneTypeFull - } catch { - // For now this is going to be just a deprecation so we don't suddenly break everyone's code - case e: AutoClonetypeException => - Builder.deprecated(e.getMessage, Some(s"${iodef.getClass}")) - iodef - } + val iodefClone = + try { + iodef.cloneTypeFull + } catch { + // For now this is going to be just a deprecation so we don't suddenly break everyone's code + case e: AutoClonetypeException => + Builder.deprecated(e.getMessage, Some(s"${iodef.getClass}")) + iodef + } module.bindIoInPlace(iodefClone) iodefClone } @@ -192,9 +201,10 @@ package experimental { package internal { import chisel3.experimental.BaseModule - import chisel3.experimental.hierarchy.{IsInstantiable, Proto, Clone} + import chisel3.experimental.hierarchy.{Clone, IsInstantiable, Proto} object BaseModule { + /** Represents a clone of an underlying object. This is used to support CloneModuleAsRecord and Instance/Definition. * * @note We don't actually "clone" anything in the traditional sense but is a placeholder so we lazily clone internal state @@ -217,7 +227,7 @@ package internal { } // Private internal class to serve as a _parent for Data in cloned ports - private[chisel3] class ModuleClone[T <: BaseModule] (val getProto: T) extends PseudoModule with IsClone[T] { + private[chisel3] class ModuleClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] { override def toString = s"ModuleClone(${getProto})" def getPorts = _portsRecord // ClonePorts that hold the bound ports for this module @@ -226,7 +236,7 @@ package internal { // This is necessary for correctly supporting .toTarget on a Module Clone. If it is made from the // Instance/Definition API, it should return an instanceTarget. If made from CMAR, it should return a // ModuleTarget. - private[chisel3] var _madeFromDefinition: Boolean = false + private[chisel3] var _madeFromDefinition: Boolean = false // Don't generate a component, but point to the one for the cloned Module private[chisel3] def generateComponent(): Option[Component] = { require(!_closed, "Can't generate module more than once") @@ -248,14 +258,14 @@ package internal { private[chisel3] def setRefAndPortsRef(namespace: Namespace): Unit = { val record = _portsRecord // Use .forceName to re-use default name resolving behavior - record.forceName(None, default=this.desiredName, namespace) + record.forceName(None, default = this.desiredName, namespace) // Now take the Ref that forceName set and convert it to the correct Arg val instName = record.getRef match { case Ref(name) => name - case bad => throwException(s"Internal Error! Cloned-module Record $record has unexpected ref $bad") + case bad => throwException(s"Internal Error! Cloned-module Record $record has unexpected ref $bad") } // Set both the record and the module to have the same instance name - record.setRef(ModuleCloneIO(getProto, instName), force=true) // force because we did .forceName first + record.setRef(ModuleCloneIO(getProto, instName), force = true) // force because we did .forceName first this.setRef(Ref(instName)) } } @@ -269,7 +279,9 @@ package internal { * @note In addition, the instance name of an InstanceClone is going to be the SAME as the proto, but this is not true * for ModuleClone. */ - private[chisel3] final class InstanceClone[T <: BaseModule] (val getProto: T, val instName: () => String) extends PseudoModule with IsClone[T] { + private[chisel3] final class InstanceClone[T <: BaseModule](val getProto: T, val instName: () => String) + extends PseudoModule + with IsClone[T] { override def toString = s"InstanceClone(${getProto})" // No addition components are generated private[chisel3] def generateComponent(): Option[Component] = None @@ -291,7 +303,7 @@ package internal { * target whose root is the Definition. This DefinitionClone is used to represent the root parent of the * InstanceClone (which represents the returned module). */ - private[chisel3] class DefinitionClone[T <: BaseModule] (val getProto: T) extends PseudoModule with IsClone[T] { + private[chisel3] class DefinitionClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] { override def toString = s"DefinitionClone(${getProto})" // No addition components are generated private[chisel3] def generateComponent(): Option[Component] = None @@ -313,13 +325,18 @@ package internal { * @note These are not true Data (the Record doesn't correspond to anything in the emitted * FIRRTL yet its elements *do*) so have some very specialized behavior. */ - private[chisel3] class ClonePorts (elts: Data*)(implicit compileOptions: CompileOptions) extends Record { + private[chisel3] class ClonePorts(elts: Data*)(implicit compileOptions: CompileOptions) extends Record { val elements = ListMap(elts.map(d => d.instanceName -> d.cloneTypeFull): _*) def apply(field: String) = elements(field) override def cloneType = (new ClonePorts(elts: _*)).asInstanceOf[this.type] } - private[chisel3] def cloneIORecord(proto: BaseModule)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): ClonePorts = { + private[chisel3] def cloneIORecord( + proto: BaseModule + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): ClonePorts = { require(proto.isClosed, "Can't clone a module before module close") // Fake Module to serve as the _parent of the cloned ports // We make this before clonePorts because we want it to come up first in naming in @@ -353,11 +370,12 @@ package experimental { object BaseModule { implicit class BaseModuleExtensions[T <: BaseModule](b: T) { - import chisel3.experimental.hierarchy.{Instance, Definition} - def toInstance: Instance[T] = new Instance(Proto(b)) + import chisel3.experimental.hierarchy.{Definition, Instance} + def toInstance: Instance[T] = new Instance(Proto(b)) def toDefinition: Definition[T] = new Definition(Proto(b)) } } + /** Abstract base class for Modules, an instantiable organizational unit for RTL. */ // TODO: seal this? @@ -461,30 +479,34 @@ package experimental { val baseName = this.getClass.getName /* A sequence of string filters applied to the name */ - val filters: Seq[String => String] = Seq( - ((a: String) => raw"\$$+anon".r.replaceAllIn(a, "_Anon")) // Merge the "$$anon" name with previous name - ) + val filters: Seq[String => String] = + Seq(((a: String) => raw"\$$+anon".r.replaceAllIn(a, "_Anon")) // Merge the "$$anon" name with previous name + ) filters - .foldLeft(baseName){ case (str, filter) => filter(str) } // 1. Apply filters to baseName - .split("\\.|\\$") // 2. Split string at '.' or '$' - .filterNot(_.forall(_.isDigit)) // 3. Drop purely numeric names - .last // 4. Use the last name + .foldLeft(baseName) { case (str, filter) => filter(str) } // 1. Apply filters to baseName + .split("\\.|\\$") // 2. Split string at '.' or '$' + .filterNot(_.forall(_.isDigit)) // 3. Drop purely numeric names + .last // 4. Use the last name } /** Legalized name of this module. */ - final lazy val name = try { - // PseudoModules are not "true modules" and thus should share - // their original modules names without uniquification - this match { - case _: PseudoModule => desiredName - case _ => Builder.globalNamespace.name(desiredName) + final lazy val name = + try { + // PseudoModules are not "true modules" and thus should share + // their original modules names without uniquification + this match { + case _: PseudoModule => desiredName + case _ => Builder.globalNamespace.name(desiredName) + } + } catch { + case e: NullPointerException => + throwException( + s"Error: desiredName of ${this.getClass.getName} is null. Did you evaluate 'name' before all values needed by desiredName were available?", + e + ) + case t: Throwable => throw t } - } catch { - case e: NullPointerException => throwException( - s"Error: desiredName of ${this.getClass.getName} is null. Did you evaluate 'name' before all values needed by desiredName were available?", e) - case t: Throwable => throw t - } /** Returns a FIRRTL ModuleName that references this object * @@ -497,8 +519,10 @@ package experimental { * @note Should not be called until circuit elaboration is complete */ final def toTarget: ModuleTarget = this match { - case m: internal.BaseModule.InstanceClone[_] => throwException(s"Internal Error! It's not legal to call .toTarget on an InstanceClone. $m") - case m: internal.BaseModule.DefinitionClone[_] => throwException(s"Internal Error! It's not legal to call .toTarget on an DefinitionClone. $m") + case m: internal.BaseModule.InstanceClone[_] => + throwException(s"Internal Error! It's not legal to call .toTarget on an InstanceClone. $m") + case m: internal.BaseModule.DefinitionClone[_] => + throwException(s"Internal Error! It's not legal to call .toTarget on an DefinitionClone. $m") case _ => ModuleTarget(this.circuitName, this.name) } @@ -514,10 +538,13 @@ package experimental { * the correct [[InstanceTarget]]s whenever using the Definition/Instance API. */ private[chisel3] def getTarget: IsModule = this match { - case m: internal.BaseModule.InstanceClone[_] if m._parent.nonEmpty => m._parent.get.getTarget.instOf(instanceName, name) - case m: internal.BaseModule.ModuleClone[_] if m._madeFromDefinition => m._parent.get.getTarget.instOf(instanceName, name) + case m: internal.BaseModule.InstanceClone[_] if m._parent.nonEmpty => + m._parent.get.getTarget.instOf(instanceName, name) + case m: internal.BaseModule.ModuleClone[_] if m._madeFromDefinition => + m._parent.get.getTarget.instOf(instanceName, name) // Without this, we get the wrong CircuitName for the Definition - case m: internal.BaseModule.DefinitionClone[_] if m._circuit.nonEmpty => ModuleTarget(this._circuit.get.circuitName, this.name) + case m: internal.BaseModule.DefinitionClone[_] if m._circuit.nonEmpty => + ModuleTarget(this._circuit.get.circuitName, this.name) case _ => this.toTarget } @@ -528,7 +555,7 @@ package experimental { final def toAbsoluteTarget: IsModule = { _parent match { case Some(parent) => parent.toAbsoluteTarget.instOf(this.instanceName, name) - case None => + case None => // FIXME Special handling for Views - evidence of "weirdness" of .toAbsoluteTarget // In theory, .toAbsoluteTarget should not be necessary, .toTarget combined with the // target disambiguation in FIRRTL's deduplication transform should ensure that .toTarget @@ -619,17 +646,19 @@ package experimental { data match { case data: Element if insideCompat => data._assignCompatibilityExplicitDirection case data: Element => // Not inside a compatibility Bundle, nothing to be done - case data: Aggregate => data.specifiedDirection match { - // Recurse into children to ensure explicit direction set somewhere - case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => data match { - case record: Record => - val compatRecord = !record.compileOptions.dontAssumeDirectionality - record.getElements.foreach(assignCompatDir(_, compatRecord)) - case vec: Vec[_] => - vec.getElements.foreach(assignCompatDir(_, insideCompat)) + case data: Aggregate => + data.specifiedDirection match { + // Recurse into children to ensure explicit direction set somewhere + case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => + data match { + case record: Record => + val compatRecord = !record.compileOptions.dontAssumeDirectionality + record.getElements.foreach(assignCompatDir(_, compatRecord)) + case vec: Vec[_] => + vec.getElements.foreach(assignCompatDir(_, insideCompat)) + } + case SpecifiedDirection.Input | SpecifiedDirection.Output => // forced assign, nothing to do } - case SpecifiedDirection.Input | SpecifiedDirection.Output => // forced assign, nothing to do - } } } @@ -669,10 +698,12 @@ package experimental { /** Signal name (for simulation). */ override def instanceName: String = - if (_parent == None) name else _component match { - case None => getRef.name - case Some(c) => getRef fullName c - } + if (_parent == None) name + else + _component match { + case None => getRef.name + case Some(c) => getRef.fullName(c) + } } } diff --git a/core/src/main/scala/chisel3/ModuleAspect.scala b/core/src/main/scala/chisel3/ModuleAspect.scala index a528fa72..471ab980 100644 --- a/core/src/main/scala/chisel3/ModuleAspect.scala +++ b/core/src/main/scala/chisel3/ModuleAspect.scala @@ -12,8 +12,9 @@ import chisel3.internal.{Builder, PseudoModule} * @param module Module for which this object is an aspect of * @param moduleCompileOptions */ -abstract class ModuleAspect private[chisel3] (module: RawModule) - (implicit moduleCompileOptions: CompileOptions) extends RawModule with PseudoModule { +abstract class ModuleAspect private[chisel3] (module: RawModule)(implicit moduleCompileOptions: CompileOptions) + extends RawModule + with PseudoModule { Builder.addAspect(module, this) @@ -23,4 +24,3 @@ abstract class ModuleAspect private[chisel3] (module: RawModule) override val _namespace = module._namespace } - diff --git a/core/src/main/scala/chisel3/MultiClock.scala b/core/src/main/scala/chisel3/MultiClock.scala index 6a745f14..e96946f5 100644 --- a/core/src/main/scala/chisel3/MultiClock.scala +++ b/core/src/main/scala/chisel3/MultiClock.scala @@ -7,6 +7,7 @@ import chisel3.internal._ import scala.language.experimental.macros object withClockAndReset { + /** Creates a new Clock and Reset scope * * @param clock the new implicit Clock @@ -32,13 +33,14 @@ object withClockAndReset { } object withClock { + /** Creates a new Clock scope * * @param clock the new implicit Clock * @param block the block of code to run with new implicit Clock * @return the result of the block */ - def apply[T](clock: Clock)(block: => T): T = { + def apply[T](clock: Clock)(block: => T): T = { // Save parentScope val parentClock = Builder.currentClock Builder.currentClock = Some(clock) @@ -50,6 +52,7 @@ object withClock { } object withReset { + /** Creates a new Reset scope * * @param reset the new implicit Reset @@ -67,4 +70,3 @@ object withReset { } } - diff --git a/core/src/main/scala/chisel3/Mux.scala b/core/src/main/scala/chisel3/Mux.scala index 00f2a717..df56182e 100644 --- a/core/src/main/scala/chisel3/Mux.scala +++ b/core/src/main/scala/chisel3/Mux.scala @@ -6,11 +6,12 @@ import scala.language.experimental.macros import chisel3.internal._ import chisel3.internal.Builder.pushOp -import chisel3.internal.sourceinfo.{SourceInfo, MuxTransform} +import chisel3.internal.sourceinfo.{MuxTransform, SourceInfo} import chisel3.internal.firrtl._ import chisel3.internal.firrtl.PrimOp._ object Mux extends SourceInfoDoc { + /** Creates a mux, whose output is one of the inputs depending on the * value of the condition. * @@ -25,13 +26,19 @@ object Mux extends SourceInfoDoc { def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T] /** @group SourceInfoTransformMacro */ - def do_apply[T <: Data](cond: Bool, con: T, alt: T)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): T = { + def do_apply[T <: Data]( + cond: Bool, + con: T, + alt: T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { requireIsHardware(cond, "mux condition") requireIsHardware(con, "mux true value") requireIsHardware(alt, "mux false value") val d = cloneSupertype(Seq(con, alt), "Mux") - val conRef = con match { // this matches chisel semantics (DontCare as object) to firrtl semantics (invalidate) + val conRef = con match { // this matches chisel semantics (DontCare as object) to firrtl semantics (invalidate) case DontCare => val dcWire = Wire(d) dcWire := DontCare diff --git a/core/src/main/scala/chisel3/Num.scala b/core/src/main/scala/chisel3/Num.scala index 219e18f4..c7e0721f 100644 --- a/core/src/main/scala/chisel3/Num.scala +++ b/core/src/main/scala/chisel3/Num.scala @@ -8,7 +8,6 @@ import chisel3.internal.firrtl.{BinaryPoint, KnownBinaryPoint} import scala.language.experimental.macros import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} - // REVIEW TODO: Further discussion needed on what Num actually is. /** Abstract trait defining operations available on numeric-like hardware data types. @@ -43,10 +42,10 @@ trait Num[T <: Data] { * $maxWidth * @group Arithmetic */ - final def + (that: T): T = macro SourceInfoTransform.thatArg + final def +(that: T): T = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_+ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + def do_+(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T /** Multiplication operator * @@ -56,10 +55,10 @@ trait Num[T <: Data] { * $singleCycleMul * @group Arithmetic */ - final def * (that: T): T = macro SourceInfoTransform.thatArg + final def *(that: T): T = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_* (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + def do_*(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T /** Division operator * @@ -69,10 +68,10 @@ trait Num[T <: Data] { * @todo full rules * @group Arithmetic */ - final def / (that: T): T = macro SourceInfoTransform.thatArg + final def /(that: T): T = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_/ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + def do_/(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T /** Modulo operator * @@ -81,10 +80,10 @@ trait Num[T <: Data] { * $singleCycleDiv * @group Arithmetic */ - final def % (that: T): T = macro SourceInfoTransform.thatArg + final def %(that: T): T = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_% (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + def do_%(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T /** Subtraction operator * @@ -93,10 +92,10 @@ trait Num[T <: Data] { * $maxWidthPlusOne * @group Arithmetic */ - final def - (that: T): T = macro SourceInfoTransform.thatArg + final def -(that: T): T = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_- (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T + def do_-(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T /** Less than operator * @@ -104,10 +103,10 @@ trait Num[T <: Data] { * @return a hardware [[Bool]] asserted if this $coll is less than `that` * @group Comparison */ - final def < (that: T): Bool = macro SourceInfoTransform.thatArg + final def <(that: T): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_< (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool + def do_<(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool /** Less than or equal to operator * @@ -115,10 +114,10 @@ trait Num[T <: Data] { * @return a hardware [[Bool]] asserted if this $coll is less than or equal to `that` * @group Comparison */ - final def <= (that: T): Bool = macro SourceInfoTransform.thatArg + final def <=(that: T): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_<= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool + def do_<=(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool /** Greater than operator * @@ -126,10 +125,10 @@ trait Num[T <: Data] { * @return a hardware [[Bool]] asserted if this $coll is greater than `that` * @group Comparison */ - final def > (that: T): Bool = macro SourceInfoTransform.thatArg + final def >(that: T): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_> (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool + def do_>(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool /** Greater than or equal to operator * @@ -137,10 +136,10 @@ trait Num[T <: Data] { * @return a hardware [[Bool]] asserted if this $coll is greather than or equal to `that` * @group Comparison */ - final def >= (that: T): Bool = macro SourceInfoTransform.thatArg + final def >=(that: T): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_>= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool + def do_>=(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool /** Absolute value operator * @@ -150,7 +149,10 @@ trait Num[T <: Data] { */ final def abs: T = macro SourceInfoTransform.noArg - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) final def abs(dummy: Int*): T = macro SourceInfoTransform.noArgDummy /** @group SourceInfoTransformMacro */ @@ -189,7 +191,6 @@ object Num extends NumObject * BigInts and Double and BigDecimal * For backwards compatibility this is used with FixedPoint and Interval objects * but is better used with the Num Object - * */ trait NumObject { val MaxBitsBigIntToBigDecimal = 108 @@ -254,7 +255,7 @@ trait NumObject { * @return */ def toDouble(i: BigInt, binaryPoint: Int): Double = { - if(i.bitLength >= 54) { + if (i.bitLength >= 54) { throw new ChiselException( s"BigInt $i with bitlength ${i.bitLength} is too big, precision lost with > $MaxBitsBigIntToDouble bits" ) @@ -275,7 +276,8 @@ trait NumObject { case KnownBinaryPoint(n) => toDouble(value, n) case x => throw new ChiselException(s"Error converting BigDecimal $value to BigInt, binary point must be known, not $x") - } } + } + } /** * converts a bigInt with the given binaryPoint into the BigDecimal representation @@ -284,7 +286,7 @@ trait NumObject { * @return */ def toBigDecimal(value: BigInt, binaryPoint: Int): BigDecimal = { - if(value.bitLength > MaxBitsBigIntToBigDecimal) { + if (value.bitLength > MaxBitsBigIntToBigDecimal) { throw new ChiselException( s"BigInt $value with bitlength ${value.bitLength} is too big, precision lost with > $MaxBitsBigIntToBigDecimal bits" ) diff --git a/core/src/main/scala/chisel3/Printable.scala b/core/src/main/scala/chisel3/Printable.scala index 006286f9..c477716b 100644 --- a/core/src/main/scala/chisel3/Printable.scala +++ b/core/src/main/scala/chisel3/Printable.scala @@ -6,10 +6,7 @@ import chisel3.internal.firrtl.Component import scala.collection.mutable -import java.util.{ - MissingFormatArgumentException, - UnknownFormatConversionException -} +import java.util.{MissingFormatArgumentException, UnknownFormatConversionException} /** Superclass of things that can be printed in the resulting circuit * @@ -47,17 +44,21 @@ import java.util.{ // Could be implemented by adding a new format specifier to Firrtl (eg. %m) // TODO Should we provide more functions like map and mkPrintable? sealed abstract class Printable { + /** Unpack into format String and a List of String arguments (identifiers) * @note This must be called after elaboration when Chisel nodes actually * have names */ def unpack(ctx: Component): (String, Iterable[String]) + /** Allow for appending Printables like Strings */ final def +(that: Printable): Printables = Printables(List(this, that)) + /** Allow for appending Strings to Printables */ final def +(that: String): Printables = Printables(List(this, PString(that))) } object Printable { + /** Pack standard printf fmt, args* style into Printable */ def pack(fmt: String, data: Data*): Printable = { @@ -68,11 +69,11 @@ object Printable { def errorMsg(index: Int) = s"""| fmt = "$fmt" | ${carrotAt(index)} - | data = ${data mkString ", "}""".stripMargin + | data = ${data.mkString(", ")}""".stripMargin def getArg(i: Int): Data = { if (!args.hasNext) { val msg = "has no matching argument!\n" + errorMsg(i) - // Exception wraps msg in s"Format Specifier '$msg'" + // Exception wraps msg in s"Format Specifier '$msg'" throw new MissingFormatArgumentException(msg) } args.next() @@ -85,14 +86,14 @@ object Printable { if (percent) { val arg = c match { case FirrtlFormat(x) => FirrtlFormat(x.toString, getArg(i)) - case 'n' => Name(getArg(i)) - case 'N' => FullName(getArg(i)) - case '%' => Percent + case 'n' => Name(getArg(i)) + case 'N' => FullName(getArg(i)) + case '%' => Percent case x => val msg = s"Illegal format specifier '$x'!\n" + errorMsg(i) throw new UnknownFormatConversionException(msg) } - pables += PString(str dropRight 1) // remove format % + pables += PString(str.dropRight(1)) // remove format % pables += arg str = "" percent = false @@ -105,9 +106,11 @@ object Printable { val msg = s"Trailing %\n" + errorMsg(fmt.size - 1) throw new UnknownFormatConversionException(msg) } - require(!args.hasNext, + require( + !args.hasNext, s"Too many arguments! More format specifier(s) expected!\n" + - errorMsg(fmt.size)) + errorMsg(fmt.size) + ) pables += PString(str) Printables(pables) @@ -117,15 +120,17 @@ object Printable { case class Printables(pables: Iterable[Printable]) extends Printable { require(pables.hasDefiniteSize, "Infinite-sized iterables are not supported!") final def unpack(ctx: Component): (String, Iterable[String]) = { - val (fmts, args) = pables.map(_ unpack ctx).unzip + val (fmts, args) = pables.map(_.unpack(ctx)).unzip (fmts.mkString, args.flatten) } } + /** Wrapper for printing Scala Strings */ case class PString(str: String) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = - (str replaceAll ("%", "%%"), List.empty) + (str.replaceAll("%", "%%"), List.empty) } + /** Superclass for Firrtl format specifiers for Bits */ sealed abstract class FirrtlFormat(private[chisel3] val specifier: Char) extends Printable { def bits: Bits @@ -137,7 +142,7 @@ object FirrtlFormat { final val legalSpecifiers = List('d', 'x', 'b', 'c') def unapply(x: Char): Option[Char] = - Option(x) filter (x => legalSpecifiers contains x) + Option(x).filter(x => legalSpecifiers contains x) /** Helper for constructing Firrtl Formats * Accepts data to simplify pack @@ -152,26 +157,33 @@ object FirrtlFormat { case "x" => Hexadecimal(bits) case "b" => Binary(bits) case "c" => Character(bits) - case c => throw new Exception(s"Illegal format specifier '$c'!") + case c => throw new Exception(s"Illegal format specifier '$c'!") } } } + /** Format bits as Decimal */ case class Decimal(bits: Bits) extends FirrtlFormat('d') + /** Format bits as Hexidecimal */ case class Hexadecimal(bits: Bits) extends FirrtlFormat('x') + /** Format bits as Binary */ case class Binary(bits: Bits) extends FirrtlFormat('b') + /** Format bits as Character */ case class Character(bits: Bits) extends FirrtlFormat('c') + /** Put innermost name (eg. field of bundle) */ case class Name(data: Data) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.name, List.empty) } + /** Put full name within parent namespace (eg. bundleName.field) */ case class FullName(data: Data) extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = (data.ref.fullName(ctx), List.empty) } + /** Represents escaped percents */ case object Percent extends Printable { final def unpack(ctx: Component): (String, Iterable[String]) = ("%%", List.empty) diff --git a/core/src/main/scala/chisel3/Printf.scala b/core/src/main/scala/chisel3/Printf.scala index be0146bb..bdcca8e1 100644 --- a/core/src/main/scala/chisel3/Printf.scala +++ b/core/src/main/scala/chisel3/Printf.scala @@ -12,10 +12,10 @@ import chisel3.internal.sourceinfo.SourceInfo * See apply methods for use */ object printf { + /** Helper for packing escape characters */ private[chisel3] def format(formatIn: String): String = { - require(formatIn forall (c => c.toInt > 0 && c.toInt < 128), - "format strings must comprise non-null ASCII values") + require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") def escaped(x: Char) = { require(x.toInt >= 0, s"char ${x} to Int ${x.toInt} must be >= 0") if (x == '"' || x == '\\') { @@ -25,15 +25,18 @@ object printf { } else if (x == '\t') { "\\t" } else { - require(x.toInt >= 32, s"char ${x} to Int ${x.toInt} must be >= 32") // TODO \xNN once FIRRTL issue #59 is resolved + require( + x.toInt >= 32, + s"char ${x} to Int ${x.toInt} must be >= 32" + ) // TODO \xNN once FIRRTL issue #59 is resolved x } } - formatIn map escaped mkString "" + formatIn.map(escaped).mkString("") } /** Named class for [[printf]]s. */ - final class Printf private[chisel3](val pable: Printable) extends VerificationStatement + final class Printf private[chisel3] (val pable: Printable) extends VerificationStatement /** Prints a message in simulation * @@ -73,7 +76,8 @@ object printf { * @param data format string varargs containing data to print */ def apply(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = - apply(Printable.pack(fmt, data:_*)) + apply(Printable.pack(fmt, data: _*)) + /** Prints a message in simulation * * Prints a message every cycle. If defined within the scope of a [[when]] block, the message @@ -90,18 +94,29 @@ object printf { */ def apply(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = { var printfId: Printf = null - when (!Module.reset.asBool) { + when(!Module.reset.asBool) { printfId = printfWithoutReset(pable) } printfId } - private[chisel3] def printfWithoutReset(pable: Printable)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = { + private[chisel3] def printfWithoutReset( + pable: Printable + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Printf = { val clock = Builder.forcedClock val printfId = new Printf(pable) pushCommand(chisel3.internal.firrtl.Printf(printfId, sourceInfo, clock.ref, pable)) printfId } - private[chisel3] def printfWithoutReset(fmt: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Printf = - printfWithoutReset(Printable.pack(fmt, data:_*)) + private[chisel3] def printfWithoutReset( + fmt: String, + data: Bits* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Printf = + printfWithoutReset(Printable.pack(fmt, data: _*)) } diff --git a/core/src/main/scala/chisel3/RawModule.scala b/core/src/main/scala/chisel3/RawModule.scala index e977d918..b81372d8 100644 --- a/core/src/main/scala/chisel3/RawModule.scala +++ b/core/src/main/scala/chisel3/RawModule.scala @@ -8,7 +8,7 @@ import scala.language.experimental.macros import scala.annotation.nowarn import chisel3.experimental.BaseModule import chisel3.internal._ -import chisel3.internal.BaseModule.{ModuleClone, InstanceClone} +import chisel3.internal.BaseModule.{InstanceClone, ModuleClone} import chisel3.internal.Builder._ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.UnlocatableSourceInfo @@ -19,8 +19,7 @@ import _root_.firrtl.annotations.{IsModule, ModuleTarget} * multiple IO() declarations. */ @nowarn("msg=class Port") // delete when Port becomes private -abstract class RawModule(implicit moduleCompileOptions: CompileOptions) - extends BaseModule { +abstract class RawModule(implicit moduleCompileOptions: CompileOptions) extends BaseModule { // // RTL construction internals // @@ -49,19 +48,22 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) port._computeName(None, None).orElse(names.get(port)) match { case Some(name) => if (_namespace.contains(name)) { - Builder.error(s"""Unable to name port $port to "$name" in $this,""" + - " name is already taken by another port!") + Builder.error( + s"""Unable to name port $port to "$name" in $this,""" + + " name is already taken by another port!" + ) } port.setRef(ModuleIO(this, _namespace.name(name))) case None => - Builder.error(s"Unable to name port $port in $this, " + - "try making it a public field of the Module") + Builder.error( + s"Unable to name port $port in $this, " + + "try making it a public field of the Module" + ) port.setRef(ModuleIO(this, "<UNNAMED>")) } } } - private[chisel3] override def generateComponent(): Option[Component] = { require(!_closed, "Can't generate module more than once") _closed = true @@ -79,29 +81,29 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) // All suggestions are in, force names to every node. for (id <- getIds) { id match { - case id: ModuleClone[_] => id.setRefAndPortsRef(_namespace) // special handling + case id: ModuleClone[_] => id.setRefAndPortsRef(_namespace) // special handling case id: InstanceClone[_] => id.setAsInstanceRef() - case id: BaseModule => id.forceName(None, default=id.desiredName, _namespace) - case id: MemBase[_] => id.forceName(None, default="MEM", _namespace) - case id: stop.Stop => id.forceName(None, default="stop", _namespace) - case id: assert.Assert => id.forceName(None, default="assert", _namespace) - case id: assume.Assume => id.forceName(None, default="assume", _namespace) - case id: cover.Cover => id.forceName(None, default="cover", _namespace) - case id: printf.Printf => id.forceName(None, default="printf", _namespace) - case id: Data => + case id: BaseModule => id.forceName(None, default = id.desiredName, _namespace) + case id: MemBase[_] => id.forceName(None, default = "MEM", _namespace) + case id: stop.Stop => id.forceName(None, default = "stop", _namespace) + case id: assert.Assert => id.forceName(None, default = "assert", _namespace) + case id: assume.Assume => id.forceName(None, default = "assume", _namespace) + case id: cover.Cover => id.forceName(None, default = "cover", _namespace) + case id: printf.Printf => id.forceName(None, default = "printf", _namespace) + case id: Data => if (id.isSynthesizable) { id.topBinding match { case OpBinding(_, _) => - id.forceName(Some(""), default="T", _namespace) + id.forceName(Some(""), default = "T", _namespace) case MemoryPortBinding(_, _) => - id.forceName(None, default="MPORT", _namespace) + id.forceName(None, default = "MPORT", _namespace) case PortBinding(_) => - id.forceName(None, default="PORT", _namespace) + id.forceName(None, default = "PORT", _namespace) case RegBinding(_, _) => - id.forceName(None, default="REG", _namespace) + id.forceName(None, default = "REG", _namespace) case WireBinding(_, _) => - id.forceName(Some(""), default="WIRE", _namespace) - case _ => // don't name literals + id.forceName(Some(""), default = "WIRE", _namespace) + case _ => // don't name literals } } // else, don't name unbound types } @@ -110,19 +112,20 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) closeUnboundIds(names) - val firrtlPorts = getModulePorts map { port: Data => + val firrtlPorts = getModulePorts.map { port: Data => // Special case Vec to make FIRRTL emit the direction of its // element. // Just taking the Vec's specifiedDirection is a bug in cases like // Vec(Flipped()), since the Vec's specifiedDirection is // Unspecified. val direction = port match { - case v: Vec[_] => v.specifiedDirection match { - case SpecifiedDirection.Input => SpecifiedDirection.Input - case SpecifiedDirection.Output => SpecifiedDirection.Output - case SpecifiedDirection.Flip => SpecifiedDirection.flip(v.sample_element.specifiedDirection) - case SpecifiedDirection.Unspecified => v.sample_element.specifiedDirection - } + case v: Vec[_] => + v.specifiedDirection match { + case SpecifiedDirection.Input => SpecifiedDirection.Input + case SpecifiedDirection.Output => SpecifiedDirection.Output + case SpecifiedDirection.Flip => SpecifiedDirection.flip(v.sample_element.specifiedDirection) + case SpecifiedDirection.Unspecified => v.sample_element.specifiedDirection + } case _ => port.specifiedDirection } @@ -134,7 +137,7 @@ abstract class RawModule(implicit moduleCompileOptions: CompileOptions) // unless the client wants explicit control over their generation. val invalidateCommands = { if (!compileOptions.explicitInvalidate) { - getModulePorts map { port => DefInvalid(UnlocatableSourceInfo, port.ref) } + getModulePorts.map { port => DefInvalid(UnlocatableSourceInfo, port.ref) } } else { Seq() } @@ -204,13 +207,15 @@ package object internal { .map(_.forceFinalName("io")) .orElse { // Fallback if reflection fails, user can wrap in IO(...) - self.findPort("io") - .collect { case r: Record => r } - }.getOrElse(throwException( - s"Compatibility mode Module '$this' must have a 'val io' Bundle. " + - "If there is such a field and you still see this error, autowrapping has failed (sorry!). " + - "Please wrap the Bundle declaration in IO(...)." - )) + self.findPort("io").collect { case r: Record => r } + } + .getOrElse( + throwException( + s"Compatibility mode Module '$this' must have a 'val io' Bundle. " + + "If there is such a field and you still see this error, autowrapping has failed (sorry!). " + + "Please wrap the Bundle declaration in IO(...)." + ) + ) } /** Legacy Module class that restricts IOs to just io, clock, and reset, and provides a constructor @@ -221,15 +226,19 @@ package object internal { */ abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions) extends Module { // Provide a non-deprecated constructor - def this(override_clock: Option[Clock] = None, override_reset: Option[Bool]=None) - (implicit moduleCompileOptions: CompileOptions) = { + def this( + override_clock: Option[Clock] = None, + override_reset: Option[Bool] = None + )( + implicit moduleCompileOptions: CompileOptions + ) = { this() this.override_clock = override_clock this.override_reset = override_reset } def this(_clock: Clock)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), None)(moduleCompileOptions) - def this(_reset: Bool)(implicit moduleCompileOptions: CompileOptions) = + def this(_reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(None, Option(_reset))(moduleCompileOptions) def this(_clock: Clock, _reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), Option(_reset))(moduleCompileOptions) @@ -240,12 +249,15 @@ package object internal { protected def _compatIoPortBound() = portsContains(_io) private[chisel3] override def generateComponent(): Option[Component] = { - _compatAutoWrapPorts() // pre-IO(...) compatibility hack + _compatAutoWrapPorts() // pre-IO(...) compatibility hack // Restrict IO to just io, clock, and reset require(_io != null, "Module must have io") require(portsContains(_io), "Module must have io wrapped in IO(...)") - require((portsContains(clock)) && (portsContains(reset)), "Internal error, module did not have clock or reset as IO") + require( + (portsContains(clock)) && (portsContains(reset)), + "Internal error, module did not have clock or reset as IO" + ) require(portsSize == 3, "Module must only have io, clock, and reset as IO") super.generateComponent() @@ -265,8 +277,10 @@ package object internal { * '''Do not use this class in user code'''. Use whichever `BlackBox` is imported by your wildcard * import (preferably `import chisel3._`). */ - abstract class LegacyBlackBox(params: Map[String, Param] = Map.empty[String, Param]) - (implicit moduleCompileOptions: CompileOptions) + abstract class LegacyBlackBox( + params: Map[String, Param] = Map.empty[String, Param] + )( + implicit moduleCompileOptions: CompileOptions) extends chisel3.BlackBox(params) { override private[chisel3] lazy val _io: Record = reflectivelyFindValIO(this) @@ -305,5 +319,6 @@ package object internal { * * @note this is a val instead of an object because of the need to wrap in Module(...) */ - private[chisel3] val ViewParent = Module.do_apply(new ViewParentAPI)(UnlocatableSourceInfo, ExplicitCompileOptions.Strict) + private[chisel3] val ViewParent = + Module.do_apply(new ViewParentAPI)(UnlocatableSourceInfo, ExplicitCompileOptions.Strict) } diff --git a/core/src/main/scala/chisel3/Reg.scala b/core/src/main/scala/chisel3/Reg.scala index 122c5ebd..204beb79 100644 --- a/core/src/main/scala/chisel3/Reg.scala +++ b/core/src/main/scala/chisel3/Reg.scala @@ -27,9 +27,9 @@ import chisel3.internal.sourceinfo.SourceInfo * // Width of r4.unknown is inferred * // Width of r4.known is set to 8 * }}} - * */ object Reg { + /** Construct a [[Reg]] from a type template with no initialization value (reset is ignored). * Value will not change unless the [[Reg]] is given a connection. * @param t The template from which to construct this wire @@ -74,6 +74,7 @@ object Reg { * }}} */ object RegNext { + /** Returns a register ''with an unset width'' connected to the signal `next` and with no reset value. */ def apply[T <: Data](next: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { val model = (next match { @@ -94,7 +95,7 @@ object RegNext { case next: Bits => next.cloneTypeWidth(Width()) case next => next.cloneTypeFull }).asInstanceOf[T] - val reg = RegInit(model, init) // TODO: this makes NO sense + val reg = RegInit(model, init) // TODO: this makes NO sense requireIsHardware(next, "reg next") reg := next @@ -162,6 +163,7 @@ object RegNext { * }}} */ object RegInit { + /** Construct a [[Reg]] from a type template initialized to the specified value on reset * @param t The type template used to construct this [[Reg]] * @param init The value the [[Reg]] is initialized to on reset diff --git a/core/src/main/scala/chisel3/SIntFactory.scala b/core/src/main/scala/chisel3/SIntFactory.scala index b34c7dde..3fafacda 100644 --- a/core/src/main/scala/chisel3/SIntFactory.scala +++ b/core/src/main/scala/chisel3/SIntFactory.scala @@ -5,8 +5,10 @@ package chisel3 import chisel3.internal.firrtl.{IntervalRange, SLit, Width} trait SIntFactory { + /** Create an SInt type with inferred width. */ def apply(): SInt = apply(Width()) + /** Create a SInt type or port with fixed width. */ def apply(width: Width): SInt = new SInt(width) diff --git a/core/src/main/scala/chisel3/SeqUtils.scala b/core/src/main/scala/chisel3/SeqUtils.scala index 5c86efd3..b1136120 100644 --- a/core/src/main/scala/chisel3/SeqUtils.scala +++ b/core/src/main/scala/chisel3/SeqUtils.scala @@ -10,6 +10,7 @@ import chisel3.internal.sourceinfo._ import chisel3.internal.plugin.autoNameRecursively private[chisel3] object SeqUtils { + /** Concatenates the data elements of the input sequence, in sequence order, together. * The first element of the sequence forms the least significant bits, while the last element * in the sequence forms the most significant bits. @@ -27,10 +28,10 @@ private[chisel3] object SeqUtils { in.head.asUInt } else { val lo = autoNameRecursively("lo")(prefix("lo") { - asUInt(in.slice(0, in.length/2)) + asUInt(in.slice(0, in.length / 2)) }) val hi = autoNameRecursively("hi")(prefix("hi") { - asUInt(in.slice(in.length/2, in.length)) + asUInt(in.slice(in.length / 2, in.length)) }) hi ## lo } @@ -45,7 +46,7 @@ private[chisel3] object SeqUtils { case 0 => 0.U case 1 => in.head case n => - val sum = count(in take n/2) +& count(in drop n/2) + val sum = count(in.take(n / 2)) +& count(in.drop(n / 2)) sum(BigInt(n).bitLength - 1, 0) } @@ -54,8 +55,12 @@ private[chisel3] object SeqUtils { def priorityMux[T <: Data](in: Seq[(Bool, T)]): T = macro SourceInfoTransform.inArg /** @group SourceInfoTransformMacros */ - def do_priorityMux[T <: Data](in: Seq[(Bool, T)]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + def do_priorityMux[T <: Data]( + in: Seq[(Bool, T)] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { if (in.size == 1) { in.head._2 } else { @@ -72,13 +77,16 @@ private[chisel3] object SeqUtils { def oneHotMux[T <: Data](in: Iterable[(Bool, T)]): T = macro SourceInfoTransform.inArg /** @group SourceInfoTransformMacros */ - def do_oneHotMux[T <: Data](in: Iterable[(Bool, T)]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + def do_oneHotMux[T <: Data]( + in: Iterable[(Bool, T)] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { if (in.tail.isEmpty) { in.head._2 - } - else { - val output = cloneSupertype(in.toSeq map { _._2}, "oneHotMux") + } else { + val output = cloneSupertype(in.toSeq.map { _._2 }, "oneHotMux") def buildAndOrMultiplexor[TT <: Data](inputs: Iterable[(Bool, TT)]): T = { val masked = for ((s, i) <- inputs) yield Mux(s, i.asUInt, 0.U) @@ -89,8 +97,9 @@ private[chisel3] object SeqUtils { case _: SInt => // SInt's have to be managed carefully so sign extension works - val sInts: Iterable[(Bool, SInt)] = in.collect { case (s: Bool, f: SInt) => - (s, f.asTypeOf(output).asInstanceOf[SInt]) + val sInts: Iterable[(Bool, SInt)] = in.collect { + case (s: Bool, f: SInt) => + (s, f.asTypeOf(output).asInstanceOf[SInt]) } val masked = for ((s, i) <- sInts) yield Mux(s, i, 0.S) @@ -99,20 +108,20 @@ private[chisel3] object SeqUtils { case _: FixedPoint => val (sels, possibleOuts) = in.toSeq.unzip - val (intWidths, binaryPoints) = in.toSeq.map { case (_, o) => - val fo = o.asInstanceOf[FixedPoint] - require(fo.binaryPoint.known, "Mux1H requires width/binary points to be defined") - (fo.getWidth - fo.binaryPoint.get, fo.binaryPoint.get) + val (intWidths, binaryPoints) = in.toSeq.map { + case (_, o) => + val fo = o.asInstanceOf[FixedPoint] + require(fo.binaryPoint.known, "Mux1H requires width/binary points to be defined") + (fo.getWidth - fo.binaryPoint.get, fo.binaryPoint.get) }.unzip if (intWidths.distinct.length == 1 && binaryPoints.distinct.length == 1) { buildAndOrMultiplexor(in) - } - else { + } else { val maxIntWidth = intWidths.max val maxBP = binaryPoints.max val inWidthMatched = Seq.fill(intWidths.length)(Wire(FixedPoint((maxIntWidth + maxBP).W, maxBP.BP))) - inWidthMatched.zipWithIndex foreach { case (e, idx) => e := possibleOuts(idx).asInstanceOf[FixedPoint] } + inWidthMatched.zipWithIndex.foreach { case (e, idx) => e := possibleOuts(idx).asInstanceOf[FixedPoint] } buildAndOrMultiplexor(sels.zip(inWidthMatched)) } @@ -123,12 +132,12 @@ private[chisel3] object SeqUtils { val (sel, inData) = in.unzip val inElts = inData.map(_.asInstanceOf[Aggregate].getElements) // We want to iterate on the columns of inElts, so we transpose - out.getElements.zip(inElts.transpose).foreach { case (outElt, elts) => - outElt := oneHotMux(sel.zip(elts)) + out.getElements.zip(inElts.transpose).foreach { + case (outElt, elts) => + outElt := oneHotMux(sel.zip(elts)) } out.asInstanceOf[T] - } - else { + } else { throwException(s"Cannot Mux1H with aggregates with inferred widths") } diff --git a/core/src/main/scala/chisel3/StrongEnum.scala b/core/src/main/scala/chisel3/StrongEnum.scala index fa420e80..6f9cce55 100644 --- a/core/src/main/scala/chisel3/StrongEnum.scala +++ b/core/src/main/scala/chisel3/StrongEnum.scala @@ -10,11 +10,11 @@ import chisel3.internal.Builder.pushOp import chisel3.internal.firrtl.PrimOp._ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ -import chisel3.internal.{Binding, Builder, ChildBinding, ConstrainedBinding, InstanceId, throwException} +import chisel3.internal.{throwException, Binding, Builder, ChildBinding, ConstrainedBinding, InstanceId} import firrtl.annotations._ - object EnumAnnotations { + /** An annotation for strong enum instances that are ''not'' inside of Vecs * * @param target the enum instance being annotated @@ -31,7 +31,7 @@ object EnumAnnotations { /** An annotation for Vecs of strong enums. * * The ''fields'' parameter deserves special attention, since it may be difficult to understand. Suppose you create a the following Vec: - + * * {{{ * VecInit(new Bundle { * val e = MyEnum() @@ -47,13 +47,14 @@ object EnumAnnotations { * @param target the Vec being annotated * @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. - * */ - case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]]) extends SingleTargetAnnotation[Named] { + case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]]) + extends SingleTargetAnnotation[Named] { def duplicate(n: Named): EnumVecAnnotation = this.copy(target = n) } - case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]]) extends ChiselAnnotation { + case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]]) + extends ChiselAnnotation { override def toFirrtl: EnumVecAnnotation = EnumVecAnnotation(target.toNamed, typeName, fields) } @@ -70,7 +71,6 @@ object EnumAnnotations { } import EnumAnnotations._ - abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolean = true) extends Element { // Use getSimpleName instead of enumTypeName because for debugging purposes @@ -78,10 +78,11 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea // Enum annotation), and it's more consistent with Bundle printing. override def toString: String = { litOption match { - case Some(value) => factory.nameOfValue(value) match { - case Some(name) => s"${factory.getClass.getSimpleName.init}($value=$name)" - case None => stringAccessor(s"${factory.getClass.getSimpleName.init}($value=(invalid))") - } + case Some(value) => + factory.nameOfValue(value) match { + case Some(name) => s"${factory.getClass.getSimpleName.init}($value=$name)" + case None => stringAccessor(s"${factory.getClass.getSimpleName.init}($value=(invalid))") + } case _ => stringAccessor(s"${factory.getClass.getSimpleName.init}") } } @@ -92,7 +93,7 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea requireIsHardware(this, "bits operated on") requireIsHardware(other, "bits operated on") - if(!this.typeEquivalent(other)) { + if (!this.typeEquivalent(other)) { throwException(s"Enum types are not equivalent: ${this.enumTypeName}, ${other.enumTypeName}") } @@ -104,24 +105,34 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea this.factory == that.asInstanceOf[EnumType].factory } - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { this := factory.apply(that.asUInt) } - final def === (that: EnumType): Bool = macro SourceInfoTransform.thatArg - final def =/= (that: EnumType): Bool = macro SourceInfoTransform.thatArg - final def < (that: EnumType): Bool = macro SourceInfoTransform.thatArg - final def <= (that: EnumType): Bool = macro SourceInfoTransform.thatArg - final def > (that: EnumType): Bool = macro SourceInfoTransform.thatArg - final def >= (that: EnumType): Bool = macro SourceInfoTransform.thatArg - - def do_=== (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, EqualOp, that) - def do_=/= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, NotEqualOp, that) - def do_< (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessOp, that) - def do_> (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterOp, that) - def do_<= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, LessEqOp, that) - def do_>= (that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = compop(sourceInfo, GreaterEqOp, that) + final def ===(that: EnumType): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: EnumType): Bool = macro SourceInfoTransform.thatArg + final def <(that: EnumType): Bool = macro SourceInfoTransform.thatArg + final def <=(that: EnumType): Bool = macro SourceInfoTransform.thatArg + final def >(that: EnumType): Bool = macro SourceInfoTransform.thatArg + final def >=(that: EnumType): Bool = macro SourceInfoTransform.thatArg + + def do_===(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, EqualOp, that) + def do_=/=(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, NotEqualOp, that) + def do_<(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessOp, that) + def do_>(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterOp, that) + def do_<=(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, LessEqOp, that) + def do_>=(that: EnumType)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = + compop(sourceInfo, GreaterEqOp, that) override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = pushOp(DefPrim(sourceInfo, UInt(width), AsUIntOp, ref)) @@ -151,21 +162,26 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea * @param u2 zero or more additional values to look for * @return a hardware [[Bool]] that indicates if this value matches any of the given values */ - final def isOneOf(u1: EnumType, u2: EnumType*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool - = isOneOf(u1 +: u2.toSeq) + final def isOneOf( + u1: EnumType, + u2: EnumType* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Bool = isOneOf(u1 +: u2.toSeq) def next(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = { if (litOption.isDefined) { val index = factory.all.indexOf(this) - if (index < factory.all.length-1) { + if (index < factory.all.length - 1) { factory.all(index + 1).asInstanceOf[this.type] } else { factory.all.head.asInstanceOf[this.type] } } else { - val enums_with_nexts = factory.all zip (factory.all.tail :+ factory.all.head) - val next_enum = SeqUtils.priorityMux(enums_with_nexts.map { case (e,n) => (this === e, n) } ) + val enums_with_nexts = factory.all.zip(factory.all.tail :+ factory.all.head) + val next_enum = SeqUtils.priorityMux(enums_with_nexts.map { case (e, n) => (this === e, n) }) next_enum.asInstanceOf[this.type] } } @@ -175,7 +191,10 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea lit.bindLitArg(this) } - override private[chisel3] def bind(target: Binding, parentDirection: SpecifiedDirection = SpecifiedDirection.Unspecified): Unit = { + override private[chisel3] def bind( + target: Binding, + parentDirection: SpecifiedDirection = SpecifiedDirection.Unspecified + ): Unit = { super.bind(target, parentDirection) // Make sure we only annotate hardware and not literals @@ -186,10 +205,11 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea // This function conducts a depth-wise search to find all enum-type fields within a vector or bundle (or vector of bundles) private def enumFields(d: Aggregate): Seq[Seq[String]] = d match { - case v: Vec[_] => v.sample_element match { - case b: Bundle => enumFields (b) - case _ => Seq () - } + case v: Vec[_] => + v.sample_element match { + case b: Bundle => enumFields(b) + case _ => Seq() + } case b: Bundle => b.elements.collect { case (name, e: EnumType) if this.typeEquivalent(e) => Seq(Seq(name)) @@ -205,10 +225,11 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea } d.binding match { - case Some(ChildBinding(parent)) => outerMostVec(parent) match { - case outer @ Some(_) => outer - case None => currentVecOpt - } + case Some(ChildBinding(parent)) => + outerMostVec(parent) match { + case outer @ Some(_) => outer + case None => currentVecOpt + } case _ => currentVecOpt } } @@ -216,7 +237,7 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea private def annotateEnum(): Unit = { val anno = outerMostVec() match { case Some(v) => EnumVecChiselAnnotation(v, enumTypeName, enumFields(v)) - case None => EnumComponentChiselAnnotation(this, enumTypeName) + case None => EnumComponentChiselAnnotation(this, enumTypeName) } if (!Builder.annotations.contains(anno)) { @@ -233,14 +254,13 @@ abstract class EnumType(private val factory: EnumFactory, selfAnnotating: Boolea def toPrintable: Printable = FullName(this) // TODO: Find a better pretty printer } - abstract class EnumFactory { class Type extends EnumType(this) object Type { def apply(): Type = EnumFactory.this.apply() } - private var id: BigInt = 0 + private var id: BigInt = 0 private[chisel3] var width: Width = 0.W private case class EnumRecord(inst: Type, name: String) @@ -255,7 +275,7 @@ abstract class EnumFactory { // Do all bitvectors of this Enum's width represent legal states? private[chisel3] def isTotal: Boolean = { (this.getWidth < 31) && // guard against Integer overflow - (enumRecords.size == (1 << this.getWidth)) + (enumRecords.size == (1 << this.getWidth)) } private[chisel3] def globalAnnotation: EnumDefChiselAnnotation = @@ -280,7 +300,7 @@ abstract class EnumFactory { enumRecords.append(EnumRecord(result, name)) - width = (1 max id.bitLength).W + width = (1.max(id.bitLength)).W id += 1 result @@ -302,11 +322,17 @@ abstract class EnumFactory { def apply(): Type = new Type - private def castImpl(n: UInt, warn: Boolean)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = { + private def castImpl( + n: UInt, + warn: Boolean + )( + implicit sourceInfo: SourceInfo, + connectionCompileOptions: CompileOptions + ): Type = { if (n.litOption.isDefined) { enumInstances.find(_.litValue == n.litValue) match { case Some(result) => result - case None => throwException(s"${n.litValue} is not a valid value for $enumTypeName") + case None => throwException(s"${n.litValue} is not a valid value for $enumTypeName") } } else if (!n.isWidthKnown) { throwException(s"Non-literal UInts being cast to $enumTypeName must have a defined width") @@ -314,7 +340,9 @@ abstract class EnumFactory { throwException(s"The UInt being cast to $enumTypeName is wider than $enumTypeName's width ($getWidth)") } else { if (warn && !this.isTotal) { - Builder.warning(s"Casting non-literal UInt to $enumTypeName. You can use $enumTypeName.safe to cast without this warning.") + Builder.warning( + s"Casting non-literal UInt to $enumTypeName. You can use $enumTypeName.safe to cast without this warning." + ) } val glue = Wire(new UnsafeEnum(width)) glue := n @@ -330,7 +358,8 @@ abstract class EnumFactory { * @param n the UInt to cast * @return the equivalent Enum to the value of the cast UInt */ - def apply(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = castImpl(n, warn = true) + def apply(n: UInt)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Type = + castImpl(n, warn = true) /** Safely cast an [[UInt]] to the type of this Enum * @@ -344,9 +373,8 @@ abstract class EnumFactory { } } - private[chisel3] object EnumMacros { - def ValImpl(c: Context) : c.Tree = { + def ValImpl(c: Context): c.Tree = { import c.universe._ // Much thanks to michael_s for this solution: @@ -375,7 +403,6 @@ private[chisel3] object EnumMacros { } } - // This is an enum type that can be connected directly to UInts. It is used as a "glue" to cast non-literal UInts // to enums. private[chisel3] class UnsafeEnum(override val width: Width) extends EnumType(UnsafeEnum, selfAnnotating = false) { diff --git a/core/src/main/scala/chisel3/UIntFactory.scala b/core/src/main/scala/chisel3/UIntFactory.scala index e0f3dc92..64127991 100644 --- a/core/src/main/scala/chisel3/UIntFactory.scala +++ b/core/src/main/scala/chisel3/UIntFactory.scala @@ -9,8 +9,10 @@ import firrtl.ir.{Closed, IntWidth, Open} // This is currently a factory because both Bits and UInt inherit it. trait UIntFactory { + /** Create a UInt type with inferred width. */ def apply(): UInt = apply(Width()) + /** Create a UInt port with specified width. */ def apply(width: Width): UInt = new UInt(width) @@ -21,6 +23,7 @@ trait UIntFactory { // Bind result to being an Literal lit.bindLitArg(result) } + /** Create a UInt with the specified range, validate that range is effectively > 0 */ def apply(range: IntervalRange): UInt = { @@ -34,8 +37,8 @@ trait UIntFactory { } // because this is a UInt we don't have to take into account the lower bound - val newWidth = if(range.upperBound.isInstanceOf[IsKnown]) { - KnownWidth(Utils.getUIntWidth(range.maxAdjusted.get).max(1)) // max(1) handles range"[0,0]" + val newWidth = if (range.upperBound.isInstanceOf[IsKnown]) { + KnownWidth(Utils.getUIntWidth(range.maxAdjusted.get).max(1)) // max(1) handles range"[0,0]" } else { UnknownWidth() } diff --git a/core/src/main/scala/chisel3/VerificationStatement.scala b/core/src/main/scala/chisel3/VerificationStatement.scala index 23adc192..bfdfc26e 100644 --- a/core/src/main/scala/chisel3/VerificationStatement.scala +++ b/core/src/main/scala/chisel3/VerificationStatement.scala @@ -12,6 +12,7 @@ import chisel3.internal.sourceinfo.SourceInfo import scala.reflect.macros.blackbox object assert { + /** Checks for a condition to be valid in the circuit at all times. If the * condition evaluates to false, the circuit simulation stops with an error. * @@ -33,34 +34,62 @@ object assert { * that */ // Macros currently can't take default arguments, so we need two functions to emulate defaults. - def apply(cond: Bool, message: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assert = macro _applyMacroWithMessage - def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assert = macro _applyMacroWithNoMessage + def apply( + cond: Bool, + message: String, + data: Bits* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Assert = macro _applyMacroWithMessage + def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assert = + macro _applyMacroWithNoMessage /** An elaboration-time assertion. Calls the built-in Scala assert function. */ def apply(cond: Boolean, message: => String): Unit = Predef.assert(cond, message) + /** An elaboration-time assertion. Calls the built-in Scala assert function. */ def apply(cond: Boolean): Unit = Predef.assert(cond, "") /** Named class for assertions. */ - final class Assert private[chisel3]() extends VerificationStatement + final class Assert private[chisel3] () extends VerificationStatement import VerificationStatement._ - def _applyMacroWithMessage(c: blackbox.Context)(cond: c.Tree, message: c.Tree, data: c.Tree*)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithMessage( + c: blackbox.Context + )(cond: c.Tree, + message: c.Tree, + data: c.Tree* + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message), ..$data)($sourceInfo, $compileOptions)" } - def _applyMacroWithNoMessage(c: blackbox.Context)(cond: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithNoMessage( + c: blackbox.Context + )(cond: c.Tree + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)" } /** Used by our macros. Do not call directly! */ - def _applyWithSourceLine(cond: Bool, line: SourceLineInfo, message: Option[String], data: Bits*) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assert = { + def _applyWithSourceLine( + cond: Bool, + line: SourceLineInfo, + message: Option[String], + data: Bits* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Assert = { val id = new Assert() when(!Module.reset.asBool()) { Builder.pushCommand(Verification(id, Formal.Assert, sourceInfo, Module.clock.ref, cond.ref, "")) @@ -70,8 +99,8 @@ object assert { } } - object assume { + /** Assumes a condition to be valid in the circuit at all times. * Acts like an assertion in simulation and imposes a declarative * assumption on the state explored by formal tools. @@ -91,34 +120,62 @@ object assume { * @note See [[printf.apply(fmt:String* printf]] for format string documentation */ // Macros currently can't take default arguments, so we need two functions to emulate defaults. - def apply(cond: Bool, message: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assume = macro _applyMacroWithMessage - def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assume = macro _applyMacroWithNoMessage + def apply( + cond: Bool, + message: String, + data: Bits* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Assume = macro _applyMacroWithMessage + def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assume = + macro _applyMacroWithNoMessage /** An elaboration-time assumption. Calls the built-in Scala assume function. */ def apply(cond: Boolean, message: => String): Unit = Predef.assume(cond, message) + /** An elaboration-time assumption. Calls the built-in Scala assume function. */ def apply(cond: Boolean): Unit = Predef.assume(cond, "") /** Named class for assumptions. */ - final class Assume private[chisel3]() extends VerificationStatement + final class Assume private[chisel3] () extends VerificationStatement import VerificationStatement._ - def _applyMacroWithMessage(c: blackbox.Context)(cond: c.Tree, message: c.Tree, data: c.Tree*)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithMessage( + c: blackbox.Context + )(cond: c.Tree, + message: c.Tree, + data: c.Tree* + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message), ..$data)($sourceInfo, $compileOptions)" } - def _applyMacroWithNoMessage(c: blackbox.Context)(cond: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithNoMessage( + c: blackbox.Context + )(cond: c.Tree + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)" } /** Used by our macros. Do not call directly! */ - def _applyWithSourceLine(cond: Bool, line: SourceLineInfo, message: Option[String], data: Bits*) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Assume = { + def _applyWithSourceLine( + cond: Bool, + line: SourceLineInfo, + message: Option[String], + data: Bits* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Assume = { val id = new Assume() when(!Module.reset.asBool()) { Builder.pushCommand(Verification(id, Formal.Assume, sourceInfo, Module.clock.ref, cond.ref, "")) @@ -128,8 +185,8 @@ object assume { } } - object cover { + /** Declares a condition to be covered. * At ever clock event, a counter is incremented iff the condition is active * and reset is inactive. @@ -146,29 +203,48 @@ object cover { * @param message a string describing the cover event */ // Macros currently can't take default arguments, so we need two functions to emulate defaults. - def apply(cond: Bool, message: String)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover = macro _applyMacroWithMessage - def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover = macro _applyMacroWithNoMessage + def apply(cond: Bool, message: String)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover = + macro _applyMacroWithMessage + def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover = + macro _applyMacroWithNoMessage /** Named class for cover statements. */ - final class Cover private[chisel3]() extends VerificationStatement + final class Cover private[chisel3] () extends VerificationStatement import VerificationStatement._ - def _applyMacroWithNoMessage(c: blackbox.Context)(cond: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithNoMessage( + c: blackbox.Context + )(cond: c.Tree + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.None)($sourceInfo, $compileOptions)" } - def _applyMacroWithMessage(c: blackbox.Context)(cond: c.Tree, message: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = { + def _applyMacroWithMessage( + c: blackbox.Context + )(cond: c.Tree, + message: c.Tree + )(sourceInfo: c.Tree, + compileOptions: c.Tree + ): c.Tree = { import c.universe._ val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("_applyWithSourceLine")) q"$apply_impl_do($cond, ${getLine(c)}, _root_.scala.Some($message))($sourceInfo, $compileOptions)" } /** Used by our macros. Do not call directly! */ - def _applyWithSourceLine(cond: Bool, line: SourceLineInfo, message: Option[String]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Cover = { + def _applyWithSourceLine( + cond: Bool, + line: SourceLineInfo, + message: Option[String] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Cover = { val id = new Cover() when(!Module.reset.asBool()) { Builder.pushCommand(Verification(id, Formal.Cover, sourceInfo, Module.clock.ref, cond.ref, "")) @@ -178,30 +254,34 @@ object cover { } object stop { + /** Terminate execution, indicating success. * * @param message a string describing why the simulation was stopped */ def apply(message: String = "")(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Stop = { val stp = new Stop() - when (!Module.reset.asBool) { + when(!Module.reset.asBool) { pushCommand(Stop(stp, sourceInfo, Builder.forcedClock.ref, 0)) } stp } /** Terminate execution with a failure code. */ - @deprecated("Non-zero return codes are not well supported. Please use assert(false.B) if you want to indicate a failure.", "Chisel 3.5") + @deprecated( + "Non-zero return codes are not well supported. Please use assert(false.B) if you want to indicate a failure.", + "Chisel 3.5" + ) def apply(code: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Stop = { val stp = new Stop() - when (!Module.reset.asBool) { + when(!Module.reset.asBool) { pushCommand(Stop(stp, sourceInfo, Builder.forcedClock.ref, code)) } stp } /** Named class for [[stop]]s. */ - final class Stop private[chisel3]()extends VerificationStatement + final class Stop private[chisel3] () extends VerificationStatement } /** Base class for all verification statements: Assert, Assume, Cover, Stop and Printf. */ @@ -220,8 +300,16 @@ private object VerificationStatement { } // creates a printf to inform the user of a failed assertion or assumption - def failureMessage(kind: String, lineInfo: SourceLineInfo, cond: Bool, message: Option[String], data: Seq[Bits]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) : Unit = { + def failureMessage( + kind: String, + lineInfo: SourceLineInfo, + cond: Bool, + message: Option[String], + data: Seq[Bits] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { val (filename, line, content) = lineInfo val lineMsg = s"$filename:$line $content".replaceAll("%", "%%") val fmt = message match { @@ -230,7 +318,7 @@ private object VerificationStatement { case None => s"$kind failed\n at $lineMsg\n" } when(!cond) { - printf.printfWithoutReset(fmt, data:_*) + printf.printfWithoutReset(fmt, data: _*) } } } diff --git a/core/src/main/scala/chisel3/When.scala b/core/src/main/scala/chisel3/When.scala index ca383c0f..727d8d0c 100644 --- a/core/src/main/scala/chisel3/When.scala +++ b/core/src/main/scala/chisel3/When.scala @@ -9,6 +9,7 @@ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo} object when { + /** Create a `when` condition block, where whether a block of logic is * executed or not depends on the conditional. * @@ -27,7 +28,13 @@ object when { * }}} */ - def apply(cond: => Bool)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): WhenContext = { + def apply( + cond: => Bool + )(block: => Any + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): WhenContext = { new WhenContext(sourceInfo, Some(() => cond), block, 0, Nil) } @@ -44,7 +51,7 @@ object when { * } * } * }}} - * */ + */ def cond: Bool = { implicit val compileOptions = ExplicitCompileOptions.Strict implicit val sourceInfo = UnlocatableSourceInfo @@ -66,13 +73,12 @@ object when { * added by preprocessing the command queue. */ final class WhenContext private[chisel3] ( - sourceInfo: SourceInfo, - cond: Option[() => Bool], - block: => Any, + sourceInfo: SourceInfo, + cond: Option[() => Bool], + block: => Any, firrtlDepth: Int, // For capturing conditions from prior whens or elsewhens - altConds: List[() => Bool] -) { + altConds: List[() => Bool]) { @deprecated("Use when(...) { ... }, this should never have been public", "Chisel 3.4.2") def this(sourceInfo: SourceInfo, cond: Option[() => Bool], block: => Any, firrtlDepth: Int = 0) = @@ -87,8 +93,9 @@ final class WhenContext private[chisel3] ( val alt = altConds.foldRight(true.B) { case (c, acc) => acc & !c() } - cond.map(alt && _()) - .getOrElse(alt) + cond + .map(alt && _()) + .getOrElse(alt) } /** This block of logic gets executed if above conditions have been @@ -97,7 +104,13 @@ final class WhenContext private[chisel3] ( * declaration and assignment of the Bool node of the predicate in * the correct place. */ - def elsewhen (elseCond: => Bool)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): WhenContext = { + def elsewhen( + elseCond: => Bool + )(block: => Any + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): WhenContext = { new WhenContext(sourceInfo, Some(() => elseCond), block, firrtlDepth + 1, cond ++: altConds) } @@ -113,26 +126,30 @@ final class WhenContext private[chisel3] ( def active: Boolean = scopeOpen - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def active(dummy: Int*): Boolean = active /* * */ if (firrtlDepth > 0) { pushCommand(AltBegin(sourceInfo)) } - cond.foreach( c => pushCommand(WhenBegin(sourceInfo, c().ref)) ) + cond.foreach(c => pushCommand(WhenBegin(sourceInfo, c().ref))) Builder.pushWhen(this) try { scopeOpen = true block } catch { case _: scala.runtime.NonLocalReturnControl[_] => - throwException("Cannot exit from a when() block with a \"return\"!" + - " Perhaps you meant to use Mux or a Wire as a return value?" + throwException( + "Cannot exit from a when() block with a \"return\"!" + + " Perhaps you meant to use Mux or a Wire as a return value?" ) } scopeOpen = false Builder.popWhen() - cond.foreach(_ => pushCommand(WhenEnd(sourceInfo,firrtlDepth))) - if (cond.isEmpty) { pushCommand(OtherwiseEnd(sourceInfo,firrtlDepth)) } + cond.foreach(_ => pushCommand(WhenEnd(sourceInfo, firrtlDepth))) + if (cond.isEmpty) { pushCommand(OtherwiseEnd(sourceInfo, firrtlDepth)) } } diff --git a/core/src/main/scala/chisel3/aop/Aspect.scala b/core/src/main/scala/chisel3/aop/Aspect.scala index be9b8975..dd014357 100644 --- a/core/src/main/scala/chisel3/aop/Aspect.scala +++ b/core/src/main/scala/chisel3/aop/Aspect.scala @@ -12,10 +12,12 @@ import firrtl.AnnotationSeq * @tparam T Type of top-level module */ abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation { + /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]] * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]] */ private[aop] var annotationsInAspect: AnnotationSeq = Seq() + /** Convert this Aspect to a seq of FIRRTL annotation * @param top * @return diff --git a/core/src/main/scala/chisel3/dontTouch.scala b/core/src/main/scala/chisel3/dontTouch.scala index e679f1a4..dc998ff5 100644 --- a/core/src/main/scala/chisel3/dontTouch.scala +++ b/core/src/main/scala/chisel3/dontTouch.scala @@ -2,7 +2,7 @@ package chisel3 -import chisel3.experimental.{ChiselAnnotation, annotate, requireIsHardware} +import chisel3.experimental.{annotate, requireIsHardware, ChiselAnnotation} import firrtl.transforms.DontTouchAnnotation /** Marks that a signal is an optimization barrier to Chisel and the FIRRTL compiler. This has the effect of @@ -26,6 +26,7 @@ import firrtl.transforms.DontTouchAnnotation * dontTouch. */ object dontTouch { + /** Mark a signal as an optimization barrier to Chisel and FIRRTL. * * @note Requires the argument to be bound to hardware diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala index e94bae2d..a366f0c3 100644 --- a/core/src/main/scala/chisel3/experimental/Analog.scala +++ b/core/src/main/scala/chisel3/experimental/Analog.scala @@ -5,7 +5,18 @@ package chisel3.experimental import chisel3.internal.firrtl.Width import chisel3.internal.sourceinfo.SourceInfo import chisel3.internal._ -import chisel3.{ActualDirection, Bits, CompileOptions, Data, Element, PString, Printable, RawModule, SpecifiedDirection, UInt} +import chisel3.{ + ActualDirection, + Bits, + CompileOptions, + Data, + Element, + PString, + Printable, + RawModule, + SpecifiedDirection, + UInt +} import scala.collection.mutable @@ -47,7 +58,7 @@ final class Analog private (private[chisel3] val width: Width) extends Element { _parent.foreach(_.addId(this)) SpecifiedDirection.fromParent(parentDirection, specifiedDirection) match { case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => - case x => throwException(s"Analog may not have explicit direction, got '$x'") + case x => throwException(s"Analog may not have explicit direction, got '$x'") } val targetTopBinding = target match { case target: TopBinding => target @@ -67,8 +78,12 @@ final class Analog private (private[chisel3] val width: Width) extends Element { override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = throwException("Analog does not support asUInt") - private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo, - compileOptions: CompileOptions): Unit = { + private[chisel3] override def connectFromBits( + that: Bits + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Unit = { throwException("Analog does not support connectFromBits") } diff --git a/core/src/main/scala/chisel3/experimental/Trace.scala b/core/src/main/scala/chisel3/experimental/Trace.scala index 2d965c7b..4ab615a5 100644 --- a/core/src/main/scala/chisel3/experimental/Trace.scala +++ b/core/src/main/scala/chisel3/experimental/Trace.scala @@ -18,7 +18,7 @@ import firrtl.transforms.DontTouchAllTargets * // get final reference of `a` Seq(ReferenceTarget("Dut", "Dut", Seq.empty, "a", Seq.empty)) * val firrtlReferenceOfDutA = finalTarget(annos)(dut.a) * }}} - * */ + */ object Trace { /** Trace a Instance name. */ @@ -49,8 +49,8 @@ object Trace { * @param chiselTarget original annotated target in Chisel, which should not be changed or renamed in FIRRTL. */ private case class TraceNameAnnotation[T <: CompleteTarget](target: T, chiselTarget: T) - extends SingleTargetAnnotation[T] - with DontTouchAllTargets { + extends SingleTargetAnnotation[T] + with DontTouchAllTargets { def duplicate(n: T): Annotation = this.copy(target = n) } @@ -64,6 +64,6 @@ object Trace { * This API can be used to gather all final reference to the signal or module which is marked by `traceName` */ def finalTargetMap(annos: AnnotationSeq): Map[CompleteTarget, Seq[CompleteTarget]] = annos.collect { - case TraceNameAnnotation(t, chiselTarget) => chiselTarget -> t - }.groupBy(_._1).map{case (k, v) => k -> v.map(_._2)} + case TraceNameAnnotation(t, chiselTarget) => chiselTarget -> t + }.groupBy(_._1).map { case (k, v) => k -> v.map(_._2) } } diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala b/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala index 438f97b8..c6ebe604 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/DataProduct.scala @@ -3,7 +3,7 @@ package chisel3.experimental.dataview import chisel3.experimental.BaseModule -import chisel3.{Data, Vec, getRecursiveFields} +import chisel3.{getRecursiveFields, Data, Vec} import scala.annotation.implicitNotFound @@ -18,9 +18,12 @@ import scala.annotation.implicitNotFound * @tparam A Type that has elements of type [[Data]] * @see [[https://www.chisel-lang.org/chisel3/docs/explanations/dataview#dataproduct Detailed Documentation]] */ -@implicitNotFound("Could not find implicit value for DataProduct[${A}].\n" + - "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview#dataproduct") +@implicitNotFound( + "Could not find implicit value for DataProduct[${A}].\n" + + "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview#dataproduct" +) trait DataProduct[-A] { + /** Provides [[Data]] elements within some containing object * * @param a Containing object @@ -59,6 +62,7 @@ sealed trait LowPriorityDataProduct { * @note DataProduct implementations provided in this object are available in the implicit scope */ object DataProduct extends LowPriorityDataProduct { + /** [[DataProduct]] implementation for [[BaseModule]] */ implicit val userModuleDataProduct: DataProduct[BaseModule] = new DataProduct[BaseModule] { def dataIterator(a: BaseModule, path: String): Iterator[(Data, String)] = { @@ -78,19 +82,18 @@ object DataProduct extends LowPriorityDataProduct { } /** [[DataProduct]] implementation for any `Seq[A]` where `A` has an implementation of `DataProduct`. */ - implicit def seqDataProduct[A : DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] { + implicit def seqDataProduct[A: DataProduct]: DataProduct[Seq[A]] = new DataProduct[Seq[A]] { def dataIterator(a: Seq[A], path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] - a.iterator - .zipWithIndex - .flatMap { case (elt, idx) => + a.iterator.zipWithIndex.flatMap { + case (elt, idx) => dpa.dataIterator(elt, s"$path[$idx]") - } + } } } /** [[DataProduct]] implementation for any [[Tuple2]] where each field has an implementation of `DataProduct`. */ - implicit def tuple2DataProduct[A : DataProduct, B : DataProduct]: DataProduct[(A, B)] = new DataProduct[(A, B)] { + implicit def tuple2DataProduct[A: DataProduct, B: DataProduct]: DataProduct[(A, B)] = new DataProduct[(A, B)] { def dataIterator(tup: (A, B), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] val dpb = implicitly[DataProduct[B]] @@ -100,7 +103,7 @@ object DataProduct extends LowPriorityDataProduct { } /** [[DataProduct]] implementation for any [[Tuple3]] where each field has an implementation of `DataProduct`. */ - implicit def tuple3DataProduct[A : DataProduct, B : DataProduct, C : DataProduct]: DataProduct[(A, B, C)] = + implicit def tuple3DataProduct[A: DataProduct, B: DataProduct, C: DataProduct]: DataProduct[(A, B, C)] = new DataProduct[(A, B, C)] { def dataIterator(tup: (A, B, C), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -112,7 +115,12 @@ object DataProduct extends LowPriorityDataProduct { } /** [[DataProduct]] implementation for any [[Tuple4]] where each field has an implementation of `DataProduct`. */ - implicit def tuple4DataProduct[A : DataProduct, B : DataProduct, C : DataProduct, D : DataProduct]: DataProduct[(A, B, C, D)] = + implicit def tuple4DataProduct[ + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct + ]: DataProduct[(A, B, C, D)] = new DataProduct[(A, B, C, D)] { def dataIterator(tup: (A, B, C, D), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -129,11 +137,12 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple5]] where each field has an implementation of `DataProduct`. */ implicit def tuple5DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct]: DataProduct[(A, B, C, D, E)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct + ]: DataProduct[(A, B, C, D, E)] = new DataProduct[(A, B, C, D, E)] { def dataIterator(tup: (A, B, C, D, E), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -152,12 +161,13 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple6]] where each field has an implementation of `DataProduct`. */ implicit def tuple6DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct, - F : DataProduct]: DataProduct[(A, B, C, D, E, F)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct, + F: DataProduct + ]: DataProduct[(A, B, C, D, E, F)] = new DataProduct[(A, B, C, D, E, F)] { def dataIterator(tup: (A, B, C, D, E, F), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -178,13 +188,14 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple7]] where each field has an implementation of `DataProduct`. */ implicit def tuple7DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct, - F : DataProduct, - G : DataProduct]: DataProduct[(A, B, C, D, E, F, G)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct, + F: DataProduct, + G: DataProduct + ]: DataProduct[(A, B, C, D, E, F, G)] = new DataProduct[(A, B, C, D, E, F, G)] { def dataIterator(tup: (A, B, C, D, E, F, G), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -207,14 +218,15 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple8]] where each field has an implementation of `DataProduct`. */ implicit def tuple8DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct, - F : DataProduct, - G : DataProduct, - H : DataProduct]: DataProduct[(A, B, C, D, E, F, G, H)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct, + F: DataProduct, + G: DataProduct, + H: DataProduct + ]: DataProduct[(A, B, C, D, E, F, G, H)] = new DataProduct[(A, B, C, D, E, F, G, H)] { def dataIterator(tup: (A, B, C, D, E, F, G, H), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -239,15 +251,16 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple9]] where each field has an implementation of `DataProduct`. */ implicit def tuple9DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct, - F : DataProduct, - G : DataProduct, - H : DataProduct, - I : DataProduct]: DataProduct[(A, B, C, D, E, F, G, H, I)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct, + F: DataProduct, + G: DataProduct, + H: DataProduct, + I: DataProduct + ]: DataProduct[(A, B, C, D, E, F, G, H, I)] = new DataProduct[(A, B, C, D, E, F, G, H, I)] { def dataIterator(tup: (A, B, C, D, E, F, G, H, I), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] @@ -274,16 +287,17 @@ object DataProduct extends LowPriorityDataProduct { /** [[DataProduct]] implementation for any [[Tuple9]] where each field has an implementation of `DataProduct`. */ implicit def tuple10DataProduct[ - A : DataProduct, - B : DataProduct, - C : DataProduct, - D : DataProduct, - E : DataProduct, - F : DataProduct, - G : DataProduct, - H : DataProduct, - I : DataProduct, - J : DataProduct]: DataProduct[(A, B, C, D, E, F, G, H, I, J)] = + A: DataProduct, + B: DataProduct, + C: DataProduct, + D: DataProduct, + E: DataProduct, + F: DataProduct, + G: DataProduct, + H: DataProduct, + I: DataProduct, + J: DataProduct + ]: DataProduct[(A, B, C, D, E, F, G, H, I, J)] = new DataProduct[(A, B, C, D, E, F, G, H, I, J)] { def dataIterator(tup: (A, B, C, D, E, F, G, H, I, J), path: String): Iterator[(Data, String)] = { val dpa = implicitly[DataProduct[A]] diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala index c17a5574..7f20964d 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala @@ -11,7 +11,6 @@ import chisel3.ExplicitCompileOptions.Strict import scala.reflect.runtime.universe.WeakTypeTag import annotation.implicitNotFound - /** Mapping between a target type `T` and a view type `V` * * Enables calling `.viewAs[T]` on instances of the target type. @@ -41,9 +40,11 @@ import annotation.implicitNotFound * @see [[DataView$ object DataView]] for factory methods * @see [[PartialDataView object PartialDataView]] for defining non-total `DataViews` */ -@implicitNotFound("Could not find implicit value for DataView[${T}, ${V}].\n" + - "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview") -sealed class DataView[T : DataProduct, V <: Data] private[chisel3] ( +@implicitNotFound( + "Could not find implicit value for DataView[${T}, ${V}].\n" + + "Please see https://www.chisel-lang.org/chisel3/docs/explanations/dataview" +) +sealed class DataView[T: DataProduct, V <: Data] private[chisel3] ( /** Function constructing an object of the View type from an object of the Target type */ private[chisel3] val mkView: T => V, /** Function that returns corresponding fields of the target and view */ @@ -51,8 +52,8 @@ sealed class DataView[T : DataProduct, V <: Data] private[chisel3] ( // Aliasing this with a def below to make the ScalaDoc show up for the field _total: Boolean )( - implicit private[chisel3] val sourceInfo: SourceInfo -) { + implicit private[chisel3] val sourceInfo: SourceInfo) { + /** Indicates if the mapping contains every field of the target */ def total: Boolean = _total @@ -89,15 +90,30 @@ sealed class DataView[T : DataProduct, V <: Data] private[chisel3] ( object DataView { /** Default factory method, alias for [[pairs]] */ - def apply[T : DataProduct, V <: Data](mkView: T => V, pairs: ((T, V) => (Data, Data))*)(implicit sourceInfo: SourceInfo): DataView[T, V] = + def apply[T: DataProduct, V <: Data]( + mkView: T => V, + pairs: ((T, V) => (Data, Data))* + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = DataView.pairs(mkView, pairs: _*) /** Construct [[DataView]]s with pairs of functions from the target and view to corresponding fields */ - def pairs[T : DataProduct, V <: Data](mkView: T => V, pairs: ((T, V) => (Data, Data))*)(implicit sourceInfo: SourceInfo): DataView[T, V] = + def pairs[T: DataProduct, V <: Data]( + mkView: T => V, + pairs: ((T, V) => (Data, Data))* + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = mapping(mkView: T => V, swizzle(pairs)) /** More general factory method for complex mappings */ - def mapping[T : DataProduct, V <: Data](mkView: T => V, mapping: (T, V) => Iterable[(Data, Data)])(implicit sourceInfo: SourceInfo): DataView[T, V] = + def mapping[T: DataProduct, V <: Data]( + mkView: T => V, + mapping: (T, V) => Iterable[(Data, Data)] + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = new DataView[T, V](mkView, mapping, _total = true) /** Provides `invert` for invertible [[DataView]]s @@ -107,7 +123,7 @@ object DataView { * * @note [[PartialDataView]]s are **not** invertible and will result in an elaboration time exception */ - implicit class InvertibleDataView[T <: Data : WeakTypeTag, V <: Data : WeakTypeTag](view: DataView[T, V]) { + implicit class InvertibleDataView[T <: Data: WeakTypeTag, V <: Data: WeakTypeTag](view: DataView[T, V]) { def invert(mkView: V => T): DataView[V, T] = { // It would've been nice to make this a compiler error, but it's unclear how to make that work. // We tried having separate TotalDataView and PartialDataView and only defining inversion for @@ -143,7 +159,10 @@ object DataView { DataView[A, A](chiselTypeOf.apply, { case (x, y) => (x, y) }) /** Provides `DataView[Seq[A], Vec[B]]` for all `A` such that there exists `DataView[A, B]` */ - implicit def seqDataView[A : DataProduct, B <: Data](implicit dv: DataView[A, B], sourceInfo: SourceInfo): DataView[Seq[A], Vec[B]] = { + implicit def seqDataView[A: DataProduct, B <: Data]( + implicit dv: DataView[A, B], + sourceInfo: SourceInfo + ): DataView[Seq[A], Vec[B]] = { // TODO this would need a better way to determine the prototype for the Vec DataView.mapping[Seq[A], Vec[B]]( xs => Vec(xs.size, chiselTypeClone(xs.head.viewAs[B]))(sourceInfo, Strict), // xs.head is not correct in general @@ -151,223 +170,395 @@ object DataView { ) } - /** Provides implementations of [[DataView]] for [[Tuple2]] to [[HWTuple2]] */ - implicit def tuple2DataView[T1 : DataProduct, T2 : DataProduct, V1 <: Data, V2 <: Data]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], sourceInfo: SourceInfo + /** Provides implementations of [[DataView]] for [[Tuple2]] to [[HWTuple2]] */ + implicit def tuple2DataView[T1: DataProduct, T2: DataProduct, V1 <: Data, V2 <: Data]( + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + sourceInfo: SourceInfo ): DataView[(T1, T2), HWTuple2[V1, V2]] = DataView.mapping( - { case (a, b) => new HWTuple2(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType)}, - { case ((a, b), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2) + { case (a, b) => new HWTuple2(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType) }, + { + case ((a, b), hwt) => + Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2) } ) - /** Provides implementations of [[DataView]] for [[Tuple3]] to [[HWTuple3]] */ - implicit def tuple3DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data - ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], sourceInfo: SourceInfo + /** Provides implementations of [[DataView]] for [[Tuple3]] to [[HWTuple3]] */ + implicit def tuple3DataView[T1: DataProduct, T2: DataProduct, T3: DataProduct, V1 <: Data, V2 <: Data, V3 <: Data]( + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3), HWTuple3[V1, V2, V3]] = DataView.mapping( - { case (a, b, c) => new HWTuple3(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType)}, - { case ((a, b, c), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3) + { case (a, b, c) => new HWTuple3(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType) }, + { + case ((a, b, c), hwt) => + Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2, c.viewAs[V3] -> hwt._3) } ) - /** Provides implementations of [[DataView]] for [[Tuple4]] to [[HWTuple4]] */ + /** Provides implementations of [[DataView]] for [[Tuple4]] to [[HWTuple4]] */ implicit def tuple4DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4), HWTuple4[V1, V2, V3, V4]] = DataView.mapping( - { case (a, b, c, d) => - new HWTuple4(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType - )}, - { case ((a, b, c, d), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4) + { + case (a, b, c, d) => + new HWTuple4(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType) + }, + { + case ((a, b, c, d), hwt) => + Seq(a.viewAs[V1] -> hwt._1, b.viewAs[V2] -> hwt._2, c.viewAs[V3] -> hwt._3, d.viewAs[V4] -> hwt._4) } ) - /** Provides implementations of [[DataView]] for [[Tuple5]] to [[HWTuple5]] */ + /** Provides implementations of [[DataView]] for [[Tuple5]] to [[HWTuple5]] */ implicit def tuple5DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5), HWTuple5[V1, V2, V3, V4, V5]] = { DataView.mapping( - { case tup: Tuple5[T1, T2, T3, T4, T5] => - val (a, b, c, d, e) = tup - new HWTuple5(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType - ) + { + case tup: Tuple5[T1, T2, T3, T4, T5] => + val (a, b, c, d, e) = tup + new HWTuple5( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType + ) }, - { case ((a, b, c, d, e), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5) + { + case ((a, b, c, d, e), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5 + ) } ) } - /** Provides implementations of [[DataView]] for [[Tuple6]] to [[HWTuple6]] */ + /** Provides implementations of [[DataView]] for [[Tuple6]] to [[HWTuple6]] */ implicit def tuple6DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, V6 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], - v5: DataView[T5, V5], v6: DataView[T6, V6], - sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5, T6), HWTuple6[V1, V2, V3, V4, V5, V6]] = DataView.mapping( - { case (a, b, c, d, e, f) => - new HWTuple6(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType, f.viewAs[V6].cloneType - ) + { + case (a, b, c, d, e, f) => + new HWTuple6( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType, + f.viewAs[V6].cloneType + ) }, - { case ((a, b, c, d, e, f), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5, - f.viewAs[V6] -> hwt._6) + { + case ((a, b, c, d, e, f), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5, + f.viewAs[V6] -> hwt._6 + ) } ) - /** Provides implementations of [[DataView]] for [[Tuple7]] to [[HWTuple7]] */ + /** Provides implementations of [[DataView]] for [[Tuple7]] to [[HWTuple7]] */ implicit def tuple7DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, - V6 <: Data, V7 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], - v5: DataView[T5, V5], v6: DataView[T6, V6], v7: DataView[T7, V7], - sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5, T6, T7), HWTuple7[V1, V2, V3, V4, V5, V6, V7]] = DataView.mapping( - { case (a, b, c, d, e, f, g) => - new HWTuple7(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType, f.viewAs[V6].cloneType, g.viewAs[V7].cloneType - ) + { + case (a, b, c, d, e, f, g) => + new HWTuple7( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType, + f.viewAs[V6].cloneType, + g.viewAs[V7].cloneType + ) }, - { case ((a, b, c, d, e, f, g), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5, - f.viewAs[V6] -> hwt._6, - g.viewAs[V7] -> hwt._7) + { + case ((a, b, c, d, e, f, g), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5, + f.viewAs[V6] -> hwt._6, + g.viewAs[V7] -> hwt._7 + ) } ) - /** Provides implementations of [[DataView]] for [[Tuple8]] to [[HWTuple8]] */ + /** Provides implementations of [[DataView]] for [[Tuple8]] to [[HWTuple8]] */ implicit def tuple8DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, - V6 <: Data, V7 <: Data, V8 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], - v5: DataView[T5, V5], v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8], - sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8), HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8]] = DataView.mapping( - { case (a, b, c, d, e, f, g, h) => - new HWTuple8(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType, f.viewAs[V6].cloneType, g.viewAs[V7].cloneType, h.viewAs[V8].cloneType - ) + { + case (a, b, c, d, e, f, g, h) => + new HWTuple8( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType, + f.viewAs[V6].cloneType, + g.viewAs[V7].cloneType, + h.viewAs[V8].cloneType + ) }, - { case ((a, b, c, d, e, f, g, h), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5, - f.viewAs[V6] -> hwt._6, - g.viewAs[V7] -> hwt._7, - h.viewAs[V8] -> hwt._8) + { + case ((a, b, c, d, e, f, g, h), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5, + f.viewAs[V6] -> hwt._6, + g.viewAs[V7] -> hwt._7, + h.viewAs[V8] -> hwt._8 + ) } ) - /** Provides implementations of [[DataView]] for [[Tuple9]] to [[HWTuple9]] */ + /** Provides implementations of [[DataView]] for [[Tuple9]] to [[HWTuple9]] */ implicit def tuple9DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, T9 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, - V6 <: Data, V7 <: Data, V8 <: Data, V9 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + T9: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data, + V9 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], - v5: DataView[T5, V5], v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8], - v9: DataView[T9, V9], - sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8], + v9: DataView[T9, V9], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8, T9), HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9]] = DataView.mapping( - { case (a, b, c, d, e, f, g, h, i) => - new HWTuple9(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType, f.viewAs[V6].cloneType, g.viewAs[V7].cloneType, h.viewAs[V8].cloneType, - i.viewAs[V9].cloneType - ) + { + case (a, b, c, d, e, f, g, h, i) => + new HWTuple9( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType, + f.viewAs[V6].cloneType, + g.viewAs[V7].cloneType, + h.viewAs[V8].cloneType, + i.viewAs[V9].cloneType + ) }, - { case ((a, b, c, d, e, f, g, h, i), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5, - f.viewAs[V6] -> hwt._6, - g.viewAs[V7] -> hwt._7, - h.viewAs[V8] -> hwt._8, - i.viewAs[V9] -> hwt._9) + { + case ((a, b, c, d, e, f, g, h, i), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5, + f.viewAs[V6] -> hwt._6, + g.viewAs[V7] -> hwt._7, + h.viewAs[V8] -> hwt._8, + i.viewAs[V9] -> hwt._9 + ) } ) - /** Provides implementations of [[DataView]] for [[Tuple10]] to [[HWTuple10]] */ + /** Provides implementations of [[DataView]] for [[Tuple10]] to [[HWTuple10]] */ implicit def tuple10DataView[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, T9 : DataProduct, T10 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, - V6 <: Data, V7 <: Data, V8 <: Data, V9 <: Data, V10 <: Data + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + T9: DataProduct, + T10: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data, + V9 <: Data, + V10 <: Data ]( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], - v5: DataView[T5, V5], v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8], - v9: DataView[T9, V9], v10: DataView[T10, V10], - sourceInfo: SourceInfo + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8], + v9: DataView[T9, V9], + v10: DataView[T10, V10], + sourceInfo: SourceInfo ): DataView[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10]] = DataView.mapping( - { case (a, b, c, d, e, f, g, h, i, j) => - new HWTuple10(a.viewAs[V1].cloneType, b.viewAs[V2].cloneType, c.viewAs[V3].cloneType, d.viewAs[V4].cloneType, - e.viewAs[V5].cloneType, f.viewAs[V6].cloneType, g.viewAs[V7].cloneType, h.viewAs[V8].cloneType, - i.viewAs[V9].cloneType, j.viewAs[V10].cloneType - ) + { + case (a, b, c, d, e, f, g, h, i, j) => + new HWTuple10( + a.viewAs[V1].cloneType, + b.viewAs[V2].cloneType, + c.viewAs[V3].cloneType, + d.viewAs[V4].cloneType, + e.viewAs[V5].cloneType, + f.viewAs[V6].cloneType, + g.viewAs[V7].cloneType, + h.viewAs[V8].cloneType, + i.viewAs[V9].cloneType, + j.viewAs[V10].cloneType + ) }, - { case ((a, b, c, d, e, f, g, h, i, j), hwt) => - Seq(a.viewAs[V1] -> hwt._1, - b.viewAs[V2] -> hwt._2, - c.viewAs[V3] -> hwt._3, - d.viewAs[V4] -> hwt._4, - e.viewAs[V5] -> hwt._5, - f.viewAs[V6] -> hwt._6, - g.viewAs[V7] -> hwt._7, - h.viewAs[V8] -> hwt._8, - i.viewAs[V9] -> hwt._9, - j.viewAs[V10] -> hwt._10) + { + case ((a, b, c, d, e, f, g, h, i, j), hwt) => + Seq( + a.viewAs[V1] -> hwt._1, + b.viewAs[V2] -> hwt._2, + c.viewAs[V3] -> hwt._3, + d.viewAs[V4] -> hwt._4, + e.viewAs[V5] -> hwt._5, + f.viewAs[V6] -> hwt._6, + g.viewAs[V7] -> hwt._7, + h.viewAs[V8] -> hwt._8, + i.viewAs[V9] -> hwt._9, + j.viewAs[V10] -> hwt._10 + ) } ) } @@ -376,14 +567,29 @@ object DataView { object PartialDataView { /** Default factory method, alias for [[pairs]] */ - def apply[T: DataProduct, V <: Data](mkView: T => V, pairs: ((T, V) => (Data, Data))*)(implicit sourceInfo: SourceInfo): DataView[T, V] = + def apply[T: DataProduct, V <: Data]( + mkView: T => V, + pairs: ((T, V) => (Data, Data))* + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = PartialDataView.pairs(mkView, pairs: _*) /** Construct [[DataView]]s with pairs of functions from the target and view to corresponding fields */ - def pairs[T: DataProduct, V <: Data](mkView: T => V, pairs: ((T, V) => (Data, Data))*)(implicit sourceInfo: SourceInfo): DataView[T, V] = + def pairs[T: DataProduct, V <: Data]( + mkView: T => V, + pairs: ((T, V) => (Data, Data))* + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = mapping(mkView, DataView.swizzle(pairs)) /** More general factory method for complex mappings */ - def mapping[T: DataProduct, V <: Data](mkView: T => V, mapping: (T, V) => Iterable[(Data, Data)])(implicit sourceInfo: SourceInfo): DataView[T, V] = + def mapping[T: DataProduct, V <: Data]( + mkView: T => V, + mapping: (T, V) => Iterable[(Data, Data)] + )( + implicit sourceInfo: SourceInfo + ): DataView[T, V] = new DataView[T, V](mkView, mapping, _total = false) } diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala index 1acf43e1..3278d82c 100644 --- a/core/src/main/scala/chisel3/experimental/dataview/package.scala +++ b/core/src/main/scala/chisel3/experimental/dataview/package.scala @@ -39,27 +39,39 @@ package object dataview { } // This private type alias lets us provide a custom error message for misuing the .viewAs for upcasting Bundles - @implicitNotFound("${A} is not a subtype of ${B}! Did you mean .viewAs[${B}]? " + - "Please see https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview") + @implicitNotFound( + "${A} is not a subtype of ${B}! Did you mean .viewAs[${B}]? " + + "Please see https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview" + ) private type SubTypeOf[A, B] = A <:< B /** Provides `viewAsSupertype` for subclasses of [[Bundle]] */ implicit class BundleUpcastable[T <: Bundle](target: T) { + /** View a [[Bundle]] or [[Record]] as a parent type (upcast) */ def viewAsSupertype[V <: Bundle](proto: V)(implicit ev: SubTypeOf[T, V], sourceInfo: SourceInfo): V = { - implicit val dataView = PartialDataView.mapping[T, V](_ => proto, { - case (a, b) => - val aElts = a.elements - val bElts = b.elements - val bKeys = bElts.keySet - val keys = aElts.keysIterator.filter(bKeys.contains) - keys.map(k => aElts(k) -> bElts(k)).toSeq - }) + implicit val dataView = PartialDataView.mapping[T, V]( + _ => proto, + { + case (a, b) => + val aElts = a.elements + val bElts = b.elements + val bKeys = bElts.keySet + val keys = aElts.keysIterator.filter(bKeys.contains) + keys.map(k => aElts(k) -> bElts(k)).toSeq + } + ) target.viewAs[V] } } - private def nonTotalViewException(dataView: DataView[_, _], target: Any, view: Data, targetFields: Seq[String], viewFields: Seq[String]) = { + private def nonTotalViewException( + dataView: DataView[_, _], + target: Any, + view: Data, + targetFields: Seq[String], + viewFields: Seq[String] + ) = { def missingMsg(name: String, fields: Seq[String]): Option[String] = { val str = fields.mkString(", ") fields.size match { @@ -77,18 +89,17 @@ package object dataview { } // TODO should this be moved to class Aggregate / can it be unified with Aggregate.bind? - private def doBind[T : DataProduct, V <: Data](target: T, view: V, dataView: DataView[T, V]): Unit = { + private def doBind[T: DataProduct, V <: Data](target: T, view: V, dataView: DataView[T, V]): Unit = { val mapping = dataView.mapping(target, view) val total = dataView.total // Lookups to check the mapping results val viewFieldLookup: Map[Data, String] = getRecursiveFields(view, "_").toMap - val targetContains: Data => Boolean = implicitly[DataProduct[T]].dataSet(target) + val targetContains: Data => Boolean = implicitly[DataProduct[T]].dataSet(target) // Resulting bindings for each Element of the View val childBindings = new mutable.HashMap[Data, mutable.ListBuffer[Element]] ++ - viewFieldLookup.view - .collect { case (elt: Element, _) => elt } + viewFieldLookup.view.collect { case (elt: Element, _) => elt } .map(_ -> new mutable.ListBuffer[Element]) def viewFieldName(d: Data): String = @@ -115,7 +126,9 @@ package object dataview { val fieldName = viewFieldName(vex) val vwidth = widthAsString(vex) val twidth = widthAsString(tex) - throw InvalidViewException(s"View field $fieldName has width ${vwidth} that is incompatible with target value $tex's width ${twidth}") + throw InvalidViewException( + s"View field $fieldName has width ${vwidth} that is incompatible with target value $tex's width ${twidth}" + ) } childBindings(vex) += tex } @@ -137,23 +150,24 @@ package object dataview { } // Errors in totality of the View, use var List to keep fast path cheap (no allocation) - var viewNonTotalErrors: List[Data] = Nil + var viewNonTotalErrors: List[Data] = Nil var targetNonTotalErrors: List[String] = Nil val targetSeen: Option[mutable.Set[Data]] = if (total) Some(mutable.Set.empty[Data]) else None - val resultBindings = childBindings.map { case (data, targets) => - val targetsx = targets match { - case collection.Seq(target: Element) => target - case collection.Seq() => - viewNonTotalErrors = data :: viewNonTotalErrors - data.asInstanceOf[Element] // Return the Data itself, will error after this map, cast is safe - case x => - throw InvalidViewException(s"Got $x, expected Seq(_: Direct)") - } - // TODO record and report aliasing errors - targetSeen.foreach(_ += targetsx) - data -> targetsx + val resultBindings = childBindings.map { + case (data, targets) => + val targetsx = targets match { + case collection.Seq(target: Element) => target + case collection.Seq() => + viewNonTotalErrors = data :: viewNonTotalErrors + data.asInstanceOf[Element] // Return the Data itself, will error after this map, cast is safe + case x => + throw InvalidViewException(s"Got $x, expected Seq(_: Direct)") + } + // TODO record and report aliasing errors + targetSeen.foreach(_ += targetsx) + data -> targetsx }.toMap // Check for totality of Target @@ -169,7 +183,7 @@ package object dataview { } view match { - case elt: Element => view.bind(ViewBinding(resultBindings(elt))) + case elt: Element => view.bind(ViewBinding(resultBindings(elt))) case agg: Aggregate => // We record total Data mappings to provide a better .toTarget val topt = target match { @@ -221,31 +235,31 @@ package object dataview { @tailrec private[chisel3] def reify(elt: Element, topBinding: TopBinding): Element = topBinding match { case ViewBinding(target) => reify(target, elt.topBinding) - case _ => elt + case _ => elt } - /** Determine the target of a View if it is a single Target - * - * @note An Aggregate may be a view of unrelated [[Data]] (eg. like a Seq or tuple) and thus this - * there is no single Data representing the Target and this function will return None - * @return The single Data target of this view or None if a single Data doesn't exist - */ - private[chisel3] def reifySingleData(data: Data): Option[Data] = { - val candidate: Option[Data] = - data.binding.collect { // First check if this is a total mapping of an Aggregate - case AggregateViewBinding(_, Some(t)) => t - }.orElse { // Otherwise look via top binding - data.topBindingOpt match { - case None => None - case Some(ViewBinding(target)) => Some(target) - case Some(AggregateViewBinding(lookup, _)) => lookup.get(data) - case Some(_) => None - } + /** Determine the target of a View if it is a single Target + * + * @note An Aggregate may be a view of unrelated [[Data]] (eg. like a Seq or tuple) and thus this + * there is no single Data representing the Target and this function will return None + * @return The single Data target of this view or None if a single Data doesn't exist + */ + private[chisel3] def reifySingleData(data: Data): Option[Data] = { + val candidate: Option[Data] = + data.binding.collect { // First check if this is a total mapping of an Aggregate + case AggregateViewBinding(_, Some(t)) => t + }.orElse { // Otherwise look via top binding + data.topBindingOpt match { + case None => None + case Some(ViewBinding(target)) => Some(target) + case Some(AggregateViewBinding(lookup, _)) => lookup.get(data) + case Some(_) => None } - candidate.flatMap { d => - // Candidate may itself be a view, keep tracing in those cases - if (isView(d)) reifySingleData(d) else Some(d) } + candidate.flatMap { d => + // Candidate may itself be a view, keep tracing in those cases + if (isView(d)) reifySingleData(d) else Some(d) } + } } diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala index c7b51072..b498daf0 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala @@ -13,14 +13,17 @@ import chisel3.internal.BaseModule.IsClone import firrtl.annotations.{IsModule, ModuleTarget} /** User-facing Definition type. - * Represents a definition of an object of type [[A]] which are marked as @instantiable + * Represents a definition of an object of type [[A]] which are marked as @instantiable * Can be created using Definition.apply method. - * + * * These definitions are then used to create multiple [[Instance]]s. * * @param underlying The internal representation of the definition, which may be either be directly the object, or a clone of an object */ -final case class Definition[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) extends IsLookupable with SealedHierarchy[A] { +final case class Definition[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) + extends IsLookupable + with SealedHierarchy[A] { + /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!! * Instead, mark the field you are accessing with [[@public]] * @@ -35,14 +38,22 @@ final case class Definition[+A] private[chisel3] (private[chisel3] underlying: U * @param lookup typeclass which contains the correct lookup function, based on the types of A and B * @param macroGenerated a value created in the macro, to make it harder for users to use this API */ - def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C = { + def _lookup[B, C]( + that: A => B + )( + implicit lookup: Lookupable[B], + macroGenerated: chisel3.internal.MacroGenerated + ): lookup.C = { lookup.definitionLookup(that, this) } /** @return the context of any Data's return from inside the instance */ private[chisel3] def getInnerDataContext: Option[BaseModule] = proto match { case value: BaseModule => - val newChild = Module.do_pseudo_apply(new internal.BaseModule.DefinitionClone(value))(chisel3.internal.sourceinfo.UnlocatableSourceInfo, chisel3.ExplicitCompileOptions.Strict) + val newChild = Module.do_pseudo_apply(new internal.BaseModule.DefinitionClone(value))( + chisel3.internal.sourceinfo.UnlocatableSourceInfo, + chisel3.ExplicitCompileOptions.Strict + ) newChild._circuit = value._circuit.orElse(Some(value)) newChild._parent = None Some(newChild) @@ -50,14 +61,14 @@ final case class Definition[+A] private[chisel3] (private[chisel3] underlying: U } override def toDefinition: Definition[A] = this - override def toInstance: Instance[A] = new Instance(underlying) - + override def toInstance: Instance[A] = new Instance(underlying) } /** Factory methods for constructing [[Definition]]s */ object Definition extends SourceInfoDoc { implicit class DefinitionBaseModuleExtensions[T <: BaseModule](d: Definition[T]) { + /** If this is an instance of a Module, returns the toTarget of this instance * @return target of this instance */ @@ -68,6 +79,7 @@ object Definition extends SourceInfoDoc { */ def toAbsoluteTarget: IsModule = d.proto.toAbsoluteTarget } + /** A construction method to build a Definition of a Module * * @param proto the Module being defined @@ -82,7 +94,12 @@ object Definition extends SourceInfoDoc { * * @return the input module as a Definition */ - def do_apply[T <: BaseModule with IsInstantiable](proto: => T) (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Definition[T] = { + def do_apply[T <: BaseModule with IsInstantiable]( + proto: => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Definition[T] = { val dynamicContext = new DynamicContext(Nil) Builder.globalNamespace.copyTo(dynamicContext.globalNamespace) dynamicContext.inDefinition = true diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala index 4b8d3ccc..2016bb54 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Hierarchy.scala @@ -34,28 +34,27 @@ sealed trait Hierarchy[+A] { * E.g. isA[List[Int]] will return true, even if underlying proto is of type List[String] * @return Whether underlying proto is of provided type (with caveats outlined above) */ - def isA[B : TypeTag]: Boolean = { + def isA[B: TypeTag]: Boolean = { val tptag = implicitly[TypeTag[B]] // drop any type information for the comparison, because the proto will not have that information. - val name = tptag.tpe.toString.takeWhile(_ != '[') + val name = tptag.tpe.toString.takeWhile(_ != '[') inBaseClasses(name) } - // This code handles a special-case where, within an mdoc context, the type returned from // scala reflection (typetag) looks different than when returned from java reflection. // This function detects this case and reshapes the string to match. private def modifyReplString(clz: String): String = { - if(clz != null) { + if (clz != null) { clz.split('.').toList match { case "repl" :: "MdocSession" :: app :: rest => s"$app.this." + rest.mkString(".") - case other => clz + case other => clz } } else clz } private lazy val superClasses = calculateSuperClasses(proto.getClass()) private def calculateSuperClasses(clz: Class[_]): Set[String] = { - if(clz != null) { + if (clz != null) { Set(modifyReplString(clz.getCanonicalName())) ++ clz.getInterfaces().flatMap(i => calculateSuperClasses(i)) ++ calculateSuperClasses(clz.getSuperclass()) @@ -65,7 +64,6 @@ sealed trait Hierarchy[+A] { } private def inBaseClasses(clz: String): Boolean = superClasses.contains(clz) - /** Used by Chisel's internal macros. DO NOT USE in your normal Chisel code!!! * Instead, mark the field you are accessing with [[@public]] * @@ -80,7 +78,12 @@ sealed trait Hierarchy[+A] { * @param lookup typeclass which contains the correct lookup function, based on the types of A and B * @param macroGenerated a value created in the macro, to make it harder for users to use this API */ - def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C + def _lookup[B, C]( + that: A => B + )( + implicit lookup: Lookupable[B], + macroGenerated: chisel3.internal.MacroGenerated + ): lookup.C /** @return Return the underlying Definition[A] of this Hierarchy[A] */ def toDefinition: Definition[A] @@ -94,6 +97,7 @@ private[chisel3] trait SealedHierarchy[+A] extends Hierarchy[A] object Hierarchy { implicit class HierarchyBaseModuleExtensions[T <: BaseModule](i: Hierarchy[T]) { + /** Returns the toTarget of this hierarchy * @return target of this hierarchy */ diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala index 97b62c23..cc926771 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala @@ -11,12 +11,12 @@ import chisel3.experimental.BaseModule import firrtl.annotations.IsModule /** User-facing Instance type. - * Represents a unique instance of type [[A]] which are marked as @instantiable + * Represents a unique instance of type [[A]] which are marked as @instantiable * Can be created using Instance.apply method. * * @param underlying The internal representation of the instance, which may be either be directly the object, or a clone of an object */ -final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Underlying[A]) extends SealedHierarchy[A] { +final case class Instance[+A] private[chisel3] (private[chisel3] underlying: Underlying[A]) extends SealedHierarchy[A] { underlying match { case Proto(p: IsClone[_]) => chisel3.internal.throwException("Cannot have a Proto with a clone!") case other => //Ok @@ -24,16 +24,16 @@ final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Un /** @return the context of any Data's return from inside the instance */ private[chisel3] def getInnerDataContext: Option[BaseModule] = underlying match { - case Proto(value: BaseModule) => Some(value) - case Proto(value: IsInstantiable) => None - case Clone(i: BaseModule) => Some(i) + case Proto(value: BaseModule) => Some(value) + case Proto(value: IsInstantiable) => None + case Clone(i: BaseModule) => Some(i) case Clone(i: InstantiableClone[_]) => i.getInnerContext } /** @return the context this instance. Note that for non-module clones, getInnerDataContext will be the same as getClonedParent */ private[chisel3] def getClonedParent: Option[BaseModule] = underlying match { case Proto(value: BaseModule) => value._parent - case Clone(i: BaseModule) => i._parent + case Clone(i: BaseModule) => i._parent case Clone(i: InstantiableClone[_]) => i.getInnerContext } @@ -51,19 +51,25 @@ final case class Instance[+A] private [chisel3] (private[chisel3] underlying: Un * @param lookup typeclass which contains the correct lookup function, based on the types of A and B * @param macroGenerated a value created in the macro, to make it harder for users to use this API */ - def _lookup[B, C](that: A => B)(implicit lookup: Lookupable[B], macroGenerated: chisel3.internal.MacroGenerated): lookup.C = { + def _lookup[B, C]( + that: A => B + )( + implicit lookup: Lookupable[B], + macroGenerated: chisel3.internal.MacroGenerated + ): lookup.C = { lookup.instanceLookup(that, this) } /** Returns the definition of this Instance */ override def toDefinition: Definition[A] = new Definition(Proto(proto)) - override def toInstance: Instance[A] = this + override def toInstance: Instance[A] = this } /** Factory methods for constructing [[Instance]]s */ object Instance extends SourceInfoDoc { implicit class InstanceBaseModuleExtensions[T <: BaseModule](i: Instance[T]) { + /** If this is an instance of a Module, returns the toTarget of this instance * @return target of this instance */ @@ -81,19 +87,26 @@ object Instance extends SourceInfoDoc { } } + /** A constructs an [[Instance]] from a [[Definition]] * * @param definition the Module being created * @return an instance of the module definition */ - def apply[T <: BaseModule with IsInstantiable](definition: Definition[T]): Instance[T] = macro InstanceTransform.apply[T] + def apply[T <: BaseModule with IsInstantiable](definition: Definition[T]): Instance[T] = + macro InstanceTransform.apply[T] /** A constructs an [[Instance]] from a [[Definition]] * * @param definition the Module being created * @return an instance of the module definition */ - def do_apply[T <: BaseModule with IsInstantiable](definition: Definition[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Instance[T] = { + def do_apply[T <: BaseModule with IsInstantiable]( + definition: Definition[T] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Instance[T] = { val ports = experimental.CloneModuleAsRecord(definition.proto) val clone = ports._parent.get.asInstanceOf[ModuleClone[T]] clone._madeFromDefinition = true diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala index 4f3c2d42..27e06d92 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/IsInstantiable.scala @@ -6,7 +6,6 @@ package chisel3.experimental.hierarchy * Instead, use the [[@instantiable]] annotation on your trait or class. * * This trait indicates whether a class can be returned from an Instance. - * */ trait IsInstantiable diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala index 37d29a43..a82cbd7d 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/IsLookupable.scala @@ -4,9 +4,9 @@ package chisel3.experimental.hierarchy /** A User-extendable trait to mark metadata-containers, e.g. parameter case classes, as valid to return unchanged * from an instance. - * + * * This should only be true of the metadata returned is identical for ALL instances! - * + * * @example For instances of the same proto, metadata or other construction parameters * may be useful to access outside of the instance construction. For parameters that are * the same for all instances, we should mark it as IsLookupable diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala b/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala index c16cc633..d4818f63 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala @@ -16,9 +16,12 @@ object LibraryHooks { * definition's Underlying * @note Implicitly requires being inside a Hierarchy Library Extension */ - def buildInstance[A](definition: Definition[A], - createUnderlying: Underlying[A] => Underlying[A] - )(implicit inside: InsideHierarchyLibraryExtension): Instance[A] = { + def buildInstance[A]( + definition: Definition[A], + createUnderlying: Underlying[A] => Underlying[A] + )( + implicit inside: InsideHierarchyLibraryExtension + ): Instance[A] = { new Instance(createUnderlying(definition.underlying)) } diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala index ff4d676c..1223d6ce 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala @@ -11,18 +11,20 @@ import scala.collection.mutable.HashMap import chisel3._ import chisel3.experimental.dataview.{isView, reify, reifySingleData} import chisel3.internal.firrtl.{Arg, ILit, Index, Slot, ULit} -import chisel3.internal.{AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent, throwException} +import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBinding, ViewBinding, ViewParent} /** Represents lookup typeclass to determine how a value accessed from an original IsInstantiable * should be tweaked to return the Instance's version * Sealed. */ -@implicitNotFound("@public is only legal within a class marked @instantiable and only on vals of type" + - " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option") +@implicitNotFound( + "@public is only legal within a class marked @instantiable and only on vals of type" + + " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable or Option" +) trait Lookupable[-B] { type C // Return type of the lookup /** Function called to modify the returned value of type B from A, into C - * + * * @param that function that selects B from A * @param instance Instance of A, used to determine C's context * @return @@ -35,8 +37,8 @@ trait Lookupable[-B] { * @param definition Definition of A, used to determine C's context * @return */ - def definitionLookup[A](that: A => B, definition: Definition[A]): C - protected def getProto[A](h: Hierarchy[A]): A = h.proto + def definitionLookup[A](that: A => B, definition: Definition[A]): C + protected def getProto[A](h: Hierarchy[A]): A = h.proto protected def getUnderlying[A](h: Hierarchy[A]): Underlying[A] = h.underlying } @@ -48,8 +50,13 @@ object Lookupable { * @param context new context * @return */ - private[chisel3] def cloneDataToContext[T <: Data](data: T, context: BaseModule) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + private[chisel3] def cloneDataToContext[T <: Data]( + data: T, + context: BaseModule + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { internal.requireIsHardware(data, "cross module reference type") data._parent match { case None => data @@ -68,11 +75,18 @@ object Lookupable { } // The business logic of lookupData // Also called by cloneViewToContext which potentially needs to lookup stuff from ioMap or the cache - private[chisel3] def doLookupData[A, B <: Data](data: B, cache: HashMap[Data, Data], ioMap: Option[Map[Data, Data]], context: Option[BaseModule]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): B = { + private[chisel3] def doLookupData[A, B <: Data]( + data: B, + cache: HashMap[Data, Data], + ioMap: Option[Map[Data, Data]], + context: Option[BaseModule] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): B = { def impl[C <: Data](d: C): C = d match { case x: Data if ioMap.nonEmpty && ioMap.get.contains(x) => ioMap.get(x).asInstanceOf[C] - case x: Data if cache.contains(x) => cache(x).asInstanceOf[C] + case x: Data if cache.contains(x) => cache(x).asInstanceOf[C] case _ => assert(context.nonEmpty) // TODO is this even possible? Better error message here val ret = cloneDataToContext(d, context.get) @@ -105,12 +119,13 @@ object Lookupable { * Invariants that elt is a Child of something of the type of data is dynamically checked as we traverse */ private def mapRootAndExtractSubField[A <: Data](arg: A, f: Data => Data): A = { - def err(msg: String) = throwException(s"Internal Error! $msg") + def err(msg: String) = throwException(s"Internal Error! $msg") def unrollCoordinates(res: List[Arg], d: Data): (List[Arg], Data) = d.binding.get match { - case ChildBinding(parent) => d.getRef match { - case arg @ (_: Slot | _: Index) => unrollCoordinates(arg :: res, parent) - case other => err(s"Unroll coordinates failed for '$arg'! Unexpected arg '$other'") - } + case ChildBinding(parent) => + d.getRef match { + case arg @ (_: Slot | _: Index) => unrollCoordinates(arg :: res, parent) + case other => err(s"Unroll coordinates failed for '$arg'! Unexpected arg '$other'") + } case _ => (res, d) } def applyCoordinates(fullCoor: List[Arg], start: Data): Data = { @@ -133,15 +148,22 @@ object Lookupable { try { result.asInstanceOf[A] } catch { - case _: ClassCastException => err(s"Applying '$coor' to '$newRoot' somehow resulted in '$result'") + case _: ClassCastException => err(s"Applying '$coor' to '$newRoot' somehow resulted in '$result'") } } // TODO this logic is complicated, can any of it be unified with viewAs? // If `.viewAs` would capture its arguments, we could potentially use it // TODO Describe what this is doing at a high level - private[chisel3] def cloneViewToContext[A, B <: Data](data: B, cache: HashMap[Data, Data], ioMap: Option[Map[Data, Data]], context: Option[BaseModule]) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): B = { + private[chisel3] def cloneViewToContext[A, B <: Data]( + data: B, + cache: HashMap[Data, Data], + ioMap: Option[Map[Data, Data]], + context: Option[BaseModule] + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): B = { // alias to shorten lookups def lookupData[C <: Data](d: C) = doLookupData(d, cache, ioMap, context) @@ -150,29 +172,31 @@ object Lookupable { // We have to lookup the target(s) of the view since they may need to be underlying into the current context val newBinding = data.topBinding match { case ViewBinding(target) => ViewBinding(lookupData(reify(target))) - case avb @ AggregateViewBinding(map, targetOpt) => data match { - case _: Element => ViewBinding(lookupData(reify(map(data)))) - case _: Aggregate => - // Provide a 1:1 mapping if possible - val singleTargetOpt = targetOpt.filter(_ => avb == data.binding.get).flatMap(reifySingleData) - singleTargetOpt match { - case Some(singleTarget) => // It is 1:1! - // This is a little tricky because the values in newMap need to point to Elements of newTarget - val newTarget = lookupData(singleTarget) - val newMap = coiterate(result, data).map { case (res, from) => - (res: Data) -> mapRootAndExtractSubField(map(from), _ => newTarget) - }.toMap - AggregateViewBinding(newMap, Some(newTarget)) + case avb @ AggregateViewBinding(map, targetOpt) => + data match { + case _: Element => ViewBinding(lookupData(reify(map(data)))) + case _: Aggregate => + // Provide a 1:1 mapping if possible + val singleTargetOpt = targetOpt.filter(_ => avb == data.binding.get).flatMap(reifySingleData) + singleTargetOpt match { + case Some(singleTarget) => // It is 1:1! + // This is a little tricky because the values in newMap need to point to Elements of newTarget + val newTarget = lookupData(singleTarget) + val newMap = coiterate(result, data).map { + case (res, from) => + (res: Data) -> mapRootAndExtractSubField(map(from), _ => newTarget) + }.toMap + AggregateViewBinding(newMap, Some(newTarget)) - case None => // No 1:1 mapping so we have to do a flat binding - // Just remap each Element of this aggregate - val newMap = coiterate(result, data).map { - // Upcast res to Data since Maps are invariant in the Key type parameter - case (res, from) => (res: Data) -> lookupData(reify(map(from))) - }.toMap - AggregateViewBinding(newMap, None) - } - } + case None => // No 1:1 mapping so we have to do a flat binding + // Just remap each Element of this aggregate + val newMap = coiterate(result, data).map { + // Upcast res to Data since Maps are invariant in the Key type parameter + case (res, from) => (res: Data) -> lookupData(reify(map(from))) + }.toMap + AggregateViewBinding(newMap, None) + } + } } // TODO Unify the following with `.viewAs` @@ -188,7 +212,7 @@ object Lookupable { case (agg: Aggregate, _) if agg != result => Builder.unnamedViews += agg case _ => // Do nothing - } + } } result.bind(newBinding) @@ -196,6 +220,7 @@ object Lookupable { result.forceName(None, "view", Builder.viewNamespace) result } + /** Given a module (either original or a clone), clone it to a new context * * This function effectively recurses up the parents of module to find whether: @@ -208,8 +233,13 @@ object Lookupable { * @param context new context * @return original or clone in the new context */ - private[chisel3] def cloneModuleToContext[T <: BaseModule](module: Underlying[T], context: BaseModule) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Underlying[T] = { + private[chisel3] def cloneModuleToContext[T <: BaseModule]( + module: Underlying[T], + context: BaseModule + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Underlying[T] = { // Recursive call def rec[A <: BaseModule](m: A): Underlying[A] = { def clone(x: A, p: Option[BaseModule], name: () => String): Underlying[A] = { @@ -221,7 +251,7 @@ object Lookupable { case (c, ctx) if ctx == c => Proto(c) case (c, ctx: IsClone[_]) if ctx.hasSameProto(c) => Clone(ctx.asInstanceOf[IsClone[A]]) case (c, ctx) if c._parent.isEmpty => Proto(c) - case (_, _) => + case (_, _) => cloneModuleToContext(Proto(m._parent.get), context) match { case Proto(p) => Proto(m) case Clone(p: BaseModule) => @@ -254,93 +284,107 @@ object Lookupable { type B = X type C = X def definitionLookup[A](that: A => B, definition: Definition[A]): C = that(definition.proto) - def instanceLookup[A](that: A => B, instance: Instance[A]): C = that(instance.proto) + def instanceLookup[A](that: A => B, instance: Instance[A]): C = that(instance.proto) } - implicit def lookupInstance[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[Instance[B]] { - type C = Instance[B] - def definitionLookup[A](that: A => Instance[B], definition: Definition[A]): C = { - val ret = that(definition.proto) - new Instance(cloneModuleToContext(ret.underlying, definition.getInnerDataContext.get)) - } - def instanceLookup[A](that: A => Instance[B], instance: Instance[A]): C = { - val ret = that(instance.proto) - instance.underlying match { - // If instance is just a normal module, no changing of context is necessary - case Proto(_) => new Instance(ret.underlying) - case Clone(_) => new Instance(cloneModuleToContext(ret.underlying, instance.getInnerDataContext.get)) + implicit def lookupInstance[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = + new Lookupable[Instance[B]] { + type C = Instance[B] + def definitionLookup[A](that: A => Instance[B], definition: Definition[A]): C = { + val ret = that(definition.proto) + new Instance(cloneModuleToContext(ret.underlying, definition.getInnerDataContext.get)) } - } - } - - implicit def lookupModule[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] { - type C = Instance[B] - def definitionLookup[A](that: A => B, definition: Definition[A]): C = { - val ret = that(definition.proto) - new Instance(cloneModuleToContext(Proto(ret), definition.getInnerDataContext.get)) - } - def instanceLookup[A](that: A => B, instance: Instance[A]): C = { - val ret = that(instance.proto) - instance.underlying match { - // If instance is just a normal module, no changing of context is necessary - case Proto(_) => new Instance(Proto(ret)) - case Clone(_) => new Instance(cloneModuleToContext(Proto(ret), instance.getInnerDataContext.get)) + def instanceLookup[A](that: A => Instance[B], instance: Instance[A]): C = { + val ret = that(instance.proto) + instance.underlying match { + // If instance is just a normal module, no changing of context is necessary + case Proto(_) => new Instance(ret.underlying) + case Clone(_) => new Instance(cloneModuleToContext(ret.underlying, instance.getInnerDataContext.get)) + } } } - } - implicit def lookupData[B <: Data](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] { - type C = B - def definitionLookup[A](that: A => B, definition: Definition[A]): C = { - val ret = that(definition.proto) - if (isView(ret)) { - ??? // TODO!!!!!! cloneViewToContext(ret, instance, ioMap, instance.getInnerDataContext) - } else { - doLookupData(ret, definition.cache, None, definition.getInnerDataContext) + implicit def lookupModule[B <: BaseModule](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = + new Lookupable[B] { + type C = Instance[B] + def definitionLookup[A](that: A => B, definition: Definition[A]): C = { + val ret = that(definition.proto) + new Instance(cloneModuleToContext(Proto(ret), definition.getInnerDataContext.get)) } - } - def instanceLookup[A](that: A => B, instance: Instance[A]): C = { - val ret = that(instance.proto) - val ioMap: Option[Map[Data, Data]] = instance.underlying match { - case Clone(x: ModuleClone[_]) => Some(x.ioMap) - case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap) - case _ => None + def instanceLookup[A](that: A => B, instance: Instance[A]): C = { + val ret = that(instance.proto) + instance.underlying match { + // If instance is just a normal module, no changing of context is necessary + case Proto(_) => new Instance(Proto(ret)) + case Clone(_) => new Instance(cloneModuleToContext(Proto(ret), instance.getInnerDataContext.get)) + } } - if (isView(ret)) { - cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext) - } else { - doLookupData(ret, instance.cache, ioMap, instance.getInnerDataContext) + } + + implicit def lookupData[B <: Data](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = + new Lookupable[B] { + type C = B + def definitionLookup[A](that: A => B, definition: Definition[A]): C = { + val ret = that(definition.proto) + if (isView(ret)) { + ??? // TODO!!!!!! cloneViewToContext(ret, instance, ioMap, instance.getInnerDataContext) + } else { + doLookupData(ret, definition.cache, None, definition.getInnerDataContext) + } } + def instanceLookup[A](that: A => B, instance: Instance[A]): C = { + val ret = that(instance.proto) + val ioMap: Option[Map[Data, Data]] = instance.underlying match { + case Clone(x: ModuleClone[_]) => Some(x.ioMap) + case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap) + case _ => None + } + if (isView(ret)) { + cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext) + } else { + doLookupData(ret, instance.cache, ioMap, instance.getInnerDataContext) + } + } } - } import scala.language.higherKinds // Required to avoid warning for lookupIterable type parameter - implicit def lookupIterable[B, F[_] <: Iterable[_]](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions, lookupable: Lookupable[B]) = new Lookupable[F[B]] { + implicit def lookupIterable[B, F[_] <: Iterable[_]]( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions, + lookupable: Lookupable[B] + ) = new Lookupable[F[B]] { type C = F[lookupable.C] def definitionLookup[A](that: A => F[B], definition: Definition[A]): C = { val ret = that(definition.proto).asInstanceOf[Iterable[B]] - ret.map{ x: B => lookupable.definitionLookup[A](_ => x, definition) }.asInstanceOf[C] + ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) }.asInstanceOf[C] } def instanceLookup[A](that: A => F[B], instance: Instance[A]): C = { import instance._ val ret = that(proto).asInstanceOf[Iterable[B]] - ret.map{ x: B => lookupable.instanceLookup[A](_ => x, instance) }.asInstanceOf[C] + ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) }.asInstanceOf[C] } } - implicit def lookupOption[B](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions, lookupable: Lookupable[B]) = new Lookupable[Option[B]] { + implicit def lookupOption[B]( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions, + lookupable: Lookupable[B] + ) = new Lookupable[Option[B]] { type C = Option[lookupable.C] def definitionLookup[A](that: A => Option[B], definition: Definition[A]): C = { val ret = that(definition.proto) - ret.map{ x: B => lookupable.definitionLookup[A](_ => x, definition) } + ret.map { x: B => lookupable.definitionLookup[A](_ => x, definition) } } def instanceLookup[A](that: A => Option[B], instance: Instance[A]): C = { import instance._ val ret = that(proto) - ret.map{ x: B => lookupable.instanceLookup[A](_ => x, instance) } + ret.map { x: B => lookupable.instanceLookup[A](_ => x, instance) } } } - implicit def lookupIsInstantiable[B <: IsInstantiable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new Lookupable[B] { + implicit def lookupIsInstantiable[B <: IsInstantiable]( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ) = new Lookupable[B] { type C = Instance[B] def definitionLookup[A](that: A => B, definition: Definition[A]): C = { val ret = that(definition.proto) @@ -360,8 +404,9 @@ object Lookupable { } } - implicit def lookupIsLookupable[B <: IsLookupable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = new SimpleLookupable[B]() - + implicit def lookupIsLookupable[B <: IsLookupable](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = + new SimpleLookupable[B]() + implicit val lookupInt = new SimpleLookupable[Int]() implicit val lookupByte = new SimpleLookupable[Byte]() implicit val lookupShort = new SimpleLookupable[Short]() diff --git a/core/src/main/scala/chisel3/experimental/package.scala b/core/src/main/scala/chisel3/experimental/package.scala index 5397a1c3..ce258a25 100644 --- a/core/src/main/scala/chisel3/experimental/package.scala +++ b/core/src/main/scala/chisel3/experimental/package.scala @@ -16,9 +16,9 @@ package object experimental { import chisel3.internal.BaseModule // 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 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) @@ -32,6 +32,7 @@ package object experimental { type ClonePorts = BaseModule.ClonePorts object CloneModuleAsRecord { + /** Clones an existing module and returns a record of all its top-level ports. * Each element of the record is named with a string matching the * corresponding port's name and shares the port's type. @@ -41,13 +42,18 @@ package object experimental { * q2_io.enq <> q1.io.deq * }}} */ - def apply(proto: BaseModule)(implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo, compileOptions: CompileOptions): ClonePorts = { + def apply( + proto: BaseModule + )( + implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo, + compileOptions: CompileOptions + ): ClonePorts = { BaseModule.cloneIORecord(proto) } } val requireIsHardware = chisel3.internal.requireIsHardware - val requireIsChiselType = chisel3.internal.requireIsChiselType + val requireIsChiselType = chisel3.internal.requireIsChiselType type Direction = ActualDirection val Direction = ActualDirection @@ -68,6 +74,7 @@ package object experimental { class dump extends chisel3.internal.naming.dump class treedump extends chisel3.internal.naming.treedump + /** Experimental macro for naming Chisel hardware values * * By default, Chisel uses reflection for naming which only works for public fields of `Bundle` @@ -94,6 +101,7 @@ package object experimental { * }}} */ class chiselName extends chisel3.internal.naming.chiselName + /** Do not name instances of this type in [[chiselName]] * * By default, `chiselName` will include `val` names of instances of annotated classes as a @@ -138,6 +146,7 @@ package object experimental { */ object VecLiterals { implicit class AddVecLiteralConstructor[T <: Data](x: Vec[T]) { + /** Given a generator of a list tuples of the form [Int, Data] * constructs a Vec literal, parallel concept to `BundleLiteral` * @@ -150,15 +159,16 @@ package object experimental { } implicit class AddObjectLiteralConstructor(x: Vec.type) { + /** This provides an literal construction method for cases using * object `Vec` as in `Vec.Lit(1.U, 2.U)` */ def Lit[T <: Data](elems: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = { require(elems.nonEmpty, s"Lit.Vec(...) must have at least one element") - val indexElements = elems.zipWithIndex.map { case (element, index) => (index, element)} + val indexElements = elems.zipWithIndex.map { case (element, index) => (index, element) } val widestElement = elems.maxBy(_.getWidth) val vec: Vec[T] = Vec.apply(indexElements.length, chiselTypeOf(widestElement)) - vec.Lit(indexElements:_*) + vec.Lit(indexElements: _*) } } } @@ -178,7 +188,7 @@ package object experimental { */ final class HWTuple2[+A <: Data, +B <: Data] private[chisel3] (val _1: A, val _2: B) extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually - override protected def _usingPlugin: Boolean = true + override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple2(chiselTypeClone(_1), chiselTypeClone(_2)) } @@ -188,12 +198,16 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple3[+A <: Data, +B <: Data, +C <: Data] private[chisel3] ( - val _1: A, val _2: B, val _3: C - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple3( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3) ) } @@ -203,12 +217,18 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple4[+A <: Data, +B <: Data, +C <: Data, +D <: Data] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple4( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4) ) } @@ -218,12 +238,20 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple5[+A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple5( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5) ) } @@ -233,12 +261,21 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple6[+A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data, +F <: Data] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E, val _6: F - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E, + val _6: F) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple6( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5), + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5), chiselTypeClone(_6) ) } @@ -248,14 +285,33 @@ package object experimental { * Users may not instantiate this class directly. Instead they should use the implicit conversion from `Tuple7` in * `chisel3.experimental.conversions` */ - final class HWTuple7[+A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data, +F <: Data, +G <: Data] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E, val _6: F, val _7: G - ) extends Bundle()(Strict) { + final class HWTuple7[ + +A <: Data, + +B <: Data, + +C <: Data, + +D <: Data, + +E <: Data, + +F <: Data, + +G <: Data + ] private[chisel3] ( + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E, + val _6: F, + val _7: G) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple7( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5), - chiselTypeClone(_6), chiselTypeClone(_7) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5), + chiselTypeClone(_6), + chiselTypeClone(_7) ) } @@ -265,15 +321,35 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple8[ - +A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data, +F <: Data, +G <: Data, +H <: Data + +A <: Data, + +B <: Data, + +C <: Data, + +D <: Data, + +E <: Data, + +F <: Data, + +G <: Data, + +H <: Data ] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E, val _6: F, val _7: G, val _8: H - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E, + val _6: F, + val _7: G, + val _8: H) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple8( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5), - chiselTypeClone(_6), chiselTypeClone(_7), chiselTypeClone(_8) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5), + chiselTypeClone(_6), + chiselTypeClone(_7), + chiselTypeClone(_8) ) } @@ -283,34 +359,82 @@ package object experimental { * `chisel3.experimental.conversions` */ final class HWTuple9[ - +A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data, +F <: Data, +G <: Data, +H <: Data, +I <: Data + +A <: Data, + +B <: Data, + +C <: Data, + +D <: Data, + +E <: Data, + +F <: Data, + +G <: Data, + +H <: Data, + +I <: Data ] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E, val _6: F, val _7: G, val _8: H, val _9: I - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E, + val _6: F, + val _7: G, + val _8: H, + val _9: I) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple9( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5), - chiselTypeClone(_6), chiselTypeClone(_7), chiselTypeClone(_8), chiselTypeClone(_9) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5), + chiselTypeClone(_6), + chiselTypeClone(_7), + chiselTypeClone(_8), + chiselTypeClone(_9) ) } - /** [[Data]] equivalent of Scala's [[Tuple9]] * * Users may not instantiate this class directly. Instead they should use the implicit conversion from `Tuple9` in * `chisel3.experimental.conversions` */ final class HWTuple10[ - +A <: Data, +B <: Data, +C <: Data, +D <: Data, +E <: Data, +F <: Data, +G <: Data, +H <: Data, +I <: Data, +J <: Data + +A <: Data, + +B <: Data, + +C <: Data, + +D <: Data, + +E <: Data, + +F <: Data, + +G <: Data, + +H <: Data, + +I <: Data, + +J <: Data ] private[chisel3] ( - val _1: A, val _2: B, val _3: C, val _4: D, val _5: E, val _6: F, val _7: G, val _8: H, val _9: I, val _10: J - ) extends Bundle()(Strict) { + val _1: A, + val _2: B, + val _3: C, + val _4: D, + val _5: E, + val _6: F, + val _7: G, + val _8: H, + val _9: I, + val _10: J) + extends Bundle()(Strict) { // Because this implementation exists in chisel3.core, it cannot compile with the plugin, so we implement the behavior manually override protected def _usingPlugin: Boolean = true override protected def _cloneTypeImpl: Bundle = new HWTuple10( - chiselTypeClone(_1), chiselTypeClone(_2), chiselTypeClone(_3), chiselTypeClone(_4), chiselTypeClone(_5), - chiselTypeClone(_6), chiselTypeClone(_7), chiselTypeClone(_8), chiselTypeClone(_9), chiselTypeClone(_10) + chiselTypeClone(_1), + chiselTypeClone(_2), + chiselTypeClone(_3), + chiselTypeClone(_4), + chiselTypeClone(_5), + chiselTypeClone(_6), + chiselTypeClone(_7), + chiselTypeClone(_8), + chiselTypeClone(_9), + chiselTypeClone(_10) ) } } diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala index aa58cb95..5b4ad1b9 100644 --- a/core/src/main/scala/chisel3/internal/BiConnect.scala +++ b/core/src/main/scala/chisel3/internal/BiConnect.scala @@ -4,7 +4,7 @@ package chisel3.internal import chisel3._ import chisel3.experimental.dataview.reify -import chisel3.experimental.{Analog, BaseModule, attach} +import chisel3.experimental.{attach, Analog, BaseModule} import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.{Connect, DefInvalid} @@ -14,18 +14,17 @@ import chisel3.internal.sourceinfo._ import scala.annotation.tailrec /** -* BiConnect.connect executes a bidirectional connection element-wise. -* -* Note that the arguments are left and right (not source and sink) so the -* intent is for the operation to be commutative. -* -* The connect operation will recurse down the left Data (with the right Data). -* An exception will be thrown if a movement through the left cannot be matched -* in the right (or if the right side has extra fields). -* -* See elemConnect for details on how the root connections are issued. -* -*/ + * BiConnect.connect executes a bidirectional connection element-wise. + * + * Note that the arguments are left and right (not source and sink) so the + * intent is for the operation to be commutative. + * + * The connect operation will recurse down the left Data (with the right Data). + * An exception will be thrown if a movement through the left cannot be matched + * in the right (or if the right side has extra fields). + * + * See elemConnect for details on how the root connections are issued. + */ private[chisel3] object BiConnect { // These are all the possible exceptions that can be thrown. @@ -53,26 +52,32 @@ private[chisel3] object BiConnect { BiConnectException(": DontCare cannot be a connection sink (LHS)") /** This function is what recursively tries to connect a left and right together - * - * There is some cleverness in the use of internal try-catch to catch exceptions - * during the recursive decent and then rethrow them with extra information added. - * This gives the user a 'path' to where in the connections things went wrong. - */ - def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: RawModule): Unit = { + * + * There is some cleverness in the use of internal try-catch to catch exceptions + * during the recursive decent and then rethrow them with extra information added. + * This gives the user a 'path' to where in the connections things went wrong. + */ + def connect( + sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + left: Data, + right: Data, + context_mod: RawModule + ): Unit = { (left, right) match { // Handle element case (root case) case (left_a: Analog, right_a: Analog) => try { markAnalogConnected(sourceInfo, left_a, context_mod) markAnalogConnected(sourceInfo, right_a, context_mod) - } catch { // convert attach exceptions to BiConnectExceptions + } catch { // convert attach exceptions to BiConnectExceptions case attach.AttachException(message) => throw BiConnectException(message) } attach.impl(Seq(left_a, right_a), context_mod)(sourceInfo) case (left_a: Analog, DontCare) => try { markAnalogConnected(sourceInfo, left_a, context_mod) - } catch { // convert attach exceptions to BiConnectExceptions + } catch { // convert attach exceptions to BiConnectExceptions case attach.AttachException(message) => throw BiConnectException(message) } pushCommand(DefInvalid(sourceInfo, left_a.lref)) @@ -82,7 +87,7 @@ private[chisel3] object BiConnect { // TODO(twigg): Verify the element-level classes are connectable } // Handle Vec case - case (left_v: Vec[Data@unchecked], right_v: Vec[Data@unchecked]) => { + case (left_v: Vec[Data @unchecked], right_v: Vec[Data @unchecked]) => { if (left_v.length != right_v.length) { throw MismatchedVecException } @@ -96,7 +101,7 @@ private[chisel3] object BiConnect { } } // Handle Vec connected to DontCare - case (left_v: Vec[Data@unchecked], DontCare) => { + case (left_v: Vec[Data @unchecked], DontCare) => { for (idx <- 0 until left_v.length) { try { implicit val compileOptions = connectCompileOptions @@ -107,7 +112,7 @@ private[chisel3] object BiConnect { } } // Handle DontCare connected to Vec - case (DontCare, right_v: Vec[Data@unchecked]) => { + case (DontCare, right_v: Vec[Data @unchecked]) => { for (idx <- 0 until right_v.length) { try { implicit val compileOptions = connectCompileOptions @@ -135,7 +140,7 @@ private[chisel3] object BiConnect { case _ => true } } - def canBeSink(data: Data): Boolean = traceFlow(true, data) + def canBeSink(data: Data): Boolean = traceFlow(true, data) def canBeSource(data: Data): Boolean = traceFlow(false, data) // chisel3 <> is commutative but FIRRTL <- is not val flipConnection = !canBeSink(left_r) || !canBeSource(right_r) @@ -181,21 +186,23 @@ private[chisel3] object BiConnect { } // Do connection of two Records - def recordConnect(sourceInfo: SourceInfo, - connectCompileOptions: CompileOptions, - left_r: Record, - right_r: Record, - context_mod: RawModule): Unit = { + def recordConnect( + sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + left_r: Record, + right_r: Record, + context_mod: RawModule + ): Unit = { // Verify right has no extra fields that left doesn't have - for((field, right_sub) <- right_r.elements) { - if(!left_r.elements.isDefinedAt(field)) { + for ((field, right_sub) <- right_r.elements) { + if (!left_r.elements.isDefinedAt(field)) { if (connectCompileOptions.connectFieldsMustMatch) { throw MissingLeftFieldException(field) } } } // For each field in left, descend with right - for((field, left_sub) <- left_r.elements) { + for ((field, left_sub) <- left_r.elements) { try { right_r.elements.get(field) match { case Some(right_sub) => connect(sourceInfo, connectCompileOptions, left_sub, right_sub, context_mod) @@ -211,7 +218,6 @@ private[chisel3] object BiConnect { } } - // These functions (finally) issue the connection operation // Issue with right as sink, left as source private def issueConnectL2R(left: Element, right: Element)(implicit sourceInfo: SourceInfo): Unit = { @@ -238,13 +244,19 @@ private[chisel3] object BiConnect { // This function checks if element-level connection operation allowed. // Then it either issues it or throws the appropriate exception. - def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, _left: Element, _right: Element, context_mod: RawModule): Unit = { - import BindingDirection.{Internal, Input, Output} // Using extensively so import these + def elemConnect( + implicit sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + _left: Element, + _right: Element, + context_mod: RawModule + ): Unit = { + import BindingDirection.{Input, Internal, Output} // Using extensively so import these val left = reify(_left) val right = reify(_right) // If left or right have no location, assume in context module // This can occur if one of them is a literal, unbound will error previously - val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod) + val left_mod: BaseModule = left.topBinding.location.getOrElse(context_mod) val right_mod: BaseModule = right.topBinding.location.getOrElse(context_mod) val left_parent = Builder.retrieveParent(left_mod, context_mod).getOrElse(None) @@ -254,54 +266,54 @@ private[chisel3] object BiConnect { val right_direction = BindingDirection.from(right.topBinding, right.direction) // CASE: Context is same module as left node and right node is in a child module - if((left_mod == context_mod) && (right_parent == context_mod)) { + if ((left_mod == context_mod) && (right_parent == context_mod)) { // Thus, right node better be a port node and thus have a direction hint ((left_direction, right_direction): @unchecked) match { // CURRENT MOD CHILD MOD - case (Input, Input) => issueConnectL2R(left, right) - case (Internal, Input) => issueConnectL2R(left, right) + case (Input, Input) => issueConnectL2R(left, right) + case (Internal, Input) => issueConnectL2R(left, right) - case (Output, Output) => issueConnectR2L(left, right) - case (Internal, Output) => issueConnectR2L(left, right) + case (Output, Output) => issueConnectR2L(left, right) + case (Internal, Output) => issueConnectR2L(left, right) - case (Input, Output) => throw BothDriversException - case (Output, Input) => throw NeitherDriverException - case (_, Internal) => throw UnknownRelationException + case (Input, Output) => throw BothDriversException + case (Output, Input) => throw NeitherDriverException + case (_, Internal) => throw UnknownRelationException } } // CASE: Context is same module as right node and left node is in child module - else if((right_mod == context_mod) && (left_parent == context_mod)) { + else if ((right_mod == context_mod) && (left_parent == context_mod)) { // Thus, left node better be a port node and thus have a direction hint ((left_direction, right_direction): @unchecked) match { // CHILD MOD CURRENT MOD - case (Input, Input) => issueConnectR2L(left, right) - case (Input, Internal) => issueConnectR2L(left, right) + case (Input, Input) => issueConnectR2L(left, right) + case (Input, Internal) => issueConnectR2L(left, right) - case (Output, Output) => issueConnectL2R(left, right) - case (Output, Internal) => issueConnectL2R(left, right) + case (Output, Output) => issueConnectL2R(left, right) + case (Output, Internal) => issueConnectL2R(left, right) - case (Input, Output) => throw NeitherDriverException - case (Output, Input) => throw BothDriversException - case (Internal, _) => throw UnknownRelationException + case (Input, Output) => throw NeitherDriverException + case (Output, Input) => throw BothDriversException + case (Internal, _) => throw UnknownRelationException } } // CASE: Context is same module that both left node and right node are in - else if( (context_mod == left_mod) && (context_mod == right_mod) ) { + else if ((context_mod == left_mod) && (context_mod == right_mod)) { ((left_direction, right_direction): @unchecked) match { // CURRENT MOD CURRENT MOD - case (Input, Output) => issueConnectL2R(left, right) - case (Input, Internal) => issueConnectL2R(left, right) - case (Internal, Output) => issueConnectL2R(left, right) + case (Input, Output) => issueConnectL2R(left, right) + case (Input, Internal) => issueConnectL2R(left, right) + case (Internal, Output) => issueConnectL2R(left, right) - case (Output, Input) => issueConnectR2L(left, right) - case (Output, Internal) => issueConnectR2L(left, right) - case (Internal, Input) => issueConnectR2L(left, right) + case (Output, Input) => issueConnectR2L(left, right) + case (Output, Internal) => issueConnectR2L(left, right) + case (Internal, Input) => issueConnectR2L(left, right) - case (Input, Input) => throw BothDriversException - case (Output, Output) => throw BothDriversException - case (Internal, Internal) => { + case (Input, Input) => throw BothDriversException + case (Output, Output) => throw BothDriversException + case (Internal, Internal) => { if (connectCompileOptions.dontAssumeDirectionality) { throw UnknownDriverException } else { @@ -314,22 +326,22 @@ private[chisel3] object BiConnect { // CASE: Context is the parent module of both the module containing left node // and the module containing right node // Note: This includes case when left and right in same module but in parent - else if((left_parent == context_mod) && (right_parent == context_mod)) { + else if ((left_parent == context_mod) && (right_parent == context_mod)) { // Thus both nodes must be ports and have a direction hint ((left_direction, right_direction): @unchecked) match { // CHILD MOD CHILD MOD - case (Input, Output) => issueConnectR2L(left, right) - case (Output, Input) => issueConnectL2R(left, right) + case (Input, Output) => issueConnectR2L(left, right) + case (Output, Input) => issueConnectL2R(left, right) - case (Input, Input) => throw NeitherDriverException - case (Output, Output) => throw BothDriversException - case (_, Internal) => + case (Input, Input) => throw NeitherDriverException + case (Output, Output) => throw BothDriversException + case (_, Internal) => if (connectCompileOptions.dontAssumeDirectionality) { throw UnknownRelationException } else { issueConnectR2L(left, right) } - case (Internal, _) => + case (Internal, _) => if (connectCompileOptions.dontAssumeDirectionality) { throw UnknownRelationException } else { @@ -347,7 +359,7 @@ private[chisel3] object BiConnect { def markAnalogConnected(implicit sourceInfo: SourceInfo, analog: Analog, contextModule: RawModule): Unit = { analog.biConnectLocs.get(contextModule) match { case Some(sl) => throw AttachAlreadyBulkConnectedException(sl) - case None => // Do nothing + case None => // Do nothing } // Mark bulk connected analog.biConnectLocs(contextModule) = sourceInfo diff --git a/core/src/main/scala/chisel3/internal/Binding.scala b/core/src/main/scala/chisel3/internal/Binding.scala index a0dcc20c..6431dd23 100644 --- a/core/src/main/scala/chisel3/internal/Binding.scala +++ b/core/src/main/scala/chisel3/internal/Binding.scala @@ -12,14 +12,16 @@ import scala.collection.immutable.VectorMap */ object requireIsHardware { def apply(node: Data, msg: String = ""): Unit = { - node._parent match { // Compatibility layer hack + node._parent match { // Compatibility layer hack case Some(x: BaseModule) => x._compatAutoWrapPorts case _ => } if (!node.isSynthesizable) { val prefix = if (msg.nonEmpty) s"$msg " else "" - throw ExpectedHardwareException(s"$prefix'$node' must be hardware, " + - "not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?") + throw ExpectedHardwareException( + s"$prefix'$node' must be hardware, " + + "not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?" + ) } } } @@ -36,12 +38,15 @@ object requireIsChiselType { // Element only direction used for the Binding system only. private[chisel3] sealed abstract class BindingDirection private[chisel3] object BindingDirection { + /** Internal type or wire */ case object Internal extends BindingDirection + /** Module port with output direction */ case object Output extends BindingDirection + /** Module port with input direction */ case object Input extends BindingDirection @@ -50,11 +55,12 @@ private[chisel3] object BindingDirection { */ def from(binding: TopBinding, direction: ActualDirection): BindingDirection = { binding match { - case PortBinding(_) => direction match { - case ActualDirection.Output => Output - case ActualDirection.Input => Input - case dir => throw new RuntimeException(s"Unexpected port element direction '$dir'") - } + case PortBinding(_) => + direction match { + case ActualDirection.Output => Output + case ActualDirection.Input => Input + case dir => throw new RuntimeException(s"Unexpected port element direction '$dir'") + } case _ => Internal } } @@ -81,7 +87,7 @@ sealed trait ConstrainedBinding extends TopBinding { // This allows aspect modules to pretend to be enclosed modules for connectivity checking, // inside vs outside instance checking, etc. Builder.aspectModule(enclosure) match { - case None => Some(enclosure) + case None => Some(enclosure) case Some(aspect) => Some(aspect) } } @@ -100,18 +106,29 @@ sealed trait ConditionalDeclarable extends TopBinding { case class PortBinding(enclosure: BaseModule) extends ConstrainedBinding -case class OpBinding(enclosure: RawModule, visibility: Option[WhenContext]) extends ConstrainedBinding with ReadOnlyBinding with ConditionalDeclarable -case class MemoryPortBinding(enclosure: RawModule, visibility: Option[WhenContext]) extends ConstrainedBinding with ConditionalDeclarable -case class RegBinding(enclosure: RawModule, visibility: Option[WhenContext]) extends ConstrainedBinding with ConditionalDeclarable -case class WireBinding(enclosure: RawModule, visibility: Option[WhenContext]) extends ConstrainedBinding with ConditionalDeclarable +case class OpBinding(enclosure: RawModule, visibility: Option[WhenContext]) + extends ConstrainedBinding + with ReadOnlyBinding + with ConditionalDeclarable +case class MemoryPortBinding(enclosure: RawModule, visibility: Option[WhenContext]) + extends ConstrainedBinding + with ConditionalDeclarable +case class RegBinding(enclosure: RawModule, visibility: Option[WhenContext]) + extends ConstrainedBinding + with ConditionalDeclarable +case class WireBinding(enclosure: RawModule, visibility: Option[WhenContext]) + extends ConstrainedBinding + with ConditionalDeclarable case class ChildBinding(parent: Data) extends Binding { def location: Option[BaseModule] = parent.topBinding.location } + /** Special binding for Vec.sample_element */ case class SampleElementBinding[T <: Data](parent: Vec[T]) extends Binding { def location = parent.topBinding.location } + /** Special binding for Mem types */ case class MemTypeBinding[T <: Data](parent: MemBase[T]) extends Binding { def location: Option[BaseModule] = parent._parent @@ -122,12 +139,13 @@ case class DontCareBinding() extends UnconstrainedBinding // Views currently only support 1:1 Element-level mappings private[chisel3] case class ViewBinding(target: Element) extends UnconstrainedBinding + /** Binding for Aggregate Views * @param childMap Mapping from children of this view to each child's target * @param target Optional Data this Aggregate views if the view is total and the target is a Data */ -private[chisel3] case class AggregateViewBinding(childMap: Map[Data, Element], target: Option[Data]) extends UnconstrainedBinding - +private[chisel3] case class AggregateViewBinding(childMap: Map[Data, Element], target: Option[Data]) + extends UnconstrainedBinding /** Binding for Data's returned from accessing an Instance/Definition members, if not readable/writable port */ private[chisel3] case object CrossModuleBinding extends TopBinding { diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala index 71894887..fb6ebcc7 100644 --- a/core/src/main/scala/chisel3/internal/Builder.scala +++ b/core/src/main/scala/chisel3/internal/Builder.scala @@ -6,7 +6,7 @@ import scala.util.DynamicVariable import scala.collection.mutable.ArrayBuffer import chisel3._ import chisel3.experimental._ -import chisel3.experimental.hierarchy.{Instance, Clone} +import chisel3.experimental.hierarchy.{Clone, Instance} import chisel3.internal.firrtl._ import chisel3.internal.naming._ import _root_.firrtl.annotations.{CircuitName, ComponentName, IsMember, ModuleName, Named, ReferenceTarget} @@ -34,8 +34,8 @@ private[chisel3] class Namespace(keywords: Set[String]) { private def sanitize(s: String, leadingDigitOk: Boolean = false): String = { // TODO what character set does FIRRTL truly support? using ANSI C for now def legalStart(c: Char) = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' - def legal(c: Char) = legalStart(c) || (c >= '0' && c <= '9') - val res = s filter legal + def legal(c: Char) = legalStart(c) || (c >= '0' && c <= '9') + val res = s.filter(legal) val headOk = (!res.isEmpty) && (leadingDigitOk || legalStart(res.head)) if (headOk) res else s"_$res" } @@ -55,6 +55,7 @@ private[chisel3] class Namespace(keywords: Set[String]) { } private[chisel3] object Namespace { + /** Constructs an empty Namespace */ def empty: Namespace = new Namespace(Set.empty[String]) } @@ -73,14 +74,17 @@ private[chisel3] class IdGen { * These are only valid once the design has been elaborated, and should not be used during its construction. */ trait InstanceId { - def instanceName: String - def pathName: String + def instanceName: String + def pathName: String def parentPathName: String - def parentModName: String + def parentModName: String + /** Returns a FIRRTL Named that refers to this object in the elaborated hardware graph */ def toNamed: Named + /** Returns a FIRRTL IsMember that refers to this object in the elaborated hardware graph */ def toTarget: IsMember + /** Returns a FIRRTL IsMember that refers to the absolute path to this object in the elaborated hardware graph */ def toAbsoluteTarget: IsMember } @@ -111,10 +115,10 @@ private[chisel3] trait HasId extends InstanceId { private var prefix_seed: Prefix = Nil // Post-seed hooks called to carry the suggested seeds to other candidates as needed - private val suggest_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit] + private val suggest_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String => Unit] // Post-seed hooks called to carry the auto seeds to other candidates as needed - private val auto_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit] + private val auto_postseed_hooks = scala.collection.mutable.ListBuffer.empty[String => Unit] /** Takes the last seed suggested. Multiple calls to this function will take the last given seed, unless * this HasId is a module port (see overridden method in Data.scala). @@ -124,7 +128,7 @@ private[chisel3] trait HasId extends InstanceId { * * Is a lower priority than [[suggestName]], in that regardless of whether [[autoSeed]] * was called, [[suggestName]] will always take precedence if it was called. - * + * * @param seed Seed for the name of this component * @return this object */ @@ -132,7 +136,7 @@ private[chisel3] trait HasId extends InstanceId { // Bypass the overridden behavior of autoSeed in [[Data]], apply autoSeed even to ports private[chisel3] def forceAutoSeed(seed: String): this.type = { auto_seed = Some(seed) - for(hook <- auto_postseed_hooks) { hook(seed) } + for (hook <- auto_postseed_hooks) { hook(seed) } prefix_seed = Builder.getPrefix this } @@ -143,14 +147,14 @@ private[chisel3] trait HasId extends InstanceId { * * Is a higher priority than [[autoSeed]], in that regardless of whether [[autoSeed]] * was called, [[suggestName]] will always take precedence. - * + * * @param seed The seed for the name of this component * @return this object */ - def suggestName(seed: =>String): this.type = { - if(suggested_seed.isEmpty) suggested_seed = Some(seed) + def suggestName(seed: => String): this.type = { + if (suggested_seed.isEmpty) suggested_seed = Some(seed) prefix_seed = Builder.getPrefix - for(hook <- suggest_postseed_hooks) { hook(seed) } + for (hook <- suggest_postseed_hooks) { hook(seed) } this } @@ -171,6 +175,7 @@ private[chisel3] trait HasId extends InstanceId { * @return the name, if it can be computed */ private[chisel3] def _computeName(defaultPrefix: Option[String], defaultSeed: Option[String]): Option[String] = { + /** Computes a name of this signal, given the seed and prefix * @param seed * @param prefix @@ -189,14 +194,14 @@ private[chisel3] trait HasId extends InstanceId { defaultSeed.map { default => defaultPrefix match { case Some(p) => buildName(default, p :: construction_prefix.reverse) - case None => buildName(default, construction_prefix.reverse) + case None => buildName(default, construction_prefix.reverse) } } } } /** This resolves the precedence of [[autoSeed]] and [[suggestName]] - * + * * @return the current calculation of a name, if it exists */ private[chisel3] def seedOpt: Option[String] = suggested_seed.orElse(auto_seed) @@ -206,14 +211,14 @@ private[chisel3] trait HasId extends InstanceId { private[chisel3] def hasAutoSeed: Boolean = auto_seed.isDefined - private[chisel3] def addSuggestPostnameHook(hook: String=>Unit): Unit = suggest_postseed_hooks += hook - private[chisel3] def addAutoPostnameHook(hook: String=>Unit): Unit = auto_postseed_hooks += hook + private[chisel3] def addSuggestPostnameHook(hook: String => Unit): Unit = suggest_postseed_hooks += hook + private[chisel3] def addAutoPostnameHook(hook: String => Unit): Unit = auto_postseed_hooks += hook // Uses a namespace to convert suggestion into a true name // Will not do any naming if the reference already assigned. // (e.g. tried to suggest a name to part of a Record) - private[chisel3] def forceName(prefix: Option[String], default: =>String, namespace: Namespace): Unit = - if(_ref.isEmpty) { + private[chisel3] def forceName(prefix: Option[String], default: => String, namespace: Namespace): Unit = + if (_ref.isEmpty) { val candidate_name = _computeName(prefix, Some(default)).get val available_name = namespace.name(candidate_name) setRef(Ref(available_name)) @@ -226,15 +231,15 @@ private[chisel3] trait HasId extends InstanceId { _ref = Some(imm) } } - private[chisel3] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) - private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) - private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) - private[chisel3] def getRef: Arg = _ref.get + private[chisel3] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) + private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) + private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) + private[chisel3] def getRef: Arg = _ref.get private[chisel3] def getOptionRef: Option[Arg] = _ref private def refName(c: Component): String = _ref match { - case Some(arg) => arg fullName c - case None => _computeName(None, None).get + case Some(arg) => arg.fullName(c) + case None => _computeName(None, None).get } // Helper for reifying views if they map to a single Target @@ -253,33 +258,35 @@ private[chisel3] trait HasId extends InstanceId { (p._component, this) match { case (Some(c), _) => refName(c) case (None, d: Data) if d.topBindingOpt == Some(CrossModuleBinding) => _ref.get.localName - case (None, _) => throwException(s"signalName/pathName should be called after circuit elaboration: $this, ${_parent}") + case (None, _) => + throwException(s"signalName/pathName should be called after circuit elaboration: $this, ${_parent}") } case None => throwException("this cannot happen") } def pathName: String = _parent match { - case None => instanceName + case None => instanceName case Some(ViewParent) => s"${reifyParent.pathName}.$instanceName" - case Some(p) => s"${p.pathName}.$instanceName" + case Some(p) => s"${p.pathName}.$instanceName" } def parentPathName: String = _parent match { case Some(ViewParent) => reifyParent.pathName - case Some(p) => p.pathName - case None => throwException(s"$instanceName doesn't have a parent") + case Some(p) => p.pathName + case None => throwException(s"$instanceName doesn't have a parent") } def parentModName: String = _parent match { case Some(ViewParent) => reifyParent.name - case Some(p) => p.name - case None => throwException(s"$instanceName doesn't have a parent") + case Some(p) => p.name + case None => throwException(s"$instanceName doesn't have a parent") } // TODO Should this be public? protected def circuitName: String = _parent match { - case None => _circuit match { - case None => instanceName - case Some(o) => o.circuitName - } + case None => + _circuit match { + case None => instanceName + case Some(o) => o.circuitName + } case Some(ViewParent) => reifyParent.circuitName - case Some(p) => p.circuitName + case Some(p) => p.circuitName } private[chisel3] def getPublicFields(rootClass: Class[_]): Seq[java.lang.reflect.Method] = { @@ -302,8 +309,10 @@ private[chisel3] trait HasId extends InstanceId { this.getClass.getMethods.filter(isPublicVal).sortWith(_.getName < _.getName) } } + /** Holds the implementation of toNamed for Data and MemBase */ private[chisel3] trait NamedComponent extends HasId { + /** Returns a FIRRTL ComponentName that references this object * @note Should not be called until circuit elaboration is complete */ @@ -319,7 +328,7 @@ private[chisel3] trait NamedComponent extends HasId { import _root_.firrtl.annotations.{Target, TargetToken} val root = _parent.map { case ViewParent => reifyParent - case other => other + case other => other }.get.getTarget // All NamedComponents will have a parent, only the top module can have None here Target.toTargetTokens(name).toList match { case TargetToken.Ref(r) :: components => root.ref(r).copy(component = components) @@ -333,8 +342,8 @@ private[chisel3] trait NamedComponent extends HasId { def makeTarget(p: BaseModule) = p.toAbsoluteTarget.ref(localTarget.ref).copy(component = localTarget.component) _parent match { case Some(ViewParent) => makeTarget(reifyParent) - case Some(parent) => makeTarget(parent) - case None => localTarget + case Some(parent) => makeTarget(parent) + case None => localTarget } } } @@ -369,9 +378,9 @@ private[chisel3] class DynamicContext(val annotationSeq: AnnotationSeq) { // Set by object Module.apply before calling class Module constructor // Used to distinguish between no Module() wrapping, multiple wrappings, and rewrapping var readyForModuleConstr: Boolean = false - var whenStack: List[WhenContext] = Nil - var currentClock: Option[Clock] = None - var currentReset: Option[Reset] = None + var whenStack: List[WhenContext] = Nil + var currentClock: Option[Clock] = None + var currentReset: Option[Reset] = None val errors = new ErrorLog val namingStack = new NamingStack // Used to indicate if this is the top-level module of full elaboration, or from a Definition @@ -396,7 +405,7 @@ private[chisel3] object Builder extends LazyLogging { def restoreContext(dc: DynamicContext) = dynamicContextVar.value = Some(dc) // Ensure we have a thread-specific ChiselContext - private val chiselContext = new ThreadLocal[ChiselContext]{ + private val chiselContext = new ThreadLocal[ChiselContext] { override def initialValue: ChiselContext = { new ChiselContext } @@ -419,12 +428,12 @@ private[chisel3] object Builder extends LazyLogging { def idGen: IdGen = chiselContext.get.idGen def globalNamespace: Namespace = dynamicContext.globalNamespace - def components: ArrayBuffer[Component] = dynamicContext.components - def annotations: ArrayBuffer[ChiselAnnotation] = dynamicContext.annotations - def annotationSeq: AnnotationSeq = dynamicContext.annotationSeq - def namingStack: NamingStack = dynamicContext.namingStack + def components: ArrayBuffer[Component] = dynamicContext.components + def annotations: ArrayBuffer[ChiselAnnotation] = dynamicContext.annotations + def annotationSeq: AnnotationSeq = dynamicContext.annotationSeq + def namingStack: NamingStack = dynamicContext.namingStack - def unnamedViews: ArrayBuffer[Data] = dynamicContext.unnamedViews + def unnamedViews: ArrayBuffer[Data] = dynamicContext.unnamedViews def viewNamespace: Namespace = chiselContext.get.viewNamespace // Puts a prefix string onto the prefix stack @@ -441,8 +450,8 @@ private[chisel3] object Builder extends LazyLogging { def pushPrefix(d: HasId): Boolean = { def buildAggName(id: HasId): Option[String] = { def getSubName(field: Data): Option[String] = field.getOptionRef.flatMap { - case Slot(_, field) => Some(field) // Record - case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing + case Slot(_, field) => Some(field) // Record + case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing case Index(_, ULit(n, _)) => Some(n.toString) // Vec lit indexing case Index(_, _: Node) => None // Vec dynamic indexing case ModuleIO(_, n) => Some(n) // BlackBox port @@ -452,13 +461,14 @@ private[chisel3] object Builder extends LazyLogging { // If the binding is None, this is an illegal connection and later logic will error def recData(data: Data): Option[String] = data.binding.flatMap { case (_: WireBinding | _: RegBinding | _: MemoryPortBinding | _: OpBinding) => data.seedOpt - case ChildBinding(parent) => recData(parent).map { p => - // And name of the field if we have one, we don't for dynamic indexing of Vecs - getSubName(data).map(p + "_" + _).getOrElse(p) - } - case SampleElementBinding(parent) => recData(parent) + case ChildBinding(parent) => + recData(parent).map { p => + // And name of the field if we have one, we don't for dynamic indexing of Vecs + getSubName(data).map(p + "_" + _).getOrElse(p) + } + case SampleElementBinding(parent) => recData(parent) case PortBinding(mod) if Builder.currentModule.contains(mod) => data.seedOpt - case PortBinding(mod) => map2(mod.seedOpt, data.seedOpt)(_ + "_" + _) + case PortBinding(mod) => map2(mod.seedOpt, data.seedOpt)(_ + "_" + _) case (_: LitBinding | _: DontCareBinding) => None case _ => Some("view_") // TODO implement } @@ -495,30 +505,31 @@ private[chisel3] object Builder extends LazyLogging { def currentModule: Option[BaseModule] = dynamicContextVar.value match { case Some(dyanmicContext) => dynamicContext.currentModule - case _ => None + case _ => None } def currentModule_=(target: Option[BaseModule]): Unit = { dynamicContext.currentModule = target } def aspectModule(module: BaseModule): Option[BaseModule] = dynamicContextVar.value match { case Some(dynamicContext) => dynamicContext.aspectModule.get(module) - case _ => None + case _ => None } + /** Retrieves the parent of a module based on the elaboration context - * - * @param module the module to get the parent of - * @param context the context the parent should be evaluated in - * @return the parent of the module provided - */ + * + * @param module the module to get the parent of + * @param context the context the parent should be evaluated in + * @return the parent of the module provided + */ def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = { module._parent match { case Some(parentModule) => { //if a parent exists investigate, otherwise return None context match { case aspect: ModuleAspect => { //if aspect context, do the translation - Builder.aspectModule(parentModule) match { - case Some(parentAspect) => Some(parentAspect) //we've found a translation - case _ => Some(parentModule) //no translation found - } + Builder.aspectModule(parentModule) match { + case Some(parentAspect) => Some(parentAspect) //we've found a translation + case _ => Some(parentModule) //no translation found + } } //otherwise just return our parent case _ => Some(parentModule) } @@ -531,10 +542,11 @@ private[chisel3] object Builder extends LazyLogging { } def forcedModule: BaseModule = currentModule match { case Some(module) => module - case None => throwException( - "Error: Not in a Module. Likely cause: Missed Module() wrap or bare chisel API call." - // A bare api call is, e.g. calling Wire() from the scala console). - ) + case None => + throwException( + "Error: Not in a Module. Likely cause: Missed Module() wrap or bare chisel API call." + // A bare api call is, e.g. calling Wire() from the scala console). + ) } def referenceUserModule: RawModule = { currentModule match { @@ -543,18 +555,20 @@ private[chisel3] object Builder extends LazyLogging { case Some(aspect: RawModule) => aspect case other => module } - case _ => throwException( - "Error: Not in a RawModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox." - // A bare api call is, e.g. calling Wire() from the scala console). - ) + case _ => + throwException( + "Error: Not in a RawModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox." + // A bare api call is, e.g. calling Wire() from the scala console). + ) } } def forcedUserModule: RawModule = currentModule match { case Some(module: RawModule) => module - case _ => throwException( - "Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox." - // A bare api call is, e.g. calling Wire() from the scala console). - ) + case _ => + throwException( + "Error: Not in a UserModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox." + // A bare api call is, e.g. calling Wire() from the scala console). + ) } def hasDynamicContext: Boolean = dynamicContextVar.value.isDefined @@ -594,8 +608,8 @@ private[chisel3] object Builder extends LazyLogging { def inDefinition: Boolean = { dynamicContextVar.value - .map(_.inDefinition) - .getOrElse(false) + .map(_.inDefinition) + .getOrElse(false) } def forcedClock: Clock = currentClock.getOrElse( @@ -623,10 +637,11 @@ private[chisel3] object Builder extends LazyLogging { * (Note: Map is Iterable[Tuple2[_,_]] and thus excluded) */ def nameRecursively(prefix: String, nameMe: Any, namer: (HasId, String) => Unit): Unit = nameMe match { - case (id: Instance[_]) => id.underlying match { - case Clone(m: internal.BaseModule.ModuleClone[_]) => namer(m.getPorts, prefix) - case _ => - } + case (id: Instance[_]) => + id.underlying match { + case Clone(m: internal.BaseModule.ModuleClone[_]) => namer(m.getPorts, prefix) + case _ => + } case (id: HasId) => namer(id, prefix) case Some(elt) => nameRecursively(prefix, elt, namer) case (iter: Iterable[_]) if iter.hasDefiniteSize => @@ -644,7 +659,7 @@ private[chisel3] object Builder extends LazyLogging { throwException(m) } } - def warning(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.warning(m) + def warning(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.warning(m) def deprecated(m: => String, location: Option[String] = None): Unit = if (dynamicContextVar.value.isDefined) errors.deprecated(m, location) @@ -667,7 +682,7 @@ private[chisel3] object Builder extends LazyLogging { if (getScalaMajorVersion == 11) { val url = _root_.firrtl.stage.transforms.CheckScalaVersion.migrationDocumentLink val msg = s"Chisel 3.4 is the last version that will support Scala 2.11. " + - s"Please upgrade to Scala 2.12. See $url" + s"Please upgrade to Scala 2.12. See $url" deprecated(msg, Some("")) } } @@ -680,8 +695,7 @@ private[chisel3] object Builder extends LazyLogging { for (view <- unnamedViews) { val localTarget = view.toTarget val absTarget = view.toAbsoluteTarget - val elts = getRecursiveFields.lazily(view, "") - .collect { case (elt: Element, _) => elt } + val elts = getRecursiveFields.lazily(view, "").collect { case (elt: Element, _) => elt } for (elt <- elts) { val targetOfView = reify(elt) renames.record(localTarget, targetOfView.toTarget) @@ -691,10 +705,14 @@ private[chisel3] object Builder extends LazyLogging { renames } - private[chisel3] def build[T <: BaseModule](f: => T, dynamicContext: DynamicContext, forceModName: Boolean = true): (Circuit, T) = { + private[chisel3] def build[T <: BaseModule]( + f: => T, + dynamicContext: DynamicContext, + forceModName: Boolean = true + ): (Circuit, T) = { dynamicContextVar.withValue(Some(dynamicContext)) { ViewParent // Must initialize the singleton in a Builder context or weird things can happen - // in tiny designs/testcases that never access anything in chisel3.internal + // in tiny designs/testcases that never access anything in chisel3.internal checkScalaVersion() logger.info("Elaborating design...") val mod = f @@ -719,24 +737,28 @@ object DynamicNamingStack { def pushContext(): NamingContextInterface = { Builder.namingStackOption match { case Some(namingStack) => namingStack.pushContext() - case None => DummyNamer + case None => DummyNamer } } def popReturnContext[T <: Any](prefixRef: T, until: NamingContextInterface): T = { until match { case DummyNamer => - require(Builder.namingStackOption.isEmpty, - "Builder context must remain stable throughout a chiselName-annotated function invocation") + require( + Builder.namingStackOption.isEmpty, + "Builder context must remain stable throughout a chiselName-annotated function invocation" + ) case context: NamingContext => - require(Builder.namingStackOption.isDefined, - "Builder context must remain stable throughout a chiselName-annotated function invocation") + require( + Builder.namingStackOption.isDefined, + "Builder context must remain stable throughout a chiselName-annotated function invocation" + ) Builder.namingStackOption.get.popContext(prefixRef, context) } prefixRef } - def length() : Int = Builder.namingStackOption.get.length + def length(): Int = Builder.namingStackOption.get.length } /** Casts BigInt to Int, issuing an error when the input isn't representable. */ diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala index d6e0c0e6..c42f39ed 100644 --- a/core/src/main/scala/chisel3/internal/Error.scala +++ b/core/src/main/scala/chisel3/internal/Error.scala @@ -38,7 +38,7 @@ object ExceptionHelpers { */ def trimStackTraceToUserCode( packageTrimlist: Set[String] = packageTrimlist, - anchor: Option[String] = Some(builderName) + anchor: Option[String] = Some(builderName) ): Unit = { def inTrimlist(ste: StackTraceElement) = { val packageName = ste.getClassName().takeWhile(_ != '.') @@ -47,25 +47,28 @@ object ExceptionHelpers { // Step 1: Remove elements from the top in the package trimlist ((a: Array[StackTraceElement]) => a.dropWhile(inTrimlist)) - // Step 2: Optionally remove elements from the bottom until the anchor + // Step 2: Optionally remove elements from the bottom until the anchor .andThen(_.reverse) - .andThen( a => + .andThen(a => anchor match { case Some(b) => a.dropWhile(ste => !ste.getClassName.startsWith(b)) case None => a } ) - // Step 3: Remove elements from the bottom in the package trimlist + // Step 3: Remove elements from the bottom in the package trimlist .andThen(_.dropWhile(inTrimlist)) - // Step 4: Reverse back to the original order + // Step 4: Reverse back to the original order .andThen(_.reverse.toArray) - // Step 5: Add ellipsis stack trace elements and "--full-stacktrace" info + // Step 5: Add ellipsis stack trace elements and "--full-stacktrace" info .andThen(a => ellipsis() +: a :+ ellipsis() :+ - ellipsis(Some("Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace"))) - // Step 5: Mutate the stack trace in this exception + ellipsis( + Some("Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace") + ) + ) + // Step 5: Mutate the stack trace in this exception .andThen(throwable.setStackTrace(_)) .apply(throwable.getStackTrace) } @@ -95,18 +98,21 @@ class ChiselException(message: String, cause: Throwable = null) extends Exceptio case a => getCauses(a, throwable +: acc) } - /** Returns true if an exception contains */ + /** Returns true if an exception contains */ private def containsBuilder(throwable: Throwable): Boolean = - throwable.getStackTrace().collectFirst { - case ste if ste.getClassName().startsWith(ExceptionHelpers.builderName) => throwable - }.isDefined + throwable + .getStackTrace() + .collectFirst { + case ste if ste.getClassName().startsWith(ExceptionHelpers.builderName) => throwable + } + .isDefined /** Examine this [[ChiselException]] and it's causes for the first [[Throwable]] that contains a stack trace including * a stack trace element whose declaring class is the [[builderName]]. If no such element exists, return this * [[ChiselException]]. */ private lazy val likelyCause: Throwable = - getCauses(this).collectFirst{ case a if containsBuilder(a) => a }.getOrElse(this) + getCauses(this).collectFirst { case a if containsBuilder(a) => a }.getOrElse(this) /** For an exception, return a stack trace trimmed to user code only * @@ -139,7 +145,9 @@ class ChiselException(message: String, cause: Throwable = null) extends Exceptio sw.write(likelyCause.toString + "\n") sw.write("\t...\n") trimmed.foreach(ste => sw.write(s"\tat $ste\n")) - sw.write("\t... (Stack trace trimmed to user code only, rerun with --full-stacktrace if you wish to see the full stack trace)\n") + sw.write( + "\t... (Stack trace trimmed to user code only, rerun with --full-stacktrace if you wish to see the full stack trace)\n" + ) sw.toString } } @@ -157,6 +165,7 @@ private[chisel3] object ErrorLog { } private[chisel3] class ErrorLog { + /** Log an error message */ def error(m: => String): Unit = errors += new Error(m, getUserLineNumber) @@ -168,16 +177,17 @@ private[chisel3] class ErrorLog { /** Emit an informational message */ @deprecated("This method will be removed in 3.5", "3.4") def info(m: String): Unit = - println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) + println(new Info("[%2.3f] %s".format(elapsedTime / 1e3, m), None)) /** Log a deprecation warning message */ def deprecated(m: => String, location: Option[String]): Unit = { val sourceLoc = location match { case Some(loc) => loc - case None => getUserLineNumber match { - case Some(elt: StackTraceElement) => s"${elt.getFileName}:${elt.getLineNumber}" - case None => "(unknown)" - } + case None => + getUserLineNumber match { + case Some(elt: StackTraceElement) => s"${elt.getFileName}:${elt.getLineNumber}" + case None => "(unknown)" + } } val thisEntry = (m, sourceLoc) @@ -186,15 +196,20 @@ private[chisel3] class ErrorLog { /** Throw an exception if any errors have yet occurred. */ def checkpoint(logger: Logger): Unit = { - deprecations.foreach { case ((message, sourceLoc), count) => - logger.warn(s"${ErrorLog.depTag} $sourceLoc ($count calls): $message") + deprecations.foreach { + case ((message, sourceLoc), count) => + logger.warn(s"${ErrorLog.depTag} $sourceLoc ($count calls): $message") } errors.foreach(e => logger.error(e.toString)) if (!deprecations.isEmpty) { - logger.warn(s"${ErrorLog.warnTag} ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." + - s" These may stop compiling in a future release - you are encouraged to fix these issues.${Console.RESET}") - logger.warn(s"${ErrorLog.warnTag} Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:") + logger.warn( + s"${ErrorLog.warnTag} ${Console.YELLOW}There were ${deprecations.size} deprecated function(s) used." + + s" These may stop compiling in a future release - you are encouraged to fix these issues.${Console.RESET}" + ) + logger.warn( + s"${ErrorLog.warnTag} Line numbers for deprecations reported by Chisel may be inaccurate; enable scalac compiler deprecation warnings via either of the following methods:" + ) logger.warn(s"${ErrorLog.warnTag} In the sbt interactive console, enter:") logger.warn(s"""${ErrorLog.warnTag} set scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")""") logger.warn(s"${ErrorLog.warnTag} or, in your build.sbt, add the line:") @@ -205,16 +220,22 @@ private[chisel3] class ErrorLog { val allWarnings = errors.filter(!_.isFatal) if (!allWarnings.isEmpty && !allErrors.isEmpty) { - logger.warn(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") + logger.warn( + s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} and ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration." + ) } else if (!allWarnings.isEmpty) { - logger.warn(s"${ErrorLog.warnTag} There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration.") + logger.warn( + s"${ErrorLog.warnTag} There were ${Console.YELLOW}${allWarnings.size} warning(s)${Console.RESET} during hardware elaboration." + ) } else if (!allErrors.isEmpty) { - logger.warn(s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration.") + logger.warn( + s"${ErrorLog.errTag} There were ${Console.RED}${allErrors.size} error(s)${Console.RESET} during hardware elaboration." + ) } if (!allErrors.isEmpty) { throw new ChiselException("Fatal errors during hardware elaboration. Look above for error list.") - with scala.util.control.NoStackTrace + with scala.util.control.NoStackTrace } else { // No fatal errors, clear accumulated warnings since they've been reported errors.clear() @@ -228,20 +249,25 @@ private[chisel3] class ErrorLog { // List of classpath prefixes that are Chisel internals and should be ignored when looking for user code // utils are not part of internals and errors there can be reported val chiselPrefixes = Set( - "java.", - "scala.", - "chisel3.", - "chisel3.internal.", - "chisel3.experimental.", - "chisel3.package$" // for some compatibility / deprecated types - ) + "java.", + "scala.", + "chisel3.", + "chisel3.internal.", + "chisel3.experimental.", + "chisel3.package$" // for some compatibility / deprecated types + ) !chiselPrefixes.filter(className.startsWith(_)).isEmpty } - Thread.currentThread().getStackTrace.toList.dropWhile( - // Get rid of everything in Chisel core - ste => isChiselClassname(ste.getClassName) - ).headOption + Thread + .currentThread() + .getStackTrace + .toList + .dropWhile( + // Get rid of everything in Chisel core + ste => isChiselClassname(ste.getClassName) + ) + .headOption } private val errors = ArrayBuffer[LogEntry]() @@ -257,7 +283,7 @@ private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) override def toString: String = line match { case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}" - case None => s"${format} ${msg}" + case None => s"${format} ${msg}" } protected def tag(name: String, color: String): String = @@ -266,7 +292,7 @@ private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) private class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { override def isFatal: Boolean = true - def format: String = tag("error", Console.RED) + def format: String = tag("error", Console.RED) } private class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala index 6173fc91..b4d9aeff 100644 --- a/core/src/main/scala/chisel3/internal/MonoConnect.scala +++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala @@ -12,28 +12,28 @@ import scala.language.experimental.macros import chisel3.internal.sourceinfo.SourceInfo /** -* MonoConnect.connect executes a mono-directional connection element-wise. -* -* Note that this isn't commutative. There is an explicit source and sink -* already determined before this function is called. -* -* The connect operation will recurse down the left Data (with the right Data). -* An exception will be thrown if a movement through the left cannot be matched -* in the right. The right side is allowed to have extra Record fields. -* Vecs must still be exactly the same size. -* -* See elemConnect for details on how the root connections are issued. -* -* Note that a valid sink must be writable so, one of these must hold: -* - Is an internal writable node (Reg or Wire) -* - Is an output of the current module -* - Is an input of a submodule of the current module -* -* Note that a valid source must be readable so, one of these must hold: -* - Is an internal readable node (Reg, Wire, Op) -* - Is a literal -* - Is a port of the current module or submodule of the current module -*/ + * MonoConnect.connect executes a mono-directional connection element-wise. + * + * Note that this isn't commutative. There is an explicit source and sink + * already determined before this function is called. + * + * The connect operation will recurse down the left Data (with the right Data). + * An exception will be thrown if a movement through the left cannot be matched + * in the right. The right side is allowed to have extra Record fields. + * Vecs must still be exactly the same size. + * + * See elemConnect for details on how the root connections are issued. + * + * Note that a valid sink must be writable so, one of these must hold: + * - Is an internal writable node (Reg or Wire) + * - Is an output of the current module + * - Is an input of a submodule of the current module + * + * Note that a valid source must be readable so, one of these must hold: + * - Is an internal readable node (Reg, Wire, Op) + * - Is a literal + * - Is a port of the current module or submodule of the current module + */ private[chisel3] object MonoConnect { def formatName(data: Data) = s"""${data.earlyName} in ${data.parentNameOpt.getOrElse("(unknown)")}""" @@ -41,9 +41,13 @@ private[chisel3] object MonoConnect { // These are all the possible exceptions that can be thrown. // These are from element-level connection def UnreadableSourceException(sink: Data, source: Data) = - MonoConnectException(s"""${formatName(source)} cannot be read from module ${sink.parentNameOpt.getOrElse("(unknown)")}.""") + MonoConnectException( + s"""${formatName(source)} cannot be read from module ${sink.parentNameOpt.getOrElse("(unknown)")}.""" + ) def UnwritableSinkException(sink: Data, source: Data) = - MonoConnectException(s"""${formatName(sink)} cannot be written from module ${source.parentNameOpt.getOrElse("(unknown)")}.""") + MonoConnectException( + s"""${formatName(sink)} cannot be written from module ${source.parentNameOpt.getOrElse("(unknown)")}.""" + ) def SourceEscapedWhenScopeException(source: Data) = MonoConnectException(s"Source ${formatName(source)} has escaped the scope of the when in which it was constructed.") def SinkEscapedWhenScopeException(sink: Data) = @@ -56,7 +60,9 @@ private[chisel3] object MonoConnect { def MissingFieldException(field: String) = MonoConnectException(s"Source Record missing field ($field).") def MismatchedException(sink: Data, source: Data) = - MonoConnectException(s"Sink (${sink.cloneType.toString}) and Source (${source.cloneType.toString}) have different types.") + MonoConnectException( + s"Sink (${sink.cloneType.toString}) and Source (${source.cloneType.toString}) have different types." + ) def DontCareCantBeSink = MonoConnectException("DontCare cannot be a connection sink") def AnalogCantBeMonoSink(sink: Data) = @@ -64,28 +70,32 @@ private[chisel3] object MonoConnect { def AnalogCantBeMonoSource(source: Data) = MonoConnectException(s"Source ${formatName(source)} of type Analog cannot participate in a mono connection (:=)") def AnalogMonoConnectionException(source: Data, sink: Data) = - MonoConnectException(s"Source ${formatName(source)} and sink ${formatName(sink)} of type Analog cannot participate in a mono connection (:=)") + MonoConnectException( + s"Source ${formatName(source)} and sink ${formatName(sink)} of type Analog cannot participate in a mono connection (:=)" + ) def checkWhenVisibility(x: Data): Boolean = { x.topBinding match { - case mp: MemoryPortBinding => true // TODO (albert-magyar): remove this "bridge" for odd enable logic of current CHIRRTL memories + case mp: MemoryPortBinding => + true // TODO (albert-magyar): remove this "bridge" for odd enable logic of current CHIRRTL memories case cd: ConditionalDeclarable => cd.visibility.map(_.active()).getOrElse(true) case _ => true } } /** This function is what recursively tries to connect a sink and source together - * - * There is some cleverness in the use of internal try-catch to catch exceptions - * during the recursive decent and then rethrow them with extra information added. - * This gives the user a 'path' to where in the connections things went wrong. - */ + * + * There is some cleverness in the use of internal try-catch to catch exceptions + * during the recursive decent and then rethrow them with extra information added. + * This gives the user a 'path' to where in the connections things went wrong. + */ def connect( - sourceInfo: SourceInfo, - connectCompileOptions: CompileOptions, - sink: Data, - source: Data, - context_mod: RawModule): Unit = + sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + sink: Data, + source: Data, + context_mod: RawModule + ): Unit = (sink, source) match { // Handle legal element cases, note (Bool, Bool) is caught by the first two, as Bool is a UInt @@ -118,8 +128,8 @@ private[chisel3] object MonoConnect { // Handle Vec case case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) => - if(sink_v.length != source_v.length) { throw MismatchedVecException } - for(idx <- 0 until sink_v.length) { + if (sink_v.length != source_v.length) { throw MismatchedVecException } + for (idx <- 0 until sink_v.length) { try { implicit val compileOptions = connectCompileOptions connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod) @@ -129,7 +139,7 @@ private[chisel3] object MonoConnect { } // Handle Vec connected to DontCare. Apply the DontCare to individual elements. case (sink_v: Vec[Data @unchecked], DontCare) => - for(idx <- 0 until sink_v.length) { + for (idx <- 0 until sink_v.length) { try { implicit val compileOptions = connectCompileOptions connect(sourceInfo, connectCompileOptions, sink_v(idx), source, context_mod) @@ -141,7 +151,7 @@ private[chisel3] object MonoConnect { // Handle Record case case (sink_r: Record, source_r: Record) => // For each field, descend with right - for((field, sink_sub) <- sink_r.elements) { + for ((field, sink_sub) <- sink_r.elements) { try { source_r.elements.get(field) match { case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod) @@ -158,7 +168,7 @@ private[chisel3] object MonoConnect { // Handle Record connected to DontCare. Apply the DontCare to individual elements. case (sink_r: Record, DontCare) => // For each field, descend with right - for((field, sink_sub) <- sink_r.elements) { + for ((field, sink_sub) <- sink_r.elements) { try { connect(sourceInfo, connectCompileOptions, sink_sub, source, context_mod) } catch { @@ -171,7 +181,7 @@ private[chisel3] object MonoConnect { // DontCare as a sink is illegal. case (DontCare, _) => throw DontCareCantBeSink // Analog is illegal in mono connections. - case (_: Analog, _:Analog) => throw AnalogMonoConnectionException(source, sink) + case (_: Analog, _: Analog) => throw AnalogMonoConnectionException(source, sink) // Analog is illegal in mono connections. case (_: Analog, _) => throw AnalogCantBeMonoSink(sink) // Analog is illegal in mono connections. @@ -192,13 +202,19 @@ private[chisel3] object MonoConnect { // This function checks if element-level connection operation allowed. // Then it either issues it or throws the appropriate exception. - def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, _sink: Element, _source: Element, context_mod: RawModule): Unit = { - import BindingDirection.{Internal, Input, Output} // Using extensively so import these + def elemConnect( + implicit sourceInfo: SourceInfo, + connectCompileOptions: CompileOptions, + _sink: Element, + _source: Element, + context_mod: RawModule + ): Unit = { + import BindingDirection.{Input, Internal, Output} // Using extensively so import these val sink = reify(_sink) val source = reify(_source) // If source has no location, assume in context module // This can occur if is a literal, unbound will error previously - val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException(sink, source)) + val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException(sink, source)) val source_mod: BaseModule = source.topBinding.location.getOrElse(context_mod) val sink_parent = Builder.retrieveParent(sink_mod, context_mod).getOrElse(None) @@ -216,69 +232,69 @@ private[chisel3] object MonoConnect { } // CASE: Context is same module that both left node and right node are in - if( (context_mod == sink_mod) && (context_mod == source_mod) ) { + if ((context_mod == sink_mod) && (context_mod == source_mod)) { ((sink_direction, source_direction): @unchecked) match { // SINK SOURCE // CURRENT MOD CURRENT MOD - case (Output, _) => issueConnect(sink, source) - case (Internal, _) => issueConnect(sink, source) - case (Input, _) => throw UnwritableSinkException(sink, source) + case (Output, _) => issueConnect(sink, source) + case (Internal, _) => issueConnect(sink, source) + case (Input, _) => throw UnwritableSinkException(sink, source) } } // CASE: Context is same module as sink node and right node is in a child module - else if((sink_mod == context_mod) && (source_parent == context_mod)) { + else if ((sink_mod == context_mod) && (source_parent == context_mod)) { // Thus, right node better be a port node and thus have a direction ((sink_direction, source_direction): @unchecked) match { // SINK SOURCE // CURRENT MOD CHILD MOD - case (Internal, Output) => issueConnect(sink, source) - case (Internal, Input) => issueConnect(sink, source) - case (Output, Output) => issueConnect(sink, source) - case (Output, Input) => issueConnect(sink, source) - case (_, Internal) => { + case (Internal, Output) => issueConnect(sink, source) + case (Internal, Input) => issueConnect(sink, source) + case (Output, Output) => issueConnect(sink, source) + case (Output, Input) => issueConnect(sink, source) + case (_, Internal) => { if (!(connectCompileOptions.dontAssumeDirectionality)) { issueConnect(sink, source) } else { throw UnreadableSourceException(sink, source) } } - case (Input, Output) if (!(connectCompileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink) - case (Input, _) => throw UnwritableSinkException(sink, source) + case (Input, Output) if (!(connectCompileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink) + case (Input, _) => throw UnwritableSinkException(sink, source) } } // CASE: Context is same module as source node and sink node is in child module - else if((source_mod == context_mod) && (sink_parent == context_mod)) { + else if ((source_mod == context_mod) && (sink_parent == context_mod)) { // Thus, left node better be a port node and thus have a direction ((sink_direction, source_direction): @unchecked) match { // SINK SOURCE // CHILD MOD CURRENT MOD - case (Input, _) => issueConnect(sink, source) - case (Output, _) => throw UnwritableSinkException(sink, source) - case (Internal, _) => throw UnwritableSinkException(sink, source) + case (Input, _) => issueConnect(sink, source) + case (Output, _) => throw UnwritableSinkException(sink, source) + case (Internal, _) => throw UnwritableSinkException(sink, source) } } // CASE: Context is the parent module of both the module containing sink node // and the module containing source node // Note: This includes case when sink and source in same module but in parent - else if((sink_parent == context_mod) && (source_parent == context_mod)) { + else if ((sink_parent == context_mod) && (source_parent == context_mod)) { // Thus both nodes must be ports and have a direction ((sink_direction, source_direction): @unchecked) match { // SINK SOURCE // CHILD MOD CHILD MOD - case (Input, Input) => issueConnect(sink, source) - case (Input, Output) => issueConnect(sink, source) - case (Output, _) => throw UnwritableSinkException(sink, source) - case (_, Internal) => { + case (Input, Input) => issueConnect(sink, source) + case (Input, Output) => issueConnect(sink, source) + case (Output, _) => throw UnwritableSinkException(sink, source) + case (_, Internal) => { if (!(connectCompileOptions.dontAssumeDirectionality)) { issueConnect(sink, source) } else { throw UnreadableSourceException(sink, source) } } - case (Internal, _) => throw UnwritableSinkException(sink, source) + case (Internal, _) => throw UnwritableSinkException(sink, source) } } diff --git a/core/src/main/scala/chisel3/internal/Namer.scala b/core/src/main/scala/chisel3/internal/Namer.scala index c6e36cb6..c36aafef 100644 --- a/core/src/main/scala/chisel3/internal/Namer.scala +++ b/core/src/main/scala/chisel3/internal/Namer.scala @@ -42,6 +42,7 @@ import scala.collection.JavaConverters._ * ability to take descendant naming contexts. */ sealed trait NamingContextInterface { + /** Suggest a name (that will be propagated to FIRRTL) for an object, then returns the object * itself (so this can be inserted transparently anywhere). * Is a no-op (so safe) when applied on objects that aren't named, including non-Chisel data @@ -61,8 +62,7 @@ sealed trait NamingContextInterface { object DummyNamer extends NamingContextInterface { def name[T](obj: T, name: String): T = obj - def namePrefix(prefix: String): Unit = { - } + def namePrefix(prefix: String): Unit = {} } /** Actual namer functionality. @@ -71,7 +71,7 @@ class NamingContext extends NamingContextInterface { val descendants = new IdentityHashMap[AnyRef, ListBuffer[NamingContext]]() val anonymousDescendants = ListBuffer[NamingContext]() val items = ListBuffer[(AnyRef, String)]() - var closed = false // a sanity check to ensure no more name() calls are done after namePrefix + var closed = false // a sanity check to ensure no more name() calls are done after namePrefix /** Adds a NamingContext object as a descendant - where its contained objects will have names * prefixed with the name given to the reference object, if the reference object is named in the @@ -82,11 +82,13 @@ class NamingContext extends NamingContextInterface { case ref: AnyRef => // getOrElseUpdate val l = descendants.get(ref) - val buf = if (l != null) l else { - val value = ListBuffer[NamingContext]() - descendants.put(ref, value) - value - } + val buf = + if (l != null) l + else { + val value = ListBuffer[NamingContext]() + descendants.put(ref, value) + value + } buf += descendant case _ => anonymousDescendants += descendant } @@ -95,8 +97,8 @@ class NamingContext extends NamingContextInterface { def name[T](obj: T, name: String): T = { assert(!closed, "Can't name elements after namePrefix called") obj match { - case _: NoChiselNamePrefix => // Don't name things with NoChiselNamePrefix - case ref: AnyRef => items += ((ref, name)) + case _: NoChiselNamePrefix => // Don't name things with NoChiselNamePrefix + case ref: AnyRef => items += ((ref, name)) case _ => } obj @@ -156,5 +158,5 @@ class NamingStack { } } - def length() : Int = namingStack.length + def length(): Int = namingStack.length } diff --git a/core/src/main/scala/chisel3/internal/SourceInfo.scala b/core/src/main/scala/chisel3/internal/SourceInfo.scala index 0d6d8eb7..dc7f7fab 100644 --- a/core/src/main/scala/chisel3/internal/SourceInfo.scala +++ b/core/src/main/scala/chisel3/internal/SourceInfo.scala @@ -20,6 +20,7 @@ import scala.reflect.macros.blackbox.Context /** Abstract base class for generalized source information. */ sealed trait SourceInfo { + /** A prettier toString * * Make a useful message if SourceInfo is available, nothing otherwise diff --git a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala index ac784882..2d21a7cb 100644 --- a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala +++ b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala @@ -5,7 +5,7 @@ import chisel3._ import chisel3.experimental._ import chisel3.internal.sourceinfo.{NoSourceInfo, SourceInfo, SourceLine, UnlocatableSourceInfo} import firrtl.{ir => fir} -import chisel3.internal.{HasId, castToInt, throwException} +import chisel3.internal.{castToInt, throwException, HasId} import scala.annotation.{nowarn, tailrec} import scala.collection.immutable.Queue @@ -21,9 +21,9 @@ private[chisel3] object Converter { case PString(str) => (str.replaceAll("%", "%%"), List.empty) case format: FirrtlFormat => ("%" + format.specifier, List(format.bits.ref)) - case Name(data) => (data.ref.name, List.empty) + case Name(data) => (data.ref.name, List.empty) case FullName(data) => (data.ref.fullName(ctx), List.empty) - case Percent => ("%%", List.empty) + case Percent => ("%%", List.empty) } private def reportInternalError(msg: String): Nothing = { @@ -53,9 +53,9 @@ private[chisel3] object Converter { def convert(dir: MemPortDirection): firrtl.MPortDir = dir match { case MemPortDirection.INFER => firrtl.MInfer - case MemPortDirection.READ => firrtl.MRead + case MemPortDirection.READ => firrtl.MRead case MemPortDirection.WRITE => firrtl.MWrite - case MemPortDirection.RDWR => firrtl.MReadWrite + case MemPortDirection.RDWR => firrtl.MReadWrite } // TODO @@ -82,7 +82,8 @@ private[chisel3] object Converter { fir.UIntLiteral(n, fir.IntWidth(u.minWidth)) case ULit(n, w) => fir.UIntLiteral(n, convert(w)) - case slit @ SLit(n, w) => fir.SIntLiteral(n, convert(w)) + case slit @ SLit(n, w) => + fir.SIntLiteral(n, convert(w)) val unsigned = if (n < 0) (BigInt(1) << slit.width.get) + n else n val uint = convert(ULit(unsigned, slit.width), ctx, info) fir.DoPrim(firrtl.PrimOps.AsSInt, Seq(uint), Seq.empty, fir.UnknownType) @@ -120,19 +121,43 @@ private[chisel3] object Converter { case e @ DefWire(info, id) => Some(fir.DefWire(convert(info), e.name, extractType(id, info))) case e @ DefReg(info, id, clock) => - Some(fir.DefRegister(convert(info), e.name, extractType(id, info), convert(clock, ctx, info), - firrtl.Utils.zero, convert(getRef(id, info), ctx, info))) + Some( + fir.DefRegister( + convert(info), + e.name, + extractType(id, info), + convert(clock, ctx, info), + firrtl.Utils.zero, + convert(getRef(id, info), ctx, info) + ) + ) case e @ DefRegInit(info, id, clock, reset, init) => - Some(fir.DefRegister(convert(info), e.name, extractType(id, info), convert(clock, ctx, info), - convert(reset, ctx, info), convert(init, ctx, info))) + Some( + fir.DefRegister( + convert(info), + e.name, + extractType(id, info), + convert(clock, ctx, info), + convert(reset, ctx, info), + convert(init, ctx, info) + ) + ) case e @ DefMemory(info, id, t, size) => Some(firrtl.CDefMemory(convert(info), e.name, extractType(t, info), size, false)) case e @ DefSeqMemory(info, id, t, size, ruw) => Some(firrtl.CDefMemory(convert(info), e.name, extractType(t, info), size, true, ruw)) case e: DefMemPort[_] => val info = e.sourceInfo - Some(firrtl.CDefMPort(convert(e.sourceInfo), e.name, fir.UnknownType, - e.source.fullName(ctx), Seq(convert(e.index, ctx, info), convert(e.clock, ctx, info)), convert(e.dir))) + Some( + firrtl.CDefMPort( + convert(e.sourceInfo), + e.name, + fir.UnknownType, + e.source.fullName(ctx), + Seq(convert(e.index, ctx, info), convert(e.clock, ctx, info)), + convert(e.dir) + ) + ) case Connect(info, loc, exp) => Some(fir.Connect(convert(info), convert(loc, ctx, info), convert(exp, ctx, info))) case BulkConnect(info, loc, exp) => @@ -147,16 +172,33 @@ private[chisel3] object Converter { Some(fir.Stop(convert(info), ret, convert(clock, ctx, info), firrtl.Utils.one, e.name)) case e @ Printf(_, info, clock, pable) => val (fmt, args) = unpack(pable, ctx) - Some(fir.Print(convert(info), fir.StringLit(fmt), - args.map(a => convert(a, ctx, info)), convert(clock, ctx, info), firrtl.Utils.one, e.name)) + Some( + fir.Print( + convert(info), + fir.StringLit(fmt), + args.map(a => convert(a, ctx, info)), + convert(clock, ctx, info), + firrtl.Utils.one, + e.name + ) + ) case e @ Verification(_, op, info, clk, pred, msg) => val firOp = op match { case Formal.Assert => fir.Formal.Assert case Formal.Assume => fir.Formal.Assume - case Formal.Cover => fir.Formal.Cover + case Formal.Cover => fir.Formal.Cover } - Some(fir.Verification(firOp, convert(info), convert(clk, ctx, info), - convert(pred, ctx, info), firrtl.Utils.one, fir.StringLit(msg), e.name)) + Some( + fir.Verification( + firOp, + convert(info), + convert(clk, ctx, info), + convert(pred, ctx, info), + firrtl.Utils.one, + fir.StringLit(msg), + e.name + ) + ) case _ => None } @@ -183,59 +225,60 @@ private[chisel3] object Converter { */ def convert(cmds: Seq[Command], ctx: Component): fir.Statement = { @tailrec - def rec(acc: Queue[fir.Statement], - scope: List[WhenFrame]) - (cmds: Seq[Command]): Seq[fir.Statement] = { + def rec(acc: Queue[fir.Statement], scope: List[WhenFrame])(cmds: Seq[Command]): Seq[fir.Statement] = { if (cmds.isEmpty) { assert(scope.isEmpty) acc - } else convertSimpleCommand(cmds.head, ctx) match { - // Most Commands map 1:1 - case Some(stmt) => - rec(acc :+ stmt, scope)(cmds.tail) - // When scoping logic does not map 1:1 and requires pushing/popping WhenFrames - // Please see WhenFrame for more details - case None => cmds.head match { - case WhenBegin(info, pred) => - val when = fir.Conditionally(convert(info), convert(pred, ctx, info), fir.EmptyStmt, fir.EmptyStmt) - val frame = WhenFrame(when, acc, false) - rec(Queue.empty, frame +: scope)(cmds.tail) - case WhenEnd(info, depth, _) => - val frame = scope.head - val when = if (frame.alt) frame.when.copy(alt = fir.Block(acc)) - else frame.when.copy(conseq = fir.Block(acc)) - // Check if this when has an else - cmds.tail.headOption match { - case Some(AltBegin(_)) => - assert(!frame.alt, "Internal Error! Unexpected when structure!") // Only 1 else per when - rec(Queue.empty, frame.copy(when = when, alt = true) +: scope.tail)(cmds.drop(2)) - case _ => // Not followed by otherwise - // If depth > 0 then we need to close multiple When scopes so we add a new WhenEnd - // If we're nested we need to add more WhenEnds to ensure each When scope gets - // properly closed - val cmdsx = if (depth > 0) WhenEnd(info, depth - 1, false) +: cmds.tail else cmds.tail - rec(frame.outer :+ when, scope.tail)(cmdsx) + } else + convertSimpleCommand(cmds.head, ctx) match { + // Most Commands map 1:1 + case Some(stmt) => + rec(acc :+ stmt, scope)(cmds.tail) + // When scoping logic does not map 1:1 and requires pushing/popping WhenFrames + // Please see WhenFrame for more details + case None => + cmds.head match { + case WhenBegin(info, pred) => + val when = fir.Conditionally(convert(info), convert(pred, ctx, info), fir.EmptyStmt, fir.EmptyStmt) + val frame = WhenFrame(when, acc, false) + rec(Queue.empty, frame +: scope)(cmds.tail) + case WhenEnd(info, depth, _) => + val frame = scope.head + val when = + if (frame.alt) frame.when.copy(alt = fir.Block(acc)) + else frame.when.copy(conseq = fir.Block(acc)) + // Check if this when has an else + cmds.tail.headOption match { + case Some(AltBegin(_)) => + assert(!frame.alt, "Internal Error! Unexpected when structure!") // Only 1 else per when + rec(Queue.empty, frame.copy(when = when, alt = true) +: scope.tail)(cmds.drop(2)) + case _ => // Not followed by otherwise + // If depth > 0 then we need to close multiple When scopes so we add a new WhenEnd + // If we're nested we need to add more WhenEnds to ensure each When scope gets + // properly closed + val cmdsx = if (depth > 0) WhenEnd(info, depth - 1, false) +: cmds.tail else cmds.tail + rec(frame.outer :+ when, scope.tail)(cmdsx) + } + case OtherwiseEnd(info, depth) => + val frame = scope.head + val when = frame.when.copy(alt = fir.Block(acc)) + // TODO For some reason depth == 1 indicates the last closing otherwise whereas + // depth == 0 indicates last closing when + val cmdsx = if (depth > 1) OtherwiseEnd(info, depth - 1) +: cmds.tail else cmds.tail + rec(scope.head.outer :+ when, scope.tail)(cmdsx) } - case OtherwiseEnd(info, depth) => - val frame = scope.head - val when = frame.when.copy(alt = fir.Block(acc)) - // TODO For some reason depth == 1 indicates the last closing otherwise whereas - // depth == 0 indicates last closing when - val cmdsx = if (depth > 1) OtherwiseEnd(info, depth - 1) +: cmds.tail else cmds.tail - rec(scope.head.outer :+ when, scope.tail)(cmdsx) } - } } fir.Block(rec(Queue.empty, List.empty)(cmds)) } def convert(width: Width): fir.Width = width match { - case UnknownWidth() => fir.UnknownWidth + case UnknownWidth() => fir.UnknownWidth case KnownWidth(value) => fir.IntWidth(value) } def convert(bp: BinaryPoint): fir.Width = bp match { - case UnknownBinaryPoint => fir.UnknownWidth + case UnknownBinaryPoint => fir.UnknownWidth case KnownBinaryPoint(value) => fir.IntWidth(value) } @@ -248,15 +291,15 @@ private[chisel3] object Converter { def extractType(data: Data, info: SourceInfo): fir.Type = extractType(data, false, info) def extractType(data: Data, clearDir: Boolean, info: SourceInfo): fir.Type = data match { - case _: Clock => fir.ClockType + case _: Clock => fir.ClockType case _: AsyncReset => fir.AsyncResetType - case _: ResetType => fir.ResetType - case d: EnumType => fir.UIntType(convert(d.width)) - case d: UInt => fir.UIntType(convert(d.width)) - case d: SInt => fir.SIntType(convert(d.width)) + case _: ResetType => fir.ResetType + case d: EnumType => fir.UIntType(convert(d.width)) + case d: UInt => fir.UIntType(convert(d.width)) + case d: SInt => fir.SIntType(convert(d.width)) case d: FixedPoint => fir.FixedType(convert(d.width), convert(d.binaryPoint)) - case d: Interval => fir.IntervalType(d.range.lowerBound, d.range.upperBound, d.range.firrtlBinaryPoint) - case d: Analog => fir.AnalogType(convert(d.width)) + case d: Interval => fir.IntervalType(d.range.lowerBound, d.range.upperBound, d.range.firrtlBinaryPoint) + case d: Analog => fir.AnalogType(convert(d.width)) case d: Vec[_] => fir.VectorType(extractType(d.sample_element, clearDir, info), d.length) case d: Record => val childClearDir = clearDir || @@ -269,23 +312,23 @@ private[chisel3] object Converter { fir.Field(getRef(elt, info).name, fir.Flip, extractType(elt, false, info)) } fir.BundleType(d.elements.toIndexedSeq.reverse.map { case (_, e) => eltField(e) }) - } + } def convert(name: String, param: Param): fir.Param = param match { - case IntParam(value) => fir.IntParam(name, value) + case IntParam(value) => fir.IntParam(name, value) case DoubleParam(value) => fir.DoubleParam(name, value) case StringParam(value) => fir.StringParam(name, fir.StringLit(value)) - case RawParam(value) => fir.RawStringParam(name, value) + case RawParam(value) => fir.RawStringParam(name, value) } def convert(port: Port, topDir: SpecifiedDirection = SpecifiedDirection.Unspecified): fir.Port = { val resolvedDir = SpecifiedDirection.fromParent(topDir, port.dir) val dir = resolvedDir match { case SpecifiedDirection.Unspecified | SpecifiedDirection.Output => fir.Output - case SpecifiedDirection.Flip | SpecifiedDirection.Input => fir.Input + case SpecifiedDirection.Flip | SpecifiedDirection.Input => fir.Input } val clearDir = resolvedDir match { - case SpecifiedDirection.Input | SpecifiedDirection.Output => true + case SpecifiedDirection.Input | SpecifiedDirection.Output => true case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => false } val info = UnlocatableSourceInfo // Unfortunately there is no source locator for ports ATM @@ -297,8 +340,13 @@ private[chisel3] object Converter { case ctx @ DefModule(_, name, ports, cmds) => fir.Module(fir.NoInfo, name, ports.map(p => convert(p)), convert(cmds.toList, ctx)) case ctx @ DefBlackBox(id, name, ports, topDir, params) => - fir.ExtModule(fir.NoInfo, name, ports.map(p => convert(p, topDir)), id.desiredName, - params.map { case (name, p) => convert(name, p) }.toSeq) + fir.ExtModule( + fir.NoInfo, + name, + ports.map(p => convert(p, topDir)), + id.desiredName, + params.map { case (name, p) => convert(name, p) }.toSeq + ) } def convert(circuit: Circuit): fir.Circuit = @@ -310,4 +358,3 @@ private[chisel3] object Converter { fir.Circuit(fir.NoInfo, lazyModules.map(convert), circuit.name) } } - diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala index 68f5f18e..1ee8842f 100644 --- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -15,7 +15,6 @@ import scala.collection.immutable.NumericRange import scala.math.BigDecimal.RoundingMode import scala.annotation.nowarn - case class PrimOp(name: String) { override def toString: String = name } @@ -68,35 +67,36 @@ object PrimOp { sealed abstract class Arg { def localName: String = name def contextualName(ctx: Component): String = name - def fullName(ctx: Component): String = contextualName(ctx) + def fullName(ctx: Component): String = contextualName(ctx) def name: String } case class Node(id: HasId) extends Arg { override def contextualName(ctx: Component): String = id.getOptionRef match { case Some(arg) => arg.contextualName(ctx) - case None => id.instanceName + case None => id.instanceName } override def localName: String = id.getOptionRef match { case Some(arg) => arg.localName - case None => id.instanceName + case None => id.instanceName } def name: String = id.getOptionRef match { case Some(arg) => arg.name - case None => id.instanceName + case None => id.instanceName } } object Arg { def earlyLocalName(id: HasId): String = id.getOptionRef match { case Some(Index(Node(imm), Node(value))) => s"${earlyLocalName(imm)}[${earlyLocalName(imm)}]" - case Some(Index(Node(imm), arg)) => s"${earlyLocalName(imm)}[${arg.localName}]" - case Some(Slot(Node(imm), name)) => s"${earlyLocalName(imm)}.$name" - case Some(arg) => arg.name - case None => id match { - case data: Data => data._computeName(None, Some("?")).get - case _ => "?" - } + case Some(Index(Node(imm), arg)) => s"${earlyLocalName(imm)}[${arg.localName}]" + case Some(Slot(Node(imm), name)) => s"${earlyLocalName(imm)}.$name" + case Some(arg) => arg.name + case None => + id match { + case data: Data => data._computeName(None, Some("?")).get + case _ => "?" + } } } @@ -121,8 +121,10 @@ abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { protected def minWidth: Int if (forcedWidth) { - require(widthArg.get >= minWidth, - s"The literal value ${num} was elaborated with a specified width of ${widthArg.get} bits, but at least ${minWidth} bits are required.") + require( + widthArg.get >= minWidth, + s"The literal value ${num} was elaborated with a specified width of ${widthArg.get} bits, but at least ${minWidth} bits are required." + ) } } @@ -131,8 +133,8 @@ case class ILit(n: BigInt) extends Arg { } case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { - def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")" - def minWidth: Int = 1 max n.bitLength + def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")" + def minWidth: Int = 1.max(n.bitLength) def cloneWithWidth(newWidth: Width): this.type = { ULit(n, newWidth).asInstanceOf[this.type] @@ -171,8 +173,11 @@ case class IntervalLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends Li s"asInterval(${ULit(unsigned, width).name}, ${n}, ${n}, ${binaryPoint.asInstanceOf[KnownBinaryPoint].value})" } val range: IntervalRange = { - new IntervalRange(IntervalRange.getBound(isClosed = true, BigDecimal(n)), - IntervalRange.getBound(isClosed = true, BigDecimal(n)), IntervalRange.getRangeWidth(binaryPoint)) + new IntervalRange( + IntervalRange.getBound(isClosed = true, BigDecimal(n)), + IntervalRange.getBound(isClosed = true, BigDecimal(n)), + IntervalRange.getRangeWidth(binaryPoint) + ) } def minWidth: Int = 1 + n.bitLength @@ -182,6 +187,7 @@ case class IntervalLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends Li } case class Ref(name: String) extends Arg + /** Arg for ports of Modules * @param mod the module this port belongs to * @param name the name of the port @@ -190,6 +196,7 @@ case class ModuleIO(mod: BaseModule, name: String) extends Arg { override def contextualName(ctx: Component): String = if (mod eq ctx.id) name else s"${mod.getRef.name}.$name" } + /** Ports of cloned modules (CloneModuleAsRecord) * @param mod The original module for which these ports are a clone * @param name the name of the module instance @@ -224,22 +231,22 @@ object Width { sealed abstract class Width { type W = Int - def min(that: Width): Width = this.op(that, _ min _) - def max(that: Width): Width = this.op(that, _ max _) - def + (that: Width): Width = this.op(that, _ + _) - def + (that: Int): Width = this.op(this, (a, b) => a + that) - def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that)) + def min(that: Width): Width = this.op(that, _ min _) + def max(that: Width): Width = this.op(that, _ max _) + def +(that: Width): Width = this.op(that, _ + _) + def +(that: Int): Width = this.op(this, (a, b) => a + that) + def shiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that)) def dynamicShiftLeft(that: Width): Width = this.op(that, (a, b) => a + (1 << b) - 1) def known: Boolean - def get: W + def get: W protected def op(that: Width, f: (W, W) => W): Width } sealed case class UnknownWidth() extends Width { def known: Boolean = false - def get: Int = None.get + def get: Int = None.get def op(that: Width, f: (W, W) => W): Width = this override def toString: String = "" } @@ -247,10 +254,10 @@ sealed case class UnknownWidth() extends Width { sealed case class KnownWidth(value: Int) extends Width { require(value >= 0) def known: Boolean = true - def get: Int = value + def get: Int = value def op(that: Width, f: (W, W) => W): Width = that match { case KnownWidth(x) => KnownWidth(f(value, x)) - case _ => that + case _ => that } override def toString: String = s"<${value.toString}>" } @@ -262,36 +269,35 @@ object BinaryPoint { sealed abstract class BinaryPoint { type W = Int - def max(that: BinaryPoint): BinaryPoint = this.op(that, _ max _) - def + (that: BinaryPoint): BinaryPoint = this.op(that, _ + _) - def + (that: Int): BinaryPoint = this.op(this, (a, b) => a + that) - def shiftRight(that: Int): BinaryPoint = this.op(this, (a, b) => 0 max (a - that)) + def max(that: BinaryPoint): BinaryPoint = this.op(that, _ max _) + def +(that: BinaryPoint): BinaryPoint = this.op(that, _ + _) + def +(that: Int): BinaryPoint = this.op(this, (a, b) => a + that) + def shiftRight(that: Int): BinaryPoint = this.op(this, (a, b) => 0.max(a - that)) def dynamicShiftLeft(that: BinaryPoint): BinaryPoint = this.op(that, (a, b) => a + (1 << b) - 1) def known: Boolean - def get: W + def get: W protected def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint } case object UnknownBinaryPoint extends BinaryPoint { def known: Boolean = false - def get: Int = None.get + def get: Int = None.get def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint = this override def toString: String = "" } sealed case class KnownBinaryPoint(value: Int) extends BinaryPoint { def known: Boolean = true - def get: Int = value + def get: Int = value def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint = that match { case KnownBinaryPoint(x) => KnownBinaryPoint(f(value, x)) - case _ => that + case _ => that } override def toString: String = s"<<${value.toString}>>" } - sealed abstract class MemPortDirection(name: String) { override def toString: String = name } @@ -305,17 +311,18 @@ object MemPortDirection { sealed trait RangeType { def getWidth: Width - def * (that: IntervalRange): IntervalRange - def +& (that: IntervalRange): IntervalRange - def -& (that: IntervalRange): IntervalRange - def << (that: Int): IntervalRange - def >> (that: Int): IntervalRange - def << (that: KnownWidth): IntervalRange - def >> (that: KnownWidth): IntervalRange + def *(that: IntervalRange): IntervalRange + def +&(that: IntervalRange): IntervalRange + def -&(that: IntervalRange): IntervalRange + def <<(that: Int): IntervalRange + def >>(that: Int): IntervalRange + def <<(that: KnownWidth): IntervalRange + def >>(that: KnownWidth): IntervalRange def merge(that: IntervalRange): IntervalRange } object IntervalRange { + /** Creates an IntervalRange, this is used primarily by the range interpolator macro * @param lower lower bound * @param upper upper bound @@ -352,7 +359,9 @@ object IntervalRange { case KnownWidth(w) => val nearestPowerOf2 = BigInt("1" + ("0" * (w - 1)), 2) IntervalRange( - firrtlir.Closed(BigDecimal(-nearestPowerOf2)), firrtlir.Closed(BigDecimal(nearestPowerOf2 - 1)), binaryPoint + firrtlir.Closed(BigDecimal(-nearestPowerOf2)), + firrtlir.Closed(BigDecimal(nearestPowerOf2 - 1)), + binaryPoint ) case _ => IntervalRange(firrtlir.UnknownBound, firrtlir.UnknownBound, binaryPoint) @@ -365,22 +374,19 @@ object IntervalRange { } def getBound(isClosed: Boolean, value: String): firrtlir.Bound = { - if(value == "?") { + if (value == "?") { firrtlir.UnknownBound - } - else if(isClosed) { + } else if (isClosed) { firrtlir.Closed(BigDecimal(value)) - } - else { + } else { firrtlir.Open(BigDecimal(value)) } } def getBound(isClosed: Boolean, value: BigDecimal): firrtlir.Bound = { - if(isClosed) { + if (isClosed) { firrtlir.Closed(value) - } - else { + } else { firrtlir.Open(value) } } @@ -394,33 +400,30 @@ object IntervalRange { } def getBinaryPoint(n: Int): firrtlir.Width = { - if(n < 0) { + if (n < 0) { firrtlir.UnknownWidth - } - else { + } else { firrtlir.IntWidth(n) } } def getBinaryPoint(n: BinaryPoint): firrtlir.Width = { n match { - case UnknownBinaryPoint => firrtlir.UnknownWidth + case UnknownBinaryPoint => firrtlir.UnknownWidth case KnownBinaryPoint(w) => firrtlir.IntWidth(w) } } def getRangeWidth(w: Width): firrtlir.Width = { - if(w.known) { + if (w.known) { firrtlir.IntWidth(w.get) - } - else { + } else { firrtlir.UnknownWidth } } def getRangeWidth(binaryPoint: BinaryPoint): firrtlir.Width = { - if(binaryPoint.known) { + if (binaryPoint.known) { firrtlir.IntWidth(binaryPoint.get) - } - else { + } else { firrtlir.UnknownWidth } } @@ -428,47 +431,46 @@ object IntervalRange { def Unknown: IntervalRange = range"[?,?].?" } - sealed class IntervalRange( - val lowerBound: firrtlir.Bound, - val upperBound: firrtlir.Bound, - private[chisel3] val firrtlBinaryPoint: firrtlir.Width) - extends firrtlir.IntervalType(lowerBound, upperBound, firrtlBinaryPoint) + val lowerBound: firrtlir.Bound, + val upperBound: firrtlir.Bound, + private[chisel3] val firrtlBinaryPoint: firrtlir.Width) + extends firrtlir.IntervalType(lowerBound, upperBound, firrtlBinaryPoint) with RangeType { (lowerBound, upperBound) match { case (firrtlir.Open(begin), firrtlir.Open(end)) => - if(begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") + if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") binaryPoint match { case KnownBinaryPoint(bp) => - if(begin >= end - (BigDecimal(1) / BigDecimal(BigInt(1) << bp))) { + if (begin >= end - (BigDecimal(1) / BigDecimal(BigInt(1) << bp))) { throw new ChiselException(s"Invalid range with ${serialize}") } case _ => } case (firrtlir.Open(begin), firrtlir.Closed(end)) => - if(begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") + if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") case (firrtlir.Closed(begin), firrtlir.Open(end)) => - if(begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") + if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") case (firrtlir.Closed(begin), firrtlir.Closed(end)) => - if(begin > end) throw new ChiselException(s"Invalid range with ${serialize}") + if (begin > end) throw new ChiselException(s"Invalid range with ${serialize}") case _ => } override def toString: String = { val binaryPoint = firrtlBinaryPoint match { case firrtlir.IntWidth(n) => s"$n" - case _ => "?" + case _ => "?" } val lowerBoundString = lowerBound match { - case firrtlir.Closed(l) => s"[$l" - case firrtlir.Open(l) => s"($l" - case firrtlir.UnknownBound => s"[?" + case firrtlir.Closed(l) => s"[$l" + case firrtlir.Open(l) => s"($l" + case firrtlir.UnknownBound => s"[?" } val upperBoundString = upperBound match { - case firrtlir.Closed(l) => s"$l]" - case firrtlir.Open(l) => s"$l)" - case firrtlir.UnknownBound => s"?]" + case firrtlir.Closed(l) => s"$l]" + case firrtlir.Open(l) => s"$l)" + case firrtlir.UnknownBound => s"?]" } s"""range"$lowerBoundString,$upperBoundString.$binaryPoint"""" } @@ -487,8 +489,8 @@ sealed class IntervalRange( case Some(inc) => lower match { case firrtlir.Closed(n) => Some(n) - case firrtlir.Open(n) => Some(n + inc) - case _ => None + case firrtlir.Open(n) => Some(n + inc) + case _ => None } case _ => None @@ -503,8 +505,8 @@ sealed class IntervalRange( case Some(inc) => upper match { case firrtlir.Closed(n) => Some(n) - case firrtlir.Open(n) => Some(n - inc) - case _ => None + case firrtlir.Open(n) => Some(n - inc) + case _ => None } case _ => None @@ -528,16 +530,18 @@ sealed class IntervalRange( override def getWidth: Width = { width match { - case firrtlir.IntWidth(n) => KnownWidth(n.toInt) + case firrtlir.IntWidth(n) => KnownWidth(n.toInt) case firrtlir.UnknownWidth => UnknownWidth() } } private def doFirrtlOp(op: firrtlir.PrimOp, that: IntervalRange): IntervalRange = { - PrimOps.set_primop_type( - firrtlir.DoPrim(op, - Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", that)), Nil,firrtlir.UnknownType) - ).tpe match { + PrimOps + .set_primop_type( + firrtlir + .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", that)), Nil, firrtlir.UnknownType) + ) + .tpe match { case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) case other => sys.error("BAD!") } @@ -545,24 +549,27 @@ sealed class IntervalRange( private def doFirrtlDynamicShift(that: UInt, isLeft: Boolean): IntervalRange = { val uinttpe = that.widthOption match { - case None => firrtlir.UIntType(firrtlir.UnknownWidth) + case None => firrtlir.UIntType(firrtlir.UnknownWidth) case Some(w) => firrtlir.UIntType(firrtlir.IntWidth(w)) } - val op = if(isLeft) PrimOps.Dshl else PrimOps.Dshr - PrimOps.set_primop_type( - firrtlir.DoPrim(op, - Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", uinttpe)), Nil,firrtlir.UnknownType) - ).tpe match { + val op = if (isLeft) PrimOps.Dshl else PrimOps.Dshr + PrimOps + .set_primop_type( + firrtlir + .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", uinttpe)), Nil, firrtlir.UnknownType) + ) + .tpe match { case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) case other => sys.error("BAD!") } } private def doFirrtlOp(op: firrtlir.PrimOp, that: Int): IntervalRange = { - PrimOps.set_primop_type( - firrtlir.DoPrim(op, - Seq(firrtlir.Reference("a", this)), Seq(BigInt(that)), firrtlir.UnknownType) - ).tpe match { + PrimOps + .set_primop_type( + firrtlir.DoPrim(op, Seq(firrtlir.Reference("a", this)), Seq(BigInt(that)), firrtlir.UnknownType) + ) + .tpe match { case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) case other => sys.error("BAD!") } @@ -596,7 +603,7 @@ sealed class IntervalRange( } private def adjustBoundValue(value: BigDecimal, binaryPointValue: Int): BigDecimal = { - if(binaryPointValue >= 0) { + if (binaryPointValue >= 0) { val maskFactor = BigDecimal(1 << binaryPointValue) val a = (value * maskFactor) val b = a.setScale(0, RoundingMode.DOWN) @@ -611,9 +618,9 @@ sealed class IntervalRange( binaryPoint match { case KnownBinaryPoint(binaryPointValue) => bound match { - case firrtlir.Open(value) => firrtlir.Open(adjustBoundValue(value, binaryPointValue)) + case firrtlir.Open(value) => firrtlir.Open(adjustBoundValue(value, binaryPointValue)) case firrtlir.Closed(value) => firrtlir.Closed(adjustBoundValue(value, binaryPointValue)) - case _ => bound + case _ => bound } case _ => firrtlir.UnknownBound } @@ -746,19 +753,22 @@ sealed class IntervalRange( override def merge(that: IntervalRange): IntervalRange = { val lowest = (this.getLowestPossibleValue, that.getLowestPossibleValue) match { case (Some(l1), Some(l2)) => - if(l1 < l2) { this.lower } else { that.lower } + if (l1 < l2) { this.lower } + else { that.lower } case _ => firrtlir.UnknownBound } val highest = (this.getHighestPossibleValue, that.getHighestPossibleValue) match { case (Some(l1), Some(l2)) => - if(l1 >= l2) { this.lower } else { that.lower } + if (l1 >= l2) { this.lower } + else { that.lower } case _ => firrtlir.UnknownBound } val newBinaryPoint = (this.firrtlBinaryPoint, that.firrtlBinaryPoint) match { case (firrtlir.IntWidth(b1), firrtlir.IntWidth(b2)) => - if(b1 > b2) { firrtlir.IntWidth(b1)} else { firrtlir.IntWidth(b2) } + if (b1 > b2) { firrtlir.IntWidth(b1) } + else { firrtlir.IntWidth(b2) } case _ => firrtlir.UnknownWidth } @@ -788,8 +798,21 @@ case class DefWire(sourceInfo: SourceInfo, id: Data) extends Definition case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg) extends Definition case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition case class DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: BigInt) extends Definition -case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: BigInt, readUnderWrite: fir.ReadUnderWrite.Value) extends Definition -case class DefMemPort[T <: Data](sourceInfo: SourceInfo, id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition +case class DefSeqMemory( + sourceInfo: SourceInfo, + id: HasId, + t: Data, + size: BigInt, + readUnderWrite: fir.ReadUnderWrite.Value) + extends Definition +case class DefMemPort[T <: Data]( + sourceInfo: SourceInfo, + id: T, + source: Node, + dir: MemPortDirection, + index: Arg, + clock: Arg) + extends Definition @nowarn("msg=class Port") // delete when Port becomes private case class DefInstance(sourceInfo: SourceInfo, id: BaseModule, ports: Seq[Port]) extends Definition case class WhenBegin(sourceInfo: SourceInfo, pred: Arg) extends Command @@ -802,7 +825,10 @@ case class Attach(sourceInfo: SourceInfo, locs: Seq[Node]) extends Command case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command case class Stop(id: stop.Stop, sourceInfo: SourceInfo, clock: Arg, ret: Int) extends Definition // Note this is just deprecated which will cause deprecation warnings, use @nowarn -@deprecated("This API should never have been public, for Module port reflection, use DataMirror.modulePorts", "Chisel 3.5") +@deprecated( + "This API should never have been public, for Module port reflection, use DataMirror.modulePorts", + "Chisel 3.5" +) case class Port(id: Data, dir: SpecifiedDirection) case class Printf(id: printf.Printf, sourceInfo: SourceInfo, clock: Arg, pable: Printable) extends Definition object Formal extends Enumeration { @@ -810,18 +836,30 @@ object Formal extends Enumeration { val Assume = Value("assume") val Cover = Value("cover") } -case class Verification[T <: VerificationStatement](id: T, op: Formal.Value, sourceInfo: SourceInfo, clock: Arg, - predicate: Arg, message: String) extends Definition +case class Verification[T <: VerificationStatement]( + id: T, + op: Formal.Value, + sourceInfo: SourceInfo, + clock: Arg, + predicate: Arg, + message: String) + extends Definition @nowarn("msg=class Port") // delete when Port becomes private abstract class Component extends Arg { - def id: BaseModule - def name: String + def id: BaseModule + def name: String def ports: Seq[Port] } @nowarn("msg=class Port") // delete when Port becomes private case class DefModule(id: RawModule, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component @nowarn("msg=class Port") // delete when Port becomes private -case class DefBlackBox(id: BaseBlackBox, name: String, ports: Seq[Port], topDir: SpecifiedDirection, params: Map[String, Param]) extends Component +case class DefBlackBox( + id: BaseBlackBox, + name: String, + ports: Seq[Port], + topDir: SpecifiedDirection, + params: Map[String, Param]) + extends Component case class Circuit(name: String, components: Seq[Component], annotations: Seq[ChiselAnnotation], renames: RenameMap) { def firrtlAnnotations: Iterable[Annotation] = annotations.flatMap(_.toFirrtl.update(renames)) diff --git a/core/src/main/scala/chisel3/internal/prefix.scala b/core/src/main/scala/chisel3/internal/prefix.scala index 620d0864..1e4c5ff1 100644 --- a/core/src/main/scala/chisel3/internal/prefix.scala +++ b/core/src/main/scala/chisel3/internal/prefix.scala @@ -15,7 +15,6 @@ package chisel3.internal * } * * }}} - * */ private[chisel3] object prefix { // scalastyle:ignore @@ -51,7 +50,7 @@ private[chisel3] object prefix { // scalastyle:ignore // This causes extra prefixes to be added, and subsequently cleared in the // Module constructor. Thus, we need to just make sure if the previous push // was an incorrect one, to not pop off an empty stack - if(Builder.getPrefix.nonEmpty) Builder.popPrefix() + if (Builder.getPrefix.nonEmpty) Builder.popPrefix() ret } } @@ -65,7 +64,6 @@ private[chisel3] object prefix { // scalastyle:ignore * } * * }}} - * */ private[chisel3] object noPrefix { diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala index faca3ae4..bd088e21 100644 --- a/core/src/main/scala/chisel3/package.scala +++ b/core/src/main/scala/chisel3/package.scala @@ -3,7 +3,7 @@ import chisel3.internal.firrtl.BinaryPoint /** This package contains the main chisel3 API. - */ + */ package object chisel3 { import internal.firrtl.{Port, Width} import internal.Builder @@ -28,22 +28,27 @@ package object chisel3 { * `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 { 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) + 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()) + /** Int to SInt conversion, recommended style for constants. */ def S: SInt = SInt.Lit(bigint, Width()) + /** Int to UInt conversion with specified width, recommended style for constants. */ def U(width: Width): UInt = UInt.Lit(bigint, width) + /** Int to SInt conversion with specified width, recommended style for constants. */ def S(width: Width): SInt = SInt.Lit(bigint, width) @@ -52,19 +57,26 @@ package object chisel3 { */ def asUInt: UInt = UInt.Lit(bigint, Width()) - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def asUInt(dummy: Int*): UInt = asUInt /** Int to SInt conversion, recommended style for variables. */ def asSInt: SInt = SInt.Lit(bigint, Width()) - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def asSInt(dummy: Int*): SInt = asSInt /** 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) @@ -74,9 +86,11 @@ package object chisel3 { 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 + /** String to UInt parse with specified width, recommended style for constants. */ def U(width: Width): UInt = str.asUInt(width) @@ -85,10 +99,13 @@ package object chisel3 { */ def asUInt: UInt = { val bigInt = parse(str) - UInt.Lit(bigInt, Width(bigInt.bitLength max 1)) + UInt.Lit(bigInt, Width(bigInt.bitLength.max(1))) } - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def asUInt(dummy: Int*): UInt = asUInt /** String to UInt parse with specified width, recommended style for variables. @@ -99,10 +116,10 @@ package object chisel3 { 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 + case "d" => 10 + case "o" => 8 + case "b" => 2 + case _ => Builder.error(s"Invalid base $base"); 2 } BigInt(num.filterNot(_ == '_'), radix) } @@ -113,6 +130,7 @@ package object chisel3 { } implicit class fromBooleanToLiteral(boolean: Boolean) { + /** Boolean to Bool conversion, recommended style for constants. */ def B: Bool = Bool.Lit(boolean) @@ -121,34 +139,37 @@ package object chisel3 { */ def asBool: Bool = Bool.Lit(boolean) - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def asBool(dummy: Int*): Bool = asBool } // 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) + extends experimental.FixedPoint.Implicits.fromDoubleToLiteral(double) implicit class fromBigDecimalToLiteral(bigDecimal: BigDecimal) - extends experimental.FixedPoint.Implicits.fromBigDecimalToLiteral(bigDecimal) + extends experimental.FixedPoint.Implicits.fromBigDecimalToLiteral(bigDecimal) // 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) + extends experimental.Interval.Implicits.fromIntToLiteralInterval(int) implicit class fromLongToLiteralInterval(long: Long) - extends experimental.Interval.Implicits.fromLongToLiteralInterval(long) + extends experimental.Interval.Implicits.fromLongToLiteralInterval(long) implicit class fromBigIntToLiteralInterval(bigInt: BigInt) - extends experimental.Interval.Implicits.fromBigIntToLiteralInterval(bigInt) + extends experimental.Interval.Implicits.fromBigIntToLiteralInterval(bigInt) implicit class fromDoubleToLiteralInterval(double: Double) - extends experimental.Interval.Implicits.fromDoubleToLiteralInterval(double) + extends experimental.Interval.Implicits.fromDoubleToLiteralInterval(double) implicit class fromBigDecimalToLiteralInterval(bigDecimal: BigDecimal) - extends experimental.Interval.Implicits.fromBigDecimalToLiteralInterval(bigDecimal) + extends experimental.Interval.Implicits.fromBigDecimalToLiteralInterval(bigDecimal) implicit class fromIntToWidth(int: Int) { def W: Width = Width(int) @@ -187,25 +208,27 @@ package object chisel3 { /** Implicit for custom Printable string interpolator */ implicit class PrintableHelper(val sc: StringContext) extends AnyVal { + /** Custom string interpolator for generating Printables: p"..." * Will call .toString on any non-Printable arguments (mimicking s"...") */ def p(args: Any*): Printable = { sc.checkLengths(args) // Enforce sc.parts.size == pargs.size + 1 - val pargs: Seq[Option[Printable]] = args map { + val pargs: Seq[Option[Printable]] = args.map { case p: Printable => Some(p) - case d: Data => Some(d.toPrintable) - case any => for { - v <- Option(any) // Handle null inputs - str = v.toString - if !str.isEmpty // Handle empty Strings - } yield PString(str) + case d: Data => Some(d.toPrintable) + case any => + for { + v <- Option(any) // Handle null inputs + str = v.toString + if !str.isEmpty // Handle empty Strings + } yield PString(str) } - val parts = sc.parts map StringContext.treatEscapes + val parts = sc.parts.map(StringContext.treatEscapes) // Zip sc.parts and pargs together ito flat Seq // eg. Seq(sc.parts(0), pargs(0), sc.parts(1), pargs(1), ...) val seq = for { // append None because sc.parts.size == pargs.size + 1 - (literal, arg) <- parts zip (pargs :+ None) + (literal, arg) <- parts.zip(pargs :+ None) optPable <- Seq(Some(PString(literal)), arg) pable <- optPable // Remove Option[_] } yield pable @@ -221,19 +244,26 @@ package object chisel3 { def getDataElements(a: Aggregate): Seq[Element] = { a.allElements } - @deprecated("duplicated with DataMirror.fullModulePorts, this returns an internal API, will be removed in Chisel 3.6", "Chisel 3.5") + @deprecated( + "duplicated with DataMirror.fullModulePorts, this returns an internal API, will be removed in Chisel 3.6", + "Chisel 3.5" + ) def getModulePorts(m: Module): Seq[Port] = m.getPorts class BindingException(message: String) extends ChiselException(message) + /** A function expected a Chisel type but got a hardware object */ case class ExpectedChiselTypeException(message: String) extends BindingException(message) - /**A function expected a hardware object but got a Chisel type + + /** A function expected a hardware object but got a Chisel type */ case class ExpectedHardwareException(message: String) extends BindingException(message) + /** An aggregate had a mix of specified and unspecified directionality children */ case class MixedDirectionAggregateException(message: String) extends BindingException(message) + /** Attempted to re-bind an already bound (directionality or hardware) object */ case class RebindingException(message: String) extends BindingException(message) diff --git a/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala index 18c6c7aa..d66b51ac 100644 --- a/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala +++ b/macros/src/main/scala/chisel3/internal/InstantiableMacro.scala @@ -6,7 +6,6 @@ import scala.language.experimental.macros import scala.annotation.StaticAnnotation import scala.reflect.macros.whitebox - private[chisel3] object instantiableMacro { def impl(c: whitebox.Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { @@ -38,7 +37,7 @@ private[chisel3] object instantiableMacro { val result = { val (clz, objOpt) = annottees.map(_.tree).toList match { case Seq(c, o) => (c, Some(o)) - case Seq(c) => (c, None) + case Seq(c) => (c, None) } val (newClz, implicitClzs, tpname) = clz match { case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => @@ -46,19 +45,27 @@ private[chisel3] object instantiableMacro { val instname = TypeName(tpname + c.freshName()) val (newStats, extensions) = processBody(stats) val argTParams = tparams.map(_.name) - (q""" $mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats } """, - Seq(q"""implicit class $defname[..$tparams](___module: chisel3.experimental.hierarchy.Definition[$tpname[..$argTParams]]) { ..$extensions }""", - q"""implicit class $instname[..$tparams](___module: chisel3.experimental.hierarchy.Instance[$tpname[..$argTParams]]) { ..$extensions } """), - tpname) + ( + q""" $mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats } """, + Seq( + q"""implicit class $defname[..$tparams](___module: chisel3.experimental.hierarchy.Definition[$tpname[..$argTParams]]) { ..$extensions }""", + q"""implicit class $instname[..$tparams](___module: chisel3.experimental.hierarchy.Instance[$tpname[..$argTParams]]) { ..$extensions } """ + ), + tpname + ) case q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => val defname = TypeName(tpname + c.freshName()) val instname = TypeName(tpname + c.freshName()) val (newStats, extensions) = processBody(stats) val argTParams = tparams.map(_.name) - (q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats }", - Seq(q"""implicit class $defname[..$tparams](___module: chisel3.experimental.hierarchy.Definition[$tpname[..$argTParams]]) { ..$extensions }""", - q"""implicit class $instname[..$tparams](___module: chisel3.experimental.hierarchy.Instance[$tpname[..$argTParams]]) { ..$extensions } """), - tpname) + ( + q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents with chisel3.experimental.hierarchy.IsInstantiable { $self => ..$newStats }", + Seq( + q"""implicit class $defname[..$tparams](___module: chisel3.experimental.hierarchy.Definition[$tpname[..$argTParams]]) { ..$extensions }""", + q"""implicit class $instname[..$tparams](___module: chisel3.experimental.hierarchy.Instance[$tpname[..$argTParams]]) { ..$extensions } """ + ), + tpname + ) } val newObj = objOpt match { case None => q"""object ${tpname.toTermName} { ..$implicitClzs } """ diff --git a/macros/src/main/scala/chisel3/internal/RangeTransform.scala b/macros/src/main/scala/chisel3/internal/RangeTransform.scala index b9a2d2aa..f401241d 100644 --- a/macros/src/main/scala/chisel3/internal/RangeTransform.scala +++ b/macros/src/main/scala/chisel3/internal/RangeTransform.scala @@ -12,8 +12,8 @@ import scala.util.matching.Regex // Workaround for https://github.com/sbt/sbt/issues/3966 object RangeTransform { val UnspecifiedNumber: Regex = """(\?).*""".r - val IntegerNumber: Regex = """(-?\d+).*""".r - val DecimalNumber: Regex = """(-?\d+\.\d+).*""".r + val IntegerNumber: Regex = """(-?\d+).*""".r + val DecimalNumber: Regex = """(-?\d+\.\d+).*""".r } /** Convert the string to IntervalRange, with unknown, open or closed endpoints and a binary point @@ -48,8 +48,8 @@ class RangeTransform(val c: blackbox.Context) { } var nextStringIndex: Int = 1 - var nextArgIndex: Int = 0 - var currString: String = strings.head + var nextArgIndex: Int = 0 + var currString: String = strings.head /** Mutably gets the next numeric value in the range specifier. */ diff --git a/macros/src/main/scala/chisel3/internal/RuntimeDeprecationTransform.scala b/macros/src/main/scala/chisel3/internal/RuntimeDeprecationTransform.scala index e7eb7162..ff41bd30 100644 --- a/macros/src/main/scala/chisel3/internal/RuntimeDeprecationTransform.scala +++ b/macros/src/main/scala/chisel3/internal/RuntimeDeprecationTransform.scala @@ -3,7 +3,7 @@ package chisel3.internal import scala.reflect.macros.whitebox.Context -import scala.annotation.{StaticAnnotation, compileTimeOnly} +import scala.annotation.{compileTimeOnly, StaticAnnotation} import scala.language.experimental.macros // Workaround for https://github.com/sbt/sbt/issues/3966 @@ -14,24 +14,34 @@ class RuntimeDeprecatedTransform(val c: Context) { /** Adds a Builder.deprecated(...) call based on the contents of a plain @deprecated annotation. */ def runtimeDeprecated(annottees: c.Tree*): c.Tree = { - val transformed = annottees.map(annottee => annottee match { - case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => { - val Modifiers(_, _, annotations) = mods - val annotationMessage = annotations.collect { // get all messages from deprecated annotations - case q"new deprecated($desc, $since)" => desc - } match { // ensure there's only one and return it - case msg :: Nil => msg - case _ => c.abort(c.enclosingPosition, s"@chiselRuntimeDeprecated annotion must be used with exactly one @deprecated annotation, got annotations $annotations") - } - val message = s"$tname is deprecated: $annotationMessage" - val transformedExpr = q""" { + val transformed = annottees.map(annottee => + annottee match { + case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => { + val Modifiers(_, _, annotations) = mods + val annotationMessage = annotations.collect { // get all messages from deprecated annotations + case q"new deprecated($desc, $since)" => desc + } match { // ensure there's only one and return it + case msg :: Nil => msg + case _ => + c.abort( + c.enclosingPosition, + s"@chiselRuntimeDeprecated annotion must be used with exactly one @deprecated annotation, got annotations $annotations" + ) + } + val message = s"$tname is deprecated: $annotationMessage" + val transformedExpr = q""" { _root_.chisel3.internal.Builder.deprecated($message) $expr } """ - q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr" + q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr" + } + case other => + c.abort( + c.enclosingPosition, + s"@chiselRuntimeDeprecated annotion may only be used on defs, got ${showCode(other)}" + ) } - case other => c.abort(c.enclosingPosition, s"@chiselRuntimeDeprecated annotion may only be used on defs, got ${showCode(other)}") - }) + ) q"..$transformed" } } diff --git a/macros/src/main/scala/chisel3/internal/naming/NamingAnnotations.scala b/macros/src/main/scala/chisel3/internal/naming/NamingAnnotations.scala index 0c400a07..82223d78 100644 --- a/macros/src/main/scala/chisel3/internal/naming/NamingAnnotations.scala +++ b/macros/src/main/scala/chisel3/internal/naming/NamingAnnotations.scala @@ -13,7 +13,7 @@ package chisel3.internal.naming import scala.reflect.macros.whitebox.Context -import scala.annotation.{StaticAnnotation, compileTimeOnly} +import scala.annotation.{compileTimeOnly, StaticAnnotation} import scala.language.experimental.macros // Workaround for https://github.com/sbt/sbt/issues/3966 @@ -79,13 +79,13 @@ class NamingTransforms(val c: Context) { class ClassBodyTransformer(val contextVar: TermName) extends ValNameTransformer { override def transform(tree: Tree): Tree = tree match { case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => - tree // don't recurse into inner classes + tree // don't recurse into inner classes case q"$mods trait $tpname[..$tparams] extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => - tree // don't recurse into inner classes + tree // don't recurse into inner classes case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => { val Modifiers(_, _, annotations) = mods // don't apply naming transform twice - val containsChiselName = annotations.map({q"new chiselName()" equalsStructure _}).fold(false)({_||_}) + val containsChiselName = annotations.map({ q"new chiselName()" equalsStructure _ }).fold(false)({ _ || _ }) // transforming overloaded initializers causes errors, and the transform isn't helpful val isInitializer = tname == TermName("<init>") if (containsChiselName || isInitializer) { @@ -108,7 +108,7 @@ class NamingTransforms(val c: Context) { case q"return $expr" => q"return $globalNamingStack.popReturnContext($expr, $contextVar)" // Do not recurse into methods case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => tree - case other => super.transform(other) + case other => super.transform(other) } } @@ -163,26 +163,35 @@ class NamingTransforms(val c: Context) { def chiselName(annottees: c.Tree*): c.Tree = { var namedElts: Int = 0 - val transformed = annottees.map(annottee => annottee match { - case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => { - val transformedStats = transformClassBody(stats) - namedElts += 1 - q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$transformedStats }" - } - case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" => { - annottee // Don't fail noisly when a companion object is passed in with the actual class def - } - // Currently disallow on traits, this won't work well with inheritance. - case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => { - val transformedExpr = transformHierarchicalMethod(expr) - namedElts += 1 - q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr" + val transformed = annottees.map(annottee => + annottee match { + case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" => { + val transformedStats = transformClassBody(stats) + namedElts += 1 + q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$transformedStats }" + } + case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" => { + annottee // Don't fail noisly when a companion object is passed in with the actual class def + } + // Currently disallow on traits, this won't work well with inheritance. + case q"$mods def $tname[..$tparams](...$paramss): $tpt = $expr" => { + val transformedExpr = transformHierarchicalMethod(expr) + namedElts += 1 + q"$mods def $tname[..$tparams](...$paramss): $tpt = $transformedExpr" + } + case other => + c.abort( + c.enclosingPosition, + s"@chiselName annotion may only be used on classes and methods, got ${showCode(other)}" + ) } - case other => c.abort(c.enclosingPosition, s"@chiselName annotion may only be used on classes and methods, got ${showCode(other)}") - }) + ) if (namedElts != 1) { - c.abort(c.enclosingPosition, s"@chiselName annotation did not match exactly one valid tree, got:\r\n${annottees.map(tree => showCode(tree)).mkString("\r\n\r\n")}") + c.abort( + c.enclosingPosition, + s"@chiselName annotation did not match exactly one valid tree, got:\r\n${annottees.map(tree => showCode(tree)).mkString("\r\n\r\n")}" + ) } q"..$transformed" diff --git a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala index ac3e236c..01e0acd6 100644 --- a/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala +++ b/macros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala @@ -9,7 +9,6 @@ import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context import scala.reflect.macros.whitebox - /** Transforms a function call so that it can both provide implicit-style source information and * have a chained apply call. Without macros, only one is possible, since having a implicit * argument in the definition will cause the compiler to interpret a chained apply as an @@ -65,7 +64,6 @@ class DefinitionWrapTransform(val c: Context) extends SourceInfoTransformMacro { } } - // Workaround for https://github.com/sbt/sbt/issues/3966 object InstanceTransform // Module instantiation transform @@ -138,7 +136,7 @@ class VecTransform(val c: Context) extends SourceInfoTransformMacro { def reduceTree(redOp: c.Tree, layerOp: c.Tree): c.Tree = { q"$thisObj.do_reduceTree($redOp,$layerOp)($implicitSourceInfo, $implicitCompileOptions)" } - def reduceTreeDefault(redOp: c.Tree ): c.Tree = { + def reduceTreeDefault(redOp: c.Tree): c.Tree = { q"$thisObj.do_reduceTree($redOp)($implicitSourceInfo, $implicitCompileOptions)" } } @@ -148,13 +146,17 @@ class VecTransform(val c: Context) extends SourceInfoTransformMacro { */ abstract class AutoSourceTransform extends SourceInfoTransformMacro { import c.universe._ + /** Returns the TermName of the transformed function, which is the applied function name with do_ * prepended. */ def doFuncTerm: TermName = { val funcName = c.macroApplication match { case q"$_.$funcName[..$_](...$_)" => funcName - case _ => throw new Exception(s"Chisel Internal Error: Could not resolve function name from macro application: ${showCode(c.macroApplication)}") + case _ => + throw new Exception( + s"Chisel Internal Error: Could not resolve function name from macro application: ${showCode(c.macroApplication)}" + ) } TermName("do_" + funcName) } @@ -223,6 +225,7 @@ class CompileOptionsTransform(val c: Context) extends AutoSourceTransform { // Workaround for https://github.com/sbt/sbt/issues/3966 object SourceInfoWhiteboxTransform + /** Special whitebox version of the blackbox SourceInfoTransform, used when fun things need to * happen to satisfy the type system while preventing the use of macro overrides. */ diff --git a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala index e56380a1..2d3a2cae 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/BundleComponent.scala @@ -70,11 +70,9 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi (primaryConstructor, paramAccessors.toList) } - override def transform(tree: Tree): Tree = tree match { case bundle: ClassDef if isBundle(bundle.symbol) && !bundle.mods.hasFlag(Flag.ABSTRACT) => - // ==================== Generate _cloneTypeImpl ==================== val (con, params) = getConstructorAndParams(bundle.impl.body) if (con.isEmpty) { @@ -99,13 +97,14 @@ private[plugin] class BundleComponent(val global: Global, arguments: ChiselPlugi if (isData(vp.symbol)) cloneTypeFull(select) else select }) - val tparamList = bundle.tparams.map{ t => Ident(t.symbol) } - val ttpe = if(tparamList.nonEmpty) AppliedTypeTree(Ident(bundle.symbol), tparamList) else Ident(bundle.symbol) + val tparamList = bundle.tparams.map { t => Ident(t.symbol) } + val ttpe = if (tparamList.nonEmpty) AppliedTypeTree(Ident(bundle.symbol), tparamList) else Ident(bundle.symbol) val newUntyped = New(ttpe, conArgs) val neww = localTyper.typed(newUntyped) // Create the symbol for the method and have it be associated with the Bundle class - val cloneTypeSym = bundle.symbol.newMethod(TermName("_cloneTypeImpl"), bundle.symbol.pos.focus, Flag.OVERRIDE | Flag.PROTECTED) + val cloneTypeSym = + bundle.symbol.newMethod(TermName("_cloneTypeImpl"), bundle.symbol.pos.focus, Flag.OVERRIDE | Flag.PROTECTED) // Handwritten cloneTypes don't have the Method flag set, unclear if it matters cloneTypeSym.resetFlag(Flags.METHOD) // Need to set the type to chisel3.Bundle for the override to work diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala index cee11df5..eced652b 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselComponent.scala @@ -11,7 +11,9 @@ import scala.tools.nsc.transform.TypingTransformers // The component of the chisel plugin. Not sure exactly what the difference is between // a Plugin and a PluginComponent. -class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) extends PluginComponent with TypingTransformers { +class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) + extends PluginComponent + with TypingTransformers { import global._ val runsAfter: List[String] = List[String]("typer") val phaseName: String = "chiselcomponent" @@ -25,8 +27,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte } } - class MyTypingTransformer(unit: CompilationUnit) - extends TypingTransformer(unit) { + class MyTypingTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { private def shouldMatchGen(bases: Tree*): Type => Boolean = { val cache = mutable.HashMap.empty[Type, Boolean] @@ -51,7 +52,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte recShouldMatch(s.typeArgs.head, seen + s) } else { // This is the standard inheritance hierarchy, Scalac catches loops here - s.parents.exists( p => recShouldMatch(p, seen) ) + s.parents.exists(p => recShouldMatch(p, seen)) } } @@ -62,24 +63,25 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // Return function so that it captures the cache { q: Type => - cache.getOrElseUpdate(q, { - // First check if a match, then check early exit, then recurse - if(terminate(q)){ - true - } else if(earlyExit(q)) { - false - } else { - recShouldMatch(q, Set.empty) + cache.getOrElseUpdate( + q, { + // First check if a match, then check early exit, then recurse + if (terminate(q)) { + true + } else if (earlyExit(q)) { + false + } else { + recShouldMatch(q, Set.empty) + } } - }) + ) } } - - private val shouldMatchData : Type => Boolean = shouldMatchGen(tq"chisel3.Data") - private val shouldMatchDataOrMem : Type => Boolean = shouldMatchGen(tq"chisel3.Data", tq"chisel3.MemBase[_]") - private val shouldMatchModule : Type => Boolean = shouldMatchGen(tq"chisel3.experimental.BaseModule") - private val shouldMatchInstance : Type => Boolean = shouldMatchGen(tq"chisel3.experimental.hierarchy.Instance[_]") + private val shouldMatchData: Type => Boolean = shouldMatchGen(tq"chisel3.Data") + private val shouldMatchDataOrMem: Type => Boolean = shouldMatchGen(tq"chisel3.Data", tq"chisel3.MemBase[_]") + private val shouldMatchModule: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.BaseModule") + private val shouldMatchInstance: Type => Boolean = shouldMatchGen(tq"chisel3.experimental.hierarchy.Instance[_]") // Given a type tree, infer the type and return it private def inferType(t: Tree): Type = localTyper.typed(t, nsc.Mode.TYPEmode).tpe @@ -97,13 +99,13 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte Flags.CASEACCESSOR, Flags.PARAMACCESSOR ) - badFlags.forall{ x => !mods.hasFlag(x)} + badFlags.forall { x => !mods.hasFlag(x) } } // Ensure expression isn't null, as you can't call `null.autoName("myname")` val isNull = dd.rhs match { case Literal(Constant(null)) => true - case _ => false + case _ => false } okFlags(dd.mods) && !isNull && dd.rhs != EmptyTree @@ -130,7 +132,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // Ensure expression isn't null, as you can't call `null.autoName("myname")` val isNull = dd.rhs match { case Literal(Constant(null)) => true - case _ => false + case _ => false } val tpe = inferType(dd.tpt) definitions.isTupleType(tpe) && okFlags(dd.mods) && !isNull && dd.rhs != EmptyTree @@ -139,7 +141,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte private def findUnapplyNames(tree: Tree): Option[List[String]] = { val applyArgs: Option[List[Tree]] = tree match { case Match(_, List(CaseDef(_, _, Apply(_, args)))) => Some(args) - case _ => None + case _ => None } applyArgs.flatMap { args => var ok = true @@ -147,7 +149,7 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte args.foreach { case Ident(TermName(name)) => result += name // Anything unexpected and we abort - case _ => ok = false + case _ => ok = false } if (ok) Some(result.toList) else None } @@ -169,9 +171,9 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte // If a Data and in a Bundle, just get the name but not a prefix if (shouldMatchData(tpe) && inBundle(dd)) { val str = stringFromTermName(name) - val newRHS = transform(rhs) // chisel3.internal.plugin.autoNameRecursively + val newRHS = transform(rhs) // chisel3.internal.plugin.autoNameRecursively val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } // If a Data or a Memory, get the name and a prefix else if (shouldMatchDataOrMem(tpe)) { @@ -179,18 +181,18 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte val newRHS = transform(rhs) val prefixed = q"chisel3.experimental.prefix.apply[$tpt](name=$str)(f=$newRHS)" val named = q"chisel3.internal.plugin.autoNameRecursively($str)($prefixed)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) // If an instance, just get a name but no prefix } else if (shouldMatchModule(tpe)) { val str = stringFromTermName(name) val newRHS = transform(rhs) val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } else if (shouldMatchInstance(tpe)) { val str = stringFromTermName(name) val newRHS = transform(rhs) val named = q"chisel3.internal.plugin.autoNameRecursively($str)($newRHS)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) } else { // Otherwise, continue super.transform(tree) @@ -202,9 +204,10 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments) exte if (fieldsOfInterest.reduce(_ || _)) { findUnapplyNames(rhs) match { case Some(names) => - val onames: List[Option[String]] = fieldsOfInterest.zip(names).map { case (ok, name) => if (ok) Some(name) else None } + val onames: List[Option[String]] = + fieldsOfInterest.zip(names).map { case (ok, name) => if (ok) Some(name) else None } val named = q"chisel3.internal.plugin.autoNameRecursivelyProduct($onames)($rhs)" - treeCopy.ValDef(dd, mods, name, tpt, localTyper typed named) + treeCopy.ValDef(dd, mods, name, tpt, localTyper.typed(named)) case None => // It's not clear how this could happen but we don't want to crash super.transform(tree) } diff --git a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala index eadb76b6..bd02d50c 100644 --- a/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala +++ b/plugin/src/main/scala/chisel3/internal/plugin/ChiselPlugin.scala @@ -21,7 +21,11 @@ object ChiselPlugin { val name = "chiselplugin" // Also logs why the compoennt was not run - private[plugin] def runComponent(global: Global, arguments: ChiselPluginArguments)(unit: global.CompilationUnit): Boolean = { + private[plugin] def runComponent( + global: Global, + arguments: ChiselPluginArguments + )(unit: global.CompilationUnit + ): Boolean = { // This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow, // instead we just check the version and if its an early Scala version, the plugin does nothing val scalaVersion = scala.util.Properties.versionNumberString.split('.') @@ -70,6 +74,4 @@ class ChiselPlugin(val global: Global) extends Plugin { true } - } - diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index aa379629..30a97df6 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -17,7 +17,8 @@ trait BackendCompilationUtilities extends LazyLogging { lazy val TestDirectory = FirrtlBackendCompilationUtilities.TestDirectory def timeStamp: String = FirrtlBackendCompilationUtilities.timeStamp def loggingProcessLogger: ProcessLogger = FirrtlBackendCompilationUtilities.loggingProcessLogger - def copyResourceToFile(name: String, file: File): Unit = FirrtlBackendCompilationUtilities.copyResourceToFile(name, file) + def copyResourceToFile(name: String, file: File): Unit = + FirrtlBackendCompilationUtilities.copyResourceToFile(name, file) def createTestDirectory(testName: String): File = FirrtlBackendCompilationUtilities.createTestDirectory(testName) def makeHarness(template: String => String, post: String)(f: File): File = FirrtlBackendCompilationUtilities.makeHarness(template, post)(f) @@ -98,10 +99,9 @@ trait BackendCompilationUtilities extends LazyLogging { import firrtl.stage.FirrtlCircuitAnnotation options.collectFirst { case a: FirrtlCircuitAnnotation => a.circuit } match { - case None => false + case None => false case Some(_) => true } // ********************************************************************************************* } } - diff --git a/src/main/scala/chisel3/aop/AspectLibrary.scala b/src/main/scala/chisel3/aop/AspectLibrary.scala index 1a16b61f..04ac2384 100644 --- a/src/main/scala/chisel3/aop/AspectLibrary.scala +++ b/src/main/scala/chisel3/aop/AspectLibrary.scala @@ -8,7 +8,7 @@ import firrtl.options.{OptionsException, RegisteredLibrary, ShellOption} /** Enables adding aspects to a design from the commandline, e.g. * sbt> runMain chisel3.stage.ChiselMain --module <module> --with-aspect <aspect> */ -final class AspectLibrary() extends RegisteredLibrary { +final class AspectLibrary() extends RegisteredLibrary { val name = "AspectLibrary" import scala.reflect.runtime.universe._ @@ -34,16 +34,20 @@ final class AspectLibrary() extends RegisteredLibrary { throw new OptionsException(s"Unable to locate aspect '$aspectName'! (Did you misspell it?)", e) case e: InstantiationException => throw new OptionsException( - s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)", e) + s"Unable to create instance of aspect '$aspectName'! (Does this class take parameters?)", + e + ) } } - val options = Seq(new ShellOption[String]( - longOption = "with-aspect", - toAnnotationSeq = { - case aspectName: String => Seq(apply(aspectName)) - }, - helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)", - helpValueName = Some("<package>.<aspect>") - )) + val options = Seq( + new ShellOption[String]( + longOption = "with-aspect", + toAnnotationSeq = { + case aspectName: String => Seq(apply(aspectName)) + }, + helpText = "The name/class of an aspect to compile with (must be a class/object without arguments!)", + helpValueName = Some("<package>.<aspect>") + ) + ) } diff --git a/src/main/scala/chisel3/aop/Select.scala b/src/main/scala/chisel3/aop/Select.scala index 6bd13445..3a2a8931 100644 --- a/src/main/scala/chisel3/aop/Select.scala +++ b/src/main/scala/chisel3/aop/Select.scala @@ -47,17 +47,18 @@ object Select { */ def instancesIn(parent: Hierarchy[BaseModule]): Seq[Instance[BaseModule]] = { check(parent) - implicit val mg = new chisel3.internal.MacroGenerated{} + implicit val mg = new chisel3.internal.MacroGenerated {} parent.proto._component.get match { - case d: DefModule => d.commands.collect { - case d: DefInstance => - d.id match { - case p: chisel3.internal.BaseModule.IsClone[_] => - parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] } - case other: BaseModule => - parent._lookup { x => other } - } - } + case d: DefModule => + d.commands.collect { + case d: DefInstance => + d.id match { + case p: chisel3.internal.BaseModule.IsClone[_] => + parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] } + case other: BaseModule => + parent._lookup { x => other } + } + } case other => Nil } } @@ -66,25 +67,26 @@ object Select { * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class. * @note IMPORTANT: this function ignores type parameters. E.g. instancesOf[List[Int]] would return List[String]. - * + * * @param parent hierarchy which instantiates the returned Definitions */ - def instancesOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = { + def instancesOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Instance[T]] = { check(parent) - implicit val mg = new chisel3.internal.MacroGenerated{} + implicit val mg = new chisel3.internal.MacroGenerated {} parent.proto._component.get match { - case d: DefModule => d.commands.flatMap { - case d: DefInstance => - d.id match { - case p: chisel3.internal.BaseModule.IsClone[_] => - val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] } - if(i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None - case other: BaseModule => - val i = parent._lookup { x => other } - if(i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None - } - case other => None - } + case d: DefModule => + d.commands.flatMap { + case d: DefInstance => + d.id match { + case p: chisel3.internal.BaseModule.IsClone[_] => + val i = parent._lookup { x => new Instance(Clone(p)).asInstanceOf[Instance[BaseModule]] } + if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None + case other: BaseModule => + val i = parent._lookup { x => other } + if (i.isA[T]) Some(i.asInstanceOf[Instance[T]]) else None + } + case other => None + } case other => Nil } } @@ -96,39 +98,40 @@ object Select { * * @param root top of the hierarchy to search for instances/modules of given type */ - def allInstancesOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = { - val soFar = if(root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil + def allInstancesOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Instance[T]] = { + val soFar = if (root.isA[T]) Seq(root.toInstance.asInstanceOf[Instance[T]]) else Nil val allLocalInstances = instancesIn(root) soFar ++ (allLocalInstances.flatMap(allInstancesOf[T])) } /** Selects the Definitions of all instances/modules directly instantiated within given module - * + * * @param parent */ def definitionsIn(parent: Hierarchy[BaseModule]): Seq[Definition[BaseModule]] = { type DefType = Definition[BaseModule] - implicit val mg = new chisel3.internal.MacroGenerated{} + implicit val mg = new chisel3.internal.MacroGenerated {} check(parent) val defs = parent.proto._component.get match { - case d: DefModule => d.commands.collect { - case i: DefInstance => - i.id match { - case p: chisel3.internal.BaseModule.IsClone[_] => - parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] } - case other: BaseModule => - parent._lookup { x => other.toDefinition } - } - } + case d: DefModule => + d.commands.collect { + case i: DefInstance => + i.id match { + case p: chisel3.internal.BaseModule.IsClone[_] => + parent._lookup { x => new Definition(Proto(p.getProto)).asInstanceOf[Definition[BaseModule]] } + case other: BaseModule => + parent._lookup { x => other.toDefinition } + } + } case other => Nil } - val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { case ((set, list), definition: Definition[BaseModule]) => - if(set.contains(definition)) (set, list) else (set + definition, definition +: list) + val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { + case ((set, list), definition: Definition[BaseModule]) => + if (set.contains(definition)) (set, list) else (set + definition, definition +: list) } defList.reverse } - /** Selects all Definitions of instances/modules directly instantiated within given module, of provided type * * @note IMPORTANT: this function requires summoning a TypeTag[T], which will fail if T is an inner class. @@ -136,26 +139,28 @@ object Select { * * @param parent hierarchy which instantiates the returned Definitions */ - def definitionsOf[T <: BaseModule : TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = { + def definitionsOf[T <: BaseModule: TypeTag](parent: Hierarchy[BaseModule]): Seq[Definition[T]] = { check(parent) - implicit val mg = new chisel3.internal.MacroGenerated{} + implicit val mg = new chisel3.internal.MacroGenerated {} type DefType = Definition[T] val defs = parent.proto._component.get match { - case d: DefModule => d.commands.flatMap { - case d: DefInstance => - d.id match { - case p: chisel3.internal.BaseModule.IsClone[_] => - val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] } - if(d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None - case other: BaseModule => - val d = parent._lookup { x => other.toDefinition } - if(d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None - } - case other => None - } + case d: DefModule => + d.commands.flatMap { + case d: DefInstance => + d.id match { + case p: chisel3.internal.BaseModule.IsClone[_] => + val d = parent._lookup { x => new Definition(Clone(p)).asInstanceOf[Definition[BaseModule]] } + if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None + case other: BaseModule => + val d = parent._lookup { x => other.toDefinition } + if (d.isA[T]) Some(d.asInstanceOf[Definition[T]]) else None + } + case other => None + } } - val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { case ((set, list), definition: Definition[T]) => - if(set.contains(definition)) (set, list) else (set + definition, definition +: list) + val (_, defList) = defs.foldLeft((Set.empty[DefType], List.empty[DefType])) { + case ((set, list), definition: Definition[T]) => + if (set.contains(definition)) (set, list) else (set + definition, definition +: list) } defList.reverse } @@ -168,14 +173,14 @@ object Select { * * @param root top of the hierarchy to search for definitions of given type */ - def allDefinitionsOf[T <: BaseModule : TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = { + def allDefinitionsOf[T <: BaseModule: TypeTag](root: Hierarchy[BaseModule]): Seq[Definition[T]] = { type DefType = Definition[T] val allDefSet = mutable.HashSet[Definition[BaseModule]]() val defSet = mutable.HashSet[DefType]() val defList = mutable.ArrayBuffer[DefType]() def rec(hier: Definition[BaseModule]): Unit = { - if(hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) { - defSet += hier.asInstanceOf[DefType] + if (hier.isA[T] && !defSet.contains(hier.asInstanceOf[DefType])) { + defSet += hier.asInstanceOf[DefType] defList += hier.asInstanceOf[DefType] } allDefSet += hier @@ -188,7 +193,6 @@ object Select { defList.toList } - /** Collects all components selected by collector within module and all children modules it instantiates * directly or indirectly * Accepts a collector function, rather than a collector partial function (see [[collectDeep]]) @@ -203,8 +207,8 @@ object Select { def getDeep[T](module: BaseModule)(collector: BaseModule => Seq[T]): Seq[T] = { check(module) val myItems = collector(module) - val deepChildrenItems = instances(module).flatMap { - i => getDeep(i)(collector) + val deepChildrenItems = instances(module).flatMap { i => + getDeep(i)(collector) } myItems ++ deepChildrenItems } @@ -223,8 +227,8 @@ object Select { def collectDeep[T](module: BaseModule)(collector: PartialFunction[BaseModule, T]): Iterable[T] = { check(module) val myItems = collector.lift(module) - val deepChildrenItems = instances(module).flatMap { - i => collectDeep(i)(collector) + val deepChildrenItems = instances(module).flatMap { i => + collectDeep(i)(collector) } myItems ++ deepChildrenItems } @@ -238,14 +242,19 @@ object Select { def instances(module: BaseModule): Seq[BaseModule] = { check(module) module._component.get match { - case d: DefModule => d.commands.flatMap { - case i: DefInstance => i.id match { - case m: ModuleClone[_] if !m._madeFromDefinition => None - case _: PseudoModule => throw new Exception("instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!") - case other => Some(other) + case d: DefModule => + d.commands.flatMap { + case i: DefInstance => + i.id match { + case m: ModuleClone[_] if !m._madeFromDefinition => None + case _: PseudoModule => + throw new Exception( + "instances, collectDeep, and getDeep are currently incompatible with Definition/Instance!" + ) + case other => Some(other) + } + case _ => None } - case _ => None - } case other => Nil } } @@ -256,7 +265,7 @@ object Select { def registers(module: BaseModule): Seq[Data] = { check(module) module._component.get.asInstanceOf[DefModule].commands.collect { - case r: DefReg => r.id + case r: DefReg => r.id case r: DefRegInit => r.id } } @@ -274,7 +283,7 @@ object Select { */ def ios[T <: BaseModule](parent: Hierarchy[T]): Seq[Data] = { check(parent) - implicit val mg = new chisel3.internal.MacroGenerated{} + implicit val mg = new chisel3.internal.MacroGenerated {} parent._lookup { x => ios(parent.proto) } } @@ -366,9 +375,14 @@ object Select { */ def attachedTo(module: BaseModule)(signal: Data): Set[Data] = { check(module) - module._component.get.asInstanceOf[DefModule].commands.collect { - case Attach(_, seq) if seq.contains(signal) => seq - }.flatMap { seq => seq.map(_.id.asInstanceOf[Data]) }.toSet + module._component.get + .asInstanceOf[DefModule] + .commands + .collect { + case Attach(_, seq) if seq.contains(signal) => seq + } + .flatMap { seq => seq.map(_.id.asInstanceOf[Data]) } + .toSet } /** Selects all connections to a signal or its parent signal(s) (if the signal is an element of an aggregate signal) @@ -382,31 +396,42 @@ object Select { check(module) val sensitivitySignals = getIntermediateAndLeafs(signal).toSet val predicatedConnects = mutable.ArrayBuffer[PredicatedConnect]() - val isPort = module._component.get.asInstanceOf[DefModule].ports.flatMap{ p => getIntermediateAndLeafs(p.id) }.contains(signal) + val isPort = module._component.get + .asInstanceOf[DefModule] + .ports + .flatMap { p => getIntermediateAndLeafs(p.id) } + .contains(signal) var prePredicates: Seq[Predicate] = Nil var seenDef = isPort - searchWhens(module, (cmd: Command, preds) => { - cmd match { - case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] => - val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data]) - if(x.contains(signal)) prePredicates = preds - case Connect(_, loc@Node(d: Data), exp) => - val effected = getEffected(loc).toSet - if(sensitivitySignals.intersect(effected).nonEmpty) { - val expData = getData(exp) - prePredicates.reverse.zip(preds.reverse).foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal")) - predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false) - } - case BulkConnect(_, loc@Node(d: Data), exp) => - val effected = getEffected(loc).toSet - if(sensitivitySignals.intersect(effected).nonEmpty) { - val expData = getData(exp) - prePredicates.reverse.zip(preds.reverse).foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal")) - predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true) - } - case other => + searchWhens( + module, + (cmd: Command, preds) => { + cmd match { + case cmd: DefinitionIR if cmd.id.isInstanceOf[Data] => + val x = getIntermediateAndLeafs(cmd.id.asInstanceOf[Data]) + if (x.contains(signal)) prePredicates = preds + case Connect(_, loc @ Node(d: Data), exp) => + val effected = getEffected(loc).toSet + if (sensitivitySignals.intersect(effected).nonEmpty) { + val expData = getData(exp) + prePredicates.reverse + .zip(preds.reverse) + .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal")) + predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = false) + } + case BulkConnect(_, loc @ Node(d: Data), exp) => + val effected = getEffected(loc).toSet + if (sensitivitySignals.intersect(effected).nonEmpty) { + val expData = getData(exp) + prePredicates.reverse + .zip(preds.reverse) + .foreach(x => assert(x._1 == x._2, s"Prepredicates $x must match for signal $signal")) + predicatedConnects += PredicatedConnect(preds.dropRight(prePredicates.size), d, expData, isBulk = true) + } + case other => + } } - }) + ) predicatedConnects.toSeq } @@ -414,14 +439,18 @@ object Select { * * @param module */ - def stops(module: BaseModule): Seq[Stop] = { + def stops(module: BaseModule): Seq[Stop] = { val stops = mutable.ArrayBuffer[Stop]() - searchWhens(module, (cmd: Command, preds: Seq[Predicate]) => { - cmd match { - case chisel3.internal.firrtl.Stop(_, _, clock, ret) => stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock]) - case other => + searchWhens( + module, + (cmd: Command, preds: Seq[Predicate]) => { + cmd match { + case chisel3.internal.firrtl.Stop(_, _, clock, ret) => + stops += Stop(preds, ret, getId(clock).asInstanceOf[Clock]) + case other => + } } - }) + ) stops.toSeq } @@ -431,12 +460,16 @@ object Select { */ def printfs(module: BaseModule): Seq[Printf] = { val printfs = mutable.ArrayBuffer[Printf]() - searchWhens(module, (cmd: Command, preds: Seq[Predicate]) => { - cmd match { - case chisel3.internal.firrtl.Printf(id, _, clock, pable) => printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock]) - case other => + searchWhens( + module, + (cmd: Command, preds: Seq[Predicate]) => { + cmd match { + case chisel3.internal.firrtl.Printf(id, _, clock, pable) => + printfs += Printf(id, preds, pable, getId(clock).asInstanceOf[Clock]) + case other => + } } - }) + ) printfs.toSeq } @@ -450,15 +483,15 @@ object Select { // Given a loc, return all subcomponents of id that could be assigned to in connect private def getEffected(a: Arg): Seq[Data] = a match { case Node(id: Data) => getIntermediateAndLeafs(id) - case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name)) + case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name)) case Index(imm, value) => getEffected(imm) } // Given an arg, return the corresponding id. Don't use on a loc of a connect. private def getId(a: Arg): HasId = a match { case Node(id) => id - case l: ULit => l.num.U(l.w) - case l: SLit => l.num.S(l.w) + case l: ULit => l.num.U(l.w) + case l: SLit => l.num.S(l.w) case l: FPLit => FixedPoint(l.num, l.w, l.binaryPoint) case other => sys.error(s"Something went horribly wrong! I was expecting ${other} to be a lit or a node!") @@ -478,9 +511,10 @@ object Select { str.splitAt(str.indexOf('>'))._2.drop(1) } } catch { - case e: ChiselException => i.getOptionRef.get match { - case l: LitArg => l.num.intValue.toString - } + case e: ChiselException => + i.getOptionRef.get match { + case l: LitArg => l.num.intValue.toString + } } // Collects when predicates as it searches through a module, then applying processCommand to non-when related commands @@ -489,21 +523,22 @@ object Select { module._component.get.asInstanceOf[DefModule].commands.foldLeft((Seq.empty[Predicate], Option.empty[Predicate])) { (blah, cmd) => (blah, cmd) match { - case ((preds, o), cmd) => cmd match { - case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None) - case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None) - case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None) - case other: WhenBegin => - sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!") - case _: WhenEnd => (preds.tail, Some(preds.head)) - case AltBegin(_) if o.isDefined => (o.get.not +: preds, o) - case _: AltBegin => - sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!") - case OtherwiseEnd(_, _) => (preds.tail, None) - case other => - processCommand(cmd, preds) - (preds, o) - } + case ((preds, o), cmd) => + cmd match { + case WhenBegin(_, Node(pred: Bool)) => (When(pred) +: preds, None) + case WhenBegin(_, l: LitArg) if l.num == BigInt(1) => (When(true.B) +: preds, None) + case WhenBegin(_, l: LitArg) if l.num == BigInt(0) => (When(false.B) +: preds, None) + case other: WhenBegin => + sys.error(s"Something went horribly wrong! I was expecting ${other.pred} to be a lit or a bool!") + case _: WhenEnd => (preds.tail, Some(preds.head)) + case AltBegin(_) if o.isDefined => (o.get.not +: preds, o) + case _: AltBegin => + sys.error(s"Something went horribly wrong! I was expecting ${o} to be nonEmpty!") + case OtherwiseEnd(_, _) => (preds.tail, None) + case other => + processCommand(cmd, preds) + (preds, o) + } } } } @@ -524,7 +559,7 @@ object Select { * @param bool the when predicate */ case class When(bool: Bool) extends Predicate { - def not: WhenNot = WhenNot(bool) + def not: WhenNot = WhenNot(bool) def serialize: String = s"${getName(bool)}" } @@ -533,7 +568,7 @@ object Select { * @param bool the when predicate corresponding to this otherwise predicate */ case class WhenNot(bool: Bool) extends Predicate { - def not: When = When(bool) + def not: When = When(bool) def serialize: String = s"!${getName(bool)}" } @@ -549,7 +584,7 @@ object Select { case class PredicatedConnect(preds: Seq[Predicate], loc: Data, exp: Data, isBulk: Boolean) extends Serializeable { def serialize: String = { val moduleTarget = loc.toTarget.moduleTarget.serialize - s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if(isBulk) "<>" else ":="} ${getName(exp)}" + s"$moduleTarget: when(${preds.map(_.serialize).mkString(" & ")}): ${getName(loc)} ${if (isBulk) "<>" else ":="} ${getName(exp)}" } } diff --git a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala index 92e24ba1..dbe1fd7b 100644 --- a/src/main/scala/chisel3/aop/injecting/InjectStatement.scala +++ b/src/main/scala/chisel3/aop/injecting/InjectStatement.scala @@ -15,7 +15,12 @@ import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleT * @param modules Additional modules that may be instantiated by s * @param annotations Additional annotations that should be passed down compiler */ -case class InjectStatement(module: ModuleTarget, s: firrtl.ir.Statement, modules: Seq[firrtl.ir.DefModule], annotations: Seq[Annotation]) extends SingleTargetAnnotation[ModuleTarget] { +case class InjectStatement( + module: ModuleTarget, + s: firrtl.ir.Statement, + modules: Seq[firrtl.ir.DefModule], + annotations: Seq[Annotation]) + extends SingleTargetAnnotation[ModuleTarget] { val target: ModuleTarget = module override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n) } diff --git a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala index ed59d4fb..abe208cf 100644 --- a/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala +++ b/src/main/scala/chisel3/aop/injecting/InjectingAspect.scala @@ -2,7 +2,7 @@ package chisel3.aop.injecting -import chisel3.{Module, ModuleAspect, RawModule, withClockAndReset} +import chisel3.{withClockAndReset, Module, ModuleAspect, RawModule} import chisel3.aop._ import chisel3.internal.{Builder, DynamicContext} import chisel3.internal.firrtl.DefModule @@ -22,12 +22,12 @@ import scala.collection.mutable * @tparam M Type of root module (join point) */ case class InjectingAspect[T <: RawModule, M <: RawModule]( - selectRoots: T => Iterable[M], - injection: M => Unit -) extends InjectorAspect[T, M]( - selectRoots, - injection -) + selectRoots: T => Iterable[M], + injection: M => Unit) + extends InjectorAspect[T, M]( + selectRoots, + injection + ) /** Extend to inject Chisel code into a module of type M * @@ -38,11 +38,12 @@ case class InjectingAspect[T <: RawModule, M <: RawModule]( * @tparam M Type of root module (join point) */ abstract class InjectorAspect[T <: RawModule, M <: RawModule]( - selectRoots: T => Iterable[M], - injection: M => Unit -) extends Aspect[T] { + selectRoots: T => Iterable[M], + injection: M => Unit) + extends Aspect[T] { final def toAnnotation(top: T): AnnotationSeq = { - val moduleNames = Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map{i => i.toTarget.module }.toSeq + val moduleNames = + Select.allDefinitionsOf[chisel3.experimental.BaseModule](top.toDefinition).map { i => i.toTarget.module }.toSeq toAnnotation(selectRoots(top), top.name, moduleNames) } @@ -62,22 +63,26 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule]( dynamicContext.globalNamespace.name(n) } - val (chiselIR, _) = Builder.build(Module(new ModuleAspect(module) { - module match { - case x: Module => withClockAndReset(x.clock, x.reset) { injection(module) } - case x: RawModule => injection(module) - } - }), dynamicContext) + val (chiselIR, _) = Builder.build( + Module(new ModuleAspect(module) { + module match { + case x: Module => withClockAndReset(x.clock, x.reset) { injection(module) } + case x: RawModule => injection(module) + } + }), + dynamicContext + ) val comps = chiselIR.components.map { case x: DefModule if x.name == module.name => x.copy(id = module) case other => other } - val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot{ a => a.isInstanceOf[DesignAnnotation[_]] } + val annotations = chiselIR.annotations.map(_.toFirrtl).filterNot { a => a.isInstanceOf[DesignAnnotation[_]] } /** Statements to be injected via aspect. */ val stmts = mutable.ArrayBuffer[ir.Statement]() + /** Modules to be injected via aspect. */ val modules = Aspect.getFirrtl(chiselIR.copy(components = comps)).modules.flatMap { // for "container" modules, inject their statements @@ -93,4 +98,3 @@ abstract class InjectorAspect[T <: RawModule, M <: RawModule]( }.toSeq } } - diff --git a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala index cc5601b1..8a0b6ecb 100644 --- a/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala +++ b/src/main/scala/chisel3/aop/injecting/InjectingTransform.scala @@ -2,7 +2,7 @@ package chisel3.aop.injecting -import firrtl.{ChirrtlForm, CircuitForm, CircuitState, Transform, ir} +import firrtl.{ir, ChirrtlForm, CircuitForm, CircuitState, Transform} import scala.collection.mutable @@ -11,7 +11,7 @@ import scala.collection.mutable * Implemented with Chisel Aspects and the [[chisel3.aop.injecting]] library */ class InjectingTransform extends Transform { - override def inputForm: CircuitForm = ChirrtlForm + override def inputForm: CircuitForm = ChirrtlForm override def outputForm: CircuitForm = ChirrtlForm override def execute(state: CircuitState): CircuitState = { diff --git a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala index a9752426..1340f253 100644 --- a/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala +++ b/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala @@ -13,7 +13,6 @@ import firrtl.AnnotationSeq */ case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect) - /** Extend to make custom inspections of an elaborated design and printing out results * * @param inspect Given top-level design, print things and return nothing diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index ccb4ec1f..f3754e00 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -3,10 +3,10 @@ /** The Chisel compatibility package allows legacy users to continue using the `Chisel` (capital C) package name * while moving to the more standard package naming convention `chisel3` (lowercase c). */ -import chisel3._ // required for implicit conversions. +import chisel3._ // required for implicit conversions. import chisel3.experimental.chiselName import chisel3.util.random.FibonacciLFSR -import chisel3.stage.{ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage, phases} +import chisel3.stage.{phases, ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage} package object Chisel { import chisel3.internal.firrtl.Width @@ -23,23 +23,26 @@ package object Chisel { case object OUTPUT extends Direction case object NODIR extends Direction - val Input = chisel3.Input - val Output = chisel3.Output + val Input = chisel3.Input + val Output = chisel3.Output object Flipped { - def apply[T<:Data](target: T): T = chisel3.Flipped[T](target) + def apply[T <: Data](target: T): T = chisel3.Flipped[T](target) } - implicit class AddDirectionToData[T<:Data](target: T) { - def asInput: T = Input(target) + implicit class AddDirectionToData[T <: Data](target: T) { + def asInput: T = Input(target) def asOutput: T = Output(target) - def flip: T = Flipped(target) + def flip: T = Flipped(target) - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def flip(dummy: Int*): T = flip } - implicit class AddDirMethodToData[T<:Data](target: T) { + implicit class AddDirMethodToData[T <: Data](target: T) { import chisel3.ActualDirection import chisel3.experimental.DataMirror import chisel3.internal.requireIsHardware @@ -47,11 +50,12 @@ package object Chisel { def dir: Direction = { requireIsHardware(target) // This has the side effect of calling _autoWrapPorts target match { - case e: Element => DataMirror.directionOf(e) match { - case ActualDirection.Output => OUTPUT - case ActualDirection.Input => INPUT - case _ => NODIR - } + case e: Element => + DataMirror.directionOf(e) match { + case ActualDirection.Output => OUTPUT + case ActualDirection.Input => INPUT + case _ => NODIR + } case _ => NODIR } } @@ -81,9 +85,9 @@ package object Chisel { def apply(dir: Direction): Clock = { val result = apply() dir match { - case INPUT => Input(result) + case INPUT => Input(result) case OUTPUT => Output(result) - case _ => result + case _ => result } } } @@ -130,20 +134,33 @@ package object Chisel { apply(Seq.fill(n)(gen)) def apply[T <: Data](elts: Seq[T]): Vec[T] = macro VecTransform.apply_elts + /** @group SourceInfoTransformMacro */ def do_apply[T <: Data](elts: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = chisel3.VecInit(elts) def apply[T <: Data](elt0: T, elts: T*): Vec[T] = macro VecTransform.apply_elt0 + /** @group SourceInfoTransformMacro */ - def do_apply[T <: Data](elt0: T, elts: T*) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = + def do_apply[T <: Data]( + elt0: T, + elts: T* + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[T] = chisel3.VecInit(elt0 +: elts.toSeq) def tabulate[T <: Data](n: Int)(gen: (Int) => T): Vec[T] = macro VecTransform.tabulate + /** @group SourceInfoTransformMacro */ - def do_tabulate[T <: Data](n: Int)(gen: (Int) => T) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = + def do_tabulate[T <: Data]( + n: Int + )(gen: (Int) => T + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): Vec[T] = chisel3.VecInit.tabulate(n)(gen) } type Vec[T <: Data] = chisel3.Vec[T] @@ -157,8 +174,10 @@ package object Chisel { /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait UIntFactory extends chisel3.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) @@ -171,19 +190,21 @@ package object Chisel { /** 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 INPUT => Input(result) + case INPUT => Input(result) case OUTPUT => Output(result) - case NODIR => result + case NODIR => result } } @@ -197,13 +218,16 @@ package object Chisel { /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait SIntFactory extends chisel3.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) @@ -215,16 +239,18 @@ package object Chisel { /** 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 INPUT => Input(result) + case INPUT => Input(result) case OUTPUT => Output(result) - case NODIR => result + case NODIR => result } } } @@ -232,6 +258,7 @@ package object Chisel { /** This contains literal constructor factory methods that are deprecated as of Chisel3. */ trait BoolFactory extends chisel3.BoolFactory { + /** Creates Bool literal. */ def apply(x: Boolean): Bool = x.B @@ -240,9 +267,9 @@ package object Chisel { def apply(dir: Direction): Bool = { val result = apply() dir match { - case INPUT => Input(result) + case INPUT => Input(result) case OUTPUT => Output(result) - case NODIR => result + case NODIR => result } } } @@ -286,12 +313,22 @@ package object Chisel { implicit class SeqMemCompatibility(a: SeqMem.type) { import chisel3.internal.sourceinfo.SourceInfo - def apply[T <: Data](t: T, size: BigInt) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = + def apply[T <: Data]( + t: T, + size: BigInt + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SyncReadMem[T] = a.do_apply(size, t) - def apply[T <: Data](t: T, size: Int) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SyncReadMem[T] = + def apply[T <: Data]( + t: T, + size: Int + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SyncReadMem[T] = a.do_apply(size, t) } @@ -329,8 +366,14 @@ package object Chisel { * is a valid value. In those cases, you can either use the outType only Reg * constructor or pass in `null.asInstanceOf[T]`. */ - def apply[T <: Data](t: T = null, next: T = null, init: T = null) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = { + def apply[T <: Data]( + t: T = null, + next: T = null, + init: T = null + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { if (t ne null) { val reg = if (init ne null) { RegInit(t, init) @@ -386,19 +429,19 @@ package object Chisel { 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 = { + def run[T <: Module](args: Array[String], gen: () => T): Unit = { val circuit = ChiselStage.elaborate(gen()) parseArgs(args) val output_file = new File(target_dir.getOrElse(new File(".").getCanonicalPath) + "/" + circuit.name + ".fir") - (new phases.Emitter).transform(Seq(ChiselCircuitAnnotation(circuit), - ChiselOutputFileAnnotation(output_file.toString))) + (new phases.Emitter) + .transform(Seq(ChiselCircuitAnnotation(circuit), ChiselOutputFileAnnotation(output_file.toString))) } } @deprecated("debug doesn't do anything in Chisel3 as no pruning happens in the frontend", "chisel3") object debug { - def apply (arg: Data): Data = arg + def apply(arg: Data): Data = arg } // Deprecated as of Chsiel3 @@ -423,7 +466,7 @@ package object Chisel { object log2Up { def apply(in: BigInt): Int = { require(in >= 0) - 1 max (in-1).bitLength + 1.max((in - 1).bitLength) } def apply(in: Int): Int = apply(BigInt(in)) } @@ -431,7 +474,7 @@ package object Chisel { /** Compute the log2 rounded down with min value of 1 */ object log2Down { def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1) - def apply(in: Int): Int = apply(BigInt(in)) + def apply(in: Int): Int = apply(BigInt(in)) } val BitPat = chisel3.util.BitPat @@ -472,8 +515,13 @@ package object Chisel { val Queue = chisel3.util.Queue type Queue[T <: Data] = QueueCompatibility[T] - sealed class QueueCompatibility[T <: Data](gen: T, entries: Int, pipe: Boolean = false, flow: Boolean = false) - (implicit compileOptions: chisel3.CompileOptions) + sealed class QueueCompatibility[T <: Data]( + gen: T, + entries: Int, + pipe: Boolean = false, + flow: Boolean = false + )( + implicit compileOptions: chisel3.CompileOptions) extends chisel3.util.Queue[T](gen, entries, pipe, flow)(compileOptions) { def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, override_reset: Option[Bool]) = { @@ -489,6 +537,7 @@ package object Chisel { } 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. @@ -522,10 +571,10 @@ package object Chisel { * 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] = { + 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]] + (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]] } /** An old Enum API that returns a map of symbols to UInts. @@ -541,7 +590,7 @@ package object Chisel { 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]] + (l.zip(createValues(l.length))).toMap.asInstanceOf[Map[Symbol, T]] } } @@ -564,16 +613,18 @@ package object Chisel { * }}} */ object LFSR16 { + /** Generates a 16-bit linear feedback shift register, returning the register contents. * @param increment optional control to gate when the LFSR updates. */ @chiselName def apply(increment: Bool = true.B): UInt = - VecInit( FibonacciLFSR - .maxPeriod(16, increment, seed = Some(BigInt(1) << 15)) - .asBools - .reverse ) - .asUInt + VecInit( + FibonacciLFSR + .maxPeriod(16, increment, seed = Some(BigInt(1) << 15)) + .asBools + .reverse + ).asUInt } @@ -598,7 +649,6 @@ package object Chisel { val Pipe = chisel3.util.Pipe type Pipe[T <: Data] = chisel3.util.Pipe[T] - /** 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 @@ -638,7 +688,8 @@ package object Chisel { final def toUInt(implicit compileOptions: CompileOptions): UInt = a.do_asUInt(DeprecatedSourceInfo, compileOptions) - final def toBools(implicit compileOptions: CompileOptions): Seq[Bool] = a.do_asBools(DeprecatedSourceInfo, compileOptions) + final def toBools(implicit compileOptions: CompileOptions): Seq[Bool] = + a.do_asBools(DeprecatedSourceInfo, compileOptions) } } diff --git a/src/main/scala/chisel3/experimental/conversions/package.scala b/src/main/scala/chisel3/experimental/conversions/package.scala index 574f9f96..7374f223 100644 --- a/src/main/scala/chisel3/experimental/conversions/package.scala +++ b/src/main/scala/chisel3/experimental/conversions/package.scala @@ -1,4 +1,3 @@ - package chisel3.experimental import chisel3._ @@ -12,116 +11,229 @@ import scala.language.implicitConversions package object conversions { /** Implicit conversion between `Seq` and `Vec` */ - implicit def seq2vec[A : DataProduct, B <: Data](xs: Seq[A])(implicit dv: DataView[A, B]): Vec[B] = + implicit def seq2vec[A: DataProduct, B <: Data](xs: Seq[A])(implicit dv: DataView[A, B]): Vec[B] = xs.viewAs[Vec[B]] /** Implicit conversion between [[Tuple2]] and [[HWTuple2]] */ - implicit def tuple2hwtuple[T1 : DataProduct, T2 : DataProduct, V1 <: Data, V2 <: Data]( + implicit def tuple2hwtuple[T1: DataProduct, T2: DataProduct, V1 <: Data, V2 <: Data]( tup: (T1, T2) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2] ): HWTuple2[V1, V2] = { tup.viewAs[HWTuple2[V1, V2]] } /** Implicit conversion between [[Tuple3]] and [[HWTuple3]] */ - implicit def tuple3hwtuple[T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, V1 <: Data, V2 <: Data, V3 <: Data]( + implicit def tuple3hwtuple[T1: DataProduct, T2: DataProduct, T3: DataProduct, V1 <: Data, V2 <: Data, V3 <: Data]( tup: (T1, T2, T3) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3] ): HWTuple3[V1, V2, V3] = { tup.viewAs[HWTuple3[V1, V2, V3]] } /** Implicit conversion between [[Tuple4]] and [[HWTuple4]] */ implicit def tuple4hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data - ]( - tup: (T1, T2, T3, T4) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data + ](tup: (T1, T2, T3, T4) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4] ): HWTuple4[V1, V2, V3, V4] = { tup.viewAs[HWTuple4[V1, V2, V3, V4]] } /** Implicit conversion between [[Tuple5]] and [[HWTuple5]] */ implicit def tuple5hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data - ]( - tup: (T1, T2, T3, T4, T5) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data + ](tup: (T1, T2, T3, T4, T5) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5] ): HWTuple5[V1, V2, V3, V4, V5] = { tup.viewAs[HWTuple5[V1, V2, V3, V4, V5]] } /** Implicit conversion between [[Tuple6]] and [[HWTuple6]] */ implicit def tuple6hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, T6 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, V6 <: Data - ]( - tup: (T1, T2, T3, T4, T5, T6) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data + ](tup: (T1, T2, T3, T4, T5, T6) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], - v6: DataView[T6, V6] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6] ): HWTuple6[V1, V2, V3, V4, V5, V6] = { tup.viewAs[HWTuple6[V1, V2, V3, V4, V5, V6]] } /** Implicit conversion between [[Tuple7]] and [[HWTuple7]] */ implicit def tuple7hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, V6 <: Data, V7 <: Data - ]( - tup: (T1, T2, T3, T4, T5, T6, T7) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data + ](tup: (T1, T2, T3, T4, T5, T6, T7) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], - v6: DataView[T6, V6], v7: DataView[T7, V7] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7] ): HWTuple7[V1, V2, V3, V4, V5, V6, V7] = { tup.viewAs[HWTuple7[V1, V2, V3, V4, V5, V6, V7]] } /** Implicit conversion between [[Tuple8]] and [[HWTuple8]] */ implicit def tuple8hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, V6 <: Data, V7 <: Data, V8 <: Data - ]( - tup: (T1, T2, T3, T4, T5, T6, T7, T8) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data + ](tup: (T1, T2, T3, T4, T5, T6, T7, T8) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], - v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8] ): HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8] = { tup.viewAs[HWTuple8[V1, V2, V3, V4, V5, V6, V7, V8]] } /** Implicit conversion between [[Tuple9]] and [[HWTuple9]] */ implicit def tuple9hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, T9 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, V6 <: Data, V7 <: Data, V8 <: Data, V9 <: Data - ]( - tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + T9: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data, + V9 <: Data + ](tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], - v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8], v9: DataView[T9, V9] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8], + v9: DataView[T9, V9] ): HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9] = { tup.viewAs[HWTuple9[V1, V2, V3, V4, V5, V6, V7, V8, V9]] } /** Implicit conversion between [[Tuple10]] and [[HWTuple10]] */ implicit def tuple10hwtuple[ - T1 : DataProduct, T2 : DataProduct, T3 : DataProduct, T4 : DataProduct, T5 : DataProduct, - T6 : DataProduct, T7 : DataProduct, T8 : DataProduct, T9 : DataProduct, T10 : DataProduct, - V1 <: Data, V2 <: Data, V3 <: Data, V4 <: Data, V5 <: Data, V6 <: Data, V7 <: Data, V8 <: Data, V9 <: Data, V10 <: Data - ]( - tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) + T1: DataProduct, + T2: DataProduct, + T3: DataProduct, + T4: DataProduct, + T5: DataProduct, + T6: DataProduct, + T7: DataProduct, + T8: DataProduct, + T9: DataProduct, + T10: DataProduct, + V1 <: Data, + V2 <: Data, + V3 <: Data, + V4 <: Data, + V5 <: Data, + V6 <: Data, + V7 <: Data, + V8 <: Data, + V9 <: Data, + V10 <: Data + ](tup: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) )( - implicit v1: DataView[T1, V1], v2: DataView[T2, V2], v3: DataView[T3, V3], v4: DataView[T4, V4], v5: DataView[T5, V5], - v6: DataView[T6, V6], v7: DataView[T7, V7], v8: DataView[T8, V8], v9: DataView[T9, V9], v10: DataView[T10, V10] + implicit v1: DataView[T1, V1], + v2: DataView[T2, V2], + v3: DataView[T3, V3], + v4: DataView[T4, V4], + v5: DataView[T5, V5], + v6: DataView[T6, V6], + v7: DataView[T7, V7], + v8: DataView[T8, V8], + v9: DataView[T9, V9], + v10: DataView[T10, V10] ): HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10] = { tup.viewAs[HWTuple10[V1, V2, V3, V4, V5, V6, V7, V8, V9, V10]] } diff --git a/src/main/scala/chisel3/experimental/verification/package.scala b/src/main/scala/chisel3/experimental/verification/package.scala index a026542d..1cedb8da 100644 --- a/src/main/scala/chisel3/experimental/verification/package.scala +++ b/src/main/scala/chisel3/experimental/verification/package.scala @@ -8,20 +8,44 @@ import chisel3.internal.sourceinfo.SourceInfo package object verification { object assert { - @deprecated("Please use chisel3.assert instead. The chisel3.experimental.verification package will be removed.", "Chisel 3.5") - def apply(predicate: Bool, msg: String = "") - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): chisel3.assert.Assert = chisel3.assert(predicate, msg) + @deprecated( + "Please use chisel3.assert instead. The chisel3.experimental.verification package will be removed.", + "Chisel 3.5" + ) + def apply( + predicate: Bool, + msg: String = "" + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): chisel3.assert.Assert = chisel3.assert(predicate, msg) } object assume { - @deprecated("Please use chisel3.assume instead. The chisel3.experimental.verification package will be removed.", "Chisel 3.5") - def apply(predicate: Bool, msg: String = "") - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): chisel3.assume.Assume = chisel3.assume(predicate, msg) + @deprecated( + "Please use chisel3.assume instead. The chisel3.experimental.verification package will be removed.", + "Chisel 3.5" + ) + def apply( + predicate: Bool, + msg: String = "" + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): chisel3.assume.Assume = chisel3.assume(predicate, msg) } object cover { - @deprecated("Please use chisel3.cover instead. The chisel3.experimental.verification package will be removed.", "Chisel 3.5") - def apply(predicate: Bool, msg: String = "") - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): chisel3.cover.Cover = chisel3.cover(predicate, msg) + @deprecated( + "Please use chisel3.cover instead. The chisel3.experimental.verification package will be removed.", + "Chisel 3.5" + ) + def apply( + predicate: Bool, + msg: String = "" + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): chisel3.cover.Cover = chisel3.cover(predicate, msg) } } diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index a94558ce..bbf43a45 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -20,4 +20,3 @@ private[chisel3] object Emitter { result ++ moduleStrings } } - diff --git a/src/main/scala/chisel3/stage/ChiselAnnotations.scala b/src/main/scala/chisel3/stage/ChiselAnnotations.scala index de47ef36..c5811813 100644 --- a/src/main/scala/chisel3/stage/ChiselAnnotations.scala +++ b/src/main/scala/chisel3/stage/ChiselAnnotations.scala @@ -3,7 +3,15 @@ package chisel3.stage import firrtl.annotations.{Annotation, NoTargetAnnotation} -import firrtl.options.{BufferedCustomFileEmission, CustomFileEmission, HasShellOptions, OptionsException, ShellOption, StageOptions, Unserializable} +import firrtl.options.{ + BufferedCustomFileEmission, + CustomFileEmission, + HasShellOptions, + OptionsException, + ShellOption, + StageOptions, + Unserializable +} import firrtl.options.Viewer.view import chisel3.{ChiselException, Module} import chisel3.RawModule @@ -29,7 +37,9 @@ case object NoRunFirrtlCompilerAnnotation longOption = "no-run-firrtl", toAnnotationSeq = _ => Seq(NoRunFirrtlCompilerAnnotation), helpText = "Do not run the FIRRTL compiler (generate FIRRTL IR from Chisel and exit)", - shortOption = Some("chnrf") ) ) + shortOption = Some("chnrf") + ) + ) } @@ -45,7 +55,9 @@ case object PrintFullStackTraceAnnotation new ShellOption[Unit]( longOption = "full-stacktrace", toAnnotationSeq = _ => Seq(PrintFullStackTraceAnnotation), - helpText = "Show full stack trace when an exception is thrown" ) ) + helpText = "Show full stack trace when an exception is thrown" + ) + ) } @@ -68,15 +80,18 @@ object ChiselGeneratorAnnotation extends HasShellOptions { * that Module is found */ def apply(name: String): ChiselGeneratorAnnotation = { - val gen = () => try { - Class.forName(name).asInstanceOf[Class[_ <: RawModule]].newInstance() - } catch { - case e: ClassNotFoundException => - throw new OptionsException(s"Unable to locate module '$name'! (Did you misspell it?)", e) - case e: InstantiationException => - throw new OptionsException( - s"Unable to create instance of module '$name'! (Does this class take parameters?)", e) - } + val gen = () => + try { + Class.forName(name).asInstanceOf[Class[_ <: RawModule]].newInstance() + } catch { + case e: ClassNotFoundException => + throw new OptionsException(s"Unable to locate module '$name'! (Did you misspell it?)", e) + case e: InstantiationException => + throw new OptionsException( + s"Unable to create instance of module '$name'! (Does this class take parameters?)", + e + ) + } ChiselGeneratorAnnotation(gen) } @@ -85,17 +100,16 @@ object ChiselGeneratorAnnotation extends HasShellOptions { longOption = "module", toAnnotationSeq = (a: String) => Seq(ChiselGeneratorAnnotation(a)), helpText = "The name of a Chisel module to elaborate (module must be in the classpath)", - helpValueName = Some("<package>.<module>") ) ) + helpValueName = Some("<package>.<module>") + ) + ) } /** Stores a Chisel Circuit * @param circuit a Chisel Circuit */ -case class ChiselCircuitAnnotation(circuit: Circuit) - extends NoTargetAnnotation - with ChiselOption - with Unserializable { +case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption with Unserializable { /* Caching the hashCode for a large circuit is necessary due to repeated queries. * Not caching the hashCode will cause severe performance degredations for large [[Circuit]]s. */ @@ -135,8 +149,9 @@ case class CircuitSerializationAnnotation(circuit: Circuit, filename: String, fo override def getBytesBuffered: Iterable[Array[Byte]] = format match { case FirrtlFileFormat => - OldEmitter.emitLazily(circuit) - .map(_.getBytes) + OldEmitter + .emitLazily(circuit) + .map(_.getBytes) // TODO Use lazy Iterables so that we don't have to materialize full intermediate data structures case ProtoBufFileFormat => val ostream = new java.io.ByteArrayOutputStream @@ -155,7 +170,9 @@ object ChiselOutputFileAnnotation extends HasShellOptions { longOption = "chisel-output-file", toAnnotationSeq = (a: String) => Seq(ChiselOutputFileAnnotation(a)), helpText = "Write Chisel-generated FIRRTL to this file (default: <circuit-main>.fir)", - helpValueName = Some("<file>") ) ) + helpValueName = Some("<file>") + ) + ) } diff --git a/src/main/scala/chisel3/stage/ChiselCli.scala b/src/main/scala/chisel3/stage/ChiselCli.scala index 8e1974ed..26b032bf 100644 --- a/src/main/scala/chisel3/stage/ChiselCli.scala +++ b/src/main/scala/chisel3/stage/ChiselCli.scala @@ -6,9 +6,11 @@ import firrtl.options.Shell trait ChiselCli { this: Shell => parser.note("Chisel Front End Options") - Seq( NoRunFirrtlCompilerAnnotation, - PrintFullStackTraceAnnotation, - ChiselOutputFileAnnotation, - ChiselGeneratorAnnotation ) + Seq( + NoRunFirrtlCompilerAnnotation, + PrintFullStackTraceAnnotation, + ChiselOutputFileAnnotation, + ChiselGeneratorAnnotation + ) .foreach(_.addOptions(parser)) } diff --git a/src/main/scala/chisel3/stage/ChiselOptions.scala b/src/main/scala/chisel3/stage/ChiselOptions.scala index 46a68f64..ed4d0a2f 100644 --- a/src/main/scala/chisel3/stage/ChiselOptions.scala +++ b/src/main/scala/chisel3/stage/ChiselOptions.scala @@ -5,22 +5,24 @@ package chisel3.stage import chisel3.internal.firrtl.Circuit class ChiselOptions private[stage] ( - val runFirrtlCompiler: Boolean = true, - val printFullStackTrace: Boolean = false, - val outputFile: Option[String] = None, + val runFirrtlCompiler: Boolean = true, + val printFullStackTrace: Boolean = false, + val outputFile: Option[String] = None, val chiselCircuit: Option[Circuit] = None) { private[stage] def copy( - runFirrtlCompiler: Boolean = runFirrtlCompiler, - printFullStackTrace: Boolean = printFullStackTrace, - outputFile: Option[String] = outputFile, - chiselCircuit: Option[Circuit] = chiselCircuit ): ChiselOptions = { + runFirrtlCompiler: Boolean = runFirrtlCompiler, + printFullStackTrace: Boolean = printFullStackTrace, + outputFile: Option[String] = outputFile, + chiselCircuit: Option[Circuit] = chiselCircuit + ): ChiselOptions = { new ChiselOptions( - runFirrtlCompiler = runFirrtlCompiler, + runFirrtlCompiler = runFirrtlCompiler, printFullStackTrace = printFullStackTrace, - outputFile = outputFile, - chiselCircuit = chiselCircuit ) + outputFile = outputFile, + chiselCircuit = chiselCircuit + ) } diff --git a/src/main/scala/chisel3/stage/ChiselPhase.scala b/src/main/scala/chisel3/stage/ChiselPhase.scala index aa37f3b1..6c7affbc 100644 --- a/src/main/scala/chisel3/stage/ChiselPhase.scala +++ b/src/main/scala/chisel3/stage/ChiselPhase.scala @@ -2,28 +2,26 @@ package chisel3.stage -import firrtl.options.{ - Dependency, - Phase, - PhaseManager -} +import firrtl.options.{Dependency, Phase, PhaseManager} import firrtl.options.phases.DeletedWrapper private[chisel3] class ChiselPhase extends PhaseManager(ChiselPhase.targets) { - override val wrappers = Seq( (a: Phase) => DeletedWrapper(a) ) + override val wrappers = Seq((a: Phase) => DeletedWrapper(a)) } private[chisel3] object ChiselPhase { val targets: Seq[PhaseManager.PhaseDependency] = - Seq( Dependency[chisel3.stage.phases.Checks], - Dependency[chisel3.stage.phases.AddImplicitOutputFile], - Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], - Dependency[chisel3.stage.phases.MaybeAspectPhase], - Dependency[chisel3.stage.phases.AddSerializationAnnotations], - Dependency[chisel3.stage.phases.Convert], - Dependency[chisel3.stage.phases.MaybeFirrtlStage] ) + Seq( + Dependency[chisel3.stage.phases.Checks], + Dependency[chisel3.stage.phases.AddImplicitOutputFile], + Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], + Dependency[chisel3.stage.phases.MaybeAspectPhase], + Dependency[chisel3.stage.phases.AddSerializationAnnotations], + Dependency[chisel3.stage.phases.Convert], + Dependency[chisel3.stage.phases.MaybeFirrtlStage] + ) } diff --git a/src/main/scala/chisel3/stage/ChiselStage.scala b/src/main/scala/chisel3/stage/ChiselStage.scala index 0c76f411..1224a8f1 100644 --- a/src/main/scala/chisel3/stage/ChiselStage.scala +++ b/src/main/scala/chisel3/stage/ChiselStage.scala @@ -22,7 +22,7 @@ import chisel3.{ChiselException, RawModule} import chisel3.internal.{firrtl => cir, ErrorLog} import chisel3.stage.CircuitSerializationAnnotation.FirrtlFileFormat -import java.io.{StringWriter, PrintWriter} +import java.io.{PrintWriter, StringWriter} class ChiselStage extends Stage { @@ -51,17 +51,16 @@ class ChiselStage extends Stage { * @return a string containing the Verilog output */ final def emitChirrtl( - gen: => RawModule, - args: Array[String] = Array.empty, - annotations: AnnotationSeq = Seq.empty): String = { + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty + ): String = { val annos = execute(Array("--no-run-firrtl") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) - annos - .collectFirst { - case a: ChiselCircuitAnnotation => CircuitSerializationAnnotation(a.circuit, "", FirrtlFileFormat).getBytes - } - .get + annos.collectFirst { + case a: ChiselCircuitAnnotation => CircuitSerializationAnnotation(a.circuit, "", FirrtlFileFormat).getBytes + }.get .map(_.toChar) .mkString @@ -74,15 +73,15 @@ class ChiselStage extends Stage { * @return a string containing the FIRRTL output */ final def emitFirrtl( - gen: => RawModule, - args: Array[String] = Array.empty, - annotations: AnnotationSeq = Seq.empty): String = { - - execute(Array("-X", "high") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) - .collect { - case EmittedFirrtlCircuitAnnotation(a) => a - case EmittedFirrtlModuleAnnotation(a) => a - }.map(_.value) + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty + ): String = { + + execute(Array("-X", "high") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations).collect { + case EmittedFirrtlCircuitAnnotation(a) => a + case EmittedFirrtlModuleAnnotation(a) => a + }.map(_.value) .mkString("") } @@ -94,15 +93,15 @@ class ChiselStage extends Stage { * @return a string containing the Verilog output */ final def emitVerilog( - gen: => RawModule, - args: Array[String] = Array.empty, - annotations: AnnotationSeq = Seq.empty): String = { - - execute(Array("-X", "verilog") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) - .collectFirst { - case EmittedVerilogCircuitAnnotation(a) => a - case EmittedVerilogModuleAnnotation(a) => a - }.map(_.value) + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty + ): String = { + + execute(Array("-X", "verilog") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations).collectFirst { + case EmittedVerilogCircuitAnnotation(a) => a + case EmittedVerilogModuleAnnotation(a) => a + }.map(_.value) .mkString("") } @@ -114,15 +113,15 @@ class ChiselStage extends Stage { * @return a string containing the SystemVerilog output */ final def emitSystemVerilog( - gen: => RawModule, - args: Array[String] = Array.empty, - annotations: AnnotationSeq = Seq.empty): String = { - - execute(Array("-X", "sverilog") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations) - .collectFirst { - case EmittedVerilogCircuitAnnotation(a) => a - case EmittedVerilogModuleAnnotation(a) => a - }.map(_.value) + gen: => RawModule, + args: Array[String] = Array.empty, + annotations: AnnotationSeq = Seq.empty + ): String = { + + execute(Array("-X", "sverilog") ++ args, ChiselGeneratorAnnotation(() => gen) +: annotations).collectFirst { + case EmittedVerilogCircuitAnnotation(a) => a + case EmittedVerilogModuleAnnotation(a) => a + }.map(_.value) .mkString("") } @@ -138,8 +137,7 @@ object ChiselStage { */ def elaborate(gen: => RawModule): cir.Circuit = { val phase = new ChiselPhase { - override val targets = Seq( Dependency[chisel3.stage.phases.Checks], - Dependency[chisel3.stage.phases.Elaborate] ) + override val targets = Seq(Dependency[chisel3.stage.phases.Checks], Dependency[chisel3.stage.phases.Elaborate]) } phase @@ -161,7 +159,8 @@ object ChiselStage { Dependency[chisel3.stage.phases.AddImplicitOutputFile], Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], Dependency[chisel3.stage.phases.MaybeAspectPhase], - Dependency[chisel3.stage.phases.Convert] ) + Dependency[chisel3.stage.phases.Convert] + ) } phase @@ -181,7 +180,8 @@ object ChiselStage { Dependency[chisel3.stage.phases.AddImplicitOutputFile], Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], Dependency[chisel3.stage.phases.MaybeAspectPhase], - Dependency[chisel3.stage.phases.Convert] ) + Dependency[chisel3.stage.phases.Convert] + ) } phase @@ -209,14 +209,16 @@ object ChiselStage { Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], Dependency[chisel3.stage.phases.MaybeAspectPhase], Dependency[chisel3.stage.phases.Convert], - Dependency[firrtl.stage.phases.Compiler] ) + Dependency[firrtl.stage.phases.Compiler] + ) ) phase .transform(Seq(ChiselGeneratorAnnotation(() => gen), RunFirrtlTransformAnnotation(new HighFirrtlEmitter))) .collectFirst { case EmittedFirrtlCircuitAnnotation(a) => a - }.get + } + .get .value } @@ -233,14 +235,16 @@ object ChiselStage { Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], Dependency[chisel3.stage.phases.MaybeAspectPhase], Dependency[chisel3.stage.phases.Convert], - Dependency[firrtl.stage.phases.Compiler] ) + Dependency[firrtl.stage.phases.Compiler] + ) ) phase .transform(Seq(ChiselGeneratorAnnotation(() => gen), RunFirrtlTransformAnnotation(new VerilogEmitter))) .collectFirst { case EmittedVerilogCircuitAnnotation(a) => a - }.get + } + .get .value } @@ -256,14 +260,16 @@ object ChiselStage { Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile], Dependency[chisel3.stage.phases.MaybeAspectPhase], Dependency[chisel3.stage.phases.Convert], - Dependency[firrtl.stage.phases.Compiler] ) + Dependency[firrtl.stage.phases.Compiler] + ) ) phase .transform(Seq(ChiselGeneratorAnnotation(() => gen), RunFirrtlTransformAnnotation(new SystemVerilogEmitter))) .collectFirst { case EmittedVerilogCircuitAnnotation(a) => a - }.get + } + .get .value } diff --git a/src/main/scala/chisel3/stage/package.scala b/src/main/scala/chisel3/stage/package.scala index c307d3ae..bf03e2df 100644 --- a/src/main/scala/chisel3/stage/package.scala +++ b/src/main/scala/chisel3/stage/package.scala @@ -12,14 +12,13 @@ package object stage { implicit object ChiselOptionsView extends OptionsView[ChiselOptions] { - def view(options: AnnotationSeq): ChiselOptions = options - .collect { case a: ChiselOption => a } - .foldLeft(new ChiselOptions()){ (c, x) => + def view(options: AnnotationSeq): ChiselOptions = options.collect { case a: ChiselOption => a } + .foldLeft(new ChiselOptions()) { (c, x) => x match { case _: NoRunFirrtlCompilerAnnotation.type => c.copy(runFirrtlCompiler = false) case _: PrintFullStackTraceAnnotation.type => c.copy(printFullStackTrace = true) - case ChiselOutputFileAnnotation(f) => c.copy(outputFile = Some(f)) - case ChiselCircuitAnnotation(a) => c.copy(chiselCircuit = Some(a)) + case ChiselOutputFileAnnotation(f) => c.copy(outputFile = Some(f)) + case ChiselCircuitAnnotation(a) => c.copy(chiselCircuit = Some(a)) } } diff --git a/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala b/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala index 3ce9dacd..6874e2a2 100644 --- a/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala +++ b/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala @@ -16,15 +16,16 @@ class AddImplicitOutputAnnotationFile extends Phase { override def optionalPrerequisiteOf = Seq.empty override def invalidates(a: Phase) = false - def transform(annotations: AnnotationSeq): AnnotationSeq = annotations - .collectFirst{ case _: OutputAnnotationFileAnnotation => annotations } - .getOrElse{ + def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst { + case _: OutputAnnotationFileAnnotation => annotations + }.getOrElse { - val x: Option[AnnotationSeq] = annotations - .collectFirst{ case a: ChiselCircuitAnnotation => - OutputAnnotationFileAnnotation(a.circuit.name) +: annotations } - - x.getOrElse(annotations) + val x: Option[AnnotationSeq] = annotations.collectFirst { + case a: ChiselCircuitAnnotation => + OutputAnnotationFileAnnotation(a.circuit.name) +: annotations } + x.getOrElse(annotations) + } + } diff --git a/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala b/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala index e39d4d54..2507c2c8 100644 --- a/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala +++ b/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala @@ -18,11 +18,12 @@ class AddImplicitOutputFile extends Phase { override def invalidates(a: Phase) = false def transform(annotations: AnnotationSeq): AnnotationSeq = - annotations.collectFirst{ case _: ChiselOutputFileAnnotation => annotations }.getOrElse{ + annotations.collectFirst { case _: ChiselOutputFileAnnotation => annotations }.getOrElse { - val x: Option[AnnotationSeq] = annotations - .collectFirst{ case a: ChiselCircuitAnnotation => - ChiselOutputFileAnnotation(a.circuit.name) +: annotations } + val x: Option[AnnotationSeq] = annotations.collectFirst { + case a: ChiselCircuitAnnotation => + ChiselOutputFileAnnotation(a.circuit.name) +: annotations + } x.getOrElse(annotations) } diff --git a/src/main/scala/chisel3/stage/phases/AddSerializationAnnotations.scala b/src/main/scala/chisel3/stage/phases/AddSerializationAnnotations.scala index 93425b07..d35b2f2e 100644 --- a/src/main/scala/chisel3/stage/phases/AddSerializationAnnotations.scala +++ b/src/main/scala/chisel3/stage/phases/AddSerializationAnnotations.scala @@ -22,7 +22,9 @@ class AddSerializationAnnotations extends Phase { def transform(annotations: AnnotationSeq): AnnotationSeq = { val chiselOptions = view[ChiselOptions](annotations) val circuit = chiselOptions.chiselCircuit.getOrElse { - throw new ChiselException(s"Unable to locate the elaborated circuit, did ${classOf[Elaborate].getName} run correctly") + throw new ChiselException( + s"Unable to locate the elaborated circuit, did ${classOf[Elaborate].getName} run correctly" + ) } val baseFilename = chiselOptions.outputFile.getOrElse(circuit.name) diff --git a/src/main/scala/chisel3/stage/phases/AspectPhase.scala b/src/main/scala/chisel3/stage/phases/AspectPhase.scala index 72965861..efe2c3a4 100644 --- a/src/main/scala/chisel3/stage/phases/AspectPhase.scala +++ b/src/main/scala/chisel3/stage/phases/AspectPhase.scala @@ -28,7 +28,7 @@ class AspectPhase extends Phase { Nil case other => Seq(other) } - if(dut.isDefined) { + if (dut.isDefined) { val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) } remainingAnnotations ++ newAnnotations } else annotations diff --git a/src/main/scala/chisel3/stage/phases/Checks.scala b/src/main/scala/chisel3/stage/phases/Checks.scala index 1ff7f64c..55c90ccb 100644 --- a/src/main/scala/chisel3/stage/phases/Checks.scala +++ b/src/main/scala/chisel3/stage/phases/Checks.scala @@ -31,21 +31,24 @@ class Checks extends Phase { throw new OptionsException( s"""|At most one NoRunFirrtlCompilerAnnotation can be specified, but found '${noF.size}'. Did you duplicate: | - option or annotation: -chnrf, --no-run-firrtl, NoRunFirrtlCompilerAnnotation - |""".stripMargin) + |""".stripMargin + ) } if (st.size > 1) { throw new OptionsException( s"""|At most one PrintFullStackTraceAnnotation can be specified, but found '${noF.size}'. Did you duplicate: | - option or annotation: --full-stacktrace, PrintFullStackTraceAnnotation - |""".stripMargin) + |""".stripMargin + ) } if (outF.size > 1) { throw new OptionsException( s"""|At most one Chisel output file can be specified but found '${outF.size}'. Did you duplicate: | - option or annotation: --chisel-output-file, ChiselOutputFileAnnotation - |""".stripMargin) + |""".stripMargin + ) } annotations diff --git a/src/main/scala/chisel3/stage/phases/Convert.scala b/src/main/scala/chisel3/stage/phases/Convert.scala index b5b01b8d..014ed3f2 100644 --- a/src/main/scala/chisel3/stage/phases/Convert.scala +++ b/src/main/scala/chisel3/stage/phases/Convert.scala @@ -24,20 +24,13 @@ class Convert extends Phase { def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap { case a: ChiselCircuitAnnotation => Some(a) ++ - /* Convert this Chisel Circuit to a FIRRTL Circuit */ - Some(FirrtlCircuitAnnotation(Converter.convert(a.circuit))) ++ - /* Convert all Chisel Annotations to FIRRTL Annotations */ - a - .circuit - .firrtlAnnotations ++ - a - .circuit - .annotations - .collect { + /* Convert this Chisel Circuit to a FIRRTL Circuit */ + Some(FirrtlCircuitAnnotation(Converter.convert(a.circuit))) ++ + /* Convert all Chisel Annotations to FIRRTL Annotations */ + a.circuit.firrtlAnnotations ++ + a.circuit.annotations.collect { case anno: RunFirrtlTransform => anno.transformClass - } - .distinct - .map { c: Class[_ <: Transform] => RunFirrtlTransformAnnotation(c.newInstance()) } + }.distinct.map { c: Class[_ <: Transform] => RunFirrtlTransformAnnotation(c.newInstance()) } case a => Some(a) } diff --git a/src/main/scala/chisel3/stage/phases/Elaborate.scala b/src/main/scala/chisel3/stage/phases/Elaborate.scala index e8f2623e..2cfb3200 100644 --- a/src/main/scala/chisel3/stage/phases/Elaborate.scala +++ b/src/main/scala/chisel3/stage/phases/Elaborate.scala @@ -20,18 +20,19 @@ class Elaborate extends Phase { override def invalidates(a: Phase) = false def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap { - case ChiselGeneratorAnnotation(gen) => try { - val (circuit, dut) = Builder.build(Module(gen()), new DynamicContext(annotations)) - Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut)) - } catch { - /* if any throwable comes back and we're in "stack trace trimming" mode, then print an error and trim the stack trace - */ - case scala.util.control.NonFatal(a) => - if (!view[ChiselOptions](annotations).printFullStackTrace) { - a.trimStackTraceToUserCode() - } - throw(a) - } + case ChiselGeneratorAnnotation(gen) => + try { + val (circuit, dut) = Builder.build(Module(gen()), new DynamicContext(annotations)) + Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut)) + } catch { + /* if any throwable comes back and we're in "stack trace trimming" mode, then print an error and trim the stack trace + */ + case scala.util.control.NonFatal(a) => + if (!view[ChiselOptions](annotations).printFullStackTrace) { + a.trimStackTraceToUserCode() + } + throw (a) + } case a => Some(a) } diff --git a/src/main/scala/chisel3/stage/phases/Emitter.scala b/src/main/scala/chisel3/stage/phases/Emitter.scala index 756c5db4..254f8add 100644 --- a/src/main/scala/chisel3/stage/phases/Emitter.scala +++ b/src/main/scala/chisel3/stage/phases/Emitter.scala @@ -25,10 +25,12 @@ import java.io.{File, FileWriter} class Emitter extends Phase { override def prerequisites = - Seq( Dependency[Elaborate], - Dependency[AddImplicitOutputFile], - Dependency[AddImplicitOutputAnnotationFile], - Dependency[MaybeAspectPhase] ) + Seq( + Dependency[Elaborate], + Dependency[AddImplicitOutputFile], + Dependency[AddImplicitOutputAnnotationFile], + Dependency[MaybeAspectPhase] + ) override def optionalPrerequisites = Seq.empty override def optionalPrerequisiteOf = Seq(Dependency[Convert]) override def invalidates(a: Phase) = false diff --git a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala index c26cbd82..dcd0dfe0 100644 --- a/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala +++ b/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala @@ -16,7 +16,7 @@ class MaybeAspectPhase extends Phase { override def invalidates(a: Phase) = false def transform(annotations: AnnotationSeq): AnnotationSeq = { - if(annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) { + if (annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) { new AspectPhase().transform(annotations) } else annotations } diff --git a/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala b/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala index cd68e04c..3533d8d1 100644 --- a/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala +++ b/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala @@ -17,8 +17,8 @@ class MaybeFirrtlStage extends Phase { override def optionalPrerequisiteOf = Seq.empty override def invalidates(a: Phase) = false - def transform(annotations: AnnotationSeq): AnnotationSeq = annotations - .collectFirst { case NoRunFirrtlCompilerAnnotation => annotations } - .getOrElse { (new FirrtlStage).transform(annotations) } + def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst { + case NoRunFirrtlCompilerAnnotation => annotations + }.getOrElse { (new FirrtlStage).transform(annotations) } } diff --git a/src/main/scala/chisel3/testers/BasicTester.scala b/src/main/scala/chisel3/testers/BasicTester.scala index 99002660..5e28a523 100644 --- a/src/main/scala/chisel3/testers/BasicTester.scala +++ b/src/main/scala/chisel3/testers/BasicTester.scala @@ -13,7 +13,7 @@ class BasicTester extends Module() { // The testbench has no IOs, rather it should communicate using printf, assert, and stop. val io = IO(new Bundle() {}) - def popCount(n: Long): Int = n.toBinaryString.count(_=='1') + def popCount(n: Long): Int = n.toBinaryString.count(_ == '1') /** Ends the test reporting success. * diff --git a/src/main/scala/chisel3/testers/TesterDriver.scala b/src/main/scala/chisel3/testers/TesterDriver.scala index e87aceca..9c4b2da9 100644 --- a/src/main/scala/chisel3/testers/TesterDriver.scala +++ b/src/main/scala/chisel3/testers/TesterDriver.scala @@ -16,24 +16,27 @@ import firrtl.transforms.BlackBoxSourceHelper.writeResourceToDirectory object TesterDriver extends BackendCompilationUtilities { private[chisel3] trait Backend extends NoTargetAnnotation with Unserializable { - def execute(t: () => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq(), - nameHint: Option[String] = None - ): Boolean + def execute( + t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq(), + nameHint: Option[String] = None + ): Boolean } case object VerilatorBackend extends Backend { + /** For use with modules that should successfully be elaborated by the - * frontend, and which can be turned into executables with assertions. */ - def execute(t: () => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq(), - nameHint: Option[String] = None - ): Boolean = { + * frontend, and which can be turned into executables with assertions. + */ + def execute( + t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq(), + nameHint: Option[String] = None + ): Boolean = { val pm = new PhaseManager( - targets = Seq(Dependency[AddImplicitTesterDirectory], - Dependency[Emitter], - Dependency[Convert])) + targets = Seq(Dependency[AddImplicitTesterDirectory], Dependency[Emitter], Dependency[Convert]) + ) val annotationsx = pm.transform(ChiselGeneratorAnnotation(finishWrapper(t)) +: annotations) @@ -41,7 +44,7 @@ object TesterDriver extends BackendCompilationUtilities { val path = annotationsx.collectFirst { case TargetDirAnnotation(dir) => dir }.map(new File(_)).get // Copy CPP harness and other Verilog sources from resources into files - val cppHarness = new File(path, "top.cpp") + val cppHarness = new File(path, "top.cpp") copyResourceToFile("/chisel3/top.cpp", cppHarness) // NOTE: firrtl.Driver.execute() may end up copying these same resources in its BlackBoxSourceHelper code. // As long as the same names are used for the output files, and we avoid including duplicate files @@ -54,8 +57,10 @@ object TesterDriver extends BackendCompilationUtilities { (new FirrtlStage).execute(Array("--compiler", "verilog"), annotationsx) // Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe - if ((verilogToCpp(target, path, additionalVFiles, cppHarness) #&& - cppToExe(target, path)).! == 0) { + if ( + (verilogToCpp(target, path, additionalVFiles, cppHarness) #&& + cppToExe(target, path)).! == 0 + ) { executeExpectingSuccess(target, path) } else { false @@ -77,21 +82,26 @@ object TesterDriver extends BackendCompilationUtilities { override def invalidates(a: Phase) = false override def transform(a: AnnotationSeq) = a.flatMap { - case a@ ChiselCircuitAnnotation(circuit) => - Seq(a, TargetDirAnnotation( - firrtl.util.BackendCompilationUtilities.createTestDirectory(circuit.name) - .getAbsolutePath - .toString)) + case a @ ChiselCircuitAnnotation(circuit) => + Seq( + a, + TargetDirAnnotation( + firrtl.util.BackendCompilationUtilities.createTestDirectory(circuit.name).getAbsolutePath.toString + ) + ) case a => Seq(a) } } /** For use with modules that should successfully be elaborated by the - * frontend, and which can be turned into executables with assertions. */ - def execute(t: () => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq(), - nameHint: Option[String] = None): Boolean = { + * frontend, and which can be turned into executables with assertions. + */ + def execute( + t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq(), + nameHint: Option[String] = None + ): Boolean = { val backendAnnotations = annotations.collect { case anno: Backend => anno } val backendAnnotation = if (backendAnnotations.length == 1) { @@ -109,11 +119,11 @@ object TesterDriver extends BackendCompilationUtilities { * The finish method is a hook for code that augments the circuit built in the constructor. */ def finishWrapper(test: () => BasicTester): () => BasicTester = { () => - { - val tester = test() - tester.finish() - tester - } + { + val tester = test() + tester.finish() + tester + } } } diff --git a/src/main/scala/chisel3/testers/package.scala b/src/main/scala/chisel3/testers/package.scala index f60f7cc2..f20a7977 100644 --- a/src/main/scala/chisel3/testers/package.scala +++ b/src/main/scala/chisel3/testers/package.scala @@ -3,8 +3,5 @@ package chisel3 /** The testers package provides the basic interface for chisel testers. - * */ -package object testers { - -} +package object testers {} diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index b68acae1..220a12b1 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order +import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order /** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs * (selects) at most one. @@ -18,20 +18,22 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because class ArbiterIO[T <: Data](private val gen: T, val n: Int) extends Bundle { // See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs. -/** Input data, one per potential sender - * - * @group Signals - */ - val in = Flipped(Vec(n, Decoupled(gen))) -/** Output data after arbitration - * - * @group Signals - */ + /** Input data, one per potential sender + * + * @group Signals + */ + val in = Flipped(Vec(n, Decoupled(gen))) + + /** Output data after arbitration + * + * @group Signals + */ val out = Decoupled(gen) -/** One-Hot vector indicating which output was chosen - * - * @group Signals - */ + + /** One-Hot vector indicating which output was chosen + * + * @group Signals + */ val chosen = Output(UInt(log2Ceil(n).W)) } @@ -46,7 +48,7 @@ private object ArbiterCtrl { } abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool]) extends Module { - def grant: Seq[Bool] + def grant: Seq[Bool] def choice: UInt val io = IO(new ArbiterIO(gen, n)) @@ -60,16 +62,16 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo val locked = lockCount.value =/= 0.U val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(true.B) - when (io.out.fire && wantsLock) { + when(io.out.fire && wantsLock) { lockIdx := io.chosen lockCount.inc() } - when (locked) { io.chosen := lockIdx } - for ((in, (g, i)) <- io.in zip grant.zipWithIndex) + when(locked) { io.chosen := lockIdx } + for ((in, (g, i)) <- io.in.zip(grant.zipWithIndex)) in.ready := Mux(locked, lockIdx === i.asUInt, g) && io.out.ready } else { - for ((in, g) <- io.in zip grant) + for ((in, g) <- io.in.zip(grant)) in.ready := g && io.out.ready } } @@ -78,27 +80,27 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ extends LockingArbiterLike[T](gen, n, count, needsLock) { lazy val lastGrant = RegEnable(io.chosen, io.out.fire) lazy val grantMask = (0 until n).map(_.asUInt > lastGrant) - lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } + lazy val validMask = io.in.zip(grantMask).map { case (in, g) => in.valid && g } override def grant: Seq[Bool] = { val ctrl = ArbiterCtrl((0 until n).map(i => validMask(i)) ++ io.in.map(_.valid)) (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) } - override lazy val choice = WireDefault((n-1).asUInt) - for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := i.asUInt } - for (i <- n-1 to 1 by -1) - when (validMask(i)) { choice := i.asUInt } + override lazy val choice = WireDefault((n - 1).asUInt) + for (i <- n - 2 to 0 by -1) + when(io.in(i).valid) { choice := i.asUInt } + for (i <- n - 1 to 1 by -1) + 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 = WireDefault((n-1).asUInt) - for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := i.asUInt } + override lazy val choice = WireDefault((n - 1).asUInt) + for (i <- n - 2 to 0 by -1) + when(io.in(i).valid) { choice := i.asUInt } } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -133,17 +135,17 @@ class RRArbiter[T <: Data](val gen: T, val n: Int) extends LockingRRArbiter[T](g class Arbiter[T <: Data](val gen: T, val n: Int) extends Module { val io = IO(new ArbiterIO(gen, n)) - 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 := (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 := i.asUInt io.out.bits := io.in(i).bits } } val grant = ArbiterCtrl(io.in.map(_.valid)) - for ((in, g) <- io.in zip grant) + for ((in, g) <- io.in.zip(grant)) in.ready := g && io.out.ready io.out.valid := !grant.last || io.in.last.valid } diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 808245de..d27fee14 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -6,12 +6,11 @@ import scala.language.experimental.macros import chisel3._ import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} - object BitPat { private[chisel3] implicit val bitPatOrder = new Ordering[BitPat] { import scala.math.Ordered.orderingToOrdered - def compare(x: BitPat, y: BitPat): Int = (x.getWidth, x.value, x.mask) compare (y.getWidth, y.value, y.mask) + def compare(x: BitPat, y: BitPat): Int = (x.getWidth, x.value, x.mask).compare(y.getWidth, y.value, y.mask) } /** Parses a bit pattern string into (bits, mask, width). @@ -33,7 +32,7 @@ object BitPat { var mask = BigInt(0) var count = 0 for (d <- x.tail) { - if (! (d == '_' || d.isWhitespace)) { + if (!(d == '_' || d.isWhitespace)) { require("01?".contains(d), "Literal: " + x + " contains illegal character: " + d) mask = (mask << 1) + (if (d == '?') 0 else 1) bits = (bits << 1) + (if (d == '1') 1 else 0) @@ -105,15 +104,14 @@ object BitPat { import scala.language.experimental.macros - final def === (that: BitPat): Bool = macro SourceInfoTransform.thatArg - final def =/= (that: BitPat): Bool = macro SourceInfoTransform.thatArg + final def ===(that: BitPat): Bool = macro SourceInfoTransform.thatArg + final def =/=(that: BitPat): Bool = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ - def do_=== (that: BitPat) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that === x + def do_===(that: BitPat)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that === x + /** @group SourceInfoTransformMacro */ - def do_=/= (that: BitPat) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that =/= x + def do_=/=(that: BitPat)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = that =/= x } } @@ -148,6 +146,7 @@ package experimental { /** A Set of [[BitPat]] represents a set of bit vector with mask. */ sealed trait BitSet { outer => + /** all [[BitPat]] elements in [[terms]] make up this [[BitSet]]. * all [[terms]] should be have the same width. */ @@ -229,7 +228,6 @@ package experimental { } - /** Bit patterns are literals with masks, used to represent values with don't * care bits. Equality comparisons will ignore don't care bits. * @@ -239,7 +237,9 @@ package experimental { * "b10001".U === BitPat("b101??") // evaluates to false.B * }}} */ -sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) extends util.experimental.BitSet with SourceInfoDoc { +sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) + extends util.experimental.BitSet + with SourceInfoDoc { import chisel3.util.experimental.BitSet def terms = Set(this) @@ -247,11 +247,11 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) extends * Get specified width of said BitPat */ override def getWidth: Int = width - def apply(x: Int): BitPat = macro SourceInfoTransform.xArg - def apply(x: Int, y: Int): BitPat = macro SourceInfoTransform.xyArg - def === (that: UInt): Bool = macro SourceInfoTransform.thatArg - def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg - def ## (that: BitPat): BitPat = macro SourceInfoTransform.thatArg + def apply(x: Int): BitPat = macro SourceInfoTransform.xArg + def apply(x: Int, y: Int): BitPat = macro SourceInfoTransform.xyArg + def ===(that: UInt): Bool = macro SourceInfoTransform.thatArg + def =/=(that: UInt): Bool = macro SourceInfoTransform.thatArg + def ##(that: BitPat): BitPat = macro SourceInfoTransform.thatArg /** @group SourceInfoTransformMacro */ def do_apply(x: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = { @@ -266,15 +266,15 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, val width: Int) extends } /** @group SourceInfoTransformMacro */ - def do_=== (that: UInt) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { + def do_===(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { value.asUInt === (that & mask.asUInt) } + /** @group SourceInfoTransformMacro */ - def do_=/= (that: UInt) - (implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { + def do_=/=(that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = { !(this === that) } + /** @group SourceInfoTransformMacro */ def do_##(that: BitPat)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): BitPat = { new BitPat((value << that.getWidth) + that.value, (mask << that.getWidth) + that.mask, this.width + that.getWidth) diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index ddf7546a..0d8318bf 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -19,6 +19,7 @@ import chisel3._ * }}} */ object FillInterleaved { + /** Creates n repetitions of each bit of x in order. * * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) @@ -58,6 +59,7 @@ object PopCount { * }}} */ object Fill { + /** Create n repetitions of x using a tree fanout topology. * * Output data-equivalent to x ## x ## ... ## x (n repetitions). @@ -66,8 +68,8 @@ object Fill { def apply(n: Int, x: UInt): UInt = { n match { case _ if n < 0 => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.") - case 0 => UInt(0.W) - case 1 => x + case 0 => UInt(0.W) + case 1 => x case _ if x.isWidthKnown && x.getWidth == 1 => Mux(x.asBool, ((BigInt(1) << n) - 1).asUInt(n.W), 0.U(n.W)) case _ => @@ -75,7 +77,7 @@ object Fill { val p2 = Array.ofDim[UInt](nBits) p2(0) = x for (i <- 1 until p2.length) - p2(i) = Cat(p2(i-1), p2(i-1)) + p2(i) = Cat(p2(i - 1), p2(i - 1)) Cat((0 until nBits).filter(i => (n & (1 << i)) != 0).map(p2(_))) } } @@ -91,22 +93,22 @@ object Fill { */ object Reverse { private def doit(in: UInt, length: Int): UInt = length match { - case _ if length < 0 => throw new IllegalArgumentException(s"length (=$length) must be nonnegative integer.") - case _ if length <= 1 => in + case _ if length < 0 => throw new IllegalArgumentException(s"length (=$length) must be nonnegative integer.") + case _ if length <= 1 => in case _ if isPow2(length) && length >= 8 && length <= 64 => // This esoterica improves simulation performance var res = in var shift = length >> 1 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) + mask = mask ^ (mask(length - shift - 1, 0) << shift) + res = ((res >> shift) & mask) | ((res(length - shift - 1, 0) << shift) & ~mask) shift = shift >> 1 } while (shift > 0) res case _ => - val half = (1 << log2Ceil(length))/2 - Cat(doit(in(half-1,0), half), doit(in(length-1,half), length-half)) + val half = (1 << log2Ceil(length)) / 2 + Cat(doit(in(half - 1, 0), half), doit(in(length - 1, half), length - half)) } def apply(in: UInt): UInt = doit(in, in.getWidth) diff --git a/src/main/scala/chisel3/util/BlackBoxUtils.scala b/src/main/scala/chisel3/util/BlackBoxUtils.scala index 443d7f3e..7c4400f8 100644 --- a/src/main/scala/chisel3/util/BlackBoxUtils.scala +++ b/src/main/scala/chisel3/util/BlackBoxUtils.scala @@ -4,14 +4,20 @@ package chisel3.util import chisel3._ import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform} -import firrtl.transforms.{BlackBoxPathAnno, BlackBoxResourceAnno, BlackBoxInlineAnno, BlackBoxSourceHelper, - BlackBoxNotFoundException} +import firrtl.transforms.{ + BlackBoxInlineAnno, + BlackBoxNotFoundException, + BlackBoxPathAnno, + BlackBoxResourceAnno, + BlackBoxSourceHelper +} import firrtl.annotations.ModuleName import logger.LazyLogging private[util] object BlackBoxHelpers { implicit class BlackBoxInlineAnnoHelpers(anno: BlackBoxInlineAnno.type) extends LazyLogging { + /** Generate a BlackBoxInlineAnno from a Java Resource and a module name. */ def fromResource(resourceName: String, moduleName: ModuleName) = try { val blackBoxFile = os.resource / os.RelPath(resourceName.dropWhile(_ == '/')) diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala index 3369eb18..c5adce56 100644 --- a/src/main/scala/chisel3/util/Cat.scala +++ b/src/main/scala/chisel3/util/Cat.scala @@ -15,6 +15,7 @@ import chisel3._ * }}} */ object Cat { + /** Concatenates the argument data elements, in argument order, together. The first argument * forms the most significant bits, while the last argument forms the least significant bits. */ diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 58961630..df60f059 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order +import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order /** Returns the base-2 integer logarithm of an UInt. * @@ -17,9 +17,9 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because * Log2(13.U) // evaluates to 3.U (truncation) * Log2(myUIntWire) * }}} - * */ object Log2 { + /** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt. */ @chiselName @@ -29,11 +29,11 @@ object Log2 { } else if (width == 2) { x(1) } else if (width <= divideAndConquerThreshold) { - Mux(x(width-1), (width-1).asUInt, 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) - val lo = x(mid-1, 0) + val hi = x(width - 1, mid) + val lo = x(mid - 1, 0) val useHi = hi.orR Cat(useHi, Mux(useHi, Log2(hi, width - mid), Log2(lo, mid))) } diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 1ac94bfe..754112eb 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -17,7 +17,13 @@ import chisel3.internal.sourceinfo.SourceInfo * @note DO NOT USE. This API is subject to change without warning. */ class SwitchContext[T <: Element](cond: T, whenContext: Option[WhenContext], lits: Set[BigInt]) { - def is(v: Iterable[T])(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SwitchContext[T] = { + def is( + v: Iterable[T] + )(block: => Any + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SwitchContext[T] = { if (!v.isEmpty) { val newLits = v.map { w => require(w.litOption.isDefined, "is condition must be literal") @@ -26,17 +32,25 @@ class SwitchContext[T <: Element](cond: T, whenContext: Option[WhenContext], lit value } // def instead of val so that logic ends up in legal place - def p = v.map(_.asUInt === cond.asUInt).reduce(_||_) + def p = v.map(_.asUInt === cond.asUInt).reduce(_ || _) whenContext match { case Some(w) => new SwitchContext(cond, Some(w.elsewhen(p)(block)), lits ++ newLits) - case None => new SwitchContext(cond, Some(when(p)(block)), lits ++ newLits) + case None => new SwitchContext(cond, Some(when(p)(block)), lits ++ newLits) } } else { this } } - def is(v: T)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SwitchContext[T] = is(Seq(v))(block) - def is(v: T, vr: T*)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SwitchContext[T] = is(v :: vr.toList)(block) + def is(v: T)(block: => Any)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SwitchContext[T] = + is(Seq(v))(block) + def is( + v: T, + vr: T* + )(block: => Any + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): SwitchContext[T] = is(v :: vr.toList)(block) } /** Use to specify cases in a [[switch]] block, equivalent to a [[when$ when]] block comparing to @@ -84,15 +98,17 @@ object is { */ object switch { def apply[T <: Element](cond: T)(x: => Any): Unit = macro impl - def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._ + def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { + import c.universe._ val q"..$body" = x val res = body.foldLeft(q"""new chisel3.util.SwitchContext($cond, None, Set.empty)""") { - case (acc, tree) => tree match { - // TODO: remove when Chisel compatibility package is removed - case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => q"$acc.is( ..$params )( ..$body )" - case q"chisel3.util.is.apply( ..$params )( ..$body )" => q"$acc.is( ..$params )( ..$body )" - case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") - } + case (acc, tree) => + tree match { + // TODO: remove when Chisel compatibility package is removed + case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => q"$acc.is( ..$params )( ..$body )" + case q"chisel3.util.is.apply( ..$params )( ..$body )" => q"$acc.is( ..$params )( ..$body )" + case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") + } } q"""{ $res }""" } diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 5910c703..ef1eff9f 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,7 +3,7 @@ package chisel3.util import chisel3._ -import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order +import chisel3.internal.naming.chiselName // can't use chisel3_ version because of compile order /** Used to generate an inline (logic directly in the containing Module, no internal Module is created) * hardware counter. @@ -42,11 +42,13 @@ class Counter private (r: Range, oldN: Option[Int] = None) { */ def n: Int = oldN match { case Some(x) => x - case None => + case None => // Reasonable for typical ranges - require(r.start == 0 && r.step == 1, + require( + r.start == 0 && r.step == 1, s"Counter.n only defined on ranges starting at 0 with step == 1, got $r. " + - "Use underlying range.") + "Use underlying range." + ) r.last + 1 } @@ -98,14 +100,14 @@ class Counter private (r: Range, oldN: Option[Int] = None) { } } -object Counter -{ +object Counter { + /** Instantiate a [[Counter! counter]] with the specified number of counts. */ def apply(n: Int): Counter = new Counter(n) /** Instantiate a [[Counter! counter]] with the specified number of counts and a gate. - * + * * @param cond condition that controls whether the counter increments this cycle * @param n number of counts before the counter resets * @return tuple of the counter value and whether the counter will wrap (the value is at @@ -115,7 +117,7 @@ object Counter def apply(cond: Bool, n: Int): (UInt, Bool) = { val c = new Counter(n) val wrap = WireInit(false.B) - when (cond) { wrap := c.inc() } + when(cond) { wrap := c.inc() } (c.value, wrap) } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 4b8b3eeb..5c71a4ea 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -6,8 +6,8 @@ package chisel3.util import chisel3._ -import chisel3.experimental.{DataMirror, Direction, requireIsChiselType} -import chisel3.internal.naming._ // can't use chisel3_ version because of compile order +import chisel3.experimental.{requireIsChiselType, DataMirror, Direction} +import chisel3.internal.naming._ // can't use chisel3_ version because of compile order /** An I/O Bundle containing 'valid' and 'ready' signals that handshake * the transfer of data stored in the 'bits' subfield. @@ -18,40 +18,41 @@ import chisel3.internal.naming._ // can't use chisel3_ version because of compi * @param gen the type of data to be wrapped in Ready/Valid * @groupdesc Signals The actual hardware fields of the Bundle */ -abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle -{ +abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle { // Compatibility hack for rocket-chip private val genType = (DataMirror.internal.isSynthesizable(gen), chisel3.internal.Builder.currentModule) match { - case (true, Some(module: Module)) - if !module.compileOptions.declaredTypeMustBeUnbound => chiselTypeOf(gen) + case (true, Some(module: Module)) if !module.compileOptions.declaredTypeMustBeUnbound => chiselTypeOf(gen) case _ => gen } -/** Indicates that the consumer is ready to accept the data this cycle - * @group Signals - */ + /** Indicates that the consumer is ready to accept the data this cycle + * @group Signals + */ val ready = Input(Bool()) - -/** Indicates that the producer has put valid data in 'bits' - * @group Signals - */ + + /** Indicates that the producer has put valid data in 'bits' + * @group Signals + */ val valid = Output(Bool()) - -/** The data to be transferred when ready and valid are asserted at the same cycle - * @group Signals - */ - val bits = Output(genType) + + /** The data to be transferred when ready and valid are asserted at the same cycle + * @group Signals + */ + val bits = Output(genType) } object ReadyValidIO { - implicit class AddMethodsToReadyValid[T<:Data](target: ReadyValidIO[T]) { + implicit class AddMethodsToReadyValid[T <: Data](target: ReadyValidIO[T]) { /** Indicates if IO is both ready and valid - */ + */ def fire: Bool = target.ready && target.valid - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def fire(dummy: Int = 0): Bool = fire /** Push dat onto the output bits of this interface to let the consumer know it has happened. @@ -99,8 +100,8 @@ object ReadyValidIO { class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) /** This factory adds a decoupled handshaking protocol to a data bundle. */ -object Decoupled -{ +object Decoupled { + /** Wraps some Data with a DecoupledIO interface. */ def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) @@ -110,6 +111,7 @@ object Decoupled // Both of these methods return DecoupledIO parameterized by the most generic type: Data /** Returns a [[DecoupledIO]] inteface with no payload */ def apply(): DecoupledIO[Data] = apply(new EmptyBundle) + /** Returns a [[DecoupledIO]] inteface with no payload */ def empty: DecoupledIO[Data] = Decoupled() @@ -119,7 +121,10 @@ object Decoupled */ @chiselName def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { - require(DataMirror.directionOf(irr.bits) == Direction.Output, "Only safe to cast produced Irrevocable bits to Decoupled.") + require( + DataMirror.directionOf(irr.bits) == Direction.Output, + "Only safe to cast produced Irrevocable bits to Decoupled." + ) val d = Wire(new DecoupledIO(chiselTypeOf(irr.bits))) d.bits := irr.bits d.valid := irr.valid @@ -138,8 +143,7 @@ object Decoupled class IrrevocableIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) /** Factory adds an irrevocable handshaking protocol to a data bundle. */ -object Irrevocable -{ +object Irrevocable { def apply[T <: Data](gen: T): IrrevocableIO[T] = new IrrevocableIO(gen) /** Upconverts a DecoupledIO input to an IrrevocableIO, allowing an IrrevocableIO to be used @@ -148,7 +152,10 @@ object Irrevocable * @note unsafe (and will error) on the consumer (output) side of an DecoupledIO */ def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = { - require(DataMirror.directionOf(dec.bits) == Direction.Input, "Only safe to cast consumed Decoupled bits to Irrevocable.") + require( + DataMirror.directionOf(dec.bits) == Direction.Input, + "Only safe to cast consumed Decoupled bits to Irrevocable." + ) val i = Wire(new IrrevocableIO(chiselTypeOf(dec.bits))) dec.bits := i.bits dec.valid := i.valid @@ -161,13 +168,14 @@ object Irrevocable * @param gen The type of data to enqueue */ object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Decoupled(gen) + def apply[T <: Data](gen: T): DecoupledIO[T] = Decoupled(gen) } + /** Consumer - drives (outputs) ready, inputs valid and bits. * @param gen The type of data to dequeue */ object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen)) + def apply[T <: Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen)) } /** An I/O Bundle for Queues @@ -176,28 +184,34 @@ object DeqIO { * @param hasFlush A boolean for whether the generated Queue is flushable * @groupdesc Signals The hardware fields of the Bundle */ -class QueueIO[T <: Data](private val gen: T, val entries: Int, val hasFlush: Boolean = false) extends Bundle -{ // See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs. +class QueueIO[T <: Data]( + private val gen: T, + val entries: Int, + val hasFlush: Boolean = false) + extends Bundle { // See github.com/freechipsproject/chisel3/issues/765 for why gen is a private val and proposed replacement APIs. /* These may look inverted, because the names (enq/deq) are from the perspective of the client, * but internally, the queue implementation itself sits on the other side * of the interface so uses the flipped instance. */ - /** I/O to enqueue data (client is producer, and Queue object is consumer), is [[Chisel.DecoupledIO]] flipped. + /** I/O to enqueue data (client is producer, and Queue object is consumer), is [[Chisel.DecoupledIO]] flipped. * @group Signals */ val enq = Flipped(EnqIO(gen)) + /** I/O to dequeue data (client is consumer and Queue object is producer), is [[Chisel.DecoupledIO]] * @group Signals */ val deq = Flipped(DeqIO(gen)) - /** The current amount of data in the queue + + /** The current amount of data in the queue * @group Signals */ val count = Output(UInt(log2Ceil(entries + 1).W)) + /** When asserted, reset the enqueue and dequeue pointers, effectively flushing the queue (Optional IO for a flushable Queue) * @group Signals - */ + */ val flush = if (hasFlush) Some(Input(Bool())) else None } @@ -218,13 +232,15 @@ class QueueIO[T <: Data](private val gen: T, val entries: Int, val hasFlush: Boo * }}} */ @chiselName -class Queue[T <: Data](val gen: T, - val entries: Int, - val pipe: Boolean = false, - val flow: Boolean = false, - val useSyncReadMem: Boolean = false, - val hasFlush: Boolean = false) - (implicit compileOptions: chisel3.CompileOptions) +class Queue[T <: Data]( + val gen: T, + val entries: Int, + val pipe: Boolean = false, + val flow: Boolean = false, + val useSyncReadMem: Boolean = false, + val hasFlush: Boolean = false +)( + implicit compileOptions: chisel3.CompileOptions) extends Module() { require(entries > -1, "Queue must have non-negative number of entries") require(entries != 0, "Use companion object Queue.apply for zero entries") @@ -253,21 +269,21 @@ class Queue[T <: Data](val gen: T, // when flush is high, empty the queue // Semantically, any enqueues happen before the flush. - when (do_enq) { + when(do_enq) { ram(enq_ptr.value) := io.enq.bits enq_ptr.inc() } - when (do_deq) { + when(do_deq) { deq_ptr.inc() } - when (do_enq =/= do_deq) { + when(do_enq =/= do_deq) { maybe_full := do_enq } when(flush) { enq_ptr.reset() deq_ptr.reset() maybe_full := false.B - } + } io.deq.valid := !empty io.enq.ready := !full @@ -276,22 +292,21 @@ class Queue[T <: Data](val gen: T, val deq_ptr_next = Mux(deq_ptr.value === (entries.U - 1.U), 0.U, deq_ptr.value + 1.U) val r_addr = WireDefault(Mux(do_deq, deq_ptr_next, deq_ptr.value)) io.deq.bits := ram.read(r_addr) - } - else { + } else { io.deq.bits := ram(deq_ptr.value) } if (flow) { - when (io.enq.valid) { io.deq.valid := true.B } - when (empty) { + when(io.enq.valid) { io.deq.valid := true.B } + when(empty) { io.deq.bits := io.enq.bits do_deq := false.B - when (io.deq.ready) { do_enq := false.B } + when(io.deq.ready) { do_enq := false.B } } } if (pipe) { - when (io.deq.ready) { io.enq.ready := true.B } + when(io.deq.ready) { io.enq.ready := true.B } } val ptr_diff = enq_ptr.value - deq_ptr.value @@ -299,17 +314,17 @@ class Queue[T <: Data](val gen: T, if (isPow2(entries)) { io.count := Mux(maybe_full && ptr_match, entries.U, 0.U) | ptr_diff } else { - io.count := Mux(ptr_match, - Mux(maybe_full, - entries.asUInt, 0.U), - Mux(deq_ptr.value > enq_ptr.value, - entries.asUInt + ptr_diff, ptr_diff)) + io.count := Mux( + ptr_match, + Mux(maybe_full, entries.asUInt, 0.U), + Mux(deq_ptr.value > enq_ptr.value, entries.asUInt + ptr_diff, ptr_diff) + ) } } /** Factory for a generic hardware queue. */ -object Queue -{ +object Queue { + /** Create a [[Queue]] and supply a [[DecoupledIO]] containing the product. * * @param enq input (enqueue) interface to the queue, also determines type of queue elements. @@ -329,12 +344,13 @@ object Queue */ @chiselName def apply[T <: Data]( - enq: ReadyValidIO[T], - entries: Int = 2, - pipe: Boolean = false, - flow: Boolean = false, - useSyncReadMem: Boolean = false, - flush: Option[Bool] = None): DecoupledIO[T] = { + enq: ReadyValidIO[T], + entries: Int = 2, + pipe: Boolean = false, + flow: Boolean = false, + useSyncReadMem: Boolean = false, + flush: Option[Bool] = None + ): DecoupledIO[T] = { if (entries == 0) { val deq = Wire(new DecoupledIO(chiselTypeOf(enq.bits))) deq.valid := enq.valid @@ -373,12 +389,13 @@ object Queue */ @chiselName def irrevocable[T <: Data]( - enq: ReadyValidIO[T], - entries: Int = 2, - pipe: Boolean = false, - flow: Boolean = false, - useSyncReadMem: Boolean = false, - flush: Option[Bool] = None): IrrevocableIO[T] = { + enq: ReadyValidIO[T], + entries: Int = 2, + pipe: Boolean = false, + flow: Boolean = false, + useSyncReadMem: Boolean = false, + flush: Option[Bool] = None + ): IrrevocableIO[T] = { val deq = apply(enq, entries, pipe, flow, useSyncReadMem, flush) require(entries > 0, "Zero-entry queues don't guarantee Irrevocability") val irr = Wire(new IrrevocableIO(chiselTypeOf(deq.bits))) diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 4501a2de..059506d9 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -26,9 +26,10 @@ import chisel3._ * }}} */ trait Enum { + /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ protected def createValues(n: Int): Seq[UInt] = - (0 until n).map(_.U((1 max log2Ceil(n)).W)) + (0 until n).map(_.U((1.max(log2Ceil(n))).W)) /** Returns n unique UInt values * diff --git a/src/main/scala/chisel3/util/ExtModuleUtils.scala b/src/main/scala/chisel3/util/ExtModuleUtils.scala index 62f384bc..5c9c02ba 100644 --- a/src/main/scala/chisel3/util/ExtModuleUtils.scala +++ b/src/main/scala/chisel3/util/ExtModuleUtils.scala @@ -3,8 +3,13 @@ package chisel3.util import chisel3.experimental.{ChiselAnnotation, ExtModule, RunFirrtlTransform} -import firrtl.transforms.{BlackBoxPathAnno, BlackBoxResourceAnno, BlackBoxInlineAnno, BlackBoxSourceHelper, - BlackBoxNotFoundException} +import firrtl.transforms.{ + BlackBoxInlineAnno, + BlackBoxNotFoundException, + BlackBoxPathAnno, + BlackBoxResourceAnno, + BlackBoxSourceHelper +} import BlackBoxHelpers._ diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 792280ac..99d567ad 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -12,6 +12,6 @@ import scala.language.implicitConversions object ImplicitConversions { // The explicit fromIntToLiteral resolves an ambiguous conversion between fromIntToLiteral and // UInt.asUInt. - implicit def intToUInt(x: Int): UInt = chisel3.fromIntToLiteral(x).asUInt + implicit def intToUInt(x: Int): UInt = chisel3.fromIntToLiteral(x).asUInt implicit def booleanToBool(x: Boolean): Bool = x.B } diff --git a/src/main/scala/chisel3/util/Lookup.scala b/src/main/scala/chisel3/util/Lookup.scala index e0ed694f..f538c4d1 100644 --- a/src/main/scala/chisel3/util/Lookup.scala +++ b/src/main/scala/chisel3/util/Lookup.scala @@ -29,8 +29,9 @@ import chisel3._ object ListLookup { def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = { val map = mapping.map(m => (m._1 === addr, m._2)) - default.zipWithIndex map { case (d, i) => - map.foldRight(d)((m, n) => Mux(m._1, m._2(i), n)) + default.zipWithIndex.map { + case (d, i) => + map.foldRight(d)((m, n) => Mux(m._1, m._2(i), n)) } } } diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala index 2a833e80..6eab9241 100644 --- a/src/main/scala/chisel3/util/Math.scala +++ b/src/main/scala/chisel3/util/Math.scala @@ -47,7 +47,7 @@ object log2Up { object log2Ceil { def apply(in: BigInt): Int = { require(in > 0) - (in-1).bitLength + (in - 1).bitLength } def apply(in: Int): Int = apply(BigInt(in)) } @@ -82,7 +82,7 @@ object log2Down { */ object log2Floor { def apply(in: BigInt): Int = log2Ceil(in) - (if (isPow2(in)) 0 else 1) - def apply(in: Int): Int = apply(BigInt(in)) + def apply(in: Int): Int = apply(BigInt(in)) } /** Returns whether a Scala integer is a power of two. @@ -95,12 +95,12 @@ object log2Floor { * }}} */ object isPow2 { - def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) - def apply(in: Int): Boolean = apply(BigInt(in)) + def apply(in: BigInt): Boolean = in > 0 && ((in & (in - 1)) == 0) + def apply(in: Int): Boolean = apply(BigInt(in)) } - object unsignedBitLength { + /** Return the number of bits required to encode a specific value, assuming no sign bit is required. * * Basically, `n.bitLength`. NOTE: This will return 0 for a value of 0. @@ -115,6 +115,7 @@ object unsignedBitLength { } object signedBitLength { + /** Return the number of bits required to encode a specific value, assuming a sign bit is required. * * Basically, 0 for 0, 1 for -1, and `n.bitLength` + 1 for everything else. @@ -124,9 +125,9 @@ object signedBitLength { */ def apply(in: BigInt): Int = { in.toInt match { - case 0 => 0 + case 0 => 0 case -1 => 1 - case _ => in.bitLength + 1 + case _ => in.bitLength + 1 } } diff --git a/src/main/scala/chisel3/util/MixedVec.scala b/src/main/scala/chisel3/util/MixedVec.scala index 14d6be38..5f8c9da8 100644 --- a/src/main/scala/chisel3/util/MixedVec.scala +++ b/src/main/scala/chisel3/util/MixedVec.scala @@ -19,6 +19,7 @@ import scala.collection.immutable.ListMap * }}} */ object MixedVecInit { + /** * Create a MixedVec wire from a Seq of values. */ @@ -45,6 +46,7 @@ object MixedVecInit { * @return MixedVec with the given types. */ object MixedVec { + /** * Create a MixedVec type from a Seq of Chisel types. */ @@ -111,7 +113,7 @@ final class MixedVec[T <: Data](private val eltsIn: Seq[T]) extends Record with */ def :=(that: Seq[T]): Unit = { require(this.length == that.length) - for ((a, b) <- this zip that) + for ((a, b) <- this.zip(that)) a := b } diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala index 946de461..e84b86a4 100644 --- a/src/main/scala/chisel3/util/Mux.scala +++ b/src/main/scala/chisel3/util/Mux.scala @@ -23,8 +23,8 @@ import chisel3._ */ object Mux1H { def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = - apply(sel zip in) - def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in) + apply(sel.zip(in)) + def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in) def apply[T <: Data](sel: UInt, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) def apply(sel: UInt, in: UInt): Bool = (sel & in).orR @@ -44,8 +44,8 @@ object Mux1H { * Returns the output of the Mux tree. */ object PriorityMux { - def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in) - def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) + def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in) + def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel.zip(in)) def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) } @@ -57,12 +57,13 @@ object PriorityMux { * }}} */ object MuxLookup { + /** @param key a key to search for * @param default a default value if nothing is found * @param mapping a sequence to search of keys and values * @return the value found or the default if not */ - def apply[S <: UInt, T <: Data] (key: S, default: T, mapping: Seq[(S, T)]): T = { + def apply[S <: UInt, T <: Data](key: S, default: T, mapping: Seq[(S, T)]): T = { /* If the mapping is defined for all possible values of the key, then don't use the default value */ val (defaultx, mappingx) = key.widthOption match { case Some(width) => @@ -77,7 +78,7 @@ object MuxLookup { case None => (default, mapping) } - mappingx.foldLeft(defaultx){ case (d, (k, v)) => Mux(k === key, v, d) } + mappingx.foldLeft(defaultx) { case (d, (k, v)) => Mux(k === key, v, d) } } } @@ -89,12 +90,14 @@ object MuxLookup { * }}} */ object MuxCase { + /** @param default the default value if none are enabled * @param mapping a set of data values with associated enables - * @return the first value in mapping that is enabled */ - def apply[T <: Data] (default: T, mapping: Seq[(Bool, T)]): T = { + * @return the first value in mapping that is enabled + */ + def apply[T <: Data](default: T, mapping: Seq[(Bool, T)]): T = { var res = default - for ((t, v) <- mapping.reverse){ + for ((t, v) <- mapping.reverse) { res = Mux(t, v, res) } res diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 03f470c7..23b350e5 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -20,15 +20,15 @@ import chisel3._ object OHToUInt { def apply(in: Seq[Bool]): UInt = apply(Cat(in.reverse), in.size) def apply(in: Vec[Bool]): UInt = apply(in.asUInt, in.size) - def apply(in: Bits): UInt = apply(in, in.getWidth) + def apply(in: Bits): UInt = apply(in, in.getWidth) def apply(in: Bits, width: Int): UInt = { if (width <= 2) { Log2(in, width) } else { - val mid = 1 << (log2Ceil(width)-1) - val hi = in(width-1, mid) - val lo = in(mid-1, 0) + val mid = 1 << (log2Ceil(width) - 1) + val hi = in(width - 1, mid) + val lo = in(mid - 1, 0) Cat(hi.orR, apply(hi | lo, mid)) } } @@ -44,7 +44,7 @@ object OHToUInt { */ object PriorityEncoder { def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(_.asUInt)) - def apply(in: Bits): UInt = apply(in.asBools) + def apply(in: Bits): UInt = apply(in.asBools) } /** Returns the one hot encoding of the input UInt. @@ -52,7 +52,6 @@ object PriorityEncoder { * @example {{{ * UIntToOH(2.U) // results in "b0100".U * }}} - * */ object UIntToOH { def apply(in: UInt): UInt = 1.U << in diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index e2b5d172..ddb74dd6 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -5,6 +5,7 @@ package chisel3.util import chisel3._ object RegEnable { + /** Returns a register with the specified next, update enable gate, and no reset initialization. * * @example {{{ @@ -13,7 +14,7 @@ object RegEnable { */ def apply[T <: Data](next: T, enable: Bool): T = { val r = Reg(chiselTypeOf(next)) - when (enable) { r := next } + when(enable) { r := next } r } @@ -25,13 +26,13 @@ object RegEnable { */ def apply[T <: Data](next: T, init: T, enable: Bool): T = { val r = RegInit(init) - when (enable) { r := next } + when(enable) { r := next } r } } -object ShiftRegister -{ +object ShiftRegister { + /** Returns the n-cycle delayed version of the input signal. * * @param in input to delay @@ -55,18 +56,17 @@ object ShiftRegister * val regDelayTwoReset = ShiftRegister(nextVal, 2, 0.U, ena) * }}} */ - def apply[T <: Data](in: T, n: Int, resetData: T, en: Bool): T = ShiftRegisters(in, n, resetData, en).lastOption.getOrElse(in) + def apply[T <: Data](in: T, n: Int, resetData: T, en: Bool): T = + ShiftRegisters(in, n, resetData, en).lastOption.getOrElse(in) } +object ShiftRegisters { -object ShiftRegisters -{ /** Returns a sequence of delayed input signal registers from 1 to n. * * @param in input to delay * @param n number of cycles to delay * @param en enable the shift - * */ def apply[T <: Data](in: T, n: Int, en: Bool = true.B): Seq[T] = Seq.iterate(in, n + 1)(util.RegEnable(_, en)).drop(1) @@ -77,7 +77,6 @@ object ShiftRegisters * @param n number of cycles to delay * @param resetData reset value for each register in the shift * @param en enable the shift - * */ def apply[T <: Data](in: T, n: Int, resetData: T, en: Bool): Seq[T] = Seq.iterate(in, n + 1)(util.RegEnable(_, resetData, en)).drop(1) diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala index 97c13696..cc8f2456 100644 --- a/src/main/scala/chisel3/util/TransitName.scala +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -42,24 +42,23 @@ object TransitName { * @param to the thing that will receive the "good" name * @return the `from` parameter */ - def apply[T<:HasId](from: T, to: HasId): T = { + def apply[T <: HasId](from: T, to: HasId): T = { // To transit a name, we need to hook on both the suggestName and autoSeed mechanisms - from.addSuggestPostnameHook((given_name: String) => {to.suggestName(given_name)}) - from.addAutoPostnameHook((given_name: String) => {to.autoSeed(given_name)}) + from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name) }) + from.addAutoPostnameHook((given_name: String) => { to.autoSeed(given_name) }) from } - /** Transit a name from one type to another ''and add a suffix'' * @param suffix the suffix to append * @param from the thing with a "good" name * @param to the thing that will receive the "good" name * @return the `from` parameter */ - def withSuffix[T<:HasId](suffix: String)(from: T, to: HasId): T = { + def withSuffix[T <: HasId](suffix: String)(from: T, to: HasId): T = { // To transit a name, we need to hook on both the suggestName and autoSeed mechanisms - from.addSuggestPostnameHook((given_name: String) => {to.suggestName(given_name + suffix)}) - from.addAutoPostnameHook((given_name: String) => {to.autoSeed(given_name + suffix)}) + from.addSuggestPostnameHook((given_name: String) => { to.suggestName(given_name + suffix) }) + from.addAutoPostnameHook((given_name: String) => { to.autoSeed(given_name + suffix) }) from } diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 5d80502a..eeb2ab68 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -20,7 +20,8 @@ import chisel3._ * @groupdesc Signals The actual hardware fields of the Bundle */ class Valid[+T <: Data](gen: T) extends Bundle { - /** A bit that will be asserted when `bits` is valid + + /** A bit that will be asserted when `bits` is valid * @group Signals */ val valid = Output(Bool()) @@ -28,14 +29,17 @@ class Valid[+T <: Data](gen: T) extends Bundle { /** The data to be transferred, qualified by `valid` * @group Signals */ - val bits = Output(gen) + val bits = Output(gen) /** True when `valid` is asserted * @return a Chisel [[Bool]] true if `valid` is asserted */ def fire: Bool = valid - @deprecated("Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", "Chisel 3.5") + @deprecated( + "Calling this function with an empty argument list is invalid in Scala 3. Use the form without parentheses instead", + "Chisel 3.5" + ) def fire(dummy: Int = 0): Bool = valid } @@ -122,7 +126,7 @@ object Pipe { } else { val v = RegNext(enqValid, false.B) val b = RegEnable(enqBits, enqValid) - val out = apply(v, b, latency-1)(compileOptions) + val out = apply(v, b, latency - 1)(compileOptions) TransitName.withSuffix("Pipe_valid")(out, v) TransitName.withSuffix("Pipe_bits")(out, b) @@ -182,12 +186,12 @@ class Pipe[T <: Data](val gen: T, val latency: Int = 1)(implicit compileOptions: */ class PipeIO extends Bundle { - /** [[Valid]] input + /** [[Valid]] input * @group Signals */ val enq = Input(Valid(gen)) - /** [[Valid]] output. Data will appear here `latency` cycles after being valid at `enq`. + /** [[Valid]] output. Data will appear here `latency` cycles after being valid at `enq`. * @group Signals */ val deq = Output(Valid(gen)) diff --git a/src/main/scala/chisel3/util/experimental/BoringUtils.scala b/src/main/scala/chisel3/util/experimental/BoringUtils.scala index f2a3e757..254f83a4 100644 --- a/src/main/scala/chisel3/util/experimental/BoringUtils.scala +++ b/src/main/scala/chisel3/util/experimental/BoringUtils.scala @@ -3,11 +3,11 @@ package chisel3.util.experimental import chisel3._ -import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} import chisel3.internal.{InstanceId, NamedComponent, Namespace} import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation} -import firrtl.passes.wiring.{WiringTransform, SourceAnnotation, SinkAnnotation} -import firrtl.annotations.{ModuleName, ComponentName} +import firrtl.passes.wiring.{SinkAnnotation, SourceAnnotation, WiringTransform} +import firrtl.annotations.{ComponentName, ModuleName} import scala.concurrent.SyncVar @@ -122,20 +122,25 @@ object BoringUtils { * @note if a uniqueName is not specified, the returned name may differ from the user-provided name */ def addSource( - component: NamedComponent, - name: String, + component: NamedComponent, + name: String, disableDedup: Boolean = false, - uniqueName: Boolean = false): String = { + uniqueName: Boolean = false + ): String = { - val id = if (uniqueName) { newName(name) } else { name } + val id = if (uniqueName) { newName(name) } + else { name } val maybeDedup = if (disableDedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(component.toNamed.module) }) } - else { Seq[ChiselAnnotation]() } + else { Seq[ChiselAnnotation]() } val annotations = - Seq(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl = SourceAnnotation(component.toNamed, id) - def transformClass = classOf[WiringTransform] }, - new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(component.toNamed) } ) ++ maybeDedup + Seq( + new ChiselAnnotation with RunFirrtlTransform { + def toFirrtl = SourceAnnotation(component.toNamed, id) + def transformClass = classOf[WiringTransform] + }, + new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(component.toNamed) } + ) ++ maybeDedup annotations.foreach(annotate(_)) id @@ -150,25 +155,28 @@ object BoringUtils { * @throws BoringUtilsException if name is expected to exist and it doesn't */ def addSink( - component: InstanceId, - name: String, + component: InstanceId, + name: String, disableDedup: Boolean = false, - forceExists: Boolean = false): Unit = { + forceExists: Boolean = false + ): Unit = { if (forceExists && !checkName(name)) { - throw new BoringUtilsException(s"Sink ID '$name' not found in BoringUtils ID namespace") } + throw new BoringUtilsException(s"Sink ID '$name' not found in BoringUtils ID namespace") + } def moduleName = component.toNamed match { - case c: ModuleName => c + case c: ModuleName => c case c: ComponentName => c.module case _ => throw new ChiselException("Can only add a Module or Component sink", null) } val maybeDedup = if (disableDedup) { Seq(new ChiselAnnotation { def toFirrtl = NoDedupAnnotation(moduleName) }) } - else { Seq[ChiselAnnotation]() } + else { Seq[ChiselAnnotation]() } val annotations = Seq(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl = SinkAnnotation(component.toNamed, name) - def transformClass = classOf[WiringTransform] }) ++ maybeDedup + def toFirrtl = SinkAnnotation(component.toNamed, name) + def transformClass = classOf[WiringTransform] + }) ++ maybeDedup annotations.foreach(annotate(_)) } @@ -181,11 +189,12 @@ object BoringUtils { * component */ def bore(source: Data, sinks: Seq[Data]): String = { - val boringName = try { - source.instanceName - } catch { - case _: Exception => "bore" - } + val boringName = + try { + source.instanceName + } catch { + case _: Exception => "bore" + } val genName = addSource(source, boringName, true, true) sinks.foreach(addSink(_, genName, true, true)) genName diff --git a/src/main/scala/chisel3/util/experimental/ForceNames.scala b/src/main/scala/chisel3/util/experimental/ForceNames.scala index bac69ed4..53ee2bd2 100644 --- a/src/main/scala/chisel3/util/experimental/ForceNames.scala +++ b/src/main/scala/chisel3/util/experimental/ForceNames.scala @@ -2,7 +2,7 @@ package chisel3.util.experimental -import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} import firrtl.Mappers._ import firrtl._ import firrtl.annotations._ @@ -49,7 +49,7 @@ object forceName { * @param instance Instance to name */ def apply(instance: chisel3.experimental.BaseModule, name: String): Unit = { - annotate(new ChiselAnnotation with RunFirrtlTransform { + annotate(new ChiselAnnotation with RunFirrtlTransform { def toFirrtl = { val t = instance.toAbsoluteTarget ForceNameAnnotation(t, name) @@ -64,7 +64,7 @@ object forceName { * @param instance Signal to name */ def apply(instance: chisel3.experimental.BaseModule): Unit = { - annotate(new ChiselAnnotation with RunFirrtlTransform { + annotate(new ChiselAnnotation with RunFirrtlTransform { def toFirrtl = { val t = instance.toAbsoluteTarget ForceNameAnnotation(t, instance.instanceName) @@ -80,8 +80,7 @@ object forceName { * @param target signal/instance to force the name * @param name name to force it to be */ -case class ForceNameAnnotation(target: IsMember, name: String) - extends SingleTargetAnnotation[IsMember] { +case class ForceNameAnnotation(target: IsMember, name: String) extends SingleTargetAnnotation[IsMember] { def duplicate(n: IsMember): ForceNameAnnotation = this.copy(target = n, name) // Errors if renaming to multiple targets @@ -105,6 +104,7 @@ case class ForceNameAnnotation(target: IsMember, name: String) * Could (should?) be moved to FIRRTL. */ private object ForceNamesTransform { + /** Returns the [[IsModule]] which is referred to, or if a [[ReferenceTarget]], the enclosing [[IsModule]] * * @param a signal/instance/module @@ -123,10 +123,12 @@ private object ForceNamesTransform { */ def allInstancePaths(graph: InstanceKeyGraph): IsModule => List[List[(Instance, OfModule)]] = { val lookup: String => List[List[(Instance, OfModule)]] = - str => graph.findInstancesInHierarchy(str) - .view - .map(_.map(_.toTokens).toList) - .toList + str => + graph + .findInstancesInHierarchy(str) + .view + .map(_.map(_.toTokens).toList) + .toList allInstancePaths(lookup) _ } @@ -136,8 +138,10 @@ private object ForceNamesTransform { * @param target target to get all instance paths to * @return */ - def allInstancePaths(lookup: String => List[List[(Instance, OfModule)]]) - (target: IsModule): List[List[(Instance, OfModule)]] = { + def allInstancePaths( + lookup: String => List[List[(Instance, OfModule)]] + )(target: IsModule + ): List[List[(Instance, OfModule)]] = { target match { case ModuleTarget(circuit, module) => if (circuit == module) List(List((Instance(module), OfModule(module)))) @@ -149,16 +153,13 @@ private object ForceNamesTransform { } } - /** Builds the map of module name to map of old signal/instance name to new signal/instance name * * @param state CircuitState to operate on * @param igraph built instance key graph from state's circuit * @return */ - def buildForceNameMap(state: CircuitState, - igraph: => InstanceKeyGraph - ): Option[Map[String, Map[String, String]]] = { + def buildForceNameMap(state: CircuitState, igraph: => InstanceKeyGraph): Option[Map[String, Map[String, String]]] = { val forceNames = state.annotations.collect { case f: ForceNameAnnotation => f } val badNames = mutable.HashSet[ForceNameAnnotation]() val allNameMaps = forceNames.groupBy { case f => referringIsModule(f.target) }.mapValues { value => @@ -207,9 +208,9 @@ private object ForceNamesTransform { * - Use to avoid prefixing behavior on specific instances whose enclosing modules are inlined */ class ForceNamesTransform extends Transform with DependencyAPIMigration { - override def optionalPrerequisites: Seq[TransformDependency] = Seq(Dependency[InlineInstances]) + override def optionalPrerequisites: Seq[TransformDependency] = Seq(Dependency[InlineInstances]) override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters - override def prerequisites: Seq[TransformDependency] = Seq(Dependency(LowerTypes)) + override def prerequisites: Seq[TransformDependency] = Seq(Dependency(LowerTypes)) override def invalidates(a: Transform): Boolean = firrtl.passes.InferTypes == a import ForceNamesTransform._ @@ -226,22 +227,23 @@ class ForceNamesTransform extends Transform with DependencyAPIMigration { */ private def forceNamesInModule( modToNames: Map[String, Map[String, String]], - renameMap: RenameMap, - ct: CircuitTarget, - igraph: InstanceKeyGraph - )(mod: DefModule): DefModule = { + renameMap: RenameMap, + ct: CircuitTarget, + igraph: InstanceKeyGraph + )(mod: DefModule + ): DefModule = { val mt = ct.module(mod.name) val instToOfModule = mutable.HashMap[String, String]() val names = modToNames.getOrElse(mod.name, Map.empty[String, String]) // Need to find WRef referring to mems for prefixing def onExpr(expr: Expression): Expression = expr match { - case ref @ Reference(n, _,_,_) if names.contains(n) => + case ref @ Reference(n, _, _, _) if names.contains(n) => ref.copy(name = names(n)) - case sub @ SubField(WRef(i, _, _, _), p,_,_) if instToOfModule.contains(i) => + case sub @ SubField(WRef(i, _, _, _), p, _, _) if instToOfModule.contains(i) => val newsub = modToNames.get(instToOfModule(i)) match { case Some(map) if map.contains(p) => sub.copy(name = map(p)) - case _ => sub + case _ => sub } newsub.map(onExpr) case other => other.map(onExpr) @@ -269,17 +271,19 @@ class ForceNamesTransform extends Transform with DependencyAPIMigration { } else port } - val childInstanceHasRename = igraph.getChildInstanceMap(OfModule(mod.name)).exists { - o => modToNames.contains(o._2.value) + val childInstanceHasRename = igraph.getChildInstanceMap(OfModule(mod.name)).exists { o => + modToNames.contains(o._2.value) } - if(childInstanceHasRename || modToNames.contains(mod.name)) { + if (childInstanceHasRename || modToNames.contains(mod.name)) { val ns = Namespace(mod) val conflicts = names.values.collect { case k if ns.contains(k) => k } - if(conflicts.isEmpty) { + if (conflicts.isEmpty) { mod.map(onPort).map(onStmt) } else { - throw new FirrtlUserException(s"Cannot force the following names in module ${mod.name} because they conflict: ${conflicts.mkString(",")}") + throw new FirrtlUserException( + s"Cannot force the following names in module ${mod.name} because they conflict: ${conflicts.mkString(",")}" + ) } } else mod } diff --git a/src/main/scala/chisel3/util/experimental/Inline.scala b/src/main/scala/chisel3/util/experimental/Inline.scala index 1d5fcb89..fd5c6aa5 100644 --- a/src/main/scala/chisel3/util/experimental/Inline.scala +++ b/src/main/scala/chisel3/util/experimental/Inline.scala @@ -6,7 +6,7 @@ import chisel3._ import chisel3.experimental.{BaseModule, ChiselAnnotation, RunFirrtlTransform} import firrtl.Transform import firrtl.passes.{InlineAnnotation, InlineInstances} -import firrtl.transforms.{NoDedupAnnotation, FlattenAnnotation, Flatten} +import firrtl.transforms.{Flatten, FlattenAnnotation, NoDedupAnnotation} import firrtl.annotations.Annotation /** Inlines an instance of a module @@ -40,11 +40,15 @@ import firrtl.annotations.Annotation * }}} */ trait InlineInstance { self: BaseModule => - Seq(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = InlineAnnotation(self.toNamed) - def transformClass: Class[_ <: Transform] = classOf[InlineInstances] }, - new ChiselAnnotation { - def toFirrtl: Annotation = NoDedupAnnotation(self.toNamed) }) + Seq( + new ChiselAnnotation with RunFirrtlTransform { + def toFirrtl: Annotation = InlineAnnotation(self.toNamed) + def transformClass: Class[_ <: Transform] = classOf[InlineInstances] + }, + new ChiselAnnotation { + def toFirrtl: Annotation = NoDedupAnnotation(self.toNamed) + } + ) .map(chisel3.experimental.annotate(_)) } @@ -75,10 +79,14 @@ trait InlineInstance { self: BaseModule => * }}} */ trait FlattenInstance { self: BaseModule => - Seq(new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = FlattenAnnotation(self.toNamed) - def transformClass: Class[_ <: Transform] = classOf[Flatten] }, - new ChiselAnnotation { - def toFirrtl: Annotation = NoDedupAnnotation(self.toNamed) }) - .map(chisel3.experimental.annotate(_)) + Seq( + new ChiselAnnotation with RunFirrtlTransform { + def toFirrtl: Annotation = FlattenAnnotation(self.toNamed) + def transformClass: Class[_ <: Transform] = classOf[Flatten] + }, + new ChiselAnnotation { + def toFirrtl: Annotation = NoDedupAnnotation(self.toNamed) + } + ) + .map(chisel3.experimental.annotate(_)) } diff --git a/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala b/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala index 93981485..bd46abe9 100644 --- a/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala +++ b/src/main/scala/chisel3/util/experimental/LoadMemoryTransform.scala @@ -3,7 +3,7 @@ package chisel3.util.experimental import chisel3._ -import chisel3.experimental.{RunFirrtlTransform, annotate, ChiselAnnotation} +import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} import firrtl.annotations._ import firrtl.ir.{Module => _, _} import firrtl.transforms.BlackBoxInlineAnno @@ -21,11 +21,11 @@ import scala.collection.mutable case class ChiselLoadMemoryAnnotation[T <: Data]( target: MemBase[T], fileName: String, - hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex -) - extends ChiselAnnotation with RunFirrtlTransform { + hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex) + extends ChiselAnnotation + with RunFirrtlTransform { - if(fileName.isEmpty) { + if (fileName.isEmpty) { throw new Exception( s"""LoadMemory from file annotations file empty file name""" ) @@ -39,7 +39,6 @@ case class ChiselLoadMemoryAnnotation[T <: Data]( } } - /** [[loadMemoryFromFile]] is an annotation generator that helps with loading a memory from a text file as a bind module. This relies on * Verilator and Verilog's `\$readmemh` or `\$readmemb`. The [[https://github.com/freechipsproject/treadle Treadle * backend]] can also recognize this annotation and load memory at run-time. @@ -101,22 +100,20 @@ case class ChiselLoadMemoryAnnotation[T <: Data]( */ object loadMemoryFromFile { - /** Annotate a memory such that it can be initialized using a file * @param memory the memory * @param filename the file used for initialization * @param hexOrBinary whether the file uses a hex or binary number representation */ def apply[T <: Data]( - memory: MemBase[T], - fileName: String, + memory: MemBase[T], + fileName: String, hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex ): Unit = { annotate(ChiselLoadMemoryAnnotation(memory, fileName, hexOrBinary)) } } - /** [[loadMemoryFromFileInline]] is an annotation generator that helps with loading a memory from a text file inlined in * the Verilog module. This relies on Verilator and Verilog's `\$readmemh` or `\$readmemb`. * The [[https://github.com/freechipsproject/treadle Treadlebackend]] can also recognize this annotation and load memory at run-time. @@ -179,15 +176,14 @@ object loadMemoryFromFile { */ object loadMemoryFromFileInline { - /** Annotate a memory such that it can be initialized inline using a file * @param memory the memory * @param fileName the file used for initialization * @param hexOrBinary whether the file uses a hex or binary number representation */ def apply[T <: Data]( - memory: MemBase[T], - fileName: String, + memory: MemBase[T], + fileName: String, hexOrBinary: MemoryLoadFileType.FileType = MemoryLoadFileType.Hex ): Unit = { annotate(new ChiselAnnotation { @@ -204,14 +200,14 @@ object loadMemoryFromFileInline { * not need this transform to do that. */ class LoadMemoryTransform extends Transform { - def inputForm: CircuitForm = LowForm + def inputForm: CircuitForm = LowForm def outputForm: CircuitForm = LowForm private var memoryCounter: Int = -1 private val bindModules: mutable.ArrayBuffer[BlackBoxInlineAnno] = new mutable.ArrayBuffer() - private val verilogEmitter: VerilogEmitter = new VerilogEmitter + private val verilogEmitter: VerilogEmitter = new VerilogEmitter /** run the pass * @param circuit the circuit @@ -219,19 +215,19 @@ class LoadMemoryTransform extends Transform { * @return */ def run(circuit: Circuit, annotations: AnnotationSeq): Circuit = { - val groups = annotations - .collect{ case m: LoadMemoryAnnotation => m } + val groups = annotations.collect { case m: LoadMemoryAnnotation => m } .groupBy(_.target.serialize) - val memoryAnnotations = groups.map { case (key, annos) => + val memoryAnnotations = groups.map { + case (key, annos) => if (annos.size > 1) { throw new Exception( s"Multiple (${annos.size} found for memory $key one LoadMemoryAnnotation is allowed per memory" ) } key -> annos.head - } + } - val modulesByName = circuit.modules.collect { case module: firrtl.ir.Module => module.name -> module }.toMap + val modulesByName = circuit.modules.collect { case module: firrtl.ir.Module => module.name -> module }.toMap /* Walk the module and for memories that are annotated with [[LoadMemoryAnnotation]]s generate the bindable modules for * Verilog emission. @@ -251,32 +247,34 @@ class LoadMemoryTransform extends Transform { val writer = new java.io.StringWriter val readmem = hexOrBinary match { case MemoryLoadFileType.Binary => "$readmemb" - case MemoryLoadFileType.Hex => "$readmemh" + case MemoryLoadFileType.Hex => "$readmemh" } modulesByName.get(moduleName.name).foreach { module => - val renderer = verilogEmitter.getRenderer(module, modulesByName)(writer) - val loadFileName = lma.getFileName - - memoryCounter += 1 - val bindsToName = s"BindsTo_${memoryCounter}_${moduleName.name}" - renderer.emitVerilogBind(bindsToName, - s""" - |initial begin - | $readmem("$loadFileName", ${myModule.name}.$componentName); - |end - """.stripMargin) - val inLineText = writer.toString + "\n" + - s"""bind ${myModule.name} $bindsToName ${bindsToName}_Inst(.*);""" - - val blackBoxInline = BlackBoxInlineAnno( - moduleName, - moduleName.serialize + "." + componentName + ".v", - inLineText - ) - - bindModules += blackBoxInline - } + val renderer = verilogEmitter.getRenderer(module, modulesByName)(writer) + val loadFileName = lma.getFileName + + memoryCounter += 1 + val bindsToName = s"BindsTo_${memoryCounter}_${moduleName.name}" + renderer.emitVerilogBind( + bindsToName, + s""" + |initial begin + | $readmem("$loadFileName", ${myModule.name}.$componentName); + |end + """.stripMargin + ) + val inLineText = writer.toString + "\n" + + s"""bind ${myModule.name} $bindsToName ${bindsToName}_Inst(.*);""" + + val blackBoxInline = BlackBoxInlineAnno( + moduleName, + moduleName.serialize + "." + componentName + ".v", + inLineText + ) + + bindModules += blackBoxInline + } case _ => } @@ -284,8 +282,8 @@ class LoadMemoryTransform extends Transform { def processStatements(statement: Statement): Statement = { statement match { - case m: DefMemory => processMemory(m.name) - case s => s map processStatements + case m: DefMemory => processMemory(m.name) + case s => s.map(processStatements) } statement } @@ -299,7 +297,7 @@ class LoadMemoryTransform extends Transform { myModule } - circuit map processModule + circuit.map(processModule) } def execute(state: CircuitState): CircuitState = { @@ -309,11 +307,10 @@ class LoadMemoryTransform extends Transform { case _ => false } - if(isVerilog) { + if (isVerilog) { run(state.circuit, state.annotations) state.copy(annotations = state.annotations ++ bindModules) - } - else { + } else { state } } diff --git a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala index 4dcea99e..de2f207b 100644 --- a/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala +++ b/src/main/scala/chisel3/util/experimental/decode/EspressoMinimizer.scala @@ -19,7 +19,7 @@ case object EspressoNotFoundException extends Exception */ object EspressoMinimizer extends Minimizer with LazyLogging { def minimize(table: TruthTable): TruthTable = - TruthTable.merge(TruthTable.split(table).map{case (table, indexes) => (espresso(table), indexes)}) + TruthTable.merge(TruthTable.split(table).map { case (table, indexes) => (espresso(table), indexes) }) private def espresso(table: TruthTable): TruthTable = { def writeTable(table: TruthTable): String = { @@ -34,10 +34,9 @@ object EspressoMinimizer extends Minimizer with LazyLogging { } val tableType: String = defaultType match { case '?' => "fr" - case _ => "fd" + case _ => "fd" } - val rawTable = table - .toString + val rawTable = table.toString .split("\n") .filter(_.contains("->")) .mkString("\n") @@ -69,11 +68,13 @@ object EspressoMinimizer extends Minimizer with LazyLogging { logger.trace(s"""espresso input table: |$input |""".stripMargin) - val output = try { - os.proc("espresso").call(stdin = input).out.chunks.mkString - } catch { - case e: java.io.IOException if e.getMessage.contains("error=2, No such file or directory") => throw EspressoNotFoundException - } + val output = + try { + os.proc("espresso").call(stdin = input).out.chunks.mkString + } catch { + case e: java.io.IOException if e.getMessage.contains("error=2, No such file or directory") => + throw EspressoNotFoundException + } logger.trace(s"""espresso output table: |$output |""".stripMargin) diff --git a/src/main/scala/chisel3/util/experimental/decode/Minimizer.scala b/src/main/scala/chisel3/util/experimental/decode/Minimizer.scala index 86847710..c4065ac9 100644 --- a/src/main/scala/chisel3/util/experimental/decode/Minimizer.scala +++ b/src/main/scala/chisel3/util/experimental/decode/Minimizer.scala @@ -3,6 +3,7 @@ package chisel3.util.experimental.decode abstract class Minimizer { + /** Minimize a multi-input multi-output logic function given by the truth table `table`, with function output values * on unspecified inputs treated as `default`, and return a minimized PLA-like representation of the function. * @@ -26,4 +27,4 @@ abstract class Minimizer { * }}} */ def minimize(table: TruthTable): TruthTable -}
\ No newline at end of file +} diff --git a/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala b/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala index 59120221..a3481869 100644 --- a/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala +++ b/src/main/scala/chisel3/util/experimental/decode/QMCMinimizer.scala @@ -125,12 +125,15 @@ object QMCMinimizer extends Minimizer { * b: nonessential prime implicants * c: implicants that are not cover by any of the essential prime implicants */ - private def getEssentialPrimeImplicants(primes: Seq[Implicant], minterms: Seq[Implicant]): (Seq[Implicant], Seq[Implicant], Seq[Implicant]) = { + private def getEssentialPrimeImplicants( + primes: Seq[Implicant], + minterms: Seq[Implicant] + ): (Seq[Implicant], Seq[Implicant], Seq[Implicant]) = { // primeCovers(i): implicants that `prime(i)` covers val primeCovers = primes.map(p => minterms.filter(p.covers)) // eliminate prime implicants that can be covered by other prime implicants - for (((icover, pi), i) <- (primeCovers zip primes).zipWithIndex) { - for (((jcover, pj), _) <- (primeCovers zip primes).zipWithIndex.drop(i + 1)) { + for (((icover, pi), i) <- (primeCovers.zip(primes)).zipWithIndex) { + for (((jcover, pj), _) <- (primeCovers.zip(primes)).zipWithIndex.drop(i + 1)) { // we prefer prime implicants with wider implicants coverage if (icover.size > jcover.size && jcover.forall(pi.covers)) { // calculate essential prime implicants with `pj` eliminated from prime implicants table @@ -165,6 +168,7 @@ object QMCMinimizer extends Minimizer { * @return Selected nonessential prime implicants */ private def getCover(implicants: Seq[Implicant], minterms: Seq[Implicant]): Seq[Implicant] = { + /** Calculate the implementation cost (using comparators) of a list of implicants, more don't cares is cheaper * * @param cover Implicant list @@ -193,7 +197,8 @@ object QMCMinimizer extends Minimizer { * @return `a` < `b` */ @tailrec - def listLess(a: Seq[Implicant], b: Seq[Implicant]): Boolean = b.nonEmpty && (a.isEmpty || a.head < b.head || a.head == b.head && listLess(a.tail, b.tail)) + def listLess(a: Seq[Implicant], b: Seq[Implicant]): Boolean = + b.nonEmpty && (a.isEmpty || a.head < b.head || a.head == b.head && listLess(a.tail, b.tail)) ca < cb || ca == cb && listLess(a.sortWith(_ < _), b.sortWith(_ < _)) } @@ -216,8 +221,14 @@ object QMCMinimizer extends Minimizer { // extract decode table to inputs and outputs val (inputs, outputs) = table.table.unzip - require(outputs.map(_.getWidth == table.default.getWidth).reduce(_ && _), "All output BitPats and default BitPat must have the same length") - require(if (inputs.toSeq.length > 1) inputs.tail.map(_.width == inputs.head.width).reduce(_ && _) else true, "All input BitPats must have the same length") + require( + outputs.map(_.getWidth == table.default.getWidth).reduce(_ && _), + "All output BitPats and default BitPat must have the same length" + ) + require( + if (inputs.toSeq.length > 1) inputs.tail.map(_.width == inputs.head.width).reduce(_ && _) else true, + "All input BitPats must have the same length" + ) // make sure no two inputs specified in the truth table intersect for (t <- inputs.tails; if t.nonEmpty) @@ -234,9 +245,11 @@ object QMCMinimizer extends Minimizer { val outputBp = BitPat("b" + "?" * (m - i - 1) + "1" + "?" * i) // Minterms, implicants that makes the output to be 1 - val mint: Seq[Implicant] = table.table.filter { case (_, t) => t.mask.testBit(i) && t.value.testBit(i) }.map(_._1).map(toImplicant) + val mint: Seq[Implicant] = + table.table.filter { case (_, t) => t.mask.testBit(i) && t.value.testBit(i) }.map(_._1).map(toImplicant) // Maxterms, implicants that makes the output to be 0 - val maxt: Seq[Implicant] = table.table.filter { case (_, t) => t.mask.testBit(i) && !t.value.testBit(i) }.map(_._1).map(toImplicant) + val maxt: Seq[Implicant] = + table.table.filter { case (_, t) => t.mask.testBit(i) && !t.value.testBit(i) }.map(_._1).map(toImplicant) // Don't cares, implicants that can produce either 0 or 1 as output val dc: Seq[Implicant] = table.table.filter { case (_, t) => !t.mask.testBit(i) }.map(_._1).map(toImplicant) @@ -251,16 +264,14 @@ object QMCMinimizer extends Minimizer { implicants.foreach(_.isPrime = true) val cols = (0 to n).reverse.map(b => implicants.filter(b == _.bp.mask.bitCount)) - val mergeTable = cols.map( - c => (0 to n).map( - b => collection.mutable.Set(c.filter(b == _.bp.value.bitCount):_*) - ) - ) + val mergeTable = cols.map(c => (0 to n).map(b => collection.mutable.Set(c.filter(b == _.bp.value.bitCount): _*))) // O(n ^ 3) for (i <- 0 to n) { for (j <- 0 until n - i) { - mergeTable(i)(j).foreach(a => mergeTable(i + 1)(j) ++= mergeTable(i)(j + 1).filter(_ similar a).map(_ merge a)) + mergeTable(i)(j).foreach(a => + mergeTable(i + 1)(j) ++= mergeTable(i)(j + 1).filter(_.similar(a)).map(_.merge(a)) + ) } if (defaultToDc) { for (j <- 0 until n - i) { @@ -268,14 +279,14 @@ object QMCMinimizer extends Minimizer { if (a.bp.mask.testBit(i) && !a.bp.value.testBit(i)) { // this bit is `0` val t = new BitPat(a.bp.value.setBit(i), a.bp.mask, a.width) - if (!maxt.exists(_.intersects(t))) mergeTable(i + 1)(j) += t merge a + if (!maxt.exists(_.intersects(t))) mergeTable(i + 1)(j) += t.merge(a) } } for (a <- mergeTable(i)(j + 1).filter(_.isPrime)) { if (a.bp.mask.testBit(i) && a.bp.value.testBit(i)) { // this bit is `1` val t = new BitPat(a.bp.value.clearBit(i), a.bp.mask, a.width) - if (!maxt.exists(_.intersects(t))) mergeTable(i + 1)(j) += a merge t + if (!maxt.exists(_.intersects(t))) mergeTable(i + 1)(j) += a.merge(t) } } } @@ -288,20 +299,29 @@ object QMCMinimizer extends Minimizer { val (essentialPrimeImplicants, nonessentialPrimeImplicants, uncoveredImplicants) = getEssentialPrimeImplicants(primeImplicants, implicants) - (essentialPrimeImplicants ++ getCover(nonessentialPrimeImplicants, uncoveredImplicants)).map(a => (a.bp, outputBp)) + (essentialPrimeImplicants ++ getCover(nonessentialPrimeImplicants, uncoveredImplicants)).map(a => + (a.bp, outputBp) + ) }) - minimized.tail.foldLeft(table.copy(table = Seq(minimized.head))) { case (tb, t) => - if (tb.table.exists(x => x._1 == t._1)) { - tb.copy(table = tb.table.map { case (k, v) => - if (k == t._1) { - def ones(bitPat: BitPat) = bitPat.rawString.zipWithIndex.collect{case ('1', x) => x} - (k, BitPat("b" + (0 until v.getWidth).map(i => if ((ones(v) ++ ones(t._2)).contains(i)) "1" else "?").mkString)) - } else (k, v) - }) - } else { - tb.copy(table = tb.table :+ t) - } + minimized.tail.foldLeft(table.copy(table = Seq(minimized.head))) { + case (tb, t) => + if (tb.table.exists(x => x._1 == t._1)) { + tb.copy(table = tb.table.map { + case (k, v) => + if (k == t._1) { + def ones(bitPat: BitPat) = bitPat.rawString.zipWithIndex.collect { case ('1', x) => x } + ( + k, + BitPat( + "b" + (0 until v.getWidth).map(i => if ((ones(v) ++ ones(t._2)).contains(i)) "1" else "?").mkString + ) + ) + } else (k, v) + }) + } else { + tb.copy(table = tb.table :+ t) + } } } -}
\ No newline at end of file +} diff --git a/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala b/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala index 322466f9..e742fd66 100644 --- a/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala +++ b/src/main/scala/chisel3/util/experimental/decode/TruthTable.scala @@ -13,10 +13,11 @@ sealed class TruthTable private (val table: Seq[(BitPat, BitPat)], val default: def writeRow(map: (BitPat, BitPat)): String = s"${map._1.rawString}->${map._2.rawString}" - (table.map(writeRow) ++ Seq(s"${" "*(inputWidth + 2)}${default.rawString}")).mkString("\n") + (table.map(writeRow) ++ Seq(s"${" " * (inputWidth + 2)}${default.rawString}")).mkString("\n") } - def copy(table: Seq[(BitPat, BitPat)] = this.table, default: BitPat = this.default, sort: Boolean = this.sort) = TruthTable(table, default, sort) + def copy(table: Seq[(BitPat, BitPat)] = this.table, default: BitPat = this.default, sort: Boolean = this.sort) = + TruthTable(table, default, sort) override def equals(y: Any): Boolean = { y match { @@ -27,27 +28,36 @@ sealed class TruthTable private (val table: Seq[(BitPat, BitPat)], val default: } object TruthTable { + /** Convert a table and default output into a [[TruthTable]]. */ def apply(table: Iterable[(BitPat, BitPat)], default: BitPat, sort: Boolean = true): TruthTable = { require(table.map(_._1.getWidth).toSet.size == 1, "input width not equal.") require(table.map(_._2.getWidth).toSet.size == 1, "output width not equal.") val outputWidth = table.map(_._2.getWidth).head - val mergedTable = table.groupBy(_._1.toString).map { case (key, values) => - // merge same input inputs. - values.head._1 -> BitPat(s"b${ - Seq.tabulate(outputWidth) { i => - val outputSet = values.map(_._2) - .map(_.rawString) - .map(_ (i)) - .toSet - .filterNot(_ == '?') - require(outputSet.size != 2, s"TruthTable conflict in :\n${values.map { case (i, o) => s"${i.rawString}->${o.rawString}" }.mkString("\n")}") - outputSet.headOption.getOrElse('?') - }.mkString - }") - }.toSeq + val mergedTable = table + .groupBy(_._1.toString) + .map { + case (key, values) => + // merge same input inputs. + values.head._1 -> BitPat(s"b${Seq + .tabulate(outputWidth) { i => + val outputSet = values + .map(_._2) + .map(_.rawString) + .map(_(i)) + .toSet + .filterNot(_ == '?') + require( + outputSet.size != 2, + s"TruthTable conflict in :\n${values.map { case (i, o) => s"${i.rawString}->${o.rawString}" }.mkString("\n")}" + ) + outputSet.headOption.getOrElse('?') + } + .mkString}") + } + .toSeq import BitPat.bitPatOrder - new TruthTable(if(sort) mergedTable.sorted else mergedTable, default, sort) + new TruthTable(if (sort) mergedTable.sorted else mergedTable, default, sort) } /** Parse TruthTable from its string representation. */ @@ -77,10 +87,17 @@ object TruthTable { BitPat(s"b${bitPat.rawString.zipWithIndex.filter(b => indexes.contains(b._2)).map(_._1).mkString}") def tableFilter(indexes: Seq[Int]): Option[(TruthTable, Seq[Int])] = { - if(indexes.nonEmpty) Some((TruthTable( - table.table.map { case (in, out) => in -> bpFilter(out, indexes) }, - bpFilter(table.default, indexes) - ), indexes)) else None + if (indexes.nonEmpty) + Some( + ( + TruthTable( + table.table.map { case (in, out) => in -> bpFilter(out, indexes) }, + bpFilter(table.default, indexes) + ), + indexes + ) + ) + else None } def index(bitPat: BitPat, bpType: Char): Seq[Int] = @@ -99,7 +116,12 @@ object TruthTable { tables: Seq[(TruthTable, Seq[Int])] ): TruthTable = { def reIndex(bitPat: BitPat, table: TruthTable, indexes: Seq[Int]): Seq[(Char, Int)] = - table.table.map(a => a._1.toString -> a._2).collectFirst{ case (k, v) if k == bitPat.toString => v}.getOrElse(BitPat.dontCare(indexes.size)).rawString.zip(indexes) + table.table + .map(a => a._1.toString -> a._2) + .collectFirst { case (k, v) if k == bitPat.toString => v } + .getOrElse(BitPat.dontCare(indexes.size)) + .rawString + .zip(indexes) def bitPat(indexedChar: Seq[(Char, Int)]) = BitPat(s"b${indexedChar .sortBy(_._2) .map(_._1) diff --git a/src/main/scala/chisel3/util/experimental/decode/decoder.scala b/src/main/scala/chisel3/util/experimental/decode/decoder.scala index e0bf83b2..4feda672 100644 --- a/src/main/scala/chisel3/util/experimental/decode/decoder.scala +++ b/src/main/scala/chisel3/util/experimental/decode/decoder.scala @@ -3,13 +3,14 @@ package chisel3.util.experimental.decode import chisel3._ -import chisel3.experimental.{ChiselAnnotation, annotate} -import chisel3.util.{BitPat, pla} -import chisel3.util.experimental.{BitSet, getAnnotations} +import chisel3.experimental.{annotate, ChiselAnnotation} +import chisel3.util.{pla, BitPat} +import chisel3.util.experimental.{getAnnotations, BitSet} import firrtl.annotations.Annotation import logger.LazyLogging object decoder extends LazyLogging { + /** Use a specific [[Minimizer]] to generated decoded signals. * * @param minimizer specific [[Minimizer]], can be [[QMCMinimizer]] or [[EspressoMinimizer]]. @@ -71,7 +72,8 @@ object decoder extends LazyLogging { qmc(input, truthTable) } - try espresso(input, truthTable) catch { + try espresso(input, truthTable) + catch { case EspressoNotFoundException => logger.error(s"espresso is not found in your PATH:\n${sys.env("PATH").split(":").mkString("\n")}".stripMargin) qmcFallBack(input, truthTable) @@ -81,7 +83,6 @@ object decoder extends LazyLogging { } } - /** Generate a decoder circuit that matches the input to each bitSet. * * The resulting circuit functions like the following but is optimized with a logic minifier. @@ -104,9 +105,7 @@ object decoder extends LazyLogging { { bitSets.zipWithIndex.flatMap { case (bs, i) => - bs.terms.map(bp => - s"${bp.rawString}->${if (errorBit) "0"}${"0" * (bitSets.size - i - 1)}1${"0" * i}" - ) + bs.terms.map(bp => s"${bp.rawString}->${if (errorBit) "0"}${"0" * (bitSets.size - i - 1)}1${"0" * i}") } ++ Seq(s"${if (errorBit) "1"}${"?" * bitSets.size}") }.mkString("\n") ) diff --git a/src/main/scala/chisel3/util/experimental/getAnnotations.scala b/src/main/scala/chisel3/util/experimental/getAnnotations.scala index dc9b75ee..ac6e6bd1 100644 --- a/src/main/scala/chisel3/util/experimental/getAnnotations.scala +++ b/src/main/scala/chisel3/util/experimental/getAnnotations.scala @@ -4,6 +4,7 @@ import chisel3.internal.Builder import firrtl.AnnotationSeq object getAnnotations { + /** Returns the global Annotations */ def apply(): AnnotationSeq = Builder.annotationSeq } diff --git a/src/main/scala/chisel3/util/experimental/group.scala b/src/main/scala/chisel3/util/experimental/group.scala index e43115d0..202c95d8 100644 --- a/src/main/scala/chisel3/util/experimental/group.scala +++ b/src/main/scala/chisel3/util/experimental/group.scala @@ -3,7 +3,7 @@ package chisel3.util.experimental import chisel3._ -import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} import chisel3.internal.requireIsHardware import firrtl.Transform import firrtl.transforms.{GroupAnnotation, GroupComponents} @@ -46,12 +46,14 @@ object group { * @tparam T Parent type of input components */ def apply[T <: Data]( - components: Seq[T], - newModule: String, - newInstance: String, - outputSuffix: Option[String] = None, - inputSuffix: Option[String] = None - )(implicit compileOptions: CompileOptions): Unit = { + components: Seq[T], + newModule: String, + newInstance: String, + outputSuffix: Option[String] = None, + inputSuffix: Option[String] = None + )( + implicit compileOptions: CompileOptions + ): Unit = { if (compileOptions.checkSynthesizable) { components.foreach { data => requireIsHardware(data, s"Component ${data.toString} is marked to group, but is not bound.") @@ -64,4 +66,3 @@ object group { }) } } - diff --git a/src/main/scala/chisel3/util/pla.scala b/src/main/scala/chisel3/util/pla.scala index c57ca962..d4707d26 100644 --- a/src/main/scala/chisel3/util/pla.scala +++ b/src/main/scala/chisel3/util/pla.scala @@ -68,7 +68,8 @@ object pla { val inverterMask = invert.value & invert.mask if (inverterMask.bitCount != 0) - require(invert.getWidth == numberOfOutputs, + require( + invert.getWidth == numberOfOutputs, "non-zero inverter mask must have the same width as the output part of specified PLA table" ) @@ -99,28 +100,28 @@ object pla { // the OR matrix val orMatrixOutputs: UInt = Cat( - Seq - .tabulate(numberOfOutputs) { i => - val andMatrixLines = table - // OR matrix composed by input terms which makes this output bit a `1` - .filter { - case (_, or) => or.mask.testBit(i) && or.value.testBit(i) - }.map { - case (inputTerm, _) => - andMatrixOutputs(inputTerm.toString) - } - if (andMatrixLines.isEmpty) false.B - else Cat(andMatrixLines).orR() - } - .reverse - ) + Seq + .tabulate(numberOfOutputs) { i => + val andMatrixLines = table + // OR matrix composed by input terms which makes this output bit a `1` + .filter { + case (_, or) => or.mask.testBit(i) && or.value.testBit(i) + }.map { + case (inputTerm, _) => + andMatrixOutputs(inputTerm.toString) + } + if (andMatrixLines.isEmpty) false.B + else Cat(andMatrixLines).orR() + } + .reverse + ) // the INV matrix, useful for decoders val invMatrixOutputs: UInt = Cat( Seq .tabulate(numberOfOutputs) { i => if (inverterMask.testBit(i)) ~orMatrixOutputs(i) - else orMatrixOutputs(i) + else orMatrixOutputs(i) } .reverse ) diff --git a/src/main/scala/chisel3/util/random/FibonacciLFSR.scala b/src/main/scala/chisel3/util/random/FibonacciLFSR.scala index 32f5caa8..4da51a4e 100644 --- a/src/main/scala/chisel3/util/random/FibonacciLFSR.scala +++ b/src/main/scala/chisel3/util/random/FibonacciLFSR.scala @@ -40,14 +40,16 @@ import chisel3._ * $paramUpdateSeed */ class FibonacciLFSR( - width: Int, - taps: Set[Int], - seed: Option[BigInt] = Some(1), + width: Int, + taps: Set[Int], + seed: Option[BigInt] = Some(1), val reduction: LFSRReduce = XOR, - step: Int = 1, - updateSeed: Boolean = false) extends PRNG(width, seed, step, updateSeed) with LFSR { + step: Int = 1, + updateSeed: Boolean = false) + extends PRNG(width, seed, step, updateSeed) + with LFSR { - def delta(s: Seq[Bool]): Seq[Bool] = taps.map{ case i => s(i - 1) }.reduce(reduction) +: s.dropRight(1) + def delta(s: Seq[Bool]): Seq[Bool] = taps.map { case i => s(i - 1) }.reduce(reduction) +: s.dropRight(1) } @@ -87,11 +89,12 @@ object FibonacciLFSR { * $paramReduction */ def apply( - width: Int, - taps: Set[Int], + width: Int, + taps: Set[Int], increment: Bool = true.B, - seed: Option[BigInt] = Some(1), - reduction: LFSRReduce = XOR): UInt = PRNG(new FibonacciLFSR(width, taps, seed, reduction), increment) + seed: Option[BigInt] = Some(1), + reduction: LFSRReduce = XOR + ): UInt = PRNG(new FibonacciLFSR(width, taps, seed, reduction), increment) /** Return a pseudorandom [[UInt]] generated using a maximal period [[FibonacciLFSR]] * $paramWidth @@ -100,9 +103,10 @@ object FibonacciLFSR { * $paramReduction */ def maxPeriod( - width: Int, + width: Int, increment: Bool = true.B, - seed: Option[BigInt] = Some(1), - reduction: LFSRReduce = XOR): UInt = PRNG(new MaxPeriodFibonacciLFSR(width, seed, reduction), increment) + seed: Option[BigInt] = Some(1), + reduction: LFSRReduce = XOR + ): UInt = PRNG(new MaxPeriodFibonacciLFSR(width, seed, reduction), increment) } diff --git a/src/main/scala/chisel3/util/random/GaloisLFSR.scala b/src/main/scala/chisel3/util/random/GaloisLFSR.scala index 68346e82..f452cf75 100644 --- a/src/main/scala/chisel3/util/random/GaloisLFSR.scala +++ b/src/main/scala/chisel3/util/random/GaloisLFSR.scala @@ -38,21 +38,21 @@ import chisel3._ * $paramUpdateSeed */ class GaloisLFSR( - width: Int, - taps: Set[Int], - seed: Option[BigInt] = Some(1), + width: Int, + taps: Set[Int], + seed: Option[BigInt] = Some(1), val reduction: LFSRReduce = XOR, - step: Int = 1, - updateSeed: Boolean = false) extends PRNG(width, seed, step, updateSeed) with LFSR { + step: Int = 1, + updateSeed: Boolean = false) + extends PRNG(width, seed, step, updateSeed) + with LFSR { def delta(s: Seq[Bool]): Seq[Bool] = { val first = s.head - (s.tail :+ first) - .zipWithIndex - .map { - case (a, i) if taps(i + 1) && (i + 1 != s.size) => reduction(a, first) - case (a, _) => a - } + (s.tail :+ first).zipWithIndex.map { + case (a, i) if taps(i + 1) && (i + 1 != s.size) => reduction(a, first) + case (a, _) => a + } } } @@ -93,11 +93,12 @@ object GaloisLFSR { * $paramReduction */ def apply( - width: Int, - taps: Set[Int], + width: Int, + taps: Set[Int], increment: Bool = true.B, - seed: Option[BigInt] = Some(1), - reduction: LFSRReduce = XOR): UInt = PRNG(new GaloisLFSR(width, taps, seed, reduction), increment) + seed: Option[BigInt] = Some(1), + reduction: LFSRReduce = XOR + ): UInt = PRNG(new GaloisLFSR(width, taps, seed, reduction), increment) /** Return a pseudorandom [[UInt]] generated using a maximal period [[GaloisLFSR]] * $paramWidth @@ -106,9 +107,10 @@ object GaloisLFSR { * $paramReduction */ def maxPeriod( - width: Int, + width: Int, increment: Bool = true.B, - seed: Option[BigInt] = Some(1), - reduction: LFSRReduce = XOR): UInt = PRNG(new MaxPeriodGaloisLFSR(width, seed, reduction), increment) + seed: Option[BigInt] = Some(1), + reduction: LFSRReduce = XOR + ): UInt = PRNG(new MaxPeriodGaloisLFSR(width, seed, reduction), increment) } diff --git a/src/main/scala/chisel3/util/random/LFSR.scala b/src/main/scala/chisel3/util/random/LFSR.scala index 08b124f6..b26cfa5d 100644 --- a/src/main/scala/chisel3/util/random/LFSR.scala +++ b/src/main/scala/chisel3/util/random/LFSR.scala @@ -48,7 +48,8 @@ trait LFSR extends PRNG { def reduction: LFSRReduce override protected def resetValue: Vec[Bool] = seed match { - case Some(s) => reduction match { + case Some(s) => + reduction match { case XOR => require(s != 0, "Seed cannot be zero") case XNOR => require(s != BigInt(2).pow(width) - 1, "Seed cannot be all ones (max value)") } @@ -87,8 +88,9 @@ object LFSR { FibonacciLFSR.maxPeriod(width, increment, seed, XOR) /** Utility used to report an unknown tap width */ - private [random] def badWidth(width: Int): Nothing = throw new IllegalArgumentException( - s"No max period LFSR taps stored for requested width '$width'") + private[random] def badWidth(width: Int): Nothing = throw new IllegalArgumentException( + s"No max period LFSR taps stored for requested width '$width'" + ) /** A mapping of widths to a sequence of known LFSR taps that produce a maximal period LFSR. These work for either a * [[chisel3.util.random.FibonacciLFSR Fibonacci LFSR]] or a [[chisel3.util.random.GaloisLFSR Galois LFSR]]. Taps are @@ -104,796 +106,798 @@ object LFSR { /** First portion of known taps (a combined map hits the 64KB JVM method limit) */ private def tapsFirst = Map( - 2 -> Seq(Set(2, 1)), - 3 -> Seq(Set(3, 2)), - 4 -> Seq(Set(4, 3)), - 5 -> Seq(Set(5, 3), Set(5, 4, 3, 2)), - 6 -> Seq(Set(6, 5), Set(6, 5, 3, 2)), - 7 -> Seq(Set(7, 6), Set(7, 6, 5, 4)), - 8 -> Seq(Set(8, 6, 5, 4)), - 9 -> Seq(Set(9, 5), Set(9, 8, 6, 5)), - 10 -> Seq(Set(10, 7), Set(10, 9, 7, 6)), - 11 -> Seq(Set(11, 9), Set(11, 10, 9, 7)), - 12 -> Seq(Set(12, 11, 8, 6)), - 13 -> Seq(Set(13, 12, 10, 9)), - 14 -> Seq(Set(14, 13, 11, 9)), - 15 -> Seq(Set(15, 14), Set(15, 14, 13, 11)), - 16 -> Seq(Set(16, 14, 13, 11)), - 17 -> Seq(Set(17, 14), Set(17, 16, 15, 14)), - 18 -> Seq(Set(18, 11), Set(18, 17, 16, 13)), - 19 -> Seq(Set(19, 18, 17, 14)), - 20 -> Seq(Set(20, 17), Set(20, 19, 16, 14)), - 21 -> Seq(Set(21, 19), Set(21, 20, 19, 16)), - 22 -> Seq(Set(22, 21), Set(22, 19, 18, 17)), - 23 -> Seq(Set(23, 18), Set(23, 22, 20, 18)), - 24 -> Seq(Set(24, 23, 21, 20)), - 25 -> Seq(Set(25, 22), Set(25, 24, 23, 22)), - 26 -> Seq(Set(26, 25, 24, 20)), - 27 -> Seq(Set(27, 26, 25, 22)), - 28 -> Seq(Set(28, 25), Set(28, 27, 24, 22)), - 29 -> Seq(Set(29, 27), Set(29, 28, 27, 25)), - 30 -> Seq(Set(30, 29, 26, 24)), - 31 -> Seq(Set(31, 28), Set(31, 30, 29, 28)), - 32 -> Seq(Set(32, 30, 26, 25)), - 33 -> Seq(Set(33, 20), Set(33, 32, 29, 27)), - 34 -> Seq(Set(34, 31, 30, 26)), - 35 -> Seq(Set(35, 33), Set(35, 34, 28, 27)), - 36 -> Seq(Set(36, 25), Set(36, 35, 29, 28)), - 37 -> Seq(Set(37, 36, 33, 31)), - 38 -> Seq(Set(38, 37, 33, 32)), - 39 -> Seq(Set(39, 35), Set(39, 38, 35, 32)), - 40 -> Seq(Set(40, 37, 36, 35)), - 41 -> Seq(Set(41, 38), Set(41, 40, 39, 38)), - 42 -> Seq(Set(42, 40, 37, 35)), - 43 -> Seq(Set(43, 42, 38, 37)), - 44 -> Seq(Set(44, 42, 39, 38)), - 45 -> Seq(Set(45, 44, 42, 41)), - 46 -> Seq(Set(46, 40, 39, 38)), - 47 -> Seq(Set(47, 42), Set(47, 46, 43, 42)), - 48 -> Seq(Set(48, 44, 41, 39)), - 49 -> Seq(Set(49, 40), Set(49, 45, 44, 43)), - 50 -> Seq(Set(50, 48, 47, 46)), - 51 -> Seq(Set(51, 50, 48, 45)), - 52 -> Seq(Set(52, 49), Set(52, 51, 49, 46)), - 53 -> Seq(Set(53, 52, 51, 47)), - 54 -> Seq(Set(54, 51, 48, 46)), - 55 -> Seq(Set(55, 31), Set(55, 54, 53, 49)), - 56 -> Seq(Set(56, 54, 52, 49)), - 57 -> Seq(Set(57, 50), Set(57, 55, 54, 52)), - 58 -> Seq(Set(58, 39), Set(58, 57, 53, 52)), - 59 -> Seq(Set(59, 57, 55, 52)), - 60 -> Seq(Set(60, 59), Set(60, 58, 56, 55)), - 61 -> Seq(Set(61, 60, 59, 56)), - 62 -> Seq(Set(62, 59, 57, 56)), - 63 -> Seq(Set(63, 62), Set(63, 62, 59, 58)), - 64 -> Seq(Set(64, 63, 61, 60)), - 65 -> Seq(Set(65, 47), Set(65, 64, 62, 61)), - 66 -> Seq(Set(66, 60, 58, 57)), - 67 -> Seq(Set(67, 66, 65, 62)), - 68 -> Seq(Set(68, 59), Set(68, 67, 63, 61)), - 69 -> Seq(Set(69, 67, 64, 63)), - 70 -> Seq(Set(70, 69, 67, 65)), - 71 -> Seq(Set(71, 65), Set(71, 70, 68, 66)), - 72 -> Seq(Set(72, 69, 63, 62)), - 73 -> Seq(Set(73, 48), Set(73, 71, 70, 69)), - 74 -> Seq(Set(74, 71, 70, 67)), - 75 -> Seq(Set(75, 74, 72, 69)), - 76 -> Seq(Set(76, 74, 72, 71)), - 77 -> Seq(Set(77, 75, 72, 71)), - 78 -> Seq(Set(78, 77, 76, 71)), - 79 -> Seq(Set(79, 70), Set(79, 77, 76, 75)), - 80 -> Seq(Set(80, 78, 76, 71)), - 81 -> Seq(Set(81, 77), Set(81, 79, 78, 75)), - 82 -> Seq(Set(82, 78, 76, 73)), - 83 -> Seq(Set(83, 81, 79, 76)), - 84 -> Seq(Set(84, 71), Set(84, 83, 77, 75)), - 85 -> Seq(Set(85, 84, 83, 77)), - 86 -> Seq(Set(86, 84, 81, 80)), - 87 -> Seq(Set(87, 74), Set(87, 86, 82, 80)), - 88 -> Seq(Set(88, 80, 79, 77)), - 89 -> Seq(Set(89, 51), Set(89, 86, 84, 83)), - 90 -> Seq(Set(90, 88, 87, 85)), - 91 -> Seq(Set(91, 90, 86, 83)), - 92 -> Seq(Set(92, 90, 87, 86)), - 93 -> Seq(Set(93, 91), Set(93, 91, 90, 87)), - 94 -> Seq(Set(94, 73), Set(94, 93, 89, 88)), - 95 -> Seq(Set(95, 84), Set(95, 94, 90, 88)), - 96 -> Seq(Set(96, 90, 87, 86)), - 97 -> Seq(Set(97, 91), Set(97, 95, 93, 91)), - 98 -> Seq(Set(98, 87), Set(98, 97, 91, 90)), - 99 -> Seq(Set(99, 95, 94, 92)), - 100 -> Seq(Set(100, 63), Set(100, 98, 93, 92)), - 101 -> Seq(Set(101, 100, 95, 94)), - 102 -> Seq(Set(102, 99, 97, 96)), - 103 -> Seq(Set(103, 94), Set(103, 102, 99, 94)), - 104 -> Seq(Set(104, 103, 94, 93)), - 105 -> Seq(Set(105, 89), Set(105, 104, 99, 98)), - 106 -> Seq(Set(106, 91), Set(106, 105, 101, 100)), - 107 -> Seq(Set(107, 105, 99, 98)), - 108 -> Seq(Set(108, 77), Set(108, 103, 97, 96)), - 109 -> Seq(Set(109, 107, 105, 104)), - 110 -> Seq(Set(110, 109, 106, 104)), - 111 -> Seq(Set(111, 101), Set(111, 109, 107, 104)), - 112 -> Seq(Set(112, 108, 106, 101)), - 113 -> Seq(Set(113, 104), Set(113, 111, 110, 108)), - 114 -> Seq(Set(114, 113, 112, 103)), - 115 -> Seq(Set(115, 110, 108, 107)), - 116 -> Seq(Set(116, 114, 111, 110)), - 117 -> Seq(Set(117, 116, 115, 112)), - 118 -> Seq(Set(118, 85), Set(118, 116, 113, 112)), - 119 -> Seq(Set(119, 111), Set(119, 116, 111, 110)), - 120 -> Seq(Set(120, 118, 114, 111)), - 121 -> Seq(Set(121, 103), Set(121, 120, 116, 113)), - 122 -> Seq(Set(122, 121, 120, 116)), - 123 -> Seq(Set(123, 121), Set(123, 122, 119, 115)), - 124 -> Seq(Set(124, 87), Set(124, 119, 118, 117)), - 125 -> Seq(Set(125, 120, 119, 118)), - 126 -> Seq(Set(126, 124, 122, 119)), - 127 -> Seq(Set(127, 126), Set(127, 126, 124, 120)), - 128 -> Seq(Set(128, 127, 126, 121)), - 129 -> Seq(Set(129, 124), Set(129, 128, 125, 124)), - 130 -> Seq(Set(130, 127), Set(130, 129, 128, 125)), - 131 -> Seq(Set(131, 129, 128, 123)), - 132 -> Seq(Set(132, 103), Set(132, 130, 127, 123)), - 133 -> Seq(Set(133, 131, 125, 124)), - 134 -> Seq(Set(134, 77), Set(134, 133, 129, 127)), - 135 -> Seq(Set(135, 124), Set(135, 132, 131, 129)), - 136 -> Seq(Set(136, 134, 133, 128)), - 137 -> Seq(Set(137, 116), Set(137, 136, 133, 126)), - 138 -> Seq(Set(138, 137, 131, 130)), - 139 -> Seq(Set(139, 136, 134, 131)), - 140 -> Seq(Set(140, 111), Set(140, 139, 136, 132)), - 141 -> Seq(Set(141, 140, 135, 128)), - 142 -> Seq(Set(142, 121), Set(142, 141, 139, 132)), - 143 -> Seq(Set(143, 141, 140, 138)), - 144 -> Seq(Set(144, 142, 140, 137)), - 145 -> Seq(Set(145, 93), Set(145, 144, 140, 139)), - 146 -> Seq(Set(146, 144, 143, 141)), - 147 -> Seq(Set(147, 145, 143, 136)), - 148 -> Seq(Set(148, 121), Set(148, 145, 143, 141)), - 149 -> Seq(Set(149, 142, 140, 139)), - 150 -> Seq(Set(150, 97), Set(150, 148, 147, 142)), - 151 -> Seq(Set(151, 148), Set(151, 150, 149, 148)), - 152 -> Seq(Set(152, 150, 149, 146)), - 153 -> Seq(Set(153, 152), Set(153, 149, 148, 145)), - 154 -> Seq(Set(154, 153, 149, 145)), - 155 -> Seq(Set(155, 151, 150, 148)), - 156 -> Seq(Set(156, 153, 151, 147)), - 157 -> Seq(Set(157, 155, 152, 151)), - 158 -> Seq(Set(158, 153, 152, 150)), - 159 -> Seq(Set(159, 128), Set(159, 156, 153, 148)), - 160 -> Seq(Set(160, 158, 157, 155)), - 161 -> Seq(Set(161, 143), Set(161, 159, 158, 155)), - 162 -> Seq(Set(162, 158, 155, 154)), - 163 -> Seq(Set(163, 160, 157, 156)), - 164 -> Seq(Set(164, 159, 158, 152)), - 165 -> Seq(Set(165, 162, 157, 156)), - 166 -> Seq(Set(166, 164, 163, 156)), - 167 -> Seq(Set(167, 161), Set(167, 165, 163, 161)), - 168 -> Seq(Set(168, 162, 159, 152)), - 169 -> Seq(Set(169, 135), Set(169, 164, 163, 161)), - 170 -> Seq(Set(170, 147), Set(170, 169, 166, 161)), - 171 -> Seq(Set(171, 169, 166, 165)), - 172 -> Seq(Set(172, 165), Set(172, 169, 165, 161)), - 173 -> Seq(Set(173, 171, 168, 165)), - 174 -> Seq(Set(174, 161), Set(174, 169, 166, 165)), - 175 -> Seq(Set(175, 169), Set(175, 173, 171, 169)), - 176 -> Seq(Set(176, 167, 165, 164)), - 177 -> Seq(Set(177, 169), Set(177, 175, 174, 172)), - 178 -> Seq(Set(178, 91), Set(178, 176, 171, 170)), - 179 -> Seq(Set(179, 178, 177, 175)), - 180 -> Seq(Set(180, 173, 170, 168)), - 181 -> Seq(Set(181, 180, 175, 174)), - 182 -> Seq(Set(182, 181, 176, 174)), - 183 -> Seq(Set(183, 127), Set(183, 179, 176, 175)), - 184 -> Seq(Set(184, 177, 176, 175)), - 185 -> Seq(Set(185, 161), Set(185, 184, 182, 177)), - 186 -> Seq(Set(186, 180, 178, 177)), - 187 -> Seq(Set(187, 182, 181, 180)), - 188 -> Seq(Set(188, 186, 183, 182)), - 189 -> Seq(Set(189, 187, 184, 183)), - 190 -> Seq(Set(190, 188, 184, 177)), - 191 -> Seq(Set(191, 182), Set(191, 187, 185, 184)), - 192 -> Seq(Set(192, 190, 178, 177)), - 193 -> Seq(Set(193, 178), Set(193, 189, 186, 184)), - 194 -> Seq(Set(194, 107), Set(194, 192, 191, 190)), - 195 -> Seq(Set(195, 193, 192, 187)), - 196 -> Seq(Set(196, 194, 187, 185)), - 197 -> Seq(Set(197, 195, 193, 188)), - 198 -> Seq(Set(198, 133), Set(198, 193, 190, 183)), - 199 -> Seq(Set(199, 165), Set(199, 198, 195, 190)), - 200 -> Seq(Set(200, 198, 197, 195)), - 201 -> Seq(Set(201, 187), Set(201, 199, 198, 195)), - 202 -> Seq(Set(202, 147), Set(202, 198, 196, 195)), - 203 -> Seq(Set(203, 202, 196, 195)), - 204 -> Seq(Set(204, 201, 200, 194)), - 205 -> Seq(Set(205, 203, 200, 196)), - 206 -> Seq(Set(206, 201, 197, 196)), - 207 -> Seq(Set(207, 164), Set(207, 206, 201, 198)), - 208 -> Seq(Set(208, 207, 205, 199)), - 209 -> Seq(Set(209, 203), Set(209, 207, 206, 204)), - 210 -> Seq(Set(210, 207, 206, 198)), - 211 -> Seq(Set(211, 203, 201, 200)), - 212 -> Seq(Set(212, 107), Set(212, 209, 208, 205)), - 213 -> Seq(Set(213, 211, 208, 207)), - 214 -> Seq(Set(214, 213, 211, 209)), - 215 -> Seq(Set(215, 192), Set(215, 212, 210, 209)), - 216 -> Seq(Set(216, 215, 213, 209)), - 217 -> Seq(Set(217, 172), Set(217, 213, 212, 211)), - 218 -> Seq(Set(218, 207), Set(218, 217, 211, 210)), - 219 -> Seq(Set(219, 218, 215, 211)), - 220 -> Seq(Set(220, 211, 210, 208)), - 221 -> Seq(Set(221, 219, 215, 213)), - 222 -> Seq(Set(222, 220, 217, 214)), - 223 -> Seq(Set(223, 190), Set(223, 221, 219, 218)), - 224 -> Seq(Set(224, 222, 217, 212)), - 225 -> Seq(Set(225, 193), Set(225, 224, 220, 215)), - 226 -> Seq(Set(226, 223, 219, 216)), - 227 -> Seq(Set(227, 223, 218, 217)), - 228 -> Seq(Set(228, 226, 217, 216)), - 229 -> Seq(Set(229, 228, 225, 219)), - 230 -> Seq(Set(230, 224, 223, 222)), - 231 -> Seq(Set(231, 205), Set(231, 229, 227, 224)), - 232 -> Seq(Set(232, 228, 223, 221)), - 233 -> Seq(Set(233, 159), Set(233, 232, 229, 224)), - 234 -> Seq(Set(234, 203), Set(234, 232, 225, 223)), - 235 -> Seq(Set(235, 234, 229, 226)), - 236 -> Seq(Set(236, 231), Set(236, 229, 228, 226)), - 237 -> Seq(Set(237, 236, 233, 230)), - 238 -> Seq(Set(238, 237, 236, 233)), - 239 -> Seq(Set(239, 203), Set(239, 238, 232, 227)), - 240 -> Seq(Set(240, 237, 235, 232)), - 241 -> Seq(Set(241, 171), Set(241, 237, 233, 232)), - 242 -> Seq(Set(242, 241, 236, 231)), - 243 -> Seq(Set(243, 242, 238, 235)), - 244 -> Seq(Set(244, 243, 240, 235)), - 245 -> Seq(Set(245, 244, 241, 239)), - 246 -> Seq(Set(246, 245, 244, 235)), - 247 -> Seq(Set(247, 165), Set(247, 245, 243, 238)), - 248 -> Seq(Set(248, 238, 234, 233)), - 249 -> Seq(Set(249, 163), Set(249, 248, 245, 242)), - 250 -> Seq(Set(250, 147), Set(250, 247, 245, 240)), - 251 -> Seq(Set(251, 249, 247, 244)), - 252 -> Seq(Set(252, 185), Set(252, 251, 247, 241)), - 253 -> Seq(Set(253, 252, 247, 246)), - 254 -> Seq(Set(254, 253, 252, 247)), - 255 -> Seq(Set(255, 203), Set(255, 253, 252, 250)), - 256 -> Seq(Set(256, 254, 251, 246)), - 257 -> Seq(Set(257, 245), Set(257, 255, 251, 250)), - 258 -> Seq(Set(258, 175), Set(258, 254, 252, 249)), - 259 -> Seq(Set(259, 257, 253, 249)), - 260 -> Seq(Set(260, 253, 252, 250)), - 261 -> Seq(Set(261, 257, 255, 254)), - 262 -> Seq(Set(262, 258, 254, 253)), - 263 -> Seq(Set(263, 170), Set(263, 261, 258, 252)), - 264 -> Seq(Set(264, 263, 255, 254)), - 265 -> Seq(Set(265, 223), Set(265, 263, 262, 260)), - 266 -> Seq(Set(266, 219), Set(266, 265, 260, 259)), - 267 -> Seq(Set(267, 264, 261, 259)), - 268 -> Seq(Set(268, 243), Set(268, 267, 264, 258)), - 269 -> Seq(Set(269, 268, 263, 262)), - 270 -> Seq(Set(270, 217), Set(270, 267, 263, 260)), - 271 -> Seq(Set(271, 213), Set(271, 265, 264, 260)), - 272 -> Seq(Set(272, 270, 266, 263)), - 273 -> Seq(Set(273, 250), Set(273, 272, 271, 266)), - 274 -> Seq(Set(274, 207), Set(274, 272, 267, 265)), - 275 -> Seq(Set(275, 266, 265, 264)), - 276 -> Seq(Set(276, 275, 273, 270)), - 277 -> Seq(Set(277, 274, 271, 265)), - 278 -> Seq(Set(278, 273), Set(278, 277, 274, 273)), - 279 -> Seq(Set(279, 274), Set(279, 278, 275, 274)), - 280 -> Seq(Set(280, 278, 275, 271)), - 281 -> Seq(Set(281, 188), Set(281, 280, 277, 272)), - 282 -> Seq(Set(282, 247), Set(282, 278, 277, 272)), - 283 -> Seq(Set(283, 278, 276, 271)), - 284 -> Seq(Set(284, 165), Set(284, 279, 278, 276)), - 285 -> Seq(Set(285, 280, 278, 275)), - 286 -> Seq(Set(286, 217), Set(286, 285, 276, 271)), - 287 -> Seq(Set(287, 216), Set(287, 285, 282, 281)), - 288 -> Seq(Set(288, 287, 278, 277)), - 289 -> Seq(Set(289, 268), Set(289, 286, 285, 277)), - 290 -> Seq(Set(290, 288, 287, 285)), - 291 -> Seq(Set(291, 286, 280, 279)), - 292 -> Seq(Set(292, 195), Set(292, 291, 289, 285)), - 293 -> Seq(Set(293, 292, 287, 282)), - 294 -> Seq(Set(294, 233), Set(294, 292, 291, 285)), - 295 -> Seq(Set(295, 247), Set(295, 293, 291, 290)), - 296 -> Seq(Set(296, 292, 287, 285)), - 297 -> Seq(Set(297, 292), Set(297, 296, 293, 292)), - 298 -> Seq(Set(298, 294, 290, 287)), - 299 -> Seq(Set(299, 295, 293, 288)), - 300 -> Seq(Set(300, 293), Set(300, 290, 288, 287)), - 301 -> Seq(Set(301, 299, 296, 292)), - 302 -> Seq(Set(302, 261), Set(302, 297, 293, 290)), - 303 -> Seq(Set(303, 297, 291, 290)), - 304 -> Seq(Set(304, 303, 302, 293)), - 305 -> Seq(Set(305, 203), Set(305, 303, 299, 298)), - 306 -> Seq(Set(306, 305, 303, 299)), - 307 -> Seq(Set(307, 305, 303, 299)), - 308 -> Seq(Set(308, 306, 299, 293)), - 309 -> Seq(Set(309, 307, 302, 299)), - 310 -> Seq(Set(310, 309, 305, 302)), - 311 -> Seq(Set(311, 308, 306, 304)), - 312 -> Seq(Set(312, 307, 302, 301)), - 313 -> Seq(Set(313, 234), Set(313, 312, 310, 306)), - 314 -> Seq(Set(314, 299), Set(314, 311, 305, 300)), - 315 -> Seq(Set(315, 314, 306, 305)), - 316 -> Seq(Set(316, 181), Set(316, 309, 305, 304)), - 317 -> Seq(Set(317, 315, 313, 310)), - 318 -> Seq(Set(318, 313, 312, 310)), - 319 -> Seq(Set(319, 283), Set(319, 318, 317, 308)), - 320 -> Seq(Set(320, 319, 317, 316)), - 321 -> Seq(Set(321, 290), Set(321, 319, 316, 314)), - 322 -> Seq(Set(322, 255), Set(322, 321, 320, 305)), - 323 -> Seq(Set(323, 322, 320, 313)), - 324 -> Seq(Set(324, 321, 320, 318)), - 325 -> Seq(Set(325, 323, 320, 315)), - 326 -> Seq(Set(326, 325, 323, 316)), - 327 -> Seq(Set(327, 293), Set(327, 325, 322, 319)), - 328 -> Seq(Set(328, 323, 321, 319)), - 329 -> Seq(Set(329, 279), Set(329, 326, 323, 321)), - 330 -> Seq(Set(330, 328, 323, 322)), - 331 -> Seq(Set(331, 329, 325, 321)), - 332 -> Seq(Set(332, 209), Set(332, 325, 321, 320)), - 333 -> Seq(Set(333, 331), Set(333, 331, 329, 325)), - 334 -> Seq(Set(334, 333, 330, 327)), - 335 -> Seq(Set(335, 333, 328, 325)), - 336 -> Seq(Set(336, 335, 332, 329)), - 337 -> Seq(Set(337, 282), Set(337, 336, 331, 327)), - 338 -> Seq(Set(338, 336, 335, 332)), - 339 -> Seq(Set(339, 332, 329, 323)), - 340 -> Seq(Set(340, 337, 336, 329)), - 341 -> Seq(Set(341, 336, 330, 327)), - 342 -> Seq(Set(342, 217), Set(342, 341, 340, 331)), - 343 -> Seq(Set(343, 268), Set(343, 338, 335, 333)), - 344 -> Seq(Set(344, 338, 334, 333)), - 345 -> Seq(Set(345, 323), Set(345, 343, 341, 337)), - 346 -> Seq(Set(346, 344, 339, 335)), - 347 -> Seq(Set(347, 344, 337, 336)), - 348 -> Seq(Set(348, 344, 341, 340)), - 349 -> Seq(Set(349, 347, 344, 343)), - 350 -> Seq(Set(350, 297), Set(350, 340, 337, 336)), - 351 -> Seq(Set(351, 317), Set(351, 348, 345, 343)), - 352 -> Seq(Set(352, 346, 341, 339)), - 353 -> Seq(Set(353, 284), Set(353, 349, 346, 344)), - 354 -> Seq(Set(354, 349, 341, 340)), - 355 -> Seq(Set(355, 354, 350, 349)), - 356 -> Seq(Set(356, 349, 347, 346)), - 357 -> Seq(Set(357, 355, 347, 346)), - 358 -> Seq(Set(358, 351, 350, 344)), - 359 -> Seq(Set(359, 291), Set(359, 358, 352, 350)), - 360 -> Seq(Set(360, 359, 335, 334)), - 361 -> Seq(Set(361, 360, 357, 354)), - 362 -> Seq(Set(362, 299), Set(362, 360, 351, 344)), - 363 -> Seq(Set(363, 362, 356, 355)), - 364 -> Seq(Set(364, 297), Set(364, 363, 359, 352)), - 365 -> Seq(Set(365, 360, 359, 356)), - 366 -> Seq(Set(366, 337), Set(366, 362, 359, 352)), - 367 -> Seq(Set(367, 346), Set(367, 365, 363, 358)), - 368 -> Seq(Set(368, 361, 359, 351)), - 369 -> Seq(Set(369, 278), Set(369, 367, 359, 358)), - 370 -> Seq(Set(370, 231), Set(370, 368, 367, 365)), - 371 -> Seq(Set(371, 369, 368, 363)), - 372 -> Seq(Set(372, 369, 365, 357)), - 373 -> Seq(Set(373, 371, 366, 365)), - 374 -> Seq(Set(374, 369, 368, 366)), - 375 -> Seq(Set(375, 359), Set(375, 374, 368, 367)), - 376 -> Seq(Set(376, 371, 369, 368)), - 377 -> Seq(Set(377, 336), Set(377, 376, 374, 369)), - 378 -> Seq(Set(378, 335), Set(378, 374, 365, 363)), - 379 -> Seq(Set(379, 375, 370, 369)), - 380 -> Seq(Set(380, 333), Set(380, 377, 374, 366)), - 381 -> Seq(Set(381, 380, 379, 376)), - 382 -> Seq(Set(382, 301), Set(382, 379, 375, 364)), - 383 -> Seq(Set(383, 293), Set(383, 382, 378, 374)), - 384 -> Seq(Set(384, 378, 369, 368)), - 385 -> Seq(Set(385, 379), Set(385, 383, 381, 379)), - 386 -> Seq(Set(386, 303), Set(386, 381, 380, 376)), - 387 -> Seq(Set(387, 385, 379, 378)), - 388 -> Seq(Set(388, 387, 385, 374)), - 389 -> Seq(Set(389, 384, 380, 379)), - 390 -> Seq(Set(390, 301), Set(390, 388, 380, 377)), - 391 -> Seq(Set(391, 363), Set(391, 390, 389, 385)), - 392 -> Seq(Set(392, 386, 382, 379)), - 393 -> Seq(Set(393, 386), Set(393, 392, 391, 386)), - 394 -> Seq(Set(394, 259), Set(394, 392, 387, 386)) ) + 2 -> Seq(Set(2, 1)), + 3 -> Seq(Set(3, 2)), + 4 -> Seq(Set(4, 3)), + 5 -> Seq(Set(5, 3), Set(5, 4, 3, 2)), + 6 -> Seq(Set(6, 5), Set(6, 5, 3, 2)), + 7 -> Seq(Set(7, 6), Set(7, 6, 5, 4)), + 8 -> Seq(Set(8, 6, 5, 4)), + 9 -> Seq(Set(9, 5), Set(9, 8, 6, 5)), + 10 -> Seq(Set(10, 7), Set(10, 9, 7, 6)), + 11 -> Seq(Set(11, 9), Set(11, 10, 9, 7)), + 12 -> Seq(Set(12, 11, 8, 6)), + 13 -> Seq(Set(13, 12, 10, 9)), + 14 -> Seq(Set(14, 13, 11, 9)), + 15 -> Seq(Set(15, 14), Set(15, 14, 13, 11)), + 16 -> Seq(Set(16, 14, 13, 11)), + 17 -> Seq(Set(17, 14), Set(17, 16, 15, 14)), + 18 -> Seq(Set(18, 11), Set(18, 17, 16, 13)), + 19 -> Seq(Set(19, 18, 17, 14)), + 20 -> Seq(Set(20, 17), Set(20, 19, 16, 14)), + 21 -> Seq(Set(21, 19), Set(21, 20, 19, 16)), + 22 -> Seq(Set(22, 21), Set(22, 19, 18, 17)), + 23 -> Seq(Set(23, 18), Set(23, 22, 20, 18)), + 24 -> Seq(Set(24, 23, 21, 20)), + 25 -> Seq(Set(25, 22), Set(25, 24, 23, 22)), + 26 -> Seq(Set(26, 25, 24, 20)), + 27 -> Seq(Set(27, 26, 25, 22)), + 28 -> Seq(Set(28, 25), Set(28, 27, 24, 22)), + 29 -> Seq(Set(29, 27), Set(29, 28, 27, 25)), + 30 -> Seq(Set(30, 29, 26, 24)), + 31 -> Seq(Set(31, 28), Set(31, 30, 29, 28)), + 32 -> Seq(Set(32, 30, 26, 25)), + 33 -> Seq(Set(33, 20), Set(33, 32, 29, 27)), + 34 -> Seq(Set(34, 31, 30, 26)), + 35 -> Seq(Set(35, 33), Set(35, 34, 28, 27)), + 36 -> Seq(Set(36, 25), Set(36, 35, 29, 28)), + 37 -> Seq(Set(37, 36, 33, 31)), + 38 -> Seq(Set(38, 37, 33, 32)), + 39 -> Seq(Set(39, 35), Set(39, 38, 35, 32)), + 40 -> Seq(Set(40, 37, 36, 35)), + 41 -> Seq(Set(41, 38), Set(41, 40, 39, 38)), + 42 -> Seq(Set(42, 40, 37, 35)), + 43 -> Seq(Set(43, 42, 38, 37)), + 44 -> Seq(Set(44, 42, 39, 38)), + 45 -> Seq(Set(45, 44, 42, 41)), + 46 -> Seq(Set(46, 40, 39, 38)), + 47 -> Seq(Set(47, 42), Set(47, 46, 43, 42)), + 48 -> Seq(Set(48, 44, 41, 39)), + 49 -> Seq(Set(49, 40), Set(49, 45, 44, 43)), + 50 -> Seq(Set(50, 48, 47, 46)), + 51 -> Seq(Set(51, 50, 48, 45)), + 52 -> Seq(Set(52, 49), Set(52, 51, 49, 46)), + 53 -> Seq(Set(53, 52, 51, 47)), + 54 -> Seq(Set(54, 51, 48, 46)), + 55 -> Seq(Set(55, 31), Set(55, 54, 53, 49)), + 56 -> Seq(Set(56, 54, 52, 49)), + 57 -> Seq(Set(57, 50), Set(57, 55, 54, 52)), + 58 -> Seq(Set(58, 39), Set(58, 57, 53, 52)), + 59 -> Seq(Set(59, 57, 55, 52)), + 60 -> Seq(Set(60, 59), Set(60, 58, 56, 55)), + 61 -> Seq(Set(61, 60, 59, 56)), + 62 -> Seq(Set(62, 59, 57, 56)), + 63 -> Seq(Set(63, 62), Set(63, 62, 59, 58)), + 64 -> Seq(Set(64, 63, 61, 60)), + 65 -> Seq(Set(65, 47), Set(65, 64, 62, 61)), + 66 -> Seq(Set(66, 60, 58, 57)), + 67 -> Seq(Set(67, 66, 65, 62)), + 68 -> Seq(Set(68, 59), Set(68, 67, 63, 61)), + 69 -> Seq(Set(69, 67, 64, 63)), + 70 -> Seq(Set(70, 69, 67, 65)), + 71 -> Seq(Set(71, 65), Set(71, 70, 68, 66)), + 72 -> Seq(Set(72, 69, 63, 62)), + 73 -> Seq(Set(73, 48), Set(73, 71, 70, 69)), + 74 -> Seq(Set(74, 71, 70, 67)), + 75 -> Seq(Set(75, 74, 72, 69)), + 76 -> Seq(Set(76, 74, 72, 71)), + 77 -> Seq(Set(77, 75, 72, 71)), + 78 -> Seq(Set(78, 77, 76, 71)), + 79 -> Seq(Set(79, 70), Set(79, 77, 76, 75)), + 80 -> Seq(Set(80, 78, 76, 71)), + 81 -> Seq(Set(81, 77), Set(81, 79, 78, 75)), + 82 -> Seq(Set(82, 78, 76, 73)), + 83 -> Seq(Set(83, 81, 79, 76)), + 84 -> Seq(Set(84, 71), Set(84, 83, 77, 75)), + 85 -> Seq(Set(85, 84, 83, 77)), + 86 -> Seq(Set(86, 84, 81, 80)), + 87 -> Seq(Set(87, 74), Set(87, 86, 82, 80)), + 88 -> Seq(Set(88, 80, 79, 77)), + 89 -> Seq(Set(89, 51), Set(89, 86, 84, 83)), + 90 -> Seq(Set(90, 88, 87, 85)), + 91 -> Seq(Set(91, 90, 86, 83)), + 92 -> Seq(Set(92, 90, 87, 86)), + 93 -> Seq(Set(93, 91), Set(93, 91, 90, 87)), + 94 -> Seq(Set(94, 73), Set(94, 93, 89, 88)), + 95 -> Seq(Set(95, 84), Set(95, 94, 90, 88)), + 96 -> Seq(Set(96, 90, 87, 86)), + 97 -> Seq(Set(97, 91), Set(97, 95, 93, 91)), + 98 -> Seq(Set(98, 87), Set(98, 97, 91, 90)), + 99 -> Seq(Set(99, 95, 94, 92)), + 100 -> Seq(Set(100, 63), Set(100, 98, 93, 92)), + 101 -> Seq(Set(101, 100, 95, 94)), + 102 -> Seq(Set(102, 99, 97, 96)), + 103 -> Seq(Set(103, 94), Set(103, 102, 99, 94)), + 104 -> Seq(Set(104, 103, 94, 93)), + 105 -> Seq(Set(105, 89), Set(105, 104, 99, 98)), + 106 -> Seq(Set(106, 91), Set(106, 105, 101, 100)), + 107 -> Seq(Set(107, 105, 99, 98)), + 108 -> Seq(Set(108, 77), Set(108, 103, 97, 96)), + 109 -> Seq(Set(109, 107, 105, 104)), + 110 -> Seq(Set(110, 109, 106, 104)), + 111 -> Seq(Set(111, 101), Set(111, 109, 107, 104)), + 112 -> Seq(Set(112, 108, 106, 101)), + 113 -> Seq(Set(113, 104), Set(113, 111, 110, 108)), + 114 -> Seq(Set(114, 113, 112, 103)), + 115 -> Seq(Set(115, 110, 108, 107)), + 116 -> Seq(Set(116, 114, 111, 110)), + 117 -> Seq(Set(117, 116, 115, 112)), + 118 -> Seq(Set(118, 85), Set(118, 116, 113, 112)), + 119 -> Seq(Set(119, 111), Set(119, 116, 111, 110)), + 120 -> Seq(Set(120, 118, 114, 111)), + 121 -> Seq(Set(121, 103), Set(121, 120, 116, 113)), + 122 -> Seq(Set(122, 121, 120, 116)), + 123 -> Seq(Set(123, 121), Set(123, 122, 119, 115)), + 124 -> Seq(Set(124, 87), Set(124, 119, 118, 117)), + 125 -> Seq(Set(125, 120, 119, 118)), + 126 -> Seq(Set(126, 124, 122, 119)), + 127 -> Seq(Set(127, 126), Set(127, 126, 124, 120)), + 128 -> Seq(Set(128, 127, 126, 121)), + 129 -> Seq(Set(129, 124), Set(129, 128, 125, 124)), + 130 -> Seq(Set(130, 127), Set(130, 129, 128, 125)), + 131 -> Seq(Set(131, 129, 128, 123)), + 132 -> Seq(Set(132, 103), Set(132, 130, 127, 123)), + 133 -> Seq(Set(133, 131, 125, 124)), + 134 -> Seq(Set(134, 77), Set(134, 133, 129, 127)), + 135 -> Seq(Set(135, 124), Set(135, 132, 131, 129)), + 136 -> Seq(Set(136, 134, 133, 128)), + 137 -> Seq(Set(137, 116), Set(137, 136, 133, 126)), + 138 -> Seq(Set(138, 137, 131, 130)), + 139 -> Seq(Set(139, 136, 134, 131)), + 140 -> Seq(Set(140, 111), Set(140, 139, 136, 132)), + 141 -> Seq(Set(141, 140, 135, 128)), + 142 -> Seq(Set(142, 121), Set(142, 141, 139, 132)), + 143 -> Seq(Set(143, 141, 140, 138)), + 144 -> Seq(Set(144, 142, 140, 137)), + 145 -> Seq(Set(145, 93), Set(145, 144, 140, 139)), + 146 -> Seq(Set(146, 144, 143, 141)), + 147 -> Seq(Set(147, 145, 143, 136)), + 148 -> Seq(Set(148, 121), Set(148, 145, 143, 141)), + 149 -> Seq(Set(149, 142, 140, 139)), + 150 -> Seq(Set(150, 97), Set(150, 148, 147, 142)), + 151 -> Seq(Set(151, 148), Set(151, 150, 149, 148)), + 152 -> Seq(Set(152, 150, 149, 146)), + 153 -> Seq(Set(153, 152), Set(153, 149, 148, 145)), + 154 -> Seq(Set(154, 153, 149, 145)), + 155 -> Seq(Set(155, 151, 150, 148)), + 156 -> Seq(Set(156, 153, 151, 147)), + 157 -> Seq(Set(157, 155, 152, 151)), + 158 -> Seq(Set(158, 153, 152, 150)), + 159 -> Seq(Set(159, 128), Set(159, 156, 153, 148)), + 160 -> Seq(Set(160, 158, 157, 155)), + 161 -> Seq(Set(161, 143), Set(161, 159, 158, 155)), + 162 -> Seq(Set(162, 158, 155, 154)), + 163 -> Seq(Set(163, 160, 157, 156)), + 164 -> Seq(Set(164, 159, 158, 152)), + 165 -> Seq(Set(165, 162, 157, 156)), + 166 -> Seq(Set(166, 164, 163, 156)), + 167 -> Seq(Set(167, 161), Set(167, 165, 163, 161)), + 168 -> Seq(Set(168, 162, 159, 152)), + 169 -> Seq(Set(169, 135), Set(169, 164, 163, 161)), + 170 -> Seq(Set(170, 147), Set(170, 169, 166, 161)), + 171 -> Seq(Set(171, 169, 166, 165)), + 172 -> Seq(Set(172, 165), Set(172, 169, 165, 161)), + 173 -> Seq(Set(173, 171, 168, 165)), + 174 -> Seq(Set(174, 161), Set(174, 169, 166, 165)), + 175 -> Seq(Set(175, 169), Set(175, 173, 171, 169)), + 176 -> Seq(Set(176, 167, 165, 164)), + 177 -> Seq(Set(177, 169), Set(177, 175, 174, 172)), + 178 -> Seq(Set(178, 91), Set(178, 176, 171, 170)), + 179 -> Seq(Set(179, 178, 177, 175)), + 180 -> Seq(Set(180, 173, 170, 168)), + 181 -> Seq(Set(181, 180, 175, 174)), + 182 -> Seq(Set(182, 181, 176, 174)), + 183 -> Seq(Set(183, 127), Set(183, 179, 176, 175)), + 184 -> Seq(Set(184, 177, 176, 175)), + 185 -> Seq(Set(185, 161), Set(185, 184, 182, 177)), + 186 -> Seq(Set(186, 180, 178, 177)), + 187 -> Seq(Set(187, 182, 181, 180)), + 188 -> Seq(Set(188, 186, 183, 182)), + 189 -> Seq(Set(189, 187, 184, 183)), + 190 -> Seq(Set(190, 188, 184, 177)), + 191 -> Seq(Set(191, 182), Set(191, 187, 185, 184)), + 192 -> Seq(Set(192, 190, 178, 177)), + 193 -> Seq(Set(193, 178), Set(193, 189, 186, 184)), + 194 -> Seq(Set(194, 107), Set(194, 192, 191, 190)), + 195 -> Seq(Set(195, 193, 192, 187)), + 196 -> Seq(Set(196, 194, 187, 185)), + 197 -> Seq(Set(197, 195, 193, 188)), + 198 -> Seq(Set(198, 133), Set(198, 193, 190, 183)), + 199 -> Seq(Set(199, 165), Set(199, 198, 195, 190)), + 200 -> Seq(Set(200, 198, 197, 195)), + 201 -> Seq(Set(201, 187), Set(201, 199, 198, 195)), + 202 -> Seq(Set(202, 147), Set(202, 198, 196, 195)), + 203 -> Seq(Set(203, 202, 196, 195)), + 204 -> Seq(Set(204, 201, 200, 194)), + 205 -> Seq(Set(205, 203, 200, 196)), + 206 -> Seq(Set(206, 201, 197, 196)), + 207 -> Seq(Set(207, 164), Set(207, 206, 201, 198)), + 208 -> Seq(Set(208, 207, 205, 199)), + 209 -> Seq(Set(209, 203), Set(209, 207, 206, 204)), + 210 -> Seq(Set(210, 207, 206, 198)), + 211 -> Seq(Set(211, 203, 201, 200)), + 212 -> Seq(Set(212, 107), Set(212, 209, 208, 205)), + 213 -> Seq(Set(213, 211, 208, 207)), + 214 -> Seq(Set(214, 213, 211, 209)), + 215 -> Seq(Set(215, 192), Set(215, 212, 210, 209)), + 216 -> Seq(Set(216, 215, 213, 209)), + 217 -> Seq(Set(217, 172), Set(217, 213, 212, 211)), + 218 -> Seq(Set(218, 207), Set(218, 217, 211, 210)), + 219 -> Seq(Set(219, 218, 215, 211)), + 220 -> Seq(Set(220, 211, 210, 208)), + 221 -> Seq(Set(221, 219, 215, 213)), + 222 -> Seq(Set(222, 220, 217, 214)), + 223 -> Seq(Set(223, 190), Set(223, 221, 219, 218)), + 224 -> Seq(Set(224, 222, 217, 212)), + 225 -> Seq(Set(225, 193), Set(225, 224, 220, 215)), + 226 -> Seq(Set(226, 223, 219, 216)), + 227 -> Seq(Set(227, 223, 218, 217)), + 228 -> Seq(Set(228, 226, 217, 216)), + 229 -> Seq(Set(229, 228, 225, 219)), + 230 -> Seq(Set(230, 224, 223, 222)), + 231 -> Seq(Set(231, 205), Set(231, 229, 227, 224)), + 232 -> Seq(Set(232, 228, 223, 221)), + 233 -> Seq(Set(233, 159), Set(233, 232, 229, 224)), + 234 -> Seq(Set(234, 203), Set(234, 232, 225, 223)), + 235 -> Seq(Set(235, 234, 229, 226)), + 236 -> Seq(Set(236, 231), Set(236, 229, 228, 226)), + 237 -> Seq(Set(237, 236, 233, 230)), + 238 -> Seq(Set(238, 237, 236, 233)), + 239 -> Seq(Set(239, 203), Set(239, 238, 232, 227)), + 240 -> Seq(Set(240, 237, 235, 232)), + 241 -> Seq(Set(241, 171), Set(241, 237, 233, 232)), + 242 -> Seq(Set(242, 241, 236, 231)), + 243 -> Seq(Set(243, 242, 238, 235)), + 244 -> Seq(Set(244, 243, 240, 235)), + 245 -> Seq(Set(245, 244, 241, 239)), + 246 -> Seq(Set(246, 245, 244, 235)), + 247 -> Seq(Set(247, 165), Set(247, 245, 243, 238)), + 248 -> Seq(Set(248, 238, 234, 233)), + 249 -> Seq(Set(249, 163), Set(249, 248, 245, 242)), + 250 -> Seq(Set(250, 147), Set(250, 247, 245, 240)), + 251 -> Seq(Set(251, 249, 247, 244)), + 252 -> Seq(Set(252, 185), Set(252, 251, 247, 241)), + 253 -> Seq(Set(253, 252, 247, 246)), + 254 -> Seq(Set(254, 253, 252, 247)), + 255 -> Seq(Set(255, 203), Set(255, 253, 252, 250)), + 256 -> Seq(Set(256, 254, 251, 246)), + 257 -> Seq(Set(257, 245), Set(257, 255, 251, 250)), + 258 -> Seq(Set(258, 175), Set(258, 254, 252, 249)), + 259 -> Seq(Set(259, 257, 253, 249)), + 260 -> Seq(Set(260, 253, 252, 250)), + 261 -> Seq(Set(261, 257, 255, 254)), + 262 -> Seq(Set(262, 258, 254, 253)), + 263 -> Seq(Set(263, 170), Set(263, 261, 258, 252)), + 264 -> Seq(Set(264, 263, 255, 254)), + 265 -> Seq(Set(265, 223), Set(265, 263, 262, 260)), + 266 -> Seq(Set(266, 219), Set(266, 265, 260, 259)), + 267 -> Seq(Set(267, 264, 261, 259)), + 268 -> Seq(Set(268, 243), Set(268, 267, 264, 258)), + 269 -> Seq(Set(269, 268, 263, 262)), + 270 -> Seq(Set(270, 217), Set(270, 267, 263, 260)), + 271 -> Seq(Set(271, 213), Set(271, 265, 264, 260)), + 272 -> Seq(Set(272, 270, 266, 263)), + 273 -> Seq(Set(273, 250), Set(273, 272, 271, 266)), + 274 -> Seq(Set(274, 207), Set(274, 272, 267, 265)), + 275 -> Seq(Set(275, 266, 265, 264)), + 276 -> Seq(Set(276, 275, 273, 270)), + 277 -> Seq(Set(277, 274, 271, 265)), + 278 -> Seq(Set(278, 273), Set(278, 277, 274, 273)), + 279 -> Seq(Set(279, 274), Set(279, 278, 275, 274)), + 280 -> Seq(Set(280, 278, 275, 271)), + 281 -> Seq(Set(281, 188), Set(281, 280, 277, 272)), + 282 -> Seq(Set(282, 247), Set(282, 278, 277, 272)), + 283 -> Seq(Set(283, 278, 276, 271)), + 284 -> Seq(Set(284, 165), Set(284, 279, 278, 276)), + 285 -> Seq(Set(285, 280, 278, 275)), + 286 -> Seq(Set(286, 217), Set(286, 285, 276, 271)), + 287 -> Seq(Set(287, 216), Set(287, 285, 282, 281)), + 288 -> Seq(Set(288, 287, 278, 277)), + 289 -> Seq(Set(289, 268), Set(289, 286, 285, 277)), + 290 -> Seq(Set(290, 288, 287, 285)), + 291 -> Seq(Set(291, 286, 280, 279)), + 292 -> Seq(Set(292, 195), Set(292, 291, 289, 285)), + 293 -> Seq(Set(293, 292, 287, 282)), + 294 -> Seq(Set(294, 233), Set(294, 292, 291, 285)), + 295 -> Seq(Set(295, 247), Set(295, 293, 291, 290)), + 296 -> Seq(Set(296, 292, 287, 285)), + 297 -> Seq(Set(297, 292), Set(297, 296, 293, 292)), + 298 -> Seq(Set(298, 294, 290, 287)), + 299 -> Seq(Set(299, 295, 293, 288)), + 300 -> Seq(Set(300, 293), Set(300, 290, 288, 287)), + 301 -> Seq(Set(301, 299, 296, 292)), + 302 -> Seq(Set(302, 261), Set(302, 297, 293, 290)), + 303 -> Seq(Set(303, 297, 291, 290)), + 304 -> Seq(Set(304, 303, 302, 293)), + 305 -> Seq(Set(305, 203), Set(305, 303, 299, 298)), + 306 -> Seq(Set(306, 305, 303, 299)), + 307 -> Seq(Set(307, 305, 303, 299)), + 308 -> Seq(Set(308, 306, 299, 293)), + 309 -> Seq(Set(309, 307, 302, 299)), + 310 -> Seq(Set(310, 309, 305, 302)), + 311 -> Seq(Set(311, 308, 306, 304)), + 312 -> Seq(Set(312, 307, 302, 301)), + 313 -> Seq(Set(313, 234), Set(313, 312, 310, 306)), + 314 -> Seq(Set(314, 299), Set(314, 311, 305, 300)), + 315 -> Seq(Set(315, 314, 306, 305)), + 316 -> Seq(Set(316, 181), Set(316, 309, 305, 304)), + 317 -> Seq(Set(317, 315, 313, 310)), + 318 -> Seq(Set(318, 313, 312, 310)), + 319 -> Seq(Set(319, 283), Set(319, 318, 317, 308)), + 320 -> Seq(Set(320, 319, 317, 316)), + 321 -> Seq(Set(321, 290), Set(321, 319, 316, 314)), + 322 -> Seq(Set(322, 255), Set(322, 321, 320, 305)), + 323 -> Seq(Set(323, 322, 320, 313)), + 324 -> Seq(Set(324, 321, 320, 318)), + 325 -> Seq(Set(325, 323, 320, 315)), + 326 -> Seq(Set(326, 325, 323, 316)), + 327 -> Seq(Set(327, 293), Set(327, 325, 322, 319)), + 328 -> Seq(Set(328, 323, 321, 319)), + 329 -> Seq(Set(329, 279), Set(329, 326, 323, 321)), + 330 -> Seq(Set(330, 328, 323, 322)), + 331 -> Seq(Set(331, 329, 325, 321)), + 332 -> Seq(Set(332, 209), Set(332, 325, 321, 320)), + 333 -> Seq(Set(333, 331), Set(333, 331, 329, 325)), + 334 -> Seq(Set(334, 333, 330, 327)), + 335 -> Seq(Set(335, 333, 328, 325)), + 336 -> Seq(Set(336, 335, 332, 329)), + 337 -> Seq(Set(337, 282), Set(337, 336, 331, 327)), + 338 -> Seq(Set(338, 336, 335, 332)), + 339 -> Seq(Set(339, 332, 329, 323)), + 340 -> Seq(Set(340, 337, 336, 329)), + 341 -> Seq(Set(341, 336, 330, 327)), + 342 -> Seq(Set(342, 217), Set(342, 341, 340, 331)), + 343 -> Seq(Set(343, 268), Set(343, 338, 335, 333)), + 344 -> Seq(Set(344, 338, 334, 333)), + 345 -> Seq(Set(345, 323), Set(345, 343, 341, 337)), + 346 -> Seq(Set(346, 344, 339, 335)), + 347 -> Seq(Set(347, 344, 337, 336)), + 348 -> Seq(Set(348, 344, 341, 340)), + 349 -> Seq(Set(349, 347, 344, 343)), + 350 -> Seq(Set(350, 297), Set(350, 340, 337, 336)), + 351 -> Seq(Set(351, 317), Set(351, 348, 345, 343)), + 352 -> Seq(Set(352, 346, 341, 339)), + 353 -> Seq(Set(353, 284), Set(353, 349, 346, 344)), + 354 -> Seq(Set(354, 349, 341, 340)), + 355 -> Seq(Set(355, 354, 350, 349)), + 356 -> Seq(Set(356, 349, 347, 346)), + 357 -> Seq(Set(357, 355, 347, 346)), + 358 -> Seq(Set(358, 351, 350, 344)), + 359 -> Seq(Set(359, 291), Set(359, 358, 352, 350)), + 360 -> Seq(Set(360, 359, 335, 334)), + 361 -> Seq(Set(361, 360, 357, 354)), + 362 -> Seq(Set(362, 299), Set(362, 360, 351, 344)), + 363 -> Seq(Set(363, 362, 356, 355)), + 364 -> Seq(Set(364, 297), Set(364, 363, 359, 352)), + 365 -> Seq(Set(365, 360, 359, 356)), + 366 -> Seq(Set(366, 337), Set(366, 362, 359, 352)), + 367 -> Seq(Set(367, 346), Set(367, 365, 363, 358)), + 368 -> Seq(Set(368, 361, 359, 351)), + 369 -> Seq(Set(369, 278), Set(369, 367, 359, 358)), + 370 -> Seq(Set(370, 231), Set(370, 368, 367, 365)), + 371 -> Seq(Set(371, 369, 368, 363)), + 372 -> Seq(Set(372, 369, 365, 357)), + 373 -> Seq(Set(373, 371, 366, 365)), + 374 -> Seq(Set(374, 369, 368, 366)), + 375 -> Seq(Set(375, 359), Set(375, 374, 368, 367)), + 376 -> Seq(Set(376, 371, 369, 368)), + 377 -> Seq(Set(377, 336), Set(377, 376, 374, 369)), + 378 -> Seq(Set(378, 335), Set(378, 374, 365, 363)), + 379 -> Seq(Set(379, 375, 370, 369)), + 380 -> Seq(Set(380, 333), Set(380, 377, 374, 366)), + 381 -> Seq(Set(381, 380, 379, 376)), + 382 -> Seq(Set(382, 301), Set(382, 379, 375, 364)), + 383 -> Seq(Set(383, 293), Set(383, 382, 378, 374)), + 384 -> Seq(Set(384, 378, 369, 368)), + 385 -> Seq(Set(385, 379), Set(385, 383, 381, 379)), + 386 -> Seq(Set(386, 303), Set(386, 381, 380, 376)), + 387 -> Seq(Set(387, 385, 379, 378)), + 388 -> Seq(Set(388, 387, 385, 374)), + 389 -> Seq(Set(389, 384, 380, 379)), + 390 -> Seq(Set(390, 301), Set(390, 388, 380, 377)), + 391 -> Seq(Set(391, 363), Set(391, 390, 389, 385)), + 392 -> Seq(Set(392, 386, 382, 379)), + 393 -> Seq(Set(393, 386), Set(393, 392, 391, 386)), + 394 -> Seq(Set(394, 259), Set(394, 392, 387, 386)) + ) /** Second portion of known taps (a combined map hits the 64KB JVM method limit) */ private def tapsSecond = Map( - 395 -> Seq(Set(395, 390, 389, 384)), - 396 -> Seq(Set(396, 371), Set(396, 392, 390, 389)), - 397 -> Seq(Set(397, 392, 387, 385)), - 398 -> Seq(Set(398, 393, 392, 384)), - 399 -> Seq(Set(399, 313), Set(399, 397, 390, 388)), - 400 -> Seq(Set(400, 398, 397, 395)), - 401 -> Seq(Set(401, 249), Set(401, 399, 392, 389)), - 402 -> Seq(Set(402, 399, 398, 393)), - 403 -> Seq(Set(403, 398, 395, 394)), - 404 -> Seq(Set(404, 215), Set(404, 400, 398, 397)), - 405 -> Seq(Set(405, 398, 397, 388)), - 406 -> Seq(Set(406, 249), Set(406, 402, 397, 393)), - 407 -> Seq(Set(407, 336), Set(407, 402, 400, 398)), - 408 -> Seq(Set(408, 407, 403, 401)), - 409 -> Seq(Set(409, 322), Set(409, 406, 404, 402)), - 410 -> Seq(Set(410, 407, 406, 400)), - 411 -> Seq(Set(411, 408, 401, 399)), - 412 -> Seq(Set(412, 265), Set(412, 409, 404, 401)), - 413 -> Seq(Set(413, 407, 406, 403)), - 414 -> Seq(Set(414, 405, 401, 398)), - 415 -> Seq(Set(415, 313), Set(415, 413, 411, 406)), - 416 -> Seq(Set(416, 414, 411, 407)), - 417 -> Seq(Set(417, 310), Set(417, 416, 414, 407)), - 418 -> Seq(Set(418, 417, 415, 403)), - 419 -> Seq(Set(419, 415, 414, 404)), - 420 -> Seq(Set(420, 412, 410, 407)), - 421 -> Seq(Set(421, 419, 417, 416)), - 422 -> Seq(Set(422, 273), Set(422, 421, 416, 412)), - 423 -> Seq(Set(423, 398), Set(423, 420, 418, 414)), - 424 -> Seq(Set(424, 422, 417, 415)), - 425 -> Seq(Set(425, 413), Set(425, 422, 421, 418)), - 426 -> Seq(Set(426, 415, 414, 412)), - 427 -> Seq(Set(427, 422, 421, 416)), - 428 -> Seq(Set(428, 323), Set(428, 426, 425, 417)), - 429 -> Seq(Set(429, 422, 421, 419)), - 430 -> Seq(Set(430, 419, 417, 415)), - 431 -> Seq(Set(431, 311), Set(431, 430, 428, 426)), - 432 -> Seq(Set(432, 429, 428, 419)), - 433 -> Seq(Set(433, 400), Set(433, 430, 428, 422)), - 434 -> Seq(Set(434, 429, 423, 422)), - 435 -> Seq(Set(435, 430, 426, 423)), - 436 -> Seq(Set(436, 271), Set(436, 432, 431, 430)), - 437 -> Seq(Set(437, 436, 435, 431)), - 438 -> Seq(Set(438, 373), Set(438, 436, 432, 421)), - 439 -> Seq(Set(439, 390), Set(439, 437, 436, 431)), - 440 -> Seq(Set(440, 439, 437, 436)), - 441 -> Seq(Set(441, 410), Set(441, 440, 433, 430)), - 442 -> Seq(Set(442, 440, 437, 435)), - 443 -> Seq(Set(443, 442, 437, 433)), - 444 -> Seq(Set(444, 435, 432, 431)), - 445 -> Seq(Set(445, 441, 439, 438)), - 446 -> Seq(Set(446, 341), Set(446, 442, 439, 431)), - 447 -> Seq(Set(447, 374), Set(447, 446, 441, 438)), - 448 -> Seq(Set(448, 444, 442, 437)), - 449 -> Seq(Set(449, 315), Set(449, 446, 440, 438)), - 450 -> Seq(Set(450, 371), Set(450, 443, 438, 434)), - 451 -> Seq(Set(451, 450, 441, 435)), - 452 -> Seq(Set(452, 448, 447, 446)), - 453 -> Seq(Set(453, 449, 447, 438)), - 454 -> Seq(Set(454, 449, 445, 444)), - 455 -> Seq(Set(455, 417), Set(455, 453, 449, 444)), - 456 -> Seq(Set(456, 454, 445, 433)), - 457 -> Seq(Set(457, 441), Set(457, 454, 449, 446)), - 458 -> Seq(Set(458, 255), Set(458, 453, 448, 445)), - 459 -> Seq(Set(459, 457, 454, 447)), - 460 -> Seq(Set(460, 399), Set(460, 459, 455, 451)), - 461 -> Seq(Set(461, 460, 455, 454)), - 462 -> Seq(Set(462, 389), Set(462, 457, 451, 450)), - 463 -> Seq(Set(463, 370), Set(463, 456, 455, 452)), - 464 -> Seq(Set(464, 460, 455, 441)), - 465 -> Seq(Set(465, 406), Set(465, 463, 462, 457)), - 466 -> Seq(Set(466, 460, 455, 452)), - 467 -> Seq(Set(467, 466, 461, 456)), - 468 -> Seq(Set(468, 464, 459, 453)), - 469 -> Seq(Set(469, 467, 464, 460)), - 470 -> Seq(Set(470, 321), Set(470, 468, 462, 461)), - 471 -> Seq(Set(471, 470), Set(471, 469, 468, 465)), - 472 -> Seq(Set(472, 470, 469, 461)), - 473 -> Seq(Set(473, 470, 467, 465)), - 474 -> Seq(Set(474, 283), Set(474, 465, 463, 456)), - 475 -> Seq(Set(475, 471, 467, 466)), - 476 -> Seq(Set(476, 461), Set(476, 475, 468, 466)), - 477 -> Seq(Set(477, 470, 462, 461)), - 478 -> Seq(Set(478, 357), Set(478, 477, 474, 472)), - 479 -> Seq(Set(479, 375), Set(479, 475, 472, 470)), - 480 -> Seq(Set(480, 473, 467, 464)), - 481 -> Seq(Set(481, 343), Set(481, 480, 472, 471)), - 482 -> Seq(Set(482, 477, 476, 473)), - 483 -> Seq(Set(483, 479, 477, 474)), - 484 -> Seq(Set(484, 379), Set(484, 483, 482, 470)), - 485 -> Seq(Set(485, 479, 469, 468)), - 486 -> Seq(Set(486, 481, 478, 472)), - 487 -> Seq(Set(487, 393), Set(487, 485, 483, 478)), - 488 -> Seq(Set(488, 487, 485, 484)), - 489 -> Seq(Set(489, 406), Set(489, 484, 483, 480)), - 490 -> Seq(Set(490, 271), Set(490, 485, 483, 481)), - 491 -> Seq(Set(491, 488, 485, 480)), - 492 -> Seq(Set(492, 491, 485, 484)), - 493 -> Seq(Set(493, 490, 488, 483)), - 494 -> Seq(Set(494, 357), Set(494, 493, 489, 481)), - 495 -> Seq(Set(495, 419), Set(495, 494, 486, 480)), - 496 -> Seq(Set(496, 494, 491, 480)), - 497 -> Seq(Set(497, 419), Set(497, 493, 488, 486)), - 498 -> Seq(Set(498, 495, 489, 487)), - 499 -> Seq(Set(499, 494, 493, 488)), - 500 -> Seq(Set(500, 499, 494, 490)), - 501 -> Seq(Set(501, 499, 497, 496)), - 502 -> Seq(Set(502, 498, 497, 494)), - 503 -> Seq(Set(503, 500), Set(503, 502, 501, 500)), - 504 -> Seq(Set(504, 502, 490, 483)), - 505 -> Seq(Set(505, 349), Set(505, 500, 497, 493)), - 506 -> Seq(Set(506, 411), Set(506, 501, 494, 491)), - 507 -> Seq(Set(507, 504, 501, 494)), - 508 -> Seq(Set(508, 399), Set(508, 505, 500, 495)), - 509 -> Seq(Set(509, 506, 502, 501)), - 510 -> Seq(Set(510, 501, 500, 498)), - 511 -> Seq(Set(511, 501), Set(511, 509, 503, 501)), - 512 -> Seq(Set(512, 510, 507, 504)), - 513 -> Seq(Set(513, 428), Set(513, 505, 503, 500)), - 514 -> Seq(Set(514, 511, 509, 507)), - 515 -> Seq(Set(515, 511, 508, 501)), - 516 -> Seq(Set(516, 514, 511, 509)), - 517 -> Seq(Set(517, 515, 507, 505)), - 518 -> Seq(Set(518, 485), Set(518, 516, 515, 507)), - 519 -> Seq(Set(519, 440), Set(519, 517, 511, 507)), - 520 -> Seq(Set(520, 509, 507, 503)), - 521 -> Seq(Set(521, 489), Set(521, 519, 514, 512)), - 522 -> Seq(Set(522, 518, 509, 507)), - 523 -> Seq(Set(523, 521, 517, 510)), - 524 -> Seq(Set(524, 357), Set(524, 523, 519, 515)), - 525 -> Seq(Set(525, 524, 521, 519)), - 526 -> Seq(Set(526, 525, 521, 517)), - 527 -> Seq(Set(527, 480), Set(527, 526, 520, 518)), - 528 -> Seq(Set(528, 526, 522, 517)), - 529 -> Seq(Set(529, 487), Set(529, 528, 525, 522)), - 530 -> Seq(Set(530, 527, 523, 520)), - 531 -> Seq(Set(531, 529, 525, 519)), - 532 -> Seq(Set(532, 531), Set(532, 529, 528, 522)), - 533 -> Seq(Set(533, 531, 530, 529)), - 534 -> Seq(Set(534, 533, 529, 527)), - 535 -> Seq(Set(535, 533, 529, 527)), - 536 -> Seq(Set(536, 533, 531, 529)), - 537 -> Seq(Set(537, 443), Set(537, 536, 535, 527)), - 538 -> Seq(Set(538, 537, 536, 533)), - 539 -> Seq(Set(539, 535, 534, 529)), - 540 -> Seq(Set(540, 361), Set(540, 537, 534, 529)), - 541 -> Seq(Set(541, 537, 531, 528)), - 542 -> Seq(Set(542, 540, 539, 533)), - 543 -> Seq(Set(543, 527), Set(543, 538, 536, 532)), - 544 -> Seq(Set(544, 538, 535, 531)), - 545 -> Seq(Set(545, 423), Set(545, 539, 537, 532)), - 546 -> Seq(Set(546, 545, 544, 538)), - 547 -> Seq(Set(547, 543, 540, 534)), - 548 -> Seq(Set(548, 545, 543, 538)), - 549 -> Seq(Set(549, 546, 545, 533)), - 550 -> Seq(Set(550, 357), Set(550, 546, 533, 529)), - 551 -> Seq(Set(551, 416), Set(551, 550, 547, 542)), - 552 -> Seq(Set(552, 550, 547, 532)), - 553 -> Seq(Set(553, 514), Set(553, 550, 549, 542)), - 554 -> Seq(Set(554, 551, 546, 543)), - 555 -> Seq(Set(555, 551, 546, 545)), - 556 -> Seq(Set(556, 403), Set(556, 549, 546, 540)), - 557 -> Seq(Set(557, 552, 551, 550)), - 558 -> Seq(Set(558, 553, 549, 544)), - 559 -> Seq(Set(559, 525), Set(559, 557, 552, 550)), - 560 -> Seq(Set(560, 554, 551, 549)), - 561 -> Seq(Set(561, 490), Set(561, 558, 552, 550)), - 562 -> Seq(Set(562, 560, 558, 551)), - 563 -> Seq(Set(563, 561, 554, 549)), - 564 -> Seq(Set(564, 401), Set(564, 563, 561, 558)), - 565 -> Seq(Set(565, 564, 559, 554)), - 566 -> Seq(Set(566, 413), Set(566, 564, 561, 560)), - 567 -> Seq(Set(567, 424), Set(567, 563, 557, 556)), - 568 -> Seq(Set(568, 558, 557, 551)), - 569 -> Seq(Set(569, 492), Set(569, 568, 559, 557)), - 570 -> Seq(Set(570, 503), Set(570, 563, 558, 552)), - 571 -> Seq(Set(571, 569, 566, 561)), - 572 -> Seq(Set(572, 571, 564, 560)), - 573 -> Seq(Set(573, 569, 567, 563)), - 574 -> Seq(Set(574, 561), Set(574, 569, 565, 560)), - 575 -> Seq(Set(575, 429), Set(575, 572, 570, 569)), - 576 -> Seq(Set(576, 573, 572, 563)), - 577 -> Seq(Set(577, 552), Set(577, 575, 574, 569)), - 578 -> Seq(Set(578, 562, 556, 555)), - 579 -> Seq(Set(579, 572, 570, 567)), - 580 -> Seq(Set(580, 579, 576, 574)), - 581 -> Seq(Set(581, 575, 574, 568)), - 582 -> Seq(Set(582, 497), Set(582, 579, 576, 571)), - 583 -> Seq(Set(583, 453), Set(583, 581, 577, 575)), - 584 -> Seq(Set(584, 581, 571, 570)), - 585 -> Seq(Set(585, 464), Set(585, 583, 582, 577)), - 586 -> Seq(Set(586, 584, 581, 579)), - 587 -> Seq(Set(587, 586, 581, 576)), - 588 -> Seq(Set(588, 437), Set(588, 577, 572, 571)), - 589 -> Seq(Set(589, 586, 585, 579)), - 590 -> Seq(Set(590, 497), Set(590, 588, 587, 578)), - 591 -> Seq(Set(591, 587, 585, 582)), - 592 -> Seq(Set(592, 591, 573, 568)), - 593 -> Seq(Set(593, 507), Set(593, 588, 585, 584)), - 594 -> Seq(Set(594, 575), Set(594, 586, 584, 583)), - 595 -> Seq(Set(595, 594, 593, 586)), - 596 -> Seq(Set(596, 592, 591, 590)), - 597 -> Seq(Set(597, 588, 585, 583)), - 598 -> Seq(Set(598, 597, 592, 591)), - 599 -> Seq(Set(599, 569), Set(599, 593, 591, 590)), - 600 -> Seq(Set(600, 599, 590, 589)), - 601 -> Seq(Set(601, 400), Set(601, 600, 597, 589)), - 602 -> Seq(Set(602, 596, 594, 591)), - 603 -> Seq(Set(603, 600, 599, 597)), - 604 -> Seq(Set(604, 600, 598, 589)), - 605 -> Seq(Set(605, 600, 598, 595)), - 606 -> Seq(Set(606, 602, 599, 591)), - 607 -> Seq(Set(607, 502), Set(607, 600, 598, 595)), - 608 -> Seq(Set(608, 606, 602, 585)), - 609 -> Seq(Set(609, 578), Set(609, 601, 600, 597)), - 610 -> Seq(Set(610, 483), Set(610, 602, 600, 599)), - 611 -> Seq(Set(611, 609, 607, 601)), - 612 -> Seq(Set(612, 607, 602, 598)), - 613 -> Seq(Set(613, 609, 603, 594)), - 614 -> Seq(Set(614, 613, 612, 607)), - 615 -> Seq(Set(615, 404), Set(615, 614, 609, 608)), - 616 -> Seq(Set(616, 614, 602, 597)), - 617 -> Seq(Set(617, 417), Set(617, 612, 608, 607)), - 618 -> Seq(Set(618, 615, 604, 598)), - 619 -> Seq(Set(619, 614, 611, 610)), - 620 -> Seq(Set(620, 619, 618, 611)), - 621 -> Seq(Set(621, 616, 615, 609)), - 622 -> Seq(Set(622, 325), Set(622, 612, 610, 605)), - 623 -> Seq(Set(623, 555), Set(623, 614, 613, 612)), - 624 -> Seq(Set(624, 617, 615, 612)), - 625 -> Seq(Set(625, 492), Set(625, 620, 617, 613)), - 626 -> Seq(Set(626, 623, 621, 613)), - 627 -> Seq(Set(627, 622, 617, 613)), - 628 -> Seq(Set(628, 405), Set(628, 626, 617, 616)), - 629 -> Seq(Set(629, 627, 624, 623)), - 630 -> Seq(Set(630, 628, 626, 623)), - 631 -> Seq(Set(631, 324), Set(631, 625, 623, 617)), - 632 -> Seq(Set(632, 629, 619, 613)), - 633 -> Seq(Set(633, 532), Set(633, 632, 631, 626)), - 634 -> Seq(Set(634, 319), Set(634, 631, 629, 627)), - 635 -> Seq(Set(635, 631, 625, 621)), - 636 -> Seq(Set(636, 632, 628, 623)), - 637 -> Seq(Set(637, 636, 628, 623)), - 638 -> Seq(Set(638, 637, 633, 632)), - 639 -> Seq(Set(639, 623), Set(639, 636, 635, 629)), - 640 -> Seq(Set(640, 638, 637, 626)), - 641 -> Seq(Set(641, 630), Set(641, 640, 636, 622)), - 642 -> Seq(Set(642, 523), Set(642, 636, 633, 632)), - 643 -> Seq(Set(643, 641, 640, 632)), - 644 -> Seq(Set(644, 634, 633, 632)), - 645 -> Seq(Set(645, 641, 637, 634)), - 646 -> Seq(Set(646, 397), Set(646, 635, 634, 633)), - 647 -> Seq(Set(647, 642), Set(647, 646, 643, 642)), - 648 -> Seq(Set(648, 647, 626, 625)), - 649 -> Seq(Set(649, 612), Set(649, 648, 644, 638)), - 650 -> Seq(Set(650, 647), Set(650, 644, 635, 632)), - 651 -> Seq(Set(651, 646, 638, 637)), - 652 -> Seq(Set(652, 559), Set(652, 647, 643, 641)), - 653 -> Seq(Set(653, 646, 645, 643)), - 654 -> Seq(Set(654, 649, 643, 640)), - 655 -> Seq(Set(655, 567), Set(655, 653, 639, 638)), - 656 -> Seq(Set(656, 646, 638, 637)), - 657 -> Seq(Set(657, 619), Set(657, 656, 650, 649)), - 658 -> Seq(Set(658, 603), Set(658, 651, 648, 646)), - 659 -> Seq(Set(659, 657, 655, 644)), - 660 -> Seq(Set(660, 657, 656, 648)), - 661 -> Seq(Set(661, 657, 650, 649)), - 662 -> Seq(Set(662, 365), Set(662, 659, 656, 650)), - 663 -> Seq(Set(663, 406), Set(663, 655, 652, 649)), - 664 -> Seq(Set(664, 662, 660, 649)), - 665 -> Seq(Set(665, 632), Set(665, 661, 659, 654)), - 666 -> Seq(Set(666, 664, 659, 656)), - 667 -> Seq(Set(667, 664, 660, 649)), - 668 -> Seq(Set(668, 658, 656, 651)), - 669 -> Seq(Set(669, 667, 665, 664)), - 670 -> Seq(Set(670, 517), Set(670, 669, 665, 664)), - 671 -> Seq(Set(671, 656), Set(671, 669, 665, 662)), - 672 -> Seq(Set(672, 667, 666, 661)), - 673 -> Seq(Set(673, 645), Set(673, 666, 664, 663)), - 674 -> Seq(Set(674, 671, 665, 660)), - 675 -> Seq(Set(675, 674, 672, 669)), - 676 -> Seq(Set(676, 435), Set(676, 675, 671, 664)), - 677 -> Seq(Set(677, 674, 673, 669)), - 678 -> Seq(Set(678, 675, 673, 663)), - 679 -> Seq(Set(679, 613), Set(679, 676, 667, 661)), - 680 -> Seq(Set(680, 679, 650, 645)), - 681 -> Seq(Set(681, 678, 672, 670)), - 682 -> Seq(Set(682, 681, 679, 675)), - 683 -> Seq(Set(683, 682, 677, 672)), - 684 -> Seq(Set(684, 681, 671, 666)), - 685 -> Seq(Set(685, 684, 682, 681)), - 686 -> Seq(Set(686, 489), Set(686, 684, 674, 673)), - 687 -> Seq(Set(687, 674), Set(687, 682, 675, 673)), - 688 -> Seq(Set(688, 682, 674, 669)), - 689 -> Seq(Set(689, 675), Set(689, 686, 683, 681)), - 690 -> Seq(Set(690, 687, 683, 680)), - 691 -> Seq(Set(691, 689, 685, 678)), - 692 -> Seq(Set(692, 393), Set(692, 687, 686, 678)), - 693 -> Seq(Set(693, 691, 685, 678)), - 694 -> Seq(Set(694, 691, 681, 677)), - 695 -> Seq(Set(695, 483), Set(695, 694, 691, 686)), - 696 -> Seq(Set(696, 694, 686, 673)), - 697 -> Seq(Set(697, 430), Set(697, 689, 685, 681)), - 698 -> Seq(Set(698, 483), Set(698, 690, 689, 688)), - 699 -> Seq(Set(699, 698, 689, 684)), - 700 -> Seq(Set(700, 698, 695, 694)), - 701 -> Seq(Set(701, 699, 697, 685)), - 702 -> Seq(Set(702, 665), Set(702, 701, 699, 695)), - 703 -> Seq(Set(703, 702, 696, 691)), - 704 -> Seq(Set(704, 701, 699, 692)), - 705 -> Seq(Set(705, 686), Set(705, 704, 698, 697)), - 706 -> Seq(Set(706, 697, 695, 692)), - 707 -> Seq(Set(707, 702, 699, 692)), - 708 -> Seq(Set(708, 421), Set(708, 706, 704, 703)), - 709 -> Seq(Set(709, 708, 706, 705)), - 710 -> Seq(Set(710, 709, 696, 695)), - 711 -> Seq(Set(711, 619), Set(711, 704, 703, 700)), - 712 -> Seq(Set(712, 709, 708, 707)), - 713 -> Seq(Set(713, 672), Set(713, 706, 703, 696)), - 714 -> Seq(Set(714, 691), Set(714, 709, 707, 701)), - 715 -> Seq(Set(715, 714, 711, 708)), - 716 -> Seq(Set(716, 533), Set(716, 706, 705, 704)), - 717 -> Seq(Set(717, 716, 710, 701)), - 718 -> Seq(Set(718, 717, 716, 713)), - 719 -> Seq(Set(719, 569), Set(719, 711, 710, 707)), - 720 -> Seq(Set(720, 718, 712, 709)), - 721 -> Seq(Set(721, 712), Set(721, 720, 713, 712)), - 722 -> Seq(Set(722, 491), Set(722, 721, 718, 707)), - 723 -> Seq(Set(723, 717, 710, 707)), - 724 -> Seq(Set(724, 719, 716, 711)), - 725 -> Seq(Set(725, 720, 719, 716), Set(758)), - 726 -> Seq(Set(726, 721), Set(726, 725, 722, 721)), - 727 -> Seq(Set(727, 547), Set(727, 721, 719, 716)), - 728 -> Seq(Set(728, 726, 725, 724), Set(761)), - 729 -> Seq(Set(729, 671), Set(729, 726, 724, 718)), - 730 -> Seq(Set(730, 583), Set(730, 726, 715, 711)), - 731 -> Seq(Set(731, 729, 725, 723), Set(764)), - 732 -> Seq(Set(732, 729, 728, 725), Set(765)), - 733 -> Seq(Set(733, 731, 726, 725), Set(766)), - 734 -> Seq(Set(734, 724, 721, 720), Set(767)), - 735 -> Seq(Set(735, 691), Set(735, 733, 728, 727)), - 736 -> Seq(Set(736, 730, 728, 723), Set(769)), - 737 -> Seq(Set(737, 732), Set(737, 736, 733, 732)), - 738 -> Seq(Set(738, 391), Set(738, 730, 729, 727)), - 739 -> Seq(Set(739, 731, 723, 721), Set(772)), - 740 -> Seq(Set(740, 587), Set(740, 737, 728, 716)), - 741 -> Seq(Set(741, 738, 733, 732), Set(774)), - 742 -> Seq(Set(742, 741, 738, 730), Set(775)), - 743 -> Seq(Set(743, 653), Set(743, 742, 731, 730)), - 744 -> Seq(Set(744, 743, 733, 731), Set(777)), - 745 -> Seq(Set(745, 487), Set(745, 740, 738, 737)), - 746 -> Seq(Set(746, 395), Set(746, 738, 733, 728)), - 747 -> Seq(Set(747, 743, 741, 737), Set(780)), - 748 -> Seq(Set(748, 744, 743, 733), Set(781)), - 749 -> Seq(Set(749, 748, 743, 742), Set(782)), - 750 -> Seq(Set(750, 746, 741, 734), Set(783)), - 751 -> Seq(Set(751, 733), Set(751, 750, 748, 740)), - 752 -> Seq(Set(752, 749, 732, 731), Set(785)), - 753 -> Seq(Set(753, 595), Set(753, 748, 745, 740)), - 754 -> Seq(Set(754, 735), Set(754, 742, 740, 735)), - 755 -> Seq(Set(755, 754, 745, 743), Set(2048)), - 756 -> Seq(Set(756, 407), Set(756, 755, 747, 740)), - 757 -> Seq(Set(757, 756, 751, 750)), - 758 -> Seq(Set(758, 757, 746, 741)), - 759 -> Seq(Set(759, 661), Set(759, 757, 756, 750)), - 760 -> Seq(Set(760, 757, 747, 734)), - 761 -> Seq(Set(761, 758), Set(761, 760, 759, 758)), - 762 -> Seq(Set(762, 679), Set(762, 761, 755, 745)), - 763 -> Seq(Set(763, 754, 749, 747)), - 764 -> Seq(Set(764, 761, 759, 758)), - 765 -> Seq(Set(765, 760, 755, 754)), - 766 -> Seq(Set(766, 757, 747, 744)), - 767 -> Seq(Set(767, 599), Set(767, 763, 760, 759)), - 768 -> Seq(Set(768, 764, 751, 749)), - 769 -> Seq(Set(769, 649), Set(769, 763, 762, 760)), - 770 -> Seq(Set(770, 768, 765, 756)), - 771 -> Seq(Set(771, 765, 756, 754)), - 772 -> Seq(Set(772, 765), Set(772, 767, 766, 764)), - 773 -> Seq(Set(773, 767, 765, 763)), - 774 -> Seq(Set(774, 589), Set(774, 767, 760, 758)), - 775 -> Seq(Set(775, 408), Set(775, 771, 769, 768)), - 776 -> Seq(Set(776, 773, 764, 759)), - 777 -> Seq(Set(777, 748), Set(777, 776, 767, 761)), - 778 -> Seq(Set(778, 403), Set(778, 775, 762, 759)), - 779 -> Seq(Set(779, 776, 771, 769)), - 780 -> Seq(Set(780, 775, 772, 764)), - 781 -> Seq(Set(781, 779, 765, 764)), - 782 -> Seq(Set(782, 453), Set(782, 780, 779, 773)), - 783 -> Seq(Set(783, 715), Set(783, 782, 776, 773)), - 784 -> Seq(Set(784, 778, 775, 771)), - 785 -> Seq(Set(785, 693), Set(785, 780, 776, 775)), - 786 -> Seq(Set(786, 782, 780, 771)), + 395 -> Seq(Set(395, 390, 389, 384)), + 396 -> Seq(Set(396, 371), Set(396, 392, 390, 389)), + 397 -> Seq(Set(397, 392, 387, 385)), + 398 -> Seq(Set(398, 393, 392, 384)), + 399 -> Seq(Set(399, 313), Set(399, 397, 390, 388)), + 400 -> Seq(Set(400, 398, 397, 395)), + 401 -> Seq(Set(401, 249), Set(401, 399, 392, 389)), + 402 -> Seq(Set(402, 399, 398, 393)), + 403 -> Seq(Set(403, 398, 395, 394)), + 404 -> Seq(Set(404, 215), Set(404, 400, 398, 397)), + 405 -> Seq(Set(405, 398, 397, 388)), + 406 -> Seq(Set(406, 249), Set(406, 402, 397, 393)), + 407 -> Seq(Set(407, 336), Set(407, 402, 400, 398)), + 408 -> Seq(Set(408, 407, 403, 401)), + 409 -> Seq(Set(409, 322), Set(409, 406, 404, 402)), + 410 -> Seq(Set(410, 407, 406, 400)), + 411 -> Seq(Set(411, 408, 401, 399)), + 412 -> Seq(Set(412, 265), Set(412, 409, 404, 401)), + 413 -> Seq(Set(413, 407, 406, 403)), + 414 -> Seq(Set(414, 405, 401, 398)), + 415 -> Seq(Set(415, 313), Set(415, 413, 411, 406)), + 416 -> Seq(Set(416, 414, 411, 407)), + 417 -> Seq(Set(417, 310), Set(417, 416, 414, 407)), + 418 -> Seq(Set(418, 417, 415, 403)), + 419 -> Seq(Set(419, 415, 414, 404)), + 420 -> Seq(Set(420, 412, 410, 407)), + 421 -> Seq(Set(421, 419, 417, 416)), + 422 -> Seq(Set(422, 273), Set(422, 421, 416, 412)), + 423 -> Seq(Set(423, 398), Set(423, 420, 418, 414)), + 424 -> Seq(Set(424, 422, 417, 415)), + 425 -> Seq(Set(425, 413), Set(425, 422, 421, 418)), + 426 -> Seq(Set(426, 415, 414, 412)), + 427 -> Seq(Set(427, 422, 421, 416)), + 428 -> Seq(Set(428, 323), Set(428, 426, 425, 417)), + 429 -> Seq(Set(429, 422, 421, 419)), + 430 -> Seq(Set(430, 419, 417, 415)), + 431 -> Seq(Set(431, 311), Set(431, 430, 428, 426)), + 432 -> Seq(Set(432, 429, 428, 419)), + 433 -> Seq(Set(433, 400), Set(433, 430, 428, 422)), + 434 -> Seq(Set(434, 429, 423, 422)), + 435 -> Seq(Set(435, 430, 426, 423)), + 436 -> Seq(Set(436, 271), Set(436, 432, 431, 430)), + 437 -> Seq(Set(437, 436, 435, 431)), + 438 -> Seq(Set(438, 373), Set(438, 436, 432, 421)), + 439 -> Seq(Set(439, 390), Set(439, 437, 436, 431)), + 440 -> Seq(Set(440, 439, 437, 436)), + 441 -> Seq(Set(441, 410), Set(441, 440, 433, 430)), + 442 -> Seq(Set(442, 440, 437, 435)), + 443 -> Seq(Set(443, 442, 437, 433)), + 444 -> Seq(Set(444, 435, 432, 431)), + 445 -> Seq(Set(445, 441, 439, 438)), + 446 -> Seq(Set(446, 341), Set(446, 442, 439, 431)), + 447 -> Seq(Set(447, 374), Set(447, 446, 441, 438)), + 448 -> Seq(Set(448, 444, 442, 437)), + 449 -> Seq(Set(449, 315), Set(449, 446, 440, 438)), + 450 -> Seq(Set(450, 371), Set(450, 443, 438, 434)), + 451 -> Seq(Set(451, 450, 441, 435)), + 452 -> Seq(Set(452, 448, 447, 446)), + 453 -> Seq(Set(453, 449, 447, 438)), + 454 -> Seq(Set(454, 449, 445, 444)), + 455 -> Seq(Set(455, 417), Set(455, 453, 449, 444)), + 456 -> Seq(Set(456, 454, 445, 433)), + 457 -> Seq(Set(457, 441), Set(457, 454, 449, 446)), + 458 -> Seq(Set(458, 255), Set(458, 453, 448, 445)), + 459 -> Seq(Set(459, 457, 454, 447)), + 460 -> Seq(Set(460, 399), Set(460, 459, 455, 451)), + 461 -> Seq(Set(461, 460, 455, 454)), + 462 -> Seq(Set(462, 389), Set(462, 457, 451, 450)), + 463 -> Seq(Set(463, 370), Set(463, 456, 455, 452)), + 464 -> Seq(Set(464, 460, 455, 441)), + 465 -> Seq(Set(465, 406), Set(465, 463, 462, 457)), + 466 -> Seq(Set(466, 460, 455, 452)), + 467 -> Seq(Set(467, 466, 461, 456)), + 468 -> Seq(Set(468, 464, 459, 453)), + 469 -> Seq(Set(469, 467, 464, 460)), + 470 -> Seq(Set(470, 321), Set(470, 468, 462, 461)), + 471 -> Seq(Set(471, 470), Set(471, 469, 468, 465)), + 472 -> Seq(Set(472, 470, 469, 461)), + 473 -> Seq(Set(473, 470, 467, 465)), + 474 -> Seq(Set(474, 283), Set(474, 465, 463, 456)), + 475 -> Seq(Set(475, 471, 467, 466)), + 476 -> Seq(Set(476, 461), Set(476, 475, 468, 466)), + 477 -> Seq(Set(477, 470, 462, 461)), + 478 -> Seq(Set(478, 357), Set(478, 477, 474, 472)), + 479 -> Seq(Set(479, 375), Set(479, 475, 472, 470)), + 480 -> Seq(Set(480, 473, 467, 464)), + 481 -> Seq(Set(481, 343), Set(481, 480, 472, 471)), + 482 -> Seq(Set(482, 477, 476, 473)), + 483 -> Seq(Set(483, 479, 477, 474)), + 484 -> Seq(Set(484, 379), Set(484, 483, 482, 470)), + 485 -> Seq(Set(485, 479, 469, 468)), + 486 -> Seq(Set(486, 481, 478, 472)), + 487 -> Seq(Set(487, 393), Set(487, 485, 483, 478)), + 488 -> Seq(Set(488, 487, 485, 484)), + 489 -> Seq(Set(489, 406), Set(489, 484, 483, 480)), + 490 -> Seq(Set(490, 271), Set(490, 485, 483, 481)), + 491 -> Seq(Set(491, 488, 485, 480)), + 492 -> Seq(Set(492, 491, 485, 484)), + 493 -> Seq(Set(493, 490, 488, 483)), + 494 -> Seq(Set(494, 357), Set(494, 493, 489, 481)), + 495 -> Seq(Set(495, 419), Set(495, 494, 486, 480)), + 496 -> Seq(Set(496, 494, 491, 480)), + 497 -> Seq(Set(497, 419), Set(497, 493, 488, 486)), + 498 -> Seq(Set(498, 495, 489, 487)), + 499 -> Seq(Set(499, 494, 493, 488)), + 500 -> Seq(Set(500, 499, 494, 490)), + 501 -> Seq(Set(501, 499, 497, 496)), + 502 -> Seq(Set(502, 498, 497, 494)), + 503 -> Seq(Set(503, 500), Set(503, 502, 501, 500)), + 504 -> Seq(Set(504, 502, 490, 483)), + 505 -> Seq(Set(505, 349), Set(505, 500, 497, 493)), + 506 -> Seq(Set(506, 411), Set(506, 501, 494, 491)), + 507 -> Seq(Set(507, 504, 501, 494)), + 508 -> Seq(Set(508, 399), Set(508, 505, 500, 495)), + 509 -> Seq(Set(509, 506, 502, 501)), + 510 -> Seq(Set(510, 501, 500, 498)), + 511 -> Seq(Set(511, 501), Set(511, 509, 503, 501)), + 512 -> Seq(Set(512, 510, 507, 504)), + 513 -> Seq(Set(513, 428), Set(513, 505, 503, 500)), + 514 -> Seq(Set(514, 511, 509, 507)), + 515 -> Seq(Set(515, 511, 508, 501)), + 516 -> Seq(Set(516, 514, 511, 509)), + 517 -> Seq(Set(517, 515, 507, 505)), + 518 -> Seq(Set(518, 485), Set(518, 516, 515, 507)), + 519 -> Seq(Set(519, 440), Set(519, 517, 511, 507)), + 520 -> Seq(Set(520, 509, 507, 503)), + 521 -> Seq(Set(521, 489), Set(521, 519, 514, 512)), + 522 -> Seq(Set(522, 518, 509, 507)), + 523 -> Seq(Set(523, 521, 517, 510)), + 524 -> Seq(Set(524, 357), Set(524, 523, 519, 515)), + 525 -> Seq(Set(525, 524, 521, 519)), + 526 -> Seq(Set(526, 525, 521, 517)), + 527 -> Seq(Set(527, 480), Set(527, 526, 520, 518)), + 528 -> Seq(Set(528, 526, 522, 517)), + 529 -> Seq(Set(529, 487), Set(529, 528, 525, 522)), + 530 -> Seq(Set(530, 527, 523, 520)), + 531 -> Seq(Set(531, 529, 525, 519)), + 532 -> Seq(Set(532, 531), Set(532, 529, 528, 522)), + 533 -> Seq(Set(533, 531, 530, 529)), + 534 -> Seq(Set(534, 533, 529, 527)), + 535 -> Seq(Set(535, 533, 529, 527)), + 536 -> Seq(Set(536, 533, 531, 529)), + 537 -> Seq(Set(537, 443), Set(537, 536, 535, 527)), + 538 -> Seq(Set(538, 537, 536, 533)), + 539 -> Seq(Set(539, 535, 534, 529)), + 540 -> Seq(Set(540, 361), Set(540, 537, 534, 529)), + 541 -> Seq(Set(541, 537, 531, 528)), + 542 -> Seq(Set(542, 540, 539, 533)), + 543 -> Seq(Set(543, 527), Set(543, 538, 536, 532)), + 544 -> Seq(Set(544, 538, 535, 531)), + 545 -> Seq(Set(545, 423), Set(545, 539, 537, 532)), + 546 -> Seq(Set(546, 545, 544, 538)), + 547 -> Seq(Set(547, 543, 540, 534)), + 548 -> Seq(Set(548, 545, 543, 538)), + 549 -> Seq(Set(549, 546, 545, 533)), + 550 -> Seq(Set(550, 357), Set(550, 546, 533, 529)), + 551 -> Seq(Set(551, 416), Set(551, 550, 547, 542)), + 552 -> Seq(Set(552, 550, 547, 532)), + 553 -> Seq(Set(553, 514), Set(553, 550, 549, 542)), + 554 -> Seq(Set(554, 551, 546, 543)), + 555 -> Seq(Set(555, 551, 546, 545)), + 556 -> Seq(Set(556, 403), Set(556, 549, 546, 540)), + 557 -> Seq(Set(557, 552, 551, 550)), + 558 -> Seq(Set(558, 553, 549, 544)), + 559 -> Seq(Set(559, 525), Set(559, 557, 552, 550)), + 560 -> Seq(Set(560, 554, 551, 549)), + 561 -> Seq(Set(561, 490), Set(561, 558, 552, 550)), + 562 -> Seq(Set(562, 560, 558, 551)), + 563 -> Seq(Set(563, 561, 554, 549)), + 564 -> Seq(Set(564, 401), Set(564, 563, 561, 558)), + 565 -> Seq(Set(565, 564, 559, 554)), + 566 -> Seq(Set(566, 413), Set(566, 564, 561, 560)), + 567 -> Seq(Set(567, 424), Set(567, 563, 557, 556)), + 568 -> Seq(Set(568, 558, 557, 551)), + 569 -> Seq(Set(569, 492), Set(569, 568, 559, 557)), + 570 -> Seq(Set(570, 503), Set(570, 563, 558, 552)), + 571 -> Seq(Set(571, 569, 566, 561)), + 572 -> Seq(Set(572, 571, 564, 560)), + 573 -> Seq(Set(573, 569, 567, 563)), + 574 -> Seq(Set(574, 561), Set(574, 569, 565, 560)), + 575 -> Seq(Set(575, 429), Set(575, 572, 570, 569)), + 576 -> Seq(Set(576, 573, 572, 563)), + 577 -> Seq(Set(577, 552), Set(577, 575, 574, 569)), + 578 -> Seq(Set(578, 562, 556, 555)), + 579 -> Seq(Set(579, 572, 570, 567)), + 580 -> Seq(Set(580, 579, 576, 574)), + 581 -> Seq(Set(581, 575, 574, 568)), + 582 -> Seq(Set(582, 497), Set(582, 579, 576, 571)), + 583 -> Seq(Set(583, 453), Set(583, 581, 577, 575)), + 584 -> Seq(Set(584, 581, 571, 570)), + 585 -> Seq(Set(585, 464), Set(585, 583, 582, 577)), + 586 -> Seq(Set(586, 584, 581, 579)), + 587 -> Seq(Set(587, 586, 581, 576)), + 588 -> Seq(Set(588, 437), Set(588, 577, 572, 571)), + 589 -> Seq(Set(589, 586, 585, 579)), + 590 -> Seq(Set(590, 497), Set(590, 588, 587, 578)), + 591 -> Seq(Set(591, 587, 585, 582)), + 592 -> Seq(Set(592, 591, 573, 568)), + 593 -> Seq(Set(593, 507), Set(593, 588, 585, 584)), + 594 -> Seq(Set(594, 575), Set(594, 586, 584, 583)), + 595 -> Seq(Set(595, 594, 593, 586)), + 596 -> Seq(Set(596, 592, 591, 590)), + 597 -> Seq(Set(597, 588, 585, 583)), + 598 -> Seq(Set(598, 597, 592, 591)), + 599 -> Seq(Set(599, 569), Set(599, 593, 591, 590)), + 600 -> Seq(Set(600, 599, 590, 589)), + 601 -> Seq(Set(601, 400), Set(601, 600, 597, 589)), + 602 -> Seq(Set(602, 596, 594, 591)), + 603 -> Seq(Set(603, 600, 599, 597)), + 604 -> Seq(Set(604, 600, 598, 589)), + 605 -> Seq(Set(605, 600, 598, 595)), + 606 -> Seq(Set(606, 602, 599, 591)), + 607 -> Seq(Set(607, 502), Set(607, 600, 598, 595)), + 608 -> Seq(Set(608, 606, 602, 585)), + 609 -> Seq(Set(609, 578), Set(609, 601, 600, 597)), + 610 -> Seq(Set(610, 483), Set(610, 602, 600, 599)), + 611 -> Seq(Set(611, 609, 607, 601)), + 612 -> Seq(Set(612, 607, 602, 598)), + 613 -> Seq(Set(613, 609, 603, 594)), + 614 -> Seq(Set(614, 613, 612, 607)), + 615 -> Seq(Set(615, 404), Set(615, 614, 609, 608)), + 616 -> Seq(Set(616, 614, 602, 597)), + 617 -> Seq(Set(617, 417), Set(617, 612, 608, 607)), + 618 -> Seq(Set(618, 615, 604, 598)), + 619 -> Seq(Set(619, 614, 611, 610)), + 620 -> Seq(Set(620, 619, 618, 611)), + 621 -> Seq(Set(621, 616, 615, 609)), + 622 -> Seq(Set(622, 325), Set(622, 612, 610, 605)), + 623 -> Seq(Set(623, 555), Set(623, 614, 613, 612)), + 624 -> Seq(Set(624, 617, 615, 612)), + 625 -> Seq(Set(625, 492), Set(625, 620, 617, 613)), + 626 -> Seq(Set(626, 623, 621, 613)), + 627 -> Seq(Set(627, 622, 617, 613)), + 628 -> Seq(Set(628, 405), Set(628, 626, 617, 616)), + 629 -> Seq(Set(629, 627, 624, 623)), + 630 -> Seq(Set(630, 628, 626, 623)), + 631 -> Seq(Set(631, 324), Set(631, 625, 623, 617)), + 632 -> Seq(Set(632, 629, 619, 613)), + 633 -> Seq(Set(633, 532), Set(633, 632, 631, 626)), + 634 -> Seq(Set(634, 319), Set(634, 631, 629, 627)), + 635 -> Seq(Set(635, 631, 625, 621)), + 636 -> Seq(Set(636, 632, 628, 623)), + 637 -> Seq(Set(637, 636, 628, 623)), + 638 -> Seq(Set(638, 637, 633, 632)), + 639 -> Seq(Set(639, 623), Set(639, 636, 635, 629)), + 640 -> Seq(Set(640, 638, 637, 626)), + 641 -> Seq(Set(641, 630), Set(641, 640, 636, 622)), + 642 -> Seq(Set(642, 523), Set(642, 636, 633, 632)), + 643 -> Seq(Set(643, 641, 640, 632)), + 644 -> Seq(Set(644, 634, 633, 632)), + 645 -> Seq(Set(645, 641, 637, 634)), + 646 -> Seq(Set(646, 397), Set(646, 635, 634, 633)), + 647 -> Seq(Set(647, 642), Set(647, 646, 643, 642)), + 648 -> Seq(Set(648, 647, 626, 625)), + 649 -> Seq(Set(649, 612), Set(649, 648, 644, 638)), + 650 -> Seq(Set(650, 647), Set(650, 644, 635, 632)), + 651 -> Seq(Set(651, 646, 638, 637)), + 652 -> Seq(Set(652, 559), Set(652, 647, 643, 641)), + 653 -> Seq(Set(653, 646, 645, 643)), + 654 -> Seq(Set(654, 649, 643, 640)), + 655 -> Seq(Set(655, 567), Set(655, 653, 639, 638)), + 656 -> Seq(Set(656, 646, 638, 637)), + 657 -> Seq(Set(657, 619), Set(657, 656, 650, 649)), + 658 -> Seq(Set(658, 603), Set(658, 651, 648, 646)), + 659 -> Seq(Set(659, 657, 655, 644)), + 660 -> Seq(Set(660, 657, 656, 648)), + 661 -> Seq(Set(661, 657, 650, 649)), + 662 -> Seq(Set(662, 365), Set(662, 659, 656, 650)), + 663 -> Seq(Set(663, 406), Set(663, 655, 652, 649)), + 664 -> Seq(Set(664, 662, 660, 649)), + 665 -> Seq(Set(665, 632), Set(665, 661, 659, 654)), + 666 -> Seq(Set(666, 664, 659, 656)), + 667 -> Seq(Set(667, 664, 660, 649)), + 668 -> Seq(Set(668, 658, 656, 651)), + 669 -> Seq(Set(669, 667, 665, 664)), + 670 -> Seq(Set(670, 517), Set(670, 669, 665, 664)), + 671 -> Seq(Set(671, 656), Set(671, 669, 665, 662)), + 672 -> Seq(Set(672, 667, 666, 661)), + 673 -> Seq(Set(673, 645), Set(673, 666, 664, 663)), + 674 -> Seq(Set(674, 671, 665, 660)), + 675 -> Seq(Set(675, 674, 672, 669)), + 676 -> Seq(Set(676, 435), Set(676, 675, 671, 664)), + 677 -> Seq(Set(677, 674, 673, 669)), + 678 -> Seq(Set(678, 675, 673, 663)), + 679 -> Seq(Set(679, 613), Set(679, 676, 667, 661)), + 680 -> Seq(Set(680, 679, 650, 645)), + 681 -> Seq(Set(681, 678, 672, 670)), + 682 -> Seq(Set(682, 681, 679, 675)), + 683 -> Seq(Set(683, 682, 677, 672)), + 684 -> Seq(Set(684, 681, 671, 666)), + 685 -> Seq(Set(685, 684, 682, 681)), + 686 -> Seq(Set(686, 489), Set(686, 684, 674, 673)), + 687 -> Seq(Set(687, 674), Set(687, 682, 675, 673)), + 688 -> Seq(Set(688, 682, 674, 669)), + 689 -> Seq(Set(689, 675), Set(689, 686, 683, 681)), + 690 -> Seq(Set(690, 687, 683, 680)), + 691 -> Seq(Set(691, 689, 685, 678)), + 692 -> Seq(Set(692, 393), Set(692, 687, 686, 678)), + 693 -> Seq(Set(693, 691, 685, 678)), + 694 -> Seq(Set(694, 691, 681, 677)), + 695 -> Seq(Set(695, 483), Set(695, 694, 691, 686)), + 696 -> Seq(Set(696, 694, 686, 673)), + 697 -> Seq(Set(697, 430), Set(697, 689, 685, 681)), + 698 -> Seq(Set(698, 483), Set(698, 690, 689, 688)), + 699 -> Seq(Set(699, 698, 689, 684)), + 700 -> Seq(Set(700, 698, 695, 694)), + 701 -> Seq(Set(701, 699, 697, 685)), + 702 -> Seq(Set(702, 665), Set(702, 701, 699, 695)), + 703 -> Seq(Set(703, 702, 696, 691)), + 704 -> Seq(Set(704, 701, 699, 692)), + 705 -> Seq(Set(705, 686), Set(705, 704, 698, 697)), + 706 -> Seq(Set(706, 697, 695, 692)), + 707 -> Seq(Set(707, 702, 699, 692)), + 708 -> Seq(Set(708, 421), Set(708, 706, 704, 703)), + 709 -> Seq(Set(709, 708, 706, 705)), + 710 -> Seq(Set(710, 709, 696, 695)), + 711 -> Seq(Set(711, 619), Set(711, 704, 703, 700)), + 712 -> Seq(Set(712, 709, 708, 707)), + 713 -> Seq(Set(713, 672), Set(713, 706, 703, 696)), + 714 -> Seq(Set(714, 691), Set(714, 709, 707, 701)), + 715 -> Seq(Set(715, 714, 711, 708)), + 716 -> Seq(Set(716, 533), Set(716, 706, 705, 704)), + 717 -> Seq(Set(717, 716, 710, 701)), + 718 -> Seq(Set(718, 717, 716, 713)), + 719 -> Seq(Set(719, 569), Set(719, 711, 710, 707)), + 720 -> Seq(Set(720, 718, 712, 709)), + 721 -> Seq(Set(721, 712), Set(721, 720, 713, 712)), + 722 -> Seq(Set(722, 491), Set(722, 721, 718, 707)), + 723 -> Seq(Set(723, 717, 710, 707)), + 724 -> Seq(Set(724, 719, 716, 711)), + 725 -> Seq(Set(725, 720, 719, 716), Set(758)), + 726 -> Seq(Set(726, 721), Set(726, 725, 722, 721)), + 727 -> Seq(Set(727, 547), Set(727, 721, 719, 716)), + 728 -> Seq(Set(728, 726, 725, 724), Set(761)), + 729 -> Seq(Set(729, 671), Set(729, 726, 724, 718)), + 730 -> Seq(Set(730, 583), Set(730, 726, 715, 711)), + 731 -> Seq(Set(731, 729, 725, 723), Set(764)), + 732 -> Seq(Set(732, 729, 728, 725), Set(765)), + 733 -> Seq(Set(733, 731, 726, 725), Set(766)), + 734 -> Seq(Set(734, 724, 721, 720), Set(767)), + 735 -> Seq(Set(735, 691), Set(735, 733, 728, 727)), + 736 -> Seq(Set(736, 730, 728, 723), Set(769)), + 737 -> Seq(Set(737, 732), Set(737, 736, 733, 732)), + 738 -> Seq(Set(738, 391), Set(738, 730, 729, 727)), + 739 -> Seq(Set(739, 731, 723, 721), Set(772)), + 740 -> Seq(Set(740, 587), Set(740, 737, 728, 716)), + 741 -> Seq(Set(741, 738, 733, 732), Set(774)), + 742 -> Seq(Set(742, 741, 738, 730), Set(775)), + 743 -> Seq(Set(743, 653), Set(743, 742, 731, 730)), + 744 -> Seq(Set(744, 743, 733, 731), Set(777)), + 745 -> Seq(Set(745, 487), Set(745, 740, 738, 737)), + 746 -> Seq(Set(746, 395), Set(746, 738, 733, 728)), + 747 -> Seq(Set(747, 743, 741, 737), Set(780)), + 748 -> Seq(Set(748, 744, 743, 733), Set(781)), + 749 -> Seq(Set(749, 748, 743, 742), Set(782)), + 750 -> Seq(Set(750, 746, 741, 734), Set(783)), + 751 -> Seq(Set(751, 733), Set(751, 750, 748, 740)), + 752 -> Seq(Set(752, 749, 732, 731), Set(785)), + 753 -> Seq(Set(753, 595), Set(753, 748, 745, 740)), + 754 -> Seq(Set(754, 735), Set(754, 742, 740, 735)), + 755 -> Seq(Set(755, 754, 745, 743), Set(2048)), + 756 -> Seq(Set(756, 407), Set(756, 755, 747, 740)), + 757 -> Seq(Set(757, 756, 751, 750)), + 758 -> Seq(Set(758, 757, 746, 741)), + 759 -> Seq(Set(759, 661), Set(759, 757, 756, 750)), + 760 -> Seq(Set(760, 757, 747, 734)), + 761 -> Seq(Set(761, 758), Set(761, 760, 759, 758)), + 762 -> Seq(Set(762, 679), Set(762, 761, 755, 745)), + 763 -> Seq(Set(763, 754, 749, 747)), + 764 -> Seq(Set(764, 761, 759, 758)), + 765 -> Seq(Set(765, 760, 755, 754)), + 766 -> Seq(Set(766, 757, 747, 744)), + 767 -> Seq(Set(767, 599), Set(767, 763, 760, 759)), + 768 -> Seq(Set(768, 764, 751, 749)), + 769 -> Seq(Set(769, 649), Set(769, 763, 762, 760)), + 770 -> Seq(Set(770, 768, 765, 756)), + 771 -> Seq(Set(771, 765, 756, 754)), + 772 -> Seq(Set(772, 765), Set(772, 767, 766, 764)), + 773 -> Seq(Set(773, 767, 765, 763)), + 774 -> Seq(Set(774, 589), Set(774, 767, 760, 758)), + 775 -> Seq(Set(775, 408), Set(775, 771, 769, 768)), + 776 -> Seq(Set(776, 773, 764, 759)), + 777 -> Seq(Set(777, 748), Set(777, 776, 767, 761)), + 778 -> Seq(Set(778, 403), Set(778, 775, 762, 759)), + 779 -> Seq(Set(779, 776, 771, 769)), + 780 -> Seq(Set(780, 775, 772, 764)), + 781 -> Seq(Set(781, 779, 765, 764)), + 782 -> Seq(Set(782, 453), Set(782, 780, 779, 773)), + 783 -> Seq(Set(783, 715), Set(783, 782, 776, 773)), + 784 -> Seq(Set(784, 778, 775, 771)), + 785 -> Seq(Set(785, 693), Set(785, 780, 776, 775)), + 786 -> Seq(Set(786, 782, 780, 771)), 1024 -> Seq(Set(1024, 1015, 1002, 1001)), 2048 -> Seq(Set(2048, 2035, 2034, 2029)), - 4096 -> Seq(Set(4096, 4095, 4081, 4069)) ) + 4096 -> Seq(Set(4096, 4095, 4081, 4069)) + ) } diff --git a/src/main/scala/chisel3/util/random/PRNG.scala b/src/main/scala/chisel3/util/random/PRNG.scala index 3a44385a..2566c8d6 100644 --- a/src/main/scala/chisel3/util/random/PRNG.scala +++ b/src/main/scala/chisel3/util/random/PRNG.scala @@ -11,17 +11,17 @@ import chisel3.util.Valid */ class PRNGIO(val n: Int) extends Bundle { - /** A [[chisel3.util.Valid Valid]] interface that can be used to set the seed (internal PRNG state) + /** A [[chisel3.util.Valid Valid]] interface that can be used to set the seed (internal PRNG state) * @group Signals */ val seed: Valid[Vec[Bool]] = Input(Valid(Vec(n, Bool()))) - /** When asserted, the PRNG will increment by one + /** When asserted, the PRNG will increment by one * @group Signals */ val increment: Bool = Input(Bool()) - /** The current state of the PRNG + /** The current state of the PRNG * @group Signals */ val out: Vec[Bool] = Output(Vec(n, Bool())) @@ -34,7 +34,8 @@ class PRNGIO(val n: Int) extends Bundle { * @param updateSeed if true, when loading the seed the state will be updated as if the seed were the current state, if * false, the state will be set to the seed */ -abstract class PRNG(val width: Int, val seed: Option[BigInt], step: Int = 1, updateSeed: Boolean = false) extends Module { +abstract class PRNG(val width: Int, val seed: Option[BigInt], step: Int = 1, updateSeed: Boolean = false) + extends Module { require(width > 0, s"Width must be greater than zero! (Found '$width')") require(step > 0, s"Step size must be greater than one! (Found '$step')") @@ -51,7 +52,7 @@ abstract class PRNG(val width: Int, val seed: Option[BigInt], step: Int = 1, upd * the PRNG state should be manually reset to a safe value. [[LFSR]] handles this by, based on the chosen reduction * operator, either sets or resets the least significant bit of the state. */ - private [random] val state: Vec[Bool] = RegInit(resetValue) + private[random] val state: Vec[Bool] = RegInit(resetValue) /** State update function * @param s input state @@ -63,14 +64,15 @@ abstract class PRNG(val width: Int, val seed: Option[BigInt], step: Int = 1, upd * @param s input state * @return the next state after `step` applications of [[PRNG.delta]] */ - final def nextState(s: Seq[Bool]): Seq[Bool] = (0 until step).foldLeft(s){ case (s, _) => delta(s) } + final def nextState(s: Seq[Bool]): Seq[Bool] = (0 until step).foldLeft(s) { case (s, _) => delta(s) } - when (io.increment) { + when(io.increment) { state := nextState(state) } - when (io.seed.fire) { - state := (if (updateSeed) { nextState(io.seed.bits) } else { io.seed.bits }) + when(io.seed.fire) { + state := (if (updateSeed) { nextState(io.seed.bits) } + else { io.seed.bits }) } io.out := state diff --git a/src/main/scala/chisel3/verilog.scala b/src/main/scala/chisel3/verilog.scala index a91444de..b926a15c 100644 --- a/src/main/scala/chisel3/verilog.scala +++ b/src/main/scala/chisel3/verilog.scala @@ -8,8 +8,7 @@ object getVerilogString { } object emitVerilog { - def apply(gen: => RawModule, args: Array[String] = Array.empty, - annotations: AnnotationSeq = Seq.empty): Unit = { + def apply(gen: => RawModule, args: Array[String] = Array.empty, annotations: AnnotationSeq = Seq.empty): Unit = { (new ChiselStage).emitVerilog(gen, args, annotations) } } diff --git a/src/test/scala/chisel3/testers/TreadleBackend.scala b/src/test/scala/chisel3/testers/TreadleBackend.scala index 19b94e91..9375b10a 100644 --- a/src/test/scala/chisel3/testers/TreadleBackend.scala +++ b/src/test/scala/chisel3/testers/TreadleBackend.scala @@ -17,10 +17,12 @@ import java.io.File case object TreadleBackend extends TesterDriver.Backend { val MaxTreadleCycles = 10000L - def execute(t: () => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq(), - nameHint: Option[String] = None): Boolean = { + def execute( + t: () => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq(), + nameHint: Option[String] = None + ): Boolean = { val generatorAnnotation = chisel3.stage.ChiselGeneratorAnnotation(t) // This provides an opportunity to translate from top level generic flags to backend specific annos @@ -37,7 +39,7 @@ case object TreadleBackend extends TesterDriver.Backend { if (!annotationSeq.exists(_.isInstanceOf[NoTargetAnnotation])) { annotationSeq = annotationSeq :+ TargetDirAnnotation(targetName.getPath) } - if (!annotationSeq.exists { case CallResetAtStartupAnnotation => true ; case _ => false }) { + if (!annotationSeq.exists { case CallResetAtStartupAnnotation => true; case _ => false }) { annotationSeq = annotationSeq :+ CallResetAtStartupAnnotation } diff --git a/src/test/scala/chiselTests/AdderTree.scala b/src/test/scala/chiselTests/AdderTree.scala index 171fa616..29ef97a4 100644 --- a/src/test/scala/chiselTests/AdderTree.scala +++ b/src/test/scala/chiselTests/AdderTree.scala @@ -10,14 +10,14 @@ class AdderTree[T <: Bits with Num[T]](genType: T, vecSize: Int) extends Module val numIn = Input(Vec(vecSize, genType)) val numOut = Output(genType) }) - io.numOut := io.numIn.reduceTree((a : T, b : T) => (a + b)) + io.numOut := io.numIn.reduceTree((a: T, b: T) => (a + b)) } class AdderTreeTester(bitWidth: Int, numsToAdd: List[Int]) extends BasicTester { val genType = UInt(bitWidth.W) val dut = Module(new AdderTree(genType, numsToAdd.size)) dut.io.numIn := VecInit(numsToAdd.map(x => x.asUInt(bitWidth.W))) - val sumCorrect = dut.io.numOut === (numsToAdd.reduce(_+_) % (1 << bitWidth)).asUInt(bitWidth.W) + val sumCorrect = dut.io.numOut === (numsToAdd.reduce(_ + _) % (1 << bitWidth)).asUInt(bitWidth.W) assert(sumCorrect) stop() } @@ -27,7 +27,7 @@ class AdderTreeSpec extends ChiselPropSpec { forAll(safeUIntN(20)) { case (w: Int, v: List[Int]) => { whenever(v.size > 0 && w > 0) { - assertTesterPasses { new AdderTreeTester(w, v.map(x => math.abs(x) % ( 1 << w )).toList) } + assertTesterPasses { new AdderTreeTester(w, v.map(x => math.abs(x) % (1 << w)).toList) } } } } diff --git a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala index 7478f2eb..035a9d91 100644 --- a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala +++ b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala @@ -53,7 +53,7 @@ class AnalogBlackBoxWrapper(n: Int, idxs: Seq[Int]) extends AnalogBlackBoxModule val bbs = idxs.map(i => Module(new AnalogBlackBoxModule(i))) io.bus <> bbs.head.io.bus // Always bulk connect io.bus to first bus io.port <> bbs.flatMap(_.io.port) // Connect ports - attach(bbs.map(_.io.bus):_*) // Attach all the buses + attach(bbs.map(_.io.bus): _*) // Attach all the buses } // Common superclass for AnalogDUT and AnalogSmallDUT @@ -80,7 +80,7 @@ class AnalogDUT extends AnalogDUTModule(5) { // 5 BlackBoxes // Connect all ports to top io.ports <> mods.flatMap(_.io.port) // Attach first 3 Modules - attach(mods.take(3).map(_.io.bus):_*) + attach(mods.take(3).map(_.io.bus): _*) // Attach last module to 1st through AnalogConnector val con = Module(new AnalogConnector) attach(con.io.bus1, mods.head.io.bus) @@ -100,10 +100,9 @@ class AnalogSmallDUT extends AnalogDUTModule(4) { // 4 BlackBoxes // Connect all ports to top io.ports <> mods.flatMap(_.io.port) // Attach first 3 Modules - attach(mods.take(3).map(_.io.bus):_*) + attach(mods.take(3).map(_.io.bus): _*) } - // This tester is primarily intended to be able to pass the dut to synthesis class AnalogIntegrationTester(mod: => AnalogDUTModule) extends BasicTester { val BusValue = 2.U(32.W) // arbitrary @@ -122,17 +121,17 @@ class AnalogIntegrationTester(mod: => AnalogDUTModule) extends BasicTester { // Error checking assert(dut.out === expectedValue) - when (cycle === idx.U) { + when(cycle === idx.U) { expectedValue := BusValue + idx.U dut.in.valid := true.B } } - when (done) { stop() } + when(done) { stop() } } class AnalogIntegrationSpec extends ChiselFlatSpec { - behavior of "Verilator" + behavior.of("Verilator") it should "support simple bidirectional wires" in { assertTesterPasses( new AnalogIntegrationTester(new AnalogSmallDUT), diff --git a/src/test/scala/chiselTests/AnalogSpec.scala b/src/test/scala/chiselTests/AnalogSpec.scala index 42dafb6e..3d03af78 100644 --- a/src/test/scala/chiselTests/AnalogSpec.scala +++ b/src/test/scala/chiselTests/AnalogSpec.scala @@ -6,7 +6,7 @@ import chisel3._ import chisel3.stage.ChiselStage import chisel3.util._ import chisel3.testers.{BasicTester, TesterDriver} -import chisel3.experimental.{Analog, BaseModule, attach} +import chisel3.experimental.{attach, Analog, BaseModule} // IO for Modules that just connect bus to out class AnalogReaderIO extends Bundle { @@ -59,9 +59,14 @@ class VecAnalogReaderWrapper extends RawModule with AnalogReader { } class VecBundleAnalogReaderWrapper extends RawModule with AnalogReader { - val vecBunBus = IO(Vec(1, new Bundle { - val analog = Analog(32.W) - })) + val vecBunBus = IO( + Vec( + 1, + new Bundle { + val analog = Analog(32.W) + } + ) + ) def bus = vecBunBus(0).analog val out = IO(Output(UInt(32.W))) val mod = Module(new AnalogReaderBlackBox) @@ -74,7 +79,7 @@ abstract class AnalogTester extends BasicTester { final val BusValue = "hdeadbeef".U final val (cycle, done) = Counter(true.B, 2) - when (done) { stop() } + when(done) { stop() } final val writer = Module(new AnalogWriterBlackBox) writer.io.in := BusValue @@ -84,85 +89,103 @@ abstract class AnalogTester extends BasicTester { } class AnalogSpec extends ChiselFlatSpec with Utils { - behavior of "Analog" + behavior.of("Analog") it should "NOT be bindable to registers" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle {}) - val reg = Reg(Analog(32.W)) - }} + a[ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle {}) + val reg = Reg(Analog(32.W)) + } + } } } it should "NOT be bindable to a direction" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle { - val a = Input(Analog(32.W)) - }) - }} + a[ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle { + val a = Input(Analog(32.W)) + }) + } + } } - a [ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle { - val a = Output(Analog(32.W)) - }) - }} + a[ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle { + val a = Output(Analog(32.W)) + }) + } + } } } it should "be flippable" in { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle { - val a = Flipped(Analog(32.W)) - }) - }} + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle { + val a = Flipped(Analog(32.W)) + }) + } + } } // There is no binding on the type of a memory // Should this be an error? ignore should "NOT be a legal type for Mem" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle {}) - val mem = Mem(16, Analog(32.W)) - }} + a[ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle {}) + val mem = Mem(16, Analog(32.W)) + } + } } } it should "NOT be bindable to Mem ports" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle {}) - val mem = Mem(16, Analog(32.W)) - val port = mem(5.U) - }} + a[ChiselException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle {}) + val mem = Mem(16, Analog(32.W)) + val port = mem(5.U) + } + } } } // TODO This should probably be caught in Chisel // Also note this relies on executing Firrtl from Chisel directly it should "NOT be connectable to UInts" in { - a [Exception] should be thrownBy { - runTester { new BasicTester { - val uint = WireDefault(0.U(32.W)) - val sint = Wire(Analog(32.W)) - sint := uint - }} + a[Exception] should be thrownBy { + runTester { + new BasicTester { + val uint = WireDefault(0.U(32.W)) + val sint = Wire(Analog(32.W)) + sint := uint + } + } } } it should "work with 2 blackboxes bulk connected" in { - assertTesterPasses(new AnalogTester { - val mod = Module(new AnalogReaderBlackBox) - mod.io.bus <> writer.io.bus - check(mod) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mod = Module(new AnalogReaderBlackBox) + mod.io.bus <> writer.io.bus + check(mod) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } it should "error if any bulk connected more than once" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val wires = List.fill(3)(Wire(Analog(32.W))) @@ -170,7 +193,7 @@ class AnalogSpec extends ChiselFlatSpec with Utils { wires(0) <> wires(2) }) } - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val wires = List.fill(2)(Wire(Analog(32.W))) @@ -217,82 +240,113 @@ class AnalogSpec extends ChiselFlatSpec with Utils { } it should "work with 3 blackboxes attached" in { - assertTesterPasses(new AnalogTester { - val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox)) - attach(writer.io.bus, mods(0).io.bus, mods(1).io.bus) - mods.foreach(check(_)) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox)) + attach(writer.io.bus, mods(0).io.bus, mods(1).io.bus) + mods.foreach(check(_)) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } it should "work with 3 blackboxes separately attached via a wire" in { - assertTesterPasses(new AnalogTester { - val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox)) - val busWire = Wire(Analog(32.W)) - attach(busWire, writer.io.bus) - attach(busWire, mods(0).io.bus) - attach(mods(1).io.bus, busWire) - mods.foreach(check(_)) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mods = Seq.fill(2)(Module(new AnalogReaderBlackBox)) + val busWire = Wire(Analog(32.W)) + attach(busWire, writer.io.bus) + attach(busWire, mods(0).io.bus) + attach(mods(1).io.bus, busWire) + mods.foreach(check(_)) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } // This does not currently work in Verilator unless Firrtl does constant prop and dead code // elimination on these wires ignore should "work with intermediate wires attached to each other" in { - assertTesterPasses(new AnalogTester { - val mod = Module(new AnalogReaderBlackBox) - val busWire = Seq.fill(2)(Wire(Analog(32.W))) - attach(busWire(0), writer.io.bus) - attach(busWire(1), mod.io.bus) - attach(busWire(0), busWire(1)) - check(mod) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mod = Module(new AnalogReaderBlackBox) + val busWire = Seq.fill(2)(Wire(Analog(32.W))) + attach(busWire(0), writer.io.bus) + attach(busWire(1), mod.io.bus) + attach(busWire(0), busWire(1)) + check(mod) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } it should "work with blackboxes at different levels of the module hierarchy" in { - assertTesterPasses(new AnalogTester { - val mods = Seq(Module(new AnalogReaderBlackBox), Module(new AnalogReaderWrapper)) - val busWire = Wire(writer.io.bus.cloneType) - attach(writer.io.bus, mods(0).bus, mods(1).bus) - mods.foreach(check(_)) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mods = Seq(Module(new AnalogReaderBlackBox), Module(new AnalogReaderWrapper)) + val busWire = Wire(writer.io.bus.cloneType) + attach(writer.io.bus, mods(0).bus, mods(1).bus) + mods.foreach(check(_)) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } // This does not currently work in Verilator, but does work in VCS ignore should "support two analog ports in the same module" in { - assertTesterPasses(new AnalogTester { - val reader = Module(new AnalogReaderBlackBox) - val connector = Module(new AnalogConnector) - connector.io.bus1 <> writer.io.bus - reader.io.bus <> connector.io.bus2 - check(reader) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val reader = Module(new AnalogReaderBlackBox) + val connector = Module(new AnalogConnector) + connector.io.bus1 <> writer.io.bus + reader.io.bus <> connector.io.bus2 + check(reader) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } it should "NOT support conditional connection of analog types" in { - a [ChiselException] should be thrownBy { - assertTesterPasses(new AnalogTester { - val mod = Module(new AnalogReaderBlackBox) - when (cycle > 3.U) { - mod.io.bus <> writer.io.bus - } - check(mod) - }, Seq("/chisel3/AnalogBlackBox.v")) + a[ChiselException] should be thrownBy { + assertTesterPasses( + new AnalogTester { + val mod = Module(new AnalogReaderBlackBox) + when(cycle > 3.U) { + mod.io.bus <> writer.io.bus + } + check(mod) + }, + Seq("/chisel3/AnalogBlackBox.v") + ) } } it should "work with Vecs of Analog" in { - assertTesterPasses(new AnalogTester { - val mod = Module(new VecAnalogReaderWrapper) - mod.bus <> writer.io.bus - check(mod) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mod = Module(new VecAnalogReaderWrapper) + mod.bus <> writer.io.bus + check(mod) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } it should "work with Vecs of Bundles of Analog" in { - assertTesterPasses(new AnalogTester { - val mod = Module(new VecBundleAnalogReaderWrapper) - mod.bus <> writer.io.bus - check(mod) - }, Seq("/chisel3/AnalogBlackBox.v"), TesterDriver.verilatorOnly) + assertTesterPasses( + new AnalogTester { + val mod = Module(new VecBundleAnalogReaderWrapper) + mod.bus <> writer.io.bus + check(mod) + }, + Seq("/chisel3/AnalogBlackBox.v"), + TesterDriver.verilatorOnly + ) } } diff --git a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala index cfa07e26..af73d5d4 100644 --- a/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala +++ b/src/test/scala/chiselTests/AnnotatingDiamondSpec.scala @@ -3,17 +3,12 @@ package chiselTests import chisel3._ -import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation, RunFirrtlTransform} import chisel3.internal.InstanceId import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.testers.BasicTester import firrtl.{CircuitForm, CircuitState, DependencyAPIMigration, LowForm, Transform} -import firrtl.annotations.{ - CircuitName, - CircuitTarget, - SingleTargetAnnotation, - Target -} +import firrtl.annotations.{CircuitName, CircuitTarget, SingleTargetAnnotation, Target} import firrtl.stage.Forms import org.scalatest._ import org.scalatest.freespec.AnyFreeSpec @@ -25,10 +20,12 @@ import org.scalatest.matchers.should.Matchers case class IdentityAnnotation(target: Target, value: String) extends SingleTargetAnnotation[Target] { def duplicate(n: Target): IdentityAnnotation = this.copy(target = n) } + /** ChiselAnnotation that corresponds to the above FIRRTL annotation */ case class IdentityChiselAnnotation(target: InstanceId, value: String) - extends ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: IdentityAnnotation = IdentityAnnotation(target.toNamed, value) + extends ChiselAnnotation + with RunFirrtlTransform { + def toFirrtl: IdentityAnnotation = IdentityAnnotation(target.toNamed, value) def transformClass: Class[IdentityTransform] = classOf[IdentityTransform] } object identify { @@ -47,7 +44,7 @@ class IdentityTransform extends Transform with DependencyAPIMigration { def execute(state: CircuitState): CircuitState = { val annosx = state.annotations.map { case IdentityAnnotation(t, value) => IdentityAnnotation(t, value + ":seen") - case other => other + case other => other } state.copy(annotations = annosx) } @@ -109,8 +106,8 @@ class ModB(widthB: Int) extends Module { class TopOfDiamond extends Module { val io = IO(new Bundle { - val in = Input(UInt(32.W)) - val out = Output(UInt(32.W)) + val in = Input(UInt(32.W)) + val out = Output(UInt(32.W)) }) val x = Reg(UInt(32.W)) val y = Reg(UInt(32.W)) @@ -146,21 +143,24 @@ class AnnotatingDiamondSpec extends AnyFreeSpec with Matchers { |that happens only after emit has been called on circuit""".stripMargin in { val annos = (new ChiselStage) - .execute(Array("--target-dir", "test_run_dir", "--no-run-firrtl"), - Seq(ChiselGeneratorAnnotation(() => new TopOfDiamond))) + .execute( + Array("--target-dir", "test_run_dir", "--no-run-firrtl"), + Seq(ChiselGeneratorAnnotation(() => new TopOfDiamond)) + ) .filter { case _: IdentityAnnotation => true - case _ => false - }.toSeq + case _ => false + } + .toSeq info("Found ten (10) 'IdentityAnnotation's") - annos should have length (10) + (annos should have).length(10) info("Found IdentityAnnotation targeting '~*|ModC' with value 'ModC(16)'") - annos should contain (IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC"), "ModC(16)")) + annos should contain(IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC"), "ModC(16)")) info("Found IdentityAnnotation targeting '~*|ModC_1:seen' with value 'ModC(32)'") - annos should contain (IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC_1"), "ModC(32)")) + annos should contain(IdentityAnnotation(CircuitTarget("TopOfDiamond").module("ModC_1"), "ModC(32)")) } } } diff --git a/src/test/scala/chiselTests/AnnotationNoDedup.scala b/src/test/scala/chiselTests/AnnotationNoDedup.scala index d99a0021..2150f925 100644 --- a/src/test/scala/chiselTests/AnnotationNoDedup.scala +++ b/src/test/scala/chiselTests/AnnotationNoDedup.scala @@ -9,7 +9,6 @@ import firrtl.stage.FirrtlCircuitAnnotation import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers - class MuchUsedModule extends Module { val io = IO(new Bundle { val in = Input(UInt(16.W)) @@ -35,7 +34,7 @@ class UsesMuchUsedModule(addAnnos: Boolean) extends Module { mod3.io.in := mod2.io.out io.out := mod3.io.out - if(addAnnos) { + if (addAnnos) { doNotDedup(mod1) doNotDedup(mod3) } @@ -46,29 +45,35 @@ class AnnotationNoDedup extends AnyFreeSpec with Matchers { "Firrtl provides transform that reduces identical modules to a single instance" - { "Annotations can be added which will prevent this deduplication for specific modules instances" in { val lowFirrtl = stage - .execute(Array("-X", "low", "--target-dir", "test_run_dir"), - Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = true)))) + .execute( + Array("-X", "low", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = true))) + ) .collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit.serialize - }.getOrElse(fail) - lowFirrtl should include ("module MuchUsedModule :") - lowFirrtl should include ("module MuchUsedModule_1 :") - lowFirrtl should include ("module MuchUsedModule_3 :") - lowFirrtl should not include "module MuchUsedModule_2 :" - lowFirrtl should not include "module MuchUsedModule_4 :" + } + .getOrElse(fail) + lowFirrtl should include("module MuchUsedModule :") + lowFirrtl should include("module MuchUsedModule_1 :") + lowFirrtl should include("module MuchUsedModule_3 :") + (lowFirrtl should not).include("module MuchUsedModule_2 :") + (lowFirrtl should not).include("module MuchUsedModule_4 :") } "Turning off these annotations dedups all the occurrences" in { val lowFirrtl = stage - .execute(Array("-X", "low", "--target-dir", "test_run_dir"), - Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = false)))) + .execute( + Array("-X", "low", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new UsesMuchUsedModule(addAnnos = false))) + ) .collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit.serialize - }.getOrElse(fail) - lowFirrtl should include ("module MuchUsedModule :") - lowFirrtl should not include "module MuchUsedModule_1 :" - lowFirrtl should not include "module MuchUsedModule_3 :" - lowFirrtl should not include "module MuchUsedModule_2 :" - lowFirrtl should not include "module MuchUsedModule_4 :" + } + .getOrElse(fail) + lowFirrtl should include("module MuchUsedModule :") + (lowFirrtl should not).include("module MuchUsedModule_1 :") + (lowFirrtl should not).include("module MuchUsedModule_3 :") + (lowFirrtl should not).include("module MuchUsedModule_2 :") + (lowFirrtl should not).include("module MuchUsedModule_4 :") } } } diff --git a/src/test/scala/chiselTests/AsTypeOfTester.scala b/src/test/scala/chiselTests/AsTypeOfTester.scala index c0365177..2141cac2 100644 --- a/src/test/scala/chiselTests/AsTypeOfTester.scala +++ b/src/test/scala/chiselTests/AsTypeOfTester.scala @@ -3,13 +3,13 @@ package chiselTests import chisel3._ -import chisel3.experimental.{DataMirror, FixedPoint, ChiselEnum} +import chisel3.experimental.{ChiselEnum, DataMirror, FixedPoint} import chisel3.testers.BasicTester class AsTypeOfBundleTester extends BasicTester { class MultiTypeBundle extends Bundle { - val u = UInt(4.W) - val s = SInt(4.W) + val u = UInt(4.W) + val s = SInt(4.W) val fp = FixedPoint(4.W, 3.BP) } @@ -55,12 +55,12 @@ class AsTypeOfVecTester extends BasicTester { class AsTypeOfTruncationTester extends BasicTester { val truncate = (64 + 3).U.asTypeOf(UInt(3.W)) - val expand = 1.U.asTypeOf(UInt(3.W)) + val expand = 1.U.asTypeOf(UInt(3.W)) - assert( DataMirror.widthOf(truncate).get == 3 ) - assert( truncate === 3.U ) - assert( DataMirror.widthOf(expand).get == 3 ) - assert( expand === 1.U ) + assert(DataMirror.widthOf(truncate).get == 3) + assert(truncate === 3.U) + assert(DataMirror.widthOf(expand).get == 3) + assert(expand === 1.U) stop() } @@ -123,26 +123,26 @@ class AsChiselEnumTester extends BasicTester { } class AsTypeOfSpec extends ChiselFlatSpec { - behavior of "asTypeOf" + behavior.of("asTypeOf") it should "work with Bundles containing Bits Types" in { - assertTesterPasses{ new AsTypeOfBundleTester } + assertTesterPasses { new AsTypeOfBundleTester } } it should "work with Bundles that have fields of zero width" in { - assertTesterPasses{ new AsTypeOfBundleZeroWidthTester } + assertTesterPasses { new AsTypeOfBundleZeroWidthTester } } it should "work with Vecs containing Bits Types" in { - assertTesterPasses{ new AsTypeOfVecTester } + assertTesterPasses { new AsTypeOfVecTester } } it should "expand and truncate UInts of different width" in { - assertTesterPasses{ new AsTypeOfTruncationTester } + assertTesterPasses { new AsTypeOfTruncationTester } } it should "work for casting implicit Reset to Bool" in { - assertTesterPasses{ new ResetAsTypeOfBoolTester } + assertTesterPasses { new ResetAsTypeOfBoolTester } } it should "work for casting to and from ChiselEnums" in { diff --git a/src/test/scala/chiselTests/Assert.scala b/src/test/scala/chiselTests/Assert.scala index 0cb554f5..1849ddf8 100644 --- a/src/test/scala/chiselTests/Assert.scala +++ b/src/test/scala/chiselTests/Assert.scala @@ -11,7 +11,7 @@ class FailingAssertTester() extends BasicTester { assert(false.B) // Wait to come out of reset val (_, done) = Counter(!reset.asBool, 4) - when (done) { + when(done) { stop() } } @@ -20,13 +20,13 @@ class SucceedingAssertTester() extends BasicTester { assert(true.B) // Wait to come out of reset val (_, done) = Counter(!reset.asBool, 4) - when (done) { + when(done) { stop() } } class PipelinedResetModule extends Module { - val io = IO(new Bundle { }) + val io = IO(new Bundle {}) val a = RegInit(0xbeef.U) val b = RegInit(0xbeef.U) assert(a === b) @@ -39,7 +39,7 @@ class PipelinedResetTester extends BasicTester { module.reset := RegNext(RegNext(RegNext(reset))) val (_, done) = Counter(!reset.asBool, 4) - when (done) { + when(done) { stop() } } @@ -63,22 +63,22 @@ class BadUnescapedPercentAssertTester extends BasicTester { class AssertSpec extends ChiselFlatSpec with Utils { "A failing assertion" should "fail the testbench" in { - assert(!runTester{ new FailingAssertTester }) + assert(!runTester { new FailingAssertTester }) } "A succeeding assertion" should "not fail the testbench" in { - assertTesterPasses{ new SucceedingAssertTester } + assertTesterPasses { new SucceedingAssertTester } } "An assertion" should "not assert until we come out of reset" in { - assertTesterPasses{ new PipelinedResetTester } + assertTesterPasses { new PipelinedResetTester } } "Assertions" should "allow the modulo operator % in the message" in { - assertTesterPasses{ new ModuloAssertTester } + assertTesterPasses { new ModuloAssertTester } } they should "allow printf-style format strings with arguments" in { - assertTesterPasses{ new FormattedAssertTester } + assertTesterPasses { new FormattedAssertTester } } they should "not allow unescaped % in the message" in { - a [java.util.UnknownFormatConversionException] should be thrownBy { + a[java.util.UnknownFormatConversionException] should be thrownBy { extractCause[java.util.UnknownFormatConversionException] { ChiselStage.elaborate { new BadUnescapedPercentAssertTester } } diff --git a/src/test/scala/chiselTests/AsyncResetSpec.scala b/src/test/scala/chiselTests/AsyncResetSpec.scala index d49f390c..ac7ae0d1 100644 --- a/src/test/scala/chiselTests/AsyncResetSpec.scala +++ b/src/test/scala/chiselTests/AsyncResetSpec.scala @@ -24,16 +24,16 @@ class AsyncResetTester extends BasicTester { } reg := 5.U // Normal connection - when (count === 3.U) { + when(count === 3.U) { assert(reg === 5.U) } - when (count >= 5.U && count < 7.U) { + when(count >= 5.U && count < 7.U) { assert(reg === 123.U) - } .elsewhen (count >= 7.U) { + }.elsewhen(count >= 7.U) { assert(reg === 5.U) } - when (done) { + when(done) { stop() } } @@ -66,25 +66,25 @@ class AsyncResetAggregateTester extends BasicTester { reg(1).x := 7.U reg(1).y := 8.U - when (count === 3.U) { + when(count === 3.U) { assert(reg(0).x === 5.U) assert(reg(0).y === 6.U) assert(reg(1).x === 7.U) assert(reg(1).y === 8.U) } - when (count >= 5.U && count < 7.U) { + when(count >= 5.U && count < 7.U) { assert(reg(0).x === 0.U) assert(reg(0).y === 0.U) assert(reg(1).x === 0.U) assert(reg(1).y === 0.U) - } .elsewhen (count >= 7.U) { + }.elsewhen(count >= 7.U) { assert(reg(0).x === 5.U) assert(reg(0).y === 6.U) assert(reg(1).x === 7.U) assert(reg(1).y === 8.U) } - when (done) { + when(done) { stop() } } @@ -98,7 +98,7 @@ class AsyncResetQueueTester extends BasicTester { val asyncResetNext = RegNext(false.B, false.B) val asyncReset = asyncResetNext.asAsyncReset - val queue = withClockAndReset (slowClk, asyncReset) { + val queue = withClockAndReset(slowClk, asyncReset) { Module(new Queue(UInt(8.W), 4)) } queue.io.enq.valid := true.B @@ -107,15 +107,15 @@ class AsyncResetQueueTester extends BasicTester { queue.io.deq.ready := false.B val doCheck = RegNext(false.B, false.B) - when (queue.io.count === 3.U) { + when(queue.io.count === 3.U) { asyncResetNext := true.B doCheck := true.B } - when (doCheck) { + when(doCheck) { assert(queue.io.count === 0.U) } - when (done) { + when(done) { stop() } } @@ -140,7 +140,7 @@ class AsyncResetDontCareModule extends RawModule { class AsyncResetSpec extends ChiselFlatSpec with Utils { - behavior of "AsyncReset" + behavior.of("AsyncReset") it should "be able to be connected to DontCare" in { ChiselStage.elaborate(new AsyncResetDontCareModule) @@ -153,7 +153,7 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { } it should "NOT be allowed with non-literal reset values" in { - a [NonLiteralAsyncResetValueException] should be thrownBy extractCause[NonLiteralAsyncResetValueException] { + a[NonLiteralAsyncResetValueException] should be thrownBy extractCause[NonLiteralAsyncResetValueException] { compile(new BasicTester { val x = WireInit(123.U + 456.U) withReset(reset.asAsyncReset)(RegInit(x)) @@ -162,7 +162,7 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { } it should "NOT be allowed to connect directly to a Bool" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new BasicTester { val bool = Wire(Bool()) val areset = reset.asAsyncReset @@ -199,12 +199,12 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { val reg = withReset(reset.asAsyncReset)(RegNext(initValue, 27.S)) initValue := -43.S val (count, done) = Counter(true.B, 4) - when (count === 0.U) { + when(count === 0.U) { chisel3.assert(reg === 27.S) - } .otherwise { + }.otherwise { chisel3.assert(reg === -43.S) } - when (done) { stop() } + when(done) { stop() } }) } @@ -212,12 +212,12 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { assertTesterPasses(new BasicTester { val reg = withReset(reset.asAsyncReset)(RegNext(-6.0.F(2.BP), 3.F(2.BP))) val (count, done) = Counter(true.B, 4) - when (count === 0.U) { + when(count === 0.U) { chisel3.assert(reg === 3.F(2.BP)) - } .otherwise { + }.otherwise { chisel3.assert(reg === -6.0.F(2.BP)) } - when (done) { stop() } + when(done) { stop() } }) } @@ -230,12 +230,12 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { x } val (count, done) = Counter(true.B, 4) - when (count === 0.U) { + when(count === 0.U) { chisel3.assert(reg === 13.I) - } .otherwise { + }.otherwise { chisel3.assert(reg === 7.I) } - when (done) { stop() } + when(done) { stop() } }) } @@ -249,12 +249,12 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { RegNext(0xbad0cad0L.U.asTypeOf(new MyBundle), 0xdeadbeefL.U.asTypeOf(new MyBundle)) } val (count, done) = Counter(true.B, 4) - when (count === 0.U) { + when(count === 0.U) { chisel3.assert(reg.asUInt === 0xdeadbeefL.U) - } .otherwise { + }.otherwise { chisel3.assert(reg.asUInt === 0xbad0cad0L.U) } - when (done) { stop() } + when(done) { stop() } }) } it should "allow literals cast to Vecs as reset values" in { @@ -263,12 +263,12 @@ class AsyncResetSpec extends ChiselFlatSpec with Utils { RegNext(0xbad0cad0L.U.asTypeOf(Vec(4, UInt(8.W))), 0xdeadbeefL.U.asTypeOf(Vec(4, UInt(8.W)))) } val (count, done) = Counter(true.B, 4) - when (count === 0.U) { + when(count === 0.U) { chisel3.assert(reg.asUInt === 0xdeadbeefL.U) - } .otherwise { + }.otherwise { chisel3.assert(reg.asUInt === 0xbad0cad0L.U) } - when (done) { stop() } + when(done) { stop() } }) } } diff --git a/src/test/scala/chiselTests/AutoClonetypeSpec.scala b/src/test/scala/chiselTests/AutoClonetypeSpec.scala index ef58f1ed..2ab4c800 100644 --- a/src/test/scala/chiselTests/AutoClonetypeSpec.scala +++ b/src/test/scala/chiselTests/AutoClonetypeSpec.scala @@ -42,7 +42,7 @@ class ModuleWithInner extends Module { val out = UInt(i.W) } - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) val myWire = Wire(new InnerBundle(14)) require(myWire.i == 14) @@ -75,54 +75,64 @@ class InheritingBundle extends QueueIO(UInt(8.W), 8) { class AutoClonetypeSpec extends ChiselFlatSpec with Utils { "Bundles with Scala args" should "not need clonetype" in { - elaborate { new Module { - val io = IO(new Bundle{}) + elaborate { + new Module { + val io = IO(new Bundle {}) - val myWire = Wire(new BundleWithIntArg(8)) - assert(myWire.i == 8) - } } + val myWire = Wire(new BundleWithIntArg(8)) + assert(myWire.i == 8) + } + } } "Bundles with Scala implicit args" should "not need clonetype" in { - elaborate { new Module { - val io = IO(new Bundle{}) + elaborate { + new Module { + val io = IO(new Bundle {}) - implicit val implicitInt: Int = 4 - val myWire = Wire(new BundleWithImplicit()) + implicit val implicitInt: Int = 4 + val myWire = Wire(new BundleWithImplicit()) - assert(myWire.ii == 4) - } } + assert(myWire.ii == 4) + } + } } "Bundles with Scala explicit and impicit args" should "not need clonetype" in { - elaborate { new Module { - val io = IO(new Bundle{}) + elaborate { + new Module { + val io = IO(new Bundle {}) - implicit val implicitInt: Int = 4 - val myWire = Wire(new BundleWithArgAndImplicit(8)) + implicit val implicitInt: Int = 4 + val myWire = Wire(new BundleWithArgAndImplicit(8)) - assert(myWire.i == 8) - assert(myWire.ii == 4) - } } + assert(myWire.i == 8) + assert(myWire.ii == 4) + } + } } "Subtyped Bundles" should "not need clonetype" in { - elaborate { new Module { - val io = IO(new Bundle{}) + elaborate { + new Module { + val io = IO(new Bundle {}) - val myWire = Wire(new SubBundle(8, 4)) + val myWire = Wire(new SubBundle(8, 4)) - assert(myWire.i == 8) - assert(myWire.i2 == 4) - } } - elaborate { new Module { - val io = IO(new Bundle{}) + assert(myWire.i == 8) + assert(myWire.i2 == 4) + } + } + elaborate { + new Module { + val io = IO(new Bundle {}) - val myWire = Wire(new SubBundleVal(8, 4)) + val myWire = Wire(new SubBundleVal(8, 4)) - assert(myWire.i == 8) - assert(myWire.i2 == 4) - } } + assert(myWire.i == 8) + assert(myWire.i2 == 4) + } + } } "Autoclonetype" should "work outside of a builder context" in { @@ -130,10 +140,12 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { } "Subtyped Bundles that don't clone well" should "be now be supported!" in { - elaborate { new Module { - val io = IO(new Bundle{}) - val myWire = Wire(new SubBundleInvalid(8, 4)) - } } + elaborate { + new Module { + val io = IO(new Bundle {}) + val myWire = Wire(new SubBundleInvalid(8, 4)) + } + } } "Inner bundles with Scala args" should "not need clonetype" in { @@ -141,76 +153,92 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { } "Bundles with arguments as fields" should "not need clonetype" in { - elaborate { new Module { - val io = IO(Output(new BundleWithArgumentField(UInt(8.W), UInt(8.W)))) - io.x := 1.U - io.y := 1.U - } } + elaborate { + new Module { + val io = IO(Output(new BundleWithArgumentField(UInt(8.W), UInt(8.W)))) + io.x := 1.U + io.y := 1.U + } + } } it should "also work when giving directions to the fields" in { - elaborate { new Module { - val io = IO(new BundleWithArgumentField(Input(UInt(8.W)), Output(UInt(8.W)))) - io.y := io.x - } } + elaborate { + new Module { + val io = IO(new BundleWithArgumentField(Input(UInt(8.W)), Output(UInt(8.W)))) + io.y := io.x + } + } } "Bundles inside companion objects" should "not need clonetype" in { - elaborate { new Module { - val io = IO(Output(new CompanionObjectWithBundle.Inner)) - io.data := 1.U - } } + elaborate { + new Module { + val io = IO(Output(new CompanionObjectWithBundle.Inner)) + io.data := 1.U + } + } } "Parameterized bundles inside companion objects" should "not need clonetype" in { - elaborate { new Module { - val io = IO(Output(new CompanionObjectWithBundle.ParameterizedInner(8))) - io.data := 1.U - } } + elaborate { + new Module { + val io = IO(Output(new CompanionObjectWithBundle.ParameterizedInner(8))) + io.data := 1.U + } + } } "Nested directioned anonymous Bundles" should "not need clonetype" in { - elaborate { new Module { - val io = IO(new NestedAnonymousBundle) - val a = WireDefault(io) - io.a.a := 1.U - } } + elaborate { + new Module { + val io = IO(new NestedAnonymousBundle) + val a = WireDefault(io) + io.a.a := 1.U + } + } } "3.0 null compatibility" should "not need clonetype" in { - elaborate { new Module { - class InnerClassThing { - def createBundle: Bundle = new Bundle { - val a = Output(UInt(8.W)) + elaborate { + new Module { + class InnerClassThing { + def createBundle: Bundle = new Bundle { + val a = Output(UInt(8.W)) + } } + val io = IO((new InnerClassThing).createBundle) + val a = WireDefault(io) } - val io = IO((new InnerClassThing).createBundle) - val a = WireDefault(io) - } } + } } "Aliased fields" should "be caught" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { - elaborate { new Module { - val bundleFieldType = UInt(8.W) - val io = IO(Output(new Bundle { - val a = bundleFieldType - })) - io.a := 0.U - } } + a[ChiselException] should be thrownBy extractCause[ChiselException] { + elaborate { + new Module { + val bundleFieldType = UInt(8.W) + val io = IO(Output(new Bundle { + val a = bundleFieldType + })) + io.a := 0.U + } + } } } "Aliased fields from inadequate autoclonetype" should "be caught" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { class BadBundle(val typeTuple: (Data, Int)) extends Bundle { val a = typeTuple._1 } - elaborate { new Module { - val io = IO(Output(new BadBundle(UInt(8.W), 1))) - io.a := 0.U - } } + elaborate { + new Module { + val io = IO(Output(new BadBundle(UInt(8.W), 1))) + io.a := 0.U + } + } } } @@ -250,7 +278,7 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { elaborate(new MyModule(3)) } - behavior of "Compiler Plugin Autoclonetype" + behavior.of("Compiler Plugin Autoclonetype") it should "NOT break code that extends chisel3.util Bundles if they use the plugin" in { class MyModule extends MultiIOModule { @@ -266,34 +294,40 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { class MyBundle(i: Int) extends Bundle { val foo = UInt(i.W) } - elaborate { new MultiIOModule { - val in = IO(Input(new MyBundle(8))) - val out = IO(Output(new MyBundle(8))) - out := in - }} + elaborate { + new MultiIOModule { + val in = IO(Input(new MyBundle(8))) + val out = IO(Output(new MyBundle(8))) + out := in + } + } } it should "support type-parameterized Bundles" in { class MyBundle[T <: Data](gen: T) extends Bundle { val foo = gen } - elaborate { new MultiIOModule { - val in = IO(Input(new MyBundle(UInt(8.W)))) - val out = IO(Output(new MyBundle(UInt(8.W)))) - out := in - }} + elaborate { + new MultiIOModule { + val in = IO(Input(new MyBundle(UInt(8.W)))) + val out = IO(Output(new MyBundle(UInt(8.W)))) + out := in + } + } } it should "support Bundles with non-val implicit parameters" in { class MyBundle(implicit i: Int) extends Bundle { val foo = UInt(i.W) } - elaborate { new MultiIOModule { - implicit val x = 8 - val in = IO(Input(new MyBundle)) - val out = IO(Output(new MyBundle)) - out := in - }} + elaborate { + new MultiIOModule { + implicit val x = 8 + val in = IO(Input(new MyBundle)) + val out = IO(Output(new MyBundle)) + out := in + } + } } it should "support Bundles with multiple parameter lists" in { @@ -313,11 +347,13 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils { class MyBundle(i: Int) extends Bundle { val foo = UInt(i.W) } - elaborate { new MultiIOModule { - val in = IO(Input(new MyBundle(8))) - val out = IO(Output(new MyBundle(8))) - out := in - }} + elaborate { + new MultiIOModule { + val in = IO(Input(new MyBundle(8))) + val out = IO(Output(new MyBundle(8))) + out := in + } + } } it should "support Bundles that capture type parameters from their parent scope" in { diff --git a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala index 258d0823..b75c0c00 100644 --- a/src/test/scala/chiselTests/AutoNestedCloneSpec.scala +++ b/src/test/scala/chiselTests/AutoNestedCloneSpec.scala @@ -14,7 +14,7 @@ class BundleWithAnonymousInner(val w: Int) extends Bundle { class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils { - behavior of "autoCloneType of inner Bundle in Chisel3" + behavior.of("autoCloneType of inner Bundle in Chisel3") it should "clone a doubly-nested inner bundle successfully" in { elaborate { @@ -36,7 +36,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils { elaborate { class TestTop(val w: Int) extends Module { val io = IO(new Bundle {}) - val myWire = Wire(new Bundle{ val a = UInt(w.W) }) + val myWire = Wire(new Bundle { val a = UInt(w.W) }) } new TestTop(2) } @@ -45,13 +45,13 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils { it should "pick the correct $outer instance for an anonymous inner bundle" in { elaborate { class Inner(val w: Int) extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(w.W)) val out = Output(UInt(w.W)) }) } class Outer(val w: Int) extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(w.W)) val out = Output(UInt(w.W)) }) @@ -125,7 +125,7 @@ class AutoNestedCloneSpec extends ChiselFlatSpec with Matchers with Utils { val foo = new Bundle { val x = Input(Vec(n, gen)) } - val bar = Output(Option(new { def mkBundle = new Bundle { val x = Vec(n, gen) }}).get.mkBundle) + val bar = Output(Option(new { def mkBundle = new Bundle { val x = Vec(n, gen) } }).get.mkBundle) } val io = IO(new MyBundle(4, UInt(8.W))) val myWire = WireInit(io.foo) diff --git a/src/test/scala/chiselTests/BetterNamingTests.scala b/src/test/scala/chiselTests/BetterNamingTests.scala index a55d3e08..8fd1c11f 100644 --- a/src/test/scala/chiselTests/BetterNamingTests.scala +++ b/src/test/scala/chiselTests/BetterNamingTests.scala @@ -31,10 +31,14 @@ class IterableNaming extends NamedModuleTester { val seq = Seq.tabulate(3) { i => Seq.tabulate(2) { j => expectName(WireDefault((i * j).U), s"seq_${i}_${j}") } } - val optSet = Some(Set(expectName(WireDefault(0.U), "optSet_0"), - expectName(WireDefault(1.U), "optSet_1"), - expectName(WireDefault(2.U), "optSet_2"), - expectName(WireDefault(3.U), "optSet_3"))) + val optSet = Some( + Set( + expectName(WireDefault(0.U), "optSet_0"), + expectName(WireDefault(1.U), "optSet_1"), + expectName(WireDefault(2.U), "optSet_2"), + expectName(WireDefault(3.U), "optSet_3") + ) + ) val stack = { val s = mutable.Stack[Module]() @@ -62,7 +66,7 @@ class DigitFieldNamesInRecord extends NamedModuleTester { */ class BetterNamingTests extends ChiselFlatSpec { - behavior of "Better Naming" + behavior.of("Better Naming") it should "provide unique counters for each name" in { var module: PerNameIndexing = null @@ -77,7 +81,7 @@ class BetterNamingTests extends ChiselFlatSpec { } it should "allow digits to be field names in Records" in { - var module: DigitFieldNamesInRecord = null + var module: DigitFieldNamesInRecord = null ChiselStage.elaborate { module = new DigitFieldNamesInRecord; module } assert(module.getNameFailures() == Nil) } @@ -92,6 +96,6 @@ class BetterNamingTests extends ChiselFlatSpec { } val withLits = ChiselStage.emitChirrtl(new MyModule(true)) val noLits = ChiselStage.emitChirrtl(new MyModule(false)) - withLits should equal (noLits) + withLits should equal(noLits) } } diff --git a/src/test/scala/chiselTests/BitwiseOps.scala b/src/test/scala/chiselTests/BitwiseOps.scala index 9cbadbc1..2c050bfa 100644 --- a/src/test/scala/chiselTests/BitwiseOps.scala +++ b/src/test/scala/chiselTests/BitwiseOps.scala @@ -14,14 +14,15 @@ class BitwiseOpsTester(w: Int, _a: Int, _b: Int) extends BasicTester { assert((a | b) === (_a | _b).asUInt) assert((a ^ b) === (_a ^ _b).asUInt) assert((a.orR) === (_a != 0).asBool) - assert((a.andR) === (s"%${w}s".format(BigInt(_a).toString(2)).foldLeft(true)(_ && _ == '1') ).asBool) + assert((a.andR) === (s"%${w}s".format(BigInt(_a).toString(2)).foldLeft(true)(_ && _ == '1')).asBool) stop() } class BitwiseOpsSpec extends ChiselPropSpec { property("All bit-wise ops should return the correct result") { - forAll(safeUIntPair) { case(w: Int, a: Int, b: Int) => - assertTesterPasses{ new BitwiseOpsTester(w, a, b) } + forAll(safeUIntPair) { + case (w: Int, a: Int, b: Int) => + assertTesterPasses { new BitwiseOpsTester(w, a, b) } } } } diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala index d3d52f96..27cdbbc4 100644 --- a/src/test/scala/chiselTests/BlackBox.scala +++ b/src/test/scala/chiselTests/BlackBox.scala @@ -5,7 +5,7 @@ package chiselTests import chisel3._ import chisel3.experimental._ import chisel3.stage.ChiselStage -import chisel3.testers.{TesterDriver, BasicTester} +import chisel3.testers.{BasicTester, TesterDriver} import chisel3.util._ class BlackBoxInverter extends BlackBox { @@ -120,8 +120,7 @@ class BlackBoxWithClockTester extends BasicTester { when(end) { stop() } } -class BlackBoxConstant(value: Int) extends BlackBox( - Map("VALUE" -> value, "WIDTH" -> log2Ceil(value + 1))) { +class BlackBoxConstant(value: Int) extends BlackBox(Map("VALUE" -> value, "WIDTH" -> log2Ceil(value + 1))) { require(value >= 0, "value must be a UInt!") val io = IO(new Bundle { val out = Output(UInt(log2Ceil(value + 1).W)) @@ -147,8 +146,8 @@ class BlackBoxTypeParam(w: Int, raw: String) extends BlackBox(Map("T" -> RawPara } class BlackBoxWithParamsTester extends BasicTester { - val blackBoxOne = Module(new BlackBoxConstant(1)) - val blackBoxFour = Module(new BlackBoxConstant(4)) + val blackBoxOne = Module(new BlackBoxConstant(1)) + val blackBoxFour = Module(new BlackBoxConstant(4)) val blackBoxStringParamOne = Module(new BlackBoxStringParam("one")) val blackBoxStringParamTwo = Module(new BlackBoxStringParam("two")) val blackBoxRealParamOne = Module(new BlackBoxRealParam(1.0)) @@ -158,7 +157,7 @@ class BlackBoxWithParamsTester extends BasicTester { val (cycles, end) = Counter(true.B, 4) - assert(blackBoxOne.io.out === 1.U) + assert(blackBoxOne.io.out === 1.U) assert(blackBoxFour.io.out === 4.U) assert(blackBoxStringParamOne.io.out === 1.U) assert(blackBoxStringParamTwo.io.out === 2.U) @@ -172,47 +171,28 @@ class BlackBoxWithParamsTester extends BasicTester { class BlackBoxSpec extends ChiselFlatSpec { "A BlackBoxed inverter" should "work" in { - assertTesterPasses( - {new BlackBoxTester}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new BlackBoxTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "A BlackBoxed with flipped IO" should "work" in { - assertTesterPasses( - {new BlackBoxFlipTester}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new BlackBoxFlipTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "Multiple BlackBoxes" should "work" in { - assertTesterPasses( - {new MultiBlackBoxTester}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new MultiBlackBoxTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "A BlackBoxed register" should "work" in { - assertTesterPasses( - {new BlackBoxWithClockTester}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new BlackBoxWithClockTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "BlackBoxes with parameters" should "work" in { - assertTesterPasses( - {new BlackBoxWithParamsTester}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new BlackBoxWithParamsTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "DataMirror.modulePorts" should "work with BlackBox" in { ChiselStage.elaborate(new Module { - val io = IO(new Bundle {}) - val m = Module(new BlackBoxPassthrough) - assert(DataMirror.modulePorts(m) == Seq("in" -> m.io.in, "out" -> m.io.out)) - } - ) + val io = IO(new Bundle {}) + val m = Module(new BlackBoxPassthrough) + assert(DataMirror.modulePorts(m) == Seq("in" -> m.io.in, "out" -> m.io.out)) + }) } "A BlackBoxed using suggestName(\"io\")" should "work (but don't do this)" in { - assertTesterPasses( - {new BlackBoxTesterSuggestName}, - Seq("/chisel3/BlackBoxTest.v"), - TesterDriver.verilatorOnly) + assertTesterPasses({ new BlackBoxTesterSuggestName }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } } diff --git a/src/test/scala/chiselTests/BlackBoxImpl.scala b/src/test/scala/chiselTests/BlackBoxImpl.scala index 2fa3d8a6..4cc72dd0 100644 --- a/src/test/scala/chiselTests/BlackBoxImpl.scala +++ b/src/test/scala/chiselTests/BlackBoxImpl.scala @@ -5,7 +5,7 @@ package chiselTests import java.io.File import chisel3._ -import chisel3.util.{HasBlackBoxInline, HasBlackBoxResource, HasBlackBoxPath} +import chisel3.util.{HasBlackBoxInline, HasBlackBoxPath, HasBlackBoxResource} import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import firrtl.transforms.BlackBoxNotFoundException import org.scalacheck.Test.Failed @@ -13,22 +13,23 @@ import org.scalatest.Succeeded import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers - -class BlackBoxAdd(n : Int) extends HasBlackBoxInline { +class BlackBoxAdd(n: Int) extends HasBlackBoxInline { val io = IO(new Bundle { val in = Input(UInt(16.W)) val out = Output(UInt(16.W)) }) - setInline("BlackBoxAdd.v", + setInline( + "BlackBoxAdd.v", s""" - |module BlackBoxAdd( - | input [15:0] in, - | output [15:0] out - |); - | assign out = in + $n; - |endmodule - """.stripMargin) + |module BlackBoxAdd( + | input [15:0] in, + | output [15:0] out + |); + | assign out = in + $n; + |endmodule + """.stripMargin + ) } class UsesBlackBoxAddViaInline extends Module { @@ -89,7 +90,7 @@ class UsesBlackBoxMinusViaPath extends Module { } class BlackBoxResourceNotFound extends HasBlackBoxResource { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) addResource("/missing.resource") } @@ -102,29 +103,35 @@ class BlackBoxImplSpec extends AnyFreeSpec with Matchers { val stage = new ChiselStage "BlackBox can have verilator source implementation" - { "Implementations can be contained in-line" in { - stage.execute(Array("-X", "verilog", "--target-dir", targetDir), - Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxAddViaInline))) + stage.execute( + Array("-X", "verilog", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxAddViaInline)) + ) val verilogOutput = new File(targetDir, "BlackBoxAdd.v") - verilogOutput.exists() should be (true) + verilogOutput.exists() should be(true) verilogOutput.delete() } "Implementations can be contained in resource files" in { - stage.execute(Array("-X", "low", "--target-dir", targetDir), - Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaResource))) + stage.execute( + Array("-X", "low", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaResource)) + ) val verilogOutput = new File(targetDir, "BlackBoxTest.v") - verilogOutput.exists() should be (true) + verilogOutput.exists() should be(true) verilogOutput.delete() } "Implementations can be contained in arbitrary files" in { - stage.execute(Array("-X", "low", "--target-dir", targetDir), - Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaPath))) + stage.execute( + Array("-X", "low", "--target-dir", targetDir), + Seq(ChiselGeneratorAnnotation(() => new UsesBlackBoxMinusViaPath)) + ) val verilogOutput = new File(targetDir, "BlackBoxTest.v") - verilogOutput.exists() should be (true) + verilogOutput.exists() should be(true) verilogOutput.delete() Succeeded } "Resource files that do not exist produce Chisel errors" in { - assertThrows[BlackBoxNotFoundException]{ + assertThrows[BlackBoxNotFoundException] { ChiselStage.emitChirrtl(new UsesMissingBlackBoxResource) } } diff --git a/src/test/scala/chiselTests/BoringUtilsSpec.scala b/src/test/scala/chiselTests/BoringUtilsSpec.scala index 39859581..9be2d75a 100644 --- a/src/test/scala/chiselTests/BoringUtilsSpec.scala +++ b/src/test/scala/chiselTests/BoringUtilsSpec.scala @@ -8,7 +8,7 @@ import chisel3.testers._ import chisel3.experimental.{BaseModule, ChiselAnnotation, RunFirrtlTransform} import chisel3.util.experimental.BoringUtils -import firrtl.{CircuitForm, CircuitState, ChirrtlForm, DependencyAPIMigration, Transform} +import firrtl.{ChirrtlForm, CircuitForm, CircuitState, DependencyAPIMigration, Transform} import firrtl.annotations.{Annotation, NoTargetAnnotation} import firrtl.options.Dependency import firrtl.transforms.{DontTouchAnnotation, NoDedupAnnotation} @@ -18,7 +18,7 @@ import firrtl.stage.Forms abstract class ShouldntAssertTester(cyclesToWait: BigInt = 4) extends BasicTester { val dut: BaseModule val (_, done) = Counter(true.B, 2) - when (done) { stop() } + when(done) { stop() } } class StripNoDedupAnnotation extends Transform with DependencyAPIMigration { @@ -27,14 +27,14 @@ class StripNoDedupAnnotation extends Transform with DependencyAPIMigration { override def optionalPrerequisiteOf = Dependency[WiringTransform] +: Forms.ChirrtlEmitters override def invalidates(a: Transform) = false def execute(state: CircuitState): CircuitState = { - state.copy(annotations = state.annotations.filter{ case _: NoDedupAnnotation => false; case _ => true }) + state.copy(annotations = state.annotations.filter { case _: NoDedupAnnotation => false; case _ => true }) } } class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { class BoringInverter extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) val a = Wire(UInt(1.W)) val notA = Wire(UInt(1.W)) val b = Wire(UInt(1.W)) @@ -46,11 +46,13 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { BoringUtils.addSink(b, "x") } - behavior of "BoringUtils.{addSink, addSource}" + behavior.of("BoringUtils.{addSink, addSource}") it should "connect two wires within a module" in { - runTester(new ShouldntAssertTester { val dut = Module(new BoringInverter) }, - annotations = TesterDriver.verilatorOnly) should be (true) + runTester( + new ShouldntAssertTester { val dut = Module(new BoringInverter) }, + annotations = TesterDriver.verilatorOnly + ) should be(true) } trait WireX { this: BaseModule => @@ -77,10 +79,10 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { val sinks = Seq.fill(6)(Module(new Sink)) /* Sources are differentiated by their input connections only. */ - sources.zip(Seq(0, 1, 2)).map{ case (a, b) => a.in := b.U } + sources.zip(Seq(0, 1, 2)).map { case (a, b) => a.in := b.U } /* Sinks are differentiated by their post-boring outputs. */ - sinks.zip(Seq(0, 1, 1, 2, 2, 2)).map{ case (a, b) => chisel3.assert(a.out === b.U) } + sinks.zip(Seq(0, 1, 1, 2, 2, 2)).map { case (a, b) => chisel3.assert(a.out === b.U) } } /** This is testing a complicated wiring pattern and exercising @@ -95,22 +97,22 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { trait FailViaDedup { this: TopTester => case object FooAnnotation extends NoTargetAnnotation - chisel3.experimental.annotate( - new ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = FooAnnotation - def transformClass: Class[_ <: Transform] = classOf[StripNoDedupAnnotation] } ) + chisel3.experimental.annotate(new ChiselAnnotation with RunFirrtlTransform { + def toFirrtl: Annotation = FooAnnotation + def transformClass: Class[_ <: Transform] = classOf[StripNoDedupAnnotation] + }) } - behavior of "BoringUtils.bore" + behavior.of("BoringUtils.bore") it should "connect across modules using BoringUtils.bore" in { - runTester(new TopTester, annotations = TesterDriver.verilatorOnly) should be (true) + runTester(new TopTester, annotations = TesterDriver.verilatorOnly) should be(true) } it should "throw an exception if NoDedupAnnotations are removed" in { - intercept[WiringException] { runTester(new TopTester with FailViaDedup, - annotations = Seq(TesterDriver.VerilatorBackend)) } - .getMessage should startWith ("Unable to determine source mapping for sink") + intercept[WiringException] { + runTester(new TopTester with FailViaDedup, annotations = Seq(TesterDriver.VerilatorBackend)) + }.getMessage should startWith("Unable to determine source mapping for sink") } class InternalBore extends RawModule { @@ -127,7 +129,7 @@ class BoringUtilsSpec extends ChiselFlatSpec with ChiselRunners { } it should "work for an internal (same module) BoringUtils.bore" in { - runTester(new InternalBoreTester, annotations = TesterDriver.verilatorOnly) should be (true) + runTester(new InternalBoreTester, annotations = TesterDriver.verilatorOnly) should be(true) } } diff --git a/src/test/scala/chiselTests/BundleLiteralSpec.scala b/src/test/scala/chiselTests/BundleLiteralSpec.scala index b4adde4a..bc6522bb 100644 --- a/src/test/scala/chiselTests/BundleLiteralSpec.scala +++ b/src/test/scala/chiselTests/BundleLiteralSpec.scala @@ -29,50 +29,57 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } "bundle literals" should "pack" in { - assertTesterPasses{ new BasicTester { - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB) - bundleLit.litOption should equal (Some(169)) // packed as 42 (8-bit), false=0 (1-bit), sB=1 (1-bit) - chisel3.assert(bundleLit.asUInt() === bundleLit.litOption.get.U) // sanity-check consistency with runtime - - val longBundleLit = (new LongBundle).Lit( - _.a -> 0xDEADDEADBEEFL.U, _.b -> (-0x0BEEF00DL).S(32.W), _.c -> 4.5.F(16.W, 4.BP)) - longBundleLit.litOption should equal (Some( - (BigInt(0xDEADDEADBEEFL) << 48) - + (BigInt(0xFFFFFFFFL - 0xBEEF00DL + 1) << 16) - + BigInt(72))) - chisel3.assert(longBundleLit.asUInt() === longBundleLit.litOption.get.U) - - stop() - } } + assertTesterPasses { + new BasicTester { + val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> false.B, _.c -> MyEnum.sB) + bundleLit.litOption should equal(Some(169)) // packed as 42 (8-bit), false=0 (1-bit), sB=1 (1-bit) + chisel3.assert(bundleLit.asUInt() === bundleLit.litOption.get.U) // sanity-check consistency with runtime + + val longBundleLit = + (new LongBundle).Lit(_.a -> 0xdeaddeadbeefL.U, _.b -> (-0x0beef00dL).S(32.W), _.c -> 4.5.F(16.W, 4.BP)) + longBundleLit.litOption should equal( + Some( + (BigInt(0xdeaddeadbeefL) << 48) + + (BigInt(0xffffffffL - 0xbeef00dL + 1) << 16) + + BigInt(72) + ) + ) + chisel3.assert(longBundleLit.asUInt() === longBundleLit.litOption.get.U) + + stop() + } + } } "bundle literals" should "work in RTL" in { val outsideBundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - assertTesterPasses{ new BasicTester{ - // TODO: add direct bundle compare operations, when that feature is added - chisel3.assert(outsideBundleLit.a === 42.U) - chisel3.assert(outsideBundleLit.b === true.B) - chisel3.assert(outsideBundleLit.c === MyEnum.sB) - chisel3.assert(outsideBundleLit.isLit()) - chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt()) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - chisel3.assert(bundleLit.a === 42.U) - chisel3.assert(bundleLit.b === true.B) - chisel3.assert(bundleLit.c === MyEnum.sB) - - chisel3.assert(bundleLit.a === outsideBundleLit.a) - chisel3.assert(bundleLit.b === outsideBundleLit.b) - chisel3.assert(bundleLit.c === outsideBundleLit.c) - - val bundleWire = Wire(new MyBundle) - bundleWire := outsideBundleLit - - chisel3.assert(bundleWire.a === 42.U) - chisel3.assert(bundleWire.b === true.B) - chisel3.assert(bundleWire.c === MyEnum.sB) - - stop() - } } + assertTesterPasses { + new BasicTester { + // TODO: add direct bundle compare operations, when that feature is added + chisel3.assert(outsideBundleLit.a === 42.U) + chisel3.assert(outsideBundleLit.b === true.B) + chisel3.assert(outsideBundleLit.c === MyEnum.sB) + chisel3.assert(outsideBundleLit.isLit()) + chisel3.assert(outsideBundleLit.litValue().U === outsideBundleLit.asUInt()) + val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) + chisel3.assert(bundleLit.a === 42.U) + chisel3.assert(bundleLit.b === true.B) + chisel3.assert(bundleLit.c === MyEnum.sB) + + chisel3.assert(bundleLit.a === outsideBundleLit.a) + chisel3.assert(bundleLit.b === outsideBundleLit.b) + chisel3.assert(bundleLit.c === outsideBundleLit.c) + + val bundleWire = Wire(new MyBundle) + bundleWire := outsideBundleLit + + chisel3.assert(bundleWire.a === 42.U) + chisel3.assert(bundleWire.b === true.B) + chisel3.assert(bundleWire.c === MyEnum.sB) + + stop() + } + } } "bundle literals of vec literals" should "work" in { @@ -82,11 +89,11 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { val a = Vec(2, UInt(4.W)) val b = Vec(2, Interval(range)) }.Lit( - _.a -> Vec(2, UInt(4.W)).Lit(0 -> 0xA.U, 1 -> 0xB.U), + _.a -> Vec(2, UInt(4.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U), _.b -> Vec(2, Interval(range)).Lit(0 -> (1.5).I(range), 1 -> (0.25).I(range)) ) - chisel3.assert(bundleWithVecs.a(0) === 0xA.U) - chisel3.assert(bundleWithVecs.a(1) === 0xB.U) + chisel3.assert(bundleWithVecs.a(0) === 0xa.U) + chisel3.assert(bundleWithVecs.a(1) === 0xb.U) chisel3.assert(bundleWithVecs.b(0) === (1.5).I(range)) chisel3.assert(bundleWithVecs.b(1) === (0.25).I(range)) stop() @@ -94,17 +101,19 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } "partial bundle literals" should "work in RTL" in { - assertTesterPasses{ new BasicTester{ - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - chisel3.assert(bundleLit.a === 42.U) + assertTesterPasses { + new BasicTester { + val bundleLit = (new MyBundle).Lit(_.a -> 42.U) + chisel3.assert(bundleLit.a === 42.U) - val bundleWire = Wire(new MyBundle) - bundleWire := bundleLit + val bundleWire = Wire(new MyBundle) + bundleWire := bundleLit - chisel3.assert(bundleWire.a === 42.U) + chisel3.assert(bundleWire.a === 42.U) - stop() - } } + stop() + } + } } class MyOuterBundle extends Bundle { @@ -118,120 +127,138 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } "contained bundles" should "work" in { - assertTesterPasses{ new BasicTester{ - // Specify the inner Bundle value as a Bundle literal - val explicitBundleLit = (new MyOuterBundle).Lit( - _.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - ) - chisel3.assert(explicitBundleLit.a.a === 42.U) - chisel3.assert(explicitBundleLit.a.b === true.B) - chisel3.assert(explicitBundleLit.a.c === MyEnum.sB) - chisel3.assert(explicitBundleLit.a.isLit()) - chisel3.assert(explicitBundleLit.a.litValue().U === explicitBundleLit.a.asUInt()) - - // Specify the inner Bundle fields directly - val expandedBundleLit = (new MyOuterBundle).Lit( - _.a.a -> 42.U, _.a.b -> true.B, - _.b.c -> false.B, _.b.d -> 255.U, _.b.e -> MyEnum.sB, - _.f -> MyEnum.sB - ) - chisel3.assert(expandedBundleLit.a.a === 42.U) - chisel3.assert(expandedBundleLit.a.b === true.B) - chisel3.assert(expandedBundleLit.f === MyEnum.sB) - chisel3.assert(expandedBundleLit.b.c === false.B) - chisel3.assert(expandedBundleLit.b.d === 255.U) - chisel3.assert(expandedBundleLit.b.e === MyEnum.sB) - chisel3.assert(! expandedBundleLit.a.isLit()) // element e is missing - chisel3.assert(expandedBundleLit.b.isLit()) - chisel3.assert(! expandedBundleLit.isLit()) // element a.e is missing - chisel3.assert(expandedBundleLit.b.litValue().U === expandedBundleLit.b.asUInt()) - - // Anonymously contruct the inner Bundle literal - // A bit of weird syntax that depends on implementation details of the Bundle literal constructor - val childBundleLit = (new MyOuterBundle).Lit( - b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U, _.e -> MyEnum.sB) - ) - chisel3.assert(childBundleLit.b.c === false.B) - chisel3.assert(childBundleLit.b.d === 255.U) - chisel3.assert(childBundleLit.b.e === MyEnum.sB) - chisel3.assert(childBundleLit.b.isLit()) - chisel3.assert(! childBundleLit.isLit()) // elements a and f are missing - chisel3.assert(childBundleLit.b.litValue().U === childBundleLit.b.asUInt()) - - stop() - } } + assertTesterPasses { + new BasicTester { + // Specify the inner Bundle value as a Bundle literal + val explicitBundleLit = (new MyOuterBundle).Lit( + _.a -> (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) + ) + chisel3.assert(explicitBundleLit.a.a === 42.U) + chisel3.assert(explicitBundleLit.a.b === true.B) + chisel3.assert(explicitBundleLit.a.c === MyEnum.sB) + chisel3.assert(explicitBundleLit.a.isLit()) + chisel3.assert(explicitBundleLit.a.litValue().U === explicitBundleLit.a.asUInt()) + + // Specify the inner Bundle fields directly + val expandedBundleLit = (new MyOuterBundle).Lit( + _.a.a -> 42.U, + _.a.b -> true.B, + _.b.c -> false.B, + _.b.d -> 255.U, + _.b.e -> MyEnum.sB, + _.f -> MyEnum.sB + ) + chisel3.assert(expandedBundleLit.a.a === 42.U) + chisel3.assert(expandedBundleLit.a.b === true.B) + chisel3.assert(expandedBundleLit.f === MyEnum.sB) + chisel3.assert(expandedBundleLit.b.c === false.B) + chisel3.assert(expandedBundleLit.b.d === 255.U) + chisel3.assert(expandedBundleLit.b.e === MyEnum.sB) + chisel3.assert(!expandedBundleLit.a.isLit()) // element e is missing + chisel3.assert(expandedBundleLit.b.isLit()) + chisel3.assert(!expandedBundleLit.isLit()) // element a.e is missing + chisel3.assert(expandedBundleLit.b.litValue().U === expandedBundleLit.b.asUInt()) + + // Anonymously contruct the inner Bundle literal + // A bit of weird syntax that depends on implementation details of the Bundle literal constructor + val childBundleLit = + (new MyOuterBundle).Lit(b => b.b -> b.b.Lit(_.c -> false.B, _.d -> 255.U, _.e -> MyEnum.sB)) + chisel3.assert(childBundleLit.b.c === false.B) + chisel3.assert(childBundleLit.b.d === 255.U) + chisel3.assert(childBundleLit.b.e === MyEnum.sB) + chisel3.assert(childBundleLit.b.isLit()) + chisel3.assert(!childBundleLit.isLit()) // elements a and f are missing + chisel3.assert(childBundleLit.b.litValue().U === childBundleLit.b.asUInt()) + + stop() + } + } } "Bundle literals" should "assign" in { - assertTesterPasses{ new BasicTester{ - val bundleWire = Wire(Output(new MyBundle)) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) - bundleWire := bundleLit - - chisel3.assert(bundleWire.a === 42.U) - chisel3.assert(bundleWire.b === true.B) - chisel3.assert(bundleWire.c === MyEnum.sB) - stop() - } } + assertTesterPasses { + new BasicTester { + val bundleWire = Wire(Output(new MyBundle)) + val bundleLit = (new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB) + bundleWire := bundleLit + + chisel3.assert(bundleWire.a === 42.U) + chisel3.assert(bundleWire.b === true.B) + chisel3.assert(bundleWire.c === MyEnum.sB) + stop() + } + } } "partially initialized Bundle literals" should "assign" in { - assertTesterPasses{ new BasicTester{ - val bundleWire = Wire(Output(new MyBundle)) - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - bundleWire := bundleLit - - chisel3.assert(bundleWire.a === 42.U) - stop() - } } + assertTesterPasses { + new BasicTester { + val bundleWire = Wire(Output(new MyBundle)) + val bundleLit = (new MyBundle).Lit(_.a -> 42.U) + bundleWire := bundleLit + + chisel3.assert(bundleWire.a === 42.U) + stop() + } + } } "Bundle literals" should "work as register reset values" in { - assertTesterPasses{ new BasicTester{ - val r = RegInit((new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)) - r := (r.asUInt + 1.U).asTypeOf(new MyBundle) // prevent constprop - - // check reset values on first cycle out of reset - chisel3.assert(r.a === 42.U) - chisel3.assert(r.b === true.B) - chisel3.assert(r.c === MyEnum.sB) - stop() - } } + assertTesterPasses { + new BasicTester { + val r = RegInit((new MyBundle).Lit(_.a -> 42.U, _.b -> true.B, _.c -> MyEnum.sB)) + r := (r.asUInt + 1.U).asTypeOf(new MyBundle) // prevent constprop + + // check reset values on first cycle out of reset + chisel3.assert(r.a === 42.U) + chisel3.assert(r.b === true.B) + chisel3.assert(r.c === MyEnum.sB) + stop() + } + } } "partially initialized Bundle literals" should "work as register reset values" in { - assertTesterPasses{ new BasicTester{ - val r = RegInit((new MyBundle).Lit(_.a -> 42.U)) - r.a := r.a + 1.U // prevent const prop - chisel3.assert(r.a === 42.U) // coming out of reset - stop() - } } + assertTesterPasses { + new BasicTester { + val r = RegInit((new MyBundle).Lit(_.a -> 42.U)) + r.a := r.a + 1.U // prevent const prop + chisel3.assert(r.a === 42.U) // coming out of reset + stop() + } + } } "Fields extracted from BundleLiterals" should "work as register reset values" in { - assertTesterPasses{ new BasicTester{ - val r = RegInit((new MyBundle).Lit(_.a -> 42.U).a) - r := r + 1.U // prevent const prop - chisel3.assert(r === 42.U) // coming out of reset - stop() - } } + assertTesterPasses { + new BasicTester { + val r = RegInit((new MyBundle).Lit(_.a -> 42.U).a) + r := r + 1.U // prevent const prop + chisel3.assert(r === 42.U) // coming out of reset + stop() + } + } } "DontCare fields extracted from BundleLiterals" should "work as register reset values" in { - assertTesterPasses{ new BasicTester{ - val r = RegInit((new MyBundle).Lit(_.a -> 42.U).b) - r := reset.asBool - printf(p"r = $r\n") // Can't assert because reset value is DontCare - stop() - } } + assertTesterPasses { + new BasicTester { + val r = RegInit((new MyBundle).Lit(_.a -> 42.U).b) + r := reset.asBool + printf(p"r = $r\n") // Can't assert because reset value is DontCare + stop() + } + } } "DontCare fields extracted from BundleLiterals" should "work in other Expressions" in { - assertTesterPasses{ new BasicTester{ - val x = (new MyBundle).Lit(_.a -> 42.U).b || true.B - chisel3.assert(x === true.B) - stop() - } } + assertTesterPasses { + new BasicTester { + val x = (new MyBundle).Lit(_.a -> 42.U).b || true.B + chisel3.assert(x === true.B) + stop() + } + } } "bundle literals with bad field specifiers" should "fail" in { @@ -240,12 +267,12 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { ChiselStage.elaborate { new RawModule { val bundle = new MyBundle - bundle.Lit(x => bundle.a -> 0.U) // DONT DO THIS, this gets past a syntax error to exercise the failure + bundle.Lit(x => bundle.a -> 0.U) // DONT DO THIS, this gets past a syntax error to exercise the failure } } } } - exc.getMessage should include ("not a field") + exc.getMessage should include("not a field") } "bundle literals with duplicate fields" should "fail" in { @@ -258,21 +285,22 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } } } - exc.getMessage should include ("duplicate") - exc.getMessage should include (".a") + exc.getMessage should include("duplicate") + exc.getMessage should include(".a") } "bundle literals with non-literal values" should "fail" in { val exc = intercept[BundleLiteralException] { extractCause[BundleLiteralException] { - ChiselStage.elaborate { new RawModule { - (new MyBundle).Lit(_.a -> UInt()) - } + ChiselStage.elaborate { + new RawModule { + (new MyBundle).Lit(_.a -> UInt()) + } } } } - exc.getMessage should include ("non-literal value") - exc.getMessage should include (".a") + exc.getMessage should include("non-literal value") + exc.getMessage should include(".a") } "bundle literals with non-type-equivalent element fields" should "fail" in { @@ -285,8 +313,8 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } } } - exc.getMessage should include ("non-type-equivalent value") - exc.getMessage should include (".a") + exc.getMessage should include("non-type-equivalent value") + exc.getMessage should include(".a") } "bundle literals with non-type-equivalent sub-bundles" should "fail" in { @@ -299,8 +327,8 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } } } - exc.getMessage should include ("non-type-equivalent value") - exc.getMessage should include (".b") + exc.getMessage should include("non-type-equivalent value") + exc.getMessage should include(".b") } "bundle literals with non-type-equivalent enum element fields" should "fail" in { @@ -313,14 +341,16 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils { } } } - exc.getMessage should include ("non-type-equivalent enum value") - exc.getMessage should include (".c") + exc.getMessage should include("non-type-equivalent enum value") + exc.getMessage should include(".c") } "partial bundle literals" should "fail to pack" in { - ChiselStage.elaborate { new RawModule { - val bundleLit = (new MyBundle).Lit(_.a -> 42.U) - bundleLit.litOption should equal (None) - } } + ChiselStage.elaborate { + new RawModule { + val bundleLit = (new MyBundle).Lit(_.a -> 42.U) + bundleLit.litOption should equal(None) + } + } } } diff --git a/src/test/scala/chiselTests/BundleSpec.scala b/src/test/scala/chiselTests/BundleSpec.scala index d9f82e6d..720f877f 100644 --- a/src/test/scala/chiselTests/BundleSpec.scala +++ b/src/test/scala/chiselTests/BundleSpec.scala @@ -61,13 +61,13 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils { } "Bulk connect on Bundles" should "check that the fields match" in { - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new MyModule(new BundleFooBar, new BundleFoo) } - }).getMessage should include ("Right Record missing field") + }).getMessage should include("Right Record missing field") - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new MyModule(new BundleFoo, new BundleFooBar) } - }).getMessage should include ("Left Record missing field") + }).getMessage should include("Left Record missing field") } "Bundles" should "not be able to use Seq for constructing hardware" in { @@ -120,33 +120,39 @@ class BundleSpec extends ChiselFlatSpec with BundleSpecUtils with Utils { } (the[ChiselException] thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - val io = IO(Output(new AliasedBundle)) - io.a := 0.U - io.b := 1.U - } } + ChiselStage.elaborate { + new Module { + val io = IO(Output(new AliasedBundle)) + io.a := 0.U + io.b := 1.U + } + } }).getMessage should include("contains aliased fields named (a,b),(c,d)") } "Bundles" should "not have bound hardware" in { (the[ChiselException] thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - class MyBundle(val foo: UInt) extends Bundle - val in = IO(Input(new MyBundle(123.U))) // This should error: value passed in instead of type - val out = IO(Output(new MyBundle(UInt(8.W)))) + ChiselStage.elaborate { + new Module { + class MyBundle(val foo: UInt) extends Bundle + val in = IO(Input(new MyBundle(123.U))) // This should error: value passed in instead of type + val out = IO(Output(new MyBundle(UInt(8.W)))) - out := in - } } + out := in + } + } }).getMessage should include("must be a Chisel type, not hardware") } "Bundles" should "not recursively contain aggregates with bound hardware" in { (the[ChiselException] thrownBy extractCause[ChiselException] { - ChiselStage.elaborate { new Module { - class MyBundle(val foo: UInt) extends Bundle - val out = IO(Output(Vec(2, UInt(8.W)))) - val in = IO(Input(new MyBundle(out(0)))) // This should error: Bound aggregate passed - out := in - } } + ChiselStage.elaborate { + new Module { + class MyBundle(val foo: UInt) extends Bundle + val out = IO(Output(Vec(2, UInt(8.W)))) + val in = IO(Input(new MyBundle(out(0)))) // This should error: Bound aggregate passed + out := in + } + } }).getMessage should include("must be a Chisel type, not hardware") } "Unbound bundles sharing a field" should "not error" in { diff --git a/src/test/scala/chiselTests/BundleWire.scala b/src/test/scala/chiselTests/BundleWire.scala index 830fb7e4..3b58d52a 100644 --- a/src/test/scala/chiselTests/BundleWire.scala +++ b/src/test/scala/chiselTests/BundleWire.scala @@ -11,12 +11,12 @@ class Coord extends Bundle { class BundleWire(n: Int) extends Module { val io = IO(new Bundle { - val in = Input(new Coord) + val in = Input(new Coord) val outs = Output(Vec(n, new Coord)) }) val coords = Wire(Vec(n, new Coord)) for (i <- 0 until n) { - coords(i) := io.in + coords(i) := io.in io.outs(i) := coords(i) } } @@ -57,14 +57,13 @@ class BundleWireSpec extends ChiselPropSpec { property("All vec elems should match the inputs") { forAll(vecSizes, safeUInts, safeUInts) { (n: Int, x: Int, y: Int) => - assertTesterPasses{ new BundleWireTester(n, x, y) } + assertTesterPasses { new BundleWireTester(n, x, y) } } } } class BundleToUIntSpec extends ChiselPropSpec { property("Bundles with same data but different, underlying elements should compare as UInt") { - assertTesterPasses( new BundleToUnitTester ) + assertTesterPasses(new BundleToUnitTester) } } - diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index 8647d903..6f560b94 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -4,7 +4,12 @@ package chiselTests import chisel3._ import chisel3.aop.Aspect -import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage, NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation} +import chisel3.stage.{ + ChiselGeneratorAnnotation, + ChiselStage, + NoRunFirrtlCompilerAnnotation, + PrintFullStackTraceAnnotation +} import chisel3.testers._ import firrtl.annotations.Annotation import firrtl.ir.Circuit @@ -27,26 +32,29 @@ import scala.reflect.ClassTag /** Common utility functions for Chisel unit tests. */ trait ChiselRunners extends Assertions with BackendCompilationUtilities { - def runTester(t: => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq() - ): Boolean = { + def runTester( + t: => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq() + ): Boolean = { // Change this to enable Treadle as a backend val defaultBackend = chisel3.testers.TesterDriver.defaultBackend val hasBackend = TestUtils.containsBackend(annotations) val annos: Seq[Annotation] = if (hasBackend) annotations else defaultBackend +: annotations TesterDriver.execute(() => t, additionalVResources, annos) } - def assertTesterPasses(t: => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: AnnotationSeq = Seq() - ): Unit = { + def assertTesterPasses( + t: => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: AnnotationSeq = Seq() + ): Unit = { assert(runTester(t, additionalVResources, annotations)) } - def assertTesterFails(t: => BasicTester, - additionalVResources: Seq[String] = Seq(), - annotations: Seq[chisel3.aop.Aspect[_]] = Seq() - ): Unit = { + def assertTesterFails( + t: => BasicTester, + additionalVResources: Seq[String] = Seq(), + annotations: Seq[chisel3.aop.Aspect[_]] = Seq() + ): Unit = { assert(!runTester(t, additionalVResources, annotations)) } @@ -57,7 +65,7 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { // Sanity check that firrtl doesn't change the width x := 0.U.asTypeOf(chiselTypeOf(x)) val (_, done) = chisel3.util.Counter(true.B, 2) - when (done) { + when(done) { chisel3.assert(~(x.asUInt) === -1.S(expected.W).asUInt) stop() } @@ -70,7 +78,7 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { assert(!x.isWidthKnown, s"Asserting that width should be inferred yet width is known to Chisel!") x := 0.U.asTypeOf(chiselTypeOf(x)) val (_, done) = chisel3.util.Counter(true.B, 2) - when (done) { + when(done) { chisel3.assert(~(x.asUInt) === -1.S(expected.W).asUInt) stop() } @@ -84,11 +92,14 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { */ def compile(t: => RawModule): String = { (new ChiselStage) - .execute(Array("--target-dir", createTestDirectory(this.getClass.getSimpleName).toString), - Seq(ChiselGeneratorAnnotation(() => t))) + .execute( + Array("--target-dir", createTestDirectory(this.getClass.getSimpleName).toString), + Seq(ChiselGeneratorAnnotation(() => t)) + ) .collectFirst { case EmittedVerilogCircuitAnnotation(a) => a.value - }.getOrElse(fail("No Verilog circuit was emitted by the FIRRTL compiler!")) + } + .getOrElse(fail("No Verilog circuit was emitted by the FIRRTL compiler!")) } def elaborateAndGetModule[A <: RawModule](t: => A): A = { @@ -147,9 +158,9 @@ abstract class ChiselPropSpec extends AnyPropSpec with ChiselRunners with ScalaC n <- Gen.choose(1, 10) } yield { if (dir) { - Range(m, (m+n)*step, step) + Range(m, (m + n) * step, step) } else { - Range((m+n)*step, m, -step) + Range((m + n) * step, m, -step) } } @@ -185,7 +196,7 @@ abstract class ChiselPropSpec extends AnyPropSpec with ChiselRunners with ScalaC w <- smallPosInts i <- Gen.containerOfN[List, Int](n, Gen.choose(0, (1 << w) - 1)) j <- Gen.containerOfN[List, Int](n, Gen.choose(0, (1 << w) - 1)) - } yield (w, i zip j) + } yield (w, i.zip(j)) // Generator which gives a width w and a pair of numbers up to w bits. val safeUIntPair = for { @@ -291,7 +302,6 @@ trait Utils { } } - /** A tester which runs generator and uses an aspect to check the returned object * @param gen function to generate a Chisel module * @param f a function to check the Chisel module @@ -300,14 +310,16 @@ trait Utils { def aspectTest[T <: RawModule](gen: () => T)(f: T => Unit)(implicit scalaMajorVersion: Int): Unit = { // Runs chisel stage def run[T <: RawModule](gen: () => T, annotations: AnnotationSeq): AnnotationSeq = { - new ChiselStage().run(Seq(ChiselGeneratorAnnotation(gen), NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation) ++ annotations) + new ChiselStage().run( + Seq(ChiselGeneratorAnnotation(gen), NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation) ++ annotations + ) } // Creates a wrapping aspect to contain checking function case object BuiltAspect extends Aspect[T] { - override def toAnnotation(top: T): AnnotationSeq = {f(top); Nil} + override def toAnnotation(top: T): AnnotationSeq = { f(top); Nil } } val currentMajorVersion = scala.util.Properties.versionNumberString.split('.')(1).toInt - if(currentMajorVersion >= scalaMajorVersion) { + if (currentMajorVersion >= scalaMajorVersion) { run(gen, Seq(BuiltAspect)) } } @@ -326,25 +338,27 @@ trait Utils { * @tparam A the type of the exception to extract * @return nothing */ - def extractCause[A <: Throwable : ClassTag](thunk: => Any): Unit = { + def extractCause[A <: Throwable: ClassTag](thunk: => Any): Unit = { def unrollCauses(a: Throwable): Seq[Throwable] = a match { case null => Seq.empty case _ => a +: unrollCauses(a.getCause) } - val exceptions: Seq[_ <: Throwable] = try { - thunk - Seq.empty - } catch { - case a: Throwable => unrollCauses(a) - } + val exceptions: Seq[_ <: Throwable] = + try { + thunk + Seq.empty + } catch { + case a: Throwable => unrollCauses(a) + } - exceptions.collectFirst{ case a: A => a } match { + exceptions.collectFirst { case a: A => a } match { case Some(a) => throw a - case None => exceptions match { - case Nil => () - case h :: t => throw h - } + case None => + exceptions match { + case Nil => () + case h :: t => throw h + } } } diff --git a/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala b/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala index 40358d11..451ba885 100644 --- a/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala +++ b/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala @@ -38,7 +38,7 @@ class ChiselTestUtilitiesSpec extends ChiselFlatSpec { } it should "error if the expected width is wrong" in { - a [TestFailedException] shouldBe thrownBy { + a[TestFailedException] shouldBe thrownBy { assertInferredWidth(8) { val w = Wire(UInt()) w := 2.U(2.W) diff --git a/src/test/scala/chiselTests/Clock.scala b/src/test/scala/chiselTests/Clock.scala index 3eb949fb..c28e1344 100644 --- a/src/test/scala/chiselTests/Clock.scala +++ b/src/test/scala/chiselTests/Clock.scala @@ -24,7 +24,6 @@ class WithClockAndNoReset extends RawModule { out := a } - class ClockSpec extends ChiselPropSpec { property("Bool.asClock.asUInt should pass a signal through unaltered") { assertTesterPasses { new ClockAsUIntTester } @@ -32,6 +31,6 @@ class ClockSpec extends ChiselPropSpec { property("Should be able to use withClock in a module with no reset") { val circuit = ChiselStage.emitChirrtl(new WithClockAndNoReset) - circuit.contains("reg a : UInt<1>, clock2") should be (true) + circuit.contains("reg a : UInt<1>, clock2") should be(true) } } diff --git a/src/test/scala/chiselTests/CloneModuleSpec.scala b/src/test/scala/chiselTests/CloneModuleSpec.scala index 8359bc28..4a70db85 100644 --- a/src/test/scala/chiselTests/CloneModuleSpec.scala +++ b/src/test/scala/chiselTests/CloneModuleSpec.scala @@ -4,7 +4,7 @@ package chiselTests import chisel3._ import chisel3.stage.ChiselStage -import chisel3.util.{Decoupled, Queue, EnqIO, DeqIO, QueueIO, log2Ceil} +import chisel3.util.{log2Ceil, Decoupled, DeqIO, EnqIO, Queue, QueueIO} import chisel3.experimental.{CloneModuleAsRecord, IO} import chisel3.testers.BasicTester @@ -51,7 +51,7 @@ class QueueCloneTester(x: Int, multiIO: Boolean = false) extends BasicTester { dut.io.enq.bits := x.U dut.io.enq.valid := start dut.io.deq.ready := accept - when (dut.io.deq.fire) { + when(dut.io.deq.fire) { assert(dut.io.deq.bits === x.U) stop() } @@ -80,14 +80,15 @@ class CloneModuleAsRecordAnnotate extends Module { class CloneModuleSpec extends ChiselPropSpec { val xVals = Table( - ("x"), // First tuple defines column names - (42), // Subsequent tuples define the data + ("x"), // First tuple defines column names + (42), // Subsequent tuples define the data (63), - (99)) + (99) + ) property("QueueCloneTester should return the correct result") { - forAll (xVals) { (x: Int) => - assertTesterPasses{ new QueueCloneTester(x) } + forAll(xVals) { (x: Int) => + assertTesterPasses { new QueueCloneTester(x) } } } @@ -97,13 +98,13 @@ class CloneModuleSpec extends ChiselPropSpec { } property("Clone of MultiIOModule should simulate correctly") { - forAll (xVals) { (x: Int) => - assertTesterPasses{ new QueueCloneTester(x, multiIO=true) } + forAll(xVals) { (x: Int) => + assertTesterPasses { new QueueCloneTester(x, multiIO = true) } } } property("Clones of MultiIOModules should share the same module") { - val c = ChiselStage.convert(new QueueClone(multiIO=true)) + val c = ChiselStage.convert(new QueueClone(multiIO = true)) assert(c.modules.length == 3) } @@ -116,39 +117,39 @@ class CloneModuleSpec extends ChiselPropSpec { } // ********** Checking the output of CloneModuleAsRecord ********** // Note that we overrode desiredName so that Top is named "Top" - mod.q1.io.enq.toTarget.serialize should be ("~Top|Queue>io.enq") - mod.q2_io.deq.toTarget.serialize should be ("~Top|Queue>io.deq") - mod.q1.io.enq.toAbsoluteTarget.serialize should be ("~Top|Top/q1:Queue>io.enq") - mod.q2_io.deq.toAbsoluteTarget.serialize should be ("~Top|Top/q2:Queue>io.deq") + mod.q1.io.enq.toTarget.serialize should be("~Top|Queue>io.enq") + mod.q2_io.deq.toTarget.serialize should be("~Top|Queue>io.deq") + mod.q1.io.enq.toAbsoluteTarget.serialize should be("~Top|Top/q1:Queue>io.enq") + mod.q2_io.deq.toAbsoluteTarget.serialize should be("~Top|Top/q2:Queue>io.deq") // Legacy APIs that nevertheless were tricky to get right - mod.q1.io.enq.toNamed.serialize should be ("Top.Queue.io.enq") - mod.q2_io.deq.toNamed.serialize should be ("Top.Queue.io.deq") - mod.q1.io.enq.instanceName should be ("io.enq") - mod.q2_io.deq.instanceName should be ("io.deq") - mod.q1.io.enq.pathName should be ("Top.q1.io.enq") - mod.q2_io.deq.pathName should be ("Top.q2.io.deq") - mod.q1.io.enq.parentPathName should be ("Top.q1") - mod.q2_io.deq.parentPathName should be ("Top.q2") - mod.q1.io.enq.parentModName should be ("Queue") - mod.q2_io.deq.parentModName should be ("Queue") + mod.q1.io.enq.toNamed.serialize should be("Top.Queue.io.enq") + mod.q2_io.deq.toNamed.serialize should be("Top.Queue.io.deq") + mod.q1.io.enq.instanceName should be("io.enq") + mod.q2_io.deq.instanceName should be("io.deq") + mod.q1.io.enq.pathName should be("Top.q1.io.enq") + mod.q2_io.deq.pathName should be("Top.q2.io.deq") + mod.q1.io.enq.parentPathName should be("Top.q1") + mod.q2_io.deq.parentPathName should be("Top.q2") + mod.q1.io.enq.parentModName should be("Queue") + mod.q2_io.deq.parentModName should be("Queue") // ********** Checking the wire cloned from the output of CloneModuleAsRecord ********** val wire_io = mod.q2_wire("io").asInstanceOf[QueueIO[UInt]] - mod.q2_wire.toTarget.serialize should be ("~Top|Top>q2_wire") - wire_io.enq.toTarget.serialize should be ("~Top|Top>q2_wire.io.enq") - mod.q2_wire.toAbsoluteTarget.serialize should be ("~Top|Top>q2_wire") - wire_io.enq.toAbsoluteTarget.serialize should be ("~Top|Top>q2_wire.io.enq") + mod.q2_wire.toTarget.serialize should be("~Top|Top>q2_wire") + wire_io.enq.toTarget.serialize should be("~Top|Top>q2_wire.io.enq") + mod.q2_wire.toAbsoluteTarget.serialize should be("~Top|Top>q2_wire") + wire_io.enq.toAbsoluteTarget.serialize should be("~Top|Top>q2_wire.io.enq") // Legacy APIs - mod.q2_wire.toNamed.serialize should be ("Top.Top.q2_wire") - wire_io.enq.toNamed.serialize should be ("Top.Top.q2_wire.io.enq") - mod.q2_wire.instanceName should be ("q2_wire") - wire_io.enq.instanceName should be ("q2_wire.io.enq") - mod.q2_wire.pathName should be ("Top.q2_wire") - wire_io.enq.pathName should be ("Top.q2_wire.io.enq") - mod.q2_wire.parentPathName should be ("Top") - wire_io.enq.parentPathName should be ("Top") - mod.q2_wire.parentModName should be ("Top") - wire_io.enq.parentModName should be ("Top") + mod.q2_wire.toNamed.serialize should be("Top.Top.q2_wire") + wire_io.enq.toNamed.serialize should be("Top.Top.q2_wire.io.enq") + mod.q2_wire.instanceName should be("q2_wire") + wire_io.enq.instanceName should be("q2_wire.io.enq") + mod.q2_wire.pathName should be("Top.q2_wire") + wire_io.enq.pathName should be("Top.q2_wire.io.enq") + mod.q2_wire.parentPathName should be("Top") + wire_io.enq.parentPathName should be("Top") + mod.q2_wire.parentModName should be("Top") + wire_io.enq.parentModName should be("Top") } } diff --git a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala index 4b03dfa5..8210b120 100644 --- a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala +++ b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala @@ -114,7 +114,6 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec { }) } - "Bundles defined in Chisel._" should "work in chisel3._ Modules" in { import chisel3._ import chisel3.testers.BasicTester @@ -153,9 +152,8 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec { }) } - "Similar Bundles defined in the chisel3._ and Chisel._" should - "successfully bulk connect in chisel3._" in { + "successfully bulk connect in chisel3._" in { import chisel3._ import chisel3.testers.BasicTester import Chisel3Components._ @@ -227,12 +225,11 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec { val cond = Bool(INPUT) val out = UInt(OUTPUT, width = 32) } - val children = Seq(Module(new PassthroughModule), - Module(new PassthroughMultiIOModule), - Module(new PassthroughRawModule)) + val children = + Seq(Module(new PassthroughModule), Module(new PassthroughMultiIOModule), Module(new PassthroughRawModule)) io.out := children.map(_.io.out).reduce(_ + _) children.foreach { child => - when (io.cond) { + when(io.cond) { child.io.in := io.in } } @@ -355,4 +352,3 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec { compile(new Top(false)) } } - diff --git a/src/test/scala/chiselTests/CompatibilitySpec.scala b/src/test/scala/chiselTests/CompatibilitySpec.scala index 7ac67b7c..d134c380 100644 --- a/src/test/scala/chiselTests/CompatibilitySpec.scala +++ b/src/test/scala/chiselTests/CompatibilitySpec.scala @@ -23,7 +23,7 @@ object CompatibilityCustomCompileOptions { class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyChecks with Utils { import Chisel._ - behavior of "Chisel compatibility layer" + behavior.of("Chisel compatibility layer") it should "accept direction arguments" in { ChiselStage.elaborate(new Module { @@ -39,10 +39,10 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val b = Bool(directionArgument) val u = UInt(directionArgument, width) } - io.b shouldBe a [Bool] + io.b shouldBe a[Bool] io.b.getWidth shouldEqual 1 io.b.dir shouldEqual (expectedDirection) - io.u shouldBe a [UInt] + io.u shouldBe a[UInt] io.u.getWidth shouldEqual width io.u.dir shouldEqual (expectedDirection) }) @@ -52,7 +52,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck // Choose a random value val value: Int = Gen.choose(0, Int.MaxValue).sample.get val l = UInt(value) - l shouldBe a [UInt] + l shouldBe a[UInt] l shouldBe 'lit l.getWidth shouldEqual BigInt(value).bitLength l.litValue() shouldEqual value @@ -60,9 +60,10 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck it should "map utility objects into the package object" in { val value: Int = Gen.choose(2, 2048).sample.get - log2Up(value) shouldBe (1 max BigInt(value - 1).bitLength) + log2Up(value) shouldBe (1.max(BigInt(value - 1).bitLength)) log2Ceil(value) shouldBe (BigInt(value - 1).bitLength) - log2Down(value) shouldBe ((1 max BigInt(value - 1).bitLength) - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) + log2Down(value) shouldBe ((1.max(BigInt(value - 1).bitLength)) - (if (value > 0 && ((value & (value - 1)) == 0)) 0 + else 1)) log2Floor(value) shouldBe (BigInt(value - 1).bitLength - (if (value > 0 && ((value & (value - 1)) == 0)) 0 else 1)) isPow2(BigInt(1) << value) shouldBe true isPow2((BigInt(1) << value) - 1) shouldBe false @@ -76,7 +77,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck bs(maskPosition) = '?' val bitPatString = bs.toString val bp = BitPat("b" + bitPatString) - bp shouldBe a [BitPat] + bp shouldBe a[BitPat] bp.getWidth shouldEqual binaryString.length } @@ -87,92 +88,92 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val io = new Bundle {} val data = UInt(width = 3) val wire = Wire(data) - new ArbiterIO(data, 2) shouldBe a [ArbiterIO[UInt]] - Module(new LockingRRArbiter(data, 2, 2, None)) shouldBe a [LockingRRArbiter[UInt]] - Module(new RRArbiter(data, 2)) shouldBe a [RRArbiter[UInt]] - Module(new Arbiter(data, 2)) shouldBe a [Arbiter[UInt]] - new Counter(2) shouldBe a [Counter] - new ValidIO(data) shouldBe a [ValidIO[UInt]] - new DecoupledIO(data) shouldBe a [DecoupledIO[UInt]] - new QueueIO(data, 2) shouldBe a [QueueIO[UInt]] - Module(new Pipe(data, 2)) shouldBe a [Pipe[UInt]] - - FillInterleaved(2, wire) shouldBe a [UInt] - PopCount(wire) shouldBe a [UInt] - Fill(2, wire) shouldBe a [UInt] - Reverse(wire) shouldBe a [UInt] - Cat(wire, wire) shouldBe a [UInt] - Log2(wire) shouldBe a [UInt] + new ArbiterIO(data, 2) shouldBe a[ArbiterIO[UInt]] + Module(new LockingRRArbiter(data, 2, 2, None)) shouldBe a[LockingRRArbiter[UInt]] + Module(new RRArbiter(data, 2)) shouldBe a[RRArbiter[UInt]] + Module(new Arbiter(data, 2)) shouldBe a[Arbiter[UInt]] + new Counter(2) shouldBe a[Counter] + new ValidIO(data) shouldBe a[ValidIO[UInt]] + new DecoupledIO(data) shouldBe a[DecoupledIO[UInt]] + new QueueIO(data, 2) shouldBe a[QueueIO[UInt]] + Module(new Pipe(data, 2)) shouldBe a[Pipe[UInt]] + + FillInterleaved(2, wire) shouldBe a[UInt] + PopCount(wire) shouldBe a[UInt] + Fill(2, wire) shouldBe a[UInt] + Reverse(wire) shouldBe a[UInt] + Cat(wire, wire) shouldBe a[UInt] + Log2(wire) shouldBe a[UInt] // 'switch' and 'is' are tested below in Risc - Counter(2) shouldBe a [Counter] - DecoupledIO(wire) shouldBe a [DecoupledIO[UInt]] + Counter(2) shouldBe a[Counter] + DecoupledIO(wire) shouldBe a[DecoupledIO[UInt]] val dcd = Wire(Decoupled(data)) - dcd shouldBe a [DecoupledIO[UInt]] - Queue(dcd) shouldBe a [DecoupledIO[UInt]] - Queue(dcd, 0) shouldBe a [DecoupledIO[UInt]] - Enum(UInt(), 2) shouldBe a [List[UInt]] - ListLookup(wire, List(wire), Array((BitPat("b1"), List(wire)))) shouldBe a [List[UInt]] - Lookup(wire, wire, Seq((BitPat("b1"), wire))) shouldBe a [UInt] - Mux1H(wire, Seq(wire)) shouldBe a [UInt] - PriorityMux(Seq(Bool(false)), Seq(data)) shouldBe a [UInt] - MuxLookup(wire, wire, Seq((wire, wire))) shouldBe a [UInt] - MuxCase(wire, Seq((Bool(true), wire))) shouldBe a [UInt] - OHToUInt(wire) shouldBe a [UInt] - PriorityEncoder(wire) shouldBe a [UInt] - UIntToOH(wire) shouldBe a [UInt] - PriorityEncoderOH(wire) shouldBe a [UInt] - RegNext(wire) shouldBe a [UInt] - RegInit(wire) shouldBe a [UInt] - RegEnable(wire, Bool(true)) shouldBe a [UInt] - ShiftRegister(wire, 2) shouldBe a [UInt] - Valid(data) shouldBe a [ValidIO[UInt]] - Pipe(Wire(Valid(data)), 2) shouldBe a [ValidIO[UInt]] + dcd shouldBe a[DecoupledIO[UInt]] + Queue(dcd) shouldBe a[DecoupledIO[UInt]] + Queue(dcd, 0) shouldBe a[DecoupledIO[UInt]] + Enum(UInt(), 2) shouldBe a[List[UInt]] + ListLookup(wire, List(wire), Array((BitPat("b1"), List(wire)))) shouldBe a[List[UInt]] + Lookup(wire, wire, Seq((BitPat("b1"), wire))) shouldBe a[UInt] + Mux1H(wire, Seq(wire)) shouldBe a[UInt] + PriorityMux(Seq(Bool(false)), Seq(data)) shouldBe a[UInt] + MuxLookup(wire, wire, Seq((wire, wire))) shouldBe a[UInt] + MuxCase(wire, Seq((Bool(true), wire))) shouldBe a[UInt] + OHToUInt(wire) shouldBe a[UInt] + PriorityEncoder(wire) shouldBe a[UInt] + UIntToOH(wire) shouldBe a[UInt] + PriorityEncoderOH(wire) shouldBe a[UInt] + RegNext(wire) shouldBe a[UInt] + RegInit(wire) shouldBe a[UInt] + RegEnable(wire, Bool(true)) shouldBe a[UInt] + ShiftRegister(wire, 2) shouldBe a[UInt] + Valid(data) shouldBe a[ValidIO[UInt]] + Pipe(Wire(Valid(data)), 2) shouldBe a[ValidIO[UInt]] } ChiselStage.elaborate { new Dummy } } // Verify we can elaborate a design expressed in Chisel2 class Chisel2CompatibleRisc extends Module { val io = new Bundle { - val isWr = Bool(INPUT) + val isWr = Bool(INPUT) val wrAddr = UInt(INPUT, 8) val wrData = Bits(INPUT, 32) - val boot = Bool(INPUT) - val valid = Bool(OUTPUT) - val out = Bits(OUTPUT, 32) + val boot = Bool(INPUT) + val valid = Bool(OUTPUT) + val out = Bits(OUTPUT, 32) } val file = Mem(256, Bits(width = 32)) val code = Mem(256, Bits(width = 32)) - val pc = Reg(init=UInt(0, 8)) + val pc = Reg(init = UInt(0, 8)) val add_op :: imm_op :: Nil = Enum(2) val inst = code(pc) - val op = inst(31,24) - val rci = inst(23,16) - val rai = inst(15, 8) - val rbi = inst( 7, 0) + val op = inst(31, 24) + val rci = inst(23, 16) + val rai = inst(15, 8) + val rbi = inst(7, 0) val ra = Mux(rai === Bits(0), Bits(0), file(rai)) val rb = Mux(rbi === Bits(0), Bits(0), file(rbi)) val rc = Wire(Bits(width = 32)) io.valid := Bool(false) - io.out := Bits(0) - rc := Bits(0) + io.out := Bits(0) + rc := Bits(0) - when (io.isWr) { + when(io.isWr) { code(io.wrAddr) := io.wrData - } .elsewhen (io.boot) { + }.elsewhen(io.boot) { pc := UInt(0) - } .otherwise { + }.otherwise { switch(op) { is(add_op) { rc := ra +% rb } is(imm_op) { rc := (rai << 8) | rbi } } io.out := rc - when (rci === UInt(255)) { + when(rci === UInt(255)) { io.valid := Bool(true) - } .otherwise { + }.otherwise { file(rci) := rc } pc := pc +% UInt(1) @@ -191,7 +192,6 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck }) } - class SmallBundle extends Bundle { val f1 = UInt(width = 4) val f2 = UInt(width = 5) @@ -219,7 +219,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck val in = (new SmallBundle).asInput val out = (new BigBundle).asOutput } - val badReg = Reg(UInt(7, width=4)) + val badReg = Reg(UInt(7, width = 4)) } ChiselStage.elaborate { new CreateRegFromBoundTypeModule() } } @@ -302,9 +302,9 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck // Note: This is a regression (see https://github.com/freechipsproject/chisel3/issues/668) it should "fail for Chisel types" in { import Chisel._ - an [chisel3.ExpectedHardwareException] should be thrownBy extractCause[chisel3.ExpectedHardwareException] { + an[chisel3.ExpectedHardwareException] should be thrownBy extractCause[chisel3.ExpectedHardwareException] { ChiselStage.elaborate(new Module { - val io = new Bundle { } + val io = new Bundle {} UInt(INPUT).dir }) } @@ -342,11 +342,11 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck }) } - behavior of "BitPat" + behavior.of("BitPat") it should "support old operators" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("Deprecated method DC hasn't been removed") val bp = BitPat.DC(4) @@ -355,34 +355,34 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck ChiselStage.elaborate(new Foo) } - behavior of "Enum" + behavior.of("Enum") it should "support apply[T <: Bits](nodeType: T, n: Int): List[T]" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("works for a UInt") - Enum(UInt(), 4) shouldBe a [List[UInt]] + Enum(UInt(), 4) shouldBe a[List[UInt]] info("throw an exception for non-UInt types") - intercept [IllegalArgumentException] { + intercept[IllegalArgumentException] { Enum(SInt(), 4) - }.getMessage should include ("Only UInt supported for enums") + }.getMessage should include("Only UInt supported for enums") info("throw an exception if the bit width is specified") - intercept [IllegalArgumentException] { + intercept[IllegalArgumentException] { Enum(UInt(width = 8), 4) - }.getMessage should include ("Bit width may no longer be specified for enums") + }.getMessage should include("Bit width may no longer be specified for enums") } ChiselStage.elaborate(new Foo) } - behavior of "Queue" + behavior.of("Queue") it should "support deprecated constructors" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("reset: Option[Bool] constructor works") val option = Module(new Queue(UInt(), 4, false, false, Some(Bool(true)))) @@ -394,56 +394,56 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck ChiselStage.elaborate(new Foo) } - behavior of "LFSR16" + behavior.of("LFSR16") it should "still exist" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("Still exists") val lfsr = LFSR16() info("apply method returns a UInt") - lfsr shouldBe a [UInt] + lfsr shouldBe a[UInt] info("returned UInt has a width of 16") - lfsr.getWidth should be (16) + lfsr.getWidth should be(16) } ChiselStage.elaborate(new Foo) } - behavior of "Mem" + behavior.of("Mem") it should "support deprecated apply methods" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("apply[T <: Data](t: T, size: BigInt): Mem[T] works") val memBigInt = Mem(UInt(), 8: BigInt) - memBigInt shouldBe a [Mem[UInt]] + memBigInt shouldBe a[Mem[UInt]] info("apply[T <: Data](t: T, size: Int): Mem[T] works") val memInt = Mem(SInt(), 16: Int) - memInt shouldBe a [Mem[SInt]] + memInt shouldBe a[Mem[SInt]] } ChiselStage.elaborate(new Foo) } - behavior of "SeqMem" + behavior.of("SeqMem") it should "support deprecated apply methods" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("apply[T <: Data](t: T, size: BigInt): SeqMem[T] works") val seqMemBigInt = SeqMem(UInt(), 8: BigInt) - seqMemBigInt shouldBe a [SeqMem[UInt]] + seqMemBigInt shouldBe a[SeqMem[UInt]] info("apply[T <: Data](t: T, size: Int): SeqMem[T] works") val seqMemInt = SeqMem(UInt(), 16: Int) - seqMemInt shouldBe a [SeqMem[UInt]] + seqMemInt shouldBe a[SeqMem[UInt]] } ChiselStage.elaborate(new Foo) @@ -461,11 +461,11 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck ChiselStage.elaborate((new Foo)) } - behavior of "debug" + behavior.of("debug") it should "still exist" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) val data = UInt(width = 2) debug(data) @@ -474,35 +474,35 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck ChiselStage.elaborate(new Foo) } - behavior of "Data methods" + behavior.of("Data methods") - behavior of "Wire" + behavior.of("Wire") it should "support legacy methods" in { class Foo extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) info("apply[T <: Data](dummy: Int = 0, init: T): T works") - val first = Wire(init=UInt("hdeadbeef")) - first shouldBe a [UInt] + val first = Wire(init = UInt("hdeadbeef")) + first shouldBe a[UInt] info("apply[T <: Data](t: T, init: T): T works") val second = Wire(SInt(), SInt(-100)) - second shouldBe a [SInt] + second shouldBe a[SInt] info("apply[T <: Data](t: T, init: DontCare.type): T works") val third = Wire(UInt(), chisel3.DontCare) - third shouldBe a [UInt] + third shouldBe a[UInt] } ChiselStage.elaborate(new Foo) } - behavior of "Vec" + behavior.of("Vec") it should "support legacy methods" in { class Foo extends BasicTester { - val seq = Seq(Wire(UInt(0, width=4)), Wire(UInt(1, width=4)), Wire(UInt(2, width=4))) + val seq = Seq(Wire(UInt(0, width = 4)), Wire(UInt(1, width = 4)), Wire(UInt(2, width = 4))) val vec = Vec(seq) info("read works") @@ -513,32 +513,32 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck chisel3.assert(vec.read(UInt(1)) === UInt(3)) val (_, done) = Counter(Bool(true), 4) - when (done) { stop } + when(done) { stop } } assertTesterPasses(new Foo) } - behavior of "Bits methods" + behavior.of("Bits methods") it should "support legacy methods" in { class Foo extends Module { - val io = new Bundle{} + val io = new Bundle {} val u = UInt(8) val s = SInt(-4) info("asBits works") - s.asBits shouldBe a [Bits] + s.asBits shouldBe a[Bits] info("toSInt works") - u.toSInt shouldBe a [SInt] + u.toSInt shouldBe a[SInt] info("toUInt works") - s.toUInt shouldBe a [UInt] + s.toUInt shouldBe a[UInt] info("toBools works") - s.toBools shouldBe a [Seq[Bool]] + s.toBools shouldBe a[Seq[Bool]] } ChiselStage.elaborate(new Foo) @@ -547,8 +547,8 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck it should "properly propagate custom compileOptions in Chisel.Module" in { import CompatibilityCustomCompileOptions._ var result: Foo = null - ChiselStage.elaborate({result = new Foo; result}) - result.compileOptions should be theSameInstanceAs (customCompileOptions) + ChiselStage.elaborate({ result = new Foo; result }) + (result.compileOptions should be).theSameInstanceAs(customCompileOptions) } it should "properly set the refs of Records" in { @@ -564,7 +564,7 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck } val verilog = ChiselStage.emitVerilog(new Foo) // Check that the names are correct (and that the FIRRTL is valid) - verilog should include ("assign io_out_0 = io_in_0;") + verilog should include("assign io_out_0 = io_in_0;") } it should "ignore .suggestName on field io" in { @@ -577,8 +577,8 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck io.bar := io.foo } val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("input [7:0] io_foo") - verilog should include ("output [7:0] io_bar") + verilog should include("input [7:0] io_foo") + verilog should include("output [7:0] io_bar") } it should "properly name field io" in { @@ -591,8 +591,8 @@ class CompatibiltySpec extends ChiselFlatSpec with ScalaCheckDrivenPropertyCheck io.bar := wire } val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("input [7:0] io_foo") - verilog should include ("output [7:0] io_bar") + verilog should include("input [7:0] io_foo") + verilog should include("output [7:0] io_bar") } } diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala index 1ecf97f0..3ec59954 100644 --- a/src/test/scala/chiselTests/CompileOptionsTest.scala +++ b/src/test/scala/chiselTests/CompileOptionsTest.scala @@ -20,7 +20,7 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils { } "A Module with missing bundle fields when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { import chisel3.ExplicitCompileOptions.Strict class ConnectFieldMismatchModule extends Module { @@ -48,7 +48,7 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils { } "A Module in which a Reg is created with a bound type when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [BindingException] should be thrownBy extractCause[BindingException] { + a[BindingException] should be thrownBy extractCause[BindingException] { import chisel3.ExplicitCompileOptions.Strict class CreateRegFromBoundTypeModule extends Module { @@ -89,7 +89,7 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils { } "A Module with unwrapped IO when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [BindingException] should be thrownBy extractCause[BindingException] { + a[BindingException] should be thrownBy extractCause[BindingException] { import chisel3.ExplicitCompileOptions.Strict class RequireIOWrapModule extends Module { @@ -106,7 +106,7 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils { } "A Module connecting output as source to input as sink when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { import chisel3.ExplicitCompileOptions.Strict class SimpleModule extends Module { @@ -140,7 +140,7 @@ class CompileOptionsSpec extends ChiselFlatSpec with Utils { } "A Module with directionless connections when compiled with implicit Strict.CompileOption " should "throw an exception" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { // Verify we can suppress the inclusion of default compileOptions import Chisel.{defaultCompileOptions => _} import chisel3.ExplicitCompileOptions.Strict diff --git a/src/test/scala/chiselTests/ComplexAssign.scala b/src/test/scala/chiselTests/ComplexAssign.scala index 222b6373..99313967 100644 --- a/src/test/scala/chiselTests/ComplexAssign.scala +++ b/src/test/scala/chiselTests/ComplexAssign.scala @@ -11,16 +11,16 @@ class Complex[T <: Data](val re: T, val im: T) extends Bundle class ComplexAssign(w: Int) extends Module { val io = IO(new Bundle { - val e = Input(Bool()) - val in = Input(new Complex(UInt(w.W), UInt(w.W))) + val e = Input(Bool()) + val in = Input(new Complex(UInt(w.W), UInt(w.W))) val out = Output(new Complex(UInt(w.W), UInt(w.W))) }) - when (io.e) { + when(io.e) { val tmp = Wire(new Complex(UInt(w.W), UInt(w.W))) tmp := io.in io.out.re := tmp.re io.out.im := tmp.im - } .otherwise { + }.otherwise { io.out.re := 0.U io.out.im := 0.U } @@ -46,7 +46,7 @@ class ComplexAssignSpec extends ChiselPropSpec { implicit val noShrinkListVal = Shrink[List[Boolean]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) forAll(enSequence(2), safeUInts, safeUInts) { (en: List[Boolean], re: Int, im: Int) => - assertTesterPasses{ new ComplexAssignTester(en, re, im) } + assertTesterPasses { new ComplexAssignTester(en, re, im) } } } } diff --git a/src/test/scala/chiselTests/ConnectSpec.scala b/src/test/scala/chiselTests/ConnectSpec.scala index f9ef5946..3a2b6d93 100644 --- a/src/test/scala/chiselTests/ConnectSpec.scala +++ b/src/test/scala/chiselTests/ConnectSpec.scala @@ -10,7 +10,7 @@ import chisel3.stage.ChiselStage import chisel3.testers.BasicTester abstract class CrossCheck extends Bundle { - val in: Data + val in: Data val out: Data } @@ -41,92 +41,120 @@ class CrossConnectTester(inType: Data, outType: Data) extends BasicTester { class ConnectSpec extends ChiselPropSpec with Utils { property("SInt := SInt should succeed") { - assertTesterPasses{ new CrossConnectTester(SInt(16.W), SInt(16.W)) } + assertTesterPasses { new CrossConnectTester(SInt(16.W), SInt(16.W)) } } property("SInt := UInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), SInt(16.W)) } + } + } } property("SInt := FixedPoint should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } + } + } } property("UInt := UInt should succeed") { - assertTesterPasses{ new CrossConnectTester(UInt(16.W), UInt(16.W)) } + assertTesterPasses { new CrossConnectTester(UInt(16.W), UInt(16.W)) } } property("UInt := SInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), UInt(16.W)) } + } + } } property("UInt := FixedPoint should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), UInt(16.W)) } + } + } } property("Clock := Clock should succeed") { - assertTesterPasses{ new CrossConnectTester(Clock(), Clock()) } + assertTesterPasses { new CrossConnectTester(Clock(), Clock()) } } property("Clock := UInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Clock(), UInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(Clock(), UInt(16.W)) } + } + } } property("FixedPoint := FixedPoint should succeed") { - assertTesterPasses{ new CrossConnectTester(FixedPoint(16.W, 8.BP), FixedPoint(16.W, 8.BP)) } + assertTesterPasses { new CrossConnectTester(FixedPoint(16.W, 8.BP), FixedPoint(16.W, 8.BP)) } } property("FixedPoint := SInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) } } } + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), FixedPoint(16.W, 8.BP)) } + } + } } property("FixedPoint := UInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) } } } + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), FixedPoint(16.W, 8.BP)) } + } + } } property("Analog := Analog should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), Analog(16.W)) } + } + } } property("Analog := FixedPoint should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) } } } + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), FixedPoint(16.W, 8.BP)) } + } + } } property("FixedPoint := Analog should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(FixedPoint(16.W, 8.BP), Analog(16.W)) } + } + } } property("Analog := UInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), UInt(16.W)) } + } + } } property("Analog := SInt should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(Analog(16.W), SInt(16.W)) } + } + } } property("UInt := Analog should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(UInt(16.W), Analog(16.W)) } + } + } } property("SInt := Analog should fail") { - intercept[ChiselException]{ + intercept[ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) } } } + ChiselStage.elaborate { new CrossConnectTester(SInt(16.W), Analog(16.W)) } + } + } } property("Pipe internal connections should succeed") { - ChiselStage.elaborate( new PipeInternalWires) + ChiselStage.elaborate(new PipeInternalWires) } property("Connect error messages should have meaningful information") { @@ -139,9 +167,9 @@ class ConnectSpec extends ChiselPropSpec with Utils { inner.myReg := false.B // ERROR } - val assignError = the [ChiselException] thrownBy {ChiselStage.elaborate { new OuterAssignExample}} + val assignError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterAssignExample } } val expectedAssignError = """.*@: myReg in InnerExample cannot be written from module OuterAssignExample.""" - assignError.getMessage should fullyMatch regex expectedAssignError + (assignError.getMessage should fullyMatch).regex(expectedAssignError) class OuterReadExample extends Module { val myReg = RegInit(0.U(8.W)) @@ -149,16 +177,20 @@ class ConnectSpec extends ChiselPropSpec with Utils { myReg := inner.myReg // ERROR } - val readError = the [ChiselException] thrownBy {ChiselStage.elaborate { new OuterReadExample }} + val readError = the[ChiselException] thrownBy { ChiselStage.elaborate { new OuterReadExample } } val expectedReadError = """.*@: myReg in InnerExample cannot be read from module OuterReadExample.""" - readError.getMessage should fullyMatch regex expectedReadError - - val typeMismatchError = the [ChiselException] thrownBy {ChiselStage.elaborate { new RawModule { - val myUInt = Wire(UInt(4.W)) - val mySInt = Wire(SInt(4.W)) - myUInt := mySInt - }}} + (readError.getMessage should fullyMatch).regex(expectedReadError) + + val typeMismatchError = the[ChiselException] thrownBy { + ChiselStage.elaborate { + new RawModule { + val myUInt = Wire(UInt(4.W)) + val mySInt = Wire(SInt(4.W)) + myUInt := mySInt + } + } + } val expectedTypeMismatchError = """.*@: Sink \(UInt<4>\) and Source \(SInt<4>\) have different types.""" - typeMismatchError.getMessage should fullyMatch regex expectedTypeMismatchError + (typeMismatchError.getMessage should fullyMatch).regex(expectedTypeMismatchError) } } diff --git a/src/test/scala/chiselTests/Counter.scala b/src/test/scala/chiselTests/Counter.scala index 121d481a..0e2a339a 100644 --- a/src/test/scala/chiselTests/Counter.scala +++ b/src/test/scala/chiselTests/Counter.scala @@ -34,7 +34,7 @@ class ResetTester(n: Int) extends BasicTester { val wasReset = RegNext(triggerReset) val (value, _) = Counter(0 until 8, reset = triggerReset) - triggerReset := value === (n-1).U + triggerReset := value === (n - 1).U when(wasReset) { assert(value === 0.U) @@ -71,20 +71,20 @@ class CounterSpec extends ChiselPropSpec { } property("Counter can be en/disabled") { - forAll(safeUInts) { (seed: Int) => whenever(seed >= 0) { assertTesterPasses{ new EnableTester(seed) } } } + forAll(safeUInts) { (seed: Int) => whenever(seed >= 0) { assertTesterPasses { new EnableTester(seed) } } } } property("Counter can be reset") { - forAll(smallPosInts) { (seed: Int) => assertTesterPasses{ new ResetTester(seed) } } + forAll(smallPosInts) { (seed: Int) => assertTesterPasses { new ResetTester(seed) } } } property("Counter should wrap") { - forAll(smallPosInts) { (max: Int) => assertTesterPasses{ new WrapTester(max) } } + forAll(smallPosInts) { (max: Int) => assertTesterPasses { new WrapTester(max) } } } property("Counter should handle a range") { forAll(posRange) { (r: Range) => - assertTesterPasses{ new RangeTester(r) } + assertTesterPasses { new RangeTester(r) } } } } diff --git a/src/test/scala/chiselTests/CustomBundle.scala b/src/test/scala/chiselTests/CustomBundle.scala index b04dcc59..ee964d2d 100644 --- a/src/test/scala/chiselTests/CustomBundle.scala +++ b/src/test/scala/chiselTests/CustomBundle.scala @@ -3,7 +3,7 @@ package chiselTests import chisel3._ -import chisel3.experimental.{DataMirror, requireIsChiselType} +import chisel3.experimental.{requireIsChiselType, DataMirror} import scala.collection.immutable.ListMap // An example of how Record might be extended @@ -11,9 +11,10 @@ import scala.collection.immutable.ListMap // it is a possible implementation of a programmatic "Bundle" // (and can by connected to MyBundle below) final class CustomBundle(elts: (String, Data)*) extends Record { - val elements = ListMap(elts map { case (field, elt) => - requireIsChiselType(elt) - field -> elt + val elements = ListMap(elts.map { + case (field, elt) => + requireIsChiselType(elt) + field -> elt }: _*) def apply(elt: String): Data = elements(elt) override def cloneType: this.type = { @@ -21,4 +22,3 @@ final class CustomBundle(elts: (String, Data)*) extends Record { (new CustomBundle(cloned: _*)).asInstanceOf[this.type] } } - diff --git a/src/test/scala/chiselTests/DataPrint.scala b/src/test/scala/chiselTests/DataPrint.scala index 7fb790a8..091722b8 100644 --- a/src/test/scala/chiselTests/DataPrint.scala +++ b/src/test/scala/chiselTests/DataPrint.scala @@ -29,30 +29,32 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { } "Data types" should "have a meaningful string representation" in { - ChiselStage.elaborate { new RawModule { - UInt().toString should be ("UInt") - UInt(8.W).toString should be ("UInt<8>") - SInt(15.W).toString should be ("SInt<15>") - Bool().toString should be ("Bool") - Clock().toString should be ("Clock") - FixedPoint(5.W, 3.BP).toString should be ("FixedPoint<5><<3>>") - Vec(3, UInt(2.W)).toString should be ("UInt<2>[3]") - EnumTest.Type().toString should be ("EnumTest") - (new BundleTest).toString should be ("BundleTest") - new Bundle { val a = UInt(8.W) }.toString should be ("AnonymousBundle") - new Bundle { val a = UInt(8.W) }.a.toString should be ("UInt<8>") - }} + ChiselStage.elaborate { + new RawModule { + UInt().toString should be("UInt") + UInt(8.W).toString should be("UInt<8>") + SInt(15.W).toString should be("SInt<15>") + Bool().toString should be("Bool") + Clock().toString should be("Clock") + FixedPoint(5.W, 3.BP).toString should be("FixedPoint<5><<3>>") + Vec(3, UInt(2.W)).toString should be("UInt<2>[3]") + EnumTest.Type().toString should be("EnumTest") + (new BundleTest).toString should be("BundleTest") + new Bundle { val a = UInt(8.W) }.toString should be("AnonymousBundle") + new Bundle { val a = UInt(8.W) }.a.toString should be("UInt<8>") + } + } } - class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes + class BoundDataModule extends Module { // not in the test to avoid anon naming suffixes Wire(UInt()).toString should be("BoundDataModule.?: Wire[UInt]") Reg(SInt()).toString should be("BoundDataModule.?: Reg[SInt]") - val io = IO(Output(Bool())) // needs a name so elaboration doesn't fail + val io = IO(Output(Bool())) // needs a name so elaboration doesn't fail io.toString should be("BoundDataModule.io: IO[Bool]") val m = Mem(4, UInt(2.W)) m(2).toString should be("BoundDataModule.?: MemPort[UInt<2>]") (2.U + 2.U).toString should be("BoundDataModule.?: OpResult[UInt<2>]") - Wire(Vec(3, UInt(2.W))).toString should be ("BoundDataModule.?: Wire[UInt<2>[3]]") + Wire(Vec(3, UInt(2.W))).toString should be("BoundDataModule.?: Wire[UInt<2>[3]]") class InnerModule extends Module { val io = IO(Output(new Bundle { @@ -60,8 +62,8 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { })) } val inner = Module(new InnerModule) - inner.clock.toString should be ("InnerModule.clock: IO[Clock]") - inner.io.a.toString should be ("InnerModule.io.a: IO[UInt<4>]") + inner.clock.toString should be("InnerModule.clock: IO[Clock]") + inner.io.a.toString should be("InnerModule.io.a: IO[UInt<4>]") class FooTypeTest extends Bundle { val foo = Vec(2, UInt(8.W)) @@ -69,7 +71,7 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { } val tpe = new FooTypeTest val fooio: FooTypeTest = IO(Input(tpe)) - fooio.foo(0).toString should be ("BoundDataModule.fooio.foo[0]: IO[UInt<8>]") + fooio.foo(0).toString should be("BoundDataModule.fooio.foo[0]: IO[UInt<8>]") class NestedBundle extends Bundle { val nestedFoo = UInt(8.W) @@ -81,10 +83,8 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { val nestedTpe = new NestedType val nestedio = IO(Input(nestedTpe)) - (nestedio.foo.nestedFoo.toString should be - ("BoundDataModule.nestedio.foo.nestedFoo: IO[UInt<8>]")) - (nestedio.foo.nestedFooVec(0).toString should be - ("BoundDataModule.nestedio.foo.nestedFooVec[0]: IO[UInt<8>]")) + (nestedio.foo.nestedFoo.toString should be("BoundDataModule.nestedio.foo.nestedFoo: IO[UInt<8>]")) + (nestedio.foo.nestedFooVec(0).toString should be("BoundDataModule.nestedio.foo.nestedFooVec[0]: IO[UInt<8>]")) } "Bound data types" should "have a meaningful string representation" in { @@ -92,21 +92,25 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers { } "Literals" should "have a meaningful string representation" in { - ChiselStage.elaborate { new RawModule { - 3.U.toString should be ("UInt<2>(3)") - 3.U(5.W).toString should be ("UInt<5>(3)") - -1.S.toString should be ("SInt<1>(-1)") - false.B.toString should be ("Bool(false)") - true.B.toString should be ("Bool(true)") - 2.25.F(6.W, 2.BP).toString should be ("FixedPoint<6><<2>>(2.25)") - -2.25.F(6.W, 2.BP).toString should be ("FixedPoint<6><<2>>(-2.25)") - Vec(3, UInt(4.W)).toString should be ("UInt<4>[3]") - EnumTest.sNone.toString should be ("EnumTest(0=sNone)") - EnumTest.sTwo.toString should be ("EnumTest(2=sTwo)") - EnumTest(1.U).toString should be ("EnumTest(1=sOne)") - (new BundleTest).Lit(_.a -> 2.U, _.b -> false.B).toString should be ("BundleTest(a=UInt<8>(2), b=Bool(false))") - (new PartialBundleTest).Lit().toString should be ("PartialBundleTest(a=UInt<8>(DontCare), b=Bool(DontCare), c=SInt<8>(DontCare), e=FixedPoint<5><<3>>(DontCare), f=EnumTest(DontCare))") - DontCare.toString should be ("DontCare()") - } } + ChiselStage.elaborate { + new RawModule { + 3.U.toString should be("UInt<2>(3)") + 3.U(5.W).toString should be("UInt<5>(3)") + -1.S.toString should be("SInt<1>(-1)") + false.B.toString should be("Bool(false)") + true.B.toString should be("Bool(true)") + 2.25.F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(2.25)") + -2.25.F(6.W, 2.BP).toString should be("FixedPoint<6><<2>>(-2.25)") + Vec(3, UInt(4.W)).toString should be("UInt<4>[3]") + EnumTest.sNone.toString should be("EnumTest(0=sNone)") + EnumTest.sTwo.toString should be("EnumTest(2=sTwo)") + EnumTest(1.U).toString should be("EnumTest(1=sOne)") + (new BundleTest).Lit(_.a -> 2.U, _.b -> false.B).toString should be("BundleTest(a=UInt<8>(2), b=Bool(false))") + (new PartialBundleTest).Lit().toString should be( + "PartialBundleTest(a=UInt<8>(DontCare), b=Bool(DontCare), c=SInt<8>(DontCare), e=FixedPoint<5><<3>>(DontCare), f=EnumTest(DontCare))" + ) + DontCare.toString should be("DontCare()") + } + } } } diff --git a/src/test/scala/chiselTests/Decoder.scala b/src/test/scala/chiselTests/Decoder.scala index d802c6ce..0c644b49 100644 --- a/src/test/scala/chiselTests/Decoder.scala +++ b/src/test/scala/chiselTests/Decoder.scala @@ -10,10 +10,10 @@ import chisel3.util._ class Decoder(bitpats: List[String]) extends Module { val io = IO(new Bundle { - val inst = Input(UInt(32.W)) + val inst = Input(UInt(32.W)) val matched = Output(Bool()) }) - io.matched := VecInit(bitpats.map(BitPat(_) === io.inst)).reduce(_||_) + io.matched := VecInit(bitpats.map(BitPat(_) === io.inst)).reduce(_ || _) } class DecoderTester(pairs: List[(String, String)]) extends BasicTester { @@ -33,10 +33,10 @@ class DecoderTester(pairs: List[(String, String)]) extends BasicTester { class DecoderSpec extends ChiselPropSpec { // Use a single Int to make both a specific instruction and a BitPat that will match it - val bitpatPair = for(seed <- Arbitrary.arbitrary[Int]) yield { + val bitpatPair = for (seed <- Arbitrary.arbitrary[Int]) yield { val rnd = new scala.util.Random(seed) val bs = seed.toBinaryString - val bp = bs.map(if(rnd.nextBoolean) _ else "?") + val bp = bs.map(if (rnd.nextBoolean) _ else "?") // The following randomly throws in white space and underscores which are legal and ignored. val bpp = bp.map { a => @@ -49,11 +49,11 @@ class DecoderSpec extends ChiselPropSpec { ("b" + bs, "b" + bpp) } - private def nPairs(n: Int) = Gen.containerOfN[List, (String,String)](n,bitpatPair) + private def nPairs(n: Int) = Gen.containerOfN[List, (String, String)](n, bitpatPair) property("BitPat wildcards should be usable in decoding") { - forAll(nPairs(4)){ (pairs: List[(String, String)]) => - assertTesterPasses{ new DecoderTester(pairs) } + forAll(nPairs(4)) { (pairs: List[(String, String)]) => + assertTesterPasses { new DecoderTester(pairs) } } } } diff --git a/src/test/scala/chiselTests/DedupSpec.scala b/src/test/scala/chiselTests/DedupSpec.scala index 61f2995a..f2f2ed45 100644 --- a/src/test/scala/chiselTests/DedupSpec.scala +++ b/src/test/scala/chiselTests/DedupSpec.scala @@ -65,11 +65,10 @@ class SharedConstantValDedupTop extends Module { io.out := inst0.io.out + inst1.io.out } - class DedupSpec extends ChiselFlatSpec { private val ModuleRegex = """\s*module\s+(\w+)\b.*""".r def countModules(verilog: String): Int = - (verilog split "\n" collect { case ModuleRegex(name) => name }).size + (verilog.split("\n").collect { case ModuleRegex(name) => name }).size "Deduplication" should "occur" in { assert(countModules(compile { new DedupQueues(4) }) === 2) @@ -80,7 +79,6 @@ class DedupSpec extends ChiselFlatSpec { } it should "dedup modules that share a literal" in { - assert(countModules(compile { new SharedConstantValDedupTop }) === 2) + assert(countModules(compile { new SharedConstantValDedupTop }) === 2) } } - diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala index 39ff1f0e..0c657273 100644 --- a/src/test/scala/chiselTests/Direction.scala +++ b/src/test/scala/chiselTests/Direction.scala @@ -16,8 +16,8 @@ class DirectionHaver extends Module { val io = IO(new Bundle { val in = Input(UInt(32.W)) val out = Output(UInt(32.W)) - val inBundle = Input(new DirectionedBundle) // should override elements - val outBundle = Output(new DirectionedBundle) // should override elements + val inBundle = Input(new DirectionedBundle) // should override elements + val outBundle = Output(new DirectionedBundle) // should override elements }) } @@ -51,10 +51,10 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { property("Inputs should not be assignable") { a[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new BadDirection) + ChiselStage.elaborate(new BadDirection) } a[Exception] should be thrownBy extractCause[Exception] { - ChiselStage.elaborate(new BadSubDirection) + ChiselStage.elaborate(new BadSubDirection) } } @@ -84,7 +84,7 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { } property("Empty Vecs with no direction on the sample_element *should* cause direction errors") { - an [Exception] should be thrownBy extractCause[Exception] { + an[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) @@ -118,7 +118,7 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { } property("Explicitly directioned but empty Bundles should cause direction errors") { - an [Exception] should be thrownBy extractCause[Exception] { + an[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = UInt(8.W) @@ -241,18 +241,20 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { } val emitted: String = ChiselStage.emitChirrtl(new MyModule) - val firrtl: String = ChiselStage.convert(new MyModule).serialize + val firrtl: String = ChiselStage.convert(new MyModule).serialize // Check that emitted directions are correct. - Seq(emitted, firrtl).foreach { o => { - // Chisel Emitter formats spacing a little differently than the - // FIRRTL Emitter :-( - val s = o.replace("{flip a", "{ flip a") - assert(s.contains("output regularVec : { flip a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("input vecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("input flippedVec : { flip a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("output flippedVecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]")) - } } + Seq(emitted, firrtl).foreach { o => + { + // Chisel Emitter formats spacing a little differently than the + // FIRRTL Emitter :-( + val s = o.replace("{flip a", "{ flip a") + assert(s.contains("output regularVec : { flip a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("input vecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("input flippedVec : { flip a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("output flippedVecFlipped : { flip a : UInt<1>, b : UInt<1>}[2]")) + } + } } property("Vec with Input/Output should calculate directions properly") { @@ -308,19 +310,21 @@ class DirectionSpec extends ChiselPropSpec with Matchers with Utils { } val emitted: String = ChiselStage.emitChirrtl(new MyModule) - val firrtl: String = ChiselStage.convert(new MyModule).serialize + val firrtl: String = ChiselStage.convert(new MyModule).serialize // Check that emitted directions are correct. - Seq(emitted, firrtl).foreach { o => { - // Chisel Emitter formats spacing a little differently than the - // FIRRTL Emitter :-( - val s = o.replace("{a", "{ a") - assert(s.contains("input inputVec : { a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("input vecInput : { a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("input vecInputFlipped : { a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("output outputVec : { a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("output vecOutput : { a : UInt<1>, b : UInt<1>}[2]")) - assert(s.contains("output vecOutputFlipped : { a : UInt<1>, b : UInt<1>}[2]")) - } } + Seq(emitted, firrtl).foreach { o => + { + // Chisel Emitter formats spacing a little differently than the + // FIRRTL Emitter :-( + val s = o.replace("{a", "{ a") + assert(s.contains("input inputVec : { a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("input vecInput : { a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("input vecInputFlipped : { a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("output outputVec : { a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("output vecOutput : { a : UInt<1>, b : UInt<1>}[2]")) + assert(s.contains("output vecOutputFlipped : { a : UInt<1>, b : UInt<1>}[2]")) + } + } } } diff --git a/src/test/scala/chiselTests/DontTouchSpec.scala b/src/test/scala/chiselTests/DontTouchSpec.scala index a6e4210c..4b21840e 100644 --- a/src/test/scala/chiselTests/DontTouchSpec.scala +++ b/src/test/scala/chiselTests/DontTouchSpec.scala @@ -32,7 +32,7 @@ class HasDeadCode(withDontTouch: Boolean) extends Module { } } -class DontTouchSpec extends ChiselFlatSpec with Utils{ +class DontTouchSpec extends ChiselFlatSpec with Utils { val deadSignals = List( "io_c_0", "io_c_1", @@ -41,20 +41,20 @@ class DontTouchSpec extends ChiselFlatSpec with Utils{ "Dead code" should "be removed by default" in { val verilog = compile(new HasDeadCode(false)) for (signal <- deadSignals) { - verilog should not include (signal) + (verilog should not).include(signal) } } it should "NOT be removed if marked dontTouch" in { val verilog = compile(new HasDeadCode(true)) for (signal <- deadSignals) { - verilog should include (signal) + verilog should include(signal) } } "Dont touch" should "only work on bound hardware" in { - a [chisel3.BindingException] should be thrownBy extractCause[BindingException] { + a[chisel3.BindingException] should be thrownBy extractCause[BindingException] { ChiselStage.elaborate(new Module { - val io = IO(new Bundle { }) - dontTouch(new Bundle { val a = UInt(32.W) } ) + val io = IO(new Bundle {}) + dontTouch(new Bundle { val a = UInt(32.W) }) }) } } diff --git a/src/test/scala/chiselTests/EnableShiftRegister.scala b/src/test/scala/chiselTests/EnableShiftRegister.scala index 34dcecb0..4d407169 100644 --- a/src/test/scala/chiselTests/EnableShiftRegister.scala +++ b/src/test/scala/chiselTests/EnableShiftRegister.scala @@ -6,9 +6,9 @@ import chisel3.stage.ChiselStage class EnableShiftRegister extends Module { val io = IO(new Bundle { - val in = Input(UInt(4.W)) + val in = Input(UInt(4.W)) val shift = Input(Bool()) - val out = Output(UInt(4.W)) + val out = Output(UInt(4.W)) }) val r0 = RegInit(0.U(4.W)) val r1 = RegInit(0.U(4.W)) @@ -41,7 +41,7 @@ class EnableShiftRegisterTester(c: EnableShiftRegister) extends Tester(c) { expect(c.io.out, reg(3)) } } -*/ + */ class EnableShiftRegisterSpec extends ChiselPropSpec { @@ -49,5 +49,5 @@ class EnableShiftRegisterSpec extends ChiselPropSpec { ChiselStage.elaborate { new EnableShiftRegister } } - ignore("EnableShiftRegisterTester should return the correct result") { } + ignore("EnableShiftRegisterTester should return the correct result") {} } diff --git a/src/test/scala/chiselTests/ExtModule.scala b/src/test/scala/chiselTests/ExtModule.scala index 161b6f5f..1dbd7447 100644 --- a/src/test/scala/chiselTests/ExtModule.scala +++ b/src/test/scala/chiselTests/ExtModule.scala @@ -61,19 +61,16 @@ class MultiExtModuleTester extends BasicTester { class ExtModuleSpec extends ChiselFlatSpec { "A ExtModule inverter" should "work" in { - assertTesterPasses({ new ExtModuleTester }, - Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) + assertTesterPasses({ new ExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "Multiple ExtModules" should "work" in { - assertTesterPasses({ new MultiExtModuleTester }, - Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) + assertTesterPasses({ new MultiExtModuleTester }, Seq("/chisel3/BlackBoxTest.v"), TesterDriver.verilatorOnly) } "DataMirror.modulePorts" should "work with ExtModule" in { ChiselStage.elaborate(new Module { - val io = IO(new Bundle { }) + val io = IO(new Bundle {}) val m = Module(new extmoduletests.BlackBoxPassthrough) - assert(DataMirror.modulePorts(m) == Seq( - "in" -> m.in, "out" -> m.out)) + assert(DataMirror.modulePorts(m) == Seq("in" -> m.in, "out" -> m.out)) }) } } diff --git a/src/test/scala/chiselTests/ExtModuleImpl.scala b/src/test/scala/chiselTests/ExtModuleImpl.scala index c6cd4a9f..bb5c07bf 100644 --- a/src/test/scala/chiselTests/ExtModuleImpl.scala +++ b/src/test/scala/chiselTests/ExtModuleImpl.scala @@ -23,14 +23,17 @@ class ExtModuleAdd(n: Int) extends ExtModule with HasExtModuleInline { }) //scalastyle:off regex - setInline("ExtModuleAdd.v", s""" - |module ExtModuleAdd( - | input [15:0] in, - | output [15:0] out - |); - | assign out = in + $n; - |endmodule - """.stripMargin) + setInline( + "ExtModuleAdd.v", + s""" + |module ExtModuleAdd( + | input [15:0] in, + | output [15:0] out + |); + | assign out = in + $n; + |endmodule + """.stripMargin + ) } class UsesExtModuleAddViaInline extends Module { @@ -93,7 +96,7 @@ class UsesExtModuleMinusViaPath extends Module { } class ExtModuleResourceNotFound extends HasExtModuleResource { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) addResource("/missing.resource") } @@ -113,7 +116,7 @@ class ExtModuleImplSpec extends AnyFreeSpec with Matchers { ) val newAnnotations = (new ChiselStage).transform(annotations) - newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be (true) + newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true) val verilogOutput = new File(targetDir, "ExtModuleAdd.v") verilogOutput.exists() should be(true) verilogOutput.delete() @@ -127,7 +130,7 @@ class ExtModuleImplSpec extends AnyFreeSpec with Matchers { ) val newAnnotations = (new ChiselStage).transform(annotations) - newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be (true) + newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true) val verilogOutput = new File(targetDir, "BlackBoxTest.v") verilogOutput.exists() should be(true) verilogOutput.delete() @@ -141,14 +144,14 @@ class ExtModuleImplSpec extends AnyFreeSpec with Matchers { ) val newAnnotations = (new ChiselStage).transform(annotations) - newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be (true) + newAnnotations.exists(_.isInstanceOf[FirrtlCircuitAnnotation]) should be(true) val verilogOutput = new File(targetDir, "BlackBoxTest.v") verilogOutput.exists() should be(true) verilogOutput.delete() } "Resource files that do not exist produce Chisel errors" in { - assertThrows[BlackBoxNotFoundException]{ + assertThrows[BlackBoxNotFoundException] { ChiselStage.emitChirrtl(new UsesMissingExtModuleResource) } } diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala index 2530bb13..aedd195e 100644 --- a/src/test/scala/chiselTests/FixedPointSpec.scala +++ b/src/test/scala/chiselTests/FixedPointSpec.scala @@ -12,7 +12,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class FixedPointLiteralSpec extends AnyFlatSpec with Matchers { - behavior of "fixed point utilities" + behavior.of("fixed point utilities") they should "allow conversion between doubles and the bigints needed to represent them" in { val initialDouble = 0.125 @@ -25,11 +25,11 @@ class FixedPointLiteralSpec extends AnyFlatSpec with Matchers { they should "have their literals support to double and to BigDecimal" in { val d = -7.125 val lit1 = d.F(3.BP) - lit1.litToDouble should be (d) + lit1.litToDouble should be(d) val d2 = BigDecimal("1232123213131123.125") val lit2 = d2.F(3.BP) - lit2.litToBigDecimal should be (d2) + lit2.litToBigDecimal should be(d2) // Numbers that are too big will throw exception intercept[ChiselException] { @@ -43,33 +43,33 @@ class FixedPointFromBitsTester extends BasicTester { val uint = 3.U(4.W) val sint = (-3).S - val fp = FixedPoint.fromDouble(3.0, 4.W, 0.BP) + val fp = FixedPoint.fromDouble(3.0, 4.W, 0.BP) val fp_tpe = FixedPoint(4.W, 1.BP) val uint_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP) val sint_result = FixedPoint.fromDouble(-1.5, 4.W, 1.BP) - val fp_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP) + val fp_result = FixedPoint.fromDouble(1.5, 4.W, 1.BP) val uint2fp = uint.asTypeOf(fp_tpe) val sint2fp = sint.asTypeOf(fp_tpe) - val fp2fp = fp.asTypeOf(fp_tpe) + val fp2fp = fp.asTypeOf(fp_tpe) val uintToFp = uint.asFixedPoint(1.BP) val sintToFp = sint.asFixedPoint(1.BP) - val fpToFp = fp.asFixedPoint(1.BP) + val fpToFp = fp.asFixedPoint(1.BP) val negativefp = (-3.5).F(4.BP) val positivefp = 3.5.F(4.BP) - assert(- positivefp === negativefp) + assert(-positivefp === negativefp) assert(positivefp === -negativefp) assert(uint2fp === uint_result) assert(sint2fp === sint_result) - assert(fp2fp === fp_result) + assert(fp2fp === fp_result) assert(uintToFp === uint_result) assert(sintToFp === sint_result) - assert(fpToFp === fp_result) + assert(fpToFp === fp_result) assert(positivefp.abs() === positivefp) assert(negativefp.abs() === positivefp) @@ -94,7 +94,6 @@ class FixedPointFromBitsTester extends BasicTester { assert(f6bp0shiftright2 === 1.0.F(0.BP)) assert(f6bp2shiftright2 === 1.5.F(2.BP)) - stop() } @@ -115,7 +114,7 @@ class FixedPointMuxTester extends BasicTester { class SBP extends Module { val io = IO(new Bundle { - val in = Input(FixedPoint(6.W, 2.BP)) + val in = Input(FixedPoint(6.W, 2.BP)) val out = Output(FixedPoint(4.W, 0.BP)) }) io.out := io.in.setBinaryPoint(0) @@ -162,7 +161,7 @@ class FixedPointSpec extends ChiselPropSpec with Utils { assertTesterPasses { new FixedPointMuxTester } } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new NegativeShift(FixedPoint(1.W, 0.BP))) } } diff --git a/src/test/scala/chiselTests/GCD.scala b/src/test/scala/chiselTests/GCD.scala index 1e40c6f4..f03d4e61 100644 --- a/src/test/scala/chiselTests/GCD.scala +++ b/src/test/scala/chiselTests/GCD.scala @@ -8,17 +8,16 @@ import chisel3.testers.BasicTester class GCD extends Module { val io = IO(new Bundle { - val a = Input(UInt(32.W)) - val b = Input(UInt(32.W)) - val e = Input(Bool()) - val z = Output(UInt(32.W)) - val v = Output(Bool()) + val a = Input(UInt(32.W)) + val b = Input(UInt(32.W)) + val e = Input(Bool()) + val z = Output(UInt(32.W)) + val v = Output(Bool()) }) val x = Reg(UInt(32.W)) val y = Reg(UInt(32.W)) - when (x > y) { x := x -% y } - .otherwise { y := y -% x } - when (io.e) { x := io.a; y := io.b } + when(x > y) { x := x -% y }.otherwise { y := y -% x } + when(io.e) { x := io.a; y := io.b } io.z := x io.v := y === 0.U } @@ -39,21 +38,22 @@ class GCDTester(a: Int, b: Int, z: Int) extends BasicTester { class GCDSpec extends ChiselPropSpec { //TODO: use generators and this function to make z's - def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a%b) + def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b) val gcds = Table( - ("a", "b", "z"), // First tuple defines column names - ( 64, 48, 16), // Subsequent tuples define the data - ( 12, 9, 3), - ( 48, 64, 16)) + ("a", "b", "z"), // First tuple defines column names + (64, 48, 16), // Subsequent tuples define the data + (12, 9, 3), + (48, 64, 16) + ) property("GCD should elaborate") { ChiselStage.elaborate { new GCD } } property("GCDTester should return the correct result") { - forAll (gcds) { (a: Int, b: Int, z: Int) => - assertTesterPasses{ new GCDTester(a, b, z) } + forAll(gcds) { (a: Int, b: Int, z: Int) => + assertTesterPasses { new GCDTester(a, b, z) } } } } diff --git a/src/test/scala/chiselTests/Harness.scala b/src/test/scala/chiselTests/Harness.scala index 51576566..d4330cd6 100644 --- a/src/test/scala/chiselTests/Harness.scala +++ b/src/test/scala/chiselTests/Harness.scala @@ -15,7 +15,8 @@ module ${prefix}; endmodule """, ".v") _ - def makeFailingVerilog: (File => File) = makeHarness((prefix: String) => s""" + def makeFailingVerilog: (File => File) = makeHarness( + (prefix: String) => s""" module $prefix; initial begin assert (1 == 0) else $$error("My specific, expected error message!"); @@ -23,9 +24,12 @@ module $prefix; $$finish; end endmodule -""", ".v") _ +""", + ".v" + ) _ - def makeCppHarness: (File => File) = makeHarness((prefix: String) => s""" + def makeCppHarness: (File => File) = makeHarness( + (prefix: String) => s""" #include "V$prefix.h" #include "verilated.h" @@ -44,7 +48,9 @@ void vl_finish(const char* filename, int linenum, const char* hier) { Verilated::flushCall(); exit(0); } -""", ".cpp") _ +""", + ".cpp" + ) _ /** Compiles a C++ emulator from Verilog and returns the path to the * executable and the executable filename as a tuple. @@ -77,4 +83,3 @@ void vl_finish(const char* filename, int linenum, const char* hier) { assert(!executeExpectingFailure(target, path, "A string that doesn't match any test output")) } } - diff --git a/src/test/scala/chiselTests/IOCompatibility.scala b/src/test/scala/chiselTests/IOCompatibility.scala index 61789ffa..3e01a7a5 100644 --- a/src/test/scala/chiselTests/IOCompatibility.scala +++ b/src/test/scala/chiselTests/IOCompatibility.scala @@ -8,7 +8,7 @@ import org.scalatest._ import org.scalatest.matchers.should.Matchers class IOCSimpleIO extends Bundle { - val in = Input(UInt(32.W)) + val in = Input(UInt(32.W)) val out = Output(UInt(32.W)) } @@ -19,13 +19,13 @@ class IOCPlusOne extends Module { class IOCModuleVec(val n: Int) extends Module { val io = IO(new Bundle { - val ins = Vec(n, Input(UInt(32.W))) + val ins = Vec(n, Input(UInt(32.W))) val outs = Vec(n, Output(UInt(32.W))) }) - val pluses = VecInit(Seq.fill(n){ Module(new IOCPlusOne).io }) + val pluses = VecInit(Seq.fill(n) { Module(new IOCPlusOne).io }) for (i <- 0 until n) { pluses(i).in := io.ins(i) - io.outs(i) := pluses(i).out + io.outs(i) := pluses(i).out } } @@ -46,14 +46,13 @@ class IOCompatibilitySpec extends ChiselPropSpec with Matchers with Utils { ChiselStage.elaborate { new IOCModuleWire } } - class IOUnwrapped extends Module { val io = new IOCSimpleIO io.out := io.in } property("Unwrapped IO should generate an exception") { - a [BindingException] should be thrownBy extractCause[BindingException] { + a[BindingException] should be thrownBy extractCause[BindingException] { ChiselStage.elaborate(new IOUnwrapped) } } diff --git a/src/test/scala/chiselTests/IllegalRefSpec.scala b/src/test/scala/chiselTests/IllegalRefSpec.scala index 1bafc780..219df5af 100644 --- a/src/test/scala/chiselTests/IllegalRefSpec.scala +++ b/src/test/scala/chiselTests/IllegalRefSpec.scala @@ -39,7 +39,7 @@ object IllegalRefSpec { val o = Output(Bool()) }) private var tmp: Option[Bool] = None - when (io.i) { + when(io.i) { val x = io.i & io.i tmp = Some(x) } @@ -60,13 +60,13 @@ class IllegalRefSpec extends ChiselFlatSpec with Utils { variants.foreach { case (k, v) => s"Illegal cross-module references in ${k}" should "fail" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new IllegalRefOuter(v) } } } s"Using a signal that has escaped its enclosing when scope in ${k}" should "fail" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new CrossWhenConnect(v) } } } diff --git a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala b/src/test/scala/chiselTests/ImplicitConversionsSpec.scala index f73b23b4..4bccf636 100644 --- a/src/test/scala/chiselTests/ImplicitConversionsSpec.scala +++ b/src/test/scala/chiselTests/ImplicitConversionsSpec.scala @@ -41,7 +41,7 @@ class ImplicitConversionsSpec extends ChiselFlatSpec { } "X.B for X not in [0,1]" should "throw an exception, even outside hardware context" in { - a [ChiselException] should be thrownBy { + a[ChiselException] should be thrownBy { 65.B } } diff --git a/src/test/scala/chiselTests/InlineSpec.scala b/src/test/scala/chiselTests/InlineSpec.scala index 59a1e984..09a92e45 100644 --- a/src/test/scala/chiselTests/InlineSpec.scala +++ b/src/test/scala/chiselTests/InlineSpec.scala @@ -4,7 +4,7 @@ package chiselTests import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} -import chisel3.util.experimental.{InlineInstance, FlattenInstance} +import chisel3.util.experimental.{FlattenInstance, InlineInstance} import firrtl.passes.InlineAnnotation import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage} import firrtl.transforms.FlattenAnnotation @@ -16,7 +16,7 @@ import org.scalatest.matchers.should.Matchers class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { trait Internals { this: Module => - val io = IO(new Bundle{ val a = Input(Bool()) }) + val io = IO(new Bundle { val a = Input(Bool()) }) } class Sub extends Module with Internals trait HasSub { this: Module with Internals => @@ -29,9 +29,9 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { class Baz extends Module with Internals with HasSub class Qux extends Module with Internals with HasSub - def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] = new InstanceGraph(c) - .fullHierarchy.values.flatten.toSeq - .map( v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".") ) + def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] = + new InstanceGraph(c).fullHierarchy.values.flatten.toSeq + .map(v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".")) val chiselStage = new ChiselStage val firrtlStage = new FirrtlStage @@ -46,17 +46,20 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { "should compile to low FIRRTL" - { val chiselAnnotations = chiselStage - .execute(Array("--no-run-firrtl", "--target-dir", "test_run_dir"), - Seq(ChiselGeneratorAnnotation(() => new Top))) + .execute( + Array("--no-run-firrtl", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new Top)) + ) - chiselAnnotations.collect{ case a: InlineAnnotation => a } should have length (2) + (chiselAnnotations.collect { case a: InlineAnnotation => a } should have).length(2) val instanceNames = firrtlStage .execute(Array("-X", "low"), chiselAnnotations) .collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit - }.map(collectInstances(_, Some("Top"))) + } + .map(collectInstances(_, Some("Top"))) .getOrElse(fail) instanceNames should contain theSameElementsAs Set("Top", "Top.x_sub", "Top.y_sub", "Top.z", "Top.z.sub") @@ -71,17 +74,20 @@ class InlineSpec extends AnyFreeSpec with ChiselRunners with Matchers { "should compile to low FIRRTL" - { val chiselAnnotations = chiselStage - .execute(Array("--no-run-firrtl", "--target-dir", "test_run_dir"), - Seq(ChiselGeneratorAnnotation(() => new Top))) + .execute( + Array("--no-run-firrtl", "--target-dir", "test_run_dir"), + Seq(ChiselGeneratorAnnotation(() => new Top)) + ) - chiselAnnotations.collect{ case a: FlattenAnnotation => a} should have length(1) + (chiselAnnotations.collect { case a: FlattenAnnotation => a } should have).length(1) val instanceNames = firrtlStage .execute(Array("-X", "low"), chiselAnnotations) .collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit - }.map(collectInstances(_, Some("Top"))) + } + .map(collectInstances(_, Some("Top"))) .getOrElse(fail) instanceNames should contain theSameElementsAs Set("Top", "Top.x") diff --git a/src/test/scala/chiselTests/InstanceNameSpec.scala b/src/test/scala/chiselTests/InstanceNameSpec.scala index 7e3186f7..7eaf3106 100644 --- a/src/test/scala/chiselTests/InstanceNameSpec.scala +++ b/src/test/scala/chiselTests/InstanceNameSpec.scala @@ -23,7 +23,7 @@ class InstanceNameModule extends Module { } class InstanceNameSpec extends ChiselFlatSpec { - behavior of "instanceName" + behavior.of("instanceName") val moduleName = "InstanceNameModule" var m: InstanceNameModule = _ ChiselStage.elaborate { m = new InstanceNameModule; m } diff --git a/src/test/scala/chiselTests/IntegerMathSpec.scala b/src/test/scala/chiselTests/IntegerMathSpec.scala index 03b2b208..166e47bd 100644 --- a/src/test/scala/chiselTests/IntegerMathSpec.scala +++ b/src/test/scala/chiselTests/IntegerMathSpec.scala @@ -27,6 +27,6 @@ class IntegerMathTester extends BasicTester { class IntegerMathSpec extends ChiselPropSpec { property("All integer ops should return the correct result") { - assertTesterPasses{ new IntegerMathTester } + assertTesterPasses { new IntegerMathTester } } } diff --git a/src/test/scala/chiselTests/IntervalRangeSpec.scala b/src/test/scala/chiselTests/IntervalRangeSpec.scala index f17f1624..777e08d6 100644 --- a/src/test/scala/chiselTests/IntervalRangeSpec.scala +++ b/src/test/scala/chiselTests/IntervalRangeSpec.scala @@ -186,7 +186,6 @@ class IntervalRangeSpec extends AnyFreeSpec with Matchers { checkRange(range"[-8,7].2", C(-8), C(7), 2.BP) checkRange(range"[-8,7].2" >> 3, C(-1), C(0.75), 2.BP) - checkRange(range"(0,7).0", O(0), O(7), 0.BP) checkRange(range"(0,7).0" >> 1, O(0), O(3), 0.BP) @@ -219,19 +218,19 @@ class IntervalRangeSpec extends AnyFreeSpec with Matchers { "get possible values should return all values from high to low" in { var range = range"[0,4]" - range.getLowestPossibleValue should be (Some(0)) - range.getHighestPossibleValue should be (Some(4)) - range.getPossibleValues should be (Seq(0, 1, 2, 3, 4)) + range.getLowestPossibleValue should be(Some(0)) + range.getHighestPossibleValue should be(Some(4)) + range.getPossibleValues should be(Seq(0, 1, 2, 3, 4)) range = range"(0,4)" - range.getLowestPossibleValue should be (Some(1)) - range.getHighestPossibleValue should be (Some(3)) - range.getPossibleValues should be (Seq(1, 2, 3)) + range.getLowestPossibleValue should be(Some(1)) + range.getHighestPossibleValue should be(Some(3)) + range.getPossibleValues should be(Seq(1, 2, 3)) range = range"(-1,4).1" - range.getLowestPossibleValue should be (Some(-0.5)) - range.getHighestPossibleValue should be (Some(3.5)) - range.getPossibleValues should be (Seq(-0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5)) + range.getLowestPossibleValue should be(Some(-0.5)) + range.getHighestPossibleValue should be(Some(3.5)) + range.getPossibleValues should be(Seq(-0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5)) } } diff --git a/src/test/scala/chiselTests/IntervalSpec.scala b/src/test/scala/chiselTests/IntervalSpec.scala index c223260d..c0338f6d 100644 --- a/src/test/scala/chiselTests/IntervalSpec.scala +++ b/src/test/scala/chiselTests/IntervalSpec.scala @@ -15,7 +15,15 @@ import firrtl.passes.CheckTypes.InvalidConnect import firrtl.passes.CheckWidths.{DisjointSqueeze, InvalidRange} import firrtl.passes.{PassExceptions, WrapWithRemainder} import firrtl.stage.{CompilerAnnotation, FirrtlCircuitAnnotation} -import firrtl.{HighFirrtlCompiler, LowFirrtlCompiler, MiddleFirrtlCompiler, MinimumVerilogCompiler, NoneCompiler, SystemVerilogCompiler, VerilogCompiler} +import firrtl.{ + HighFirrtlCompiler, + LowFirrtlCompiler, + MiddleFirrtlCompiler, + MinimumVerilogCompiler, + NoneCompiler, + SystemVerilogCompiler, + VerilogCompiler +} import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers @@ -31,16 +39,17 @@ object IntervalTestHelper { */ def makeFirrtl[T <: RawModule](compilerName: String)(gen: () => T): String = { (new ChiselStage) - .execute(Array("--compiler", compilerName, - "--target-dir", "test_run_dir/IntervalSpec"), - Seq(ChiselGeneratorAnnotation(gen))) + .execute( + Array("--compiler", compilerName, "--target-dir", "test_run_dir/IntervalSpec"), + Seq(ChiselGeneratorAnnotation(gen)) + ) .collectFirst { case FirrtlCircuitAnnotation(source) => source } match { - case Some(circuit) => circuit.serialize - case _ => - throw new Exception( - s"makeFirrtl($compilerName) failed to generate firrtl circuit" - ) - } + case Some(circuit) => circuit.serialize + case _ => + throw new Exception( + s"makeFirrtl($compilerName) failed to generate firrtl circuit" + ) + } } } @@ -174,11 +183,12 @@ class MoreIntervalShiftTester extends BasicTester { * @param endNum end here * @param incNum increment by this */ -class ClipSqueezeWrapDemo(range: IntervalRange, - targetRange: IntervalRange, - startNum: Double, - endNum: Double, - incNum: Double) +class ClipSqueezeWrapDemo( + range: IntervalRange, + targetRange: IntervalRange, + startNum: Double, + endNum: Double, + incNum: Double) extends BasicTester { val binaryPointAsInt = range.binaryPoint.asInstanceOf[KnownBinaryPoint].value @@ -214,10 +224,7 @@ class ClipSqueezeWrapDemo(range: IntervalRange, ) } -class SqueezeFunctionalityTester(range: IntervalRange, - startNum: BigDecimal, - endNum: BigDecimal, - increment: BigDecimal) +class SqueezeFunctionalityTester(range: IntervalRange, startNum: BigDecimal, endNum: BigDecimal, increment: BigDecimal) extends BasicTester { val counter = RegInit(0.U(10.W)) @@ -436,20 +443,18 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { "Interval literals that don't fit in explicit ranges are caught by chisel" - { "case 1: does not fit in specified width" in { intercept[ChiselException] { - ChiselGeneratorAnnotation( - () => - new BasicTester { - val x = 5.I(3.W, 0.BP) + ChiselGeneratorAnnotation(() => + new BasicTester { + val x = 5.I(3.W, 0.BP) } ).elaborate } } "case 2: doesn't fit in specified range" in { intercept[ChiselException] { - ChiselGeneratorAnnotation( - () => - new BasicTester { - val x = 5.I(range"[0,4]") + ChiselGeneratorAnnotation(() => + new BasicTester { + val x = 5.I(range"[0,4]") } ).elaborate } @@ -459,11 +464,11 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { "Interval literals support to double and to BigDecimal" in { val d = -7.125 val lit1 = d.I(3.BP) - lit1.litToDouble should be (d) + lit1.litToDouble should be(d) val d2 = BigDecimal("1232123213131123.125") val lit2 = d2.I(3.BP) - lit2.litToBigDecimal should be (d2) + lit2.litToBigDecimal should be(d2) // Numbers that are too big will throw exception intercept[ChiselException] { @@ -476,8 +481,8 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { val inputRange = range"[-6, 6].2" val in1 = (-6.0).I(inputRange) val in2 = 6.0.I(inputRange) - BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be (-6) - BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be (6) + BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-6) + BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(6) intercept[ChiselException] { (-6.25).I(inputRange) } @@ -489,8 +494,8 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { val inputRange = range"(-6, 6).2" val in1 = (-5.75).I(inputRange) val in2 = 5.75.I(inputRange) - BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be (-5.75) - BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be (5.75) + BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-5.75) + BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(5.75) intercept[ChiselException] { (-6.0).I(inputRange) } @@ -502,8 +507,8 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { val inputRange = range"(-6, 6).2" val in1 = (-5.95).I(inputRange) val in2 = 5.95.I(inputRange) - BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be (-5.75) - BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be (5.75) + BigDecimal(in1.litValue()) / (1 << inputRange.binaryPoint.get) should be(-5.75) + BigDecimal(in2.litValue()) / (1 << inputRange.binaryPoint.get) should be(5.75) intercept[ChiselException] { (-6.1).I(inputRange) } @@ -614,28 +619,26 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { } } - def makeCircuit(operation: String, - sourceRange: IntervalRange, - targetRange: IntervalRange): () => RawModule = { () => - new Module { - val io = IO(new Bundle { val out = Output(Interval()) }) - val base = Wire(Interval(sourceRange)) - base := 6.I + def makeCircuit(operation: String, sourceRange: IntervalRange, targetRange: IntervalRange): () => RawModule = { + () => + new Module { + val io = IO(new Bundle { val out = Output(Interval()) }) + val base = Wire(Interval(sourceRange)) + base := 6.I - val disjointLeft = WireInit(Interval(targetRange), 8.I) - val w5 = operation match { - case "clip" => base.clip(disjointLeft) - case "wrap" => base.wrap(disjointLeft) - case "squeeze" => base.squeeze(disjointLeft) + val disjointLeft = WireInit(Interval(targetRange), 8.I) + val w5 = operation match { + case "clip" => base.clip(disjointLeft) + case "wrap" => base.wrap(disjointLeft) + case "squeeze" => base.squeeze(disjointLeft) + } + io.out := w5 } - io.out := w5 - } } "disjoint ranges should error when used with clip, wrap and squeeze" - { - def mustGetException(disjointLeft: Boolean, - operation: String): Boolean = { + def mustGetException(disjointLeft: Boolean, operation: String): Boolean = { val (rangeA, rangeB) = if (disjointLeft) { (range"[-4, 6]", range"[7,10]") } else { @@ -675,57 +678,37 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { "Errors are sometimes inconsistent or incorrectly labelled as Firrtl Internal Error" - { "squeeze disjoint is not internal error when defined in BasicTester" in { intercept[DisjointSqueeze] { - makeFirrtl("low")( - () => - new BasicTester { - val base = Wire(Interval(range"[-4, 6]")) - val base2 = Wire(Interval(range"[-4, 6]")) - base := 6.I - base2 := 5.I - val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) - val w5 = base.squeeze(disjointLeft) - stop() + makeFirrtl("low")(() => + new BasicTester { + val base = Wire(Interval(range"[-4, 6]")) + val base2 = Wire(Interval(range"[-4, 6]")) + base := 6.I + base2 := 5.I + val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) + val w5 = base.squeeze(disjointLeft) + stop() } ) } } "wrap disjoint is not internal error when defined in BasicTester" in { intercept[DisjointSqueeze] { - makeFirrtl("low")( - () => - new BasicTester { - val base = Wire(Interval(range"[-4, 6]")) - val base2 = Wire(Interval(range"[-4, 6]")) - base := 6.I - base2 := 5.I - val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) - val w5 = base.squeeze(disjointLeft) - stop() + makeFirrtl("low")(() => + new BasicTester { + val base = Wire(Interval(range"[-4, 6]")) + val base2 = Wire(Interval(range"[-4, 6]")) + base := 6.I + base2 := 5.I + val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) + val w5 = base.squeeze(disjointLeft) + stop() } ) } } "squeeze disjoint from Module gives exception" in { intercept[DisjointSqueeze] { - makeFirrtl("low")( - () => - new Module { - val io = IO(new Bundle { - val out = Output(Interval()) - }) - val base = Wire(Interval(range"[-4, 6]")) - base := 6.I - - val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) - val w5 = base.squeeze(disjointLeft) - io.out := w5 - } - ) - } - } - "clip disjoint from Module gives no error" in { - makeFirrtl("low")( - () => + makeFirrtl("low")(() => new Module { val io = IO(new Bundle { val out = Output(Interval()) @@ -734,25 +717,40 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { base := 6.I val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) - val w5 = base.clip(disjointLeft) + val w5 = base.squeeze(disjointLeft) io.out := w5 + } + ) + } + } + "clip disjoint from Module gives no error" in { + makeFirrtl("low")(() => + new Module { + val io = IO(new Bundle { + val out = Output(Interval()) + }) + val base = Wire(Interval(range"[-4, 6]")) + base := 6.I + + val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) + val w5 = base.clip(disjointLeft) + io.out := w5 } ) } "wrap disjoint from Module wrap with remainder" in { intercept[WrapWithRemainder] { - makeFirrtl("low")( - () => - new Module { - val io = IO(new Bundle { - val out = Output(Interval()) - }) - val base = Wire(Interval(range"[-4, 6]")) - base := 6.I - - val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) - val w5 = base.wrap(disjointLeft) - io.out := w5 + makeFirrtl("low")(() => + new Module { + val io = IO(new Bundle { + val out = Output(Interval()) + }) + val base = Wire(Interval(range"[-4, 6]")) + base := 6.I + + val disjointLeft = WireInit(Interval(range"[7,10]"), 8.I) + val w5 = base.wrap(disjointLeft) + io.out := w5 } ) } @@ -772,26 +770,24 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { "Intervals should catch assignment of literals outside of range" - { "when literal is too small" in { intercept[InvalidConnect] { - makeFirrtl("low")( - () => - new Module { - val io = IO(new Bundle { val out = Output(Interval()) }) - val base = Wire(Interval(range"[-4, 6]")) - base := (-7).I - io.out := base + makeFirrtl("low")(() => + new Module { + val io = IO(new Bundle { val out = Output(Interval()) }) + val base = Wire(Interval(range"[-4, 6]")) + base := (-7).I + io.out := base } ) } } "when literal is too big" in { intercept[InvalidConnect] { - makeFirrtl("low")( - () => - new Module { - val io = IO(new Bundle { val out = Output(Interval()) }) - val base = Wire(Interval(range"[-4, 6]")) - base := 9.I - io.out := base + makeFirrtl("low")(() => + new Module { + val io = IO(new Bundle { val out = Output(Interval()) }) + val base = Wire(Interval(range"[-4, 6]")) + base := 9.I + io.out := base } ) } @@ -834,18 +830,17 @@ class IntervalSpec extends AnyFreeSpec with Matchers with ChiselRunners { assertTesterPasses { new IntervalChainedAddTester } } "Intervals should produce canonically smaller ranges via inference" in { - val loFirrtl = makeFirrtl("low")( - () => - new Module { - val io = IO(new Bundle { - val in = Input(Interval(range"[0,1]")) - val out = Output(Interval()) - }) + val loFirrtl = makeFirrtl("low")(() => + new Module { + val io = IO(new Bundle { + val in = Input(Interval(range"[0,1]")) + val out = Output(Interval()) + }) - val intervalResult = Wire(Interval()) + val intervalResult = Wire(Interval()) - intervalResult := 1.I + 1.I + 1.I + 1.I + 1.I + 1.I + 1.I - io.out := intervalResult + intervalResult := 1.I + 1.I + 1.I + 1.I + 1.I + 1.I + 1.I + io.out := intervalResult } ) loFirrtl.contains("output io_out : SInt<4>") should be(true) diff --git a/src/test/scala/chiselTests/InvalidateAPISpec.scala b/src/test/scala/chiselTests/InvalidateAPISpec.scala index 52ad02b4..2c51e5d2 100644 --- a/src/test/scala/chiselTests/InvalidateAPISpec.scala +++ b/src/test/scala/chiselTests/InvalidateAPISpec.scala @@ -16,11 +16,13 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila def compileFirrtl(t: => Module): Unit = { val testDir = createTestDirectory(this.getClass.getSimpleName) - (new ChiselStage).execute(Array[String]("-td", testDir.getAbsolutePath, "--compiler", "verilog"), - Seq(ChiselGeneratorAnnotation(() => t))) + (new ChiselStage).execute( + Array[String]("-td", testDir.getAbsolutePath, "--compiler", "verilog"), + Seq(ChiselGeneratorAnnotation(() => t)) + ) } class TrivialInterface extends Bundle { - val in = Input(Bool()) + val in = Input(Bool()) val out = Output(Bool()) } @@ -42,7 +44,7 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila io.out := io.in } val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) - firrtlOutput should not include("is invalid") + (firrtlOutput should not).include("is invalid") } property("an output without a DontCare should emit a Firrtl \"is invalid\" with NotStrict CompileOptions") { @@ -77,7 +79,7 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila } val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) for (i <- 0 until nElements) - firrtlOutput should include(s"io.outs[$i] is invalid") + firrtlOutput should include(s"io.outs[$i] is invalid") } property("a Vec with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions and mono connect") { @@ -129,7 +131,7 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila val out = Output(Bool()) }) val counter = Counter(8) - when (counter.inc()) { + when(counter.inc()) { io.out := true.B } } @@ -137,9 +139,11 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila compileFirrtl(new ModuleWithIncompleteAssignment) } exception.getMessage should include("is not fully initialized") - } + } - property("FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect after unconditional connect") { + property( + "FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect after unconditional connect" + ) { import chisel3.ExplicitCompileOptions.Strict class ModuleWithUnconditionalAssignment extends Module { val io = IO(new Bundle { @@ -147,23 +151,25 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila }) val counter = Counter(8) io.out := false.B - when (counter.inc()) { + when(counter.inc()) { io.out := true.B } } compileFirrtl(new ModuleWithUnconditionalAssignment) } - property("FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect with otherwise clause") { + property( + "FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect with otherwise clause" + ) { import chisel3.ExplicitCompileOptions.Strict class ModuleWithConditionalAndOtherwiseAssignment extends Module { val io = IO(new Bundle { val out = Output(Bool()) }) val counter = Counter(8) - when (counter.inc()) { + when(counter.inc()) { io.out := true.B - } otherwise { + }.otherwise { io.out := false.B } } @@ -171,7 +177,9 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila compileFirrtl(new ModuleWithConditionalAndOtherwiseAssignment) } - property("an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions") { + property( + "an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions" + ) { import chisel3.ExplicitCompileOptions.NotStrict class ModuleWithoutDontCare extends Module { override val compileOptions = chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true) @@ -179,18 +187,21 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila io.out := io.in } val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) - firrtlOutput should not include("is invalid") + (firrtlOutput should not).include("is invalid") } - property("an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions module definition") { + property( + "an output without a DontCare should NOT emit a Firrtl \"is invalid\" with overriden NotStrict CompileOptions module definition" + ) { import chisel3.ExplicitCompileOptions.NotStrict - abstract class ExplicitInvalidateModule extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true)) + abstract class ExplicitInvalidateModule + extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true)) class ModuleWithoutDontCare extends ExplicitInvalidateModule { val io = IO(new TrivialInterface) io.out := io.in } val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) - firrtlOutput should not include("is invalid") + (firrtlOutput should not).include("is invalid") } property("an output without a DontCare should emit a Firrtl \"is invalid\" with overriden Strict CompileOptions") { @@ -204,9 +215,12 @@ class InvalidateAPISpec extends ChiselPropSpec with Matchers with BackendCompila firrtlOutput should include("is invalid") } - property("an output without a DontCare should emit a Firrtl \"is invalid\" with overriden Strict CompileOptions module definition") { + property( + "an output without a DontCare should emit a Firrtl \"is invalid\" with overriden Strict CompileOptions module definition" + ) { import chisel3.ExplicitCompileOptions.Strict - abstract class ImplicitInvalidateModule extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = false)) + abstract class ImplicitInvalidateModule + extends Module()(chisel3.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = false)) class ModuleWithoutDontCare extends ImplicitInvalidateModule { val io = IO(new TrivialInterface) io.out := io.in diff --git a/src/test/scala/chiselTests/LiteralExtractorSpec.scala b/src/test/scala/chiselTests/LiteralExtractorSpec.scala index bc0c67b8..3906057f 100644 --- a/src/test/scala/chiselTests/LiteralExtractorSpec.scala +++ b/src/test/scala/chiselTests/LiteralExtractorSpec.scala @@ -51,19 +51,21 @@ class LiteralExtractorSpec extends ChiselFlatSpec { } "litOption" should "return None for non-literal hardware" in { - ChiselStage.elaborate { new RawModule { - val a = Wire(UInt()) - assert(a.litOption == None) - }} + ChiselStage.elaborate { + new RawModule { + val a = Wire(UInt()) + assert(a.litOption == None) + } + } } "doubles and big decimals" should "round trip properly" in { intercept[ChiselException] { - Num.toBigDecimal(BigInt("1" * 109, 2), 0.BP) // this only works if number takes less than 109 bits + Num.toBigDecimal(BigInt("1" * 109, 2), 0.BP) // this only works if number takes less than 109 bits } intercept[ChiselException] { - Num.toDouble(BigInt("1" * 54, 2), 0.BP) // this only works if number takes less than 54 bits + Num.toDouble(BigInt("1" * 54, 2), 0.BP) // this only works if number takes less than 54 bits } val bigInt108 = BigInt("1" * 108, 2) @@ -71,22 +73,22 @@ class LiteralExtractorSpec extends ChiselFlatSpec { val bigIntFromBigDecimal = Num.toBigInt(bigDecimal, 2) - bigIntFromBigDecimal should be (bigInt108) + bigIntFromBigDecimal should be(bigInt108) val bigInt53 = BigInt("1" * 53, 2) - val double = Num.toDouble(bigInt53, 2) + val double = Num.toDouble(bigInt53, 2) val bigIntFromDouble = Num.toBigInt(double, 2) - bigIntFromDouble should be (bigInt53) + bigIntFromDouble should be(bigInt53) } "encoding and decoding of Intervals" should "round trip" in { val rangeMin = BigDecimal(-31.5) val rangeMax = BigDecimal(32.5) val range = range"($rangeMin, $rangeMax).2" - for(value <- (rangeMin - 4) to (rangeMax + 4) by 2.25) { + for (value <- (rangeMin - 4) to (rangeMax + 4) by 2.25) { if (value < rangeMin || value > rangeMax) { intercept[ChiselException] { val literal = value.I(range) @@ -125,11 +127,10 @@ class LiteralExtractorSpec extends ChiselFlatSpec { } val outsideLiteral = (new InsideBundle).Lit(_.x -> 7.S, _.y -> 6.125.F(4.BP)) - assertTesterPasses{ new LitInsideOutsideTester(outsideLiteral) } + assertTesterPasses { new LitInsideOutsideTester(outsideLiteral) } } - "bundle literals" should "do the right thing" in { class MyBundle extends Bundle { val a = UInt(8.W) @@ -142,7 +143,7 @@ class LiteralExtractorSpec extends ChiselFlatSpec { } "record literals" should "do the right thing" in { - class MyRecord extends Record{ + class MyRecord extends Record { override val elements = ListMap( "a" -> UInt(8.W), "b" -> Bool() diff --git a/src/test/scala/chiselTests/LiteralToTargetSpec.scala b/src/test/scala/chiselTests/LiteralToTargetSpec.scala index 3c404f2d..b1caecfa 100644 --- a/src/test/scala/chiselTests/LiteralToTargetSpec.scala +++ b/src/test/scala/chiselTests/LiteralToTargetSpec.scala @@ -9,12 +9,11 @@ import org.scalatest._ import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers - class LiteralToTargetSpec extends AnyFreeSpec with Matchers { "Literal Data should fail to be converted to ReferenceTarget" in { - the [chisel3.internal.ChiselException] thrownBy { + (the[chisel3.internal.ChiselException] thrownBy { class Bar extends RawModule { val a = 1.U @@ -26,6 +25,6 @@ class LiteralToTargetSpec extends AnyFreeSpec with Matchers { } ChiselStage.elaborate(new Foo) - } should have message "Illegal component name: UInt<1>(\"h01\") (note: literals are illegal)" + } should have).message("Illegal component name: UInt<1>(\"h01\") (note: literals are illegal)") } } diff --git a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala index 74e587bc..8e5e48b4 100644 --- a/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala +++ b/src/test/scala/chiselTests/LoadMemoryFromFileSpec.scala @@ -6,7 +6,7 @@ import java.io.File import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} -import chisel3.util.experimental.{loadMemoryFromFile,loadMemoryFromFileInline} +import chisel3.util.experimental.{loadMemoryFromFile, loadMemoryFromFileInline} import chisel3.util.log2Ceil import firrtl.annotations.MemoryLoadFileType import org.scalatest.freespec.AnyFreeSpec @@ -15,9 +15,9 @@ import org.scalatest.matchers.should.Matchers class UsesThreeMems(memoryDepth: Int, memoryType: Data) extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value1 = Output(memoryType) - val value2 = Output(memoryType) - val value3 = Output(memoryType) + val value1 = Output(memoryType) + val value2 = Output(memoryType) + val value3 = Output(memoryType) }) val memory1 = Mem(memoryDepth, memoryType) @@ -32,12 +32,17 @@ class UsesThreeMems(memoryDepth: Int, memoryType: Data) extends Module { io.value3 := memory3(io.address) } -class UsesThreeMemsInline(memoryDepth: Int, memoryType: Data, memoryFile: String, hexOrBinary: MemoryLoadFileType.FileType) extends Module { +class UsesThreeMemsInline( + memoryDepth: Int, + memoryType: Data, + memoryFile: String, + hexOrBinary: MemoryLoadFileType.FileType) + extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value1 = Output(memoryType) - val value2 = Output(memoryType) - val value3 = Output(memoryType) + val value1 = Output(memoryType) + val value2 = Output(memoryType) + val value3 = Output(memoryType) }) val memory1 = Mem(memoryDepth, memoryType) @@ -55,9 +60,9 @@ class UsesThreeMemsInline(memoryDepth: Int, memoryType: Data, memoryFile: String class UsesMem(memoryDepth: Int, memoryType: Data) extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value = Output(memoryType) - val value1 = Output(memoryType) - val value2 = Output(memoryType) + val value = Output(memoryType) + val value1 = Output(memoryType) + val value2 = Output(memoryType) }) val memory = Mem(memoryDepth, memoryType) @@ -77,7 +82,7 @@ class UsesMem(memoryDepth: Int, memoryType: Data) extends Module { class UsesMemLow(memoryDepth: Int, memoryType: Data) extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value = Output(memoryType) + val value = Output(memoryType) }) val memory = Mem(memoryDepth, memoryType) @@ -90,8 +95,8 @@ class UsesMemLow(memoryDepth: Int, memoryType: Data) extends Module { class FileHasSuffix(memoryDepth: Int, memoryType: Data) extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value = Output(memoryType) - val value2 = Output(memoryType) + val value = Output(memoryType) + val value2 = Output(memoryType) }) val memory = Mem(memoryDepth, memoryType) @@ -115,7 +120,7 @@ class MemoryShape extends Bundle { class HasComplexMemory(memoryDepth: Int) extends Module { val io = IO(new Bundle { val address = Input(UInt(log2Ceil(memoryDepth).W)) - val value = Output(new MemoryShape) + val value = Output(new MemoryShape) }) val memory = Mem(memoryDepth, new MemoryShape) @@ -128,7 +133,7 @@ class HasComplexMemory(memoryDepth: Int) extends Module { class HasBinarySupport(memoryDepth: Int, memoryType: Data) extends Module { val io = IO(new Bundle { val address = Input(UInt(memoryType.getWidth.W)) - val value = Output(memoryType) + val value = Output(memoryType) }) val memory = Mem(memoryDepth, memoryType) @@ -138,7 +143,6 @@ class HasBinarySupport(memoryDepth: Int, memoryType: Data) extends Module { io.value := memory(io.address) } - /** * The following tests are a bit incomplete and check that the output verilog is properly constructed * For more complete working examples @@ -147,12 +151,12 @@ class HasBinarySupport(memoryDepth: Int, memoryType: Data) extends Module { class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { def fileExistsWithMem(file: File, mem: Option[String] = None): Unit = { info(s"$file exists") - file.exists() should be (true) - mem.foreach( m => { + file.exists() should be(true) + mem.foreach(m => { info(s"Memory $m is referenced in $file") val found = io.Source.fromFile(file).getLines.exists { _.contains(s"""readmemh("$m"""") } - found should be (true) - } ) + found should be(true) + }) file.delete() } @@ -180,10 +184,10 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { ) val dir = new File(testDirName) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory1.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory2.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "UsesThreeMems.UsesThreeMems.memory3.v"), Some("./mem1")) - fileExistsWithMem( new File(dir, "firrtl_black_box_resource_files.f")) + fileExistsWithMem(new File(dir, "UsesThreeMems.UsesThreeMems.memory1.v"), Some("./mem1")) + fileExistsWithMem(new File(dir, "UsesThreeMems.UsesThreeMems.memory2.v"), Some("./mem1")) + fileExistsWithMem(new File(dir, "UsesThreeMems.UsesThreeMems.memory3.v"), Some("./mem1")) + fileExistsWithMem(new File(dir, "firrtl_black_box_resource_files.f")) } @@ -200,9 +204,9 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { memoryElements.foreach { element => val file = new File(dir, s"HasComplexMemory.HasComplexMemory.memory_$element.v") - file.exists() should be (true) + file.exists() should be(true) val fileText = io.Source.fromFile(file).getLines().mkString("\n") - fileText should include (s"""$$readmemh("./mem_$element", HasComplexMemory.memory_$element);""") + fileText should include(s"""$$readmemh("./mem_$element", HasComplexMemory.memory_$element);""") file.delete() } @@ -218,9 +222,9 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { val dir = new File(testDirName) val file = new File(dir, s"HasBinarySupport.HasBinarySupport.memory.v") - file.exists() should be (true) + file.exists() should be(true) val fileText = io.Source.fromFile(file).getLines().mkString("\n") - fileText should include (s"""$$readmemb("./mem", HasBinarySupport.memory);""") + fileText should include(s"""$$readmemb("./mem", HasBinarySupport.memory);""") file.delete() } @@ -229,15 +233,19 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { val result = (new ChiselStage).execute( args = Array("-X", "verilog", "--target-dir", testDirName), - annotations = Seq(ChiselGeneratorAnnotation(() => new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "./testmem.h", MemoryLoadFileType.Hex))) + annotations = Seq( + ChiselGeneratorAnnotation(() => + new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "./testmem.h", MemoryLoadFileType.Hex) + ) + ) ) val dir = new File(testDirName) val file = new File(dir, s"UsesThreeMemsInline.v") - file.exists() should be (true) + file.exists() should be(true) val fileText = io.Source.fromFile(file).getLines().mkString("\n") - fileText should include (s"""$$readmemh("./testmem.h", memory1);""") - fileText should include (s"""$$readmemh("./testmem.h", memory2);""") - fileText should include (s"""$$readmemh("./testmem.h", memory3);""") + fileText should include(s"""$$readmemh("./testmem.h", memory1);""") + fileText should include(s"""$$readmemh("./testmem.h", memory2);""") + fileText should include(s"""$$readmemh("./testmem.h", memory3);""") } "Module with more than one bin memory inline should work" in { @@ -245,14 +253,18 @@ class LoadMemoryFromFileSpec extends AnyFreeSpec with Matchers { val result = (new ChiselStage).execute( args = Array("-X", "verilog", "--target-dir", testDirName), - annotations = Seq(ChiselGeneratorAnnotation(() => new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "testmem.bin", MemoryLoadFileType.Binary))) + annotations = Seq( + ChiselGeneratorAnnotation(() => + new UsesThreeMemsInline(memoryDepth = 8, memoryType = UInt(16.W), "testmem.bin", MemoryLoadFileType.Binary) + ) + ) ) val dir = new File(testDirName) val file = new File(dir, s"UsesThreeMemsInline.v") - file.exists() should be (true) + file.exists() should be(true) val fileText = io.Source.fromFile(file).getLines().mkString("\n") - fileText should include (s"""$$readmemb("testmem.bin", memory1);""") - fileText should include (s"""$$readmemb("testmem.bin", memory2);""") - fileText should include (s"""$$readmemb("testmem.bin", memory3);""") + fileText should include(s"""$$readmemb("testmem.bin", memory1);""") + fileText should include(s"""$$readmemb("testmem.bin", memory2);""") + fileText should include(s"""$$readmemb("testmem.bin", memory3);""") } } diff --git a/src/test/scala/chiselTests/Math.scala b/src/test/scala/chiselTests/Math.scala index 9091b0b4..42eff6ad 100644 --- a/src/test/scala/chiselTests/Math.scala +++ b/src/test/scala/chiselTests/Math.scala @@ -10,41 +10,43 @@ class Math extends ChiselPropSpec { implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) - property ("unsignedBitLength is computed correctly") { - forAll(safeUIntWidth) { case (width: Int) => - for ( offset <- List(-1, 0, 1)) { - val n = (1 << width) + offset - if (n >= 0) { - val d = unsignedBitLength(n) - val t = if (n == 0) 0 else if (offset < 0) width else width + 1 - d shouldEqual (t) + property("unsignedBitLength is computed correctly") { + forAll(safeUIntWidth) { + case (width: Int) => + for (offset <- List(-1, 0, 1)) { + val n = (1 << width) + offset + if (n >= 0) { + val d = unsignedBitLength(n) + val t = if (n == 0) 0 else if (offset < 0) width else width + 1 + d shouldEqual (t) + } } - } } } - property ("signedBitLength is computed correctly") { - forAll(safeUIntWidth) { case (width: Int) => - for ( offset <- List(-1, 0, 1)) { - for ( mult <- List(-1, +1)) { - val n = ((1 << (width - 1)) + offset) * mult - val d = signedBitLength(n) - val t = n match { - case -2 => 2 - case -1 => 1 - case 0 => 0 - case 1 => 2 - case 2 => 3 - case _ => - if (n > 0) { - if (offset < 0) width else width + 1 - } else { - if (offset > 0) width + 1 else width - } + property("signedBitLength is computed correctly") { + forAll(safeUIntWidth) { + case (width: Int) => + for (offset <- List(-1, 0, 1)) { + for (mult <- List(-1, +1)) { + val n = ((1 << (width - 1)) + offset) * mult + val d = signedBitLength(n) + val t = n match { + case -2 => 2 + case -1 => 1 + case 0 => 0 + case 1 => 2 + case 2 => 3 + case _ => + if (n > 0) { + if (offset < 0) width else width + 1 + } else { + if (offset > 0) width + 1 else width + } + } + d shouldEqual (t) } - d shouldEqual (t) } - } } } } diff --git a/src/test/scala/chiselTests/Mem.scala b/src/test/scala/chiselTests/Mem.scala index 8bcd3aac..4dcb1ad4 100644 --- a/src/test/scala/chiselTests/Mem.scala +++ b/src/test/scala/chiselTests/Mem.scala @@ -13,7 +13,7 @@ class MemVecTester extends BasicTester { val (cnt, wrap) = Counter(true.B, 2) mem(0)(0) := 1.U - when (cnt === 1.U) { + when(cnt === 1.U) { assert(mem.read(0.U)(0) === 1.U) stop() } @@ -24,12 +24,12 @@ class SyncReadMemTester extends BasicTester { val mem = SyncReadMem(2, UInt(2.W)) val rdata = mem.read(cnt - 1.U, cnt =/= 0.U) - switch (cnt) { - is (0.U) { mem.write(cnt, 3.U) } - is (1.U) { mem.write(cnt, 2.U) } - is (2.U) { assert(rdata === 3.U) } - is (3.U) { assert(rdata === 2.U) } - is (4.U) { stop() } + switch(cnt) { + is(0.U) { mem.write(cnt, 3.U) } + is(1.U) { mem.write(cnt, 2.U) } + is(2.U) { assert(rdata === 3.U) } + is(3.U) { assert(rdata === 2.U) } + is(4.U) { stop() } } } @@ -47,24 +47,24 @@ class SyncReadMemWriteCollisionTester extends BasicTester { m1.write(cnt, cnt) // Read data from address 0 - when (cnt === 3.U) { + when(cnt === 3.U) { assert(rd0 === 2.U) assert(rd1 === 0.U) } - when (cnt === 4.U) { + when(cnt === 4.U) { stop() } } class SyncReadMemWithZeroWidthTester extends BasicTester { val (cnt, _) = Counter(true.B, 3) - val mem = SyncReadMem(2, UInt(0.W)) - val rdata = mem.read(0.U, true.B) + val mem = SyncReadMem(2, UInt(0.W)) + val rdata = mem.read(0.U, true.B) - switch (cnt) { - is (1.U) { assert(rdata === 0.U) } - is (2.U) { stop() } + switch(cnt) { + is(1.U) { assert(rdata === 0.U) } + is(2.U) { stop() } } } @@ -74,12 +74,12 @@ class HugeSMemTester(size: BigInt) extends BasicTester { val mem = SyncReadMem(size, UInt(8.W)) val rdata = mem.read(cnt - 1.U, cnt =/= 0.U) - switch (cnt) { - is (0.U) { mem.write(cnt, 3.U) } - is (1.U) { mem.write(cnt, 2.U) } - is (2.U) { assert(rdata === 3.U) } - is (3.U) { assert(rdata === 2.U) } - is (4.U) { stop() } + switch(cnt) { + is(0.U) { mem.write(cnt, 3.U) } + is(1.U) { mem.write(cnt, 2.U) } + is(2.U) { assert(rdata === 3.U) } + is(3.U) { assert(rdata === 2.U) } + is(4.U) { stop() } } } class HugeCMemTester(size: BigInt) extends BasicTester { @@ -87,12 +87,12 @@ class HugeCMemTester(size: BigInt) extends BasicTester { val mem = Mem(size, UInt(8.W)) val rdata = mem.read(cnt) - switch (cnt) { - is (0.U) { mem.write(cnt, 3.U) } - is (1.U) { mem.write(cnt, 2.U) } - is (2.U) { assert(rdata === 3.U) } - is (3.U) { assert(rdata === 2.U) } - is (4.U) { stop() } + switch(cnt) { + is(0.U) { mem.write(cnt, 3.U) } + is(1.U) { mem.write(cnt, 2.U) } + is(2.U) { assert(rdata === 3.U) } + is(3.U) { assert(rdata === 2.U) } + is(4.U) { stop() } } } @@ -104,20 +104,20 @@ class SyncReadMemBundleTester extends BasicTester { val mem = SyncReadMem(2, tpe) val rdata = mem.read(cnt - 1.U, cnt =/= 0.U) - switch (cnt) { - is (0.U) { + switch(cnt) { + is(0.U) { val w = Wire(tpe) w.foo := 3.U mem.write(cnt, w) } - is (1.U) { + is(1.U) { val w = Wire(tpe) w.foo := 2.U mem.write(cnt, w) } - is (2.U) { assert(rdata.foo === 3.U) } - is (3.U) { assert(rdata.foo === 2.U) } - is (4.U) { stop() } + is(2.U) { assert(rdata.foo === 3.U) } + is(3.U) { assert(rdata.foo === 2.U) } + is(4.U) { stop() } } } @@ -135,7 +135,7 @@ class MemBundleTester extends BasicTester { w } - when (cnt === 1.U) { + when(cnt === 1.U) { assert(mem.read(0.U).foo === 1.U) stop() } @@ -170,20 +170,20 @@ class MemorySpec extends ChiselPropSpec { val addrWidth = 65 val size = BigInt(1) << addrWidth val smem = compile(new HugeSMemTester(size)) - smem should include (s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size-1}];") + smem should include(s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size - 1}];") val cmem = compile(new HugeCMemTester(size)) - cmem should include (s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size-1}];") + cmem should include(s"reg /* sparse */ [7:0] mem [0:$addrWidth'd${size - 1}];") } property("Implicit conversions with Mem indices should work") { """ - |import chisel3._ - |import chisel3.util.ImplicitConversions._ - |class MyModule extends Module { - | val io = IO(new Bundle {}) - | val mem = Mem(32, UInt(8.W)) - | mem(0) := 0.U - |} - |""".stripMargin should compile + |import chisel3._ + |import chisel3.util.ImplicitConversions._ + |class MyModule extends Module { + | val io = IO(new Bundle {}) + | val mem = Mem(32, UInt(8.W)) + | mem(0) := 0.U + |} + |""".stripMargin should compile } } diff --git a/src/test/scala/chiselTests/MemorySearch.scala b/src/test/scala/chiselTests/MemorySearch.scala index ebfdace1..df1c6b32 100644 --- a/src/test/scala/chiselTests/MemorySearch.scala +++ b/src/test/scala/chiselTests/MemorySearch.scala @@ -7,23 +7,23 @@ import chisel3.stage.ChiselStage class MemorySearch extends Module { val io = IO(new Bundle { - val target = Input(UInt(4.W)) - val en = Input(Bool()) - val done = Output(Bool()) + val target = Input(UInt(4.W)) + val en = Input(Bool()) + val done = Output(Bool()) val address = Output(UInt(3.W)) }) - val vals = Array(0, 4, 15, 14, 2, 5, 13) + val vals = Array(0, 4, 15, 14, 2, 5, 13) val index = RegInit(0.U(3.W)) - val elts = VecInit(vals.map(_.asUInt(4.W))) + val elts = VecInit(vals.map(_.asUInt(4.W))) // val elts = Mem(UInt(32.W), 8) TODO ???? - val elt = elts(index) - val end = !io.en && ((elt === io.target) || (index === 7.U)) - when (io.en) { + val elt = elts(index) + val end = !io.en && ((elt === io.target) || (index === 7.U)) + when(io.en) { index := 0.U - } .elsewhen (!end) { + }.elsewhen(!end) { index := index +% 1.U } - io.done := end + io.done := end io.address := index } @@ -46,7 +46,7 @@ class MemorySearchTester(c: MemorySearch) extends Tester(c) { "LOOKING FOR " + target + " FOUND " + addr) } } -*/ + */ class MemorySearchSpec extends ChiselPropSpec { @@ -54,5 +54,5 @@ class MemorySearchSpec extends ChiselPropSpec { ChiselStage.elaborate { new EnableShiftRegister } } - ignore("MemorySearch should return the correct result") { } + ignore("MemorySearch should return the correct result") {} } diff --git a/src/test/scala/chiselTests/MixedVecSpec.scala b/src/test/scala/chiselTests/MixedVecSpec.scala index 369ed68a..16efafd4 100644 --- a/src/test/scala/chiselTests/MixedVecSpec.scala +++ b/src/test/scala/chiselTests/MixedVecSpec.scala @@ -87,7 +87,7 @@ class MixedVecUIntDynamicIndexTester extends BasicTester { val (cycle, done) = Counter(true.B, n) assert(vecWire(cycle) === cycle) - when (done) { stop() } + when(done) { stop() } } class MixedVecTestBundle extends Bundle { @@ -143,10 +143,10 @@ class MixedVecOneBitTester extends BasicTester { val flag = RegInit(false.B) val oneBit = Reg(MixedVec(Seq(UInt(1.W)))) - when (!flag) { + when(!flag) { oneBit(0) := 1.U(1.W) flag := true.B - } .otherwise { + }.otherwise { assert(oneBit(0) === 1.U) assert(oneBit.asUInt === 1.U) stop() @@ -179,26 +179,29 @@ class MixedVecSpec extends ChiselPropSpec with Utils { } property("MixedVecs should be assignable") { - forAll(safeUIntN(8)) { case (w: Int, v: List[Int]) => - assertTesterPasses { - new MixedVecAssignTester(w, v) - } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { + new MixedVecAssignTester(w, v) + } } } property("MixedVecs should be usable as the type for Reg()") { - forAll(safeUIntN(8)) { case (w: Int, v: List[Int]) => - assertTesterPasses { - new MixedVecRegTester(w, v) - } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { + new MixedVecRegTester(w, v) + } } } property("MixedVecs should be passed through IO") { - forAll(safeUIntN(8)) { case (w: Int, v: List[Int]) => - assertTesterPasses { - new MixedVecIOTester(v.map(i => i.U(w.W))) - } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { + new MixedVecIOTester(v.map(i => i.U(w.W))) + } } } @@ -209,21 +212,21 @@ class MixedVecSpec extends ChiselPropSpec with Utils { } property("MixedVecs should not be able to take hardware types") { - a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + a[ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val hw = Wire(MixedVec(Seq(UInt(8.W), Bool()))) val illegal = MixedVec(hw) }) } - a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + a[ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val hw = Reg(MixedVec(Seq(UInt(8.W), Bool()))) val illegal = MixedVec(hw) }) } - a [ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { + a[ExpectedChiselTypeException] should be thrownBy extractCause[ExpectedChiselTypeException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val v = Input(MixedVec(Seq(UInt(8.W), Bool()))) @@ -238,19 +241,19 @@ class MixedVecSpec extends ChiselPropSpec with Utils { } property("MixedVecs of UInts should be dynamically indexable (via VecInit)") { - assertTesterPasses{ new MixedVecUIntDynamicIndexTester } + assertTesterPasses { new MixedVecUIntDynamicIndexTester } } property("MixedVecs should be creatable from Vecs") { - assertTesterPasses{ new MixedVecFromVecTester } + assertTesterPasses { new MixedVecFromVecTester } } property("It should be possible to bulk connect a MixedVec and a Vec") { - assertTesterPasses{ new MixedVecConnectWithVecTester } + assertTesterPasses { new MixedVecConnectWithVecTester } } property("It should be possible to bulk connect a MixedVec and a Seq") { - assertTesterPasses{ new MixedVecConnectWithSeqTester } + assertTesterPasses { new MixedVecConnectWithSeqTester } } property("MixedVecs of a single 1 bit element should compile and work") { @@ -258,7 +261,7 @@ class MixedVecSpec extends ChiselPropSpec with Utils { } property("Connecting a MixedVec and something of different size should report a ChiselException") { - an [IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + an[IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(MixedVec(Seq(UInt(8.W), Bool()))) @@ -267,7 +270,7 @@ class MixedVecSpec extends ChiselPropSpec with Utils { io.out := seq }) } - an [IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + an[IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(MixedVec(Seq(UInt(8.W), Bool()))) diff --git a/src/test/scala/chiselTests/Module.scala b/src/test/scala/chiselTests/Module.scala index f0d6dbe7..13dbe1e9 100644 --- a/src/test/scala/chiselTests/Module.scala +++ b/src/test/scala/chiselTests/Module.scala @@ -12,7 +12,7 @@ import scala.io.Source import scala.annotation.nowarn class SimpleIO extends Bundle { - val in = Input(UInt(32.W)) + val in = Input(UInt(32.W)) val out = Output(UInt(32.W)) } @@ -23,13 +23,13 @@ class PlusOne extends Module { class ModuleVec(val n: Int) extends Module { val io = IO(new Bundle { - val ins = Input(Vec(n, UInt(32.W))) + val ins = Input(Vec(n, UInt(32.W))) val outs = Output(Vec(n, UInt(32.W))) }) - val pluses = VecInit(Seq.fill(n){ Module(new PlusOne).io }) + val pluses = VecInit(Seq.fill(n) { Module(new PlusOne).io }) for (i <- 0 until n) { pluses(i).in := io.ins(i) - io.outs(i) := pluses(i).out + io.outs(i) := pluses(i).out } } @@ -49,7 +49,7 @@ class ModuleWhen extends Module { val inc = Module(new PlusOne).io inc.in := io.s.in io.s.out := inc.out - } otherwise { io.s.out := io.s.in } + }.otherwise { io.s.out := io.s.in } } class ModuleForgetWrapper extends Module { @@ -69,13 +69,13 @@ class ModuleRewrap extends Module { } class ModuleWrapper(gen: => Module) extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) val child = Module(gen) override val desiredName = s"${child.desiredName}Wrapper" } class NullModuleWrapper extends Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) override lazy val desiredName = s"${child.desiredName}Wrapper" println(s"My name is ${name}") val child = Module(new ModuleWire) @@ -87,34 +87,34 @@ class ModuleSpec extends ChiselPropSpec with Utils { ChiselStage.elaborate { new ModuleVec(2) } } - ignore("ModuleVecTester should return the correct result") { } + ignore("ModuleVecTester should return the correct result") {} property("ModuleWire should elaborate") { ChiselStage.elaborate { new ModuleWire } } - ignore("ModuleWireTester should return the correct result") { } + ignore("ModuleWireTester should return the correct result") {} property("ModuleWhen should elaborate") { ChiselStage.elaborate { new ModuleWhen } } - ignore("ModuleWhenTester should return the correct result") { } + ignore("ModuleWhenTester should return the correct result") {} property("Forgetting a Module() wrapper should result in an error") { - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new ModuleForgetWrapper } }).getMessage should include("attempted to instantiate a Module without wrapping it") } property("Double wrapping a Module should result in an error") { - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new ModuleDoubleWrap } }).getMessage should include("Called Module() twice without instantiating a Module") } property("Rewrapping an already instantiated Module should result in an error") { - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new ModuleRewrap } }).getMessage should include("This is probably due to rewrapping a Module instance") } @@ -140,7 +140,7 @@ class ModuleSpec extends ChiselPropSpec with Utils { property("object Module.currentModule should return an Option reference to the current Module") { def checkModule(mod: Module): Boolean = Module.currentModule.map(_ eq mod).getOrElse(false) ChiselStage.elaborate(new Module { - val io = IO(new Bundle { }) + val io = IO(new Bundle {}) assert(Module.currentModule.get eq this) assert(checkModule(this)) }) @@ -148,24 +148,27 @@ class ModuleSpec extends ChiselPropSpec with Utils { property("object chisel3.util.experimental.getAnnotations should return current annotations.") { case class DummyAnnotation() extends NoTargetAnnotation with Unserializable - (new ChiselStage).transform(Seq( - ChiselGeneratorAnnotation(() => new RawModule { - assert(chisel3.util.experimental.getAnnotations().contains(DummyAnnotation())) - }), - DummyAnnotation(), - NoRunFirrtlCompilerAnnotation)) + (new ChiselStage).transform( + Seq( + ChiselGeneratorAnnotation(() => + new RawModule { + assert(chisel3.util.experimental.getAnnotations().contains(DummyAnnotation())) + } + ), + DummyAnnotation(), + NoRunFirrtlCompilerAnnotation + ) + ) } property("DataMirror.modulePorts should work") { ChiselStage.elaborate(new Module { - val io = IO(new Bundle { }) + val io = IO(new Bundle {}) val m = Module(new chisel3.Module { val a = IO(UInt(8.W)) val b = IO(Bool()) }) - assert(DataMirror.modulePorts(m) == Seq( - "clock" -> m.clock, "reset" -> m.reset, - "a" -> m.a, "b" -> m.b)) + assert(DataMirror.modulePorts(m) == Seq("clock" -> m.clock, "reset" -> m.reset, "a" -> m.a, "b" -> m.b)) }) } @@ -186,21 +189,25 @@ class ModuleSpec extends ChiselPropSpec with Utils { mod } // Note that this is just top-level ports, Aggregates are not flattened - DataMirror.modulePorts(mod) should contain theSameElementsInOrderAs Seq( - "clock" -> mod.clock, - "reset" -> mod.reset, - "io" -> mod.io, - "extra" -> mod.extra + (DataMirror.modulePorts(mod) should contain).theSameElementsInOrderAs( + Seq( + "clock" -> mod.clock, + "reset" -> mod.reset, + "io" -> mod.io, + "extra" -> mod.extra + ) ) // Delete this when the deprecated API is deleted // Note this also uses deprecated Port import chisel3.internal.firrtl.Port import SpecifiedDirection.{Input => IN, Unspecified} - mod.getPorts should contain theSameElementsInOrderAs Seq( - Port(mod.clock, IN), - Port(mod.reset, IN), - Port(mod.io, Unspecified), - Port(mod.extra, IN) + (mod.getPorts should contain).theSameElementsInOrderAs( + Seq( + Port(mod.clock, IN), + Port(mod.reset, IN), + Port(mod.io, Unspecified), + Port(mod.extra, IN) + ) ): @nowarn // delete when Port and getPorts become private } @@ -230,15 +237,16 @@ class ModuleSpec extends ChiselPropSpec with Utils { "io_in" -> mod.io.in, "extra" -> mod.extra ) - DataMirror.fullModulePorts(mod) should contain theSameElementsInOrderAs expected + (DataMirror.fullModulePorts(mod) should contain).theSameElementsInOrderAs(expected) } property("A desiredName parameterized by a submodule should work") { - ChiselStage.elaborate(new ModuleWrapper(new ModuleWire)).name should be ("ModuleWireWrapper") + ChiselStage.elaborate(new ModuleWrapper(new ModuleWire)).name should be("ModuleWireWrapper") } property("A name generating a null pointer exception should provide a good error message") { - (the [ChiselException] thrownBy extractCause[ChiselException] (ChiselStage.elaborate(new NullModuleWrapper))) - .getMessage should include ("desiredName of chiselTests.NullModuleWrapper is null") + (the[ChiselException] thrownBy extractCause[ChiselException]( + ChiselStage.elaborate(new NullModuleWrapper) + )).getMessage should include("desiredName of chiselTests.NullModuleWrapper is null") } property("The name of a module in a function should be sane") { def foo = { @@ -262,7 +270,7 @@ class ModuleSpec extends ChiselPropSpec with Utils { } property("emitVerilog((new PlusOne()..) shall produce a valid Verilog file in a subfolder") { - emitVerilog(new PlusOne(), Array("--target-dir", "generated")) + emitVerilog(new PlusOne(), Array("--target-dir", "generated")) val s = Source.fromFile("generated/PlusOne.v").mkString("") assert(s.contains("assign io_out = io_in + 32'h1")) } diff --git a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala b/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala index c55276ce..1a55fb3f 100644 --- a/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala +++ b/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala @@ -4,7 +4,7 @@ package chiselTests import chisel3.stage.ChiselStage -class ModuleExplicitResetSpec extends ChiselFlatSpec { +class ModuleExplicitResetSpec extends ChiselFlatSpec { "A Module with an explicit reset in compatibility mode" should "elaborate" in { import Chisel._ diff --git a/src/test/scala/chiselTests/MulLookup.scala b/src/test/scala/chiselTests/MulLookup.scala index dd539b2a..0f67ea34 100644 --- a/src/test/scala/chiselTests/MulLookup.scala +++ b/src/test/scala/chiselTests/MulLookup.scala @@ -7,9 +7,9 @@ import chisel3.testers.BasicTester class MulLookup(val w: Int) extends Module { val io = IO(new Bundle { - val x = Input(UInt(w.W)) - val y = Input(UInt(w.W)) - val z = Output(UInt((2 * w).W)) + val x = Input(UInt(w.W)) + val y = Input(UInt(w.W)) + val z = Output(UInt((2 * w).W)) }) val tbl = VecInit( for { @@ -32,7 +32,7 @@ class MulLookupSpec extends ChiselPropSpec { property("Mul lookup table should return the correct result") { forAll(smallPosInts, smallPosInts) { (x: Int, y: Int) => - assertTesterPasses{ new MulLookupTester(3, x, y) } + assertTesterPasses { new MulLookupTester(3, x, y) } } } } diff --git a/src/test/scala/chiselTests/MultiAssign.scala b/src/test/scala/chiselTests/MultiAssign.scala index fb5d6986..4cb51feb 100644 --- a/src/test/scala/chiselTests/MultiAssign.scala +++ b/src/test/scala/chiselTests/MultiAssign.scala @@ -9,16 +9,16 @@ import chisel3.util._ class LastAssignTester() extends BasicTester { val countOnClockCycles = true.B - val (cnt, wrap) = Counter(countOnClockCycles,2) + val (cnt, wrap) = Counter(countOnClockCycles, 2) val test = Wire(UInt(4.W)) - assert(test === 7.U) // allow read references before assign references + assert(test === 7.U) // allow read references before assign references test := 13.U - assert(test === 7.U) // output value should be position-independent + assert(test === 7.U) // output value should be position-independent test := 7.U - assert(test === 7.U) // this obviously should work + assert(test === 7.U) // this obviously should work when(cnt === 1.U) { stop() @@ -27,7 +27,7 @@ class LastAssignTester() extends BasicTester { class MultiAssignSpec extends ChiselFlatSpec { "The last assignment" should "be used when multiple assignments happen" in { - assertTesterPasses{ new LastAssignTester } + assertTesterPasses { new LastAssignTester } } } @@ -35,7 +35,7 @@ class IllegalAssignSpec extends ChiselFlatSpec with Utils { "Reassignments to literals" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate{ + ChiselStage.elaborate { new BasicTester { 15.U := 7.U } @@ -47,7 +47,7 @@ class IllegalAssignSpec extends ChiselFlatSpec with Utils { "Reassignments to ops" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate{ + ChiselStage.elaborate { new BasicTester { (15.U + 1.U) := 7.U } @@ -59,7 +59,7 @@ class IllegalAssignSpec extends ChiselFlatSpec with Utils { "Reassignments to bit slices" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate{ + ChiselStage.elaborate { new BasicTester { (15.U)(1, 0) := 7.U } @@ -71,7 +71,7 @@ class IllegalAssignSpec extends ChiselFlatSpec with Utils { "Bulk-connecting two read-only nodes" should "be disallowed" in { intercept[chisel3.internal.ChiselException] { extractCause[ChiselException] { - ChiselStage.elaborate{ + ChiselStage.elaborate { new BasicTester { (15.U + 1.U) <> 7.U } diff --git a/src/test/scala/chiselTests/MultiClockSpec.scala b/src/test/scala/chiselTests/MultiClockSpec.scala index 3b52e5b9..2553f3b3 100644 --- a/src/test/scala/chiselTests/MultiClockSpec.scala +++ b/src/test/scala/chiselTests/MultiClockSpec.scala @@ -18,11 +18,11 @@ class ClockDividerTest extends BasicTester { val reg2 = withClock(clock2) { RegInit(0.U(8.W)) } reg2 := reg2 + 1.U - when (reg1 < 10.U) { + when(reg1 < 10.U) { assert(reg2 === reg1 / 2.U) // 1:2 clock relationship } - when (reg1 === 10.U) { + when(reg1 === 10.U) { stop() } } @@ -45,7 +45,7 @@ class MultiClockSubModuleTest extends BasicTester { val inst = withClockAndReset(otherClock, otherReset) { Module(new SubModule) } - when (done) { + when(done) { // The counter in inst should come out of reset later and increment at half speed assert(inst.io.out === 3.U) stop() @@ -59,14 +59,14 @@ class WithResetTest extends BasicTester { reg := reg + 1.U val (cycle, done) = Counter(true.B, 10) - when (cycle < 7.U) { + when(cycle < 7.U) { assert(reg === cycle) - } .elsewhen (cycle === 7.U) { + }.elsewhen(cycle === 7.U) { reset2 := true.B - } .elsewhen (cycle === 8.U) { + }.elsewhen(cycle === 8.U) { assert(reg === 0.U) } - when (done) { stop() } + when(done) { stop() } } /** Test Mem ports with different clocks */ @@ -82,7 +82,7 @@ class MultiClockMemTest extends BasicTester { // Write port 1 walks through writing 123 val waddr = RegInit(0.U(3.W)) waddr := waddr + 1.U - when (cycle < 8.U) { + when(cycle < 8.U) { mem(waddr) := 123.U } @@ -90,27 +90,27 @@ class MultiClockMemTest extends BasicTester { val rdata = mem(raddr) // Check each write from write port 1 - when (cycle > 0.U && cycle < 9.U) { + when(cycle > 0.U && cycle < 9.U) { assert(rdata === 123.U) } // Write port 2 walks through writing 456 on 2nd time through withClock(clock2) { - when (cycle >= 8.U && cycle < 16.U) { + when(cycle >= 8.U && cycle < 16.U) { mem(waddr) := 456.U // write 456 to different address } } // Check that every even address gets 456 - when (cycle > 8.U && cycle < 17.U) { - when (raddr % 2.U === 0.U) { + when(cycle > 8.U && cycle < 17.U) { + when(raddr % 2.U === 0.U) { assert(rdata === 456.U) - } .otherwise { + }.otherwise { assert(rdata === 123.U) } } - when (done) { stop() } + when(done) { stop() } } class MultiClockSpec extends ChiselFlatSpec { @@ -151,7 +151,7 @@ class MultiClockSpec extends ChiselFlatSpec { // The reg is always in reset so will never decrement chisel3.assert(reg === 6.U) val (_, done) = Counter(true.B, 4) - when (done) { stop() } + when(done) { stop() } }) } @@ -168,7 +168,7 @@ class MultiClockSpec extends ChiselFlatSpec { chisel3.assert(0.U === 1.U) } val (_, done) = Counter(true.B, 2) - when (done) { stop() } + when(done) { stop() } }) // Check that reset will block assertTesterPasses(new BasicTester { @@ -176,7 +176,7 @@ class MultiClockSpec extends ChiselFlatSpec { chisel3.assert(0.U === 1.U) } val (_, done) = Counter(true.B, 2) - when (done) { stop() } + when(done) { stop() } }) // Check that no rising edge will block assertTesterPasses(new BasicTester { @@ -184,7 +184,7 @@ class MultiClockSpec extends ChiselFlatSpec { chisel3.assert(0.U === 1.U) } val (_, done) = Counter(true.B, 2) - when (done) { stop() } + when(done) { stop() } }) } } diff --git a/src/test/scala/chiselTests/MultiIOModule.scala b/src/test/scala/chiselTests/MultiIOModule.scala index 9abf324b..c65d8fc4 100644 --- a/src/test/scala/chiselTests/MultiIOModule.scala +++ b/src/test/scala/chiselTests/MultiIOModule.scala @@ -6,7 +6,7 @@ import chisel3._ import chisel3.testers.BasicTester class MultiIOPlusOne extends Module { - val in = IO(Input(UInt(32.W))) + val in = IO(Input(UInt(32.W))) val out = IO(Output(UInt(32.W))) out := in + 1.asUInt @@ -33,8 +33,7 @@ trait MultiIOTrait extends Module { // Composition of the two above traits, example of IO composition directly using multiple top-level // IOs rather than indirectly by constraining the type of the single .io field. -class ComposedMultiIOModule extends Module - with LiteralOutputTrait with MultiIOTrait { +class ComposedMultiIOModule extends Module with LiteralOutputTrait with MultiIOTrait { val topModuleIO = IO(Input(UInt(32.W))) myTraitIO := topModuleIO } diff --git a/src/test/scala/chiselTests/MuxSpec.scala b/src/test/scala/chiselTests/MuxSpec.scala index 33024f0b..03505f2d 100644 --- a/src/test/scala/chiselTests/MuxSpec.scala +++ b/src/test/scala/chiselTests/MuxSpec.scala @@ -4,21 +4,21 @@ package chiselTests import chisel3._ import chisel3.stage.ChiselStage -import chisel3.util.{MuxLookup, log2Ceil} +import chisel3.util.{log2Ceil, MuxLookup} import chisel3.testers.BasicTester class MuxTester extends BasicTester { assert(Mux(0.B, 1.U, 2.U) === 2.U) assert(Mux(1.B, 1.U, 2.U) === 1.U) val dontCareMux1 = Wire(UInt()) - dontCareMux1 := Mux(0.B, DontCare, 4.U) // note: Mux output of type Element + dontCareMux1 := Mux(0.B, DontCare, 4.U) // note: Mux output of type Element assert(dontCareMux1 === 4.U) val dontCareMux2 = Wire(UInt()) - dontCareMux2 := Mux(1.B, 3.U, DontCare) // note: Mux output of type Element + dontCareMux2 := Mux(1.B, 3.U, DontCare) // note: Mux output of type Element assert(dontCareMux2 === 3.U) - Mux(0.B, 3.U, DontCare) // just to make sure nothing crashes, any result is valid + Mux(0.B, 3.U, DontCare) // just to make sure nothing crashes, any result is valid stop() } @@ -45,27 +45,28 @@ class MuxLookupExhaustiveSpec extends ChiselPropSpec { val incomplete = () => Seq(0.U -> 1.U, 1.U -> 2.U, 2.U -> 3.U) property("The default value should not be optimized away for an incomplete MuxLookup") { - ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, incomplete)) should include (firrtlLit) + ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, incomplete)) should include(firrtlLit) } val exhaustive = () => (3.U -> 0.U) +: incomplete() property("The default value should be optimized away for an exhaustive MuxLookup") { - ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, exhaustive)) should not include (firrtlLit) + (ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, exhaustive)) should not).include(firrtlLit) } val overlap = () => (4096.U -> 0.U) +: incomplete() property("The default value should not be optimized away for a MuxLookup with 2^{keyWidth} non-distinct mappings") { - ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, overlap)) should include (firrtlLit) + ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, overlap)) should include(firrtlLit) } val nonLiteral = () => { val foo = Wire(UInt()); (foo -> 1.U) +: incomplete() } property("The default value should not be optimized away for a MuxLookup with a non-literal") { - ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteral)) should include (firrtlLit) + ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteral)) should include(firrtlLit) } val nonLiteralStillFull = () => { val foo = Wire(UInt()); (foo -> 1.U) +: exhaustive() } property("The default value should be optimized away for a MuxLookup with a non-literal that is still full") { - ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteralStillFull)) should not include (firrtlLit) + (ChiselStage.emitChirrtl(new MuxLookupWrapper(keyWidth, default, nonLiteralStillFull)) should not) + .include(firrtlLit) } } diff --git a/src/test/scala/chiselTests/NamingAnnotationTest.scala b/src/test/scala/chiselTests/NamingAnnotationTest.scala index 2226a48a..ded321cd 100644 --- a/src/test/scala/chiselTests/NamingAnnotationTest.scala +++ b/src/test/scala/chiselTests/NamingAnnotationTest.scala @@ -70,7 +70,7 @@ class NamedModule extends NamedModuleTester { def FunctionMockupInner(): UInt = { val my2A = 1.U val my2B = expectName(my2A +& 2.U, "test_myNested_my2B") - val my2C = my2B +& 3.U // should get named at enclosing scope + val my2C = my2B +& 3.U // should get named at enclosing scope my2C } @@ -85,14 +85,14 @@ class NamedModule extends NamedModuleTester { for ((d, i) <- myD.zipWithIndex) expectName(d, s"test_myD_$i") - myC +& 4.U // named at enclosing scope + myC +& 4.U // named at enclosing scope } // chiselName "implicitly" applied def ImplicitlyNamed(): UInt = { val implicitA = expectName(1.U + 2.U, "test3_implicitA") val implicitB = expectName(implicitA + 3.U, "test3_implicitB") - implicitB + 2.U // named at enclosing scope + implicitB + 2.U // named at enclosing scope } // Ensure this applies a partial name if there is no return value @@ -115,8 +115,9 @@ class NamedModule extends NamedModuleTester { } // Test that contents of anonymous functions are named - Seq((0, "anonInner"), (1, "anonInner_1"), (2, "anonInner_2")).foreach { case (in, name) => - val anonInner = expectName(test3 + in.U, name) + Seq((0, "anonInner"), (1, "anonInner_1"), (2, "anonInner_2")).foreach { + case (in, name) => + val anonInner = expectName(test3 + in.U, name) } NoReturnFunction() @@ -126,8 +127,8 @@ class NamedModule extends NamedModuleTester { class NameCollisionModule extends NamedModuleTester { @chiselName def repeatedCalls(id: Int): UInt = { - val test = expectName(1.U + 3.U, s"test_$id") // should disambiguate by invocation order - test + 2.U + val test = expectName(1.U + 3.U, s"test_$id") // should disambiguate by invocation order + test + 2.U } // chiselName applied by default to this @@ -167,7 +168,7 @@ object NonNamedHelper { myVal } - def NonNamedFunction() : UInt = { + def NonNamedFunction(): UInt = { val myVal = NamedFunction() myVal } @@ -230,7 +231,6 @@ class NoChiselNamePrefixTester extends NamedModuleTester { expectName(fizz.c, "fizz_c") } - /** A simple test that checks the recursive function val naming annotation both compiles and * generates the expected names. */ @@ -265,7 +265,7 @@ class NamingAnnotationSpec extends ChiselPropSpec { } property("NonBuilderFunction should run outside a Builder context") { - NonNamedHelper.NonBuilderFunction() should be (2) + NonNamedHelper.NonBuilderFunction() should be(2) } property("NoChiselNamePrefix should prevent prefixing when using @chiselName") { diff --git a/src/test/scala/chiselTests/OneHotMuxSpec.scala b/src/test/scala/chiselTests/OneHotMuxSpec.scala index 7608a3e7..b069b219 100644 --- a/src/test/scala/chiselTests/OneHotMuxSpec.scala +++ b/src/test/scala/chiselTests/OneHotMuxSpec.scala @@ -11,7 +11,6 @@ import org.scalatest._ import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers - class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners { "simple one hot mux with uint should work" in { assertTesterPasses(new SimpleOneHotTester) @@ -32,7 +31,7 @@ class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners { assertTesterPasses(new ParameterizedAggregateOneHotTester) } "simple one hot mux with all aggregates containing inferred width fixed values should NOT work" in { - intercept [ChiselException] { + intercept[ChiselException] { assertTesterPasses(new InferredWidthAggregateOneHotTester) } } @@ -56,12 +55,14 @@ class OneHotMuxSpec extends AnyFreeSpec with Matchers with ChiselRunners { class SimpleOneHotTester extends BasicTester { val out = Wire(UInt()) - out := Mux1H(Seq( - false.B -> 2.U, - false.B -> 4.U, - true.B -> 8.U, - false.B -> 11.U - )) + out := Mux1H( + Seq( + false.B -> 2.U, + false.B -> 4.U, + true.B -> 8.U, + false.B -> 11.U + ) + ) assert(out === 8.U) @@ -70,12 +71,14 @@ class SimpleOneHotTester extends BasicTester { class SIntOneHotTester extends BasicTester { val out = Wire(SInt()) - out := Mux1H(Seq( - false.B -> (-3).S, - true.B -> (-5).S, - false.B -> (-7).S, - false.B -> (-11).S - )) + out := Mux1H( + Seq( + false.B -> (-3).S, + true.B -> (-5).S, + false.B -> (-7).S, + false.B -> (-11).S + ) + ) assert(out === (-5).S) @@ -85,12 +88,14 @@ class SIntOneHotTester extends BasicTester { class FixedPointOneHotTester extends BasicTester { val out = Wire(FixedPoint(8.W, 4.BP)) - out := Mux1H(Seq( - false.B -> (-1.5).F(1.BP), - true.B -> (-2.25).F(2.BP), - false.B -> (-4.125).F(3.BP), - false.B -> (-11.625).F(3.BP) - )) + out := Mux1H( + Seq( + false.B -> (-1.5).F(1.BP), + true.B -> (-2.25).F(2.BP), + false.B -> (-4.125).F(3.BP), + false.B -> (-11.625).F(3.BP) + ) + ) assert(out === (-2.25).F(4.BP)) @@ -100,12 +105,14 @@ class FixedPointOneHotTester extends BasicTester { class AllSameFixedPointOneHotTester extends BasicTester { val out = Wire(FixedPoint(12.W, 3.BP)) - out := Mux1H(Seq( - false.B -> (-1.5).F(12.W, 3.BP), - true.B -> (-2.25).F(12.W, 3.BP), - false.B -> (-4.125).F(12.W, 3.BP), - false.B -> (-11.625).F(12.W, 3.BP) - )) + out := Mux1H( + Seq( + false.B -> (-1.5).F(12.W, 3.BP), + true.B -> (-2.25).F(12.W, 3.BP), + false.B -> (-4.125).F(12.W, 3.BP), + false.B -> (-11.625).F(12.W, 3.BP) + ) + ) assert(out === (-2.25).F(14.W, 4.BP)) @@ -199,7 +206,6 @@ class ParameterizedAggregateOneHot[T <: Data](valGen: HasMakeLit[T], outGen: T) val out = Output(outGen) }) - val values = (0 until 4).map { n => valGen.makeLit(n) } val terms = io.selectors.zip(values) io.out := Mux1H(terms) @@ -229,22 +235,26 @@ class InferredWidthAggregateOneHotTester extends BasicTester { b3.a := -0.0078125.F(7.BP) b3.b.c := -0.00390625.F(8.BP) - val o1 = Mux1H(Seq( - false.B -> b0, - false.B -> b1, - true.B -> b2, - false.B -> b3 - )) + val o1 = Mux1H( + Seq( + false.B -> b0, + false.B -> b1, + true.B -> b2, + false.B -> b3 + ) + ) assert(o1.a === -0.015625.F(5.BP)) assert(o1.b.c === -0.0078125.F(6.BP)) - val o2 = Mux1H(Seq( - false.B -> b0, - true.B -> b1, - false.B -> b2, - false.B -> b3 - )) + val o2 = Mux1H( + Seq( + false.B -> b0, + true.B -> b1, + false.B -> b2, + false.B -> b3 + ) + ) assert(o2.a === -0.0625.F(3.BP)) assert(o2.b.c === -0.03125.F(4.BP)) @@ -283,12 +293,14 @@ class DifferentBundleOneHotTester extends BasicTester { b3.a := -0.0078125.F(7.BP) b3.b.c := -0.00390625.F(8.BP) - val o1 = Mux1H(Seq( - false.B -> b0, - false.B -> b1, - true.B -> b2, - false.B -> b3 - )) + val o1 = Mux1H( + Seq( + false.B -> b0, + false.B -> b1, + true.B -> b2, + false.B -> b3 + ) + ) stop() } diff --git a/src/test/scala/chiselTests/OptionBundle.scala b/src/test/scala/chiselTests/OptionBundle.scala index 0f3502a4..628e117d 100644 --- a/src/test/scala/chiselTests/OptionBundle.scala +++ b/src/test/scala/chiselTests/OptionBundle.scala @@ -55,7 +55,7 @@ class OptionBundleSpec extends ChiselFlatSpec with Utils { } "A Bundle with an Option field" should "assert out accessing a None Option field" in { - a [Exception] should be thrownBy extractCause[Exception] { + a[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate { new InvalidOptionBundleTester() } } } diff --git a/src/test/scala/chiselTests/Padding.scala b/src/test/scala/chiselTests/Padding.scala index cb1da0b0..7950c203 100644 --- a/src/test/scala/chiselTests/Padding.scala +++ b/src/test/scala/chiselTests/Padding.scala @@ -7,7 +7,7 @@ import chisel3.stage.ChiselStage class Padder extends Module { val io = IO(new Bundle { - val a = Input(UInt(4.W)) + val a = Input(UInt(4.W)) val asp = Output(SInt(8.W)) val aup = Output(UInt(8.W)) }) @@ -31,7 +31,7 @@ class PadsTester(c: Pads) extends Tester(c) { expect(c.io.aup, test_a) } } -*/ + */ class PadderSpec extends ChiselPropSpec { @@ -39,5 +39,5 @@ class PadderSpec extends ChiselPropSpec { ChiselStage.elaborate { new Padder } } - ignore("PadderTester should return the correct result") { } + ignore("PadderTester should return the correct result") {} } diff --git a/src/test/scala/chiselTests/ParameterizedModule.scala b/src/test/scala/chiselTests/ParameterizedModule.scala index 3016728d..3ad054f8 100644 --- a/src/test/scala/chiselTests/ParameterizedModule.scala +++ b/src/test/scala/chiselTests/ParameterizedModule.scala @@ -7,7 +7,7 @@ import chisel3.testers.BasicTester class ParameterizedModule(invert: Boolean) extends Module { val io = IO(new Bundle { - val in = Input(Bool()) + val in = Input(Bool()) val out = Output(Bool()) }) if (invert) { diff --git a/src/test/scala/chiselTests/PopCount.scala b/src/test/scala/chiselTests/PopCount.scala index 42609dff..eaea7a2c 100644 --- a/src/test/scala/chiselTests/PopCount.scala +++ b/src/test/scala/chiselTests/PopCount.scala @@ -9,7 +9,7 @@ import chisel3.testers.BasicTester class PopCountTester(n: Int) extends BasicTester { val x = RegInit(0.U(n.W)) x := x + 1.U - when (RegNext(x === ~0.U(n.W))) { stop() } + when(RegNext(x === ~0.U(n.W))) { stop() } val result = PopCount(x.asBools) val expected = x.asBools.foldLeft(0.U)(_ +& _) @@ -20,6 +20,6 @@ class PopCountTester(n: Int) extends BasicTester { class PopCountSpec extends ChiselPropSpec { property("Mul lookup table should return the correct result") { - forAll(smallPosInts) { (n: Int) => assertTesterPasses { new PopCountTester(n) } } + forAll(smallPosInts) { (n: Int) => assertTesterPasses { new PopCountTester(n) } } } } diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala index c7e819ec..7d584cea 100644 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ b/src/test/scala/chiselTests/PrintableSpec.scala @@ -20,6 +20,7 @@ case class PrintfAnnotation(target: ReferenceTarget) extends SingleTargetAnnotat } object PrintfAnnotation { + /** Create annotation for a given [[printf]]. * @param c component to be annotated */ @@ -38,7 +39,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { private case class Printf(str: String, args: Seq[String]) private def getPrintfs(firrtl: String): Seq[Printf] = { def processArgs(str: String): Seq[String] = - str split "," map (_.trim) filter (_.nonEmpty) + str.split(",").map(_.trim).filter(_.nonEmpty) def processBody(str: String): (String, Seq[String]) = { str match { case StringRegex(_, fmt, args) => @@ -47,14 +48,14 @@ class PrintableSpec extends AnyFlatSpec with Matchers { } } - firrtl split "\n" collect { + firrtl.split("\n").collect { case PrintfRegex(matched) => val (str, args) = processBody(matched) Printf(str, args) } } - behavior of "Printable & Custom Interpolator" + behavior.of("Printable & Custom Interpolator") it should "pass exact strings through" in { class MyModule extends BasicTester { @@ -63,7 +64,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("An exact string", Seq())) => - case e => fail() + case e => fail() } } it should "handle Printable and String concatination" in { @@ -73,7 +74,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("First Second Third", Seq())) => - case e => fail() + case e => fail() } } it should "call toString on non-Printable objects" in { @@ -84,7 +85,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("myInt = 1234", Seq())) => - case e => fail() + case e => fail() } } it should "generate proper printf for simple Decimal printing" in { @@ -95,7 +96,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("myWire = %d", Seq("myWire"))) => - case e => fail() + case e => fail() } } it should "handle printing literals" in { @@ -116,7 +117,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%%", Seq())) => - case e => fail() + case e => fail() } } it should "correctly emit tab" in { @@ -126,7 +127,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("\\t", Seq())) => - case e => fail() + case e => fail() } } it should "support names of circuit elements including submodule IO" in { @@ -150,10 +151,8 @@ class PrintableSpec extends AnyFlatSpec with Matchers { } val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { - case Seq(Printf("foo", Seq()), - Printf("myWire.foo", Seq()), - Printf("myInst.io.fizz", Seq())) => - case e => fail() + case Seq(Printf("foo", Seq()), Printf("myWire.foo", Seq()), Printf("myInst.io.fizz", Seq())) => + case e => fail() } } it should "handle printing ports of submodules" in { @@ -169,7 +168,7 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%d", Seq("myInst.io.fizz"))) => - case e => fail() + case e => fail() } } it should "print UInts and SInts as Decimal by default" in { @@ -181,20 +180,19 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { case Seq(Printf("%d & %d", Seq("myUInt", "mySInt"))) => - case e => fail() + case e => fail() } } it should "print Vecs like Scala Seqs by default" in { class MyModule extends BasicTester { val myVec = Wire(Vec(4, UInt(32.W))) - myVec foreach (_ := 0.U) + myVec.foreach(_ := 0.U) printf(p"$myVec") } val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { - case Seq(Printf("Vec(%d, %d, %d, %d)", - Seq("myVec[0]", "myVec[1]", "myVec[2]", "myVec[3]"))) => - case e => fail() + case Seq(Printf("Vec(%d, %d, %d, %d)", Seq("myVec[0]", "myVec[1]", "myVec[2]", "myVec[3]"))) => + case e => fail() } } it should "print Bundles like Scala Maps by default" in { @@ -209,9 +207,8 @@ class PrintableSpec extends AnyFlatSpec with Matchers { } val firrtl = ChiselStage.emitChirrtl(new MyModule) getPrintfs(firrtl) match { - case Seq(Printf("AnonymousBundle(foo -> %d, bar -> %d)", - Seq("myBun.foo", "myBun.bar"))) => - case e => fail() + case Seq(Printf("AnonymousBundle(foo -> %d, bar -> %d)", Seq("myBun.foo", "myBun.bar"))) => + case e => fail() } } it should "get emitted with a name and annotated" in { @@ -243,10 +240,10 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList // check for expected annotations - exactly(3, annoLines) should include ("chiselTests.PrintfAnnotation") - exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>farewell") - exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>printf") - exactly(1, annoLines) should include ("~PrintfAnnotationTest|PrintfAnnotationTest>howdy") + exactly(3, annoLines) should include("chiselTests.PrintfAnnotation") + exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>farewell") + exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>printf") + exactly(1, annoLines) should include("~PrintfAnnotationTest|PrintfAnnotationTest>howdy") // read in FIRRTL file val firFile = new File(testDir, "PrintfAnnotationTest.fir") @@ -254,8 +251,14 @@ class PrintableSpec extends AnyFlatSpec with Matchers { val firLines = scala.io.Source.fromFile(firFile).getLines.toList // check that verification components have expected names - exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : howdy""") - exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : printf""") - exactly(1, firLines) should include ("""printf(clock, UInt<1>("h1"), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : farewell""") + exactly(1, firLines) should include( + """printf(clock, UInt<1>("h1"), "hello AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : howdy""" + ) + exactly(1, firLines) should include( + """printf(clock, UInt<1>("h1"), "goodbye AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : printf""" + ) + exactly(1, firLines) should include( + """printf(clock, UInt<1>("h1"), "adieu AnonymousBundle(foo -> %d, bar -> %d)", myBun.foo, myBun.bar) : farewell""" + ) } } diff --git a/src/test/scala/chiselTests/Printf.scala b/src/test/scala/chiselTests/Printf.scala index 24b5e090..4171f97f 100644 --- a/src/test/scala/chiselTests/Printf.scala +++ b/src/test/scala/chiselTests/Printf.scala @@ -24,7 +24,7 @@ class MultiPrintfTester() extends BasicTester { } class ASCIIPrintableTester extends BasicTester { - printf(PString((0x20 to 0x7e) map (_.toChar) mkString "")) + printf(PString((0x20 to 0x7e).map(_.toChar).mkString(""))) stop() } diff --git a/src/test/scala/chiselTests/QueueFlushSpec.scala b/src/test/scala/chiselTests/QueueFlushSpec.scala index 9e0c6bb4..d70f9605 100644 --- a/src/test/scala/chiselTests/QueueFlushSpec.scala +++ b/src/test/scala/chiselTests/QueueFlushSpec.scala @@ -9,24 +9,36 @@ import chisel3.util.random.LFSR import treadle.WriteVcdAnnotation /** Test elements can be enqueued and dequeued when flush is tied to false - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class ThingsPassThroughFlushQueueTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends ThingsPassThroughTester(elements, queueDepth, bitWidth, tap, useSyncReadMem, hasFlush = true) +class ThingsPassThroughFlushQueueTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends ThingsPassThroughTester(elements, queueDepth, bitWidth, tap, useSyncReadMem, hasFlush = true) /** Generic flush queue tester base class - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -abstract class FlushQueueTesterBase(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +abstract class FlushQueueTesterBase( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, hasFlush = true)) val elems = VecInit(elements.map(_.U)) val inCnt = Counter(elements.length + 1) @@ -51,31 +63,35 @@ abstract class FlushQueueTesterBase(elements: Seq[Int], queueDepth: Int, bitWidt //check that queue gets flushed when queue is full assert(q.io.count === 0.U) assert(!q.io.deq.valid, "Expected to not be able to dequeue when flush is asserted the previous cycle") - assert(q.io.enq.ready, "Expected enqueue to be ready when flush was asserted the previous cycle because queue should be empty") - } + assert( + q.io.enq.ready, + "Expected enqueue to be ready when flush was asserted the previous cycle because queue should be empty" + ) + } when(inCnt.value === elements.length.U) { //stop when all entries are enqueued stop() } } /** Test queue can flush at random times - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { - flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly - val halfCnt = (queueDepth + 1)/2 +class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { + flush := LFSR(16)((tap + 3) % 16) //testing a flush when flush is called randomly + val halfCnt = (queueDepth + 1) / 2 when(q.io.deq.fire) { //ensure that what comes out is what comes in assert(currQCnt <= queueDepth.U) assert(elems(outCnt) === q.io.deq.bits) outCnt := outCnt + 1.U - when (currQCnt > 0.U) { + when(currQCnt > 0.U) { currQCnt := Mux(q.io.enq.fire, currQCnt, (currQCnt - 1.U)) } } @@ -87,19 +103,20 @@ class QueueGetsFlushedTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, } /** Test queue can flush when empty - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class EmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class EmptyFlushEdgecaseTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { val cycleCounter = Counter(elements.length + 1) cycleCounter.inc() //counts every cycle //testing a flush when queue is empty - flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued + flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued q.io.enq.valid := (inCnt.value < elements.length.U) && !flush when(q.io.deq.fire) { @@ -109,23 +126,29 @@ class EmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: I } /** Test queue can enqueue during a flush - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class EnqueueEmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class EnqueueEmptyFlushEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { val cycleCounter = Counter(elements.length + 1) val outCounter = Counter(elements.length + 1) //testing an enqueue during a flush - flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued + flush := (cycleCounter.value === 0.U && inCnt.value === 0.U) //flushed only before anything is enqueued cycleCounter.inc() //counts every cycle when(q.io.deq.fire) { - //flush and enqueue were both active on the first cycle, + //flush and enqueue were both active on the first cycle, //so that element is flushed immediately which makes outCnt off by one assert(elems(outCounter.value + 1.U) === q.io.deq.bits) //ensure that what comes out is what comes in outCounter.inc() @@ -133,14 +156,20 @@ class EnqueueEmptyFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitW } /** Test queue can flush when full - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class FullQueueFlushEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { //testing a flush when queue is full flush := (currQCnt === queueDepth.U) @@ -150,7 +179,7 @@ class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidt assert(currQCnt <= queueDepth.U) assert(elems(outCnt) === q.io.deq.bits) outCnt := outCnt + 1.U - when (currQCnt > 0.U) { + when(currQCnt > 0.U) { currQCnt := currQCnt - 1.U } } @@ -162,18 +191,24 @@ class FullQueueFlushEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidt } /** Test queue can dequeue on the same cycle as a flush - * + * * @param elements The sequence of elements used in the queue * @param queueDepth The max number of entries in the queue * @param bitWidth Integer size of the data type used in the queue * @param tap Integer tap('seed') for the LFSR * @param useSyncReadMem True uses SyncReadMem instead of Mem as an internal memory element */ -class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { +class DequeueFullQueueEdgecaseTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean) + extends FlushQueueTesterBase(elements, queueDepth, bitWidth, tap, useSyncReadMem) { //Queue should be able to dequeue when queue is not empty and flush is high //testing a flush when dequeue is called - flush := currQCnt === (queueDepth/2).U + flush := currQCnt === (queueDepth / 2).U q.io.enq.valid := !flushRegister q.io.deq.ready := flush @@ -185,14 +220,14 @@ class DequeueFullQueueEdgecaseTester (elements: Seq[Int], queueDepth: Int, bitWi } when(flush) { //The outcount register is one count behind because the dequeue happens at the same time as the flush - outCnt := outCnt + currQCnt + 1.U + outCnt := outCnt + currQCnt + 1.U currQCnt := 0.U //resets the number of items currently inside queue assert(currQCnt === 0.U || q.io.deq.valid) } when(flushRegister) { //check that queue gets flushed when queue is full assert(q.io.deq.fire === false.B) - } + } } @@ -200,7 +235,7 @@ class QueueFlushSpec extends ChiselPropSpec { // Disable shrinking on error. implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty) implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) - + property("Queue should have things pass through") { forAll(vecSizes, safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) => whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) { @@ -249,7 +284,7 @@ class QueueFlushSpec extends ChiselPropSpec { property("Queue should be able to dequeue when flush is high") { forAll(Gen.choose(3, 5), safeUIntN(20), Gen.choose(0, 15), Gen.oneOf(true, false)) { (depth, se, tap, isSync) => whenever(se._1 >= 1 && depth >= 1 && se._2.nonEmpty) { - assertTesterPasses ( + assertTesterPasses( new DequeueFullQueueEdgecaseTester(se._2, depth, se._1, tap, isSync), annotations = Seq(WriteVcdAnnotation) ) diff --git a/src/test/scala/chiselTests/QueueSpec.scala b/src/test/scala/chiselTests/QueueSpec.scala index 9eb6c20c..eaeb7f01 100644 --- a/src/test/scala/chiselTests/QueueSpec.scala +++ b/src/test/scala/chiselTests/QueueSpec.scala @@ -9,7 +9,14 @@ import chisel3.testers.BasicTester import chisel3.util._ import chisel3.util.random.LFSR -class ThingsPassThroughTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean, hasFlush: Boolean) extends BasicTester { +class ThingsPassThroughTester( + elements: Seq[Int], + queueDepth: Int, + bitWidth: Int, + tap: Int, + useSyncReadMem: Boolean, + hasFlush: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem, hasFlush = hasFlush)) val elems = VecInit(elements.map { _.asUInt() @@ -34,7 +41,8 @@ class ThingsPassThroughTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int } } -class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem)) val elems = VecInit(elements.map { _.asUInt() @@ -62,7 +70,8 @@ class QueueReasonableReadyValid(elements: Seq[Int], queueDepth: Int, bitWidth: I } } -class CountIsCorrectTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +class CountIsCorrectTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, useSyncReadMem = useSyncReadMem)) val elems = VecInit(elements.map { _.asUInt(bitWidth.W) @@ -115,7 +124,8 @@ class QueueSinglePipeTester(elements: Seq[Int], bitWidth: Int, tap: Int, useSync } } -class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends BasicTester { val q = Module(new Queue(UInt(bitWidth.W), queueDepth, pipe = true, useSyncReadMem = useSyncReadMem)) val elems = VecInit(elements.map { _.asUInt(bitWidth.W) @@ -141,8 +151,9 @@ class QueuePipeTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I } } -class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { - val q = Module(new Queue(UInt(bitWidth.W), queueDepth, flow = true, useSyncReadMem = useSyncReadMem)) +class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends BasicTester { + val q = Module(new Queue(UInt(bitWidth.W), queueDepth, flow = true, useSyncReadMem = useSyncReadMem)) val elems = VecInit(elements.map { _.asUInt() }) @@ -169,7 +180,8 @@ class QueueFlowTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: I } } -class QueueFactoryTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) extends BasicTester { +class QueueFactoryTester(elements: Seq[Int], queueDepth: Int, bitWidth: Int, tap: Int, useSyncReadMem: Boolean) + extends BasicTester { val enq = Wire(Decoupled(UInt(bitWidth.W))) val deq = Queue(enq, queueDepth, useSyncReadMem = useSyncReadMem) @@ -276,6 +288,7 @@ class QueueSpec extends ChiselPropSpec { val in = Wire(Decoupled(Bool())) val iQueue = Queue.irrevocable(in, 1) } - (new chisel3.stage.phases.Elaborate).transform(Seq(chisel3.stage.ChiselGeneratorAnnotation(() => new IrrevocableQueue))) + (new chisel3.stage.phases.Elaborate) + .transform(Seq(chisel3.stage.ChiselGeneratorAnnotation(() => new IrrevocableQueue))) } } diff --git a/src/test/scala/chiselTests/RangeSpec.scala b/src/test/scala/chiselTests/RangeSpec.scala index 0b888ab6..bc723bf6 100644 --- a/src/test/scala/chiselTests/RangeSpec.scala +++ b/src/test/scala/chiselTests/RangeSpec.scala @@ -9,5 +9,4 @@ import firrtl.ir.{Closed, Open} import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers -class RangeSpec extends AnyFreeSpec with Matchers { -} +class RangeSpec extends AnyFreeSpec with Matchers {} diff --git a/src/test/scala/chiselTests/RawModuleSpec.scala b/src/test/scala/chiselTests/RawModuleSpec.scala index 3d678d1f..95687e82 100644 --- a/src/test/scala/chiselTests/RawModuleSpec.scala +++ b/src/test/scala/chiselTests/RawModuleSpec.scala @@ -7,7 +7,7 @@ import chisel3.stage.ChiselStage import chisel3.testers.BasicTester class UnclockedPlusOne extends RawModule { - val in = IO(Input(UInt(32.W))) + val in = IO(Input(UInt(32.W))) val out = IO(Output(UInt(32.W))) out := in + 1.asUInt @@ -22,14 +22,14 @@ class RawModuleTester extends BasicTester { class PlusOneModule extends Module { val io = IO(new Bundle { - val in = Input(UInt(32.W)) + val in = Input(UInt(32.W)) val out = Output(UInt(32.W)) }) io.out := io.in + 1.asUInt } class RawModuleWithImplicitModule extends RawModule { - val in = IO(Input(UInt(32.W))) + val in = IO(Input(UInt(32.W))) val out = IO(Output(UInt(32.W))) val clk = IO(Input(Clock())) val rst = IO(Input(Bool())) @@ -72,7 +72,6 @@ class RawModuleSpec extends ChiselFlatSpec with Utils { assertTesterPasses({ new ImplicitModuleInRawModuleTester }) } - "ImplicitModule directly in a RawModule" should "fail" in { intercept[chisel3.internal.ChiselException] { extractCause[ChiselException] { diff --git a/src/test/scala/chiselTests/RebindingSpec.scala b/src/test/scala/chiselTests/RebindingSpec.scala index 808b1137..5dc0589e 100644 --- a/src/test/scala/chiselTests/RebindingSpec.scala +++ b/src/test/scala/chiselTests/RebindingSpec.scala @@ -7,22 +7,26 @@ import chisel3.stage.ChiselStage class RebindingSpec extends ChiselFlatSpec with Utils { "Rebinding a literal" should "fail" in { - a [BindingException] should be thrownBy extractCause[BindingException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle { - val a = 4.U - }) - } } + a[BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle { + val a = 4.U + }) + } + } } } "Rebinding a hardware type" should "fail" in { - a [BindingException] should be thrownBy extractCause[BindingException] { - ChiselStage.elaborate { new Module { - val io = IO(new Bundle { - val a = Reg(UInt(32.W)) - }) - } } + a[BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate { + new Module { + val io = IO(new Bundle { + val a = Reg(UInt(32.W)) + }) + } + } } } } diff --git a/src/test/scala/chiselTests/RecordSpec.scala b/src/test/scala/chiselTests/RecordSpec.scala index e6986efb..da3840dd 100644 --- a/src/test/scala/chiselTests/RecordSpec.scala +++ b/src/test/scala/chiselTests/RecordSpec.scala @@ -50,18 +50,18 @@ trait RecordSpecUtils { queue.io.enq.valid := false.B val (cycle, done) = Counter(true.B, 4) - when (cycle === 0.U) { + when(cycle === 0.U) { queue.io.enq.bits("foo") := 1234.U queue.io.enq.bits("bar") := 5678.U queue.io.enq.valid := true.B } - when (cycle === 1.U) { + when(cycle === 1.U) { queue.io.deq.ready := true.B assert(queue.io.deq.valid === true.B) assert(queue.io.deq.bits("foo").asUInt === 1234.U) assert(queue.io.deq.bits("bar").asUInt === 5678.U) } - when (done) { + when(done) { stop() } } @@ -91,16 +91,16 @@ trait RecordSpecUtils { } class RecordTypeTester extends BasicTester { - val wire0 = Wire(new CustomBundle("0"-> UInt(32.W))) - val wire1 = Reg(new CustomBundle("0"-> UInt(32.W))) - val wire2 = Wire(new CustomBundle("1"-> UInt(32.W))) + val wire0 = Wire(new CustomBundle("0" -> UInt(32.W))) + val wire1 = Reg(new CustomBundle("0" -> UInt(32.W))) + val wire2 = Wire(new CustomBundle("1" -> UInt(32.W))) require(DataMirror.checkTypeEquivalence(wire0, wire1)) require(!DataMirror.checkTypeEquivalence(wire1, wire2)) } } class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils { - behavior of "Records" + behavior.of("Records") they should "bulk connect similarly to Bundles" in { ChiselStage.elaborate { new MyModule(fooBarType, fooBarType) } @@ -124,7 +124,7 @@ class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils { } } } - e.getMessage should include ("contains aliased fields named (bar,foo)") + e.getMessage should include("contains aliased fields named (bar,foo)") } they should "follow UInt serialization/deserialization API" in { @@ -144,13 +144,13 @@ class RecordSpec extends ChiselFlatSpec with RecordSpecUtils with Utils { } "Bulk connect on Record" should "check that the fields match" in { - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new MyModule(fooBarType, new CustomBundle("bar" -> UInt(32.W))) } - }).getMessage should include ("Right Record missing field") + }).getMessage should include("Right Record missing field") - (the [ChiselException] thrownBy extractCause[ChiselException] { + (the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate { new MyModule(new CustomBundle("bar" -> UInt(32.W)), fooBarType) } - }).getMessage should include ("Left Record missing field") + }).getMessage should include("Left Record missing field") } "CustomBundle" should "work like built-in aggregates" in { diff --git a/src/test/scala/chiselTests/Reg.scala b/src/test/scala/chiselTests/Reg.scala index a02e6fa5..c814a030 100644 --- a/src/test/scala/chiselTests/Reg.scala +++ b/src/test/scala/chiselTests/Reg.scala @@ -13,19 +13,19 @@ class RegSpec extends ChiselFlatSpec { "Reg" should "be of the same type and width as t" in { class RegOutTypeWidthTester extends BasicTester { val reg = Reg(UInt(2.W)) - DataMirror.widthOf(reg) should be (2.W) + DataMirror.widthOf(reg) should be(2.W) } - ChiselStage.elaborate{ new RegOutTypeWidthTester } + ChiselStage.elaborate { new RegOutTypeWidthTester } } "RegNext" should "be of unknown width" in { class RegUnknownWidthTester extends BasicTester { val reg1 = RegNext(2.U(3.W)) - DataMirror.widthOf(reg1).known should be (false) + DataMirror.widthOf(reg1).known should be(false) val reg2 = RegNext(2.U(3.W), 4.U) - DataMirror.widthOf(reg2).known should be (false) + DataMirror.widthOf(reg2).known should be(false) val reg3 = RegNext(2.U(3.W), 4.U(5.W)) - DataMirror.widthOf(reg3).known should be (false) + DataMirror.widthOf(reg3).known should be(false) } ChiselStage.elaborate { new RegUnknownWidthTester } } @@ -33,11 +33,11 @@ class RegSpec extends ChiselFlatSpec { "RegInit" should "have width only if specified in the literal" in { class RegForcedWidthTester extends BasicTester { val reg1 = RegInit(20.U) - DataMirror.widthOf(reg1).known should be (false) + DataMirror.widthOf(reg1).known should be(false) val reg2 = RegInit(20.U(7.W)) - DataMirror.widthOf(reg2) should be (7.W) + DataMirror.widthOf(reg2) should be(7.W) } - ChiselStage.elaborate{ new RegForcedWidthTester } + ChiselStage.elaborate { new RegForcedWidthTester } } } @@ -52,22 +52,22 @@ class ShiftTester(n: Int) extends BasicTester { } class ShiftResetTester(n: Int) extends BasicTester { - val (cntVal, done) = Counter(true.B, n-1) + val (cntVal, done) = Counter(true.B, n - 1) val start = 23.U val sr = ShiftRegister(cntVal + 23.U, n, 1.U, true.B) when(done) { - assert(sr === (if(n == 0) cntVal + 23.U else 1.U)) + assert(sr === (if (n == 0) cntVal + 23.U else 1.U)) stop() } } class ShiftRegisterSpec extends ChiselPropSpec { property("ShiftRegister should shift") { - forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses{ new ShiftTester(shift) } } + forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftTester(shift) } } } property("ShiftRegister should reset all values inside") { - forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses{ new ShiftResetTester(shift) } } + forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftResetTester(shift) } } } } @@ -76,8 +76,9 @@ class ShiftsTester(n: Int) extends BasicTester { val start = 23.U val srs = ShiftRegisters(cntVal + start, n) when(RegNext(done)) { - srs.zipWithIndex.foreach{ case (data, index) => - assert(data === (23 + n - 1 - index).U) + srs.zipWithIndex.foreach { + case (data, index) => + assert(data === (23 + n - 1 - index).U) } stop() } @@ -85,6 +86,6 @@ class ShiftsTester(n: Int) extends BasicTester { class ShiftRegistersSpec extends ChiselPropSpec { property("ShiftRegisters should shift") { - forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses{ new ShiftsTester(shift) } } + forAll(Gen.choose(0, 4)) { (shift: Int) => assertTesterPasses { new ShiftsTester(shift) } } } } diff --git a/src/test/scala/chiselTests/ResetSpec.scala b/src/test/scala/chiselTests/ResetSpec.scala index 7a5d444d..fe0273b3 100644 --- a/src/test/scala/chiselTests/ResetSpec.scala +++ b/src/test/scala/chiselTests/ResetSpec.scala @@ -35,10 +35,9 @@ class AbstractResetDontCareModule extends RawModule { bulkAggPort <> DontCare } - class ResetSpec extends ChiselFlatSpec with Utils { - behavior of "Reset" + behavior.of("Reset") it should "be able to be connected to DontCare" in { ChiselStage.elaborate(new AbstractResetDontCareModule) @@ -75,7 +74,7 @@ class ResetSpec extends ChiselFlatSpec with Utils { assert(inst.rst.isInstanceOf[chisel3.ResetType]) io.out := inst.out }) - sync should include ("always @(posedge clk)") + sync should include("always @(posedge clk)") val async = compile(new Module { val io = IO(new Bundle { @@ -87,27 +86,27 @@ class ResetSpec extends ChiselFlatSpec with Utils { assert(inst.rst.isInstanceOf[chisel3.ResetType]) io.out := inst.out }) - async should include ("always @(posedge clk or posedge rst)") + async should include("always @(posedge clk or posedge rst)") } - behavior of "Users" + behavior.of("Users") they should "be able to force implicit reset to be synchronous" in { val fir = ChiselStage.emitChirrtl(new Module with RequireSyncReset { - reset shouldBe a [Bool] + reset shouldBe a[Bool] }) - fir should include ("input reset : UInt<1>") + fir should include("input reset : UInt<1>") } they should "be able to force implicit reset to be asynchronous" in { val fir = ChiselStage.emitChirrtl(new Module with RequireAsyncReset { - reset shouldBe an [AsyncReset] + reset shouldBe an[AsyncReset] }) - fir should include ("input reset : AsyncReset") + fir should include("input reset : AsyncReset") } "Chisel" should "error if sync and async modules are nested" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module with RequireAsyncReset { val mod = Module(new Module with RequireSyncReset) }) diff --git a/src/test/scala/chiselTests/Risc.scala b/src/test/scala/chiselTests/Risc.scala index 74c55a12..e0eacb90 100644 --- a/src/test/scala/chiselTests/Risc.scala +++ b/src/test/scala/chiselTests/Risc.scala @@ -8,47 +8,47 @@ import chisel3.util._ class Risc extends Module { val io = IO(new Bundle { - val isWr = Input(Bool()) + val isWr = Input(Bool()) val wrAddr = Input(UInt(8.W)) val wrData = Input(Bits(32.W)) - val boot = Input(Bool()) - val valid = Output(Bool()) - val out = Output(Bits(32.W)) + val boot = Input(Bool()) + val valid = Output(Bool()) + val out = Output(Bits(32.W)) }) val memSize = 256 val file = Mem(memSize, Bits(32.W)) val code = Mem(memSize, Bits(32.W)) - val pc = RegInit(0.U(8.W)) + val pc = RegInit(0.U(8.W)) val add_op :: imm_op :: Nil = Enum(2) val inst = code(pc) - val op = inst(31,24) - val rci = inst(23,16) - val rai = inst(15, 8) - val rbi = inst( 7, 0) + val op = inst(31, 24) + val rci = inst(23, 16) + val rai = inst(15, 8) + val rbi = inst(7, 0) val ra = Mux(rai === 0.U, 0.U, file(rai)) val rb = Mux(rbi === 0.U, 0.U, file(rbi)) val rc = Wire(Bits(32.W)) io.valid := false.B - io.out := 0.U - rc := 0.U + io.out := 0.U + rc := 0.U - when (io.isWr) { + when(io.isWr) { code(io.wrAddr) := io.wrData - } .elsewhen (io.boot) { + }.elsewhen(io.boot) { pc := 0.U - } .otherwise { + }.otherwise { switch(op) { is(add_op) { rc := ra +% rb } is(imm_op) { rc := (rai << 8) | rbi } } io.out := rc - when (rci === 255.U) { + when(rci === 255.U) { io.valid := true.B - } .otherwise { + }.otherwise { file(rci) := rc } pc := pc +% 1.U @@ -111,7 +111,7 @@ class RiscTester(c: Risc) extends Tester(c) { expect(k <= 10, "TIME LIMIT") expect(c.io.out, 4) } -*/ + */ class RiscSpec extends ChiselPropSpec { @@ -119,5 +119,5 @@ class RiscSpec extends ChiselPropSpec { ChiselStage.elaborate { new Risc } } - ignore("RiscTester should return the correct result") { } + ignore("RiscTester should return the correct result") {} } diff --git a/src/test/scala/chiselTests/SIntOps.scala b/src/test/scala/chiselTests/SIntOps.scala index 222d0ba7..55b4c915 100644 --- a/src/test/scala/chiselTests/SIntOps.scala +++ b/src/test/scala/chiselTests/SIntOps.scala @@ -82,7 +82,7 @@ class SIntOpsTester(c: SIntOps) extends Tester(c) { expect(c.io.greateqout, int(test_a >= test_b)) } } -*/ + */ class SIntLitExtractTester extends BasicTester { assert(-5.S(1) === true.B) @@ -105,12 +105,12 @@ class SIntOpsSpec extends ChiselPropSpec with Utils { } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new NegativeShift(SInt())) } } - ignore("SIntOpsTester should return the correct result") { } + ignore("SIntOpsTester should return the correct result") {} property("Bit extraction on literals should work for all non-negative indices") { assertTesterPasses(new SIntLitExtractTester) diff --git a/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala b/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala index 540cc456..94f5ccc7 100644 --- a/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala +++ b/src/test/scala/chiselTests/ScalaIntervalSimulatorTest.scala @@ -11,87 +11,87 @@ class ScalaIntervalSimulatorSpec extends AnyFreeSpec with Matchers { "clip tests" - { "Should work for closed ranges" in { val sim = ScalaIntervalSimulator(range"[2,4]") - sim.clip(BigDecimal(1.0)) should be (2.0) - sim.clip(BigDecimal(2.0)) should be (2.0) - sim.clip(BigDecimal(3.0)) should be (3.0) - sim.clip(BigDecimal(4.0)) should be (4.0) - sim.clip(BigDecimal(5.0)) should be (4.0) + sim.clip(BigDecimal(1.0)) should be(2.0) + sim.clip(BigDecimal(2.0)) should be(2.0) + sim.clip(BigDecimal(3.0)) should be(3.0) + sim.clip(BigDecimal(4.0)) should be(4.0) + sim.clip(BigDecimal(5.0)) should be(4.0) } "Should work for closed ranges with binary point" in { val sim = ScalaIntervalSimulator(range"[2,6].2") - sim.clip(BigDecimal(1.75)) should be (2.0) - sim.clip(BigDecimal(2.0)) should be (2.0) - sim.clip(BigDecimal(2.25)) should be (2.25) - sim.clip(BigDecimal(2.5)) should be (2.5) - sim.clip(BigDecimal(5.75)) should be (5.75) - sim.clip(BigDecimal(6.0)) should be (6.0) - sim.clip(BigDecimal(6.25)) should be (6.0) - sim.clip(BigDecimal(6.5)) should be (6.0) - sim.clip(BigDecimal(8.5)) should be (6.0) + sim.clip(BigDecimal(1.75)) should be(2.0) + sim.clip(BigDecimal(2.0)) should be(2.0) + sim.clip(BigDecimal(2.25)) should be(2.25) + sim.clip(BigDecimal(2.5)) should be(2.5) + sim.clip(BigDecimal(5.75)) should be(5.75) + sim.clip(BigDecimal(6.0)) should be(6.0) + sim.clip(BigDecimal(6.25)) should be(6.0) + sim.clip(BigDecimal(6.5)) should be(6.0) + sim.clip(BigDecimal(8.5)) should be(6.0) } "Should work for open ranges" in { val sim = ScalaIntervalSimulator(range"(2,4)") - sim.clip(BigDecimal(1.0)) should be (3.0) - sim.clip(BigDecimal(2.0)) should be (3.0) - sim.clip(BigDecimal(3.0)) should be (3.0) - sim.clip(BigDecimal(4.0)) should be (3.0) - sim.clip(BigDecimal(5.0)) should be (3.0) + sim.clip(BigDecimal(1.0)) should be(3.0) + sim.clip(BigDecimal(2.0)) should be(3.0) + sim.clip(BigDecimal(3.0)) should be(3.0) + sim.clip(BigDecimal(4.0)) should be(3.0) + sim.clip(BigDecimal(5.0)) should be(3.0) } "Should work for open ranges with binary point" in { val sim = ScalaIntervalSimulator(range"(2,6).2") - sim.clip(BigDecimal(1.75)) should be (2.25) - sim.clip(BigDecimal(2.0)) should be (2.25) - sim.clip(BigDecimal(2.25)) should be (2.25) - sim.clip(BigDecimal(2.5)) should be (2.5) - sim.clip(BigDecimal(5.75)) should be (5.75) - sim.clip(BigDecimal(6.0)) should be (5.75) - sim.clip(BigDecimal(6.25)) should be (5.75) - sim.clip(BigDecimal(6.5)) should be (5.75) - sim.clip(BigDecimal(8.5)) should be (5.75) + sim.clip(BigDecimal(1.75)) should be(2.25) + sim.clip(BigDecimal(2.0)) should be(2.25) + sim.clip(BigDecimal(2.25)) should be(2.25) + sim.clip(BigDecimal(2.5)) should be(2.5) + sim.clip(BigDecimal(5.75)) should be(5.75) + sim.clip(BigDecimal(6.0)) should be(5.75) + sim.clip(BigDecimal(6.25)) should be(5.75) + sim.clip(BigDecimal(6.5)) should be(5.75) + sim.clip(BigDecimal(8.5)) should be(5.75) } } "wrap tests" - { "Should work for closed ranges" in { val sim = ScalaIntervalSimulator(range"[2,6]") - sim.wrap(BigDecimal(1.0)) should be (6.0) - sim.wrap(BigDecimal(2.0)) should be (2.0) - sim.wrap(BigDecimal(3.0)) should be (3.0) - sim.wrap(BigDecimal(4.0)) should be (4.0) - sim.wrap(BigDecimal(5.0)) should be (5.0) - sim.wrap(BigDecimal(6.0)) should be (6.0) - sim.wrap(BigDecimal(7.0)) should be (2.0) + sim.wrap(BigDecimal(1.0)) should be(6.0) + sim.wrap(BigDecimal(2.0)) should be(2.0) + sim.wrap(BigDecimal(3.0)) should be(3.0) + sim.wrap(BigDecimal(4.0)) should be(4.0) + sim.wrap(BigDecimal(5.0)) should be(5.0) + sim.wrap(BigDecimal(6.0)) should be(6.0) + sim.wrap(BigDecimal(7.0)) should be(2.0) } "Should work for closed ranges with binary point" in { val sim = ScalaIntervalSimulator(range"[2,6].2") - sim.wrap(BigDecimal(1.75)) should be (6.0) - sim.wrap(BigDecimal(2.0)) should be (2.0) - sim.wrap(BigDecimal(2.25)) should be (2.25) - sim.wrap(BigDecimal(2.5)) should be (2.5) - sim.wrap(BigDecimal(5.75)) should be (5.75) - sim.wrap(BigDecimal(6.0)) should be (6.0) - sim.wrap(BigDecimal(6.25)) should be (2.0) - sim.wrap(BigDecimal(6.5)) should be (2.25) + sim.wrap(BigDecimal(1.75)) should be(6.0) + sim.wrap(BigDecimal(2.0)) should be(2.0) + sim.wrap(BigDecimal(2.25)) should be(2.25) + sim.wrap(BigDecimal(2.5)) should be(2.5) + sim.wrap(BigDecimal(5.75)) should be(5.75) + sim.wrap(BigDecimal(6.0)) should be(6.0) + sim.wrap(BigDecimal(6.25)) should be(2.0) + sim.wrap(BigDecimal(6.5)) should be(2.25) } "Should work for open ranges" in { val sim = ScalaIntervalSimulator(range"(2,6)") - sim.wrap(BigDecimal(1.0)) should be (4.0) - sim.wrap(BigDecimal(2.0)) should be (5.0) - sim.wrap(BigDecimal(3.0)) should be (3.0) - sim.wrap(BigDecimal(4.0)) should be (4.0) - sim.wrap(BigDecimal(5.0)) should be (5.0) - sim.wrap(BigDecimal(6.0)) should be (3.0) - sim.wrap(BigDecimal(7.0)) should be (4.0) + sim.wrap(BigDecimal(1.0)) should be(4.0) + sim.wrap(BigDecimal(2.0)) should be(5.0) + sim.wrap(BigDecimal(3.0)) should be(3.0) + sim.wrap(BigDecimal(4.0)) should be(4.0) + sim.wrap(BigDecimal(5.0)) should be(5.0) + sim.wrap(BigDecimal(6.0)) should be(3.0) + sim.wrap(BigDecimal(7.0)) should be(4.0) } "Should work for open ranges with binary point" in { val sim = ScalaIntervalSimulator(range"(2,6).2") - sim.wrap(BigDecimal(1.75)) should be (5.5) - sim.wrap(BigDecimal(2.0)) should be (5.75) - sim.wrap(BigDecimal(2.25)) should be (2.25) - sim.wrap(BigDecimal(2.5)) should be (2.5) - sim.wrap(BigDecimal(5.75)) should be (5.75) - sim.wrap(BigDecimal(6.0)) should be (2.25) - sim.wrap(BigDecimal(6.25)) should be (2.5) - sim.wrap(BigDecimal(7.0)) should be (3.25) + sim.wrap(BigDecimal(1.75)) should be(5.5) + sim.wrap(BigDecimal(2.0)) should be(5.75) + sim.wrap(BigDecimal(2.25)) should be(2.25) + sim.wrap(BigDecimal(2.5)) should be(2.5) + sim.wrap(BigDecimal(5.75)) should be(5.75) + sim.wrap(BigDecimal(6.0)) should be(2.25) + sim.wrap(BigDecimal(6.25)) should be(2.5) + sim.wrap(BigDecimal(7.0)) should be(3.25) } } } diff --git a/src/test/scala/chiselTests/Stack.scala b/src/test/scala/chiselTests/Stack.scala index cb21e2c0..085f4e34 100644 --- a/src/test/scala/chiselTests/Stack.scala +++ b/src/test/scala/chiselTests/Stack.scala @@ -8,25 +8,25 @@ import chisel3.util._ class ChiselStack(val depth: Int) extends Module { val io = IO(new Bundle { - val push = Input(Bool()) - val pop = Input(Bool()) - val en = Input(Bool()) - val dataIn = Input(UInt(32.W)) + val push = Input(Bool()) + val pop = Input(Bool()) + val en = Input(Bool()) + val dataIn = Input(UInt(32.W)) val dataOut = Output(UInt(32.W)) }) val stack_mem = Mem(depth, UInt(32.W)) - val sp = RegInit(0.U(log2Ceil(depth + 1).W)) - val out = RegInit(0.U(32.W)) + val sp = RegInit(0.U(log2Ceil(depth + 1).W)) + val out = RegInit(0.U(32.W)) - when (io.en) { + when(io.en) { when(io.push && (sp < depth.asUInt)) { stack_mem(sp) := io.dataIn sp := sp +% 1.U - } .elsewhen(io.pop && (sp > 0.U)) { + }.elsewhen(io.pop && (sp > 0.U)) { sp := sp -% 1.U } - when (sp > 0.U) { + when(sp > 0.U) { out := stack_mem(sp -% 1.U) } } @@ -65,7 +65,7 @@ class StackTester(c: Stack) extends Tester(c) { expect(c.io.dataOut, dataOut) } } -*/ + */ class StackSpec extends ChiselPropSpec { @@ -73,5 +73,5 @@ class StackSpec extends ChiselPropSpec { ChiselStage.elaborate { new ChiselStack(2) } } - ignore("StackTester should return the correct result") { } + ignore("StackTester should return the correct result") {} } diff --git a/src/test/scala/chiselTests/Stop.scala b/src/test/scala/chiselTests/Stop.scala index 1634f776..25aae2d9 100644 --- a/src/test/scala/chiselTests/Stop.scala +++ b/src/test/scala/chiselTests/Stop.scala @@ -12,7 +12,7 @@ class StopTester() extends BasicTester { class StopImmediatelyTester extends BasicTester { val cycle = RegInit(0.asUInt(4.W)) cycle := cycle + 1.U - when (cycle === 4.U) { + when(cycle === 4.U) { stop() } assert(cycle =/= 5.U, "Simulation did not exit upon executing stop()") diff --git a/src/test/scala/chiselTests/StrongEnum.scala b/src/test/scala/chiselTests/StrongEnum.scala index 404c3f66..c43d832a 100644 --- a/src/test/scala/chiselTests/StrongEnum.scala +++ b/src/test/scala/chiselTests/StrongEnum.scala @@ -142,21 +142,21 @@ class StrongEnumFSM extends Module { io.out := (state === sTwo1s) io.state := state - switch (state) { - is (sNone) { - when (io.in) { + switch(state) { + is(sNone) { + when(io.in) { state := sOne1 } } - is (sOne1) { - when (io.in) { + is(sOne1) { + when(io.in) { state := sTwo1s - } .otherwise { + }.otherwise { state := sNone } } - is (sTwo1s) { - when (!io.in) { + is(sTwo1s) { + when(!io.in) { state := sNone } } @@ -164,7 +164,7 @@ class StrongEnumFSM extends Module { } class CastToUIntTester extends BasicTester { - for ((enum,lit) <- EnumExample.all zip EnumExample.litValues) { + for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) { val mod = Module(new CastToUInt) mod.io.in := enum assert(mod.io.out === lit) @@ -173,7 +173,7 @@ class CastToUIntTester extends BasicTester { } class CastFromLitTester extends BasicTester { - for ((enum,lit) <- EnumExample.all zip EnumExample.litValues) { + for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) { val mod = Module(new CastFromLit(lit)) assert(mod.io.out === enum) assert(mod.io.valid === true.B) @@ -182,16 +182,15 @@ class CastFromLitTester extends BasicTester { } class CastFromNonLitTester extends BasicTester { - for ((enum,lit) <- EnumExample.all zip EnumExample.litValues) { + for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) { val mod = Module(new CastFromNonLit) mod.io.in := lit assert(mod.io.out === enum) assert(mod.io.valid === true.B) } - val invalid_values = (1 until (1 << EnumExample.getWidth)). - filter(!EnumExample.litValues.map(_.litValue).contains(_)). - map(_.U) + val invalid_values = + (1 until (1 << EnumExample.getWidth)).filter(!EnumExample.litValues.map(_.litValue).contains(_)).map(_.U) for (invalid_val <- invalid_values) { val mod = Module(new CastFromNonLit) @@ -204,16 +203,15 @@ class CastFromNonLitTester extends BasicTester { } class SafeCastFromNonLitTester extends BasicTester { - for ((enum,lit) <- EnumExample.all zip EnumExample.litValues) { + for ((enum, lit) <- EnumExample.all.zip(EnumExample.litValues)) { val mod = Module(new SafeCastFromNonLit) mod.io.in := lit assert(mod.io.out === enum) assert(mod.io.valid === true.B) } - val invalid_values = (1 until (1 << EnumExample.getWidth)). - filter(!EnumExample.litValues.map(_.litValue).contains(_)). - map(_.U) + val invalid_values = + (1 until (1 << EnumExample.getWidth)).filter(!EnumExample.litValues.map(_.litValue).contains(_)).map(_.U) for (invalid_val <- invalid_values) { val mod = Module(new SafeCastFromNonLit) @@ -231,8 +229,10 @@ class CastToInvalidEnumTester extends BasicTester { } class EnumOpsTester extends BasicTester { - for (x <- EnumExample.all; - y <- EnumExample.all) { + for { + x <- EnumExample.all + y <- EnumExample.all + } { val mod = Module(new EnumOps(EnumExample, EnumExample)) mod.io.x := x mod.io.y := y @@ -264,7 +264,7 @@ class IsLitTester extends BasicTester { } class NextTester extends BasicTester { - for ((e,n) <- EnumExample.all.zip(EnumExample.litValues.tail :+ EnumExample.litValues.head)) { + for ((e, n) <- EnumExample.all.zip(EnumExample.litValues.tail :+ EnumExample.litValues.head)) { assert(e.next.litValue == n.litValue) val w = WireDefault(e) assert(w.next === EnumExample(n)) @@ -275,7 +275,7 @@ class NextTester extends BasicTester { class WidthTester extends BasicTester { assert(EnumExample.getWidth == EnumExample.litValues.last.getWidth) assert(EnumExample.all.forall(_.getWidth == EnumExample.litValues.last.getWidth)) - assert(EnumExample.all.forall{e => + assert(EnumExample.all.forall { e => val w = WireDefault(e) w.getWidth == EnumExample.litValues.last.getWidth }) @@ -289,7 +289,8 @@ class StrongEnumFSMTester extends BasicTester { // Inputs and expected results val inputs: Vec[Bool] = VecInit(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B) - val expected: Vec[Bool] = VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) + val expected: Vec[Bool] = + VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) val expected_state = VecInit(sNone, sNone, sOne1, sNone, sOne1, sTwo1s, sTwo1s, sNone, sOne1, sTwo1s) val cntr = Counter(inputs.length) @@ -342,16 +343,16 @@ class IsOneOfTester extends BasicTester { class StrongEnumSpec extends ChiselFlatSpec with Utils { import chisel3.internal.ChiselException - behavior of "Strong enum tester" + behavior.of("Strong enum tester") it should "fail to instantiate non-literal enums with the Value function" in { - an [ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { + an[ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { ChiselStage.elaborate(new SimpleConnector(NonLiteralEnumType(), NonLiteralEnumType())) } } it should "fail to instantiate non-increasing enums with the Value function" in { - an [ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { + an[ExceptionInInitializerError] should be thrownBy extractCause[ExceptionInInitializerError] { ChiselStage.elaborate(new SimpleConnector(NonIncreasingEnum(), NonIncreasingEnum())) } } @@ -362,17 +363,17 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { } it should "fail to connect a strong enum to a UInt" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new SimpleConnector(EnumExample(), UInt())) } } it should "fail to connect enums of different types" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new SimpleConnector(EnumExample(), OtherEnum())) } - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new SimpleConnector(EnumExample.Type(), OtherEnum.Type())) } } @@ -394,7 +395,7 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { } it should "prevent illegal literal casts to enums" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new CastToInvalidEnumTester) } } @@ -403,12 +404,12 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { for (w <- 0 to EnumExample.getWidth) ChiselStage.elaborate(new CastFromNonLitWidth(Some(w))) - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new CastFromNonLitWidth) } for (w <- (EnumExample.getWidth + 1) to (EnumExample.getWidth + 100)) { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new CastFromNonLitWidth(Some(w))) } } @@ -419,7 +420,7 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { } it should "fail to compare enums of different types" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new InvalidEnumOpsTester) } } @@ -462,8 +463,8 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { out := MyEnum(in) } val (log, _) = grabLog(ChiselStage.elaborate(new MyModule)) - log should include ("warn") - log should include ("Casting non-literal UInt") + log should include("warn") + log should include("Casting non-literal UInt") } it should "NOT warn if the Enum is total" in { @@ -477,7 +478,7 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { out := TotalEnum(in) } val (log, _) = grabLog(ChiselStage.elaborate(new MyModule)) - log should not include ("warn") + (log should not).include("warn") } "Casting a UInt to an Enum with .safe" should "NOT warn" in { @@ -491,7 +492,7 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { out := MyEnum.safe(in)._1 } val (log, _) = grabLog(ChiselStage.elaborate(new MyModule)) - log should not include ("warn") + (log should not).include("warn") } it should "NOT generate any validity logic if the Enum is total" in { @@ -507,7 +508,7 @@ class StrongEnumSpec extends ChiselFlatSpec with Utils { out := res } val (log, _) = grabLog(ChiselStage.elaborate(new MyModule)) - log should not include ("warn") + (log should not).include("warn") } it should "correctly check if the enumeration is one of the values in a given sequence" in { @@ -524,7 +525,7 @@ class StrongEnumAnnotator extends Module { val le100 = Value(100.U) } - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(EnumExample()) val out = Output(EnumExample()) val other = Output(OtherEnum()) @@ -584,7 +585,7 @@ class StrongEnumAnnotatorWithChiselName extends Module { val le100 = Value(100.U) } - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(EnumExample()) val out = Output(EnumExample()) val other = Output(OtherEnum()) @@ -636,7 +637,7 @@ class StrongEnumAnnotatorWithChiselName extends Module { class StrongEnumAnnotationSpec extends AnyFreeSpec with Matchers { import chisel3.experimental.EnumAnnotations._ - import firrtl.annotations.{ComponentName, Annotation} + import firrtl.annotations.{Annotation, ComponentName} val enumExampleName = "EnumExample" val otherEnumName = "OtherEnum" @@ -667,7 +668,11 @@ class StrongEnumAnnotationSpec extends AnyFreeSpec with Matchers { val correctVecAnnos = Seq( CorrectVecAnno("vec", enumExampleName, Set()), CorrectVecAnno("vec_of_vecs", enumExampleName, Set()), - CorrectVecAnno("vec_of_bundles", enumExampleName, Set(Seq("field"), Seq("vec"), Seq("inner_bundle1", "e"), Seq("inner_bundle1", "v"))), + CorrectVecAnno( + "vec_of_bundles", + enumExampleName, + Set(Seq("field"), Seq("vec"), Seq("inner_bundle1", "e"), Seq("inner_bundle1", "v")) + ), CorrectVecAnno("vec_of_bundles", otherEnumName, Set(Seq("other"))), CorrectVecAnno("vec_of_bundles", localEnumName, Set(Seq("local"))), CorrectVecAnno("bund.vec", enumExampleName, Set()), @@ -678,49 +683,49 @@ class StrongEnumAnnotationSpec extends AnyFreeSpec with Matchers { println("Enum definitions:") annos.foreach { case EnumDefAnnotation(enumTypeName, definition) => println(s"\t$enumTypeName: $definition") - case _ => + case _ => } println("Enum components:") - annos.foreach{ + annos.foreach { case EnumComponentAnnotation(target, enumTypeName) => println(s"\t$target => $enumTypeName") - case _ => + case _ => } println("Enum vecs:") - annos.foreach{ + annos.foreach { case EnumVecAnnotation(target, enumTypeName, fields) => println(s"\t$target[$fields] => $enumTypeName") - case _ => + case _ => } } def isCorrect(anno: EnumDefAnnotation, correct: CorrectDefAnno): Boolean = { (anno.typeName == correct.typeName || - anno.typeName.endsWith("." + correct.typeName) || - anno.typeName.endsWith("$" + correct.typeName)) && - anno.definition == correct.definition + anno.typeName.endsWith("." + correct.typeName) || + anno.typeName.endsWith("$" + correct.typeName)) && + anno.definition == correct.definition } def isCorrect(anno: EnumComponentAnnotation, correct: CorrectCompAnno): Boolean = { (anno.target match { case ComponentName(name, _) => name == correct.targetName - case _ => throw new Exception("Unknown target type in EnumComponentAnnotation") + case _ => throw new Exception("Unknown target type in EnumComponentAnnotation") }) && - (anno.enumTypeName == correct.typeName || anno.enumTypeName.endsWith("." + correct.typeName) || - anno.enumTypeName.endsWith("$" + correct.typeName)) + (anno.enumTypeName == correct.typeName || anno.enumTypeName.endsWith("." + correct.typeName) || + anno.enumTypeName.endsWith("$" + correct.typeName)) } def isCorrect(anno: EnumVecAnnotation, correct: CorrectVecAnno): Boolean = { (anno.target match { case ComponentName(name, _) => name == correct.targetName - case _ => throw new Exception("Unknown target type in EnumVecAnnotation") + case _ => throw new Exception("Unknown target type in EnumVecAnnotation") }) && - (anno.typeName == correct.typeName || anno.typeName.endsWith("." + correct.typeName) || - anno.typeName.endsWith("$" + correct.typeName)) && - anno.fields.map(_.toSeq).toSet == correct.fields + (anno.typeName == correct.typeName || anno.typeName.endsWith("." + correct.typeName) || + anno.typeName.endsWith("$" + correct.typeName)) && + anno.fields.map(_.toSeq).toSet == correct.fields } def allCorrectDefs(annos: Seq[EnumDefAnnotation], corrects: Seq[CorrectDefAnno]): Boolean = { corrects.forall(c => annos.exists(isCorrect(_, c))) && - correctDefAnnos.length == annos.length + correctDefAnnos.length == annos.length } // Because temporary variables might be formed and annotated, we do not check that every component or vector @@ -732,8 +737,10 @@ class StrongEnumAnnotationSpec extends AnyFreeSpec with Matchers { corrects.forall(c => annos.exists(isCorrect(_, c))) def test(strongEnumAnnotatorGen: () => Module) { - val annos = (new ChiselStage).execute(Array("--target-dir", "test_run_dir", "--no-run-firrtl"), - Seq(ChiselGeneratorAnnotation(strongEnumAnnotatorGen))) + val annos = (new ChiselStage).execute( + Array("--target-dir", "test_run_dir", "--no-run-firrtl"), + Seq(ChiselGeneratorAnnotation(strongEnumAnnotatorGen)) + ) val enumDefAnnos = annos.collect { case a: EnumDefAnnotation => a } val enumCompAnnos = annos.collect { case a: EnumComponentAnnotation => a } diff --git a/src/test/scala/chiselTests/SwitchSpec.scala b/src/test/scala/chiselTests/SwitchSpec.scala index 12bbb9e7..52f50a53 100644 --- a/src/test/scala/chiselTests/SwitchSpec.scala +++ b/src/test/scala/chiselTests/SwitchSpec.scala @@ -4,30 +4,30 @@ package chiselTests import chisel3._ import chisel3.stage.ChiselStage -import chisel3.util.{switch, is} +import chisel3.util.{is, switch} class SwitchSpec extends ChiselFlatSpec with Utils { "switch" should "require literal conditions" in { - a [java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + a[java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val state = RegInit(0.U) val wire = WireDefault(0.U) - switch (state) { - is (wire) { state := 1.U } + switch(state) { + is(wire) { state := 1.U } } }) } } it should "require mutually exclusive conditions" in { - a [java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { + a[java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle {}) val state = RegInit(0.U) - switch (state) { - is (0.U) { state := 1.U } - is (1.U) { state := 2.U } - is (0.U) { state := 3.U } + switch(state) { + is(0.U) { state := 1.U } + is(1.U) { state := 2.U } + is(0.U) { state := 3.U } } }) } @@ -40,14 +40,14 @@ class SwitchSpec extends ChiselFlatSpec with Utils { }) io.out := 0.U - switch (io.in) { - is (0.U) { io.out := 3.U } - is (1.U) { io.out := 0.U } - is (2.U) { io.out := 1.U } - is (3.U) { io.out := 3.U } + switch(io.in) { + is(0.U) { io.out := 3.U } + is(1.U) { io.out := 0.U } + is(2.U) { io.out := 1.U } + is(3.U) { io.out := 3.U } } }) - chirrtl should not include "Conditional.scala" + (chirrtl should not).include("Conditional.scala") } } diff --git a/src/test/scala/chiselTests/Tbl.scala b/src/test/scala/chiselTests/Tbl.scala index c7b45a16..5e127770 100644 --- a/src/test/scala/chiselTests/Tbl.scala +++ b/src/test/scala/chiselTests/Tbl.scala @@ -8,15 +8,15 @@ import chisel3.util._ class Tbl(w: Int, n: Int) extends Module { val io = IO(new Bundle { - val wi = Input(UInt(log2Ceil(n).W)) - val ri = Input(UInt(log2Ceil(n).W)) - val we = Input(Bool()) - val d = Input(UInt(w.W)) - val o = Output(UInt(w.W)) + val wi = Input(UInt(log2Ceil(n).W)) + val ri = Input(UInt(log2Ceil(n).W)) + val we = Input(Bool()) + val d = Input(UInt(w.W)) + val o = Output(UInt(w.W)) }) val m = Mem(n, UInt(w.W)) io.o := m(io.ri) - when (io.we) { + when(io.we) { m(io.wi) := io.d when(io.ri === io.wi) { io.o := io.d @@ -35,10 +35,10 @@ class TblTester(w: Int, n: Int, idxs: List[Int], values: List[Int]) extends Basi dut.io.ri := prev_idx dut.io.we := true.B //TODO enSequence dut.io.d := vvalues(cnt) - when (cnt > 0.U) { - when (prev_idx === vidxs(cnt)) { + when(cnt > 0.U) { + when(prev_idx === vidxs(cnt)) { assert(dut.io.o === vvalues(cnt)) - } .otherwise { + }.otherwise { assert(dut.io.o === prev_value) } } @@ -49,13 +49,14 @@ class TblTester(w: Int, n: Int, idxs: List[Int], values: List[Int]) extends Basi class TblSpec extends ChiselPropSpec { property("All table reads should return the previous write") { - forAll(safeUIntPairN(8)) { case(w: Int, pairs: List[(Int, Int)]) => - // Provide an appropriate whenever clause. - // ScalaTest will try and shrink the values on error to determine the smallest values that cause the error. - whenever(w > 0 && pairs.length > 0) { - val (idxs, values) = pairs.unzip - assertTesterPasses{ new TblTester(w, 1 << w, idxs, values) } - } + forAll(safeUIntPairN(8)) { + case (w: Int, pairs: List[(Int, Int)]) => + // Provide an appropriate whenever clause. + // ScalaTest will try and shrink the values on error to determine the smallest values that cause the error. + whenever(w > 0 && pairs.length > 0) { + val (idxs, values) = pairs.unzip + assertTesterPasses { new TblTester(w, 1 << w, idxs, values) } + } } } } diff --git a/src/test/scala/chiselTests/TesterDriverSpec.scala b/src/test/scala/chiselTests/TesterDriverSpec.scala index 5c0e277e..c3cc232f 100644 --- a/src/test/scala/chiselTests/TesterDriverSpec.scala +++ b/src/test/scala/chiselTests/TesterDriverSpec.scala @@ -42,4 +42,3 @@ class TesterDriverSpec extends ChiselFlatSpec { } } } - diff --git a/src/test/scala/chiselTests/TransitNameSpec.scala b/src/test/scala/chiselTests/TransitNameSpec.scala index 656c6731..ae08336d 100644 --- a/src/test/scala/chiselTests/TransitNameSpec.scala +++ b/src/test/scala/chiselTests/TransitNameSpec.scala @@ -1,7 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 package chiselTests - import chisel3._ import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.util.TransitName @@ -12,7 +11,7 @@ import org.scalatest.matchers.should.Matchers class TransitNameSpec extends AnyFlatSpec with Matchers { class MyModule extends RawModule { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) override val desiredName: String = "MyModule" } @@ -42,13 +41,13 @@ class TransitNameSpec extends AnyFlatSpec with Matchers { .emitFirrtl(new Top, Array("--target-dir", "test_run_dir/TransitNameSpec")) info("""output FIRRTL includes "inst MyModule"""") - firrtl should include ("inst MyModule of MyModule") + firrtl should include("inst MyModule of MyModule") info("""output FIRRTL includes "inst bar"""") - firrtl should include ("inst bar of MyModule") + firrtl should include("inst bar of MyModule") info("""output FIRRTL includes "inst baz_generated"""") - firrtl should include ("inst baz_generated of MyModule") + firrtl should include("inst baz_generated of MyModule") } } diff --git a/src/test/scala/chiselTests/UIntOps.scala b/src/test/scala/chiselTests/UIntOps.scala index bc6454b8..5fb86001 100644 --- a/src/test/scala/chiselTests/UIntOps.scala +++ b/src/test/scala/chiselTests/UIntOps.scala @@ -70,8 +70,8 @@ class UIntOpsTester(a: Long, b: Long) extends BasicTester { assert(dut.io.addampout === (a + b).U(33.W)) assert(dut.io.subampout === (a - b).S(33.W).asUInt) assert(dut.io.timesout === (a * b).U(32.W)) - assert(dut.io.divout === (a / (b max 1)).U(32.W)) - assert(dut.io.modout === (a % (b max 1)).U(32.W)) + assert(dut.io.divout === (a / (b.max(1))).U(32.W)) + assert(dut.io.modout === (a % (b.max(1))).U(32.W)) assert(dut.io.lshiftout === (a << (b % 16)).U(32.W)) assert(dut.io.rshiftout === (a >> b).U(32.W)) assert( @@ -117,7 +117,6 @@ class BasicRotate extends BasicTester { val shiftAmount = random.LFSR(4) val ctr = RegInit(0.U(4.W)) - val rotL = 1.U(3.W).rotateLeft(shiftAmount) val rotR = 1.U(3.W).rotateRight(shiftAmount) @@ -140,7 +139,7 @@ class BasicRotate extends BasicTester { ctr := ctr + 1.U - when (ctr === 15.U){ + when(ctr === 15.U) { stop() } } @@ -197,7 +196,7 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils { } property("Bools cannot be created from >1 bit UInts") { - a [Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new BadBoolConversion) } + a[Exception] should be thrownBy extractCause[Exception] { ChiselStage.elaborate(new BadBoolConversion) } } property("UIntOps should elaborate") { @@ -209,7 +208,7 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils { } property("Negative shift amounts are invalid") { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new NegativeShift(UInt())) } } diff --git a/src/test/scala/chiselTests/Util.scala b/src/test/scala/chiselTests/Util.scala index e8354b8d..d2f8bd9b 100644 --- a/src/test/scala/chiselTests/Util.scala +++ b/src/test/scala/chiselTests/Util.scala @@ -25,14 +25,14 @@ class PassthroughRawModule extends RawModule with AbstractPassthroughModule case class ScalaIntervalSimulator(intervalRange: IntervalRange) { val binaryPoint: Int = intervalRange.binaryPoint.asInstanceOf[KnownBinaryPoint].value - val epsilon: Double = 1.0 / math.pow(2.0, binaryPoint.toDouble) + val epsilon: Double = 1.0 / math.pow(2.0, binaryPoint.toDouble) val (lower, upper) = (intervalRange.lowerBound, intervalRange.upperBound) match { case (firrtlir.Closed(lower1), firrtlir.Closed(upper1)) => (lower1, upper1) case (firrtlir.Closed(lower1), firrtlir.Open(upper1)) => (lower1, upper1 - epsilon) - case (firrtlir.Open(lower1), firrtlir.Closed(upper1)) => (lower1 + epsilon, upper1) - case (firrtlir.Open(lower1), firrtlir.Open(upper1)) => (lower1 + epsilon, upper1 - epsilon) + case (firrtlir.Open(lower1), firrtlir.Closed(upper1)) => (lower1 + epsilon, upper1) + case (firrtlir.Open(lower1), firrtlir.Open(upper1)) => (lower1 + epsilon, upper1 - epsilon) case _ => throw new Exception(s"lower and upper bounds must be defined, range here is $intervalRange") } @@ -41,11 +41,9 @@ case class ScalaIntervalSimulator(intervalRange: IntervalRange) { if (value < lower) { lower - } - else if (value > upper) { + } else if (value > upper) { upper - } - else { + } else { value } } @@ -54,11 +52,9 @@ case class ScalaIntervalSimulator(intervalRange: IntervalRange) { if (value < lower) { upper + (value - lower) + epsilon - } - else if (value > upper) { + } else if (value > upper) { ((value - upper) - epsilon) + lower - } - else { + } else { value } } @@ -71,5 +67,3 @@ case class ScalaIntervalSimulator(intervalRange: IntervalRange) { Interval.fromDouble(value.toDouble, width = Width(), binaryPoint = binaryPoint.BP) } } - - diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index 24ba0bf8..2eb6ae5f 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -15,7 +15,7 @@ class LitTesterMod(vecSize: Int) extends Module { val io = IO(new Bundle { val out = Output(Vec(vecSize, UInt())) }) - io.out := VecInit(Seq.fill(vecSize){0.U}) + io.out := VecInit(Seq.fill(vecSize) { 0.U }) } class RegTesterMod(vecSize: Int) extends Module { @@ -23,7 +23,7 @@ class RegTesterMod(vecSize: Int) extends Module { val in = Input(Vec(vecSize, UInt())) val out = Output(Vec(vecSize, UInt())) }) - val vecReg = RegNext(io.in, VecInit(Seq.fill(vecSize){0.U})) + val vecReg = RegNext(io.in, VecInit(Seq.fill(vecSize) { 0.U })) io.out := vecReg } @@ -56,11 +56,11 @@ class RegTester(w: Int, values: List[Int]) extends BasicTester { val dut = Module(new RegTesterMod(values.length)) val doneReg = RegInit(false.B) dut.io.in := v - when (doneReg) { - for ((a,b) <- dut.io.out.zip(values)) + when(doneReg) { + for ((a, b) <- dut.io.out.zip(values)) assert(a === b.U) stop() - } .otherwise { + }.otherwise { doneReg := true.B for (a <- dut.io.out) assert(a === 0.U) @@ -71,7 +71,7 @@ class IOTester(w: Int, values: List[Int]) extends BasicTester { val v = VecInit(values.map(_.U(w.W))) // Does this need a Wire? No. It's a Vec of Lits and hence synthesizeable. val dut = Module(new IOTesterMod(values.length)) dut.io.in := v - for ((a,b) <- dut.io.out.zip(values)) { + for ((a, b) <- dut.io.out.zip(values)) { assert(a === b.U) } stop() @@ -81,24 +81,24 @@ class IOTesterModFill(vecSize: Int) extends Module { // This should generate a BindingException when we attempt to wire up the Vec.fill elements // since they're pure types and hence unsynthesizeable. val io = IO(new Bundle { - val in = Input(VecInit(Seq.fill(vecSize) {UInt()})) - val out = Output(VecInit(Seq.fill(vecSize) {UInt()})) + val in = Input(VecInit(Seq.fill(vecSize) { UInt() })) + val out = Output(VecInit(Seq.fill(vecSize) { UInt() })) }) io.out := io.in } class ValueTester(w: Int, values: List[Int]) extends BasicTester { val v = VecInit(values.map(_.asUInt(w.W))) - for ((a,b) <- v.zip(values)) { + for ((a, b) <- v.zip(values)) { assert(a === b.asUInt) } stop() } class TabulateTester(n: Int) extends BasicTester { - val v = VecInit(Range(0, n).map(i => (i*2).asUInt)) - val x = VecInit(Array.tabulate(n){ i => (i*2).asUInt }) - val u = VecInit.tabulate(n)(i => (i*2).asUInt) + val v = VecInit(Range(0, n).map(i => (i * 2).asUInt)) + val x = VecInit(Array.tabulate(n) { i => (i * 2).asUInt }) + val u = VecInit.tabulate(n)(i => (i * 2).asUInt) assert(v.asUInt() === x.asUInt()) assert(v.asUInt() === u.asUInt()) @@ -115,54 +115,54 @@ class FillTester(n: Int, value: Int) extends BasicTester { stop() } -object VecMultiDimTester { - +object VecMultiDimTester { + @tailrec private def assert2DIsCorrect(n: Int, arr: Vec[Vec[UInt]], compArr: Seq[Seq[Int]]): Unit = { - val compareRow = arr(n) zip compArr(n) - compareRow.foreach (x => assert(x._1 === x._2.U)) - if (n != 0) assert2DIsCorrect(n-1, arr, compArr) + val compareRow = arr(n).zip(compArr(n)) + compareRow.foreach(x => assert(x._1 === x._2.U)) + if (n != 0) assert2DIsCorrect(n - 1, arr, compArr) } @tailrec private def assert3DIsCorrect(n: Int, m: Int, arr: Vec[Vec[Vec[UInt]]], compArr: Seq[Seq[Seq[Int]]]): Unit = { - assert2DIsCorrect(m-1, arr(n), compArr(n)) - if (n != 0) assert3DIsCorrect(n-1, m, arr, compArr) + assert2DIsCorrect(m - 1, arr(n), compArr(n)) + if (n != 0) assert3DIsCorrect(n - 1, m, arr, compArr) } class TabulateTester2D(n: Int, m: Int) extends BasicTester { - def gen(x: Int, y: Int): UInt = (x+y).asUInt - def genCompVec(x: Int, y:Int): Int = x+y - val vec = VecInit.tabulate(n, m){ gen } - val compArr = Seq.tabulate(n,m){ genCompVec } - - assert2DIsCorrect(n-1, vec, compArr) + def gen(x: Int, y: Int): UInt = (x + y).asUInt + def genCompVec(x: Int, y: Int): Int = x + y + val vec = VecInit.tabulate(n, m) { gen } + val compArr = Seq.tabulate(n, m) { genCompVec } + + assert2DIsCorrect(n - 1, vec, compArr) stop() } class TabulateTester3D(n: Int, m: Int, p: Int) extends BasicTester { - def gen(x: Int, y: Int, z: Int): UInt = (x+y+z).asUInt - def genCompVec(x: Int, y:Int, z: Int): Int = x+y+z - val vec = VecInit.tabulate(n, m, p){ gen } - val compArr = Seq.tabulate(n, m, p){ genCompVec } + def gen(x: Int, y: Int, z: Int): UInt = (x + y + z).asUInt + def genCompVec(x: Int, y: Int, z: Int): Int = x + y + z + val vec = VecInit.tabulate(n, m, p) { gen } + val compArr = Seq.tabulate(n, m, p) { genCompVec } - assert3DIsCorrect(n-1, m, vec, compArr) + assert3DIsCorrect(n - 1, m, vec, compArr) stop() } class Fill2DTester(n: Int, m: Int, value: Int) extends BasicTester { - val u = VecInit.fill(n,m)(value.U) - val compareArr = Seq.fill(n,m)(value) - - assert2DIsCorrect(n-1, u, compareArr) + val u = VecInit.fill(n, m)(value.U) + val compareArr = Seq.fill(n, m)(value) + + assert2DIsCorrect(n - 1, u, compareArr) stop() } class Fill3DTester(n: Int, m: Int, p: Int, value: Int) extends BasicTester { - val u = VecInit.fill(n,m,p)(value.U) - val compareArr = Seq.fill(n,m,p)(value) + val u = VecInit.fill(n, m, p)(value.U) + val compareArr = Seq.fill(n, m, p)(value) - assert3DIsCorrect(n-1, m, u, compareArr) + assert3DIsCorrect(n - 1, m, u, compareArr) stop() } @@ -181,7 +181,7 @@ object VecMultiDimTester { class BidirectionalTester3DFill(n: Int, m: Int, p: Int) extends BasicTester { val mod = Module(new PassthroughModule) val vec3D = VecInit.fill(n, m, p)(mod.io) - + for { vec2D <- vec3D vec1D <- vec2D @@ -191,7 +191,7 @@ object VecMultiDimTester { } stop() } - + class TabulateModuleTester(value: Int) extends Module { val io = IO(Flipped(new PassthroughModuleIO)) // This drives the input of a PassthroughModule @@ -199,11 +199,11 @@ object VecMultiDimTester { } class BidirectionalTester2DTabulate(n: Int, m: Int) extends BasicTester { - val vec2D = VecInit.tabulate(n, m) { (x, y) => Module(new TabulateModuleTester(x + y + 1)).io} + val vec2D = VecInit.tabulate(n, m) { (x, y) => Module(new TabulateModuleTester(x + y + 1)).io } for { x <- 0 until n - y <- 0 until m + y <- 0 until m } yield { val value = x + y + 1 val receiveMod = Module(new PassthroughModule).io @@ -233,20 +233,23 @@ object VecMultiDimTester { class IterateTester(start: Int, len: Int)(f: UInt => UInt) extends BasicTester { val controlVec = VecInit(Seq.iterate(start.U, len)(f)) val testVec = VecInit.iterate(start.U, len)(f) - assert(controlVec.asUInt() === testVec.asUInt(), s"Expected Vec to be filled like $controlVec, instead creaeted $testVec\n") + assert( + controlVec.asUInt() === testVec.asUInt(), + s"Expected Vec to be filled like $controlVec, instead creaeted $testVec\n" + ) stop() } class ShiftRegisterTester(n: Int) extends BasicTester { - val (cnt, wrap) = Counter(true.B, n*2) - val shifter = Reg(Vec(n, UInt((log2Ceil(n) max 1).W))) - (shifter, shifter drop 1).zipped.foreach(_ := _) - shifter(n-1) := cnt - when (cnt >= n.asUInt) { + val (cnt, wrap) = Counter(true.B, n * 2) + val shifter = Reg(Vec(n, UInt((log2Ceil(n).max(1)).W))) + (shifter, shifter.drop(1)).zipped.foreach(_ := _) + shifter(n - 1) := cnt + when(cnt >= n.asUInt) { val expected = cnt - n.asUInt assert(shifter(0) === expected) } - when (wrap) { + when(wrap) { stop() } } @@ -299,10 +302,10 @@ class ModuleIODynamicIndexTester(n: Int) extends BasicTester { val (cycle, done) = Counter(true.B, n) for ((m, i) <- duts.zipWithIndex) { - when (cycle =/= i.U) { - m.in := 0.U // default + when(cycle =/= i.U) { + m.in := 0.U // default assert(m.out === 0.U) - } .otherwise { + }.otherwise { m.in := DontCare } } @@ -310,7 +313,7 @@ class ModuleIODynamicIndexTester(n: Int) extends BasicTester { duts(cycle) <> tester.io assert(duts(cycle).out === 123.U) - when (done) { stop() } + when(done) { stop() } } class ReduceTreeTester() extends BasicTester { @@ -349,84 +352,107 @@ class VecSpec extends ChiselPropSpec with Utils { implicit val noShrinkInt = Shrink[Int](_ => Stream.empty) property("Vecs should be assignable") { - forAll(safeUIntN(8)) { case(w: Int, v: List[Int]) => - assertTesterPasses{ new ValueTester(w, v) } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { new ValueTester(w, v) } } } property("Vecs should be passed through vec IO") { - forAll(safeUIntN(8)) { case(w: Int, v: List[Int]) => - assertTesterPasses{ new IOTester(w, v) } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { new IOTester(w, v) } } } property("Vec.fill with a pure type should generate an exception") { // We don't really need a sequence of random widths here, since any should throw an exception. - forAll(safeUIntWidth) { case(w: Int) => - an[BindingException] should be thrownBy extractCause[BindingException] { - ChiselStage.elaborate(new IOTesterModFill(w)) - } + forAll(safeUIntWidth) { + case (w: Int) => + an[BindingException] should be thrownBy extractCause[BindingException] { + ChiselStage.elaborate(new IOTesterModFill(w)) + } } } property("A Reg of a Vec should operate correctly") { - forAll(safeUIntN(8)) { case(w: Int, v: List[Int]) => - assertTesterPasses{ new RegTester(w, v) } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { new RegTester(w, v) } } } property("A Vec of lit should operate correctly") { - forAll(safeUIntN(8)) { case(w: Int, v: List[Int]) => - assertTesterPasses{ new LitTester(w, v) } + forAll(safeUIntN(8)) { + case (w: Int, v: List[Int]) => + assertTesterPasses { new LitTester(w, v) } } } property("VecInit should tabulate correctly") { - forAll(smallPosInts) { (n: Int) => assertTesterPasses{ new TabulateTester(n) } } + forAll(smallPosInts) { (n: Int) => assertTesterPasses { new TabulateTester(n) } } } property("VecInit should tabulate 2D vec correctly") { - forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => assertTesterPasses { new VecMultiDimTester.TabulateTester2D(n, m) } } + forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => + assertTesterPasses { new VecMultiDimTester.TabulateTester2D(n, m) } + } } property("VecInit should tabulate 3D vec correctly") { - forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => assertTesterPasses{ new VecMultiDimTester.TabulateTester3D(n, m, p) } } + forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => + assertTesterPasses { new VecMultiDimTester.TabulateTester3D(n, m, p) } + } } property("VecInit should fill correctly") { - forAll(smallPosInts, Gen.choose(0, 50)) { (n: Int, value: Int) => assertTesterPasses{ new FillTester(n, value) } } + forAll(smallPosInts, Gen.choose(0, 50)) { (n: Int, value: Int) => assertTesterPasses { new FillTester(n, value) } } } property("VecInit should fill 2D vec correctly") { - forAll(smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, value: Int) => assertTesterPasses{ new VecMultiDimTester.Fill2DTester(n, m, value) } } + forAll(smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, value: Int) => + assertTesterPasses { new VecMultiDimTester.Fill2DTester(n, m, value) } + } } - + property("VecInit should fill 3D vec correctly") { - forAll(smallPosInts, smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, p: Int, value: Int) => assertTesterPasses{ new VecMultiDimTester.Fill3DTester(n, m, p, value) } } + forAll(smallPosInts, smallPosInts, smallPosInts, Gen.choose(0, 50)) { (n: Int, m: Int, p: Int, value: Int) => + assertTesterPasses { new VecMultiDimTester.Fill3DTester(n, m, p, value) } + } } property("VecInit should support 2D fill bidirectional wire connection") { - forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => assertTesterPasses{ new VecMultiDimTester.BidirectionalTester2DFill(n, m) }} + forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => + assertTesterPasses { new VecMultiDimTester.BidirectionalTester2DFill(n, m) } + } } - + property("VecInit should support 3D fill bidirectional wire connection") { - forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => assertTesterPasses{ new VecMultiDimTester.BidirectionalTester3DFill(n, m, p) }} + forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => + assertTesterPasses { new VecMultiDimTester.BidirectionalTester3DFill(n, m, p) } + } } property("VecInit should support 2D tabulate bidirectional wire connection") { - forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => assertTesterPasses{ new VecMultiDimTester.BidirectionalTester2DTabulate(n, m) }} + forAll(smallPosInts, smallPosInts) { (n: Int, m: Int) => + assertTesterPasses { new VecMultiDimTester.BidirectionalTester2DTabulate(n, m) } + } } - + property("VecInit should support 3D tabulate bidirectional wire connection") { - forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => assertTesterPasses{ new VecMultiDimTester.BidirectionalTester3DTabulate(n, m, p) }} + forAll(smallPosInts, smallPosInts, smallPosInts) { (n: Int, m: Int, p: Int) => + assertTesterPasses { new VecMultiDimTester.BidirectionalTester3DTabulate(n, m, p) } + } } - + property("VecInit should iterate correctly") { - forAll(Gen.choose(1, 10), smallPosInts) { (start: Int, len: Int) => assertTesterPasses{ new IterateTester(start, len)(x => x + 50.U)}} + forAll(Gen.choose(1, 10), smallPosInts) { (start: Int, len: Int) => + assertTesterPasses { new IterateTester(start, len)(x => x + 50.U) } + } } property("Regs of vecs should be usable as shift registers") { - forAll(smallPosInts) { (n: Int) => assertTesterPasses{ new ShiftRegisterTester(n) } } + forAll(smallPosInts) { (n: Int) => assertTesterPasses { new ShiftRegisterTester(n) } } } property("Infering widths on huge Vecs should not cause a stack overflow") { @@ -434,15 +460,15 @@ class VecSpec extends ChiselPropSpec with Utils { } property("A Reg of a Vec of a single 1 bit element should compile and work") { - assertTesterPasses{ new OneBitUnitRegVecTester } + assertTesterPasses { new OneBitUnitRegVecTester } } property("A Vec with zero entries should compile and have zero width") { - assertTesterPasses{ new ZeroEntryVecTester } + assertTesterPasses { new ZeroEntryVecTester } } property("Dynamic indexing of a Vec of Module IOs should work") { - assertTesterPasses{ new ModuleIODynamicIndexTester(4) } + assertTesterPasses { new ModuleIODynamicIndexTester(4) } } property("It should be possible to bulk connect a Vec and a Seq") { @@ -456,7 +482,7 @@ class VecSpec extends ChiselPropSpec with Utils { } property("Bulk connecting a Vec and Seq of different sizes should report a ChiselException") { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val out = Output(Vec(4, UInt(8.W))) @@ -477,17 +503,18 @@ class VecSpec extends ChiselPropSpec with Utils { } property("Indexing a Chisel type Vec by a hardware type should give a sane error message") { - a [ExpectedHardwareException] should be thrownBy extractCause[ChiselException] { - ChiselStage.elaborate{ + a[ExpectedHardwareException] should be thrownBy extractCause[ChiselException] { + ChiselStage.elaborate { new Module { - val io = IO(new Bundle{}) + val io = IO(new Bundle {}) val foo = Vec(2, Bool()) foo(0.U) := false.B - }} + } + } } } property("reduceTree should preserve input/output type") { - assertTesterPasses { new ReduceTreeTester() } + assertTesterPasses { new ReduceTreeTester() } } } diff --git a/src/test/scala/chiselTests/VecLiteralSpec.scala b/src/test/scala/chiselTests/VecLiteralSpec.scala index 74d8c005..228f409b 100644 --- a/src/test/scala/chiselTests/VecLiteralSpec.scala +++ b/src/test/scala/chiselTests/VecLiteralSpec.scala @@ -20,10 +20,10 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { } "Vec literals should work with chisel Enums" in { - val enumVec = Vec(3, MyEnum()).Lit(0 -> MyEnum.sA, 1 -> MyEnum.sB, 2-> MyEnum.sC) - enumVec(0).toString should include (MyEnum.sA.toString) - enumVec(1).toString should include (MyEnum.sB.toString) - enumVec(2).toString should include (MyEnum.sC.toString) + val enumVec = Vec(3, MyEnum()).Lit(0 -> MyEnum.sA, 1 -> MyEnum.sB, 2 -> MyEnum.sC) + enumVec(0).toString should include(MyEnum.sA.toString) + enumVec(1).toString should include(MyEnum.sB.toString) + enumVec(2).toString should include(MyEnum.sC.toString) } "improperly constructed vec literals should be detected" - { @@ -31,7 +31,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { val e = intercept[VecLiteralException] { Vec(2, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U, 3 -> 4.U, -2 -> 7.U) } - e.getMessage should include ( + e.getMessage should include( "VecLiteral: The following indices (2,3,-2) are less than zero or greater or equal to than Vec length" ) } @@ -56,7 +56,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { val v = Vec(2, SInt(4.W)).Lit(0 -> 1.S, 1 -> -2.S) v(0).toString should include(1.S(4.W).toString) v(1).toString should include((-2).S(4.W).toString) - v.toString should include ("SInt<4>[2](0=SLit(1,<4>), 1=SLit(-2,<4>)") + v.toString should include("SInt<4>[2](0=SLit(1,<4>), 1=SLit(-2,<4>)") } "all lits must be the same type but width cannot be greater than Vec's element width" in { @@ -71,7 +71,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { //NOTE: I had problems where this would not work if this class declaration was inside test scope class HasVecInit extends Module { - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xAB.U(8.W), 1 -> 0xCD.U(8.W), 2 -> 0xEF.U(8.W), 3 -> 0xFF.U(8.W)) + val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) val y = RegInit(initValue) } @@ -86,7 +86,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { //NOTE: I had problems where this would not work if this class declaration was inside test scope class HasPartialVecInit extends Module { - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xAB.U(8.W), 2 -> 0xEF.U(8.W), 3 -> 0xFF.U(8.W)) + val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) val y = RegInit(initValue) } @@ -102,7 +102,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { class ResetRegWithPartialVecLiteral extends Module { val in = IO(Input(Vec(4, UInt(8.W)))) val out = IO(Output(Vec(4, UInt(8.W)))) - val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xAB.U(8.W), 2 -> 0xEF.U(8.W), 3 -> 0xFF.U(8.W)) + val initValue = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) val y = RegInit(initValue) when(in(1) > 0.U) { y(1) := in(1) @@ -132,7 +132,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { }.elsewhen(counter > 2.U) { // m.out(1) should not be reset, m.out(2) should be reset chisel3.assert(m.out(1) === 0xff.U) - chisel3.assert(m.out(2) === 0xEF.U) + chisel3.assert(m.out(2) === 0xef.U) } when(wrapped) { stop() @@ -141,12 +141,12 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { } "lowest of vec literal contains least significant bits and " in { - val y = Vec(4, UInt(8.W)).Lit(0 -> 0xAB.U(8.W), 1 -> 0xCD.U(8.W), 2 -> 0xEF.U(8.W), 3 -> 0xFF.U(8.W)) + val y = Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W)) y.litValue should be(BigInt("FFEFCDAB", 16)) } "the order lits are specified does not matter" in { - val y = Vec(4, UInt(8.W)).Lit(3 -> 0xFF.U(8.W), 2 -> 0xEF.U(8.W), 1 -> 0xCD.U(8.W), 0 -> 0xAB.U(8.W)) + val y = Vec(4, UInt(8.W)).Lit(3 -> 0xff.U(8.W), 2 -> 0xef.U(8.W), 1 -> 0xcd.U(8.W), 0 -> 0xab.U(8.W)) y.litValue should be(BigInt("FFEFCDAB", 16)) } @@ -164,7 +164,7 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { "registers can be initialized with a Vec literal" in { assertTesterPasses(new BasicTester { - val y = RegInit(Vec(4, UInt(8.W)).Lit(0 -> 0xAB.U(8.W), 1 -> 0xCD.U(8.W), 2 -> 0xEF.U(8.W), 3 -> 0xFF.U(8.W))) + val y = RegInit(Vec(4, UInt(8.W)).Lit(0 -> 0xab.U(8.W), 1 -> 0xcd.U(8.W), 2 -> 0xef.U(8.W), 3 -> 0xff.U(8.W))) chisel3.assert(y.asUInt === BigInt("FFEFCDAB", 16).U) stop() }) @@ -172,9 +172,9 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { "how does asUInt work" in { assertTesterPasses(new BasicTester { - val vec1 = Vec(4, UInt(16.W)).Lit(0 -> 0xDD.U, 1 -> 0xCC.U, 2 -> 0xBB.U, 3 -> 0xAA.U) + val vec1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) - val vec2 = VecInit(Seq(0xDD.U, 0xCC.U, 0xBB.U, 0xAA.U)) + val vec2 = VecInit(Seq(0xdd.U, 0xcc.U, 0xbb.U, 0xaa.U)) printf("vec1 %x\n", vec1.asUInt()) printf("vec2 %x\n", vec2.asUInt()) stop() @@ -186,10 +186,10 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { val out1 = IO(Output(UInt(64.W))) val out2 = IO(Output(UInt(64.W))) - val v1 = Vec(4, UInt(16.W)).Lit(0 -> 0xDD.U, 1 -> 0xCC.U, 2 -> 0xBB.U, 3 -> 0xAA.U) + val v1 = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) out1 := v1.asUInt - val v2 = VecInit(0xDD.U(16.W), 0xCC.U, 0xBB.U, 0xAA.U) + val v2 = VecInit(0xdd.U(16.W), 0xcc.U, 0xbb.U, 0xaa.U) out2 := v2.asUInt } @@ -201,33 +201,33 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { } "VecLits should work properly with .asUInt" in { - val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xDD.U, 1 -> 0xCC.U, 2 -> 0xBB.U, 3 -> 0xAA.U) + val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) assertTesterPasses { new BasicTester { - chisel3.assert(outsideVecLit(0) === 0xDD.U, s"v(0)") + chisel3.assert(outsideVecLit(0) === 0xdd.U, s"v(0)") stop() } } } "bundle literals should work in RTL" in { - val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xDD.U, 1 -> 0xCC.U, 2 -> 0xBB.U, 3 -> 0xAA.U) + val outsideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) assertTesterPasses { new BasicTester { - chisel3.assert(outsideVecLit(0) === 0xDD.U, s"v(0)") - chisel3.assert(outsideVecLit(1) === 0xCC.U) - chisel3.assert(outsideVecLit(2) === 0xBB.U) - chisel3.assert(outsideVecLit(3) === 0xAA.U) + chisel3.assert(outsideVecLit(0) === 0xdd.U, s"v(0)") + chisel3.assert(outsideVecLit(1) === 0xcc.U) + chisel3.assert(outsideVecLit(2) === 0xbb.U) + chisel3.assert(outsideVecLit(3) === 0xaa.U) chisel3.assert(outsideVecLit.litValue.U === outsideVecLit.asUInt()) - val insideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xDD.U, 1 -> 0xCC.U, 2 -> 0xBB.U, 3 -> 0xAA.U) - chisel3.assert(insideVecLit(0) === 0xDD.U) - chisel3.assert(insideVecLit(1) === 0xCC.U) - chisel3.assert(insideVecLit(2) === 0xBB.U) - chisel3.assert(insideVecLit(3) === 0xAA.U) + val insideVecLit = Vec(4, UInt(16.W)).Lit(0 -> 0xdd.U, 1 -> 0xcc.U, 2 -> 0xbb.U, 3 -> 0xaa.U) + chisel3.assert(insideVecLit(0) === 0xdd.U) + chisel3.assert(insideVecLit(1) === 0xcc.U) + chisel3.assert(insideVecLit(2) === 0xbb.U) + chisel3.assert(insideVecLit(3) === 0xaa.U) chisel3.assert(insideVecLit(0) === outsideVecLit(0)) chisel3.assert(insideVecLit(1) === outsideVecLit(1)) @@ -237,18 +237,18 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { val vecWire1 = Wire(Vec(4, UInt(16.W))) vecWire1 := outsideVecLit - chisel3.assert(vecWire1(0) === 0xDD.U) - chisel3.assert(vecWire1(1) === 0xCC.U) - chisel3.assert(vecWire1(2) === 0xBB.U) - chisel3.assert(vecWire1(3) === 0xAA.U) + chisel3.assert(vecWire1(0) === 0xdd.U) + chisel3.assert(vecWire1(1) === 0xcc.U) + chisel3.assert(vecWire1(2) === 0xbb.U) + chisel3.assert(vecWire1(3) === 0xaa.U) val vecWire2 = Wire(Vec(4, UInt(16.W))) vecWire2 := insideVecLit - chisel3.assert(vecWire2(0) === 0xDD.U) - chisel3.assert(vecWire2(1) === 0xCC.U) - chisel3.assert(vecWire2(2) === 0xBB.U) - chisel3.assert(vecWire2(3) === 0xAA.U) + chisel3.assert(vecWire2(0) === 0xdd.U) + chisel3.assert(vecWire2(1) === 0xcc.U) + chisel3.assert(vecWire2(2) === 0xbb.U) + chisel3.assert(vecWire2(3) === 0xaa.U) stop() } @@ -256,19 +256,21 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { } "partial vec literals should work in RTL" in { - assertTesterPasses{ new BasicTester{ - val vecLit = Vec(4, UInt(8.W)).Lit(0 -> 42.U, 2 -> 5.U) - chisel3.assert(vecLit(0) === 42.U) - chisel3.assert(vecLit(2) === 5.U) + assertTesterPasses { + new BasicTester { + val vecLit = Vec(4, UInt(8.W)).Lit(0 -> 42.U, 2 -> 5.U) + chisel3.assert(vecLit(0) === 42.U) + chisel3.assert(vecLit(2) === 5.U) - val vecWire = Wire(Vec(4, UInt(8.W))) - vecWire := vecLit + val vecWire = Wire(Vec(4, UInt(8.W))) + vecWire := vecLit - chisel3.assert(vecWire(0) === 42.U) - chisel3.assert(vecWire(2) === 5.U) + chisel3.assert(vecWire(0) === 42.U) + chisel3.assert(vecWire(2) === 5.U) - stop() - }} + stop() + } + } } "nested vec literals should be constructable" in { @@ -277,42 +279,44 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U) ) - outerVec.litValue should be (BigInt("654321", 16)) - outerVec(0).litValue should be (BigInt("321", 16)) - outerVec(1).litValue should be (BigInt("654", 16)) - outerVec(0)(0).litValue should be (BigInt(1)) - outerVec(0)(1).litValue should be (BigInt(2)) - outerVec(0)(2).litValue should be (BigInt(3)) - outerVec(1)(0).litValue should be (BigInt(4)) - outerVec(1)(1).litValue should be (BigInt(5)) - outerVec(1)(2).litValue should be (BigInt(6)) + outerVec.litValue should be(BigInt("654321", 16)) + outerVec(0).litValue should be(BigInt("321", 16)) + outerVec(1).litValue should be(BigInt("654", 16)) + outerVec(0)(0).litValue should be(BigInt(1)) + outerVec(0)(1).litValue should be(BigInt(2)) + outerVec(0)(2).litValue should be(BigInt(3)) + outerVec(1)(0).litValue should be(BigInt(4)) + outerVec(1)(1).litValue should be(BigInt(5)) + outerVec(1)(2).litValue should be(BigInt(6)) } "contained vecs should work" in { - assertTesterPasses{ new BasicTester { - val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit( - 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), - 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U) - ) - - chisel3.assert(outerVec(0)(0) === 1.U) - chisel3.assert(outerVec(0)(1) === 2.U) - chisel3.assert(outerVec(0)(2) === 3.U) - chisel3.assert(outerVec(1)(0) === 4.U) - chisel3.assert(outerVec(1)(1) === 5.U) - chisel3.assert(outerVec(1)(2) === 6.U) - - val v0 = outerVec(0) - val v1 = outerVec(1) - chisel3.assert(v0(0) === 1.U) - chisel3.assert(v0(1) === 2.U) - chisel3.assert(v0(2) === 3.U) - chisel3.assert(v1(0) === 4.U) - chisel3.assert(v1(1) === 5.U) - chisel3.assert(v1(2) === 6.U) + assertTesterPasses { + new BasicTester { + val outerVec = Vec(2, Vec(3, UInt(4.W))).Lit( + 0 -> Vec(3, UInt(4.W)).Lit(0 -> 1.U, 1 -> 2.U, 2 -> 3.U), + 1 -> Vec(3, UInt(4.W)).Lit(0 -> 4.U, 1 -> 5.U, 2 -> 6.U) + ) + + chisel3.assert(outerVec(0)(0) === 1.U) + chisel3.assert(outerVec(0)(1) === 2.U) + chisel3.assert(outerVec(0)(2) === 3.U) + chisel3.assert(outerVec(1)(0) === 4.U) + chisel3.assert(outerVec(1)(1) === 5.U) + chisel3.assert(outerVec(1)(2) === 6.U) + + val v0 = outerVec(0) + val v1 = outerVec(1) + chisel3.assert(v0(0) === 1.U) + chisel3.assert(v0(1) === 2.U) + chisel3.assert(v0(2) === 3.U) + chisel3.assert(v1(0) === 4.U) + chisel3.assert(v1(1) === 5.U) + chisel3.assert(v1(2) === 6.U) - stop() - }} + stop() + } + } } //TODO: decide what behavior here should be @@ -360,13 +364,13 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { "Vec literals should work as register reset values" in { assertTesterPasses { new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xA.U, 1 -> 0xB.U, 2 -> 0xC.U)) + val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 1 -> 0xb.U, 2 -> 0xc.U)) r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop // check reset values on first cycle out of reset - chisel3.assert(r(0) === 0xA.U) - chisel3.assert(r(1) === 0xB.U) - chisel3.assert(r(2) === 0xC.U) + chisel3.assert(r(0) === 0xa.U) + chisel3.assert(r(1) === 0xb.U) + chisel3.assert(r(2) === 0xc.U) stop() } } @@ -375,11 +379,11 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { "partially initialized Vec literals should work as register reset values" in { assertTesterPasses { new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xA.U, 2 -> 0xC.U)) + val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U)) r := (r.asUInt + 1.U).asTypeOf(Vec(3, UInt(11.W))) // prevent constprop // check reset values on first cycle out of reset - chisel3.assert(r(0) === 0xA.U) - chisel3.assert(r(2) === 0xC.U) + chisel3.assert(r(0) === 0xa.U) + chisel3.assert(r(2) === 0xc.U) stop() } } @@ -388,9 +392,9 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils { "Fields extracted from Vec Literals should work as register reset values" in { assertTesterPasses { new BasicTester { - val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xA.U, 2 -> 0xC.U).apply(0)) + val r = RegInit(Vec(3, UInt(11.W)).Lit(0 -> 0xa.U, 2 -> 0xc.U).apply(0)) r := r + 1.U // prevent const prop - chisel3.assert(r === 0xA.U) // coming out of reset + chisel3.assert(r === 0xa.U) // coming out of reset stop() } } diff --git a/src/test/scala/chiselTests/VectorPacketIO.scala b/src/test/scala/chiselTests/VectorPacketIO.scala index c4b0f1f7..1474177f 100644 --- a/src/test/scala/chiselTests/VectorPacketIO.scala +++ b/src/test/scala/chiselTests/VectorPacketIO.scala @@ -28,7 +28,7 @@ class Packet extends Bundle { * The problem does not occur if the Vec is taken out */ class VectorPacketIO(val n: Int) extends Bundle { - val ins = Vec(n, chisel3.util.DeqIO(new Packet())) + val ins = Vec(n, chisel3.util.DeqIO(new Packet())) val outs = Vec(n, chisel3.util.EnqIO(new Packet())) } @@ -37,7 +37,7 @@ class VectorPacketIO(val n: Int) extends Bundle { * the value of n does not affect the error */ class BrokenVectorPacketModule extends Module { - val n = 4 + val n = 4 val io = IO(new VectorPacketIO(n)) // Avoid a "Reference io is not fully initialized" error from firrtl. diff --git a/src/test/scala/chiselTests/VerificationSpec.scala b/src/test/scala/chiselTests/VerificationSpec.scala index 2d7144df..95b0ffe6 100644 --- a/src/test/scala/chiselTests/VerificationSpec.scala +++ b/src/test/scala/chiselTests/VerificationSpec.scala @@ -11,13 +11,13 @@ import org.scalatest.matchers.should.Matchers import java.io.File class SimpleTest extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(8.W)) val out = Output(UInt(8.W)) }) io.out := io.in cover(io.in === 3.U) - when (io.in === 3.U) { + when(io.in === 3.U) { assume(io.in =/= 2.U) assert(io.out === io.in) } @@ -31,6 +31,7 @@ case class VerifAnnotation(target: ReferenceTarget) extends SingleTargetAnnotati } object VerifAnnotation { + /** Create annotation for a given verification component. * @param c component to be annotated */ @@ -64,9 +65,10 @@ class VerificationSpec extends ChiselPropSpec with Matchers { } property("annotation of verification constructs should work") { + /** Circuit that contains and annotates verification nodes. */ class AnnotationTest extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(8.W)) val out = Output(UInt(8.W)) }) @@ -92,10 +94,10 @@ class VerificationSpec extends ChiselPropSpec with Matchers { val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList // check for expected verification annotations - exactly(3, annoLines) should include ("chiselTests.VerifAnnotation") - exactly(1, annoLines) should include ("~AnnotationTest|AnnotationTest>asst") - exactly(1, annoLines) should include ("~AnnotationTest|AnnotationTest>assm") - exactly(1, annoLines) should include ("~AnnotationTest|AnnotationTest>cov") + exactly(3, annoLines) should include("chiselTests.VerifAnnotation") + exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>asst") + exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>assm") + exactly(1, annoLines) should include("~AnnotationTest|AnnotationTest>cov") // read in FIRRTL file val firFile = new File(testDir, "AnnotationTest.fir") @@ -103,15 +105,16 @@ class VerificationSpec extends ChiselPropSpec with Matchers { val firLines = scala.io.Source.fromFile(firFile).getLines.toList // check that verification components have expected names - exactly(1, firLines) should include ("cover(clock, _T, UInt<1>(\"h1\"), \"\") : cov") - exactly(1, firLines) should include ("assume(clock, _T_3, UInt<1>(\"h1\"), \"\") : assm") - exactly(1, firLines) should include ("assert(clock, _T_7, UInt<1>(\"h1\"), \"\") : asst") + exactly(1, firLines) should include("cover(clock, _T, UInt<1>(\"h1\"), \"\") : cov") + exactly(1, firLines) should include("assume(clock, _T_3, UInt<1>(\"h1\"), \"\") : assm") + exactly(1, firLines) should include("assert(clock, _T_7, UInt<1>(\"h1\"), \"\") : asst") } property("annotation of verification constructs with suggested name should work") { + /** Circuit that annotates a renamed verification nodes. */ class AnnotationRenameTest extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(8.W)) val out = Output(UInt(8.W)) }) @@ -137,9 +140,9 @@ class VerificationSpec extends ChiselPropSpec with Matchers { val annoLines = scala.io.Source.fromFile(annoFile).getLines.toList // check for expected verification annotations - exactly(2, annoLines) should include ("chiselTests.VerifAnnotation") - exactly(1, annoLines) should include ("~AnnotationRenameTest|AnnotationRenameTest>hello") - exactly(1, annoLines) should include ("~AnnotationRenameTest|AnnotationRenameTest>howdy") + exactly(2, annoLines) should include("chiselTests.VerifAnnotation") + exactly(1, annoLines) should include("~AnnotationRenameTest|AnnotationRenameTest>hello") + exactly(1, annoLines) should include("~AnnotationRenameTest|AnnotationRenameTest>howdy") // read in FIRRTL file val firFile = new File(testDir, "AnnotationRenameTest.fir") @@ -147,7 +150,7 @@ class VerificationSpec extends ChiselPropSpec with Matchers { val firLines = scala.io.Source.fromFile(firFile).getLines.toList // check that verification components have expected names - exactly(1, firLines) should include ("assert(clock, _T, UInt<1>(\"h1\"), \"\") : hello") - exactly(1, firLines) should include ("assume(clock, _T_4, UInt<1>(\"h1\"), \"\") : howdy") + exactly(1, firLines) should include("assert(clock, _T, UInt<1>(\"h1\"), \"\") : hello") + exactly(1, firLines) should include("assume(clock, _T_4, UInt<1>(\"h1\"), \"\") : howdy") } } diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala index 3b5ec62e..032a8eac 100644 --- a/src/test/scala/chiselTests/When.scala +++ b/src/test/scala/chiselTests/When.scala @@ -14,11 +14,11 @@ class WhenTester() extends BasicTester { val out = Wire(UInt(3.W)) when(cnt.value === 0.U) { out := 1.U - } .elsewhen (cnt.value === 1.U) { + }.elsewhen(cnt.value === 1.U) { out := 2.U - } .elsewhen (cnt.value === 2.U) { + }.elsewhen(cnt.value === 2.U) { out := 3.U - } .otherwise { + }.otherwise { out := 0.U } @@ -36,11 +36,11 @@ class OverlappedWhenTester() extends BasicTester { val out = Wire(UInt(3.W)) when(cnt.value <= 0.U) { out := 1.U - } .elsewhen (cnt.value <= 1.U) { + }.elsewhen(cnt.value <= 1.U) { out := 2.U - } .elsewhen (cnt.value <= 2.U) { + }.elsewhen(cnt.value <= 2.U) { out := 3.U - } .otherwise { + }.otherwise { out := 0.U } @@ -58,13 +58,13 @@ class NoOtherwiseOverlappedWhenTester() extends BasicTester { val out = Wire(UInt(3.W)) when(cnt.value <= 0.U) { out := 1.U - } .elsewhen (cnt.value <= 1.U) { + }.elsewhen(cnt.value <= 1.U) { out := 2.U - } .elsewhen (cnt.value <= 2.U) { + }.elsewhen(cnt.value <= 2.U) { out := 3.U - } .elsewhen (cnt.value <= 3.U) { + }.elsewhen(cnt.value <= 3.U) { out := 0.U - } .otherwise { + }.otherwise { out := DontCare } @@ -77,15 +77,14 @@ class NoOtherwiseOverlappedWhenTester() extends BasicTester { class SubmoduleWhenTester extends BasicTester { val (cycle, done) = Counter(true.B, 3) - when (done) { stop() } - val children = Seq(Module(new PassthroughModule), - Module(new PassthroughMultiIOModule), - Module(new PassthroughRawModule)) + when(done) { stop() } + val children = + Seq(Module(new PassthroughModule), Module(new PassthroughMultiIOModule), Module(new PassthroughRawModule)) children.foreach { child => - when (cycle === 1.U) { + when(cycle === 1.U) { child.io.in := "hdeadbeef".U assert(child.io.out === "hdeadbeef".U) - } .otherwise { + }.otherwise { child.io.in := "h0badcad0".U assert(child.io.out === "h0badcad0".U) } @@ -97,17 +96,17 @@ class WhenCondTester extends BasicTester { val (cycle, done) = Counter(true.B, 1 << pred.size) // Cycle through every predicate pred := cycle.asBools - val Seq(a, b, c, d) = pred // Just for nicer accessors + val Seq(a, b, c, d) = pred // Just for nicer accessors // When want the when predicates on connection to optimize away, // it's not necessary but it makes the Verilog prettier val w1, w2, w3, w4, w5, w6, w7 = WireInit(Bool(), DontCare) - when (a) { + when(a) { w1 := when.cond - when (b) { + when(b) { w2 := when.cond - }.elsewhen (c) { + }.elsewhen(c) { w3 := when.cond - }.elsewhen (d) { + }.elsewhen(d) { w4 := when.cond }.otherwise { w5 := when.cond @@ -125,18 +124,18 @@ class WhenCondTester extends BasicTester { assert(w6 === !a) assert(w7) - when (done) { stop() } + when(done) { stop() } } class WhenSpec extends ChiselFlatSpec with Utils { "When, elsewhen, and otherwise with orthogonal conditions" should "work" in { - assertTesterPasses{ new WhenTester } + assertTesterPasses { new WhenTester } } "When, elsewhen, and otherwise with overlapped conditions" should "work" in { - assertTesterPasses{ new OverlappedWhenTester } + assertTesterPasses { new OverlappedWhenTester } } "When and elsewhen without otherwise with overlapped conditions" should "work" in { - assertTesterPasses{ new NoOtherwiseOverlappedWhenTester } + assertTesterPasses { new NoOtherwiseOverlappedWhenTester } } "Conditional connections to submodule ports" should "be handled properly" in { assertTesterPasses(new SubmoduleWhenTester) @@ -146,7 +145,7 @@ class WhenSpec extends ChiselFlatSpec with Utils { } "Returning in a when scope" should "give a reasonable error message" in { - val e = the [ChiselException] thrownBy extractCause[ChiselException] { + val e = the[ChiselException] thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module { val io = IO(new Bundle { val foo = Input(UInt(8.W)) @@ -164,6 +163,6 @@ class WhenSpec extends ChiselFlatSpec with Utils { io.out := func() }) } - e.getMessage should include ("Cannot exit from a when() block with a \"return\"") + e.getMessage should include("Cannot exit from a when() block with a \"return\"") } } diff --git a/src/test/scala/chiselTests/WidthSpec.scala b/src/test/scala/chiselTests/WidthSpec.scala index 34159214..77a09e1c 100644 --- a/src/test/scala/chiselTests/WidthSpec.scala +++ b/src/test/scala/chiselTests/WidthSpec.scala @@ -19,13 +19,13 @@ object SimpleBundle { class WidthSpec extends ChiselFlatSpec { "Literals without specified widths" should "get the minimum legal width" in { - "hdeadbeef".U.getWidth should be (32) - "h_dead_beef".U.getWidth should be (32) - "h0a".U.getWidth should be (4) - "h1a".U.getWidth should be (5) - "h0".U.getWidth should be (1) - 1.U.getWidth should be (1) - 1.S.getWidth should be (2) + "hdeadbeef".U.getWidth should be(32) + "h_dead_beef".U.getWidth should be(32) + "h0a".U.getWidth should be(4) + "h1a".U.getWidth should be(5) + "h0".U.getWidth should be(1) + 1.U.getWidth should be(1) + 1.S.getWidth should be(2) } } @@ -33,7 +33,7 @@ abstract class WireRegWidthSpecImpl extends ChiselFlatSpec { def name: String def builder[T <: Data](x: T): T - behavior of name + behavior.of(name) it should "set the width if the template type has a set width" in { assertKnownWidth(4) { @@ -83,7 +83,7 @@ abstract class WireDefaultRegInitSpecImpl extends ChiselFlatSpec { def builder1[T <: Data](x: T): T def builder2[T <: Data](x: T, y: T): T - behavior of s"$name (Single Argument)" + behavior.of(s"$name (Single Argument)") it should "set width if passed a literal with forced width" in { assertKnownWidth(4) { @@ -129,7 +129,7 @@ abstract class WireDefaultRegInitSpecImpl extends ChiselFlatSpec { } } - behavior of s"$name (Double Argument)" + behavior.of(s"$name (Double Argument)") it should "set the width if the template type has a set width" in { assertKnownWidth(4) { @@ -152,7 +152,10 @@ abstract class WireDefaultRegInitSpecImpl extends ChiselFlatSpec { it should "infer the width if the template type has no width" in { val templates = Seq( - () => 0.U, () => 0.U(2.W), () => WireDefault(0.U), () => WireDefault(0.U(2.W)) + () => 0.U, + () => 0.U(2.W), + () => WireDefault(0.U), + () => WireDefault(0.U(2.W)) ) for (gen <- templates) { assertInferredWidth(4) { diff --git a/src/test/scala/chiselTests/aop/InjectionSpec.scala b/src/test/scala/chiselTests/aop/InjectionSpec.scala index a28501a5..9b29b0ba 100644 --- a/src/test/scala/chiselTests/aop/InjectionSpec.scala +++ b/src/test/scala/chiselTests/aop/InjectionSpec.scala @@ -38,12 +38,15 @@ object InjectionHierarchy { val in = Input(Bool()) }) //scalastyle:off regex - setInline("SubmoduleC.v", s""" - |module SubmoduleC( - | input io_in - |); - |endmodule - """.stripMargin) + setInline( + "SubmoduleC.v", + s""" + |module SubmoduleC( + | input io_in + |); + |endmodule + """.stripMargin + ) } class AspectTester(results: Seq[Int]) extends BasicTester { @@ -63,26 +66,26 @@ object InjectionHierarchy { class InjectionSpec extends ChiselFlatSpec with Utils { import InjectionHierarchy._ val correctValueAspect = InjectingAspect( - {dut: AspectTester => Seq(dut)}, - {dut: AspectTester => - for(i <- 0 until dut.values.length) { + { dut: AspectTester => Seq(dut) }, + { dut: AspectTester => + for (i <- 0 until dut.values.length) { dut.values(i) := i.U } } ) val wrongValueAspect = InjectingAspect( - {dut: AspectTester => Seq(dut)}, - {dut: AspectTester => - for(i <- 0 until dut.values.length) { + { dut: AspectTester => Seq(dut) }, + { dut: AspectTester => + for (i <- 0 until dut.values.length) { dut.values(i) := (i + 1).U } } ) val manipulateSubmoduleAspect = InjectingAspect( - {dut: SubmoduleManipulationTester => Seq(dut)}, - {dut: SubmoduleManipulationTester => + { dut: SubmoduleManipulationTester => Seq(dut) }, + { dut: SubmoduleManipulationTester => val moduleSubmoduleB = Module(new SubmoduleB) moduleSubmoduleB.io.in := dut.moduleSubmoduleA.io.out //if we're here then we've elaborated correctly @@ -91,8 +94,8 @@ class InjectionSpec extends ChiselFlatSpec with Utils { ) val duplicateSubmoduleAspect = InjectingAspect( - {dut: SubmoduleManipulationTester => Seq(dut)}, - {_: SubmoduleManipulationTester => + { dut: SubmoduleManipulationTester => Seq(dut) }, + { _: SubmoduleManipulationTester => // By creating a second SubmoduleA, the module names would conflict unless they were uniquified val moduleSubmoduleA2 = Module(new SubmoduleA) //if we're here then we've elaborated correctly @@ -101,8 +104,8 @@ class InjectionSpec extends ChiselFlatSpec with Utils { ) val addingExternalModules = InjectingAspect( - {dut: SubmoduleManipulationTester => Seq(dut)}, - {_: SubmoduleManipulationTester => + { dut: SubmoduleManipulationTester => Seq(dut) }, + { _: SubmoduleManipulationTester => // By creating a second SubmoduleA, the module names would conflict unless they were uniquified val moduleSubmoduleC = Module(new SubmoduleC) //if we're here then we've elaborated correctly @@ -123,30 +126,36 @@ class InjectionSpec extends ChiselFlatSpec with Utils { ) "Test" should "pass if inserted the correct values" in { - assertTesterPasses{ new AspectTester(Seq(0, 1, 2)) } + assertTesterPasses { new AspectTester(Seq(0, 1, 2)) } } "Test" should "fail if inserted the wrong values" in { - assertTesterFails{ new AspectTester(Seq(9, 9, 9)) } + assertTesterFails { new AspectTester(Seq(9, 9, 9)) } } "Test" should "pass if pass wrong values, but correct with aspect" in { - assertTesterPasses({ new AspectTester(Seq(9, 9, 9))} , Nil, Seq(correctValueAspect) ++ TesterDriver.verilatorOnly) + assertTesterPasses({ new AspectTester(Seq(9, 9, 9)) }, Nil, Seq(correctValueAspect) ++ TesterDriver.verilatorOnly) } "Test" should "pass if pass wrong values, then wrong aspect, then correct aspect" in { assertTesterPasses( - new AspectTester(Seq(9, 9, 9)), Nil, Seq(wrongValueAspect, correctValueAspect) ++ TesterDriver.verilatorOnly + new AspectTester(Seq(9, 9, 9)), + Nil, + Seq(wrongValueAspect, correctValueAspect) ++ TesterDriver.verilatorOnly ) } "Test" should "fail if pass wrong values, then correct aspect, then wrong aspect" in { - assertTesterFails({ new AspectTester(Seq(9, 9, 9))} , Nil, Seq(correctValueAspect, wrongValueAspect)) + assertTesterFails({ new AspectTester(Seq(9, 9, 9)) }, Nil, Seq(correctValueAspect, wrongValueAspect)) } "Test" should "pass if the submodules in SubmoduleManipulationTester can be manipulated by manipulateSubmoduleAspect" in { - assertTesterPasses({ new SubmoduleManipulationTester} , Nil, Seq(manipulateSubmoduleAspect) ++ TesterDriver.verilatorOnly) + assertTesterPasses( + { new SubmoduleManipulationTester }, + Nil, + Seq(manipulateSubmoduleAspect) ++ TesterDriver.verilatorOnly + ) } "Module name collisions when adding a new module" should "be resolved" in { assertTesterPasses( - { new SubmoduleManipulationTester}, + { new SubmoduleManipulationTester }, Nil, Seq(duplicateSubmoduleAspect) ++ TesterDriver.verilatorOnly ) @@ -154,7 +163,7 @@ class InjectionSpec extends ChiselFlatSpec with Utils { "Adding external modules" should "work" in { assertTesterPasses( - { new SubmoduleManipulationTester}, + { new SubmoduleManipulationTester }, Nil, Seq(addingExternalModules) ++ TesterDriver.verilatorOnly ) @@ -162,7 +171,7 @@ class InjectionSpec extends ChiselFlatSpec with Utils { "Injection into multiple submodules of the same class" should "work" in { assertTesterPasses( - {new MultiModuleInjectionTester}, + { new MultiModuleInjectionTester }, Nil, Seq(multiModuleInjectionAspect) ++ TesterDriver.verilatorOnly ) diff --git a/src/test/scala/chiselTests/aop/SelectSpec.scala b/src/test/scala/chiselTests/aop/SelectSpec.scala index 2b47c6b8..72802c80 100644 --- a/src/test/scala/chiselTests/aop/SelectSpec.scala +++ b/src/test/scala/chiselTests/aop/SelectSpec.scala @@ -39,22 +39,35 @@ case class SelectAspect[T <: RawModule, X](selector: T => Seq[X], desired: T => override def toAnnotation(top: T): AnnotationSeq = { val results = selector(top) val desiredSeq = desired(top) - assert(results.length == desiredSeq.length, s"Failure! Results $results have different length than desired $desiredSeq!") + assert( + results.length == desiredSeq.length, + s"Failure! Results $results have different length than desired $desiredSeq!" + ) val mismatches = results.zip(desiredSeq).flatMap { case (res, des) if res != des => Seq((res, des)) - case other => Nil + case other => Nil } - assert(mismatches.isEmpty,s"Failure! The following selected items do not match their desired item:\n" + mismatches.map{ - case (res: Select.Serializeable, des: Select.Serializeable) => s" ${res.serialize} does not match:\n ${des.serialize}" - case (res, des) => s" $res does not match:\n $des" - }.mkString("\n")) + assert( + mismatches.isEmpty, + s"Failure! The following selected items do not match their desired item:\n" + mismatches.map { + case (res: Select.Serializeable, des: Select.Serializeable) => + s" ${res.serialize} does not match:\n ${des.serialize}" + case (res, des) => s" $res does not match:\n $des" + }.mkString("\n") + ) Nil } } class SelectSpec extends ChiselFlatSpec { - def execute[T <: RawModule, X](dut: () => T, selector: T => Seq[X], desired: T => Seq[X])(implicit tTag: TypeTag[T]): Unit = { + def execute[T <: RawModule, X]( + dut: () => T, + selector: T => Seq[X], + desired: T => Seq[X] + )( + implicit tTag: TypeTag[T] + ): Unit = { val ret = new chisel3.stage.ChiselStage().run( Seq( new chisel3.stage.ChiselGeneratorAnnotation(dut), @@ -85,16 +98,20 @@ class SelectSpec extends ChiselFlatSpec { () => new SelectTester(Seq(0, 1, 2)), { dut: SelectTester => Seq(Select.printfs(dut).last.toString) }, { dut: SelectTester => - Seq(Select.Printf( - dut.p, - Seq( - When(Select.ops("eq")(dut).last.asInstanceOf[Bool]), - When(dut.nreset), - WhenNot(dut.overflow) - ), - dut.p.pable, - dut.clock - ).toString) + Seq( + Select + .Printf( + dut.p, + Seq( + When(Select.ops("eq")(dut).last.asInstanceOf[Bool]), + When(dut.nreset), + WhenNot(dut.overflow) + ), + dut.p.pable, + dut.clock + ) + .toString + ) } ) } @@ -104,8 +121,10 @@ class SelectSpec extends ChiselFlatSpec { () => new SelectTester(Seq(0, 1, 2)), { dut: SelectTester => Select.connectionsTo(dut)(dut.counter) }, { dut: SelectTester => - Seq(PredicatedConnect(Nil, dut.counter, dut.added, false), - PredicatedConnect(Seq(When(dut.overflow)), dut.counter, dut.zero, false)) + Seq( + PredicatedConnect(Nil, dut.counter, dut.added, false), + PredicatedConnect(Seq(When(dut.overflow)), dut.counter, dut.zero, false) + ) } ) } @@ -121,7 +140,7 @@ class SelectSpec extends ChiselFlatSpec { "Test" should "pass if selecting ops" in { execute( () => new SelectTester(Seq(0, 1, 2)), - { dut: SelectTester => Select.ops(dut).collect { case ("tail", d) => d} }, + { dut: SelectTester => Select.ops(dut).collect { case ("tail", d) => d } }, { dut: SelectTester => Seq(dut.added, dut.zero) } ) } @@ -131,20 +150,22 @@ class SelectSpec extends ChiselFlatSpec { () => new SelectTester(Seq(0, 1, 2)), { dut: SelectTester => Seq(Select.stops(dut).last) }, { dut: SelectTester => - Seq(Select.Stop( - Seq( - When(Select.ops("eq")(dut)(1).asInstanceOf[Bool]), - When(dut.overflow) - ), - 0, - dut.clock - )) + Seq( + Select.Stop( + Seq( + When(Select.ops("eq")(dut)(1).asInstanceOf[Bool]), + When(dut.overflow) + ), + 0, + dut.clock + ) + ) } ) } "Blackboxes" should "be supported in Select.instances" in { - class BB extends ExtModule { } + class BB extends ExtModule {} class Top extends RawModule { val bb = Module(new BB) } @@ -173,12 +194,10 @@ class SelectSpec extends ChiselFlatSpec { } val top = ChiselGeneratorAnnotation(() => { new Top() - }).elaborate - .collectFirst { case DesignAnnotation(design: Top) => design } - .get - Select.collectDeep(top) { case x => x } should equal (Seq(top, top.inst0)) - Select.getDeep(top)(x => Seq(x)) should equal (Seq(top, top.inst0)) - Select.instances(top) should equal (Seq(top.inst0)) + }).elaborate.collectFirst { case DesignAnnotation(design: Top) => design }.get + Select.collectDeep(top) { case x => x } should equal(Seq(top, top.inst0)) + Select.getDeep(top)(x => Seq(x)) should equal(Seq(top, top.inst0)) + Select.instances(top) should equal(Seq(top.inst0)) } "Using Definition/Instance with Injecting Aspects" should "throw an error" in { @@ -202,13 +221,10 @@ class SelectSpec extends ChiselFlatSpec { } val top = ChiselGeneratorAnnotation(() => { new Top() - }).elaborate - .collectFirst { case DesignAnnotation(design: Top) => design } - .get + }).elaborate.collectFirst { case DesignAnnotation(design: Top) => design }.get intercept[Exception] { Select.collectDeep(top) { case x => x } } intercept[Exception] { Select.getDeep(top)(x => Seq(x)) } intercept[Exception] { Select.instances(top) } } } - diff --git a/src/test/scala/chiselTests/experimental/DataView.scala b/src/test/scala/chiselTests/experimental/DataView.scala index 7c5d170b..5ef062fa 100644 --- a/src/test/scala/chiselTests/experimental/DataView.scala +++ b/src/test/scala/chiselTests/experimental/DataView.scala @@ -54,7 +54,7 @@ object FlatDecoupledDataView { class DataViewSpec extends ChiselFlatSpec { - behavior of "DataView" + behavior.of("DataView") it should "support simple Bundle viewing" in { import SimpleBundleDataView._ @@ -240,8 +240,8 @@ class DataViewSpec extends ChiselFlatSpec { fooOut := cat } val chirrtl = ChiselStage.emitChirrtl(new MyModule) - chirrtl should include ("node cat = cat(barIn.foo, barIn.bar)") - chirrtl should include ("fooOut <= cat") + chirrtl should include("node cat = cat(barIn.foo, barIn.bar)") + chirrtl should include("fooOut <= cat") } it should "be composable" in { @@ -262,8 +262,8 @@ class DataViewSpec extends ChiselFlatSpec { z := b.viewAs[Bar].viewAs[Fizz] } val chirrtl = ChiselStage.emitChirrtl(new MyModule) - chirrtl should include ("y.fizz <= a.foo") - chirrtl should include ("z.fizz <= b.foo") + chirrtl should include("y.fizz <= a.foo") + chirrtl should include("z.fizz <= b.foo") } it should "enable using Seq like Data" in { @@ -277,8 +277,8 @@ class DataViewSpec extends ChiselFlatSpec { } // Verilog instead of CHIRRTL because the optimizations make it much prettier val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign y = sel ? a : c;") - verilog should include ("assign z = sel ? b : d;") + verilog should include("assign y = sel ? a : c;") + verilog should include("assign z = sel ? b : d;") } // This example should be turned into a built-in feature @@ -291,9 +291,9 @@ class DataViewSpec extends ChiselFlatSpec { } // Verilog instead of CHIRRTL because the optimizations make it much prettier val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign x = a;") - verilog should include ("assign y = b;") - verilog should include ("assign z = c;") + verilog should include("assign x = a;") + verilog should include("assign y = b;") + verilog should include("assign z = c;") } it should "support recursive composition of views" in { @@ -307,10 +307,10 @@ class DataViewSpec extends ChiselFlatSpec { Seq((w, x), (y, z)) := VecInit[HWTuple2[UInt, UInt]]((a, b), (c, d)) } val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign w = a;") - verilog should include ("assign x = b;") - verilog should include ("assign y = c;") - verilog should include ("assign z = d;") + verilog should include("assign w = a;") + verilog should include("assign x = b;") + verilog should include("assign y = c;") + verilog should include("assign z = d;") } it should "support dynamic indexing for Vec identity views" in { @@ -328,8 +328,8 @@ class DataViewSpec extends ChiselFlatSpec { dataOut := selected } val chirrtl = ChiselStage.emitChirrtl(new MyModule) - chirrtl should include ("vec[addr] <= dataIn") - chirrtl should include ("dataOut <= vec[addr]") + chirrtl should include("vec[addr] <= dataIn") + chirrtl should include("dataOut <= vec[addr]") } it should "error if you try to dynamically index a Vec view that does not correspond to a Vec target" in { @@ -346,9 +346,9 @@ class DataViewSpec extends ChiselFlatSpec { selected := (inA, inB) (outA, outB) := selected } - (the [InvalidViewException] thrownBy { + (the[InvalidViewException] thrownBy { ChiselStage.emitChirrtl(new MyModule) - }).getMessage should include ("Dynamic indexing of Views is not yet supported") + }).getMessage should include("Dynamic indexing of Views is not yet supported") } it should "error if the mapping is non-total in the view" in { @@ -360,8 +360,8 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(tpe)) out := in.viewAs[MyBundle] } - val err = the [InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) - err.toString should include ("View field '_.foo' is missing") + val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) + err.toString should include("View field '_.foo' is missing") } it should "error if the mapping is non-total in the target" in { @@ -371,8 +371,8 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(UInt(8.W))) out := (a, b).viewAs[UInt] } - val err = the [InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) - err.toString should include ("Target field '_._2' is missing") + val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) + err.toString should include("Target field '_._2' is missing") } it should "error if the mapping contains Data that are not part of the Target" in { @@ -389,8 +389,8 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(new BundleB)) out := in.viewAs[BundleB] } - val err = the [InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) - err.toString should include ("View mapping must only contain Elements within the Target") + val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) + err.toString should include("View mapping must only contain Elements within the Target") } it should "error if the mapping contains Data that are not part of the View" in { @@ -408,8 +408,8 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(new BundleB)) out.viewAs[BundleA] := in } - val err = the [InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) - err.toString should include ("View mapping must only contain Elements within the View") + val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) + err.toString should include("View mapping must only contain Elements within the View") } it should "error if a view has a width that does not match the target" in { @@ -425,9 +425,9 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(new BundleB)) out := in.viewAs[BundleB] } - val err = the [InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule) + val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule) val expected = """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <8>""".r - err.getMessage should fullyMatch regex expected + (err.getMessage should fullyMatch).regex(expected) } it should "error if a view has a known width when the target width is unknown" in { @@ -443,12 +443,13 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(new BundleB)) out := in.viewAs[BundleB] } - val err = the [InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule) - val expected = """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <unknown>""".r - err.getMessage should fullyMatch regex expected + val err = the[InvalidViewException] thrownBy ChiselStage.emitChirrtl(new MyModule) + val expected = + """View field _\.bar UInt<4> has width <4> that is incompatible with target value .+'s width <unknown>""".r + (err.getMessage should fullyMatch).regex(expected) } - behavior of "PartialDataView" + behavior.of("PartialDataView") it should "still error if the mapping is non-total in the view" in { class MyBundle(val foo: UInt, val bar: UInt) extends Bundle @@ -458,8 +459,8 @@ class DataViewSpec extends ChiselFlatSpec { val out = IO(Output(new MyBundle(UInt(8.W), UInt(8.W)))) out := in.viewAs[MyBundle] } - val err = the [InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) - err.toString should include ("View field '_.foo' is missing") + val err = the[InvalidViewException] thrownBy (ChiselStage.emitVerilog(new MyModule)) + err.toString should include("View field '_.foo' is missing") } it should "NOT error if the mapping is non-total in the target" in { @@ -470,6 +471,6 @@ class DataViewSpec extends ChiselFlatSpec { out := (a, b).viewAs[UInt] } val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign out = b;") + verilog should include("assign out = b;") } } diff --git a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala b/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala index 3f149f75..4704a942 100644 --- a/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala +++ b/src/test/scala/chiselTests/experimental/DataViewIntegrationSpec.scala @@ -5,7 +5,7 @@ package chiselTests.experimental import chisel3._ import chisel3.experimental.{BaseModule, ExtModule} import chisel3.experimental.dataview._ -import chisel3.util.{Decoupled, DecoupledIO, Queue, QueueIO, log2Ceil} +import chisel3.util.{log2Ceil, Decoupled, DecoupledIO, Queue, QueueIO} import chiselTests.ChiselFlatSpec import firrtl.transforms.DontTouchAnnotation @@ -52,6 +52,6 @@ class DataViewIntegrationSpec extends ChiselFlatSpec { "Users" should "be able to view and annotate Modules" in { val (_, annos) = getFirrtlAndAnnos(new MyModule) val ts = annos.collect { case DontTouchAnnotation(t) => t.serialize } - ts should equal (Seq("~MyModule|Queue>enq_ptr_value")) + ts should equal(Seq("~MyModule|Queue>enq_ptr_value")) } } diff --git a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala index a17b0f40..da27c9c8 100644 --- a/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala +++ b/src/test/scala/chiselTests/experimental/DataViewTargetSpec.scala @@ -5,7 +5,7 @@ package chiselTests.experimental import chisel3._ import chisel3.experimental.dataview._ import chisel3.experimental.conversions._ -import chisel3.experimental.{ChiselAnnotation, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation} import chiselTests.ChiselFlatSpec object DataViewTargetSpec { @@ -29,22 +29,22 @@ class DataViewTargetSpec extends ChiselFlatSpec { _.instanceName, _.pathName, _.parentPathName, - _.parentModName, + _.parentModName ) // Check helpers private def checkAll(impl: Data, refs: String*): Unit = { - refs.size should be (checks.size) + refs.size should be(checks.size) for ((check, value) <- checks.zip(refs)) { - check(impl) should be (value) + check(impl) should be(value) } } private def checkSameAs(impl: Data, refs: Data*): Unit = for (ref <- refs) { - checkAll(impl, checks.map(_(ref)):_*) + checkAll(impl, checks.map(_(ref)): _*) } - behavior of "DataView Naming" + behavior.of("DataView Naming") it should "support views of Elements" in { class MyChild extends Module { @@ -67,7 +67,8 @@ class DataViewTargetSpec extends ChiselFlatSpec { val foo = UInt(8.W) val bars = Vec(2, UInt(8.W)) } - implicit val dv = DataView[MyBundle, Vec[UInt]](_ => Vec(3, UInt(8.W)), _.foo -> _(0), _.bars(0) -> _(1), _.bars(1) -> _(2)) + implicit val dv = + DataView[MyBundle, Vec[UInt]](_ => Vec(3, UInt(8.W)), _.foo -> _(0), _.bars(0) -> _(1), _.bars(1) -> _(2)) class MyChild extends Module { val out = IO(Output(new MyBundle)) val outView = out.viewAs[Vec[UInt]] // Note different type @@ -82,7 +83,7 @@ class DataViewTargetSpec extends ChiselFlatSpec { out := inst.out } val m = elaborateAndGetModule(new MyParent) - val outView = m.inst.out.viewAs[Vec[UInt]]// Note different type + val outView = m.inst.out.viewAs[Vec[UInt]] // Note different type val outFooView = m.inst.out.foo.viewAs[UInt] val outBarsView = m.inst.out.bars.viewAs[Vec[UInt]] val outBars0View = m.inst.out.bars(0).viewAs[UInt] @@ -90,8 +91,15 @@ class DataViewTargetSpec extends ChiselFlatSpec { checkSameAs(m.inst.out, m.inst.outView, outView) checkSameAs(m.inst.out.foo, m.inst.outFooView, m.inst.outView(0), outFooView, outView(0)) checkSameAs(m.inst.out.bars, m.inst.outBarsView, outBarsView) - checkSameAs(m.inst.out.bars(0), m.inst.outBars0View, outBars0View, m.inst.outView(1), outView(1), - m.inst.outBarsView(0), outBarsView(0)) + checkSameAs( + m.inst.out.bars(0), + m.inst.outBars0View, + outBars0View, + m.inst.outView(1), + outView(1), + m.inst.outBarsView(0), + outBarsView(0) + ) } // Ideally this would work 1:1 but that requires changing the binding @@ -123,7 +131,7 @@ class DataViewTargetSpec extends ChiselFlatSpec { 2 -> "~MyParent|MyParent/inst:MyChild>out.foo", 3 -> "~MyParent|MyParent/inst:MyChild>out" ) - pairs should equal (expected) + pairs should equal(expected) } it should "support annotating views that cannot be mapped to a single ReferenceTarget" in { @@ -161,9 +169,9 @@ class DataViewTargetSpec extends ChiselFlatSpec { 3 -> "~MyParent|MyParent/inst:MyChild>io.c", 3 -> "~MyParent|MyParent/inst:MyChild>io.d", 4 -> "~MyParent|MyChild>io.b", - 4 -> "~MyParent|MyChild>io.d", + 4 -> "~MyParent|MyChild>io.d" ) - pairs should equal (expected) + pairs should equal(expected) } // TODO check these properties when using @instance API (especially preservation of totality) diff --git a/src/test/scala/chiselTests/experimental/ForceNames.scala b/src/test/scala/chiselTests/experimental/ForceNames.scala index 06f911e6..233b4a5f 100644 --- a/src/test/scala/chiselTests/experimental/ForceNames.scala +++ b/src/test/scala/chiselTests/experimental/ForceNames.scala @@ -6,7 +6,7 @@ import firrtl._ import chisel3._ import chisel3.experimental.annotate import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} -import chisel3.util.experimental.{ForceNameAnnotation, ForceNamesTransform, InlineInstance, forceName} +import chisel3.util.experimental.{forceName, ForceNameAnnotation, ForceNamesTransform, InlineInstance} import firrtl.annotations.{Annotation, ReferenceTarget} import firrtl.options.{Dependency, TargetDirAnnotation} import firrtl.stage.RunFirrtlTransformAnnotation @@ -61,7 +61,12 @@ object ForceNamesHierarchy { class ForceNamesSpec extends ChiselFlatSpec { - def run[T <: RawModule](dut: => T, testName: String, inputAnnos: Seq[Annotation] = Nil, info: LogLevel.Value = LogLevel.None): Iterable[String] = { + def run[T <: RawModule]( + dut: => T, + testName: String, + inputAnnos: Seq[Annotation] = Nil, + info: LogLevel.Value = LogLevel.None + ): Iterable[String] = { def stage = new ChiselStage { override val targets = Seq( Dependency[chisel3.stage.phases.Elaborate], @@ -85,11 +90,11 @@ class ForceNamesSpec extends ChiselFlatSpec { } "Force Names on a wrapping instance" should "work" in { val verilog = run(new ForceNamesHierarchy.WrapperExample, "wrapper") - exactly(1, verilog) should include ("MyLeaf inst") + exactly(1, verilog) should include("MyLeaf inst") } "Force Names on an instance port" should "work" in { val verilog = run(new ForceNamesHierarchy.RenamePortsExample, "instports") - atLeast(1, verilog) should include ("input [2:0] inn") + atLeast(1, verilog) should include("input [2:0] inn") } "Force Names with a conflicting name" should "error" in { intercept[CustomTransformException] { diff --git a/src/test/scala/chiselTests/experimental/GroupSpec.scala b/src/test/scala/chiselTests/experimental/GroupSpec.scala index 52435ad8..5e0c34bb 100644 --- a/src/test/scala/chiselTests/experimental/GroupSpec.scala +++ b/src/test/scala/chiselTests/experimental/GroupSpec.scala @@ -16,9 +16,9 @@ import scala.collection.mutable class GroupSpec extends ChiselFlatSpec { - def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] = new InstanceGraph(c) - .fullHierarchy.values.flatten.toSeq - .map( v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".") ) + def collectInstances(c: fir.Circuit, top: Option[String] = None): Seq[String] = + new InstanceGraph(c).fullHierarchy.values.flatten.toSeq + .map(v => (top.getOrElse(v.head.name) +: v.tail.map(_.name)).mkString(".")) def collectDeclarations(m: fir.DefModule): Set[String] = { val decs = mutable.HashSet[String]() @@ -32,17 +32,16 @@ class GroupSpec extends ChiselFlatSpec { def lower[T <: RawModule](gen: () => T): fir.Circuit = { (new ChiselStage) - .execute(Array("--compiler", "low", - "--target-dir", "test_run_dir"), - Seq(ChiselGeneratorAnnotation(gen))) + .execute(Array("--compiler", "low", "--target-dir", "test_run_dir"), Seq(ChiselGeneratorAnnotation(gen))) .collectFirst { case firrtl.stage.FirrtlCircuitAnnotation(circuit) => circuit - }.get + } + .get } "Module Grouping" should "compile to low FIRRTL" in { class MyModule extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val a = Input(Bool()) val b = Output(Bool()) }) @@ -56,17 +55,17 @@ class GroupSpec extends ChiselFlatSpec { val firrtlCircuit = lower(() => new MyModule) firrtlCircuit.modules.collect { case m: fir.Module if m.name == "MyModule" => - Set("doubleReg") should be (collectDeclarations(m)) + Set("doubleReg") should be(collectDeclarations(m)) case m: fir.Module if m.name == "DosRegisters" => - Set("reg1", "reg2") should be (collectDeclarations(m)) + Set("reg1", "reg2") should be(collectDeclarations(m)) } val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet - Set("MyModule", "MyModule.doubleReg") should be (instances) + Set("MyModule", "MyModule.doubleReg") should be(instances) } "Module Grouping" should "not include intermediate registers" in { class MyModule extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val a = Input(Bool()) val b = Output(Bool()) }) @@ -81,17 +80,17 @@ class GroupSpec extends ChiselFlatSpec { val firrtlCircuit = lower(() => new MyModule) firrtlCircuit.modules.collect { case m: fir.Module if m.name == "MyModule" => - Set("reg2", "doubleReg") should be (collectDeclarations(m)) + Set("reg2", "doubleReg") should be(collectDeclarations(m)) case m: fir.Module if m.name == "DosRegisters" => - Set("reg1", "reg3") should be (collectDeclarations(m)) + Set("reg1", "reg3") should be(collectDeclarations(m)) } val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet - Set("MyModule", "MyModule.doubleReg") should be (instances) + Set("MyModule", "MyModule.doubleReg") should be(instances) } "Module Grouping" should "include intermediate wires" in { class MyModule extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val a = Input(Bool()) val b = Output(Bool()) }) @@ -106,11 +105,11 @@ class GroupSpec extends ChiselFlatSpec { val firrtlCircuit = lower(() => new MyModule) firrtlCircuit.modules.collect { case m: fir.Module if m.name == "MyModule" => - Set("doubleReg") should be (collectDeclarations(m)) + Set("doubleReg") should be(collectDeclarations(m)) case m: fir.Module if m.name == "DosRegisters" => - Set("reg1", "reg3", "wire") should be (collectDeclarations(m)) + Set("reg1", "reg3", "wire") should be(collectDeclarations(m)) } val instances = collectInstances(firrtlCircuit, Some("MyModule")).toSet - Set("MyModule", "MyModule.doubleReg") should be (instances) + Set("MyModule", "MyModule.doubleReg") should be(instances) } } diff --git a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala b/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala index 78986517..713f9d04 100644 --- a/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala +++ b/src/test/scala/chiselTests/experimental/ModuleDataProductSpec.scala @@ -39,7 +39,7 @@ object ModuleDataProductSpec { class ModuleDataProductSpec extends ChiselFlatSpec { import ModuleDataProductSpec._ - behavior of "DataProduct" + behavior.of("DataProduct") it should "work for UserModules (recursively)" in { val m = elaborateAndGetModule(new MyUserModule) @@ -62,7 +62,7 @@ class ModuleDataProductSpec extends ChiselFlatSpec { val impl = implicitly[DataProduct[MyUserModule]] val set = impl.dataSet(m) for ((d, _) <- expected) { - set(d) should be (true) + set(d) should be(true) } val it = impl.dataIterator(m, "m") it.toList should contain theSameElementsAs (expected) @@ -82,7 +82,7 @@ class ModuleDataProductSpec extends ChiselFlatSpec { val impl = implicitly[DataProduct[MyExtModule]] val set = impl.dataSet(m) for ((d, _) <- expected) { - set(d) should be (true) + set(d) should be(true) } val it = impl.dataIterator(m, "m") it.toList should contain theSameElementsAs (expected) diff --git a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala index ffe3a37f..64aabb4b 100644 --- a/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala +++ b/src/test/scala/chiselTests/experimental/ProgrammaticPortsSpec.scala @@ -63,7 +63,7 @@ class ProgrammaticPortsSpec extends ChiselFlatSpec with Utils { } "SuggestName collisions on ports" should "be illegal" in { - a [ChiselException] should be thrownBy extractCause[ChiselException] { + a[ChiselException] should be thrownBy extractCause[ChiselException] { ChiselStage.elaborate(new Module { val foo = IO(UInt(8.W)).suggestName("apple") val bar = IO(UInt(8.W)).suggestName("apple") diff --git a/src/test/scala/chiselTests/experimental/TraceSpec.scala b/src/test/scala/chiselTests/experimental/TraceSpec.scala index 59548921..31ccdf9b 100644 --- a/src/test/scala/chiselTests/experimental/TraceSpec.scala +++ b/src/test/scala/chiselTests/experimental/TraceSpec.scala @@ -88,13 +88,17 @@ class TraceSpec extends ChiselFlatSpec with Matchers { .flatMap(finalTarget(annos)) .toSet .map { target: CompleteTarget => - s"""public_flat_rd -module "${target.tokens.collectFirst { case OfModule(m) => m }.get}" -var "${target.tokens.collectFirst { case Ref(r) => r }.get}"""" + s"""public_flat_rd -module "${target.tokens.collectFirst { + case OfModule(m) => m + }.get}" -var "${target.tokens.collectFirst { case Ref(r) => r }.get}"""" } .mkString("\n") + "\n" def verilatorTemplate(data: Seq[Data], annos: AnnotationSeq): String = { val vpiNames = data.flatMap(finalTarget(annos)).map { ct => - s"""TOP.${ct.circuit}.${ct.path.map { case (Instance(i), _) => i }.mkString(".")}.${ct.tokens.collectFirst { case Ref(r) => r }.get}""" + s"""TOP.${ct.circuit}.${ct.path.map { case (Instance(i), _) => i }.mkString(".")}.${ct.tokens.collectFirst { + case Ref(r) => r + }.get}""" } s""" |#include "V${topName}.h" @@ -155,20 +159,34 @@ class TraceSpec extends ChiselFlatSpec with Matchers { val verilog = testDir / s"$topName.v" val cpp = os.temp(dir = testDir, suffix = ".cpp", contents = verilatorTemplate(Seq(dut.m0.o.a.b), annos)) val exe = testDir / "obj_dir" / s"V$topName" - os.proc("verilator", "-Wall", "--cc", "--exe", "--build", "--vpi", s"$cpp", s"$verilog", s"$config").call(stdout = os.Inherit, stderr = os.Inherit, cwd = testDir) - assert(os.proc(s"$exe").call(stdout = os.Inherit, stderr = os.Inherit).exitCode == 0, "verilator should exit peacefully") + os.proc("verilator", "-Wall", "--cc", "--exe", "--build", "--vpi", s"$cpp", s"$verilog", s"$config") + .call(stdout = os.Inherit, stderr = os.Inherit, cwd = testDir) + assert( + os.proc(s"$exe").call(stdout = os.Inherit, stderr = os.Inherit).exitCode == 0, + "verilator should exit peacefully" + ) } "TraceFromCollideBundle" should "work" in { class CollideModule extends Module { - val a = IO(Input(Vec(2, new Bundle { - val b = Flipped(Bool()) - val c = Vec(2, new Bundle { - val d = UInt(2.W) - val e = Flipped(UInt(3.W)) - }) - val c_1_e = UInt(4.W) - }))) + val a = IO( + Input( + Vec( + 2, + new Bundle { + val b = Flipped(Bool()) + val c = Vec( + 2, + new Bundle { + val d = UInt(2.W) + val e = Flipped(UInt(3.W)) + } + ) + val c_1_e = UInt(4.W) + } + ) + ) + ) val a_0_c = IO(Output(UInt(5.W))) val a__0 = IO(Output(UInt(5.W))) a_0_c := DontCare @@ -298,12 +316,14 @@ class TraceSpec extends ChiselFlatSpec with Matchers { val (_, annos) = compile("NestedModule", () => new M) val dut = annos.collectFirst { case DesignAnnotation(dut) => dut }.get.asInstanceOf[M] val allTargets = finalTargetMap(annos) - allTargets(dut.a.toAbsoluteTarget) should be (Seq(refTarget("M", "a"))) - allTargets(dut.b.toAbsoluteTarget) should be (Seq( - refTarget("M", "b_0"), - refTarget("M", "b_1"), - )) - allTargets(dut.b(0).toAbsoluteTarget) should be (Seq(refTarget("M", "b_0"))) - allTargets(dut.b(1).toAbsoluteTarget) should be (Seq(refTarget("M", "b_1"))) + allTargets(dut.a.toAbsoluteTarget) should be(Seq(refTarget("M", "a"))) + allTargets(dut.b.toAbsoluteTarget) should be( + Seq( + refTarget("M", "b_0"), + refTarget("M", "b_1") + ) + ) + allTargets(dut.b(0).toAbsoluteTarget) should be(Seq(refTarget("M", "b_0"))) + allTargets(dut.b(1).toAbsoluteTarget) should be(Seq(refTarget("M", "b_1"))) } } diff --git a/src/test/scala/chiselTests/experimental/Tuple.scala b/src/test/scala/chiselTests/experimental/Tuple.scala index 5f897fbc..b57766e7 100644 --- a/src/test/scala/chiselTests/experimental/Tuple.scala +++ b/src/test/scala/chiselTests/experimental/Tuple.scala @@ -9,7 +9,7 @@ import chisel3.stage.ChiselStage class TupleSpec extends ChiselFlatSpec { - behavior of "Tuple" + behavior.of("Tuple") it should "enable using Tuple2 like Data" in { class MyModule extends Module { @@ -20,8 +20,8 @@ class TupleSpec extends ChiselFlatSpec { } // Verilog instead of CHIRRTL because the optimizations make it much prettier val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign y = sel ? a : c;") - verilog should include ("assign z = sel ? b : d;") + verilog should include("assign y = sel ? a : c;") + verilog should include("assign z = sel ? b : d;") } it should "support nesting of tuples" in { @@ -31,10 +31,10 @@ class TupleSpec extends ChiselFlatSpec { ((w, x), (y, z)) := ((a, b), (c, d)) } val chirrtl = ChiselStage.emitChirrtl(new MyModule) - chirrtl should include ("w <= a") - chirrtl should include ("x <= b") - chirrtl should include ("y <= c") - chirrtl should include ("z <= d") + chirrtl should include("w <= a") + chirrtl should include("x <= b") + chirrtl should include("y <= c") + chirrtl should include("z <= d") } it should "enable using Tuple3 like Data" in { @@ -47,9 +47,9 @@ class TupleSpec extends ChiselFlatSpec { } // Verilog instead of CHIRRTL because the optimizations make it much prettier val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign v = sel ? a : f;") - verilog should include ("assign w = sel ? b : g;") - verilog should include ("assign x = sel ? c : h;") + verilog should include("assign v = sel ? a : f;") + verilog should include("assign w = sel ? b : g;") + verilog should include("assign x = sel ? c : h;") } it should "enable using Tuple4 like Data" in { @@ -62,10 +62,10 @@ class TupleSpec extends ChiselFlatSpec { } // Verilog instead of CHIRRTL because the optimizations make it much prettier val verilog = ChiselStage.emitVerilog(new MyModule) - verilog should include ("assign v = sel ? a : f;") - verilog should include ("assign w = sel ? b : g;") - verilog should include ("assign x = sel ? c : h;") - verilog should include ("assign y = sel ? d : i;") + verilog should include("assign v = sel ? a : f;") + verilog should include("assign w = sel ? b : g;") + verilog should include("assign x = sel ? c : h;") + verilog should include("assign y = sel ? d : i;") } it should "enable using Tuple5 like Data" in { diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala index eba412f1..2c1d2e9e 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala @@ -5,20 +5,22 @@ package chiselTests.experimental.hierarchy import _root_.firrtl.annotations._ import chisel3.experimental.{annotate, BaseModule} import chisel3.Data -import chisel3.experimental.hierarchy.{Instance, Definition, Hierarchy} +import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance} object Annotations { case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] { def duplicate(n: IsMember): Annotation = this.copy(target = n) } - case class MarkChiselHierarchyAnnotation[B <: BaseModule](d: Hierarchy[B], tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation { + case class MarkChiselHierarchyAnnotation[B <: BaseModule](d: Hierarchy[B], tag: String, isAbsolute: Boolean) + extends chisel3.experimental.ChiselAnnotation { def toFirrtl = MarkAnnotation(d.toTarget, tag) } - case class MarkChiselAnnotation(d: Data, tag: String, isAbsolute: Boolean) extends chisel3.experimental.ChiselAnnotation { - def toFirrtl = if(isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag) + case class MarkChiselAnnotation(d: Data, tag: String, isAbsolute: Boolean) + extends chisel3.experimental.ChiselAnnotation { + def toFirrtl = if (isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag) } - def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false)) - def mark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true)) - def amark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, true)) + def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false)) + def mark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true)) + def amark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, true)) def amark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true)) } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala index f33f7869..efc81f94 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala @@ -5,7 +5,7 @@ package experimental.hierarchy import chisel3._ import chisel3.experimental.BaseModule -import chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public} +import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance} // TODO/Notes // - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5 @@ -19,7 +19,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val definition = Definition(new AddOne) } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("module AddOne :") + chirrtl.serialize should include("module AddOne :") } it("0.2: accessing internal fields through non-generated means is hard to do") { class Top extends Module { @@ -29,7 +29,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { definition.in } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("module AddOne :") + chirrtl.serialize should include("module AddOne :") } it("0.2: reset inference is not defaulted to Bool for definitions") { class Top extends Module with RequireAsyncReset { @@ -38,21 +38,27 @@ class DefinitionSpec extends ChiselFunSpec with Utils { i0.in := 0.U } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("inst i0 of HasUninferredReset") + chirrtl.serialize should include("inst i0 of HasUninferredReset") } it("0.3: module names of repeated definition should be sequential") { class Top extends Module { - val k = Module(new AddTwoParameterized(4, (x: Int) => Seq.tabulate(x){j => - val addOneDef = Definition(new AddOneParameterized(x+j)) - val addOne = Instance(addOneDef) - addOne - })) + val k = Module( + new AddTwoParameterized( + 4, + (x: Int) => + Seq.tabulate(x) { j => + val addOneDef = Definition(new AddOneParameterized(x + j)) + val addOne = Instance(addOneDef) + addOne + } + ) + ) } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("module AddOneParameterized :") - chirrtl.serialize should include ("module AddOneParameterized_1 :") - chirrtl.serialize should include ("module AddOneParameterized_2 :") - chirrtl.serialize should include ("module AddOneParameterized_3 :") + chirrtl.serialize should include("module AddOneParameterized :") + chirrtl.serialize should include("module AddOneParameterized_1 :") + chirrtl.serialize should include("module AddOneParameterized_2 :") + chirrtl.serialize should include("module AddOneParameterized_3 :") } it("0.4: multiple instantiations should have sequential names") { class Top extends Module { @@ -61,22 +67,28 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val otherAddOne = Module(new AddOneParameterized(4)) } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("module AddOneParameterized :") - chirrtl.serialize should include ("module AddOneParameterized_1 :") + chirrtl.serialize should include("module AddOneParameterized :") + chirrtl.serialize should include("module AddOneParameterized_1 :") } it("0.5: nested definitions should have sequential names") { class Top extends Module { - val k = Module(new AddTwoWithNested(4, (x: Int) => Seq.tabulate(x){j => - val addOneDef = Definition(new AddOneWithNested(x+j)) - val addOne = Instance(addOneDef) - addOne - })) + val k = Module( + new AddTwoWithNested( + 4, + (x: Int) => + Seq.tabulate(x) { j => + val addOneDef = Definition(new AddOneWithNested(x + j)) + val addOne = Instance(addOneDef) + addOne + } + ) + ) } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("module AddOneWithNested :") - chirrtl.serialize should include ("module AddOneWithNested_1 :") - chirrtl.serialize should include ("module AddOneWithNested_2 :") - chirrtl.serialize should include ("module AddOneWithNested_3 :") + chirrtl.serialize should include("module AddOneWithNested :") + chirrtl.serialize should include("module AddOneWithNested_1 :") + chirrtl.serialize should include("module AddOneWithNested_2 :") + chirrtl.serialize should include("module AddOneWithNested_3 :") } } describe("1: Annotations on definitions in same chisel compilation") { @@ -179,7 +191,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val (_, annos) = getFirrtlAndAnnos(new Top) annos should contain(MarkAnnotation("~Top|AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0")) } - it("1.10: should work for targets on definition to have correct circuit name"){ + it("1.10: should work for targets on definition to have correct circuit name") { class Top extends Module { val definition = Definition(new AddOneWithAnnotation) } @@ -401,10 +413,12 @@ class DefinitionSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } - it("6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both") { + it( + "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both" + ) { class Top extends Module { val i: Definition[ModuleWithCommonIntf] = Definition(new ModuleWithCommonIntf) mark(i.io.in, "gotcha") @@ -418,7 +432,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") { @@ -434,7 +448,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") { @@ -456,7 +470,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } } @@ -495,10 +509,10 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- expectedLines) { - text should include (line) + text should include(line) } for (e <- expectedAnnos.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } ignore("7.1: should work on Aggregate Views that are mapped 1:1") { @@ -523,7 +537,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { } val expectedAnnos = List( "~Top|MyModule>a".rt -> "in", - "~Top|MyModule>a.foo".rt -> "in_bar", + "~Top|MyModule>a.foo".rt -> "in_bar" ) val expectedLines = List( "i.a <= foo", @@ -532,10 +546,10 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- expectedLines) { - text should include (line) + text should include(line) } for (e <- expectedAnnos.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala index 996b36ee..de03b74b 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala @@ -11,7 +11,7 @@ object Examples { import Annotations._ @instantiable class AddOne extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val innerWire = Wire(UInt(32.W)) innerWire := in + 1.U @@ -19,7 +19,7 @@ object Examples { } @instantiable class AddOneWithAnnotation extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val innerWire = Wire(UInt(32.W)) mark(innerWire, "innerWire") @@ -28,7 +28,7 @@ object Examples { } @instantiable class AddOneWithAbsoluteAnnotation extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val innerWire = Wire(UInt(32.W)) amark(innerWire, "innerWire") @@ -37,12 +37,12 @@ object Examples { } @instantiable class AddOneParameterized(width: Int) extends Module { - @public val in = IO(Input(UInt(width.W))) + @public val in = IO(Input(UInt(width.W))) @public val out = IO(Output(UInt(width.W))) out := in + 1.U } class AddOneWithNested(width: Int) extends Module { - @public val in = IO(Input(UInt(width.W))) + @public val in = IO(Input(UInt(width.W))) @public val out = IO(Output(UInt(width.W))) val addOneDef = Seq.fill(3)(Definition(new AddOne)) out := in + 1.U @@ -50,7 +50,7 @@ object Examples { @instantiable class AddTwo extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val definition = Definition(new AddOne) @public val i0: Instance[AddOne] = Instance(definition) @@ -61,7 +61,7 @@ object Examples { } @instantiable class AddTwoMixedModules extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) val definition = Definition(new AddOne) @public val i0: Instance[AddOne] = Instance(definition) @@ -71,24 +71,25 @@ object Examples { out := i1.out } @instantiable - class AddTwoParameterized(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneParameterized]]) extends Module { - val in = IO(Input(UInt(width.W))) + class AddTwoParameterized(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneParameterized]]) + extends Module { + val in = IO(Input(UInt(width.W))) val out = IO(Output(UInt(width.W))) val addOnes = makeParameterizedOnes(width) addOnes.head.in := in out := addOnes.last.out - addOnes.zip(addOnes.tail).foreach{ case (head, tail) => tail.in := head.out} + addOnes.zip(addOnes.tail).foreach { case (head, tail) => tail.in := head.out } } @instantiable class AddTwoWithNested(width: Int, makeParameterizedOnes: Int => Seq[Instance[AddOneWithNested]]) extends Module { - val in = IO(Input(UInt(width.W))) + val in = IO(Input(UInt(width.W))) val out = IO(Output(UInt(width.W))) val addOnes = makeParameterizedOnes(width) } @instantiable class AddFour extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val definition = Definition(new AddTwoMixedModules) @public val i0 = Instance(definition) @@ -111,7 +112,7 @@ object Examples { } @instantiable class AddOneWithInstantiableWire extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val wireContainer = new WireContainer() wireContainer.innerWire := in + 1.U @@ -123,7 +124,7 @@ object Examples { } @instantiable class AddOneWithInstantiableModule extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val moduleContainer = new AddOneContainer() moduleContainer.i0.in := in @@ -136,7 +137,7 @@ object Examples { } @instantiable class AddOneWithInstantiableInstance extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val instanceContainer = new AddOneInstanceContainer() instanceContainer.i0.in := in @@ -148,7 +149,7 @@ object Examples { } @instantiable class AddOneWithInstantiableInstantiable extends Module { - @public val in = IO(Input(UInt(32.W))) + @public val in = IO(Input(UInt(32.W))) @public val out = IO(Output(UInt(32.W))) @public val containerContainer = new AddOneContainerContainer() containerContainer.container.i0.in := in @@ -157,12 +158,12 @@ object Examples { @instantiable class Viewer(val y: AddTwo, markPlease: Boolean) { @public val x = y - if(markPlease) mark(x.i0.innerWire, "first") + if (markPlease) mark(x.i0.innerWire, "first") } @instantiable class ViewerParent(val x: AddTwo, markHere: Boolean, markThere: Boolean) extends Module { @public val viewer = new Viewer(x, markThere) - if(markHere) mark(viewer.x.i0.innerWire, "second") + if (markHere) mark(viewer.x.i0.innerWire, "second") } @instantiable class MultiVal() extends Module { diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala index 94af9a8b..e6bf04c1 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala @@ -5,10 +5,9 @@ package experimental.hierarchy import chisel3._ import chisel3.experimental.BaseModule -import chisel3.experimental.hierarchy.{Definition, Instance, instantiable, public} +import chisel3.experimental.hierarchy.{instantiable, public, Definition, Instance} import chisel3.util.{DecoupledIO, Valid} - // TODO/Notes // - In backport, clock/reset are not automatically assigned. I think this is fixed in 3.5 // - CircuitTarget for annotations on the definition are wrong - needs to be fixed. @@ -22,7 +21,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val i0 = Instance(definition) } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("inst i0 of AddOne") + chirrtl.serialize should include("inst i0 of AddOne") } it("0.1: name of an instanceclone should not error") { class Top extends Module { @@ -31,7 +30,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val i = i0.i0 // This should not error } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("inst i0 of AddTwo") + chirrtl.serialize should include("inst i0 of AddTwo") } it("0.2: accessing internal fields through non-generated means is hard to do") { class Top extends Module { @@ -42,63 +41,63 @@ class InstanceSpec extends ChiselFunSpec with Utils { i0.in } val (chirrtl, _) = getFirrtlAndAnnos(new Top) - chirrtl.serialize should include ("inst i0 of AddOne") + chirrtl.serialize should include("inst i0 of AddOne") } } describe("1: Annotations on instances in same chisel compilation") { it("1.0: should work on a single instance, annotating the instance") { class Top extends Module { val definition: Definition[AddOne] = Definition(new AddOne) - val i0: Instance[AddOne] = Instance(definition) + val i0: Instance[AddOne] = Instance(definition) mark(i0, "i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOne".it, "i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOne".it, "i0")) } it("1.1: should work on a single instance, annotating an inner wire") { class Top extends Module { val definition: Definition[AddOne] = Definition(new AddOne) - val i0: Instance[AddOne] = Instance(definition) + val i0: Instance[AddOne] = Instance(definition) mark(i0.innerWire, "i0.innerWire") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOne>innerWire".rt, "i0.innerWire")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOne>innerWire".rt, "i0.innerWire")) } it("1.2: should work on a two nested instances, annotating the instance") { class Top extends Module { val definition: Definition[AddTwo] = Definition(new AddTwo) - val i0: Instance[AddTwo] = Instance(definition) + val i0: Instance[AddTwo] = Instance(definition) mark(i0.i0, "i0.i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne".it, "i0.i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne".it, "i0.i0")) } it("1.3: should work on a two nested instances, annotating the inner wire") { class Top extends Module { val definition: Definition[AddTwo] = Definition(new AddTwo) - val i0: Instance[AddTwo] = Instance(definition) + val i0: Instance[AddTwo] = Instance(definition) mark(i0.i0.innerWire, "i0.i0.innerWire") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddTwo/i0:AddOne>innerWire".rt, "i0.i0.innerWire")) } it("1.4: should work on a nested module in an instance, annotating the module") { class Top extends Module { val definition: Definition[AddTwoMixedModules] = Definition(new AddTwoMixedModules) - val i0: Instance[AddTwoMixedModules] = Instance(definition) + val i0: Instance[AddTwoMixedModules] = Instance(definition) mark(i0.i1, "i0.i1") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_1".it, "i0.i1")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddTwoMixedModules/i1:AddOne_1".it, "i0.i1")) } it("1.5: should work on an instantiable container, annotating a wire") { class Top extends Module { val definition: Definition[AddOneWithInstantiableWire] = Definition(new AddOneWithInstantiableWire) - val i0: Instance[AddOneWithInstantiableWire] = Instance(definition) + val i0: Instance[AddOneWithInstantiableWire] = Instance(definition) mark(i0.wireContainer.innerWire, "i0.innerWire") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableWire>innerWire".rt, "i0.innerWire")) } it("1.6: should work on an instantiable container, annotating a module") { class Top extends Module { @@ -107,7 +106,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i0.moduleContainer.i0, "i0.i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableModule/i0:AddOne".it, "i0.i0")) } it("1.7: should work on an instantiable container, annotating an instance") { class Top extends Module { @@ -116,7 +115,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i0.instanceContainer.i0, "i0.i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstance/i0:AddOne".it, "i0.i0")) } it("1.8: should work on an instantiable container, annotating an instantiable container's module") { class Top extends Module { @@ -125,7 +124,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i0.containerContainer.container.i0, "i0.i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0")) } it("1.9: should work on public member which references public member of another instance") { class Top extends Module { @@ -134,24 +133,24 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i0.containerContainer.container.i0, "i0.i0") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0")) + annos should contain(MarkAnnotation("~Top|Top/i0:AddOneWithInstantiableInstantiable/i0:AddOne".it, "i0.i0")) } - it("1.10: should work for targets on definition to have correct circuit name"){ + it("1.10: should work for targets on definition to have correct circuit name") { class Top extends Module { val definition = Definition(new AddOneWithAnnotation) val i0 = Instance(definition) } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire")) + annos should contain(MarkAnnotation("~Top|AddOneWithAnnotation>innerWire".rt, "innerWire")) } - it("1.11: should work on things with type parameters"){ + it("1.11: should work on things with type parameters") { class Top extends Module { val definition = Definition(new HasTypeParams[UInt](UInt(3.W))) val i0 = Instance(definition) mark(i0.blah, "blah") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/i0:HasTypeParams>blah".rt, "blah")) + annos should contain(MarkAnnotation("~Top|Top/i0:HasTypeParams>blah".rt, "blah")) } } describe("2: Annotations on designs not in the same chisel compilation") { @@ -161,7 +160,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val parent = Instance(Definition(new ViewerParent(x, false, true))) } val (_, annos) = getFirrtlAndAnnos(new Top(first)) - annos should contain (MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first")) + annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "first")) } it("2.1: should work on an innerWire, marked in a different compilation, in instanced instantiable") { val first = elaborateAndGetModule(new AddTwo) @@ -169,7 +168,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val parent = Instance(Definition(new ViewerParent(x, true, false))) } val (_, annos) = getFirrtlAndAnnos(new Top(first)) - annos should contain (MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second")) + annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "second")) } it("2.2: should work on an innerWire, marked in a different compilation, in instanced module") { val first = elaborateAndGetModule(new AddTwo) @@ -178,7 +177,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(parent.viewer.x.i0.innerWire, "third") } val (_, annos) = getFirrtlAndAnnos(new Top(first)) - annos should contain (MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third")) + annos should contain(MarkAnnotation("~AddTwo|AddTwo/i0:AddOne>innerWire".rt, "third")) } } describe("3: @public") { @@ -188,7 +187,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(mv.x, "mv.x") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/mv:MultiVal>x".rt, "mv.x")) + annos should contain(MarkAnnotation("~Top|Top/mv:MultiVal>x".rt, "mv.x")) } it("3.1: should work on lazy vals") { class Top() extends Module { @@ -196,7 +195,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(lv.x, lv.y) } val (_, annos) = getFirrtlAndAnnos(new Top) - annos should contain (MarkAnnotation("~Top|Top/lv:LazyVal>x".rt, "Hi")) + annos should contain(MarkAnnotation("~Top|Top/lv:LazyVal>x".rt, "Hi")) } it("3.2: should work on islookupables") { class Top() extends Module { @@ -275,10 +274,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- lines) { - text should include (line) + text should include(line) } for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } ignore("3.10: should work on vals in constructor arguments") { @@ -398,7 +397,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val (_, annos) = getFirrtlAndAnnos(new Top) annos should contain(MarkAnnotation("~Top|Top/i:AddTwo/i1:AddOne".it, "blah")) } - it("5.6: should work for absolute targets on definition to have correct circuit name"){ + it("5.6: should work for absolute targets on definition to have correct circuit name") { class Top extends Module { val definition = Definition(new AddOneWithAbsoluteAnnotation) val i0 = Instance(definition) @@ -437,10 +436,12 @@ class InstanceSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } - it("6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both") { + it( + "6.1 An @instantiable Module that implements an @instantiable trait should be able to use extension methods from both" + ) { class Top extends Module { val i: Instance[ModuleWithCommonIntf] = Instance(Definition(new ModuleWithCommonIntf)) mark(i.io.in, "gotcha") @@ -454,7 +455,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } it("6.2 A BlackBox that implements an @instantiable trait should be instantiable as that trait") { @@ -469,7 +470,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } it("6.3 It should be possible to have Vectors of @instantiable traits mixing concrete subclasses") { @@ -491,7 +492,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } } @@ -530,10 +531,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- expectedLines) { - text should include (line) + text should include(line) } for (e <- expectedAnnos.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } @@ -578,15 +579,15 @@ class InstanceSpec extends ChiselFunSpec with Utils { "bar.valid <= i.b.valid", "i.b.ready <= bar.ready", "bar.bits.fizz <= i.b.fizz", - "bar.bits.buzz <= i.b.buzz", + "bar.bits.buzz <= i.b.buzz" ) val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- expectedLines) { - text should include (line) + text should include(line) } for (e <- expectedAnnos.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } @@ -612,7 +613,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { } val expected = List( "~Top|Top/i:MyModule>a".rt -> "in", - "~Top|Top/i:MyModule>b.foo".rt -> "out_bar", + "~Top|Top/i:MyModule>b.foo".rt -> "out_bar" ) val lines = List( "i.a <= foo", @@ -621,10 +622,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- lines) { - text should include (line) + text should include(line) } for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } @@ -647,7 +648,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { val expected = List( // Not 1:1 so will get split out "~Top|Top/i:MyModule>a".rt -> "i.ports", - "~Top|Top/i:MyModule>b".rt -> "i.ports", + "~Top|Top/i:MyModule>b".rt -> "i.ports" ) val lines = List( "i.a <= foo", @@ -656,10 +657,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val (chirrtl, annos) = getFirrtlAndAnnos(new Top) val text = chirrtl.serialize for (line <- lines) { - text should include (line) + text should include(line) } for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } } @@ -682,11 +683,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val expected = List( "~Top|HasCMAR/c:AggregatePortModule>io".rt -> "c.io", "~Top|HasCMAR/c:AggregatePortModule>io.out".rt -> "c.io.out" - ) val (_, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } it("8.1: it should support @public on a CMAR Record in Instances") { @@ -706,11 +706,10 @@ class InstanceSpec extends ChiselFunSpec with Utils { val expected = List( "~Top|Top/i:HasCMAR/c:AggregatePortModule>io".rt -> "i.c.io", "~Top|Top/i:HasCMAR/c:AggregatePortModule>io.out".rt -> "i.c.io.out" - ) val (_, annos) = getFirrtlAndAnnos(new Top) for (e <- expected.map(MarkAnnotation.tupled)) { - annos should contain (e) + annos should contain(e) } } } @@ -769,10 +768,12 @@ class InstanceSpec extends ChiselFunSpec with Utils { it("10.0: instancesOf") { val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules => val targets = aop.Select.instancesOf[AddOne](m.toDefinition).map { i: Instance[AddOne] => i.toTarget } - targets should be (Seq( - "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, - "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it, - )) + targets should be( + Seq( + "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, + "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it + ) + ) }) getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect)) } @@ -781,14 +782,18 @@ class InstanceSpec extends ChiselFunSpec with Utils { val insts = aop.Select.instancesIn(m.toDefinition) val abs = insts.map { i: Instance[BaseModule] => i.toAbsoluteTarget } val rel = insts.map { i: Instance[BaseModule] => i.toTarget } - abs should be (Seq( - "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, - "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it, - )) - rel should be (Seq( - "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, - "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it, - )) + abs should be( + Seq( + "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, + "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it + ) + ) + rel should be( + Seq( + "~AddTwoMixedModules|AddTwoMixedModules/i0:AddOne".it, + "~AddTwoMixedModules|AddTwoMixedModules/i1:AddOne_1".it + ) + ) }) getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect)) } @@ -797,48 +802,58 @@ class InstanceSpec extends ChiselFunSpec with Utils { val insts = aop.Select.allInstancesOf[AddOne](m.toDefinition) val abs = insts.map { i: Instance[AddOne] => i.in.toAbsoluteTarget } val rel = insts.map { i: Instance[AddOne] => i.in.toTarget } - rel should be (Seq( - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, - )) - abs should be (Seq( - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, - )) + rel should be( + Seq( + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt + ) + ) + abs should be( + Seq( + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt + ) + ) }) getFirrtlAndAnnos(new AddFour, Seq(aspect)) } it("10.3: definitionsOf") { val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules => val targets = aop.Select.definitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget } - targets should be (Seq( - "~AddTwoMixedModules|AddOne>in".rt, - "~AddTwoMixedModules|AddOne_1>in".rt, - )) + targets should be( + Seq( + "~AddTwoMixedModules|AddOne>in".rt, + "~AddTwoMixedModules|AddOne_1>in".rt + ) + ) }) getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect)) } it("10.4: definitionsIn") { val aspect = aop.inspecting.InspectingAspect({ m: AddTwoMixedModules => val targets = aop.Select.definitionsIn(m.toDefinition).map { i: Definition[BaseModule] => i.toTarget } - targets should be (Seq( - "~AddTwoMixedModules|AddOne".mt, - "~AddTwoMixedModules|AddOne_1".mt, - )) + targets should be( + Seq( + "~AddTwoMixedModules|AddOne".mt, + "~AddTwoMixedModules|AddOne_1".mt + ) + ) }) getFirrtlAndAnnos(new AddTwoMixedModules, Seq(aspect)) } it("10.5: allDefinitionsOf") { val aspect = aop.inspecting.InspectingAspect({ m: AddFour => val targets = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).map { i: Definition[AddOne] => i.in.toTarget } - targets should be (Seq( - "~AddFour|AddOne>in".rt, - "~AddFour|AddOne_1>in".rt, - )) + targets should be( + Seq( + "~AddFour|AddOne>in".rt, + "~AddFour|AddOne_1>in".rt + ) + ) }) getFirrtlAndAnnos(new AddFour, Seq(aspect)) } @@ -862,120 +877,139 @@ class InstanceSpec extends ChiselFunSpec with Utils { } it("10.9: allInstancesOf.ios") { val aspect = aop.inspecting.InspectingAspect({ m: AddFour => - val abs = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] => aop.Select.ios(i).map(_.toAbsoluteTarget) } - val rel = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] => aop.Select.ios(i).map(_.toTarget) } - abs should be (Seq( - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt, - - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt, - - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt, - - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt, - )) - - rel should be (Seq( - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt, - - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt, + val abs = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] => + aop.Select.ios(i).map(_.toAbsoluteTarget) + } + val rel = aop.Select.allInstancesOf[AddOne](m.toDefinition).flatMap { i: Instance[AddOne] => + aop.Select.ios(i).map(_.toTarget) + } + abs should be( + Seq( + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt + ) + ) - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt, - - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, - "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt, - )) + rel should be( + Seq( + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>clock".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>reset".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i0:AddOne>out".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>clock".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>reset".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i0:AddTwoMixedModules/i1:AddOne_1>out".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>clock".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>reset".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i0:AddOne>out".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>clock".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>reset".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>in".rt, + "~AddFour|AddFour/i1:AddTwoMixedModules/i1:AddOne_1>out".rt + ) + ) }) getFirrtlAndAnnos(new AddFour, Seq(aspect)) } it("10.10: allDefinitionsOf.ios") { val aspect = aop.inspecting.InspectingAspect({ m: AddFour => - val abs = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] => aop.Select.ios(i).map(_.toAbsoluteTarget) } - val rel = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] => aop.Select.ios(i).map(_.toTarget) } - abs should be (Seq( - "~AddFour|AddOne>clock".rt, - "~AddFour|AddOne>reset".rt, - "~AddFour|AddOne>in".rt, - "~AddFour|AddOne>out".rt, - - "~AddFour|AddOne_1>clock".rt, - "~AddFour|AddOne_1>reset".rt, - "~AddFour|AddOne_1>in".rt, - "~AddFour|AddOne_1>out".rt, - )) + val abs = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] => + aop.Select.ios(i).map(_.toAbsoluteTarget) + } + val rel = aop.Select.allDefinitionsOf[AddOne](m.toDefinition).flatMap { i: Definition[AddOne] => + aop.Select.ios(i).map(_.toTarget) + } + abs should be( + Seq( + "~AddFour|AddOne>clock".rt, + "~AddFour|AddOne>reset".rt, + "~AddFour|AddOne>in".rt, + "~AddFour|AddOne>out".rt, + "~AddFour|AddOne_1>clock".rt, + "~AddFour|AddOne_1>reset".rt, + "~AddFour|AddOne_1>in".rt, + "~AddFour|AddOne_1>out".rt + ) + ) - rel should be (Seq( - "~AddFour|AddOne>clock".rt, - "~AddFour|AddOne>reset".rt, - "~AddFour|AddOne>in".rt, - "~AddFour|AddOne>out".rt, + rel should be( + Seq( + "~AddFour|AddOne>clock".rt, + "~AddFour|AddOne>reset".rt, + "~AddFour|AddOne>in".rt, + "~AddFour|AddOne>out".rt, + "~AddFour|AddOne_1>clock".rt, + "~AddFour|AddOne_1>reset".rt, + "~AddFour|AddOne_1>in".rt, + "~AddFour|AddOne_1>out".rt + ) + ) - "~AddFour|AddOne_1>clock".rt, - "~AddFour|AddOne_1>reset".rt, - "~AddFour|AddOne_1>in".rt, - "~AddFour|AddOne_1>out".rt, - )) - }) getFirrtlAndAnnos(new AddFour, Seq(aspect)) } it("10.11 Select.instancesIn for typed BaseModules") { val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside => val targets = aop.Select.instancesIn(m.toDefinition).map { i: Instance[BaseModule] => i.toTarget } - targets should be (Seq( - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it, - )) + targets should be( + Seq( + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it + ) + ) }) getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect)) } it("10.12 Select.instancesOf for typed BaseModules if type is ignored") { val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside => - val targets = aop.Select.instancesOf[HasTypeParams[_]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => i.toTarget } - targets should be (Seq( - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it, - )) + val targets = + aop.Select.instancesOf[HasTypeParams[_]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => i.toTarget } + targets should be( + Seq( + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it + ) + ) }) getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect)) } - it("10.13 Select.instancesOf for typed BaseModules even type is specified wrongly (should be ignored, even though we wish it weren't)") { + it( + "10.13 Select.instancesOf for typed BaseModules even type is specified wrongly (should be ignored, even though we wish it weren't)" + ) { val aspect = aop.inspecting.InspectingAspect({ m: HasMultipleTypeParamsInside => - val targets = aop.Select.instancesOf[HasTypeParams[SInt]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => i.toTarget } - targets should be (Seq( - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, - "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it, - )) + val targets = aop.Select.instancesOf[HasTypeParams[SInt]](m.toDefinition).map { i: Instance[HasTypeParams[_]] => + i.toTarget + } + targets should be( + Seq( + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i00:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i01:HasTypeParams".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i10:HasTypeParams_1".it, + "~HasMultipleTypeParamsInside|HasMultipleTypeParamsInside/i11:HasTypeParams_1".it + ) + ) }) - getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect)) + getFirrtlAndAnnos(new HasMultipleTypeParamsInside, Seq(aspect)) } } } diff --git a/src/test/scala/chiselTests/naming/NamePluginSpec.scala b/src/test/scala/chiselTests/naming/NamePluginSpec.scala index 3a539bd4..18359fd2 100644 --- a/src/test/scala/chiselTests/naming/NamePluginSpec.scala +++ b/src/test/scala/chiselTests/naming/NamePluginSpec.scala @@ -12,20 +12,20 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { "Scala plugin" should "name internally scoped components" in { class Test extends Module { - { val mywire = Wire(UInt(3.W))} + { val mywire = Wire(UInt(3.W)) } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).head.toTarget.ref should be("mywire") + aspectTest(() => new Test) { top: Test => + Select.wires(top).head.toTarget.ref should be("mywire") } } "Scala plugin" should "name internally scoped instances" in { - class Inner extends Module { } + class Inner extends Module {} class Test extends Module { { val myinstance = Module(new Inner) } } - aspectTest(() => new Test) { - top: Test => Select.instances(top).head.instanceName should be("myinstance") + aspectTest(() => new Test) { top: Test => + Select.instances(top).head.instanceName should be("myinstance") } } @@ -41,8 +41,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { builder() } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).map(_.instanceName) should be (List("first_wire", "second_wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("first_wire", "second_wire")) } } @@ -64,8 +64,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).map(_.instanceName) should be (List("x1_first_wire1", "x1", "x2_second_wire1", "x2")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("x1_first_wire1", "x1", "x2_second_wire1", "x2")) } } @@ -79,13 +79,11 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { { val blah = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("blah")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("blah")) } } - "Naming on iterables" should "work" in { class Test extends Module { @@ -100,9 +98,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("blah_0", "blah_1")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("blah_0", "blah_1")) } } @@ -122,15 +119,15 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be ( - List( - "blah_0_0", - "blah_0_1", - "blah_1_0", - "blah_1_1" - )) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be( + List( + "blah_0_0", + "blah_0_1", + "blah_1_0", + "blah_1_1" + ) + ) } } @@ -146,9 +143,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { { val blah = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("a", "b")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a", "b")) } } @@ -160,9 +156,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.ios(top).map(_.instanceName) should be (List("a")) + aspectTest(() => new Test) { top: Test => + Select.ios(top).map(_.instanceName) should be(List("a")) } } @@ -174,9 +169,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("a")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a")) } } @@ -193,9 +187,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.ios(top).map(_.instanceName) should be (List("out")) + aspectTest(() => new Test) { top: Test => + Select.ios(top).map(_.instanceName) should be(List("out")) } } @@ -212,9 +205,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("fizz")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("fizz")) } } @@ -226,13 +218,11 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.ios(top).map(_.instanceName) should be (List("a")) + aspectTest(() => new Test) { top: Test => + Select.ios(top).map(_.instanceName) should be(List("a")) } } - "autoSeed" should "override automatic naming for non-IO" in { class Test extends Module { { @@ -241,9 +231,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("b")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("b")) } } @@ -254,9 +243,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("a", "b")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a", "b")) } } @@ -268,9 +256,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("x", "b")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("x", "b")) } } @@ -283,9 +270,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("a", "b")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a", "b")) } } @@ -302,9 +288,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("w", "a", "_WIRE")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("w", "a", "_WIRE")) } } @@ -332,9 +317,8 @@ class NamePluginSpec extends ChiselFlatSpec with Utils { } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).map(_.instanceName) should be (List("a_b_c", "a_b", "a")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a_b_c", "a_b", "a")) } } } - diff --git a/src/test/scala/chiselTests/naming/PrefixSpec.scala b/src/test/scala/chiselTests/naming/PrefixSpec.scala index 0712692d..f9a78f0e 100644 --- a/src/test/scala/chiselTests/naming/PrefixSpec.scala +++ b/src/test/scala/chiselTests/naming/PrefixSpec.scala @@ -28,8 +28,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).map(_.instanceName) should be (List("x1_first_wire1", "x1", "x2_second_wire1", "x2")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("x1_first_wire1", "x1", "x2_second_wire1", "x2")) } } @@ -50,20 +50,19 @@ class PrefixSpec extends ChiselPropSpec with Utils { { val x1 = builder() } { val x2 = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be ( - List( - "x1_wire1", - "x1_wire2", - "x1_foo_wire1", - "x1", - "x2_wire1", - "x2_wire2", - "x2_foo_wire1", - "x2" - ) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be( + List( + "x1_wire1", + "x1_wire2", + "x1_foo_wire1", + "x1", + "x2_wire1", + "x2_wire2", + "x2_foo_wire1", + "x2" ) + ) } } @@ -85,9 +84,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("x1", "x1_wire", "x2", "x2_wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("x1", "x1_wire", "x2", "x2_wire")) } } @@ -105,9 +103,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { val JACOB = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("ADAM_a", "ADAM", "JACOB_a", "JACOB")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("ADAM_a", "ADAM", "JACOB_a", "JACOB")) } } @@ -122,9 +119,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { { val noprefix = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("a", "noprefix")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("a", "noprefix")) } } @@ -139,12 +135,13 @@ class PrefixSpec extends ChiselPropSpec with Utils { { val blah = builder() } } - aspectTest(() => new Test) { - top: Test => - Select.ops(top).map(x => (x._1, x._2.instanceName)) should be (List( + aspectTest(() => new Test) { top: Test => + Select.ops(top).map(x => (x._1, x._2.instanceName)) should be( + List( ("mul", "_blah_T"), ("add", "blah") - )) + ) + ) } } @@ -162,9 +159,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(Select.instances(top).head).map(_.instanceName) should be (List("wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(Select.instances(top).head).map(_.instanceName) should be(List("wire")) } } @@ -182,9 +178,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { val child = Module(module) } } - aspectTest(() => new Test) { - top: Test => - Select.wires(Select.instances(top).head).map(_.instanceName) should be (List("wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(Select.instances(top).head).map(_.instanceName) should be(List("wire")) } } @@ -204,13 +199,11 @@ class PrefixSpec extends ChiselPropSpec with Utils { val child = Module(module) } } - aspectTest(() => new Test) { - top: Test => - Select.ios(Select.instances(top).head).map(_.instanceName) should be (List("clock", "reset", "io")) + aspectTest(() => new Test) { top: Test => + Select.ios(Select.instances(top).head).map(_.instanceName) should be(List("clock", "reset", "io")) } } - property("Prefixing should not be caused by nested Iterable[Iterable[Any]]") { class Test extends Module { { @@ -220,9 +213,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("wire")) } } @@ -235,9 +227,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("iia_wire")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("iia_wire")) } } @@ -250,10 +241,9 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("mywire")) - Select.wires(top).map(_.instanceName) shouldNot be (List("wire_mywire")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("mywire")) + Select.wires(top).map(_.instanceName) shouldNot be(List("wire_mywire")) } } @@ -268,8 +258,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => Select.wires(top).map(_.instanceName) should be (List("wire_mywire", "mywire2")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("wire_mywire", "mywire2")) } } @@ -288,15 +278,16 @@ class PrefixSpec extends ChiselPropSpec with Utils { wire.vec(1.U) := RegNext(3.U) } } - aspectTest(() => new Test) { - top: Test => - Select.registers(top).map(_.instanceName) should be (List( + aspectTest(() => new Test) { top: Test => + Select.registers(top).map(_.instanceName) should be( + List( "wire_x_REG", "wire_y_REG", "wire_vec_0_REG", "wire_vec_REG", "wire_vec_1_REG" - )) + ) + ) } } @@ -312,14 +303,17 @@ class PrefixSpec extends ChiselPropSpec with Utils { child.in := RegNext(3.U) } } - aspectTest(() => new Test) { - top: Test => - Select.registers(top).map(_.instanceName) should be (List( + aspectTest(() => new Test) { top: Test => + Select.registers(top).map(_.instanceName) should be( + List( "child_in_REG" - )) - Select.registers(Select.instances(top).head).map(_.instanceName) should be (List( + ) + ) + Select.registers(Select.instances(top).head).map(_.instanceName) should be( + List( "out_REG" - )) + ) + ) } } @@ -335,14 +329,17 @@ class PrefixSpec extends ChiselPropSpec with Utils { child.in <> RegNext(3.U) } } - aspectTest(() => new Test) { - top: Test => - Select.registers(top).map(_.instanceName) should be (List( + aspectTest(() => new Test) { top: Test => + Select.registers(top).map(_.instanceName) should be( + List( "child_in_REG" - )) - Select.registers(Select.instances(top).head).map(_.instanceName) should be (List( + ) + ) + Select.registers(Select.instances(top).head).map(_.instanceName) should be( + List( "out_REG" - )) + ) + ) } } @@ -357,9 +354,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("foo_x", "foo_x_w")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("foo_x", "foo_x_w")) } } @@ -374,13 +370,11 @@ class PrefixSpec extends ChiselPropSpec with Utils { } } } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("foo_x", "foo_x_bar_w")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("foo_x", "foo_x_bar_w")) } } - property("Prefixing with wires in recursive functions should grow linearly") { class Test extends Module { def func(bools: Seq[Bool]): Bool = { @@ -394,9 +388,8 @@ class PrefixSpec extends ChiselPropSpec with Utils { val in = IO(Input(Vec(4, Bool()))) val x = func(in) } - aspectTest(() => new Test) { - top: Test => - Select.wires(top).map(_.instanceName) should be (List("x", "x_w_w", "x_w_w_w", "x_w_w_w_w")) + aspectTest(() => new Test) { top: Test => + Select.wires(top).map(_.instanceName) should be(List("x", "x_w_w", "x_w_w_w", "x_w_w_w_w")) } } diff --git a/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala b/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala index 2d804562..9dac820c 100644 --- a/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala +++ b/src/test/scala/chiselTests/stage/ChiselAnnotationsSpec.scala @@ -27,41 +27,41 @@ class ChiselAnnotation class ChiselAnnotationsSpec extends AnyFlatSpec with Matchers { - behavior of "ChiselGeneratorAnnotation elaboration" + behavior.of("ChiselGeneratorAnnotation elaboration") it should "elaborate to a ChiselCircuitAnnotation" in { val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecFoo) val res = annotation.elaborate - res(0) shouldBe a [ChiselCircuitAnnotation] - res(1) shouldBe a [DesignAnnotation[ChiselAnnotationsSpecFoo]] + res(0) shouldBe a[ChiselCircuitAnnotation] + res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]] } it should "throw an exception if elaboration fails" in { val annotation = ChiselGeneratorAnnotation(() => new ChiselAnnotationsSpecQux) - intercept [ChiselException] { annotation.elaborate } + intercept[ChiselException] { annotation.elaborate } } - behavior of "ChiselGeneratorAnnotation when stringly constructing from Module names" + behavior.of("ChiselGeneratorAnnotation when stringly constructing from Module names") it should "elaborate from a String" in { val annotation = ChiselGeneratorAnnotation("chiselTests.stage.ChiselAnnotationsSpecFoo") val res = annotation.elaborate - res(0) shouldBe a [ChiselCircuitAnnotation] - res(1) shouldBe a [DesignAnnotation[ChiselAnnotationsSpecFoo]] + res(0) shouldBe a[ChiselCircuitAnnotation] + res(1) shouldBe a[DesignAnnotation[ChiselAnnotationsSpecFoo]] } it should "throw an exception if elaboration from a String refers to nonexistant class" in { val bar = "chiselTests.stage.ChiselAnnotationsSpecBar" val annotation = ChiselGeneratorAnnotation(bar) - intercept [OptionsException] { annotation.elaborate } - .getMessage should startWith (s"Unable to locate module '$bar'") + intercept[OptionsException] { annotation.elaborate }.getMessage should startWith(s"Unable to locate module '$bar'") } it should "throw an exception if elaboration from a String refers to an anonymous class" in { val baz = "chiselTests.stage.ChiselAnnotationsSpecBaz" val annotation = ChiselGeneratorAnnotation(baz) - intercept [OptionsException] { annotation.elaborate } - .getMessage should startWith (s"Unable to create instance of module '$baz'") + intercept[OptionsException] { annotation.elaborate }.getMessage should startWith( + s"Unable to create instance of module '$baz'" + ) } } diff --git a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala b/src/test/scala/chiselTests/stage/ChiselMainSpec.scala index 1634e765..e8773111 100644 --- a/src/test/scala/chiselTests/stage/ChiselMainSpec.scala +++ b/src/test/scala/chiselTests/stage/ChiselMainSpec.scala @@ -44,13 +44,15 @@ object ChiselMainSpec { } } -case class TestClassAspect() extends InspectorAspect[RawModule] ({ - _: RawModule => println("Ran inspectingAspect") -}) +case class TestClassAspect() + extends InspectorAspect[RawModule]({ _: RawModule => + println("Ran inspectingAspect") + }) -case object TestObjectAspect extends InspectorAspect[RawModule] ({ - _: RawModule => println("Ran inspectingAspect") -}) +case object TestObjectAspect + extends InspectorAspect[RawModule]({ _: RawModule => + println("Ran inspectingAspect") + }) class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers with chiselTests.Utils { @@ -68,14 +70,14 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit } case class ChiselMainTest( - args: Array[String], - generator: Option[Class[_ <: RawModule]] = None, - files: Seq[String] = Seq.empty, - stdout: Seq[Either[String, String]] = Seq.empty, - stderr: Seq[Either[String, String]] = Seq.empty, - result: Int = 0, + args: Array[String], + generator: Option[Class[_ <: RawModule]] = None, + files: Seq[String] = Seq.empty, + stdout: Seq[Either[String, String]] = Seq.empty, + stderr: Seq[Either[String, String]] = Seq.empty, + result: Int = 0, fileChecks: Map[String, File => Unit] = Map.empty) { - def testName: String = "args" + args.mkString("_") + def testName: String = "args" + args.mkString("_") def argsString: String = args.mkString(" ") } @@ -89,14 +91,13 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit * @tparam the type of exception that should occur */ case class ChiselMainExceptionTest[A <: Throwable]( - args: Array[String], - generator: Option[Class[_ <: RawModule]] = None, - message: Seq[Either[String, String]] = Seq.empty, - stdout: Seq[Either[String, String]] = Seq.empty, - stderr: Seq[Either[String, String]] = Seq.empty, - stackTrace: Seq[Either[String, String]] = Seq.empty - ) { - def testName: String = "args" + args.mkString("_") + args: Array[String], + generator: Option[Class[_ <: RawModule]] = None, + message: Seq[Either[String, String]] = Seq.empty, + stdout: Seq[Either[String, String]] = Seq.empty, + stderr: Seq[Either[String, String]] = Seq.empty, + stackTrace: Seq[Either[String, String]] = Seq.empty) { + def testName: String = "args" + args.mkString("_") def argsString: String = args.mkString(" ") } @@ -105,12 +106,12 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit val f = new ChiselMainFixture val td = new TargetDirectoryFixture(p.testName) - p.files.foreach( f => new File(td.buildDir + s"/$f").delete() ) + p.files.foreach(f => new File(td.buildDir + s"/$f").delete()) When(s"""the user tries to compile with '${p.argsString}'""") val module: Array[String] = (if (p.generator.nonEmpty) { Array("--module", p.generator.get.getName) } - else { Array.empty[String] }) + else { Array.empty[String] }) f.stage.main(Array("-td", td.buildDir.toString) ++ module ++ p.args) val (stdout, stderr, result) = grabStdOutErr { @@ -122,25 +123,25 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit p.stdout.foreach { case Right(a) => Then(s"""STDOUT should include "$a"""") - stdout should include (a) + stdout should include(a) case Left(a) => Then(s"""STDOUT should not include "$a"""") - stdout should not include (a) + (stdout should not).include(a) } p.stderr.foreach { case Right(a) => Then(s"""STDERR should include "$a"""") - stderr should include (a) + stderr should include(a) case Left(a) => Then(s"""STDERR should not include "$a"""") - stderr should not include (a) + (stderr should not).include(a) } p.result match { case 0 => And(s"the exit code should be 0") - result shouldBe a [Right[_,_]] + result shouldBe a[Right[_, _]] case a => And(s"the exit code should be $a") result shouldBe (Left(a)) @@ -167,7 +168,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit When(s"""the user tries to compile with '${p.argsString}'""") val module: Array[String] = (if (p.generator.nonEmpty) { Array("--module", p.generator.get.getName) } - else { Array.empty[String] }) + else { Array.empty[String] }) val (stdout, stderr, result) = grabStdOutErr { catchStatus { @@ -178,7 +179,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit } Then("the expected exception was thrown") - result should be a ('right) + (result should be).a('right) val exception = result.right.get info(s""" - Exception was a "${exception.getClass.getName}"""") @@ -186,38 +187,38 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit p.message.foreach { case Right(a) => Then(s"""STDOUT should include "$a"""") - message should include (a) + message should include(a) case Left(a) => Then(s"""STDOUT should not include "$a"""") - message should not include (a) + (message should not).include(a) } p.stdout.foreach { case Right(a) => Then(s"""STDOUT should include "$a"""") - stdout should include (a) + stdout should include(a) case Left(a) => Then(s"""STDOUT should not include "$a"""") - stdout should not include (a) + (stdout should not).include(a) } p.stderr.foreach { case Right(a) => Then(s"""STDERR should include "$a"""") - stderr should include (a) + stderr should include(a) case Left(a) => Then(s"""STDERR should not include "$a"""") - stderr should not include (a) + (stderr should not).include(a) } val stackTraceString = exception.getStackTrace.mkString("\n") p.stackTrace.foreach { case Left(a) => And(s"""the stack does not include "$a"""") - stackTraceString should not include (a) + (stackTraceString should not).include(a) case Right(a) => And(s"""the stack trace includes "$a"""") - stackTraceString should include (a) + stackTraceString should include(a) } } @@ -227,9 +228,7 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit info("I compile a design") Feature("show elaborating message") { runStageExpectFiles( - ChiselMainTest(args = Array("-X", "high"), - generator = Some(classOf[SameTypesModule]) - ) + ChiselMainTest(args = Array("-X", "high"), generator = Some(classOf[SameTypesModule])) ) } @@ -268,46 +267,58 @@ class ChiselMainSpec extends AnyFeatureSpec with GivenWhenThen with Matchers wit args = Array("-X", "low"), generator = Some(classOf[BuilderErrorModule]), message = Seq(Right("Fatal errors during hardware elaboration")), - stdout = Seq(Right("ChiselMainSpec.scala:43: Invalid bit range (3,-1) in class chiselTests.stage.ChiselMainSpec$BuilderErrorModule")) + stdout = Seq( + Right( + "ChiselMainSpec.scala:43: Invalid bit range (3,-1) in class chiselTests.stage.ChiselMainSpec$BuilderErrorModule" + ) + ) ) ).foreach(runStageExpectException) } Feature("Specifying a custom output file") { - runStageExpectFiles(ChiselMainTest( - args = Array("--chisel-output-file", "Foo", "--no-run-firrtl"), - generator = Some(classOf[SameTypesModule]), - files = Seq("Foo.fir"), - fileChecks = Map( - "Foo.fir" -> { file => - And("It should be valid FIRRTL") - Parser.parse(Source.fromFile(file).mkString) - } + runStageExpectFiles( + ChiselMainTest( + args = Array("--chisel-output-file", "Foo", "--no-run-firrtl"), + generator = Some(classOf[SameTypesModule]), + files = Seq("Foo.fir"), + fileChecks = Map( + "Foo.fir" -> { file => + And("It should be valid FIRRTL") + Parser.parse(Source.fromFile(file).mkString) + } + ) ) - )) - runStageExpectFiles(ChiselMainTest( - args = Array("--chisel-output-file", "Foo.pb", "--no-run-firrtl"), - generator = Some(classOf[SameTypesModule]), - files = Seq("Foo.pb"), - fileChecks = Map( - "Foo.pb" -> { file => - And("It should be valid ProtoBuf") - firrtl.proto.FromProto.fromFile(file.toString) - } + ) + runStageExpectFiles( + ChiselMainTest( + args = Array("--chisel-output-file", "Foo.pb", "--no-run-firrtl"), + generator = Some(classOf[SameTypesModule]), + files = Seq("Foo.pb"), + fileChecks = Map( + "Foo.pb" -> { file => + And("It should be valid ProtoBuf") + firrtl.proto.FromProto.fromFile(file.toString) + } + ) ) - )) + ) } info("As an aspect writer") info("I write an aspect") Feature("Running aspects via the command line") { Seq( - ChiselMainTest(args = Array( "-X", "high", "--with-aspect", "chiselTests.stage.TestClassAspect" ), + ChiselMainTest( + args = Array("-X", "high", "--with-aspect", "chiselTests.stage.TestClassAspect"), generator = Some(classOf[SameTypesModule]), - stdout = Seq(Right("Ran inspectingAspect"))), - ChiselMainTest(args = Array( "-X", "high", "--with-aspect", "chiselTests.stage.TestObjectAspect" ), + stdout = Seq(Right("Ran inspectingAspect")) + ), + ChiselMainTest( + args = Array("-X", "high", "--with-aspect", "chiselTests.stage.TestObjectAspect"), generator = Some(classOf[SameTypesModule]), - stdout = Seq(Right("Ran inspectingAspect"))) + stdout = Seq(Right("Ran inspectingAspect")) + ) ).foreach(runStageExpectFiles) } diff --git a/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala b/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala index 99c0f7c0..b164ff20 100644 --- a/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala +++ b/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage - import firrtl.options.Viewer.view import firrtl.RenameMap @@ -13,7 +12,7 @@ import org.scalatest.matchers.should.Matchers class ChiselOptionsViewSpec extends AnyFlatSpec with Matchers { - behavior of ChiselOptionsView.getClass.getName + behavior.of(ChiselOptionsView.getClass.getName) it should "construct a view from an AnnotationSeq" in { val bar = Circuit("bar", Seq.empty, Seq.empty, RenameMap()) @@ -26,16 +25,16 @@ class ChiselOptionsViewSpec extends AnyFlatSpec with Matchers { val out = view[ChiselOptions](annotations) info("runFirrtlCompiler was set to false") - out.runFirrtlCompiler should be (false) + out.runFirrtlCompiler should be(false) info("printFullStackTrace was set to true") - out.printFullStackTrace should be (true) + out.printFullStackTrace should be(true) info("outputFile was set to 'foo'") - out.outputFile should be (Some("foo")) + out.outputFile should be(Some("foo")) info("chiselCircuit was set to circuit 'bar'") - out.chiselCircuit should be (Some(bar)) + out.chiselCircuit should be(Some(bar)) } diff --git a/src/test/scala/chiselTests/stage/ChiselStageSpec.scala b/src/test/scala/chiselTests/stage/ChiselStageSpec.scala index 7b6a2d39..e88a2385 100644 --- a/src/test/scala/chiselTests/stage/ChiselStageSpec.scala +++ b/src/test/scala/chiselTests/stage/ChiselStageSpec.scala @@ -44,44 +44,44 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { val stage = new ChiselStage } - behavior of "ChiselStage$.emitChirrtl" + behavior.of("ChiselStage$.emitChirrtl") it should "return a CHIRRTL string" in { - ChiselStage.emitChirrtl(new Foo) should include ("infer mport") + ChiselStage.emitChirrtl(new Foo) should include("infer mport") } - behavior of "ChiselStage$.emitFirrtl" + behavior.of("ChiselStage$.emitFirrtl") it should "return a High FIRRTL string" in { - ChiselStage.emitFirrtl(new Foo) should include ("mem memory") + ChiselStage.emitFirrtl(new Foo) should include("mem memory") } it should "return a flattened FIRRTL string with '-e high'" in { val args = Array("-e", "high", "-td", createTestDirectory(this.getClass.getSimpleName).toString) (new ChiselStage) - .emitFirrtl(new Foo, args) should include ("module Bar") + .emitFirrtl(new Foo, args) should include("module Bar") } - behavior of "ChiselStage$.emitVerilog" + behavior.of("ChiselStage$.emitVerilog") it should "return a Verilog string" in { - ChiselStage.emitVerilog(new Foo) should include ("endmodule") + ChiselStage.emitVerilog(new Foo) should include("endmodule") } it should "return a flattened Verilog string with '-e verilog'" in { val args = Array("-e", "verilog", "-td", createTestDirectory(this.getClass.getSimpleName).toString) (new ChiselStage) - .emitVerilog(new Foo, args) should include ("module Bar") + .emitVerilog(new Foo, args) should include("module Bar") } - behavior of "ChiselStage$.elaborate" + behavior.of("ChiselStage$.elaborate") ignore should "generate a Chisel circuit from a Chisel module" in { info("no files were written") catchWrites { ChiselStage.elaborate(new Foo) } shouldBe a[Right[_, _]] } - behavior of "ChiselStage$.convert" + behavior.of("ChiselStage$.convert") ignore should "generate a CHIRRTL circuit from a Chisel module" in { info("no files were written") @@ -95,7 +95,7 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { } shouldBe a[Right[_, _]] } - behavior of "ChiselStage$.emitChirrtl" + behavior.of("ChiselStage$.emitChirrtl") ignore should "generate a CHIRRTL string from a Chisel module" in { val wrapped = catchWrites { ChiselStage.emitChirrtl(new Foo) } @@ -104,10 +104,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { wrapped shouldBe a[Right[_, _]] info("returned string looks like FIRRTL") - wrapped.right.get should include ("circuit") + wrapped.right.get should include("circuit") } - behavior of "ChiselStage$.emitFirrtl" + behavior.of("ChiselStage$.emitFirrtl") ignore should "generate a FIRRTL string from a Chisel module" in { val wrapped = catchWrites { ChiselStage.emitFirrtl(new Foo) } @@ -116,10 +116,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { wrapped shouldBe a[Right[_, _]] info("returned string looks like FIRRTL") - wrapped.right.get should include ("circuit") + wrapped.right.get should include("circuit") } - behavior of "ChiselStage$.emitVerilog" + behavior.of("ChiselStage$.emitVerilog") ignore should "generate a Verilog string from a Chisel module" in { val wrapped = catchWrites { ChiselStage.emitVerilog(new Foo) } @@ -128,10 +128,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { wrapped shouldBe a[Right[_, _]] info("returned string looks like Verilog") - wrapped.right.get should include ("endmodule") + wrapped.right.get should include("endmodule") } - behavior of "ChiselStage$.emitSystemVerilog" + behavior.of("ChiselStage$.emitSystemVerilog") ignore should "generate a SystemvVerilog string from a Chisel module" in { val wrapped = catchWrites { ChiselStage.emitSystemVerilog(new Foo) } @@ -139,10 +139,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { wrapped shouldBe a[Right[_, _]] info("returned string looks like Verilog") - wrapped.right.get should include ("endmodule") + wrapped.right.get should include("endmodule") } - behavior of "ChiselStage phase ordering" + behavior.of("ChiselStage phase ordering") it should "only run elaboration once" in new ChiselStageFixture { info("Phase order is:\n" + stage.phaseManager.prettyPrint(" ")) @@ -150,10 +150,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { val order = stage.phaseManager.flattenedTransformOrder.map(Dependency.fromTransform) info("Elaborate only runs once") - exactly (1, order) should be (Dependency[chisel3.stage.phases.Elaborate]) + exactly(1, order) should be(Dependency[chisel3.stage.phases.Elaborate]) } - behavior of "ChiselStage$ exception handling" + behavior.of("ChiselStage$ exception handling") it should "truncate a user exception" in { info("The user's java.lang.AssertionError was thrown") @@ -163,13 +163,13 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { val message = exception.getMessage info("The exception includes the user's message") - message should include ("User threw an exception") + message should include("User threw an exception") info("The stack trace is trimmed") - exception.getStackTrace.mkString("\n") should not include ("java") + (exception.getStackTrace.mkString("\n") should not).include("java") } - behavior of "ChiselStage exception handling" + behavior.of("ChiselStage exception handling") it should "truncate a user exception" in { info("The user's java.lang.AssertionError was thrown") @@ -181,14 +181,14 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { val message = exception.getMessage info("The exception includes the user's message") - message should include ("User threw an exception") + message should include("User threw an exception") val stackTrace = exception.getStackTrace.mkString("\n") info("The stack trace is trimmed") - stackTrace should not include ("java") + (stackTrace should not).include("java") info("The stack trace include information about running --full-stacktrace") - stackTrace should include ("--full-stacktrace") + stackTrace should include("--full-stacktrace") } it should """not truncate a user exception with "--full-stacktrace"""" in { @@ -201,10 +201,10 @@ class ChiselStageSpec extends AnyFlatSpec with Matchers with Utils { val message = exception.getMessage info("The exception includes the user's message") - message should include ("User threw an exception") + message should include("User threw an exception") info("The stack trace is not trimmed") - exception.getStackTrace.mkString("\n") should include ("java") + exception.getStackTrace.mkString("\n") should include("java") } } diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala index 63ac7bbe..faf411ed 100644 --- a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3.RawModule import chisel3.stage.ChiselGeneratorAnnotation import chisel3.stage.phases.{AddImplicitOutputAnnotationFile, Elaborate} @@ -18,26 +17,25 @@ class AddImplicitOutputAnnotationFileSpec extends AnyFlatSpec with Matchers { class Fixture { val phase: Phase = new AddImplicitOutputAnnotationFile } - behavior of classOf[AddImplicitOutputAnnotationFile].toString + behavior.of(classOf[AddImplicitOutputAnnotationFile].toString) it should "not override an existing OutputAnnotationFileAnnotation" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - OutputAnnotationFileAnnotation("Bar") ) + val annotations: AnnotationSeq = + Seq(ChiselGeneratorAnnotation(() => new Foo), OutputAnnotationFileAnnotation("Bar")) - Seq( new Elaborate, phase ) + Seq(new Elaborate, phase) .foldLeft(annotations)((a, p) => p.transform(a)) - .collect{ case a: OutputAnnotationFileAnnotation => a.file } - .toSeq should be (Seq("Bar")) + .collect { case a: OutputAnnotationFileAnnotation => a.file } + .toSeq should be(Seq("Bar")) } it should "generate an OutputAnnotationFileAnnotation from a ChiselCircuitAnnotation" in new Fixture { - val annotations: AnnotationSeq = Seq( ChiselGeneratorAnnotation(() => new Foo) ) + val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo)) - Seq( new Elaborate, phase ) + Seq(new Elaborate, phase) .foldLeft(annotations)((a, p) => p.transform(a)) - .collect{ case a: OutputAnnotationFileAnnotation => a.file } - .toSeq should be (Seq("Foo")) + .collect { case a: OutputAnnotationFileAnnotation => a.file } + .toSeq should be(Seq("Foo")) } } diff --git a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala index e8ba390e..20274e7a 100644 --- a/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3.RawModule import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation} import chisel3.stage.phases.{AddImplicitOutputFile, Elaborate} @@ -19,32 +18,28 @@ class AddImplicitOutputFileSpec extends AnyFlatSpec with Matchers { class Fixture { val phase: Phase = new AddImplicitOutputFile } - behavior of classOf[AddImplicitOutputFile].toString + behavior.of(classOf[AddImplicitOutputFile].toString) it should "not override an existing ChiselOutputFileAnnotation" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - ChiselOutputFileAnnotation("Bar") ) + val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar")) - Seq( new Elaborate, phase ) + Seq(new Elaborate, phase) .foldLeft(annotations)((a, p) => p.transform(a)) - .collect{ case a: ChiselOutputFileAnnotation => a.file } - .toSeq should be (Seq("Bar")) + .collect { case a: ChiselOutputFileAnnotation => a.file } + .toSeq should be(Seq("Bar")) } it should "generate a ChiselOutputFileAnnotation from a ChiselCircuitAnnotation" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - TargetDirAnnotation("test_run_dir") ) + val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), TargetDirAnnotation("test_run_dir")) - Seq( new Elaborate, phase ) + Seq(new Elaborate, phase) .foldLeft(annotations)((a, p) => p.transform(a)) - .collect{ case a: ChiselOutputFileAnnotation => a.file } - .toSeq should be (Seq("Foo")) + .collect { case a: ChiselOutputFileAnnotation => a.file } + .toSeq should be(Seq("Foo")) } it should "do nothing to an empty annotation sequence" in new Fixture { - phase.transform(AnnotationSeq(Seq.empty)).toSeq should be (empty) + phase.transform(AnnotationSeq(Seq.empty)).toSeq should be(empty) } } diff --git a/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala b/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala index 8bca9ccd..57633eac 100644 --- a/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/AddSerializationAnnotationsSpec.scala @@ -2,14 +2,13 @@ package chiselTests.stage.phases - import chisel3.RawModule import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation, CircuitSerializationAnnotation} import chisel3.stage.CircuitSerializationAnnotation._ -import chisel3.stage.phases.{AddSerializationAnnotations, AddImplicitOutputFile, Elaborate} +import chisel3.stage.phases.{AddImplicitOutputFile, AddSerializationAnnotations, Elaborate} import firrtl.AnnotationSeq -import firrtl.options.{Phase, PhaseManager, Dependency, TargetDirAnnotation} +import firrtl.options.{Dependency, Phase, PhaseManager, TargetDirAnnotation} import firrtl.options.Viewer.view import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers @@ -23,39 +22,34 @@ class AddSerializationAnnotationsSpec extends AnyFlatSpec with Matchers { val manager = new PhaseManager(Dependency[AddSerializationAnnotations] :: Nil) } - behavior of classOf[AddSerializationAnnotations].toString + behavior.of(classOf[AddSerializationAnnotations].toString) it should "default to FirrtlFileFormat" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - ChiselOutputFileAnnotation("Bar") ) + val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar")) manager .transform(annotations) .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) } - .toSeq should be (Seq(("Bar", FirrtlFileFormat))) + .toSeq should be(Seq(("Bar", FirrtlFileFormat))) } it should "support ProtoBufFileFormat" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - ChiselOutputFileAnnotation("Bar.pb") ) + val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar.pb")) manager .transform(annotations) .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) } - .toSeq should be (Seq(("Bar", ProtoBufFileFormat))) + .toSeq should be(Seq(("Bar", ProtoBufFileFormat))) } it should "support explicitly asking for FirrtlFileFormat" in new Fixture { - val annotations: AnnotationSeq = Seq( - ChiselGeneratorAnnotation(() => new Foo), - ChiselOutputFileAnnotation("Bar.pb.fir") ) + val annotations: AnnotationSeq = + Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar.pb.fir")) manager .transform(annotations) .collect { case CircuitSerializationAnnotation(_, filename, format) => (filename, format) } - .toSeq should be (Seq(("Bar.pb", FirrtlFileFormat))) + .toSeq should be(Seq(("Bar.pb", FirrtlFileFormat))) } } diff --git a/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala b/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala index ba9e9254..3d42efdd 100644 --- a/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/ChecksSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3.stage.{ChiselOutputFileAnnotation, NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation} import chisel3.stage.phases.Checks @@ -15,15 +14,15 @@ import org.scalatest.matchers.should.Matchers class ChecksSpec extends AnyFlatSpec with Matchers { def checkExceptionMessage(phase: Phase, annotations: AnnotationSeq, messageStart: String): Unit = - intercept[OptionsException]{ phase.transform(annotations) }.getMessage should startWith(messageStart) + intercept[OptionsException] { phase.transform(annotations) }.getMessage should startWith(messageStart) class Fixture { val phase: Phase = new Checks } - behavior of classOf[Checks].toString + behavior.of(classOf[Checks].toString) it should "do nothing on sane annotation sequences" in new Fixture { val a = Seq(NoRunFirrtlCompilerAnnotation, PrintFullStackTraceAnnotation) - phase.transform(a).toSeq should be (a) + phase.transform(a).toSeq should be(a) } it should "throw an OptionsException if more than one NoRunFirrtlCompilerAnnotation is specified" in new Fixture { diff --git a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala index 8718f64b..46a2994b 100644 --- a/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/ConvertSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3._ import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform} import chisel3.stage.ChiselGeneratorAnnotation @@ -20,13 +19,13 @@ class ConvertSpecFirrtlTransform extends Transform with DependencyAPIMigration { override def optionalPrerequisites = Seq.empty override def optionalPrerequisiteOf = Seq.empty override def invalidates(a: Transform) = false - def execute(state: CircuitState): CircuitState = state + def execute(state: CircuitState): CircuitState = state } case class ConvertSpecFirrtlAnnotation(name: String) extends NoTargetAnnotation case class ConvertSpecChiselAnnotation(name: String) extends ChiselAnnotation with RunFirrtlTransform { - def toFirrtl: Annotation = ConvertSpecFirrtlAnnotation(name) + def toFirrtl: Annotation = ConvertSpecFirrtlAnnotation(name) def transformClass: Class[_ <: Transform] = classOf[ConvertSpecFirrtlTransform] } @@ -43,23 +42,24 @@ class ConvertSpec extends AnyFlatSpec with Matchers { class Fixture { val phase: Phase = new Convert } - behavior of classOf[Convert].toString + behavior.of(classOf[Convert].toString) it should "convert a Chisel Circuit to a FIRRTL Circuit" in new Fixture { val annos: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new ConvertSpecFoo)) val annosx = Seq(new Elaborate, phase) - .foldLeft(annos)( (a, p) => p.transform(a) ) + .foldLeft(annos)((a, p) => p.transform(a)) info("FIRRTL circuit generated") - annosx.collect{ case a: FirrtlCircuitAnnotation => a.circuit.main }.toSeq should be (Seq("foo")) + annosx.collect { case a: FirrtlCircuitAnnotation => a.circuit.main }.toSeq should be(Seq("foo")) info("FIRRTL annotations generated") - annosx.collect{ case a: ConvertSpecFirrtlAnnotation => a.name }.toSeq should be (Seq("bar")) + annosx.collect { case a: ConvertSpecFirrtlAnnotation => a.name }.toSeq should be(Seq("bar")) info("FIRRTL transform annotations generated") - annosx.collect{ case a: RunFirrtlTransformAnnotation => a.transform.getClass} - .toSeq should be (Seq(classOf[ConvertSpecFirrtlTransform])) + annosx.collect { case a: RunFirrtlTransformAnnotation => a.transform.getClass }.toSeq should be( + Seq(classOf[ConvertSpecFirrtlTransform]) + ) } } diff --git a/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala b/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala index fce040d4..90bb229b 100644 --- a/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3._ import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation} import chisel3.stage.phases.Elaborate @@ -15,11 +14,10 @@ class ElaborateSpec extends AnyFlatSpec with Matchers { class Foo extends Module { override def desiredName: String = "Foo" - val io = IO( - new Bundle { - val in = Input(Bool()) - val out = Output(Bool()) - }) + val io = IO(new Bundle { + val in = Input(Bool()) + val out = Output(Bool()) + }) io.out := ~io.in } @@ -30,18 +28,17 @@ class ElaborateSpec extends AnyFlatSpec with Matchers { class Fixture { val phase: Phase = new Elaborate } - behavior of classOf[Elaborate].toString + behavior.of(classOf[Elaborate].toString) it should "expand ChiselGeneratorAnnotations into ChiselCircuitAnnotations and delete originals" in new Fixture { - val annotations = Seq( ChiselGeneratorAnnotation(() => new Foo), - ChiselGeneratorAnnotation(() => new Bar) ) + val annotations = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselGeneratorAnnotation(() => new Bar)) val out = phase.transform(annotations) info("original annotations removed") - out.collect{ case a: ChiselGeneratorAnnotation => a } should be (empty) + out.collect { case a: ChiselGeneratorAnnotation => a } should be(empty) info("circuits created with the expected names") - out.collect{ case a: ChiselCircuitAnnotation => a.circuit.name } should be (Seq("Foo", "Bar")) + out.collect { case a: ChiselCircuitAnnotation => a.circuit.name } should be(Seq("Foo", "Bar")) } } diff --git a/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala b/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala index 201f8eaf..9b7d4f42 100644 --- a/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala +++ b/src/test/scala/chiselTests/stage/phases/EmitterSpec.scala @@ -2,7 +2,6 @@ package chiselTests.stage.phases - import chisel3.RawModule import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation, ChiselOutputFileAnnotation} import chisel3.stage.phases.{Convert, Elaborate, Emitter} @@ -22,32 +21,31 @@ class EmitterSpec extends AnyFlatSpec with Matchers { class Fixture { val phase: Phase = new Emitter } - behavior of classOf[Emitter].toString + behavior.of(classOf[Emitter].toString) it should "do nothing if no ChiselOutputFileAnnotations are present" in new Fixture { val dir = new File("test_run_dir/EmitterSpec") - val annotations = (new Elaborate).transform(Seq( TargetDirAnnotation(dir.toString), - ChiselGeneratorAnnotation(() => new FooModule) )) + val annotations = + (new Elaborate).transform(Seq(TargetDirAnnotation(dir.toString), ChiselGeneratorAnnotation(() => new FooModule))) val annotationsx = phase.transform(annotations) val Seq(fooFile, barFile) = Seq("Foo.fir", "Bar.fir").map(f => new File(dir + "/" + f)) info(s"$fooFile does not exist") - fooFile should not (exist) + fooFile should not(exist) info("annotations are unmodified") - annotationsx.toSeq should be (annotations.toSeq) + annotationsx.toSeq should be(annotations.toSeq) } it should "emit a ChiselCircuitAnnotation to a specific file" in new Fixture { val dir = new File("test_run_dir/EmitterSpec") val circuit = (new Elaborate) .transform(Seq(ChiselGeneratorAnnotation(() => new BarModule))) - .collectFirst{ case a: ChiselCircuitAnnotation => a} + .collectFirst { case a: ChiselCircuitAnnotation => a } .get - val annotations = phase.transform(Seq( TargetDirAnnotation(dir.toString), - circuit, - ChiselOutputFileAnnotation("Baz") )) + val annotations = + phase.transform(Seq(TargetDirAnnotation(dir.toString), circuit, ChiselOutputFileAnnotation("Baz"))) val bazFile = new File(dir + "/Baz.fir") @@ -55,7 +53,7 @@ class EmitterSpec extends AnyFlatSpec with Matchers { bazFile should (exist) info("a deleted EmittedFirrtlCircuitAnnotation should be generated") - annotations.collect{ case a @ DeletedAnnotation(_, _: EmittedFirrtlCircuitAnnotation) => a }.size should be (1) + annotations.collect { case a @ DeletedAnnotation(_, _: EmittedFirrtlCircuitAnnotation) => a }.size should be(1) } } diff --git a/src/test/scala/chiselTests/util/BitPatSpec.scala b/src/test/scala/chiselTests/util/BitPatSpec.scala index 549e8bca..38ffc3ba 100644 --- a/src/test/scala/chiselTests/util/BitPatSpec.scala +++ b/src/test/scala/chiselTests/util/BitPatSpec.scala @@ -6,13 +6,12 @@ import chisel3.util.BitPat import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers - class BitPatSpec extends AnyFlatSpec with Matchers { - behavior of classOf[BitPat].toString + behavior.of(classOf[BitPat].toString) it should "convert a BitPat to readable form" in { val testPattern = "0" * 32 + "1" * 32 + "?" * 32 + "?01" * 32 - BitPat("b" + testPattern).toString should be (s"BitPat($testPattern)") + BitPat("b" + testPattern).toString should be(s"BitPat($testPattern)") } it should "convert a BitPat to raw form" in { @@ -21,15 +20,15 @@ class BitPatSpec extends AnyFlatSpec with Matchers { } it should "not fail if BitPat width is 0" in { - intercept[IllegalArgumentException]{BitPat("b")} + intercept[IllegalArgumentException] { BitPat("b") } } it should "concat BitPat via ##" in { - (BitPat.Y(4) ## BitPat.dontCare(3) ## BitPat.N(2)).toString should be (s"BitPat(1111???00)") + (BitPat.Y(4) ## BitPat.dontCare(3) ## BitPat.N(2)).toString should be(s"BitPat(1111???00)") } it should "throw when BitPat apply to a Hardware" in { - intercept[java.lang.IllegalArgumentException]{ + intercept[java.lang.IllegalArgumentException] { chisel3.stage.ChiselStage.emitChirrtl(new chisel3.Module { BitPat(chisel3.Reg(chisel3.Bool())) }) diff --git a/src/test/scala/chiselTests/util/BitSetSpec.scala b/src/test/scala/chiselTests/util/BitSetSpec.scala index 8120cc97..dd66ba40 100644 --- a/src/test/scala/chiselTests/util/BitSetSpec.scala +++ b/src/test/scala/chiselTests/util/BitSetSpec.scala @@ -6,14 +6,13 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class BitSetSpec extends AnyFlatSpec with Matchers { - behavior of classOf[BitSet].toString + behavior.of(classOf[BitSet].toString) it should "reject unequal width when constructing a BitSet" in { intercept[IllegalArgumentException] { - BitSet.fromString( - """b0010 - |b00010 - |""".stripMargin) + BitSet.fromString("""b0010 + |b00010 + |""".stripMargin) } } @@ -21,7 +20,7 @@ class BitSetSpec extends AnyFlatSpec with Matchers { val aBitPat = BitPat("b10?") val bBitPat = BitPat("b1??") - aBitPat.subtract(bBitPat).isEmpty should be (true) + aBitPat.subtract(bBitPat).isEmpty should be(true) } it should "return nonempty subtraction result correctly" in { @@ -31,20 +30,19 @@ class BitSetSpec extends AnyFlatSpec with Matchers { val dBitPat = BitPat("b100") val diffBitPat = bBitPat.subtract(aBitPat) - bBitPat.cover(diffBitPat) should be (true) - diffBitPat.equals(cBitPat) should be (true) + bBitPat.cover(diffBitPat) should be(true) + diffBitPat.equals(cBitPat) should be(true) val largerdiffBitPat = bBitPat.subtract(dBitPat) - aBitPat.cover(dBitPat) should be (true) - largerdiffBitPat.cover(diffBitPat) should be (true) + aBitPat.cover(dBitPat) should be(true) + largerdiffBitPat.cover(diffBitPat) should be(true) } it should "be able to handle complex subtract between BitSet" in { - val aBitSet = BitSet.fromString( - """b?01?0 - |b11111 - |b00000 - |""".stripMargin) + val aBitSet = BitSet.fromString("""b?01?0 + |b11111 + |b00000 + |""".stripMargin) val bBitSet = BitSet.fromString( """b?1111 |b?0000 @@ -52,44 +50,41 @@ class BitSetSpec extends AnyFlatSpec with Matchers { ) val expected = BitPat("b?01?0") - expected.equals(aBitSet.subtract(bBitSet)) should be (true) + expected.equals(aBitSet.subtract(bBitSet)) should be(true) } it should "be generated from BitPat union" in { - val aBitSet = BitSet.fromString( - """b001?0 - |b000??""".stripMargin) + val aBitSet = BitSet.fromString("""b001?0 + |b000??""".stripMargin) val aBitPat = BitPat("b000??") val bBitPat = BitPat("b001?0") val cBitPat = BitPat("b00000") - aBitPat.cover(cBitPat) should be (true) - aBitSet.cover(bBitPat) should be (true) + aBitPat.cover(cBitPat) should be(true) + aBitSet.cover(bBitPat) should be(true) - aBitSet.equals(aBitPat.union(bBitPat)) should be (true) + aBitSet.equals(aBitPat.union(bBitPat)) should be(true) } it should "be generated from BitPat subtraction" in { - val aBitSet = BitSet.fromString( - """b001?0 - |b000??""".stripMargin) + val aBitSet = BitSet.fromString("""b001?0 + |b000??""".stripMargin) val aBitPat = BitPat("b00???") val bBitPat = BitPat("b001?1") - aBitSet.equals(aBitPat.subtract(bBitPat)) should be (true) + aBitSet.equals(aBitPat.subtract(bBitPat)) should be(true) } it should "union two BitSet together" in { - val aBitSet = BitSet.fromString( - """b001?0 - |b001?1 - |""".stripMargin) + val aBitSet = BitSet.fromString("""b001?0 + |b001?1 + |""".stripMargin) val bBitSet = BitSet.fromString( """b000?? |b01??? |""".stripMargin ) val cBitPat = BitPat("b0????") - cBitPat.equals(aBitSet.union(bBitSet)) should be (true) + cBitPat.equals(aBitSet.union(bBitSet)) should be(true) } it should "be decoded" in { @@ -100,19 +95,23 @@ class BitSetSpec extends AnyFlatSpec with Matchers { chisel3.stage.ChiselStage.emitSystemVerilog(new Module { val in = IO(Input(UInt(8.W))) val out = IO(Output(UInt(4.W))) - out := decoder.bitset(in, Seq( - BitSet.fromString( - "b000?????" + out := decoder.bitset( + in, + Seq( + BitSet.fromString( + "b000?????" + ), + BitSet.fromString( + """b0010???? + |b01?????? + |""".stripMargin + ), + BitSet.fromString( + "b11??????" + ) ), - BitSet.fromString( - """b0010???? - |b01?????? - |""".stripMargin - ), - BitSet.fromString( - "b11??????" - ) - ), true) + true + ) }) } diff --git a/src/test/scala/chiselTests/util/CatSpec.scala b/src/test/scala/chiselTests/util/CatSpec.scala index 79d2c027..a75c4ec0 100644 --- a/src/test/scala/chiselTests/util/CatSpec.scala +++ b/src/test/scala/chiselTests/util/CatSpec.scala @@ -12,7 +12,7 @@ import chiselTests.ChiselFlatSpec object CatSpec { class JackIsATypeSystemGod extends Module { - val in = IO(Input (Vec(0, UInt(8.W)))) + val in = IO(Input(Vec(0, UInt(8.W)))) val out = IO(Output(UInt(8.W))) out := Cat(in) @@ -24,7 +24,7 @@ class CatSpec extends ChiselFlatSpec { import CatSpec._ - behavior of "util.Cat" + behavior.of("util.Cat") it should "not fail to elaborate a zero-element Vec" in { @@ -41,7 +41,7 @@ class CatSpec extends ChiselFlatSpec { } val chirrtl = ChiselStage.emitChirrtl(new MyModule) for (name <- Seq("a", "b", "c", "d")) { - chirrtl should include (s"input $name : UInt<8>") + chirrtl should include(s"input $name : UInt<8>") } } @@ -54,11 +54,10 @@ class CatSpec extends ChiselFlatSpec { out := noPrefix(Cat(in)) } val chirrtl = ChiselStage.emitChirrtl(new MyModule) - chirrtl should include ("node lo_lo = cat(in[6], in[7])") - chirrtl should include ("node lo_hi = cat(in[4], in[5])") - chirrtl should include ("node hi_lo = cat(in[2], in[3])") - chirrtl should include ("node hi_hi = cat(in[0], in[1])") + chirrtl should include("node lo_lo = cat(in[6], in[7])") + chirrtl should include("node lo_hi = cat(in[4], in[5])") + chirrtl should include("node hi_lo = cat(in[2], in[3])") + chirrtl should include("node hi_hi = cat(in[0], in[1])") } - } diff --git a/src/test/scala/chiselTests/util/experimental/PlaSpec.scala b/src/test/scala/chiselTests/util/experimental/PlaSpec.scala index 8af5c936..156249a2 100644 --- a/src/test/scala/chiselTests/util/experimental/PlaSpec.scala +++ b/src/test/scala/chiselTests/util/experimental/PlaSpec.scala @@ -3,7 +3,7 @@ package chiselTests.util.experimental import chisel3._ import chisel3.stage.PrintFullStackTraceAnnotation import chisel3.testers.BasicTester -import chisel3.util.{BitPat, pla} +import chisel3.util.{pla, BitPat} import chiselTests.ChiselFlatSpec class PlaSpec extends ChiselFlatSpec { @@ -17,12 +17,17 @@ class PlaSpec extends ChiselFlatSpec { (BitPat("b100"), BitPat("b00010000")), (BitPat("b101"), BitPat("b00100000")), (BitPat("b110"), BitPat("b01000000")), - (BitPat("b111"), BitPat("b10000000")), + (BitPat("b111"), BitPat("b10000000")) ) - table.foreach { case (i, o) => - val (plaIn, plaOut) = pla(table) - plaIn := WireDefault(i.value.U(3.W)) - chisel3.assert(plaOut === o.value.U(8.W), "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut) + table.foreach { + case (i, o) => + val (plaIn, plaOut) = pla(table) + plaIn := WireDefault(i.value.U(3.W)) + chisel3.assert( + plaOut === o.value.U(8.W), + "Input " + i.toString + " produced incorrect output BitPat(%b)", + plaOut + ) } stop() }) @@ -38,12 +43,17 @@ class PlaSpec extends ChiselFlatSpec { (BitPat("b100"), BitPat("b00010000")), (BitPat("b101"), BitPat("b00100000")), (BitPat("b110"), BitPat("b01000000")), - (BitPat("b111"), BitPat("b10000000")), + (BitPat("b111"), BitPat("b10000000")) ) - table.foreach { case (i, o) => - val (plaIn, plaOut) = pla(table, BitPat("b11111111")) - plaIn := WireDefault(i.value.U(3.W)) - chisel3.assert(plaOut === ~o.value.U(8.W), "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut) + table.foreach { + case (i, o) => + val (plaIn, plaOut) = pla(table, BitPat("b11111111")) + plaIn := WireDefault(i.value.U(3.W)) + chisel3.assert( + plaOut === ~o.value.U(8.W), + "Input " + i.toString + " produced incorrect output BitPat(%b)", + plaOut + ) } stop() }) @@ -53,12 +63,13 @@ class PlaSpec extends ChiselFlatSpec { assertTesterPasses(new BasicTester { val table = Seq( (BitPat("b000"), BitPat("b?01")), - (BitPat("b111"), BitPat("b?01")), + (BitPat("b111"), BitPat("b?01")) ) - table.foreach { case (i, o) => - val (plaIn, plaOut) = pla(table) - plaIn := WireDefault(i.value.U(3.W)) - chisel3.assert(o === plaOut, "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut) + table.foreach { + case (i, o) => + val (plaIn, plaOut) = pla(table) + plaIn := WireDefault(i.value.U(3.W)) + chisel3.assert(o === plaOut, "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut) } stop() }) @@ -82,12 +93,17 @@ class PlaSpec extends ChiselFlatSpec { (BitPat("b1100"), BitPat("b0")), (BitPat("b1101"), BitPat("b1")), (BitPat("b1110"), BitPat("b1")), - (BitPat("b1111"), BitPat("b1")), + (BitPat("b1111"), BitPat("b1")) ) - table.foreach { case (i, o) => - val (plaIn, plaOut) = pla(table) - plaIn := WireDefault(i.value.U(4.W)) - chisel3.assert(plaOut === o.value.U(1.W), "Input " + i.toString + " produced incorrect output BitPat(%b)", plaOut) + table.foreach { + case (i, o) => + val (plaIn, plaOut) = pla(table) + plaIn := WireDefault(i.value.U(4.W)) + chisel3.assert( + plaOut === o.value.U(1.W), + "Input " + i.toString + " produced incorrect output BitPat(%b)", + plaOut + ) } stop() }) diff --git a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala b/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala index 255effaf..2ef316bb 100644 --- a/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala +++ b/src/test/scala/chiselTests/util/experimental/TruthTableSpec.scala @@ -4,7 +4,7 @@ package chiselTests.util.experimental import chisel3._ import chisel3.util.BitPat -import chisel3.util.experimental.decode.{TruthTable, decoder} +import chisel3.util.experimental.decode.{decoder, TruthTable} import org.scalatest.flatspec.AnyFlatSpec class TruthTableSpec extends AnyFlatSpec { @@ -64,15 +64,14 @@ class TruthTableSpec extends AnyFlatSpec { "TruthTable" should "be reproducible" in { class Foo extends Module { - val io = IO(new Bundle{ + val io = IO(new Bundle { val in = Input(UInt(4.W)) val out = Output(UInt(16.W)) }) - val table = TruthTable( - (0 until 16).map{ - i => BitPat(i.U(4.W)) -> BitPat((1<<i).U(16.W)) + (0 until 16).map { i => + BitPat(i.U(4.W)) -> BitPat((1 << i).U(16.W)) }, BitPat.dontCare(16) ) diff --git a/src/test/scala/chiselTests/util/random/LFSRSpec.scala b/src/test/scala/chiselTests/util/random/LFSRSpec.scala index 975a3c93..d47c2d7d 100644 --- a/src/test/scala/chiselTests/util/random/LFSRSpec.scala +++ b/src/test/scala/chiselTests/util/random/LFSRSpec.scala @@ -23,7 +23,7 @@ class LFSRMaxPeriod(gen: => UInt) extends BasicTester { val (_, wrap) = Counter(started, math.pow(2.0, rv.getWidth).toInt - 1) - when (rv === seed && started) { + when(rv === seed && started) { chisel3.assert(wrap) stop() } @@ -49,7 +49,7 @@ class LFSRDistribution(gen: => UInt, cycles: Int = 10000) extends BasicTester { val (trial, done) = Counter(true.B, cycles) - val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit. + val rollValue = die0 +& die1 // Note +& is critical because sum will need an extra bit. bins(rollValue) := bins(rollValue) + 1.U @@ -88,17 +88,17 @@ class LFSRResetTester(gen: => LFSR, lockUpValue: BigInt) extends BasicTester { lfsr.io.seed.bits := lockUpValue.U(lfsr.width.W).asBools lfsr.io.increment := true.B - when (count === 2.U) { + when(count === 2.U) { assert(lfsr.io.out.asUInt === lockUpValue.U, "LFSR is NOT locked up, but should be!") } lfsr.reset := count === 3.U - when (count === 4.U) { + when(count === 4.U) { assert(lfsr.io.out.asUInt =/= lockUpValue.U, "LFSR is locked up, but should not be after reset!") } - when (done) { + when(done) { stop() } @@ -110,29 +110,34 @@ class LFSRSpec extends ChiselFlatSpec with Utils { val testName = s"have a maximal period over a range of widths (${range.head} to ${range.last})" + s" using ${reduction.getClass}" it should testName in { - range - .foreach{ width => - LFSR.tapsMaxPeriod(width).foreach{ taps => - info(s"""width $width okay using taps: ${taps.mkString(", ")}""") - assertTesterPasses(new LFSRMaxPeriod(PRNG(gen(width, taps, reduction))), - annotations = TesterDriver.verilatorOnly) - } + range.foreach { width => + LFSR.tapsMaxPeriod(width).foreach { taps => + info(s"""width $width okay using taps: ${taps.mkString(", ")}""") + assertTesterPasses( + new LFSRMaxPeriod(PRNG(gen(width, taps, reduction))), + annotations = TesterDriver.verilatorOnly + ) } + } } } - behavior of "LFSR" + behavior.of("LFSR") it should "throw an exception if initialized to a seed of zero for XOR configuration" in { - { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new FooLFSR(XOR, Some(0))) } - }.getMessage should include ("Seed cannot be zero") + { + the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new FooLFSR(XOR, Some(0))) + } + }.getMessage should include("Seed cannot be zero") } it should "throw an exception if initialized to a seed of all ones for XNOR configuration" in { - { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new FooLFSR(XNOR, Some(15))) } - }.getMessage should include ("Seed cannot be all ones") + { + the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new FooLFSR(XNOR, Some(15))) + } + }.getMessage should include("Seed cannot be all ones") } it should "reset correctly without a seed for XOR configuration" in { @@ -143,34 +148,35 @@ class LFSRSpec extends ChiselFlatSpec with Utils { assertTesterPasses(new LFSRResetTester(new FooLFSR(XNOR, None), 15)) } - behavior of "MaximalPeriodGaloisLFSR" + behavior.of("MaximalPeriodGaloisLFSR") it should "throw an exception if no LFSR taps are known" in { - { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new MaxPeriodGaloisLFSR(787)) } - }.getMessage should include ("No max period LFSR taps stored for requested width") + { + the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new MaxPeriodGaloisLFSR(787)) + } + }.getMessage should include("No max period LFSR taps stored for requested width") } - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction=r), XOR, 2 to 16) - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction=r), XNOR, 2 to 16) + periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction = r), XOR, 2 to 16) + periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new GaloisLFSR(w, t, reduction = r), XNOR, 2 to 16) ignore should "have a sane distribution for larger widths" in { - ((17 to 32) ++ Seq(64, 128, 256, 512, 1024, 2048, 4096)) - .foreach{ width => - info(s"width $width okay!") - assertTesterPasses(new LFSRDistribution(LFSR(width), math.pow(2, 22).toInt)) - } + ((17 to 32) ++ Seq(64, 128, 256, 512, 1024, 2048, 4096)).foreach { width => + info(s"width $width okay!") + assertTesterPasses(new LFSRDistribution(LFSR(width), math.pow(2, 22).toInt)) + } } - behavior of "MaximalPeriodFibonacciLFSR" + behavior.of("MaximalPeriodFibonacciLFSR") - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction=r), XOR, 2 to 16) - periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction=r), XNOR, 2 to 16) + periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XOR, 2 to 16) + periodCheck((w: Int, t: Set[Int], r: LFSRReduce) => new FibonacciLFSR(w, t, reduction = r), XNOR, 2 to 16) - behavior of "LFSR maximal period taps" + behavior.of("LFSR maximal period taps") it should "contain all the expected widths" in { - ((2 to 786) ++ Seq(1024, 2048, 4096)).foreach(LFSR.tapsMaxPeriod.keys should contain (_)) + ((2 to 786) ++ Seq(1024, 2048, 4096)).foreach(LFSR.tapsMaxPeriod.keys should contain(_)) } } diff --git a/src/test/scala/chiselTests/util/random/PRNGSpec.scala b/src/test/scala/chiselTests/util/random/PRNGSpec.scala index 71a8635c..36fdf9cb 100644 --- a/src/test/scala/chiselTests/util/random/PRNGSpec.scala +++ b/src/test/scala/chiselTests/util/random/PRNGSpec.scala @@ -28,15 +28,15 @@ class PRNGStepTest extends BasicTester { val (_, done) = Counter(true.B, 16) - when (count2 === 0.U) { + when(count2 === 0.U) { assert(a === b, "1-step and 2-step PRNGs did not agree! (0b%b != 0b%b)", a, b) } - when (count4 === 0.U) { + when(count4 === 0.U) { assert(a === c, "1-step and 4-step PRNGs did not agree!") } - when (done) { + when(done) { stop() } @@ -52,11 +52,11 @@ class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) ex a.io.seed.valid := count === 2.U a.io.seed.bits := seed.U(a.width.W).asBools - when (count === 3.U) { + when(count === 3.U) { assert(a.io.out.asUInt === expected.U, "Output didn't match!") } - when (done) { + when(done) { stop() } @@ -64,18 +64,22 @@ class PRNGUpdateSeedTest(updateSeed: Boolean, seed: BigInt, expected: BigInt) ex class PRNGSpec extends ChiselFlatSpec with Utils { - behavior of "PRNG" + behavior.of("PRNG") it should "throw an exception if the step size is < 1" in { - { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new CyclePRNG(0, Some(1), 1, true)) } - }.getMessage should include ("Width must be greater than zero!") + { + the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new CyclePRNG(0, Some(1), 1, true)) + } + }.getMessage should include("Width must be greater than zero!") } it should "throw an exception if the step size is <= 0" in { - { the [IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { - ChiselStage.elaborate(new CyclePRNG(1, Some(1), 0, true)) } - }.getMessage should include ("Step size must be greater than one!") + { + the[IllegalArgumentException] thrownBy extractCause[IllegalArgumentException] { + ChiselStage.elaborate(new CyclePRNG(1, Some(1), 0, true)) + } + }.getMessage should include("Step size must be greater than one!") } it should "handle non-unary steps" in { diff --git a/src/test/scala/cookbook/Bundle2UInt.scala b/src/test/scala/cookbook/Bundle2UInt.scala index 5bc1063a..21d06df7 100644 --- a/src/test/scala/cookbook/Bundle2UInt.scala +++ b/src/test/scala/cookbook/Bundle2UInt.scala @@ -24,7 +24,7 @@ class Bundle2UInt extends CookbookTester(1) { assert(uint === 0xc3.U) } -class Bundle2UIntSpec extends CookbookSpec { +class Bundle2UIntSpec extends CookbookSpec { "Bundle2UInt" should "work" in { assertTesterPasses { new Bundle2UInt } } diff --git a/src/test/scala/cookbook/CookbookSpec.scala b/src/test/scala/cookbook/CookbookSpec.scala index c1acc0de..7d6c9726 100644 --- a/src/test/scala/cookbook/CookbookSpec.scala +++ b/src/test/scala/cookbook/CookbookSpec.scala @@ -16,7 +16,7 @@ abstract class CookbookTester(length: Int) extends BasicTester { require(length >= 0, "Simulation length must be non-negative!") val (cycle, done) = Counter(true.B, length + 1) // + 1 cycle because done is actually wrap - when (done) { stop() } + when(done) { stop() } } abstract class CookbookSpec extends ChiselFlatSpec diff --git a/src/test/scala/cookbook/FSM.scala b/src/test/scala/cookbook/FSM.scala index 0c1173ec..66f3063f 100644 --- a/src/test/scala/cookbook/FSM.scala +++ b/src/test/scala/cookbook/FSM.scala @@ -26,21 +26,21 @@ class DetectTwoOnes extends Module { io.out := (state === State.sTwo1s) - switch (state) { - is (State.sNone) { - when (io.in) { + switch(state) { + is(State.sNone) { + when(io.in) { state := State.sOne1 } } - is (State.sOne1) { - when (io.in) { + is(State.sOne1) { + when(io.in) { state := State.sTwo1s - } .otherwise { + }.otherwise { state := State.sNone } } - is (State.sTwo1s) { - when (!io.in) { + is(State.sTwo1s) { + when(!io.in) { state := State.sNone } } @@ -53,7 +53,8 @@ class DetectTwoOnesTester extends CookbookTester(10) { // Inputs and expected results val inputs: Vec[Bool] = VecInit(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B) - val expected: Vec[Bool] = VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) + val expected: Vec[Bool] = + VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) dut.io.in := inputs(cycle) assert(dut.io.out === expected(cycle)) diff --git a/src/test/scala/cookbook/RegOfVec.scala b/src/test/scala/cookbook/RegOfVec.scala index ba1ab359..ddb615c7 100644 --- a/src/test/scala/cookbook/RegOfVec.scala +++ b/src/test/scala/cookbook/RegOfVec.scala @@ -22,11 +22,11 @@ class RegOfVec extends CookbookTester(2) { val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W)))) // Simple test (cycle comes from superclass) - when (cycle === 2.U) { assert(regOfVec(2) === 123.U) } + when(cycle === 2.U) { assert(regOfVec(2) === 123.U) } for (elt <- initRegOfVec) { assert(elt === 0.U) } } -class RegOfVecSpec extends CookbookSpec { +class RegOfVecSpec extends CookbookSpec { "RegOfVec" should "work" in { assertTesterPasses { new RegOfVec } } diff --git a/src/test/scala/cookbook/VecOfBool2UInt.scala b/src/test/scala/cookbook/VecOfBool2UInt.scala index 024eca89..ca1413dc 100644 --- a/src/test/scala/cookbook/VecOfBool2UInt.scala +++ b/src/test/scala/cookbook/VecOfBool2UInt.scala @@ -21,7 +21,7 @@ class VecOfBool2UInt extends CookbookTester(1) { assert(0xd.U === uint) } -class VecOfBool2UIntSpec extends CookbookSpec { +class VecOfBool2UIntSpec extends CookbookSpec { "VecOfBool2UInt" should "work" in { assertTesterPasses { new VecOfBool2UInt } } diff --git a/src/test/scala/examples/ImplicitStateVendingMachine.scala b/src/test/scala/examples/ImplicitStateVendingMachine.scala index 817240d5..36ac82ab 100644 --- a/src/test/scala/examples/ImplicitStateVendingMachine.scala +++ b/src/test/scala/examples/ImplicitStateVendingMachine.scala @@ -12,14 +12,14 @@ class ImplicitStateVendingMachine extends SimpleVendingMachine { val incValue = WireDefault(0.asUInt(3.W)) val doDispense = value >= 4.U // 4 * nickel as 1 == $0.20 - when (doDispense) { + when(doDispense) { value := 0.U // No change given - } .otherwise { + }.otherwise { value := value + incValue } - when (io.nickel) { incValue := 1.U } - when (io.dime) { incValue := 2.U } + when(io.nickel) { incValue := 1.U } + when(io.dime) { incValue := 2.U } io.dispense := doDispense } diff --git a/src/test/scala/examples/SimpleVendingMachine.scala b/src/test/scala/examples/SimpleVendingMachine.scala index dff60a4d..819669a3 100644 --- a/src/test/scala/examples/SimpleVendingMachine.scala +++ b/src/test/scala/examples/SimpleVendingMachine.scala @@ -9,8 +9,8 @@ import chisel3.util._ class SimpleVendingMachineIO extends Bundle { val nickel = Input(Bool()) - val dime = Input(Bool()) - val dispense = Output(Bool()) + val dime = Input(Bool()) + val dispense = Output(Bool()) } // Superclass for vending machines with very simple IO @@ -24,24 +24,24 @@ class FSMVendingMachine extends SimpleVendingMachine { val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5) val state = RegInit(sIdle) - switch (state) { - is (sIdle) { - when (io.nickel) { state := s5 } - when (io.dime) { state := s10 } + switch(state) { + is(sIdle) { + when(io.nickel) { state := s5 } + when(io.dime) { state := s10 } } - is (s5) { - when (io.nickel) { state := s10 } - when (io.dime) { state := s15 } + is(s5) { + when(io.nickel) { state := s10 } + when(io.dime) { state := s15 } } - is (s10) { - when (io.nickel) { state := s15 } - when (io.dime) { state := sOk } + is(s10) { + when(io.nickel) { state := s15 } + when(io.dime) { state := sOk } } - is (s15) { - when (io.nickel) { state := sOk } - when (io.dime) { state := sOk } + is(s15) { + when(io.nickel) { state := sOk } + when(io.dime) { state := sOk } } - is (sOk) { + is(sOk) { state := sIdle } } @@ -73,11 +73,11 @@ class SimpleVendingMachineTester(mod: => SimpleVendingMachine) extends BasicTest val dut = Module(mod) val (cycle, done) = Counter(true.B, 10) - when (done) { stop(); stop() } // Stop twice because of Verilator + when(done) { stop(); stop() } // Stop twice because of Verilator val nickelInputs = VecInit(true.B, true.B, true.B, true.B, true.B, false.B, false.B, false.B, true.B, false.B) - val dimeInputs = VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) - val expected = VecInit(false.B, false.B, false.B, false.B, true.B , false.B, false.B, true.B, false.B, false.B) + val dimeInputs = VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B) + val expected = VecInit(false.B, false.B, false.B, false.B, true.B, false.B, false.B, true.B, false.B, false.B) dut.io.nickel := nickelInputs(cycle) dut.io.dime := dimeInputs(cycle) @@ -89,7 +89,10 @@ class SimpleVendingMachineSpec extends ChiselFlatSpec { assertTesterPasses { new SimpleVendingMachineTester(new FSMVendingMachine) } } "An Verilog implementation of a vending machine" should "work" in { - assertTesterPasses(new SimpleVendingMachineTester(new VerilogVendingMachineWrapper), - List("/chisel3/VerilogVendingMachine.v"), annotations = TesterDriver.verilatorOnly) + assertTesterPasses( + new SimpleVendingMachineTester(new VerilogVendingMachineWrapper), + List("/chisel3/VerilogVendingMachine.v"), + annotations = TesterDriver.verilatorOnly + ) } } diff --git a/src/test/scala/examples/VendingMachineGenerator.scala b/src/test/scala/examples/VendingMachineGenerator.scala index 72bfdf53..4adae987 100644 --- a/src/test/scala/examples/VendingMachineGenerator.scala +++ b/src/test/scala/examples/VendingMachineGenerator.scala @@ -12,12 +12,14 @@ import VendingMachineUtils._ class VendingMachineIO(val legalCoins: Seq[Coin]) extends Bundle { require(legalCoins.size >= 1, "The vending machine must accept at least 1 coin!") // Order of coins by value - val coins: Seq[Coin] = legalCoins sortBy (_.value) + val coins: Seq[Coin] = legalCoins.sortBy(_.value) // Map of coin names to their relative position in value (ie. index in inputs) val indexMap: Map[String, Int] = coins.map(_.name).zipWithIndex.toMap - require(coins map (_.value % coins.head.value == 0) reduce (_ && _), - "All coins must be a multiple of the lowest value coin!") + require( + coins.map(_.value % coins.head.value == 0).reduce(_ && _), + "All coins must be a multiple of the lowest value coin!" + ) val inputs = Input(Vec(legalCoins.size, Bool())) val dispense = Output(Bool()) @@ -34,17 +36,17 @@ abstract class ParameterizedVendingMachine(legalCoins: Seq[Coin], val sodaCost: // Enforce one hot if (io.inputs.size > 1) { for (input <- io.inputs) { - when (input) { - assert(io.inputs.filterNot(_ == input).map(!_).reduce(_ && _), - "Only 1 coin can be input in a given cycle!") + when(input) { + assert(io.inputs.filterNot(_ == input).map(!_).reduce(_ && _), "Only 1 coin can be input in a given cycle!") } } } } class VendingMachineGenerator( - legalCoins: Seq[Coin], - sodaCost: Int) extends ParameterizedVendingMachine(legalCoins, sodaCost) { + legalCoins: Seq[Coin], + sodaCost: Int) + extends ParameterizedVendingMachine(legalCoins, sodaCost) { require(sodaCost > 0, "Sodas must actually cost something!") // All coin values are normalized to a multiple of the minimum coin value @@ -57,21 +59,22 @@ class VendingMachineGenerator( val incValue = WireDefault(0.asUInt(width)) val doDispense = value >= (sodaCost / minCoin).U - when (doDispense) { + when(doDispense) { value := 0.U // No change given - } .otherwise { + }.otherwise { value := value + incValue } for ((coin, index) <- io.coins.zipWithIndex) { - when (io.inputs(index)) { incValue := (coin.value / minCoin).U } + when(io.inputs(index)) { incValue := (coin.value / minCoin).U } } io.dispense := doDispense } class ParameterizedVendingMachineTester( - mod: => ParameterizedVendingMachine, - testLength: Int) extends BasicTester { + mod: => ParameterizedVendingMachine, + testLength: Int) + extends BasicTester { require(testLength > 0, "Test length must be positive!") // Construct the module @@ -81,24 +84,24 @@ class ParameterizedVendingMachineTester( // Inputs and expected results // Do random testing private val _rand = scala.util.Random - val inputs: Seq[Option[Coin]] = Seq.fill(testLength)(coins.lift(_rand.nextInt(coins.size + 1))) + val inputs: Seq[Option[Coin]] = Seq.fill(testLength)(coins.lift(_rand.nextInt(coins.size + 1))) val expected: Seq[Boolean] = getExpectedResults(inputs, dut.sodaCost) - val inputVec: Vec[UInt] = VecInit(inputs map { + val inputVec: Vec[UInt] = VecInit(inputs.map { case Some(coin) => (1 << dut.io.indexMap(coin.name)).asUInt(coins.size.W) - case None => 0.asUInt(coins.size.W) + case None => 0.asUInt(coins.size.W) }) - val expectedVec: Vec[Bool] = VecInit(expected map (_.B)) + val expectedVec: Vec[Bool] = VecInit(expected.map(_.B)) val (idx, done) = Counter(true.B, testLength + 1) - when (done) { stop(); stop() } // Two stops for Verilator + when(done) { stop(); stop() } // Two stops for Verilator dut.io.inputs := inputVec(idx).asBools assert(dut.io.dispense === expectedVec(idx)) } class VendingMachineGeneratorSpec extends ChiselFlatSpec { - behavior of "The vending machine generator" + behavior.of("The vending machine generator") it should "generate a vending machine that accepts only nickels and dimes and costs $0.20" in { val coins = Seq(Nickel, Dime) diff --git a/src/test/scala/examples/VendingMachineUtils.scala b/src/test/scala/examples/VendingMachineUtils.scala index 6847768a..8d5aea57 100644 --- a/src/test/scala/examples/VendingMachineUtils.scala +++ b/src/test/scala/examples/VendingMachineUtils.scala @@ -24,7 +24,7 @@ object VendingMachineUtils { for (input <- inputs) { val incValue = input match { case Some(coin) => coin.value - case None => 0 + case None => 0 } if (value >= sodaCost) { outputs.append(true) |
