-
Notifications
You must be signed in to change notification settings - Fork 615
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change the width of static shift right #3824
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,12 +9,18 @@ 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 dynamicShiftLeft(that: Width): Width = | ||
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) | ||
@deprecated( | ||
"The width of shift-right now differs by type, use unsignedShiftRight and signedShiftRight", | ||
"Chisel 7.0.0" | ||
) | ||
def shiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that)) | ||
def unsignedShiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that)) | ||
def signedShiftRight(that: Int): Width = this.op(this, (a, b) => 1.max(a - that)) | ||
def dynamicShiftLeft(that: Width): Width = | ||
Comment on lines
+21
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mega-nit: the three new methods could all be made final. This would make them inconsistent with other methods here, though. There's also very limited risk here because this thing is sealed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the sealing is more than sufficient. I probably don't actually want them to be final because I have the ulterior motive of possibly introducing a "WidthChanged" private subclass of |
||
this.op(that, (a, b) => a + (1 << b) - 1) | ||
|
||
def known: Boolean | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,20 +7,22 @@ import chisel3.internal.WarningFilter | |
import java.io.File | ||
|
||
class ChiselOptions private[stage] ( | ||
val printFullStackTrace: Boolean = false, | ||
val throwOnFirstError: Boolean = false, | ||
val outputFile: Option[String] = None, | ||
val chiselCircuit: Option[Circuit] = None, | ||
val sourceRoots: Vector[File] = Vector.empty, | ||
val warningFilters: Vector[WarningFilter] = Vector.empty) { | ||
val printFullStackTrace: Boolean = false, | ||
val throwOnFirstError: Boolean = false, | ||
val outputFile: Option[String] = None, | ||
val chiselCircuit: Option[Circuit] = None, | ||
val sourceRoots: Vector[File] = Vector.empty, | ||
val warningFilters: Vector[WarningFilter] = Vector.empty, | ||
val legacyShiftRightWidth: Boolean = false) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: the naming of this may be better as |
||
|
||
private[stage] def copy( | ||
printFullStackTrace: Boolean = printFullStackTrace, | ||
throwOnFirstError: Boolean = throwOnFirstError, | ||
outputFile: Option[String] = outputFile, | ||
chiselCircuit: Option[Circuit] = chiselCircuit, | ||
sourceRoots: Vector[File] = sourceRoots, | ||
warningFilters: Vector[WarningFilter] = warningFilters | ||
printFullStackTrace: Boolean = printFullStackTrace, | ||
throwOnFirstError: Boolean = throwOnFirstError, | ||
outputFile: Option[String] = outputFile, | ||
chiselCircuit: Option[Circuit] = chiselCircuit, | ||
sourceRoots: Vector[File] = sourceRoots, | ||
warningFilters: Vector[WarningFilter] = warningFilters, | ||
legacyShiftRightWidth: Boolean = legacyShiftRightWidth | ||
): ChiselOptions = { | ||
|
||
new ChiselOptions( | ||
|
@@ -29,7 +31,8 @@ class ChiselOptions private[stage] ( | |
outputFile = outputFile, | ||
chiselCircuit = chiselCircuit, | ||
sourceRoots = sourceRoots, | ||
warningFilters = warningFilters | ||
warningFilters = warningFilters, | ||
legacyShiftRightWidth = legacyShiftRightWidth | ||
) | ||
|
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,12 +23,14 @@ import org.scalatest.funspec.AnyFunSpec | |
import org.scalatest.matchers.should.Matchers | ||
import org.scalatest.propspec.AnyPropSpec | ||
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks | ||
import org.scalactic.source.Position | ||
|
||
import java.io.{ByteArrayOutputStream, PrintStream} | ||
import java.security.Permission | ||
import scala.reflect.ClassTag | ||
import java.text.SimpleDateFormat | ||
import java.util.Calendar | ||
import chisel3.reflect.DataMirror | ||
|
||
/** Common utility functions for Chisel unit tests. */ | ||
trait ChiselRunners extends Assertions { | ||
|
@@ -124,38 +126,50 @@ trait ChiselRunners extends Assertions { | |
assert(!runTester(t, additionalVResources, annotations)) | ||
} | ||
|
||
def assertKnownWidth(expected: Int)(gen: => Data): Unit = { | ||
def assertKnownWidth(expected: Int, args: Iterable[String] = Nil)(gen: => Data)(implicit pos: Position): Unit = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh, so this is for scalatest to properly pass the source locator to the assert? Interesting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, I added this because a test was failing and I wasn't sure which one. |
||
class TestModule extends Module { | ||
val testPoint = gen | ||
assert(testPoint.getWidth === expected) | ||
val out = IO(Output(chiselTypeOf(testPoint))) | ||
// Sanity check that firrtl doesn't change the width | ||
testPoint := 0.U(0.W).asTypeOf(chiselTypeOf(testPoint)) | ||
dontTouch(testPoint) | ||
val zero = 0.U(0.W).asTypeOf(chiselTypeOf(testPoint)) | ||
if (DataMirror.isWire(testPoint)) { | ||
testPoint := zero | ||
} | ||
out := zero | ||
out := testPoint | ||
} | ||
val verilog = ChiselStage.emitSystemVerilog(new TestModule, Array.empty, Array("-disable-all-randomization")) | ||
val verilog = ChiselStage.emitSystemVerilog(new TestModule, args.toArray, Array("-disable-all-randomization")) | ||
expected match { | ||
case 0 => assert(!verilog.contains("testPoint")) | ||
case 0 => assert(!verilog.contains("out")) | ||
case 1 => | ||
assert(verilog.contains(s"testPoint")) | ||
assert(!verilog.contains(s"0] testPoint")) | ||
case _ => assert(verilog.contains(s"[${expected - 1}:0] testPoint")) | ||
assert(verilog.contains(s"out")) | ||
assert(!verilog.contains(s"0] out")) | ||
case _ => assert(verilog.contains(s"[${expected - 1}:0] out")) | ||
} | ||
} | ||
|
||
def assertInferredWidth(expected: Int)(gen: => Data): Unit = { | ||
def assertInferredWidth(expected: Int, args: Iterable[String] = Nil)(gen: => Data)(implicit pos: Position): Unit = { | ||
class TestModule extends Module { | ||
val testPoint = gen | ||
assert(!testPoint.isWidthKnown, s"Asserting that width should be inferred yet width is known to Chisel!") | ||
testPoint := 0.U(0.W).asTypeOf(chiselTypeOf(testPoint)) | ||
dontTouch(testPoint) | ||
// Sanity check that firrtl doesn't change the width | ||
val out = IO(Output(chiselTypeOf(testPoint))) | ||
val zero = 0.U(0.W).asTypeOf(chiselTypeOf(testPoint)) | ||
if (DataMirror.isWire(testPoint)) { | ||
testPoint := zero | ||
} | ||
out := zero | ||
out := testPoint | ||
} | ||
val verilog = ChiselStage.emitSystemVerilog(new TestModule, Array.empty, Array("-disable-all-randomization")) | ||
val verilog = | ||
ChiselStage.emitSystemVerilog(new TestModule, args.toArray :+ "--dump-fir", Array("-disable-all-randomization")) | ||
expected match { | ||
case 0 => assert(!verilog.contains("testPoint")) | ||
case 0 => assert(!verilog.contains("out")) | ||
case 1 => | ||
assert(verilog.contains(s"testPoint")) | ||
assert(!verilog.contains(s"0] testPoint")) | ||
case _ => assert(verilog.contains(s"[${expected - 1}:0] testPoint")) | ||
assert(verilog.contains(s"out")) | ||
assert(!verilog.contains(s"0] out")) | ||
case _ => assert(verilog.contains(s"[${expected - 1}:0] out")) | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does nowarn mean again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I deprecated
Width.shiftRight
and it would trigger a warning here (and warnings are errors), so this@nowarn
suppresses it. Obviously we are allowed to use our own deprecated APIs, but the API is public so I couldn't/shouldn't just delete it.