Skip to content

Commit

Permalink
Reject negative shift amounts; add tests
Browse files Browse the repository at this point in the history
Closes #729
  • Loading branch information
aswaterman authored and jackkoenig committed Dec 9, 2017
1 parent 81fa4f2 commit f979068
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
18 changes: 12 additions & 6 deletions chiselFrontend/src/main/scala/chisel3/core/Bits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])

/** Default print as [[Decimal]] */
final def toPrintable: Printable = Decimal(this)

protected final def validateShiftAmount(x: Int): Int = {
if (x < 0)
Builder.error(s"Negative shift amounts are illegal (got $x)")
x
}
}

// REVIEW TODO: Further discussion needed on what Num actually is.
Expand Down Expand Up @@ -494,13 +500,13 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
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 =
binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, that)
binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, validateShiftAmount(that))
override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
this << that.toInt
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 =
binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, that)
binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that))
override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
this >> that.toInt
override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
Expand Down Expand Up @@ -662,13 +668,13 @@ sealed class SInt private[core] (width: Width, lit: Option[SLit] = None)
}

override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, that)
binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, validateShiftAmount(that))
override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
this << that.toInt
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 =
binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, that)
binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that))
override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
this >> that.toInt
override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt =
Expand Down Expand Up @@ -924,13 +930,13 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit
}

override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, that)
binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, validateShiftAmount(that))
override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
(this << that.toInt).asFixedPoint(this.binaryPoint)
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, that)
binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, validateShiftAmount(that))
override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
(this >> that.toInt).asFixedPoint(this.binaryPoint)
override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint =
Expand Down
3 changes: 3 additions & 0 deletions src/test/scala/chiselTests/FixedPointSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,7 @@ class FixedPointSpec extends ChiselPropSpec {
property("should mux different widths and binary points") {
assertTesterPasses { new FixedPointMuxTester }
}
property("Negative shift amounts are invalid") {
a [ChiselException] should be thrownBy { elaborate(new NegativeShift(FixedPoint(1.W, 0.BP))) }
}
}
4 changes: 4 additions & 0 deletions src/test/scala/chiselTests/SIntOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,9 @@ class SIntOpsSpec extends ChiselPropSpec {
elaborate { new SIntOps }
}

property("Negative shift amounts are invalid") {
a [ChiselException] should be thrownBy { elaborate(new NegativeShift(SInt())) }
}

ignore("SIntOpsTester should return the correct result") { }
}
9 changes: 9 additions & 0 deletions src/test/scala/chiselTests/UIntOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ class BadBoolConversion extends Module {
io.b := io.u.toBool
}

class NegativeShift(t: => Bits) extends Module {
val io = IO(new Bundle)
Reg(t) >> -1
}

class UIntOpsSpec extends ChiselPropSpec with Matchers {
// Disable shrinking on error.
implicit val noShrinkListVal = Shrink[List[Int]](_ => Stream.empty)
Expand All @@ -111,5 +116,9 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers {
property("UIntOpsTester should return the correct result") {
assertTesterPasses { new UIntOpsTester(123, 7) }
}

property("Negative shift amounts are invalid") {
a [ChiselException] should be thrownBy { elaborate(new NegativeShift(UInt())) }
}
}

0 comments on commit f979068

Please sign in to comment.