本文主要是介绍IC验证【管中窥豹集】听到“对齐”这两个字你能想到什么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我们在做项目过程中,常常听到“对齐”这个词,“对齐”简单理解就是某个量值可以被某个颗粒度整除。
例如:“把首地址按照32byte对齐”,意思就是首地址的值需要能被32byte整除。
“把图像宽度按照16byte对齐”,意思就是图像宽度的值需要能被16byte整除。
但是我们常遇到各种“对齐”,诸如地址怎么样对齐、图像尺寸怎么样对齐等等。
这些都是什么意思?
为什么要对齐,对齐有什么好处?
验证者应该怎么对待对齐这个事情?
对齐的约束可以怎么写?
今天我们就一起聊聊~
1、和ddr打交道的地址对齐
大量的IP都需要与DDR做数据交互,所以很多时候,地址对齐的需求是来自DDR的。合理的地址对齐,可以提高ddr的访问效率。具体怎么地址对齐?这与ddr的结构是强相关的,不同的ddr结构和性质对地址对齐的要求不一样。
我们举一个简单的原理性的例子,示意一下为什么地址对齐提高ddr的访问效率:
假设一个ddr简化结构如下图,4个bank,每个bank上有一个个的内存颗粒,每个颗粒只能存1byte。
如果你要和它交互的数据宽度是4byte,按照ddr的操作规则,这4个byte一次操作不是全存在某一个bank中,而是同时存到每个bank对应相同的ddr颗粒的位置上,4个bank在相同位置上各取1byte拼起来刚好是4byte。也就是ddr一次操作只能如下图的蓝色线存地址编号0、1、2、3,每个位置读写一个byte。亦或如图中绿色线存到地址编号4、5、6、7,每个位置存一个byte。
我们看到一次访问ddr的颗粒度是4byte,所以高效率的做法就是要求访问ddr的首地址4byte对齐,即例如0、4、8这样的地址为访问起始地址。假如我们偏不对齐,从下图中的1地址读取一个数,又能怎样?
按照上面的分析,ddr会第一次访问如下图蓝色的线,取出0、1、2、3上的地址,然后保留下1、2、3地址上的数,再进行绿色的线的访问,取出4、5、6、7,保留4地址上的数。综合两次访问拼出1、2、3、4地址上的byte成一个数给你。要是你的起始地址为0的话,一次访问0,1,2,3就返回回去了,效率明显更高,一次搬家能搬完的事情为什么要搬2次呢?
当然这里只是一个最简单的原理举例,实际ddr再加上如多通道、交织等结构,更高效率的对齐要求又不一样了。
2、和cache打交道的地址对齐
对于处理器类,大概率需要和cache打交道,那就涉及访问cache的地址对齐,以提高cache的访问效率。
Jerry还是画一个简单cache结构的案例,如下图是一个2way组相连的小cache。这个cache有4个set、每个set里有2条cacheline,假设每个cacheline里有4个byte。
我们以cpu固定4byte访问为例,这种情况若cpu访问cache的地址以cacheline为颗粒度对齐,那么说明访问的数据都在同一条cacheline上,只需要访问一次cacheline即可,但是若不对齐,就说明cpu访问的数据横跨2条cacheline ,需要访问2次cacheline。这样明显效率低于对齐,如果运气不好这两条cacheline都没有命中,那就更是雪上加霜效率低下了。
3、图像宽度的对齐
对于图像相关的设计,图像分辨率也是有规定的,不是随便定的,这里会涉及图像尺寸的对齐。
因图像宽度对齐的原因相对较通用,高度对齐方式与具体设计关联更为紧密,所以我们仅以图像宽度为例简单聊聊。
图像数据一般通过总线传输,所以宽度对齐常常依赖总线传输的颗粒度,即图像宽度常常需要和总线传输的颗粒度对齐。
还是举一个最简单粗暴的例子,假设某个总线每拍传输颗粒度固定128bit(即16byte)。这个时候有一张奇葩图的尺寸是:只有一行,且这一行的宽度是40byte。
注意40byte是除不尽总线传输颗粒度16byte的,那就说明没有对齐。这种场景就如同下图,灰色代表总线传输的颗粒度,绿色代表这个图像的数据,我们可以直观看到,在最后一个16byte的时候,总线没有“用满”的,也可以叫“有气泡”。这种就会减少传输效率,甚至增加控制难度。
4、AXI相关的对齐
AXI总线应用广泛,提到AXI总线,我们常常想到所谓“4K对齐”以及不要”跨4K“,我们顺着今天的主题也来一嘴。
4K对齐指的是谁呢?4K其实是4Kbyte(下文也简称4KB),指的是AXI的slave的首地址的对齐颗粒度。
为什么是4KB呢?有一种说法是:操作系统以页为单位管理内存,因为历史原因通常默认一页大小为4KB,所以就给AXI slave划分4KB空间。
不管这里是怎么由来,反正AXI协议就如此规定了,我们更需要了解下这个slave地址4KB对齐之后意味着什么?
以上图为例,一个axi master控制两个4KB地址空间的axi slave。
我们知道,不论读写,AXI master访问数据需要先在地址通道发一个起始地址,这个起始地址在哪个slave范围就给谁发,然后基于这个起始地址,读写一系列burst数据。
如果这“一系列burst数据”全在某一个slave的4KB空间里,没有任何问题,但是如果这“一系列burst数据”超出了这个slave的4KB空间,跑到了下一个slave的4KB范围里去了,这个就有问题了。
什么问题?你的master发地址的时候我们查了你的首地址在slave0中,所以我们就让你和slave0握手交互数据,你要交互一系列burst数据,这个burst数据基于你的起始地址,前面几个数还可以比较守规矩,后面突然要操作slave1的地址范围,这slave1必然一脸懵逼,因为它都没有收到master给的地址命令,master把唯一的命令给了slave0!
这种尴尬场景就叫做AXI的跨4KB边界问题,跨4KB在burst传输场景才会出现。(当然实现时可以在接口控制处做跨4KB的拆分,自动的把给1个slave的非法交易分成给2个slave的合法交易)
怎么从地址判断是否跨4KB,或者对AXI burst传输还比较陌生的初学者,可以参考下之前的系列文章《AXI总线,关于“交易”“火车”“马匪”的故事〈二〉》
5、验证怎么看待对齐?
前面举例了很多个“对齐”,合适的对齐可以增加RTL的执行效率提高性能,让电路跑的“更爽更开心”。验证应该怎么看待这些对齐需求呢?
一定要注意!“让电路跑的更爽更开心”是在芯片实际使用的时候我们期望看到的,而验证的时候我们就是去尽量找茬的!
如果有一天,RTL告诉你说他256byte对齐更爽,但你作为验证要恪守你的底线:除非spec明确说这个DUT在应用场景上百分之一亿是256B对齐,或者如果不256B对齐RTL直接不支持会出错,否则,验证的时候应该以RTL可以支持的最小对齐方式对齐展开验证,而不是RTL最高效的对齐方式!例如前面讲的DDR的例子,期望4byte对齐效率更高性能更好,但是只是效率更高而已,没对齐又不会错!所以我们验证时候没必要约束4byte对齐,直接以byte对齐即可。
6、对齐怎么写
我们今天聊了这么多“对齐”,这个“对齐”的约束或计算怎么实现?Jerry列出几种仅供参考:
假设我们待对齐的数命名为:orign_addr
对齐后的数命名为:aligned_addr
对齐的颗粒度命名为:number_bytes
方法一:AXI协议中常用方式
aligned_addr=(INT(orign_addr/number_bytes))*number_bytes
此处的INT为向下取整之意,SystemVerilog的写法:orign_addr/number_bytes本身就默认向下取整。
除此之外,向下取整还可以显性使用系统函数$floor()、或者通过其他的计算方式实现。
方法二:移位方式
aligned_addr= (orign_addr>>number_bytes的比特数)<<number_bytes的比特数;
方法三:按位与抹零
aligned_addr=orign_addr&‘hffff00;
f后0的byte数为number_bytes
方法四:constraint中粗暴位操作
例如number_bytes是16B对齐,
aligned_addr[15:0]==0;
aligned_addr…的其他约束
方法五:constraint中粗暴余数公式
例如number_bytes是16B对齐,
aligned_addr%16==0;
结语
时光如水,今天我们始于“对齐”的含义,探索了若干种RTL对齐的原因,思考了验证应该如何看待对齐,最后给出了对齐约束的几种具体实现。
对于对齐一定还有很多细节值得探讨和咀嚼,就让我们一起在验证之路上慢慢体会吧。
祝大家越来越牛逼!加油!
欢迎关注同名公 ~ 众 ~ 号
这篇关于IC验证【管中窥豹集】听到“对齐”这两个字你能想到什么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!