IC验证【管中窥豹集】听到“对齐”这两个字你能想到什么?

2024-02-20 23:10

本文主要是介绍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验证【管中窥豹集】听到“对齐”这两个字你能想到什么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/729826

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

easyui 验证下拉菜单select

validatebox.js中添加以下方法: selectRequired: {validator: function (value) {if (value == "" || value.indexOf('请选择') >= 0 || value.indexOf('全部') >= 0) {return false;}else {return true;}},message: '该下拉框为必选项'}

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹

列举你能想到的UNIX信号,并说明信号用途

信号是一种软中断,是一种处理异步事件的方法。一般来说,操作系统都支持许多信号。尤其是UNIX,比较重要应用程序一般都会处理信号。 UNIX定义了许多信号,比如SIGINT表示中断字符信号,也就是Ctrl+C的信号,SIGBUS表示硬件故障的信号;SIGCHLD表示子进程状态改变信号;SIGKILL表示终止程序运行的信号,等等。信号量编程是UNIX下非常重要的一种技术。 Unix信号量也可以

2024年AMC10美国数学竞赛倒计时两个月:吃透1250道真题和知识点(持续)

根据通知,2024年AMC10美国数学竞赛的报名还有两周,正式比赛还有两个月就要开始了。计划参赛的孩子们要记好时间,认真备考,最后冲刺再提高成绩。 那么如何备考2024年AMC10美国数学竞赛呢?做真题,吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。通过做真题,可以帮助孩子找到真实竞赛的感觉,而且更加贴近比赛的内容,可以通过真题查漏补缺,更有针对性的补齐知识的短板。

React 笔记 父子组件传值 | 父组件调用子组件数据 | defaultProps | propsType合法性验证

1.通过props实现父组件像子组件传值 、方法、甚至整个父组件 传递整个父组件则   [变量名]={this} import Header from "./Header"render(){return(<Header msg={"我是props传递的数据"}/>)} import React,{Component} from "react";class Header extends