https://mp.weixin.qq.com/s/_aJqf1cFJDK5RVRBhxTWOw

 
介绍MaskGen的实现。
 
 
1. 基本介绍
 
给定总线宽度beatBytes,根据访问的地址(address)和访问的字节数(bytes = 2^lgSize),生成访问字节的掩码。
 
2. 实现
 
思路不复杂,写法很难懂。重构一下,提高可读性。
 
1) 首先忽略groupBy,清爽很多:
 
2) 把addr_lo重命名为address,把lgSize重命名为size,这样可以很明显的看出来address/size是一对参数。把内部的局部变量size重命名为siz。
 
3) 把beatBytes重命名为width,同时把lgBytes重命名为lgWidth
 
4) log2Up与log2Ceil意义相同,且被废弃,使用log2Ceil替代。替代之后发现,无需重新计算,直接使用lgWidth即可:
 
5) nbit的命名挺别扭,既不符合RTL习惯(bit_n),也不符合软件习惯(有下滑波浪线提示)。因为只有一处使用,所以可以直接去掉,无需使用临时变量。
 
上面这些重构比较简单,基本上都是从形式上进行。
 
6) 把helper重命名为getMask
 
从apply的返回值看,helper的返回值即是最终生成的掩码,只是位序相反。所以把helper从中性无意义的名字,修改为getMask这一个表示用途的名称:
 
 
7) i的意义
 
helper是递归方法,i每次减一。
 
helper(0)返回1位掩码:1 = 2^0;
helper(1)返回2位掩码:2 = 2^1;
helper(2)返回4位掩码:4 = 2^2;
 
把helper(i)中的i从对数值,换成原值,参数i的意义就是要返回的掩码位数:helper(n),n为要返回的掩码的位数。
 
helper(1)返回1位掩码;
helper(2)返回2位掩码;
helper(4)返回4位掩码;
 
调整内部对n的使用:
a. 对数值减法换为原值的除法;
b. 判断对数值为0,等价于判断原值为1;
 
 
8) 提取重复代码:log2Ceil(width / n)
 
width为mask的总宽度,n为要求取的掩码数。
width/n是把原有总共width个比特分成n个组(group),其值为每个组包含的比特数。
这样n的意义,除了表示求取的掩码数,也表示把原width个比特,划分成的小组的数目。
 
9) j重命名为group
 
生成掩码时使用的序号为j:
 
因为每个小组一个掩码,这个j同时也是小组的编号,将其从中性无意义的j,重命名为group,以表示小组的编号:
 
10) 重命名getMask为getMaskForNGroups
 
把getMask重命名为更清楚表达用途的名称getMaskForNGroups:
 
11) acc的意义
 
MaskGen是要生成访问内存的掩码。可以推测acc是访问(access)的意思。
 
更进一步,acc是一个标志位,标志着否访问所对应的group。这里有两个不同的可能意义:
a. 访问组内的比特对应的全部字节;
b. 访问组内的比特对应的部分字节;
 
12) n == 1
 
当n=1时,把所有width个比特看出一个整体,生成一位掩码。其实现为:
其中:acc = size >= UInt(lgWidth),eq = Bool(true)。
 
当acc=true时,size >= lgWidth,即要访问的长度,大于总线宽度。也就是说width个字节都要访问,即组内各比特对应的字节全部都要访问。这里把上面acc两种可能意义中的b排除掉了。
 
13) sub_acc
 
所谓sub,实际上是上一个层次,即当自己为1/4时,所在的1/2。
 
从acc的实现可以看出,如果sub_acc为真,则acc为真。意义为:如果width个比特中,如果某1/2的acc为真,则标志着这1/2个比特对应的字节全部都要访问,那么包含在这1/2中的2个1/4自然也都是要访问的。
 
14) bit = address(lgBitsInEachGroup)
 
用于计算地址中的偏移量,如同样访问一个字节,从0x0000开始访问与从0x0001开始访问的掩码是不同的,分别为0b0001和0b0010。
 
根据bitsInEachGroup的不同,其所对应的地址偏移量也不同。
如果小组内有1个比特,则每个组占用的偏移量为1个字节;
如果小组内有2个比特,则每个组占用的偏移量为2个字节;
如果小组内有4个比特,则每个组占用的偏移量为4个字节;
 
bit代表address中,与group占字节数相对应的地址位。比如:
当bitsInEachGroup=1时, lgBitsInEachGroup=0,取address的第0位,该位代表的偏移量为1;
当bitsInEachGroup=2时, lgBitsInEachGroup=1,取address的第1位,该位代表的偏移量为2;
当bitsInEachGroup=4时, lgBitsInEachGroup=2,取address的第2位,该位代表的偏移量为4;
 
15) siz = sizeOH(lgBitsInEachGroup)
 
