diff options
Diffstat (limited to 'src/test/scala/chiselTests')
| -rw-r--r-- | src/test/scala/chiselTests/AnalogIntegrationSpec.scala | 15 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/AnalogSpec.scala | 6 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/BetterNamingTests.scala | 5 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/ChiselSpec.scala | 7 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/CompileOptionsTest.scala | 76 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/ExtModule.scala | 71 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/MultiIOModule.scala | 58 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/PrintableSpec.scala | 8 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/RawModuleSpec.scala | 65 |
9 files changed, 219 insertions, 92 deletions
diff --git a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala index 92f89e06..de717c4f 100644 --- a/src/test/scala/chiselTests/AnalogIntegrationSpec.scala +++ b/src/test/scala/chiselTests/AnalogIntegrationSpec.scala @@ -31,11 +31,18 @@ class AnalogBlackBox(index: Int) extends BlackBox(Map("index" -> index)) { val io = IO(new AnalogBlackBoxIO(1)) } +// AnalogBlackBox wrapper, which extends Module to present the common io._ interface +class AnalogBlackBoxModule(index: Int) extends Module { + val io = IO(new AnalogBlackBoxIO(1)) + val impl = Module(new AnalogBlackBox(index)) + io <> impl.io +} + // Wraps up n blackboxes, connecing their buses and simply forwarding their ports up class AnalogBlackBoxWrapper(n: Int, idxs: Seq[Int]) extends Module { require(n > 0) val io = IO(new AnalogBlackBoxIO(n)) - val bbs = idxs.map(i => Module(new AnalogBlackBox(i))) + val bbs = idxs.map(i => Module(new AnalogBlackBoxModule(i))) io.bus <> bbs.head.io.bus // Always bulk connect io.bus to first bus io.port <> bbs.flatMap(_.io.port) // Connect ports attach(bbs.map(_.io.bus):_*) // Attach all the buses @@ -58,9 +65,9 @@ abstract class AnalogDUTModule(numBlackBoxes: Int) extends Module { class AnalogDUT extends AnalogDUTModule(5) { // 5 BlackBoxes val mods = Seq( Module(new AnalogBlackBoxWrapper(1, Seq(0))), - Module(new AnalogBlackBox(1)), + Module(new AnalogBlackBoxModule(1)), Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))), // 2 blackboxes - Module(new AnalogBlackBox(4)) + Module(new AnalogBlackBoxModule(4)) ) // Connect all ports to top io.ports <> mods.flatMap(_.io.port) @@ -79,7 +86,7 @@ class AnalogDUT extends AnalogDUTModule(5) { // 5 BlackBoxes class AnalogSmallDUT extends AnalogDUTModule(4) { // 4 BlackBoxes val mods = Seq( Module(new AnalogBlackBoxWrapper(1, Seq(0))), - Module(new AnalogBlackBox(1)), + Module(new AnalogBlackBoxModule(1)), Module(new AnalogBlackBoxWrapper(2, Seq(2, 3))) // 2 BlackBoxes ) // Connect all ports to top diff --git a/src/test/scala/chiselTests/AnalogSpec.scala b/src/test/scala/chiselTests/AnalogSpec.scala index 576a5a1f..5db9ab53 100644 --- a/src/test/scala/chiselTests/AnalogSpec.scala +++ b/src/test/scala/chiselTests/AnalogSpec.scala @@ -5,7 +5,7 @@ package chiselTests import chisel3._ import chisel3.util._ import chisel3.testers.BasicTester -import chisel3.experimental.{Analog, attach} +import chisel3.experimental.{Analog, attach, BaseModule} // IO for Modules that just connect bus to out class AnalogReaderIO extends Bundle { @@ -19,7 +19,7 @@ class AnalogWriterIO extends Bundle { } trait AnalogReader { - self: Module => + self: BaseModule => final val io = self.IO(new AnalogReaderIO) } @@ -51,7 +51,7 @@ abstract class AnalogTester extends BasicTester { final val writer = Module(new AnalogWriterBlackBox) writer.io.in := BusValue - final def check(reader: Module with AnalogReader): Unit = + final def check(reader: BaseModule with AnalogReader): Unit = assert(reader.io.out === BusValue) } diff --git a/src/test/scala/chiselTests/BetterNamingTests.scala b/src/test/scala/chiselTests/BetterNamingTests.scala index 301ab5d3..a660086f 100644 --- a/src/test/scala/chiselTests/BetterNamingTests.scala +++ b/src/test/scala/chiselTests/BetterNamingTests.scala @@ -7,10 +7,11 @@ import chisel3.util._ // Defined outside of the class so we don't get $ in name class Other(w: Int) extends Module { - val io = new Bundle { + val io = IO(new Bundle { val a = UInt(w.W) - } + }) } + // Check the names of the Modules (not instances) class PerNameIndexing(count: Int) extends NamedModuleTester { def genModName(prefix: String, idx: Int): String = if (idx == 0) prefix else s"${prefix}_$idx" diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index 584f134c..143a1495 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -7,6 +7,7 @@ import org.scalatest._ import org.scalatest.prop._ import org.scalacheck._ import chisel3._ +import chisel3.experimental.RawModule import chisel3.testers._ import firrtl.{ CommonOptions, @@ -27,21 +28,21 @@ trait ChiselRunners extends Assertions { def assertTesterFails(t: => BasicTester, additionalVResources: Seq[String] = Seq()): Unit = { assert(!runTester(t, additionalVResources)) } - def elaborate(t: => Module): Unit = Driver.elaborate(() => t) + def elaborate(t: => RawModule): Unit = Driver.elaborate(() => t) /** Given a generator, return the Firrtl that it generates. * * @param t Module generator * @return Firrtl representation as a String */ - def generateFirrtl(t: => Module): String = Driver.emit(() => t) + def generateFirrtl(t: => RawModule): String = Driver.emit(() => t) /** Compiles a Chisel Module to Verilog * NOTE: This uses the "test_run_dir" as the default directory for generated code. * @param t the generator for the module * @return the Verilog code as a string. */ - def compile(t: => Module): String = { + def compile(t: => RawModule): String = { val manager = new ExecutionOptionsManager("compile") with HasFirrtlOptions with HasChiselExecutionOptions { commonOptions = CommonOptions(targetDirName = "test_run_dir") diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala index 63e6b9d1..102653af 100644 --- a/src/test/scala/chiselTests/CompileOptionsTest.scala +++ b/src/test/scala/chiselTests/CompileOptionsTest.scala @@ -14,10 +14,6 @@ class CompileOptionsSpec extends ChiselFlatSpec { abstract class StrictModule extends Module()(chisel3.core.ExplicitCompileOptions.Strict) abstract class NotStrictModule extends Module()(chisel3.core.ExplicitCompileOptions.NotStrict) - // Generate a set of options that do not have requireIOWrap enabled, in order to - // ensure its definition comes from the implicit options passed to the Module constructor. - val strictWithoutIOWrapVal = chisel3.core.ExplicitCompileOptions.Strict.copy(requireIOWrap = false) - class SmallBundle extends Bundle { val f1 = UInt(4.W) val f2 = UInt(5.W) @@ -95,19 +91,6 @@ class CompileOptionsSpec extends ChiselFlatSpec { io.out := io.in(1) } elaborate { new RequireIOWrapModule() } -} - - "A Module with unwrapped IO when compiled with implicit NotStrict.CompileOption " should "not throw an exception" in { - import chisel3.core.ExplicitCompileOptions.NotStrict - - class RequireIOWrapModule extends Module { - val io = new Bundle { - val in = UInt(32.W).asInput - val out = Bool().asOutput - } - io.out := io.in(1) - } - elaborate { new RequireIOWrapModule() } } "A Module with unwrapped IO when compiled with implicit Strict.CompileOption " should "throw an exception" in { @@ -204,63 +187,4 @@ class CompileOptionsSpec extends ChiselFlatSpec { } elaborate { new DirectionLessConnectionModule() } } - - "A Module with wrapped IO when compiled with explicit Strict.CompileOption " should "not throw an exception" in { - implicit val strictWithoutIOWrap = strictWithoutIOWrapVal - class RequireIOWrapModule extends StrictModule { - val io = IO(new Bundle { - val in = UInt(32.W).asInput - val out = Bool().asOutput - }) - io.out := io.in(1) - } - elaborate { - new RequireIOWrapModule() - } - } - - "A Module with unwrapped IO when compiled with explicit NotStrict.CompileOption " should "not throw an exception" in { - implicit val strictWithoutIOWrap = strictWithoutIOWrapVal - class RequireIOWrapModule extends NotStrictModule { - val io = new Bundle { - val in = UInt(32.W).asInput - val out = Bool().asOutput - } - io.out := io.in(1) - } - elaborate { - new RequireIOWrapModule() - } - } - - "A Module with unwrapped IO when compiled with explicit Strict.CompileOption " should "throw an exception" in { - a [BindingException] should be thrownBy { - implicit val strictWithoutIOWrap = strictWithoutIOWrapVal - class RequireIOWrapModule extends StrictModule { - val io = new Bundle { - val in = UInt(32.W).asInput - val out = Bool().asOutput - } - io.out := io.in(1) - } - elaborate { - new RequireIOWrapModule() - } - } - } - - "A Module with unwrapped IO when compiled with an explicit requireIOWrap false " should "not throw an exception" in { - - val strictNotIOWrap = chisel3.core.ExplicitCompileOptions.Strict.copy(requireIOWrap = false, deprecateOldDirectionMethods = false) - - class NotIOWrapModule extends Module()(strictNotIOWrap) { - val io = new Bundle { - val in = UInt(32.W).asInput - val out = Bool().asOutput - } - } - elaborate { - new NotIOWrapModule() - } - } } diff --git a/src/test/scala/chiselTests/ExtModule.scala b/src/test/scala/chiselTests/ExtModule.scala new file mode 100644 index 00000000..f8927b9f --- /dev/null +++ b/src/test/scala/chiselTests/ExtModule.scala @@ -0,0 +1,71 @@ +// See LICENSE for license details. + +package chiselTests + +import java.io.File + +import org.scalatest._ +import chisel3._ +import chisel3.experimental._ +import chisel3.testers.BasicTester +import chisel3.util._ + +// Avoid collisions with regular BlackBox tests by putting ExtModule blackboxes +// in their own scope. +package ExtModule { + class BlackBoxInverter extends ExtModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + } + + class BlackBoxPassthrough extends ExtModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + } +} + +class ExtModuleTester extends BasicTester { + val blackBoxPos = Module(new ExtModule.BlackBoxInverter) + val blackBoxNeg = Module(new ExtModule.BlackBoxInverter) + + blackBoxPos.in := 1.U + blackBoxNeg.in := 0.U + + assert(blackBoxNeg.out === 1.U) + assert(blackBoxPos.out === 0.U) + stop() +} + +/** Instantiate multiple BlackBoxes with similar interfaces but different + * functionality. Used to detect failures in BlackBox naming and module + * deduplication. + */ + +class MultiExtModuleTester extends BasicTester { + val blackBoxInvPos = Module(new ExtModule.BlackBoxInverter) + val blackBoxInvNeg = Module(new ExtModule.BlackBoxInverter) + val blackBoxPassPos = Module(new ExtModule.BlackBoxPassthrough) + val blackBoxPassNeg = Module(new ExtModule.BlackBoxPassthrough) + + blackBoxInvPos.in := 1.U + blackBoxInvNeg.in := 0.U + blackBoxPassPos.in := 1.U + blackBoxPassNeg.in := 0.U + + assert(blackBoxInvNeg.out === 1.U) + assert(blackBoxInvPos.out === 0.U) + assert(blackBoxPassNeg.out === 0.U) + assert(blackBoxPassPos.out === 1.U) + stop() +} + +class ExtModuleSpec extends ChiselFlatSpec { + "A ExtModule inverter" should "work" in { + assertTesterPasses({ new ExtModuleTester }, + Seq("/BlackBoxTest.v")) + } + "Multiple ExtModules" should "work" in { + assertTesterPasses({ new MultiExtModuleTester }, + Seq("/BlackBoxTest.v")) + } +} diff --git a/src/test/scala/chiselTests/MultiIOModule.scala b/src/test/scala/chiselTests/MultiIOModule.scala new file mode 100644 index 00000000..07e09041 --- /dev/null +++ b/src/test/scala/chiselTests/MultiIOModule.scala @@ -0,0 +1,58 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.experimental.MultiIOModule +import chisel3.testers.BasicTester + +class MultiIOPlusOne extends MultiIOModule { + val in = IO(Input(UInt(32.W))) + val out = IO(Output(UInt(32.W))) + + out := in + 1.asUInt +} + +class MultiIOTester extends BasicTester { + val plusModule = Module(new MultiIOPlusOne) + plusModule.in := 42.U + assert(plusModule.out === 43.U) + stop() +} + +// Demonstrate multiple IOs with inheritance where the IO is assigned to internally +trait LiteralOutputTrait extends MultiIOModule { + val myLiteralIO = IO(Output(UInt(32.W))) + myLiteralIO := 2.U +} + +// Demonstrate multiple IOs with inheritance where the IO is not assigned +// (and must be assigned by what extends this trait). +trait MultiIOTrait extends MultiIOModule { + val myTraitIO = IO(Output(UInt(32.W))) +} + +// Composition of the two above traits, example of IO composition directly using multiple top-level +// IOs rather than indirectly by constraining the type of the single .io field. +class ComposedMultiIOModule extends MultiIOModule + with LiteralOutputTrait with MultiIOTrait { + val topModuleIO = IO(Input(UInt(32.W))) + myTraitIO := topModuleIO +} + +class ComposedMultiIOTester extends BasicTester { + val composedModule = Module(new ComposedMultiIOModule) + composedModule.topModuleIO := 42.U + assert(composedModule.myTraitIO === 42.U) + assert(composedModule.myLiteralIO === 2.U) + stop() +} + +class MultiIOSpec extends ChiselFlatSpec { + "Multiple IOs in MultiIOModule" should "work" in { + assertTesterPasses({ new MultiIOTester }) + } + "Composed MultiIO Modules" should "work" in { + assertTesterPasses({ new ComposedMultiIOTester }) + } +} diff --git a/src/test/scala/chiselTests/PrintableSpec.scala b/src/test/scala/chiselTests/PrintableSpec.scala index 62784cff..5f58429e 100644 --- a/src/test/scala/chiselTests/PrintableSpec.scala +++ b/src/test/scala/chiselTests/PrintableSpec.scala @@ -101,9 +101,9 @@ class PrintableSpec extends FlatSpec with Matchers { // Submodule IO is a subtle issue because the Chisel element has a different // parent module class MySubModule extends Module { - val io = new Bundle { + val io = IO(new Bundle { val fizz = UInt(32.W) - } + }) } class MyBundle extends Bundle { val foo = UInt(32.W) @@ -128,9 +128,9 @@ class PrintableSpec extends FlatSpec with Matchers { } it should "handle printing ports of submodules" in { class MySubModule extends Module { - val io = new Bundle { + val io = IO(new Bundle { val fizz = UInt(32.W) - } + }) } class MyModule extends BasicTester { val myInst = Module(new MySubModule) diff --git a/src/test/scala/chiselTests/RawModuleSpec.scala b/src/test/scala/chiselTests/RawModuleSpec.scala new file mode 100644 index 00000000..180a1c04 --- /dev/null +++ b/src/test/scala/chiselTests/RawModuleSpec.scala @@ -0,0 +1,65 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.experimental.{RawModule, withClockAndReset} +import chisel3.testers.BasicTester + +class UnclockedPlusOne extends RawModule { + val in = IO(Input(UInt(32.W))) + val out = IO(Output(UInt(32.W))) + + out := in + 1.asUInt +} + +class RawModuleTester extends BasicTester { + val plusModule = Module(new UnclockedPlusOne) + plusModule.in := 42.U + assert(plusModule.out === 43.U) + stop() +} + +class PlusOneModule extends Module { + val io = IO(new Bundle { + val in = Input(UInt(32.W)) + val out = Output(UInt(32.W)) + }) + io.out := io.in + 1.asUInt +} + +class RawModuleWithImpliitModule extends RawModule { + val in = IO(Input(UInt(32.W))) + val out = IO(Output(UInt(32.W))) + val clk = IO(Input(Clock())) + val rst = IO(Input(Bool())) + + withClockAndReset(clk, rst) { + val plusModule = Module(new PlusOneModule) + plusModule.io.in := in + out := plusModule.io.out + } +} + +class ImplicitModuleInRawModuleTester extends BasicTester { + val plusModule = Module(new RawModuleWithImpliitModule) + plusModule.clk := clock + plusModule.rst := reset + plusModule.in := 42.U + assert(plusModule.out === 43.U) + stop() +} + +class RawModuleSpec extends ChiselFlatSpec { + "RawModule" should "elaborate" in { + elaborate { new RawModuleWithImpliitModule } + } + + "RawModule" should "work" in { + assertTesterPasses({ new RawModuleTester }) + } + + "ImplicitModule in a withClock block in a RawModule" should "work" in { + assertTesterPasses({ new ImplicitModuleInRawModuleTester }) + } +}
\ No newline at end of file |
