如何在C代码中插入寄存器?

描述

对于逻辑级数较高的路径,常用的方法之一是在其中插入流水寄存器,将路径打断,从而降低逻辑延迟,这在HDL代码中实现起来比较容易。此外,从RTL代码风格角度讲,对于关键模块,设计时常将其输入/输出端口寄存。这起到了隔离关键路径的作用。

但是,如果使用的RTL代码是HLS转换生成的,例如使用Vitis HLS综合的,其可读性较差,想要在其生成的HDL代码中插入寄存器就变得比较困难。为此,我们想到了能否在C代码中插入寄存器,并保证Vitis HLS综合后的结果是寄存器。

这要解决四个问题:一是这样的C代码要具备一定的可复用性,比如,以模板函数的形式呈现。二是这样的C代码是参数化的,尤其是数据类型,因为需要寄存的数据其数据类型不尽相同。这仍然可以借助模板函数实现。三是保证这个函数不被优化合并掉。因为这个函数功能比较单一,输出等于输入,这就要用到INLINE的功能。四是C语言是不具备时序特征的,要实现输出与输入的延迟,就要借助相应的pragma,我们想到了Latency。

在此基础上,我们构造了下面的C++代码。不难看出,这是一个模板函数,数据类型是参数化的,使用了三个pragma。其中PIPELINE用于限定II为1,LATENCY用于限定延迟为1,INLINE用于防止该函数被合并。

寄存器

看一个具体的使用案例,如下图所示代码。功能很简单,就是实现两个数的相加。这里对两个输入数据a和b分别做了寄存,同时对结果c也做了寄存。最终的综合报告显示Latency为2,和我们预期的一致。对于生成的HDL代码,将其添加到Vivado中进行综合,综合后的结果也是符合预期的。

寄存器

 

寄存器

这里,我们对比一下三种情形。情形1:不添加流水寄存器;情形2:仅对输出添加流水寄存器;情形3:输入输出均添加流水寄存器。Vitis HLS综合结果以及其生成的HDL代码在Vivado下的综合结果对比如下图所示。首先,可以看到Latency符合预期,同时II始终为1;其次,Vivado下综合后的资源利用率与Vitis HLS的结果是不一致的。这一点也很容易理解,因为Vivado综合时会有很多优化。

寄存器

进一步,我们看到这里的延迟为1,如果需要两级延迟,就要两次调用模板函数。能否将延迟的时钟周期也设置成参数呢?答案是肯定的,如下图代码所示。这里定义了L,用来管理延迟的时钟周期个数,对应pragma Latency的min和max值。

寄存器

 

寄存器

 

 

原文标题:在C代码中插入寄存器

文章出处:【微信公众号:Lauren的FPGA】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分