summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Koenig2017-12-20 15:54:25 -0800
committerGitHub2017-12-20 15:54:25 -0800
commite27657118ff5915b96f8e3a467d464245fe09769 (patch)
tree2353d94bc70fa006639bf5019bde366b15e82b29
parent0f5ba51572b22ff5c85f9dd1add82680e0620797 (diff)
Add compileOptions to Module.apply, use for invalidating submod ports (#747)
Fixes #746 Also add test for https://github.com/freechipsproject/firrtl/issues/705
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala4
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala8
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/UserModule.scala23
-rw-r--r--coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala2
-rw-r--r--src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala22
-rw-r--r--src/test/scala/chiselTests/Util.scala22
-rw-r--r--src/test/scala/chiselTests/Vec.scala11
-rw-r--r--src/test/scala/chiselTests/When.scala20
8 files changed, 86 insertions, 26 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
index f5e0d5ba..aa0f8064 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
@@ -80,7 +80,7 @@ abstract class ExtModule(val params: Map[String, Param] = Map.empty[String, Para
component
}
- private[core] def initializeInParent() {
+ private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
implicit val sourceInfo = UnlocatableSourceInfo
for (x <- getModulePorts) {
@@ -165,7 +165,7 @@ abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param
component
}
- private[core] def initializeInParent() {
+ private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
for ((_, port) <- io.elements) {
pushCommand(DefInvalid(UnlocatableSourceInfo, port.ref))
}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index 0e919d3c..fa9ab082 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -23,7 +23,9 @@ object Module {
*/
def apply[T <: BaseModule](bc: => T): T = macro InstTransform.apply[T]
- def do_apply[T <: BaseModule](bc: => T)(implicit sourceInfo: SourceInfo): T = {
+ def do_apply[T <: BaseModule](bc: => T)
+ (implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions): T = {
if (Builder.readyForModuleConstr) {
throwException("Error: Called Module() twice without instantiating a Module." +
sourceInfo.makeMessage(" See " + _))
@@ -62,7 +64,7 @@ object Module {
// Handle connections at enclosing scope
if(!Builder.currentModule.isEmpty) {
pushCommand(DefInstance(sourceInfo, module, component.ports))
- module.initializeInParent()
+ module.initializeInParent(compileOptions)
}
module
}
@@ -124,7 +126,7 @@ abstract class BaseModule extends HasId {
/** Sets up this module in the parent context
*/
- private[core] def initializeInParent()
+ private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit
//
// Chisel Internals
diff --git a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala
index c99d53cf..9c923037 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala
@@ -81,8 +81,15 @@ abstract class UserModule(implicit moduleCompileOptions: CompileOptions)
component
}
- // There is no initialization to be done by default.
- private[core] def initializeInParent() {}
+ private[core] def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
+ implicit val sourceInfo = UnlocatableSourceInfo
+
+ if (!parentCompileOptions.explicitInvalidate) {
+ for (port <- getModulePorts) {
+ pushCommand(DefInvalid(sourceInfo, port.ref))
+ }
+ }
+ }
}
/** Abstract base class for Modules, which behave much like Verilog modules.
@@ -100,14 +107,10 @@ abstract class ImplicitModule(implicit moduleCompileOptions: CompileOptions)
// Setup ClockAndReset
Builder.currentClockAndReset = Some(ClockAndReset(clock, reset))
- private[core] override def initializeInParent() {
+ private[core] override def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
implicit val sourceInfo = UnlocatableSourceInfo
- if (!compileOptions.explicitInvalidate) {
- for (port <- getModulePorts) {
- pushCommand(DefInvalid(sourceInfo, port.ref))
- }
- }
+ super.initializeInParent(parentCompileOptions)
clock := Builder.forcedClock
reset := Builder.forcedReset
}
@@ -173,12 +176,12 @@ abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions)
super.generateComponent()
}
- private[core] override def initializeInParent() {
+ private[core] override def initializeInParent(parentCompileOptions: CompileOptions): Unit = {
// Don't generate source info referencing parents inside a module, since this interferes with
// module de-duplication in FIRRTL emission.
implicit val sourceInfo = UnlocatableSourceInfo
- if (!compileOptions.explicitInvalidate) {
+ if (!parentCompileOptions.explicitInvalidate) {
pushCommand(DefInvalid(sourceInfo, io.ref))
}
diff --git a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
index 47c77c98..9f3ac88d 100644
--- a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
+++ b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala
@@ -38,7 +38,7 @@ class UIntTransform(val c: Context) extends SourceInfoTransformMacro {
class InstTransform(val c: Context) extends SourceInfoTransformMacro {
import c.universe._
def apply[T: c.WeakTypeTag](bc: c.Tree): c.Tree = {
- q"$thisObj.do_apply($bc)($implicitSourceInfo)"
+ q"$thisObj.do_apply($bc)($implicitSourceInfo, $implicitCompileOptions)"
}
}
diff --git a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
index c0538123..457f26de 100644
--- a/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
+++ b/src/test/scala/chiselTests/CompatibilityInteroperabilitySpec.scala
@@ -217,5 +217,27 @@ class CompatibiltyInteroperabilitySpec extends ChiselFlatSpec {
stop()
})
}
+
+ "An instance of a chisel3.Module inside a Chisel.Module" should "have its inputs invalidated" in {
+ compile {
+ import Chisel._
+ new Module {
+ val io = new Bundle {
+ val in = UInt(INPUT, width = 32)
+ val cond = Bool(INPUT)
+ val out = UInt(OUTPUT, width = 32)
+ }
+ val children = Seq(Module(new PassthroughModule),
+ Module(new PassthroughMultiIOModule),
+ Module(new PassthroughRawModule))
+ io.out := children.map(_.io.out).reduce(_ + _)
+ children.foreach { child =>
+ when (io.cond) {
+ child.io.in := io.in
+ }
+ }
+ }
+ }
+ }
}
diff --git a/src/test/scala/chiselTests/Util.scala b/src/test/scala/chiselTests/Util.scala
new file mode 100644
index 00000000..80e37285
--- /dev/null
+++ b/src/test/scala/chiselTests/Util.scala
@@ -0,0 +1,22 @@
+// Useful utilities for tests
+
+package chiselTests
+
+import chisel3._
+import chisel3.experimental._
+
+class PassthroughModuleIO extends Bundle {
+ val in = Input(UInt(32.W))
+ val out = Output(UInt(32.W))
+}
+
+trait AbstractPassthroughModule extends RawModule {
+ val io = IO(new PassthroughModuleIO)
+ io.out := io.in
+}
+
+class PassthroughModule extends Module with AbstractPassthroughModule
+class PassthroughMultiIOModule extends MultiIOModule with AbstractPassthroughModule
+class PassthroughRawModule extends RawModule with AbstractPassthroughModule
+
+
diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala
index 08b9cdf5..bf25ed82 100644
--- a/src/test/scala/chiselTests/Vec.scala
+++ b/src/test/scala/chiselTests/Vec.scala
@@ -3,6 +3,7 @@
package chiselTests
import chisel3._
+import chisel3.experimental.RawModule
import chisel3.core.Binding.BindingException
import chisel3.testers.BasicTester
import chisel3.util._
@@ -153,16 +154,6 @@ class ZeroEntryVecTester extends BasicTester {
stop()
}
-class PassthroughModuleIO extends Bundle {
- val in = Input(UInt(32.W))
- val out = Output(UInt(32.W))
-}
-
-class PassthroughModule extends Module {
- val io = IO(new PassthroughModuleIO)
- io.out := io.in
-}
-
class PassthroughModuleTester extends Module {
val io = IO(Flipped(new PassthroughModuleIO))
// This drives the input of a PassthroughModule
diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala
index 3bd63831..a1a7afb7 100644
--- a/src/test/scala/chiselTests/When.scala
+++ b/src/test/scala/chiselTests/When.scala
@@ -76,6 +76,23 @@ class NoOtherwiseOverlappedWhenTester() extends BasicTester {
}
}
+class SubmoduleWhenTester extends BasicTester {
+ val (cycle, done) = Counter(true.B, 3)
+ when (done) { stop() }
+ val children = Seq(Module(new PassthroughModule),
+ Module(new PassthroughMultiIOModule),
+ Module(new PassthroughRawModule))
+ children.foreach { child =>
+ when (cycle === 1.U) {
+ child.io.in := "hdeadbeef".U
+ assert(child.io.out === "hdeadbeef".U)
+ } .otherwise {
+ child.io.in := "h0badcad0".U
+ assert(child.io.out === "h0badcad0".U)
+ }
+ }
+}
+
class WhenSpec extends ChiselFlatSpec {
"When, elsewhen, and otherwise with orthogonal conditions" should "work" in {
assertTesterPasses{ new WhenTester }
@@ -86,4 +103,7 @@ class WhenSpec extends ChiselFlatSpec {
"When and elsewhen without otherwise with overlapped conditions" should "work" in {
assertTesterPasses{ new NoOtherwiseOverlappedWhenTester }
}
+ "Conditional connections to submodule ports" should "be handled properly" in {
+ assertTesterPasses(new SubmoduleWhenTester)
+ }
}