与小组占字节数相对应的大小位:
当bitsInEachGroup=1时, lgBitsInEachGroup=0,取sizeOH的第0位,代表访存大小是否为1;
当bitsInEachGroup=2时, lgBitsInEachGroup=1,取sizeOH的第1位,代表访存大小是否为2;
当bitsInEachGroup=4时, lgBitsInEachGroup=2,取sizeOH的第2位,代表访存大小是否为4;
 
siz用于计算acc:
 
在sub_acc为假的情况下,即当前1/4所在的1/2没有被完全访问的情况下,计算当前1/4是否被全部访问。
 
siz为其中一个条件,意义为:访存大小等于当前1/4所含的比特数。
a. 如果访存大小小于当前1/4所含的比特数,则无法全部涵盖当前1/4,则acc=false;
b. 如果访存大小大于当前1/4所含的比特数,则size大于等于1/2包含的比特数;同时因为sub_acc为假,所以当前1/4所在的1/2都没有被访问。那么当前1/4也没有被访问,即acc=false;
 
16) eq
 
eq的意义为:当前小组是否被访问(全部或者部分)。
当n=1,即所有width个比特都在一个组内的情况下,eq为真,即总被访问(全部或者部分)。
 
sub_eq的意义为:当前1/4小组所在的1/2小组是否被访问。若要所在的1/2没有被访问,则当前1/4也不可能被访问:
 
如果所在的1/2全部被访问,则sub_acc=true,两个1/4的acc也都为true;
如果所在的1/2部分被访问,则sub_acc=false,两个1/4中只有一个被访问。至于哪一个被访问,则与bit的值有关。
 
第一个1/4(group%2=0)是否被访问与!bit相同;
第二个1/4(group%2=1)是否被访问与 bit相同;
 
即:
如果bit=0,则第一个1/4被访问;
如果bit=1,则第二个1/4被访问;
 
结合bit的意义:
如果bit=0,则从基地址0开始访问;
如果bit=1,则需要加上一个偏移量;
 
17) eq的命名
 
eq是equal的缩写,相等的意思。
相等涉及两个参量,a=b,这里的eq表示谁和谁相等呢?
 
被访问的小组和当前小组?
 
这个名称提示意义不足。
 
18) acc总结:
 
若要acc为真,有两种可能:
a. sub_acc为真,即1/4所在的1/2全部要访问;
b. siz && eq: 访问的大小与当前小组的大小一致,并且当前小组被访问。也就是当前小组被全部访问。
 
19) acc与eq重命名
 
acc => allBitsInGroupAccessed;
eq => anyBitsInGroupAccessed;
 
这样是不是更容易理解一些?
 
 
3. groupBy
 
按注释:
groupBy的功能是把width个比特,分成每groupBy个比特一组,每一组中原来的掩码使用OR reduction求一个值作为新的掩码值。
 
然而groupBy的实现是错的。没有发现是因为现有工程中,没有使用groupBy的功能,都是默认值1。
 
实现中:
else里面求取的是_._1,即allBitsInGroupAccessed。也就是说分组中全部的比特都要被访问,而不是只要一个比特被访问即可,是AND reduction,而非OR reduction。
 
_._2即anyBitsInGroupAccessed是OR reduction,但是生成的mask是错误的。所以groupBy的实现实际上是错误不可用的。
 
把groupBy加回来:
 
1) 没有必要判断groupBy == width
当width == groupBy时,else中返回的也是UInt(1),所以没有必要单独判断:
 
2) width / groupBy
 
groupBy即是每个小组中包含的比特数,width / groupBy是分成的小组的个数。
 
3) UInt(groupBy * 2 - 1)
 
生成一个掩码,其中位[groupBy-1, 0]为1。
 
4) 对sizeOH的影响
 
若读取的字节数大于groupBy包含的比特数(每个比特对应一个字节),则没有影响;
若读取的字节数小于groupBy包含的比特数,则相当于把读取的字节数拓宽到groupBy中包含的比特数个字节。
 
例如:
size=0(读取的字节数为1),groupBy=2(最小分组包含2个比特):
原sizeOH=0b01,新sizeOH=0b11。
 
sizeOH(1)=1,起到读取了2个字节的效果。
 
4. 实例
 
 
 
很遗憾的是,与注释中的例子不一样:
 
欢迎指出我的错误之处,谢谢!
 
5. 附录
 

