Chisel3 - util - RRArbiter

https://docs.qq.com/doc/DUWtwcWZlYm5DWG9n

循环优先级(Round Robin)仲裁器。

参考链接:

https://github.com/freechipsproject/chisel3/blob/master/src/main/scala/chisel3/util/Arbiter.scala

RRArbiter是一个仲裁器,只是使用RR的逻辑实现优先级。grant是优先级逻辑的结果,所以实现RRArbiter与严格优先级Arbiter的区别在于(仅在于)grant的生成逻辑不同。

1. RR优先级的两个层次

RR优先级的含义,包括两个层次:

a. 基于次序的优先级

小号输入口的优先级高于大号输入口;

b. 最高优先级是循环的

与严格优先级不同的是,RR逻辑中,最高优先级并不总是0,而是根据上一次选择的输入口而变化的。上一次选择的输入口的下一个输入口具有最高的优先级。

最高优先级并不是逐个向后轮换的,而是根据上一次选择的输入口可能产生跳变。因为最高优先级的输入口不一定被选择,也并不代表次优先级不能被选择。

2. 上一次轮到的输入口

要实现RR逻辑,需要记录上一次轮到的输入口,序号记为:lastGrant。

那么判断输入口是否轮过的逻辑为:i > lastGrant,为真则未轮过,为假则已轮过。

3. 忽略已经轮过的输入口

输入口的状态首先通过valid信号表达。判断某个输入口是否考虑的逻辑为:

(i > lastGrant) && io.in(i).valid;

4. 表达基于次序的优先级

基于次序的优先级的逻辑与Arbiter一样,如下(设Arbiter 输入口个数n = 4):

??

5. 引入未轮过的输入口

因为循环优先级的存在,输入口0并不总是最高优先级,其优先级还要低于未轮过的输入口,所以需要引入依赖未轮过的输入口。如下:

??

这里选择把所有的接口都加上,那些已经轮过的输入口i > lastGrant为假,自动忽略其valid。未轮过的输入口i > lastGrant为真,则会依赖其valid信号。

6. 不适用于未轮过的输入口

不过这种方法,不适用于未轮过的输入口。

假设lastGrant = 1, 那序号为2的输入口也依赖于其自身的valid,也依赖于序号为3的valid。这是不合理的。

所以这个逻辑只适用于已轮过的输入口。

7. 分而治之

此时需要使用分治策略,为已轮过的和未轮过的输入口提供不同的逻辑。而两种接口的分野就在于i > lastGrant。

8. 未轮过的输入口使用的逻辑

未轮过的输入口的优先级只依赖于前一个未轮过的输入口,如果是第一个未轮过的输入口,则其优先级最高,不依赖于任何其他输入口。

把所有输入口都当做未轮过输入口,考虑基于次序的优先级,逻辑如下:

??

若lastGrant = 1:

a. in(0)/in(1)为已轮过的输入口,使用已轮过输入口的逻辑;

b. in(2)为第一个未轮过输入口,其优先级最高,不依赖于其他输入口的valid(直接为true);

c. in(3)为第二个未轮过输入口,依赖于in(2).valid,而不依赖于in(0)/in(1);

9. 总结

总结下来,如果接口已轮过,则使用如下逻辑确定是否授权:

??

如果接口未轮过,则使用如下逻辑确定授权:

??

综合起来,如下:

??

10. RRArbiter类

??

RRArbiter类为LockingRRArbiter类的子类。

11. LockingRRArbiter类

这个类中实现RR的逻辑。

??

a. lastGrant

lastGrant记录上一次选择的输入口。

b. grantMask

为每一个输入口生成一个:i > lastGrant 逻辑。

c. validMask

根据是否轮过,决定是否考虑该输入口的valid信号。为每个输入口生成一段 (i > lastGrant) && in(i).valid逻辑。

d. ctrl

1) 依次取出validMask中的元素:(0 until n).map(i => validMask(i))

2) 依次取出所有的valid信号:io.in.map(_.valid)

3) 把两个list连接起来:listA ++ listB

??

4) 使用ArbiterCtrl连接每个元素,结果如下:

??

e. grant

grant(i) = ctrl(i) && grantMask(i) || ctrl(n + i)

如下:

??

f. choice

choice决定chosen, chosen决定io.out.valid和io.out.bits:

??

choice的逻辑如下:

??

如果还记得上一篇对循环when的解释:时间上后面执行的when先行判断,前面执行的when逐次为eslewhen/otherwise。

这里validMask的循环在后面执行,那么validMask的判断就在前面,validMask为假才会继续判断后面的valid信号。

这样就为未轮过的输入口提供了优先级。倒着来从大号到小号,是为了遵从基于次序的优先级。

值得注意的有两点:

1) 第一个循环从n-2到0,那n-1呢?

很简单,n-1已经作为默认值了。

2) 第二个循环从n-1到1,那0呢?

因为0 > lastGrant始终为false,所以validMask(0)始终为false。总是第一个进行结果已知的判断,干脆直接省略。

这是一个很有趣的地方。尽管0 > lastGrant始终为假,也就是说in(0)始终被当做已轮过的输入口,但却并未影响其基于次序的优先级和基于RR的优先级。为什么呢?

因为在设计已轮过和未轮过输入口的授权逻辑时,已经考虑到了这一点。

原文地址:https://www.cnblogs.com/wjcdx/p/10128937.html

时间: 2024-10-07 12:21:54

Chisel3 - util - RRArbiter的相关文章

Chisel3 - util - Valid

https://mp.weixin.qq.com/s/L5eAwv--WzZdr-CfW2-XNA Chisel提供的Valid接口.如果valid为置1,则表明输出的bits有效:反之,则输出无效. 参考链接: https://github.com/freechipsproject/chisel3/blob/master/src/main/scala/chisel3/util/Valid.scala ?? 1. Valid是一组用户自定义的输入输出接口 类的声明如下: class Valid[

Chisel3 - util - Pipe

https://mp.weixin.qq.com/s/WeFesE8k0ORxlaNfLvDzgg 流水线,用于添加延迟. 参考链接: https://github.com/freechipsproject/chisel3/blob/master/src/main/scala/chisel3/util/Valid.scala ?? 1. Pipe object提供了三个工厂方法 ?? 最基本的方法签名如下: def apply[T <: Data](enqValid: Bool, enqBits

Chisel3 - Tutorial - Adder4

https://mp.weixin.qq.com/s/X5EStKor2DU0-vS_wIO-fg 四位加法器.通过FullAdder级联实现. 参考链接: https://github.com/ucb-bar/chisel-tutorial/blob/release/src/main/scala/examples/Adder4.scala 1. 引入Chisel3 ?? 2. 继承自Module类 ?? 3. 定义输入输出接口 ?? 创建输入和输出接口: 这些接口都是无符号整型数:val A

mybatis异常:Could not find result map java.util.Map 问题分析及解决

错误写法 <select id="queryXXXCount" resultMap="java.util.Map" > mybatis报出的异常日志: org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.util.Map at org.apache.ibatis.builder.MapperBuilderAssistant.setStat

Java.util.ConcurrentModificationException的理解与修改

在Java开发的过程中有没有遇到类似的异常信息 Exception in thread "main" java.util.ConcurrentModificationException, 下面介绍异常原因以及这种异常的改进方法,内容很简单,有什么问题还望指正. 假设我们要实现这样一个例子: 判断集合里面有没有"world"这个元素,如果有,就添加一个"javaee"元素 出现异常的代码如下: import java.util.ArrayList;

java.util.Objects 源码学习

Objects 与 Object 区别 Object 是 Java 中所有类的基类,位于java.lang包. Objects 是 Object 的工具类,位于java.util包.它从jdk1.7开始才出现,被final修饰不能被继承,拥有私有的构造函数. 它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),用于计算对象的hashcode.返回对象的字符串表示形式.比较两个对象. Objects 各方法介绍与分析 equals

Util包中Arrays

java.util 类 Arrays java.lang.Object -java.util.Arrays public class Arrays extends Object 此类包含用来操作数组(比如排序和搜索)的各种方法.此类还包含一个允许将数组作为列表来查看的静态工厂. 除非特别注明,否则如果指定数组引用为 null,则此类中的方法都会抛出 NullPointerException. 此类中所含方法的文档都包括对实现 的简短描述.应该将这些描述视为实现注意事项,而不应将它们视为规范 的一

【java】获取当前日期时间:java.util.Date

1 public class TestDate { 2 public static void main(String[] args) { 3 System.out.println(new java.util.Date()); 4 } 5 } 运行结果:Fri Apr 07 21:56:24 CST 2017

源码分析八(org.springframework.util包之StringUtils类))

一:spring框架util包中的StringUtils类主要是处理关于字符串 的功能方法,下面直接结合代码分析: //判断字符串是否为空,如果为nul或者""则返回true,否则返回false public static boolean isEmpty(Object str) { return str == null || "".equals(str); } //判断字符串是否有长度,不等于null同时长度大于0,则为true //这里重载两个hasLength方