summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala4
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala2
-rw-r--r--src/main/scala/chisel3/internal/firrtl/Emitter.scala20
-rw-r--r--src/test/resources/chisel3/BlackBoxTest.v7
-rw-r--r--src/test/scala/chiselTests/BlackBox.scala20
-rw-r--r--src/test/scala/chiselTests/Direction.scala10
7 files changed, 56 insertions, 9 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
index 6d8e85a4..410f8cb4 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
@@ -75,7 +75,7 @@ abstract class ExtModule(val params: Map[String, Param] = Map.empty[String, Para
}
val firrtlPorts = getModulePorts map {port => Port(port, port.userDirection)}
- val component = DefBlackBox(this, name, firrtlPorts, params)
+ val component = DefBlackBox(this, name, firrtlPorts, UserDirection.Unspecified, params)
_component = Some(component)
component
}
@@ -160,7 +160,7 @@ abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param
}
val firrtlPorts = namedPorts map {namedPort => Port(namedPort._2, namedPort._2.userDirection)}
- val component = DefBlackBox(this, name, firrtlPorts, params)
+ val component = DefBlackBox(this, name, firrtlPorts, io.userDirection, params)
_component = Some(component)
component
}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index 41e09a5b..74e41895 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -19,7 +19,7 @@ object UserDirection {
/** Node and its children are forced as output
*/
case object Output extends UserDirection
- /** Node and ites children are forced as inputs
+ /** Node and its children are forced as inputs
*/
case object Input extends UserDirection
/** Mainly for containers, children are flipped.
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
index cca368ef..6e18792c 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -274,6 +274,6 @@ abstract class Component extends Arg {
def ports: Seq[Port]
}
case class DefModule(id: UserModule, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
-case class DefBlackBox(id: BaseBlackBox, name: String, ports: Seq[Port], params: Map[String, Param]) extends Component
+case class DefBlackBox(id: BaseBlackBox, name: String, ports: Seq[Port], topDir: UserDirection, params: Map[String, Param]) extends Component
case class Circuit(name: String, components: Seq[Component], annotations: Seq[Annotation] = Seq.empty)
diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
index 593052c7..c7a7f6a4 100644
--- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala
+++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala
@@ -13,12 +13,17 @@ private[chisel3] object Emitter {
private class Emitter(circuit: Circuit) {
override def toString: String = res.toString
- private def emitPort(e: Port): String = {
- val dir = e.dir match {
+ private def emitPort(e: Port, topDir: UserDirection=UserDirection.Unspecified): String = {
+ val resolvedDir = UserDirection.fromParent(topDir, e.dir)
+ val dirString = resolvedDir match {
case UserDirection.Unspecified | UserDirection.Output => "output"
case UserDirection.Flip | UserDirection.Input => "input"
}
- s"$dir ${e.id.getRef.name} : ${emitType(e.id)}"
+ val clearDir = resolvedDir match {
+ case UserDirection.Input | UserDirection.Output => true
+ case UserDirection.Unspecified | UserDirection.Flip => false
+ }
+ s"$dirString ${e.id.getRef.name} : ${emitType(e.id, clearDir)}"
}
private def emitType(d: Data, clearDir: Boolean = false): String = d match {
@@ -101,8 +106,13 @@ private class Emitter(circuit: Circuit) {
private def moduleDefn(m: Component): String = {
val body = new StringBuilder
withIndent {
- for (p <- m.ports)
- body ++= newline + emitPort(p)
+ for (p <- m.ports) {
+ val portDef = m match {
+ case bb: DefBlackBox => emitPort(p, bb.topDir)
+ case mod: DefModule => emitPort(p)
+ }
+ body ++= newline + portDef
+ }
body ++= newline
m match {
diff --git a/src/test/resources/chisel3/BlackBoxTest.v b/src/test/resources/chisel3/BlackBoxTest.v
index f88fb4ee..234d3a93 100644
--- a/src/test/resources/chisel3/BlackBoxTest.v
+++ b/src/test/resources/chisel3/BlackBoxTest.v
@@ -12,6 +12,13 @@ module BlackBoxPassthrough(
assign out = in;
endmodule
+module BlackBoxPassthrough2(
+ input [0:0] in,
+ output [0:0] out
+);
+ assign out = in;
+endmodule
+
module BlackBoxMinus(
input [15:0] in1,
input [15:0] in2,
diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala
index 983039c5..27895a54 100644
--- a/src/test/scala/chiselTests/BlackBox.scala
+++ b/src/test/scala/chiselTests/BlackBox.scala
@@ -25,6 +25,14 @@ class BlackBoxPassthrough extends BlackBox {
})
}
+// Test Flip on top-level IO
+class BlackBoxPassthrough2 extends BlackBox {
+ val io = IO(Flipped(new Bundle() {
+ val in = Output(Bool())
+ val out = Input(Bool())
+ }))
+}
+
class BlackBoxRegister extends BlackBox {
val io = IO(new Bundle() {
val clock = Input(Clock())
@@ -45,6 +53,14 @@ class BlackBoxTester extends BasicTester {
stop()
}
+class BlackBoxFlipTester extends BasicTester {
+ val blackBox = Module(new BlackBoxPassthrough2)
+
+ blackBox.io.in := 1.U
+ assert(blackBox.io.out === 1.U)
+ stop()
+}
+
/** Instantiate multiple BlackBoxes with similar interfaces but different
* functionality. Used to detect failures in BlackBox naming and module
* deduplication.
@@ -140,6 +156,10 @@ class BlackBoxSpec extends ChiselFlatSpec {
assertTesterPasses({ new BlackBoxTester },
Seq("/chisel3/BlackBoxTest.v"))
}
+ "A BlackBoxed with flipped IO" should "work" in {
+ assertTesterPasses({ new BlackBoxFlipTester },
+ Seq("/chisel3/BlackBoxTest.v"))
+ }
"Multiple BlackBoxes" should "work" in {
assertTesterPasses({ new MultiBlackBoxTester },
Seq("/chisel3/BlackBoxTest.v"))
diff --git a/src/test/scala/chiselTests/Direction.scala b/src/test/scala/chiselTests/Direction.scala
index 9b353840..49d0ab77 100644
--- a/src/test/scala/chiselTests/Direction.scala
+++ b/src/test/scala/chiselTests/Direction.scala
@@ -36,6 +36,12 @@ class BadSubDirection extends DirectionHaver {
io.inBundle.out := 0.U
}
+class TopDirectionOutput extends Module {
+ val io = IO(Output(new DirectionedBundle))
+ io.in := 42.U
+ io.out := 117.U
+}
+
class DirectionSpec extends ChiselPropSpec with Matchers {
//TODO: In Chisel3 these are actually FIRRTL errors. Remove from tests?
@@ -52,4 +58,8 @@ class DirectionSpec extends ChiselPropSpec with Matchers {
elaborate(new BadSubDirection)
}
}
+
+ property("Top-level forced outputs should be assignable") {
+ elaborate(new TopDirectionOutput)
+ }
}