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

Towards an ergonomic chiselsim testing framework [svsim] [RFC] [WIP] #4209

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

kammoh
Copy link
Contributor

@kammoh kammoh commented Jun 23, 2024

This is an attempt towards a full-featured and user-friendly testing framework with chiseltest capabilities. I really like the chiseltest's API @ekiwi and ergonomics and I think keeping a similar interface would greatly ease transition and porting to svsim.

Notable missing features include:

  • fork/join style concurrent test tasks.
    • Choice of implementation is an open question for me, e.g., if a multithreading similar to chiseltest is the best way forward.
  • A more elegant peak/poke API for all Data types including Aggregates.

Contributor Checklist

  • Did you add Scaladoc to every public function/method?
  • Did you add at least one test demonstrating the PR?
  • Did you delete any extraneous printlns/debugging code?
  • Did you specify the type of improvement?
  • Did you add appropriate documentation in docs/src?
  • Did you request a desired merge strategy?
  • Did you add text to be included in the Release Notes for this change?

Type of Improvement

  • Feature (or new API)
  • API modification

Desired Merge Strategy

  • Squash: The PR will be squashed and merged (choose this if you have no preference).
  • Rebase: You will rebase the PR onto master and it will be merged with a merge commit.

Release Notes

Reviewer Checklist (only modified by reviewer)

  • Did you add the appropriate labels? (Select the most appropriate one based on the "Type of Improvement")
  • Did you mark the proper milestone (Bug fix: 3.6.x, 5.x, or 6.x depending on impact, API modification or big change: 7.0)?
  • Did you review?
  • Did you check whether all relevant Contributor checkboxes have been checked?
  • Did you do one of the following when ready to merge:
    • Squash: You/ the contributor Enable auto-merge (squash), clean up the commit message, and label with Please Merge.
    • Merge: Ensure that contributor has cleaned up their commit history, then merge with Create a merge commit.

@carlosedp
Copy link
Contributor

I've listed a couple of improvements in #4203 that would make testing with ChiselSim closer to what chiseltest is which is very user-friendly IMO.

@ekiwi
Copy link
Contributor

ekiwi commented Jun 25, 2024

This looks great! Thanks for taking the lead on this @kammoh!

Please feel free to re-use code from chiseltest and tag me if you have any questions. The only thing you need to be careful about is to maintain the correct license information. Most of my contributions to chiseltest were licensed under BSD 3-Clause License. You will see that noted in the file header, just make sure to copy that information over with any code snippets.

Copy link
Contributor

@jackkoenig jackkoenig left a comment

Choose a reason for hiding this comment

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

Thanks so much for getting this going @kammoh. Some drive by comments but the biggest one is that this is awesome!

build.sbt Outdated
@@ -195,7 +195,7 @@ lazy val firrtl = (project in file("firrtl"))
lazy val chiselSettings = Seq(
name := "chisel",
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.18" % "test",
"org.scalatest" %% "scalatest" % "3.2.18",
Copy link
Contributor

Choose a reason for hiding this comment

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

We should not impose scalatest on downstream users of Chisel. Better options IMO are:

  1. Add a new subproject that adds just the integration (e.g. chisel-scalatest) - the rest of chiselsim stays in chisel but the sugar around scalatest specs lives in the new project.
  2. Make it a provided dependency
  3. Use runtime reflection

(1) is a little annoying but there are no sharp edges other than telling the user to grab the dependency. (2) means that if users forget to add the dependency but then use the APIs requiring chiseltest, they will get a linkage error. We can mitigate that by catching the exception and giving a better error, or perhaps just providing a sensible default. Regardless, there are more sharp edges. (3) is similar to (2) except Chisel itself could elide the dependency. I don't think there are any benefits to it over (2) and it has all of the same sharp edges.

Comment on lines 248 to 255
def waitForValid() = {
// println("wait for valid")
// clock.stepUntil(sig.valid, 1, maxWaitCycles)
// val timeout = sig.valid.peekValue().asBigInt == 0
// chisel3.assert(!timeout, s"Timeout after $maxWaitCycles cycles waiting for valid")
var cycles = 0
while (!sig.valid.peek().litToBoolean) {
clock.step()
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be a great place to take advantage of SVSims clock ticking with sentinel values:

this allows for decoupling to offset the IPC overhead.

@@ -289,7 +289,7 @@ object Flipped {
* @groupdesc Connect Utilities for connecting hardware components
* @define coll data
*/
abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
abstract class Data extends HasId with NamedComponent with SourceInfoDoc with Serializable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Whats the Serializable for?

* @param chiselArgs
* @param firtoolArgs
*/
case class ChiselSimSettings[B <: Backend](
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should make this a case class. They are so much more convenient to write but they make adding fields in a backwards compatible way very painful (generated unapply and copy methods are the bane of source and binary compatibility). I assume we're going to want to add settings to this quite a bit, so we should probably set ourselves up to make that easy.

Comment on lines +45 to +46
outputSplit: Option[Int] = Some(20_000),
outputSplitCFuncs: Option[Int] = Some(20_000),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should avoid making simualtor-specific things part of the generic ChiselSim settings

import svsim.Simulation

trait HierarchicalValue {
val gen: Data
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
val gen: Data
def gen: Data

Generally, it's best to make any virtual methods a def and let implementers decide what to do

@zhutmost
Copy link

zhutmost commented Jul 3, 2024

Hi, thanks for your effort. I want to know whether SVSIM supports multiple clocks now?

@schoeberl
Copy link
Contributor

This is VERY cool! Hope to have a smooth transition from classic ChiselTest to the new simulator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants