棋子 · 6月4日

Verilog代码设计之时分复用

做芯片第一要追求的是功能,在保证功能都满足的情况下追求性能,在性能满足的情况下追求成本,也就是面积。当然功耗也十分重要。

提高速度和降低面积属于两个矛盾的目标,各自努力的方向基本相反,想要更快的运行速度,就得堆更多的资源,在具体的设计中往往需要折中(Trade off)。

在性能允许条件下采用时分复用更多的逻辑来减少芯片的面积,面积及成本。

加比选

通常情况下面积关系为加法器 > 比较器 > 选择器,乘法器可以认为是多个加法器。

所以就有先选后比,先选后加,先选后乘。

assign sum[4:0] = enable ? (data_a + data_b) : (data_c + data_d);

assign add_a[3:0] = enable ? data_a : data_c;
assign add_b[3:0] = enable ? data_b : data_d;
assign sum[4:0]   = add_a + add_b;

image.png

画个图意思一下。

image.png

图中的加法器可以替换成,比较器,乘法器,一个运算单元,甚至巨大的一个模块。

乘法器时分复用

在计算模块中乘法器也是非常大的一部分逻辑,一个设计要考虑PPA最优,一个必须要考虑乘法器的数量多少以及复用能不能最大化,追求最好的设计是整个数据通路中乘法器空闲不下来。

通常的设计是做一个专门的乘法器模块,按系统最大的位宽开辟乘法器位宽逻辑,根据设计流程最大程度上复用乘法器资源。

image.png

每一路乘法配备一个vld,用vld来作为当前有效的乘法运算,乘法器的结果随着vld的下一拍进行锁存。从下图可以看出乘法器的复用需要将各个部分的运算时间区分开,不可避免系统的时间会变长,想要缩短时间则可以用更多的乘法器来大幅缩短时间,想要面积更小,则用更少的乘法器资源来时分复用。面积与速度互换思想核心。

image.png

always @(*)begin
if(mult0_vld)
    mult_a[3:0] = mult_a0;
else if(mult1_vld)
    mult_a[3:0] = mult_a1;
else // if(mult2_vld)
    mult_a[3:0] = mult_a2;
end

第二种选择器写法

assign mult_a[3:0] = ({4{mult0_vld}} & mult_a0)
            | ({4{mult1_vld}} & mult_a1)
            | ({4{mult2_vld}} & mult_a2)

第二种写法需要保证vld条件不会同时有效,看上去只用了一些门实现,而且没有优先级,感觉比第一种写法逻辑少,但实际上经过工具的优化后,可能消耗逻辑差不多。但是第二种写法在综合后就会是你写的这个样子,而第一种则会综合成一堆组合逻辑门。对于ECO来说,第二种写法更友好,第一种复杂多了。

而我更喜欢第一种写法,因为第一种在收集覆盖率时会更友好。代码覆盖率会清楚的看到哪一行没跑到,条件覆盖率也比较简单。每个if里面就一个条件。

乘法器调用方法,一般是在乘法器的输入保证寄存器输入,结果输出到各个复用模块时打一拍再使用。可以做成在进行完乘法运算后再打拍,这样消耗的寄存器会少很多。画个图意思一下(单bit)。

image.png

修改完后的寄存器省了很多,但是乘法器的输出寄存器负载会变大,不过后端综合时约束了max_fan_out工具会自动插buffer和复制寄存器,经过实测还是会节省很多面积。不过这是在时序较好的情况下,如果时序比较紧,这样插多余的buffer会导致时序过不了。

RAM的复用

大于1k的寄存器组使用,考虑用RAM替代,但用RAM读写数据需要时序控制逻辑,并行度会降低。要求并行度高,可使用多个RAM。

image.png

从设计的整体来看,RAM也可以复用,前面处理完空闲下来的ram,后面处理也可以使用。

真的要这么多的复用吗?

复用可以是各种的,从单个逻辑运算到一个巨大的IP。那么真的要这么多的复用吗?前面说的复用必然需要分时,所以会导致系统处理时间变长,所以必须在保证处理性能的前提下通过复用来减少面积。

在控制通路上,大大小小的计数器会有很多个,理论上一些计数器也可以复用,但是共用一个计数器意味着,这个计数器的开始和结束逻辑复杂,而到了调试(debug)阶段,必然会是调试变得复杂繁琐。

一个加法器如果要复用的数据比较多,除了是debug看起来复杂之外,增加的选择器逻辑可能也不一定会小。

两个独立的模块中有部分相同的逻辑,是否真的有必要在提高了复杂度和模块之间的耦合度的情况下去复用,这也需要考虑。

到了项目后期一个小改动也是需要回归测试所有的测试用例,为了一小点减少逻辑而付出相对巨大的工作量从而影响进度,总的来说获得的边际收益是非常小的。

所以复用虽好,但也要适时、适度。

作者:硅农
文章来源:硅农

推荐阅读

更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。

推荐阅读
关注数
19639
内容数
1303
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息