diff options
| author | Andrew Waterman | 2015-10-26 19:07:17 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2015-10-26 19:07:17 -0700 |
| commit | 69f41d6892549ef59a3c21cb05d355ea7523c5a2 (patch) | |
| tree | 56f5811215013cc27e66298da9c71099cd6a86e0 /src/main/scala/Chisel/Module.scala | |
| parent | 1b376ed6de722ffe8c3e533e4bf5d964639242e7 (diff) | |
| parent | 4b51975ec7a543e165660d654fa84eaa9b9b3b3e (diff) | |
Merge pull request #39 from ucb-bar/coresplit
Break Core.scala into bite-sized pieces
Diffstat (limited to 'src/main/scala/Chisel/Module.scala')
| -rw-r--r-- | src/main/scala/Chisel/Module.scala | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/main/scala/Chisel/Module.scala b/src/main/scala/Chisel/Module.scala new file mode 100644 index 00000000..1c1c02de --- /dev/null +++ b/src/main/scala/Chisel/Module.scala @@ -0,0 +1,108 @@ +// See LICENSE for license details. + +package Chisel +import scala.collection.mutable.{ArrayBuffer, HashSet} +import Builder.pushCommand +import Builder.dynamicContext + +object Module { + // TODO: update documentation when parameters gets removed from core Chisel + // and this gets simplified. + /** A wrapper method that all Module instantiations must be wrapped in + * (necessary to help Chisel track internal state). + * + * @param m the Module being created + * @param p Parameters passed down implicitly from that it is created in + * + * @return the input module `m` + */ + def apply[T <: Module](bc: => T)(implicit currParams: Parameters = Builder.getParams.push): T = { + paramsScope(currParams) { + val parent = dynamicContext.currentModule + val m = bc.setRefs() + // init module outputs + m._commands prependAll (for (p <- m.io.flatten; if p.dir == OUTPUT) + yield Connect(p.lref, p.fromInt(0).ref)) + dynamicContext.currentModule = parent + val ports = m.computePorts + Builder.components += Component(m, m.name, ports, m._commands) + pushCommand(DefInstance(m, ports)) + // init instance inputs + for (p <- m.io.flatten; if p.dir == INPUT) + p := p.fromInt(0) + m + }.connectImplicitIOs() + } + + //TODO @deprecated("Use Chisel.paramsScope object","08-01-2015") + def apply[T <: Module](m: => T, f: PartialFunction[Any,Any]): T = { + apply(m)(Builder.getParams.alterPartial(f)) + } +} + +/** Abstract base class for Modules, which behave much like Verilog modules. + * These may contain both logic and state which are written in the Module + * body (constructor). + * + * @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 + private[Chisel] val _commands = ArrayBuffer[Command]() + private[Chisel] val _ids = ArrayBuffer[HasId]() + dynamicContext.currentModule = Some(this) + + /** Name of the instance. */ + val name = Builder.globalNamespace.name(getClass.getName.split('.').last) + + /** IO for this Module. At the Scala level (pre-FIRRTL transformations), + * connections in and out of a Module may only go through `io` elements. + */ + def io: Bundle + val clock = Clock(INPUT) + val reset = Bool(INPUT) + + private[Chisel] def addId(d: HasId) { _ids += d } + private[Chisel] def ref = Builder.globalRefMap(this) + private[Chisel] def lref = ref + + private def ports = (clock, "clock") :: (reset, "reset") :: (io, "io") :: Nil + + private[Chisel] def computePorts = ports map { case (port, name) => + 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) + this + case None => this + } + + private def makeImplicitIOs(): Unit = ports map { case (port, name) => + } + + private def setRefs(): this.type = { + for ((port, name) <- ports) + port.setRef(ModuleIO(this, _namespace.name(name))) + + val valNames = HashSet[String](getClass.getDeclaredFields.map(_.getName):_*) + def isPublicVal(m: java.lang.reflect.Method) = + m.getParameterTypes.isEmpty && valNames.contains(m.getName) + val methods = getClass.getMethods.sortWith(_.getName > _.getName) + for (m <- methods; if isPublicVal(m)) m.invoke(this) match { + case id: HasId => id.setRef(_namespace.name(m.getName)) + case _ => + } + + _ids.foreach(_.setRef(_namespace.name("T"))) + _ids.foreach(_._onModuleClose) + this + } + + // TODO: actually implement these + def assert(cond: Bool, msg: String): Unit = {} + def printf(message: String, args: Bits*): Unit = {} +} |
