ucb-bar / chiseltest

The batteries-included testing and formal verification library for Chisel-based RTL designs.
Other
213 stars 71 forks source link

Line coverage report fails with VerilatorBackend #735

Open PhilippKasgen opened 1 week ago

PhilippKasgen commented 1 week ago

When I try to retrieve a line coverage report, chiseltest fails when I use the VerilatorBackend, but not when using the default backend. Here is a minimal example to reproduce the error:

import chisel3._
import chisel3.util._
import chiseltest._
import chiseltest.coverage._
import org.scalatest.flatspec.AnyFlatSpec
import firrtl2._

class LineCoverageTest extends AnyFlatSpec with ChiselScalatestTester {
  behavior of "LineCoverage"

  it should "report line coverage default" in {
    line_coverage(Seq())
  }

  it should "report line coverage verilator" in {
    line_coverage(Seq(VerilatorBackendAnnotation))
  }

  def line_coverage(annos: AnnotationSeq): Unit = {
    val data = LineCoverage.processCoverage(test_run(LineCoverage.annotations ++ annos).getAnnotationSeq)

    // print to console
    val code = new CodeBase()
    for (d <- data.files) {
      try {
        val report = LineCoverage.textReport(code, d).toVector
        println(report.mkString("\n"))
      } catch {
        case e: RuntimeException => println(f"${d.name} could not be found. Skipping...")
        case e: Throwable => throw(e)
      }
    }
  }

  def test_run(annos: AnnotationSeq): TestResult =
    test(new Queue(gen=UInt(5.W), entries=4))
      .withAnnotations(annos) { dut => dut.clock.step() }
}

build.sbt

scalaVersion := "2.13.12"
val chiselVersion = "6.4.0"

lazy val root = (project in file("."))
  .settings(
    libraryDependencies ++= Seq(
      "org.chipsalliance" %% "chisel" % chiselVersion,
      "org.scalatest" %% "scalatest" % "3.2.16" % "test",
      "edu.berkeley.cs" %% "chiseltest" % "6.0.0",
    )
  )

Verilator: 4.028

The console output is:

...
src/main/scala/chisel3/util/Counter.scala could not be found. Skipping...
src/main/scala/chisel3/util/Decoupled.scala could not be found. Skipping...
[info] LineCoverageTest:
[info] LineCoverage
[info] - should report line coverage default
[info] - should report line coverage verilator *** FAILED ***
[info]   java.lang.AssertionError: assertion failed: [] Missing or too many entries! 5 cover statements vs. 4 coverage entries.
[info] l_4, l_0, l_1, l_2, l_3
[info] CoverageEntry(Queue4_UInt5.sv,130,,2), CoverageEntry(Queue4_UInt5.sv,134,,0), CoverageEntry(Queue4_UInt5.sv,138,,0), CoverageEntry(Queue4_UInt5.sv,142,,0)
[info]   at scala.Predef$.assert(Predef.scala:279)
[info]   at chiseltest.simulator.VerilatorCoverage$.processInstanceCoverage(VerilatorCoverage.scala:77)
[info]   at chiseltest.simulator.VerilatorCoverage$.$anonfun$verilatorCoverageToCoverageMap$2(VerilatorCoverage.scala:56)
[info]   at scala.collection.immutable.List.flatMap(List.scala:293)
[info]   at chiseltest.simulator.VerilatorCoverage$.verilatorCoverageToCoverageMap(VerilatorCoverage.scala:51)
[info]   at chiseltest.simulator.VerilatorCoverage$.loadCoverage(VerilatorCoverage.scala:37)
[info]   at chiseltest.simulator.VerilatorSimulator$.readCoverage$2(VerilatorSimulator.scala:155)
[info]   at chiseltest.simulator.VerilatorSimulator$.$anonfun$createContextFromScratch$3(VerilatorSimulator.scala:160)
[info]   at chiseltest.simulator.jna.JNASimulatorContext.getCoverage(JNASimulatorContext.scala:145)
[info]   at chiseltest.internal.SimController.generateTestCoverageAnnotation(SimController.scala:140)
[info]   ...
[info] Run completed in 6 seconds, 925 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 1, canceled 0, ignored 0, pending 0
...

Whenever I tried this, it seems like one coverage entry is missing.

ekiwi commented 1 week ago

Thanks for the detailed report. This definitely looks like a bug in chiseltest.