https://mp.weixin.qq.com/s/3uUIHW8DmisYARYmNzUZeg 介绍如何构建由模块组成的硬件模型。 1. 子模块 一个模块可以有一个或多个子模块,创建子模块时,需要使用Module(…)包裹: Module()实现如下: bc是一个call-by-name参数,在第一次引用时调用。 1) 在调用bc创建模块之前,先保存Builder的状态。a. Module()只能用于包裹一个模块的实例化操作: Builder.readyForModuleConstr在实例化模块之前被置为false: 这个要求模块的实例化必须在Module()以内。子模块在父模块中以Module()包裹实例化,顶层模块如何实例化呢?也需要以Module()包裹,后续再讲。 b. 记录当前Builder的状态信息,如当前的val parent = Builder.currentModule为将要实例化的模块的父模块: 2) 调用bc,创建子模块 子模块创建之初,会先要设置Builder的状态,如下注释中所言: 实际代码在BaseModule类体中: 3) 恢复Builder的状态 4) 把创建的模块,转换成为一个component如果父模块不为空,则使用pushCommand把新创建的模块以DefInstance命令添加到硬件模型中。 2. generateComponent a. 处理各模块名字;b. 定义ModuleIO;c. 将模块输入输出端口转换为component所需的Port;d. 定义component:val component = DefModule(this, name, firrtlPorts, invalidateCommands ++ getCommands) 3. 顶层模块 顶层模块也需要使用Module()包裹着创建。 如顶层模块Adder4的创建。其创建函数被传给chisel3.Driver.execute方法: 可以看到,这里调用gen()的时候,也包裹在Module()之中。 只是这里的Module(gen())也是一个call-by-name参数,并不是直接调用:这里的Builder即为之前多次提到的Builder。build方法返回顶层模块Circuit。