Rocket - util - MaskGen的更多相关文章

  1. Rocket - util - Misc

    https://mp.weixin.qq.com/s/kf4FvAFye_bRdT49Yow7Hg   简单介绍Misc中各个辅助方法的用途和实现.   ​​   1. ParameterizedBu ...

  2. Rocket - util - Annotations

    https://mp.weixin.qq.com/s/7C8ZmPpwAqFqyKjL9K40Fg   介绍util中定义的注解(Annotations).   ​​   1. Annotation ...

  3. Rocket - util - Timer

    https://mp.weixin.qq.com/s/Z4JJhZ_jL1lqF1nf_orq9A   简单介绍Timer的实现.   ​​   1. 基本功能   实现定时器的功能.   2. Ti ...

  4. Rocket - util - Replacement

    https://mp.weixin.qq.com/s/zCP7wPuxgQ-r94Tr6BV5iw   简单介绍Replacement的实现.   ​​   1. 基本介绍   用于实现Cache替换 ...

  5. Rocket - util - ReduceOthers

    https://mp.weixin.qq.com/s/gbR5fuDbE_nUFVxw-p4rsA   简单介绍ReduceOthers的实现.   ​​   1. 基本介绍   输入一组Bool元素 ...

  6. Rocket - util - Repeater

    https://mp.weixin.qq.com/s/xyEq3DgYuf2QuNjssv8pkA   简单介绍Repeater的实现.   ​​   1. 基本功能   A Repeater pas ...

  7. Rocket - util - PrefixSum

    https://mp.weixin.qq.com/s/G2vLP-ncoJzSOgxGGEJkfA   简单介绍PrefixSum的实现.   ​​   1. 基本介绍   ​​ 把一个序列从前向后逐 ...

  8. Rocket - util - MultiWidthFifo

    https://mp.weixin.qq.com/s/CUnrpyQN5LRBR5bxC5u86A   简单介绍MultiWidthFifo的实现.   ​​   1. 基本介绍   实现一个输入宽度 ...

  9. Rocket - util - LanePositionedQueue

    https://mp.weixin.qq.com/s/yO_9Ec3S5-AosRVLpsBgOg   简单介绍基于通道位置的队列(LanePositionedQueue)的实现.   ​​   1. ...

随机推荐

  1. MATLAB矩阵的表示

    矩阵是matlab中最基本的数据对象. l  矩阵的建立 l  冒号表达式 l  结构矩阵和单元矩阵 1.矩阵的建立 (1)利用直接输入法建立矩阵:将矩阵的元素用中括号括起来,按矩阵行的顺序输入各元素 ...

  2. 初识Matlab及界面认识

    通过本章节的学习,需要掌握: MATLAB语言是什么 MATLAB在互联网语言中地位与应用 目标:利用MATLAB进行问题求解的基本规律.够使用MATLAB作为专业应用的工具. 1.什么叫计算? (1 ...

  3. CC2530ADC转换

    一.ADC简介 ADC支持 14 位的模拟数字转换,具有多达12 位的 ENOB(有效数字位).它包括一个模拟多路转换器,具有多达8 个各自可配置的通道,以及一个参考电压发生器.转换结果通过DMA写入 ...

  4. Maxim实时时钟芯片设计指南5413-二进制编码十进制(BCD)格式实时时钟中的状态机逻辑

    网上DS12C887的文章涉及到时间的存储格式使用的都是二进制代码,究竟使用BCD码该如何操作?正好美信官网上有一篇文章.美信官网不稳定,先贴到这里,有时间再翻译. 原文链接 State Machin ...

  5. HBase 安装snappy压缩软件以及相关编码配置

    HBase 安装snappy压缩软件以及相关编码配置 前言 ​ 在使用HBase过程中因为数据存储冗余.备份数等相关问题占用过多的磁盘空间,以及在入库过程中为了增加吞吐量所以会采用相关的压缩算法来压缩 ...

  6. php_rce

    0x01 PHP_RCE RCE(remote command/code execute):远程命令/代码执行 此题为ThinkPHP V5远程代码执行漏洞 0x02 命令执行 http://124. ...

  7. linux下安装gmp遇到 configure:error:no usable m4 in$path or /user/5bin解决方案

    安装过程中遇到如下报错: 上面的报错是因为你没有安装m4,安装m4就可以了:以下两种命令人选其一: #yum install m4 或 #apt-get install m4 ps:如果遇到权限问题就 ...

  8. 系列13 docker asp.net core部署

    一.介绍   本篇完整介绍asp.net core web api如何部署到docker容器中,并通过外部访问web api服务.在编写完成dockerfile之后,可以通过docker [image ...

  9. VMware 安装 CentOS 7

    下载并安装 VMware 访问 VMware 官方网站下载 VMware 安装包程序.博主使用的是 12.5.5 版本,下载完之后点击安装包程序进入 VMware 的安装向导,然后点击"下一 ...

  10. zabbix 自定义指标数据来源

    1.cpu load https://blog.csdn.net/scugxl/article/details/77199403 1)基本含义:运行队列长度,表示当前有多少个正在等待的进程和正在执行的 ...