在我们编写Verilog或者SysytemVerilog时,我们的代码基本都以module来进行组织,而针对一些比较通用的模块组件,我们或组织成一个单独的model,或者放在一个function中(仅限于纯组合逻辑)。
Area
在SpinalHDKL里,与Verilog、SystemVerilog中相对应的概念是Component,当我们的类继承了Component后,与之相应的我们就要定义端口及参数。以我们上篇所提到的例子,我们在例化一个加法器模块时从初阶、到中阶再到高阶,我们仍避免不了连线的话题,只不过是在伴生对象中做了一次封装从而一劳永逸。
为了解决过于细致的模块划分(不断的端口连线)及兼顾代码尽可能复用的准则,SpinalHDL里设计了Area的概念。通过类扩展集成Area,可以有效的避免上述问题。介绍Area之前,先介绍一个概念:
在Scala中,参数的传递均为引用类型,而我们定义的电路对象本身也是一个scala类的实例化对象,作为类的参数传递在类中是可以直接定义电路对象的动作的。
有了Area概念的引入,《SpinalHDL—像软件调用方法般例化模块》中所用到的加法器我们可以这么来定义:
这里我们定义了一个addArea类,其继承了Area,电路对象sumPort作为类的一个参数来传递,在类的实现里,我们实现了对加法器的实现。这种方式我们无需定义伴生对象(object)便可以方便的实现加法器单元的例化:
而生成的SystemVerilog代码如下所示:
可以看到,继承了Area的类在例化时对应的RTL代码也是没有对应的module分层的。
Area“副作用”
Area除了可以用于将通用代码从Component中抽取出来的用处之外其另外一个特性便是我们可以在我们的Component代码实现里将我们的代码按模块放置在Area里进行按功能分类,而在生成Verilog时我们定义在Area中的变量也会加上Area的前缀,如此我们可以在仿真或上板抓线时方便的进行信号提取。如下代码:
其生成的RTL代码如下所示:
可以看到,我们定义的register寄存器在RTL代码中加上了Area名前缀cntArea。
原作者: 玉骐
更多回帖