-
Notifications
You must be signed in to change notification settings - Fork 613
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cea81ad
commit 783b9d6
Showing
2 changed files
with
80 additions
and
83 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
80 changes: 80 additions & 0 deletions
80
src/main/scala/chisel3/experimental/inlinetest/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package chisel3.experimental | ||
|
||
import chisel3._ | ||
import chisel3.experimental.hierarchy.{Definition, Instance} | ||
|
||
/** Per-test parametrization needed to build a testharness that instantiates | ||
* the DUT and elaborates a test body. | ||
* | ||
* @tparam M the type of the DUT module | ||
* @tparam R the type of the result returned by the test body | ||
*/ | ||
case class TestParameters[M <: RawModule, R]( | ||
/** The [[desiredName]] of the DUT module. */ | ||
dutName: String, | ||
/** The user-provided name of the test. */ | ||
testName: String, | ||
/** A Definition of the DUT module. */ | ||
dutDefinition: Definition[M], | ||
/** The body for this test, returns a result. */ | ||
body: Instance[M] => R | ||
) | ||
|
||
/** An implementation of a testharness generator. | ||
* | ||
* @tparam M the type of the DUT module | ||
* @tparam R the type of the result returned by the test body | ||
*/ | ||
trait TestHarness[M <: RawModule, R] { | ||
|
||
/** Generate a testharness module given the test parameters. */ | ||
def generate(test: TestParameters[M, R]): RawModule with Public | ||
} | ||
|
||
object TestHarness { | ||
|
||
/** The minimal implementation of a unit testharness. Has a clock input and a synchronous reset | ||
* input. Connects these to the DUT and does nothing else. | ||
*/ | ||
class UnitTestHarness[M <: RawModule](test: TestParameters[M, Unit]) extends Module with Public { | ||
override def resetType = Module.ResetType.Synchronous | ||
override val desiredName = s"test_${test.dutName}_${test.testName}" | ||
val dut = Instance(test.dutDefinition) | ||
test.body(dut) | ||
} | ||
|
||
implicit def unitTestHarness[M <: RawModule]: TestHarness[M, Unit] = new TestHarness[M, Unit] { | ||
def generate(test: TestParameters[M, Unit]): RawModule with Public = new UnitTestHarness(test) | ||
} | ||
} | ||
|
||
/** Provides methods to build unit testharnesses inline after this module is elaborated. | ||
* | ||
* @tparam TestResult the type returned from each test body generator, typically | ||
* hardware indicating completion and/or exit code to the testharness. | ||
*/ | ||
trait HasTests[M <: RawModule] { module: M => | ||
|
||
/** A Definition of the DUT to be used for each of the tests. */ | ||
private lazy val moduleDefinition = | ||
module.toDefinition.asInstanceOf[Definition[module.type]] | ||
|
||
/** Generate an additional parent around this module. | ||
* | ||
* @param parent generator function, should instantiate the [[Definition]] | ||
*/ | ||
protected final def elaborateParentModule(parent: Definition[module.type] => RawModule with Public): Unit = | ||
afterModuleBuilt { Definition(parent(moduleDefinition)) } | ||
|
||
/** Generate a public module that instantiates this module. The default | ||
* testharness has clock and synchronous reset IOs and contains the test | ||
* body. | ||
* | ||
* @param body the circuit to elaborate inside the testharness | ||
*/ | ||
protected final def test[R](testName: String)(body: Instance[M] => R)(implicit th: TestHarness[M, R]): Unit = | ||
elaborateParentModule { moduleDefinition => | ||
val test = TestParameters[M, R](desiredName, testName, moduleDefinition, body) | ||
th.generate(test) | ||
} | ||
} |