From c313e137d4e562ef20195312501840ceab8cbc6a Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Thu, 26 Oct 2017 12:39:42 -0700 Subject: Invalidateapi (#645) * Require explicit connection to DontCare to generate "is invalid". * Add tests for RefNotInitializedException. Currently, we fail the when ... otherwise ... * Disable ScalaTest shrinking on error in ComplexAssignSpec. * fix broken merge; still some binding issues * cleanup DontCare connection checks; add missing directions to test module IOs * Have library code inherit compileOptions from the enclosing Module (if it exists). * work around current firrtl uninitialized references with Strict compile options and explicitInvalidate * more CompileOptions cleanup; move test-specific defines to package object * minimize differences with master * set default CompileOptions.explicitInvalidate to false until we fix the FIRRTL when issue * ignore the StrictCompiler property checks (until CompileOptions.explicitInvalidate is defaulted to true) * Revert "more CompileOptions cleanup; move test-specific defines to package object" This reverts commit e4486edcba990d150e76e08a2fc6abca033556e0. * Revert "work around current firrtl uninitialized references with Strict compile options and explicitInvalidate" This reverts commit 426faa430a62c3dac2dbdf33044d3386d4243157. * remove unused code * Convert to binding-based DontCare implementation * comment cleanup to minimize differences with master * Tentatively remove possibly redundant DefInvalid on module ports. * Respond to code review change request. - backout build.sbt change - correct indentation - handle bulk of DontCare semantics in elemConnect() - have DontCare extend Element, not Data (eliminate most Object specific methods - add comments indicating reason for explicit DontCare connections * Initialize test elements without requiring a DontCare. * Respond to review change requests. - DontCare should work on left or right side in BiDirectional connections - call bind() to set DontCare binding instead of messing with internal variables - DontCares are only equivalent with DontCares - clean up processWhens() definition * Eliminate DontCare connection to inputs in MonoConnect(). * Pull aggregates apart for the purpose of DontCare connections. * Restore the explicit (conditionally executed) ports DefInvalidin ImplicitModule() * Don't add DontCare's to the module list of _ids. * Add missing DefInvalid() to LegacyModule(). * Respond to review requests: add DontCare BiConnect Vec, remove null parent hack to avoid addId(), initialize singletons early in Builder * Move DontCare out of chisel3.experimental. --- src/test/scala/chiselTests/InvalidateAPISpec.scala | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/test/scala/chiselTests/InvalidateAPISpec.scala (limited to 'src/test/scala/chiselTests/InvalidateAPISpec.scala') diff --git a/src/test/scala/chiselTests/InvalidateAPISpec.scala b/src/test/scala/chiselTests/InvalidateAPISpec.scala new file mode 100644 index 00000000..7176c654 --- /dev/null +++ b/src/test/scala/chiselTests/InvalidateAPISpec.scala @@ -0,0 +1,164 @@ +// See LICENSE for license details. + +package chiselTests + +import chisel3._ +import chisel3.core.BiConnect.BiConnectException +import chisel3.util.Counter +import firrtl.passes.CheckInitialization.RefNotInitializedException +import org.scalatest._ + +class InvalidateAPISpec extends ChiselPropSpec with Matchers { + + def myGenerateFirrtl(t: => Module): String = Driver.emit(() => t) + def compileFirrtl(t: => Module): Unit = { + Driver.execute(Array[String]("--compiler", "verilog"), () => t) + } + class TrivialInterface extends Bundle { + val in = Input(Bool()) + val out = Output(Bool()) + } + + property("an output connected to DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithDontCare extends Module { + val io = IO(new TrivialInterface) + io.out := DontCare + io.out := io.in + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithDontCare) + firrtlOutput should include("io.out is invalid") + } + + property("an output without a DontCare should NOT emit a Firrtl \"is invalid\" with Strict CompileOptions") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithoutDontCare extends Module { + val io = IO(new TrivialInterface) + io.out := io.in + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) + firrtlOutput should not include("is invalid") + } + + property("an output without a DontCare should emit a Firrtl \"is invalid\" with NotStrict CompileOptions") { + import chisel3.core.ExplicitCompileOptions.NotStrict + class ModuleWithoutDontCare extends Module { + val io = IO(new TrivialInterface) + io.out := io.in + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) + firrtlOutput should include("io is invalid") + } + + property("a bundle with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithoutDontCare extends Module { + val io = IO(new TrivialInterface) + io <> DontCare + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) + firrtlOutput should include("io.out is invalid") + firrtlOutput should include("io.in is invalid") + } + + property("a Vec with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions and bulk connect") { + import chisel3.core.ExplicitCompileOptions.Strict + val nElements = 5 + class ModuleWithoutDontCare extends Module { + val io = IO(new Bundle { + val ins = Input(Vec(nElements, Bool())) + }) + io.ins <> DontCare + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) + for (i <- 0 until nElements) + firrtlOutput should include(s"io.ins[$i] is invalid") + } + + property("a Vec with a DontCare should emit a Firrtl \"is invalid\" with Strict CompileOptions and mono connect") { + import chisel3.core.ExplicitCompileOptions.Strict + val nElements = 5 + class ModuleWithoutDontCare extends Module { + val io = IO(new Bundle { + val ins = Input(Vec(nElements, Bool())) + }) + io.ins := DontCare + } + val firrtlOutput = myGenerateFirrtl(new ModuleWithoutDontCare) + for (i <- 0 until nElements) + firrtlOutput should include(s"io.ins[$i] is invalid") + } + + property("a DontCare cannot be a connection sink (LHS) for := ") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithDontCareSink extends Module { + val io = IO(new TrivialInterface) + DontCare := io.in + } + val exception = intercept[ChiselException] { + elaborate(new ModuleWithDontCareSink) + } + exception.getMessage should include("DontCare cannot be a connection sink (LHS)") + } + + property("a DontCare cannot be a connection sink (LHS) for <>") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithDontCareSink extends Module { + val io = IO(new TrivialInterface) + DontCare <> io.in + } + val exception = intercept[BiConnectException] { + elaborate(new ModuleWithDontCareSink) + } + exception.getMessage should include("DontCare cannot be a connection sink (LHS)") + } + + property("FIRRTL should complain about partial initialization with Strict CompileOptions and conditional connect") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithIncompleteAssignment extends Module { + val io = IO(new Bundle { + val out = Output(Bool()) + }) + val counter = Counter(8) + when (counter.inc()) { + io.out := true.B + } + } + val exception = intercept[RefNotInitializedException] { + compileFirrtl(new ModuleWithIncompleteAssignment) + } + exception.getMessage should include("is not fully initialized") + } + + property("FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect after unconditional connect") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithUnconditionalAssignment extends Module { + val io = IO(new Bundle { + val out = Output(Bool()) + }) + val counter = Counter(8) + io.out := false.B + when (counter.inc()) { + io.out := true.B + } + } + compileFirrtl(new ModuleWithUnconditionalAssignment) + } + + property("FIRRTL should not complain about partial initialization with Strict CompileOptions and conditional connect with otherwise clause") { + import chisel3.core.ExplicitCompileOptions.Strict + class ModuleWithConditionalAndOtherwiseAssignment extends Module { + val io = IO(new Bundle { + val out = Output(Bool()) + }) + val counter = Counter(8) + when (counter.inc()) { + io.out := true.B + } otherwise { + io.out := false.B + } + } + + compileFirrtl(new ModuleWithConditionalAndOtherwiseAssignment) + } +} -- cgit v1.2.3