Skip to content
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

Merged
merged 2 commits into from
Jun 30, 2020

Conversation

chick
Copy link
Contributor

@chick chick commented Jun 19, 2020

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.

@chick chick added this to the 3.4.0 milestone Jun 19, 2020
@chick chick requested review from ducky64 and jackkoenig June 19, 2020 18:30
@chick chick requested a review from a team as a code owner June 19, 2020 18:30
@chick chick self-assigned this Jun 19, 2020
Copy link
Contributor

@ducky64 ducky64 left a 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.

src/main/scala/chisel3/testers/TesterDriver.scala Outdated Show resolved Hide resolved
executeTreadle(t, additionalVResources, annotations, nameHint)
case VerilatorBackend =>
executeVerilog(t, additionalVResources, annotations, nameHint)
case _ => true
Copy link
Contributor

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.

Copy link
Member

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.

Copy link
Contributor Author

@chick chick Jun 20, 2020

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
Copy link
Contributor

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.

Copy link
Contributor Author

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 = {

Copy link
Contributor

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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dead code?

Copy link
Contributor Author

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
Copy link
Contributor

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?

Copy link
Contributor Author

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)
Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Contributor Author

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

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) {
Copy link
Contributor

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undone

@seldridge
Copy link
Member

It may make sense to sneak #1481 in before this (which I was intending to backport to 3.3.x). That cleans up the TesterDriver.execute method to be more stage-like and may help simplify the logic of switching backends.

Copy link
Contributor

@ducky64 ducky64 left a 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) {
Copy link
Contributor

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
@chick chick force-pushed the add-treadle-backend-for-tests branch from 9f3192d to 3694b09 Compare June 29, 2020 17:44
@chick chick merged commit 61f4abd into master Jun 30, 2020
@jackkoenig jackkoenig deleted the add-treadle-backend-for-tests branch July 7, 2021 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants