diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/chisel3/Driver.scala | 11 | ||||
| -rw-r--r-- | src/main/scala/chisel3/compatibility.scala | 33 | ||||
| -rw-r--r-- | src/main/scala/chisel3/internal/firrtl/Emitter.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/chisel3/package.scala | 7 | ||||
| -rw-r--r-- | src/main/scala/chisel3/util/BlackBoxUtils.scala | 4 | ||||
| -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 | ||||
| -rw-r--r-- | src/test/scala/cookbook/CookbookSpec.scala | 2 |
15 files changed, 266 insertions, 106 deletions
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index b2acc946..8a2256df 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -3,6 +3,7 @@ package chisel3 import chisel3.internal.firrtl.Emitter +import chisel3.experimental.RawModule import java.io._ import net.jcazevedo.moultingyaml._ @@ -88,11 +89,11 @@ object Driver extends BackendCompilationUtilities { * @param gen a function that creates a Module hierarchy * @return the resulting Chisel IR in the form of a Circuit (TODO: Should be FIRRTL IR) */ - def elaborate[T <: Module](gen: () => T): Circuit = internal.Builder.build(Module(gen())) + def elaborate[T <: RawModule](gen: () => T): Circuit = internal.Builder.build(Module(gen())) - def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen)) + def emit[T <: RawModule](gen: () => T): String = Emitter.emit(elaborate(gen)) - def emit[T <: Module](ir: Circuit): String = Emitter.emit(ir) + def emit[T <: RawModule](ir: Circuit): String = Emitter.emit(ir) def dumpFirrtl(ir: Circuit, optName: Option[File]): File = { val f = optName.getOrElse(new File(ir.name + ".fir")) @@ -122,7 +123,7 @@ object Driver extends BackendCompilationUtilities { */ def execute( optionsManager: ExecutionOptionsManager with HasChiselExecutionOptions with HasFirrtlOptions, - dut: () => Module): ChiselExecutionResult = { + dut: () => RawModule): ChiselExecutionResult = { val circuit = elaborate(dut) // this little hack let's us set the topName with the circuit name if it has not been set from args @@ -173,7 +174,7 @@ object Driver extends BackendCompilationUtilities { * @param dut The device under test * @return An execution result with useful stuff, or failure with message */ - def execute(args: Array[String], dut: () => Module): ChiselExecutionResult = { + def execute(args: Array[String], dut: () => RawModule): ChiselExecutionResult = { val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions optionsManager.parse(args) match { diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 40fbe9bf..778d2c13 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -152,16 +152,43 @@ package object Chisel { // scalastyle:ignore package.object.name object Bool extends BoolFactory val Mux = chisel3.core.Mux - type BlackBox = chisel3.core.BlackBox - + import chisel3.core.Param + abstract class BlackBox(params: Map[String, Param] = Map.empty[String, Param]) extends chisel3.core.BlackBox(params) { + // This class auto-wraps the BlackBox with IO(...), allowing legacy code (where IO(...) wasn't + // required) to build. + override def _autoWrapPorts() = { + if (!_ioPortBound()) { + IO(io) + } + } + } val Mem = chisel3.core.Mem type MemBase[T <: Data] = chisel3.core.MemBase[T] type Mem[T <: Data] = chisel3.core.Mem[T] val SeqMem = chisel3.core.SyncReadMem type SeqMem[T <: Data] = chisel3.core.SyncReadMem[T] + import chisel3.core.CompileOptions + abstract class CompatibilityModule( + override_clock: Option[Clock]=None, override_reset: Option[Bool]=None) + (implicit moduleCompileOptions: CompileOptions) + extends chisel3.core.LegacyModule(override_clock, override_reset) { + // This class auto-wraps the Module IO with IO(...), allowing legacy code (where IO(...) wasn't + // required) to build. + // Also provides the clock / reset constructors, which were used before withClock happened. + + def this(_clock: Clock)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), None)(moduleCompileOptions) + def this(_reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(None, Option(_reset))(moduleCompileOptions) + def this(_clock: Clock, _reset: Bool)(implicit moduleCompileOptions: CompileOptions) = this(Option(_clock), Option(_reset))(moduleCompileOptions) + + override def _autoWrapPorts() = { + if (!_ioPortBound()) { + IO(io) + } + } + } val Module = chisel3.core.Module - type Module = chisel3.core.Module + type Module = CompatibilityModule val printf = chisel3.core.printf diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index eb00e333..16b39e35 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -57,8 +57,8 @@ private class Emitter(circuit: Circuit) { /** Generates the FIRRTL module declaration. */ private def moduleDecl(m: Component): String = m.id match { - case _: BlackBox => newline + s"extmodule ${m.name} : " - case _: Module => newline + s"module ${m.name} : " + case _: chisel3.core.BaseBlackBox => newline + s"extmodule ${m.name} : " + case _: chisel3.core.UserModule => newline + s"module ${m.name} : " } /** Generates the FIRRTL module definition. diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 191b636e..a7ccc43b 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -151,7 +151,7 @@ package object chisel3 { // scalastyle:ignore package.object.name type SyncReadMem[T <: Data] = chisel3.core.SyncReadMem[T] val Module = chisel3.core.Module - type Module = chisel3.core.Module + type Module = chisel3.core.LegacyModule val printf = chisel3.core.printf @@ -310,6 +310,11 @@ package object chisel3 { // scalastyle:ignore package.object.name val withClock = chisel3.core.withClock val withReset = chisel3.core.withReset + type BaseModule = chisel3.core.BaseModule + type MultiIOModule = chisel3.core.ImplicitModule + type RawModule = chisel3.core.UserModule + type ExtModule = chisel3.core.ExtModule + // Implicit conversions for BlackBox Parameters implicit def fromIntToIntParam(x: Int): IntParam = IntParam(BigInt(x)) implicit def fromLongToIntParam(x: Long): IntParam = IntParam(BigInt(x)) diff --git a/src/main/scala/chisel3/util/BlackBoxUtils.scala b/src/main/scala/chisel3/util/BlackBoxUtils.scala index 084d58f9..fbcf4a59 100644 --- a/src/main/scala/chisel3/util/BlackBoxUtils.scala +++ b/src/main/scala/chisel3/util/BlackBoxUtils.scala @@ -7,7 +7,7 @@ import chisel3.core.ChiselAnnotation import firrtl.transforms.{BlackBoxInline, BlackBoxResource, BlackBoxSourceHelper} trait HasBlackBoxResource extends BlackBox { - self: Module => + self: BlackBox => def setResource(blackBoxResource: String): Unit = { annotate(ChiselAnnotation(self, classOf[BlackBoxSourceHelper], BlackBoxResource(blackBoxResource).serialize)) @@ -15,7 +15,7 @@ trait HasBlackBoxResource extends BlackBox { } trait HasBlackBoxInline extends BlackBox { - self: Module => + self: BlackBox => def setInline(blackBoxName: String, blackBoxInline: String): Unit = { annotate(ChiselAnnotation( 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 diff --git a/src/test/scala/cookbook/CookbookSpec.scala b/src/test/scala/cookbook/CookbookSpec.scala index 554a415f..638ebd46 100644 --- a/src/test/scala/cookbook/CookbookSpec.scala +++ b/src/test/scala/cookbook/CookbookSpec.scala @@ -10,7 +10,7 @@ import chiselTests.ChiselFlatSpec /** Tester for concise cookbook tests * - * Provides a length of test after which the test will pass + * Provides a length of test after which the test will pass */ abstract class CookbookTester(length: Int) extends BasicTester { require(length >= 0, "Simulation length must be non-negative!") |
