-
Notifications
You must be signed in to change notification settings - Fork 603
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
This adds a mechanism for the unittests to be run with the TreadleBac… #1483
Conversation
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.
Architecturally looks fine, but there seems to be some (possibly unintentional?) change of test behavior. Also suggestions for improvements (including documentation), based on my understanding of what the code does.
executeTreadle(t, additionalVResources, annotations, nameHint) | ||
case VerilatorBackend => | ||
executeVerilog(t, additionalVResources, annotations, nameHint) | ||
case _ => true |
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.
One (possible?) edge case is if there are multiple backend annotations, it will run once per annotation.
Also, potentially fragile in that it's possible to define additional backend classes which could be silently dropped (as opposed to failing noisily) here.
A potentially cleaner / more robust way to write this function would be filtering annotations for type of Backend, optionally checking the list is one or zero elements, getting the first element, and matching on it. Since it's guaranteed to be of type Backend
, the match can be complete and at least fail noisily (possibly even statically checked) if a condition is missed.
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.
This hints at TesterDriver
needing a standard stage/phase refactor. This type of check would normally be handled with a Checks
phase.
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.
@ducky64 Made code require a single known backend to be used.
@seldridge Yes, that would probably be better. I'd prefer not to implement now, but would like to discuss details with you
// val defaultBackend: Backend = VerilatorBackend | ||
val defaultBackend: Backend = TreadleBackend | ||
|
||
/** Use this to force a test to be run only with backends that are not Treadle |
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.
Might be more succinctly described as skipping tests when not running with Verilator.
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.
Re-worded
additionalVResources: Seq[String] = Seq(), | ||
annotations: AnnotationSeq = Seq(), | ||
nameHint: Option[String] = None): Boolean = { | ||
|
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.
style nit: unnecessary whitespace lines?
|
||
val circuit = annotationSeq.collect { case x: ChiselCircuitAnnotation => x }.head.circuit | ||
|
||
// val targetName = s"test_run_dir/${circuit.name}" + (nameHint match { |
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.
dead code?
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.
deleted
val targetName: File = createTestDirectory(circuit.name) | ||
|
||
annotationSeq = annotationSeq :+ TargetDirAnnotation(targetName.getPath) // :+ ClockInfoAnnotation(Seq(ClockInfo("clock", 10, 0))) // :+ CallResetAtStartupAnnotation | ||
annotationSeq = annotationSeq :+ TargetDirAnnotation(targetName.getPath) :+ CallResetAtStartupAnnotation |
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.
is the duplication of TargetDirAnnotation intentional?
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.
Fixed
@@ -150,23 +150,28 @@ class BlackBoxWithParamsTester extends BasicTester { | |||
class BlackBoxSpec extends ChiselFlatSpec { | |||
"A BlackBoxed inverter" should "work" in { | |||
assertTesterPasses({ new BlackBoxTester }, | |||
Seq("/chisel3/BlackBoxTest.v")) | |||
Seq("/chisel3/BlackBoxTest.v"), | |||
annotations = TesterDriver.verilatorOnly) |
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.
style nit: any reason this line isn't aligned with the above?
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.
Also, in some cases, you use annotations = ...
, and in others, you don't have the explicit keyword. Is this by choice (and what's the underlying rationale) or chance?
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 just followed the previous alignment here. But it is pretty messed up so I have reformatted.
Removed using named parameter
@@ -41,7 +44,11 @@ class CounterSpec extends ChiselPropSpec { | |||
} | |||
|
|||
property("Counter can be en/disabled") { | |||
forAll(safeUInts) { (seed: Int) => whenever(seed >= 0) { assertTesterPasses{ new EnableTester(seed) } } } | |||
assertTesterPasses{ new EnableTester(4) } | |||
// forAll(safeUInts) { (seed: Int) => whenever(seed >= 0) { |
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.
Dead code?
Wait, this actually removes the forall behavior?
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.
Good catch, debugging code that slipped through
@@ -22,6 +22,9 @@ class EnableTester(seed: Int) extends BasicTester { | |||
val (_, done) = Counter(true.B, 33) | |||
|
|||
when(done) { | |||
when(! cntEnVal === popCount(seed).asUInt) { |
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.
prints in automated regressions are probably generally discouraged?
.gitignore
Outdated
@@ -12,3 +12,4 @@ test_run_dir | |||
*~ | |||
\#*\# | |||
.\#* | |||
TestBackendName |
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.
Dead code?
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.
Undone
It may make sense to sneak #1481 in before this (which I was intending to backport to 3.3.x). That cleans up the |
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.
lgtm
Two (optional) suggestions (including the whitespace line after TesterDriver.execute, which looks like it may have been partially addressed) if you feel like it.
nameHint: Option[String] = None): Boolean = { | ||
|
||
val backendAnnotations = annotations.collect { case anno: Backend => anno } | ||
val backendAnnotation = if (backendAnnotations.length == 1) { |
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.
Random thought: would it be cleaner (or possible) to do a list match? - take the filtered / collected list and match against single-element list/seq/etc cases?
…kend This mechanism is not enabled and should not change the behavior of existing tests A following PR will deliver a switch that will allow changing the backend. The reasons for this PR - Treadle tests run much faster, enabling quicker debugging and CI cycles - This will help ensure fidelity of Treadle to the Verilator backend A few tests are marked as verilator only due to black box limitations Change treadle to a direct dependency I tried to make it a test only dependency but the TesterDriver sits in src/main requiring that regular compile have access to treadle Oops, made treadle the default A number of changes in response to @ducky64 review - made backend check clearer and add error handling for multiple backends specified - Fixed duplicate TargetDirAnnotation uses in Treadle backend - Cleaned up BlackBox test formatting - Undid unnecessary debugging changes from Counter - Undid .gitignore change, that should be on another PR A number of changes in response to @ducky64 review - Undid debugging changes made to BitWiseOps
9f3192d
to
3694b09
Compare
This PR introduces a dependency on Treadle for backend testing.
Looking for comments on implementation and concept.
Type of change: Testing enhancement
Impact: no functional change to chisel
This could enable running unit tests to go much faster, probably about 10x.
This also helps make sure Treadle has a high fidelity to verilator.
Development Phase: implementation
Release Notes
Chisel test suite tests can now be run using Treadle (manually).
This PR presents a use case for the Issue on global settings
Release Notes
The is the first part of a facility for running the chisel tests much faster using the Treadle backend.
Verilator remains the standard backend.