1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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 = {}
}
|