From 24492361da393a5b4d3e023b6511693125f4f254 Mon Sep 17 00:00:00 2001 From: Stephen Twigg Date: Tue, 26 Apr 2016 19:39:18 -0700 Subject: Rewrite BlackBox IO contract, replace _clock|_reset The old blackbox behavior still emitted extmodules that have a clk, reset pin and prepended all io's with io_ (ultimately). Most verilog modules do not follow this distinction (or use a slightly different name for clock and so on). Thus, instead BlackBox has been rewritten to not assume a clk or reset pin. Instead, the io Bundle specified is flattened directly into the Module.ports declaration. The tests have been rewritten to compensate for this. Also, added a test that uses the clock pin. As a secondary change, the _clock and _reset module parameters were bad for two reasons. One, they used null as a default, which is a scala best practices violation. Two, they were just not good names. Instead the primary constructor has been rewritten to take an Option[Clock] called override_clock and an Option[Bool] called override_reset, which default to None. (Note how the getOrElse call down below is much more natural now.) However, users may not want to specify the Some(their_clock) so I also added secondary constructors that take parameters named clock and reset and wrap them into Some calls into the primary constructor. This is a better UX because now you can just stipulate clock=blah in instantiation of that module in symmetry with using the clock in the definition of the module by invoking clock. PS: We could also back out of allowing any overrides via the Module constructor and just require the instantiating Module to do submodule.clock := newclock, etc. --- src/main/scala/Chisel/Module.scala | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'src/main/scala/Chisel/Module.scala') diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala index cfcf5a48..738863e3 100644 --- a/src/main/scala/Chisel/Module.scala +++ b/src/main/scala/Chisel/Module.scala @@ -25,8 +25,7 @@ object Module { val ports = m.computePorts Builder.components += Component(m, m.name, ports, m._commands) pushCommand(DefInstance(m, ports)) - pushCommand(DefInvalid(m.io.ref)) // init instance inputs - m.connectImplicitIOs() + m.setupInParent() } } @@ -36,8 +35,14 @@ object Module { * * @note Module instantiations must be wrapped in a Module() call. */ -abstract class Module(_clock: Clock = null, _reset: Bool = null) extends HasId { - private val _namespace = Builder.globalNamespace.child +abstract class Module( + override_clock: Option[Clock]=None, override_reset: Option[Bool]=None) +extends HasId { + def this(clock: Clock) = this(Some(clock), None) + def this(reset: Bool) = this(None, Some(reset)) + def this(clock: Clock, reset: Bool) = this(Some(clock), Some(reset)) + + private[Chisel] val _namespace = Builder.globalNamespace.child private[Chisel] val _commands = ArrayBuffer[Command]() private[Chisel] val _ids = ArrayBuffer[HasId]() dynamicContext.currentModule = Some(this) @@ -54,27 +59,29 @@ abstract class Module(_clock: Clock = null, _reset: Bool = null) extends HasId { private[Chisel] def addId(d: HasId) { _ids += d } - private def ports = (clock, "clk") :: (reset, "reset") :: (io, "io") :: Nil + private[Chisel] def ports: Seq[(String,Data)] = Vector( + ("clk", clock), ("reset", reset), ("io", io) + ) - private[Chisel] def computePorts = ports map { case (port, name) => + private[Chisel] def computePorts = for((name, port) <- ports) yield { val bundleDir = if (port.isFlip) INPUT else OUTPUT Port(port, if (port.dir == NO_DIR) bundleDir else port.dir) } - private def connectImplicitIOs(): this.type = _parent match { - case Some(p) => - clock := (if (_clock eq null) p.clock else _clock) - reset := (if (_reset eq null) p.reset else _reset) + private[Chisel] def setupInParent(): this.type = _parent match { + case Some(p) => { + pushCommand(DefInvalid(io.ref)) // init instance inputs + clock := override_clock.getOrElse(p.clock) + reset := override_reset.getOrElse(p.reset) this + } case None => this } - private def makeImplicitIOs(): Unit = ports map { case (port, name) => - } - - private def setRefs(): this.type = { - for ((port, name) <- ports) + private[Chisel] def setRefs(): this.type = { + for ((name, port) <- ports) { port.setRef(ModuleIO(this, _namespace.name(name))) + } // Suggest names to nodes using runtime reflection val valNames = HashSet[String](getClass.getDeclaredFields.map(_.getName):_*) -- cgit v1.2.3