https://mp.weixin.qq.com/s/9PsBt4_4qHx4i6C5XtuiUw
介绍LazyModule和Node构造方法的执行过程,即实例化过程。
1. NullIntSource
以NullIntSource为例,将其作为顶层的LazyModule考虑:
2. 实例化过程
1) 执行NullIntSource的构造方法,首先要逐层向上执行各个父类的构造方法;
a. 最开始执行LazyModule类的构造方法:用于构造LazyModule层级结构的是:LazyModule.scope = Some(this)。之后再添加的LazyModule都会加入到这个scope中。
b. 把本LazyModule加入到父LazyModule中:
因为这里把NullIntSource作为顶层LazyModule,所以parent为None,不执行实际添加。
c. 执行NullIntSource的构造方法,创建intnode节点;
其中首先执行BaseNode的构造方法,把当前节点加入到LazyModule.scope中:
d. 定义lazy val module:
intnode是一个source节点,没有输入只有输出。module的实现中默认让intnode.out输出0。
3. 总结
a. LazyModule提供一个框架,以容纳内部LazyModule和节点,即实现模块层次结构(hierarchy);
b. LazyModuleImp实现LazyModule的逻辑(其中为内部模块提供连接);
c. Node为LazyModule提供参数协商支持,而后提供输入输出连接;不能嵌套,也没有内部逻辑;
4. 附录
NullIntSource.scala:
// See LICENSE.SiFive for license details.
package freechips.rocketchip.interrupts
import Chisel._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
/** Useful for stubbing out parts of an interrupt interface where certain devices might be missing */
class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters) extends LazyModule
{
val intnode = IntSourceNode(IntSourcePortSimple(num, ports, sources))
lazy val module = new LazyModuleImp(this) {
intnode.out.foreach { case (o, _) => o.foreach { _ := false.B } }
}
}
object NullIntSource {
def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntNode = {
val null_int_source = LazyModule(new NullIntSource(num, ports, sources))
null_int_source.intnode
}
}