summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/Chisel/BlackBox.scala
diff options
context:
space:
mode:
Diffstat (limited to 'chiselFrontend/src/main/scala/Chisel/BlackBox.scala')
-rw-r--r--chiselFrontend/src/main/scala/Chisel/BlackBox.scala54
1 files changed, 54 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/Chisel/BlackBox.scala b/chiselFrontend/src/main/scala/Chisel/BlackBox.scala
new file mode 100644
index 00000000..be72934d
--- /dev/null
+++ b/chiselFrontend/src/main/scala/Chisel/BlackBox.scala
@@ -0,0 +1,54 @@
+// See LICENSE for license details.
+
+package Chisel
+
+import internal.Builder.pushCommand
+import internal.firrtl.{ModuleIO, DefInvalid}
+
+/** Defines a black box, which is a module that can be referenced from within
+ * Chisel, but is not defined in the emitted Verilog. Useful for connecting
+ * to RTL modules defined outside Chisel.
+ *
+ * @example
+ * {{{
+ * ... to be written once a spec is finalized ...
+ * }}}
+ */
+// REVIEW TODO: make Verilog parameters part of the constructor interface?
+abstract class BlackBox extends Module {
+ // Don't bother taking override_clock|reset, clock/reset locked out anyway
+ // TODO: actually implement this.
+ def setVerilogParameters(s: String): Unit = {}
+
+ // The body of a BlackBox is empty, the real logic happens in firrtl/Emitter.scala
+ // Bypass standard clock, reset, io port declaration by flattening io
+ // TODO(twigg): ? Really, overrides are bad, should extend BaseModule....
+ override private[Chisel] def ports = io.elements.toSeq
+
+ // Do not do reflective naming of internal signals, just name io
+ override private[Chisel] def setRefs(): this.type = {
+ for ((name, port) <- ports) {
+ port.setRef(ModuleIO(this, _namespace.name(name)))
+ }
+ // setRef is not called on the actual io.
+ // There is a risk of user improperly attempting to connect directly with io
+ // Long term solution will be to define BlackBox IO differently as part of
+ // it not descending from the (current) Module
+ this
+ }
+
+ // Don't setup clock, reset
+ // Cann't invalide io in one bunch, must invalidate each part separately
+ override private[Chisel] def setupInParent(): this.type = _parent match {
+ case Some(p) => {
+ // Just init instance inputs
+ for((_,port) <- ports) pushCommand(DefInvalid(port.ref))
+ this
+ }
+ case None => this
+ }
+
+ // Using null is horrible but these signals SHOULD NEVER be used:
+ override val clock = null
+ override val reset = null
+}