当前位置: 首页 > news >正文

round robin轮询仲裁器

上一节描述了固定仲裁器的设计,固定仲裁器的逻辑简单,实现也比较容易,但是固定仲裁器有个问题:固定仲裁器各请求的优先级是不会发生变化的。那么就会存在有请求一直拿不到权限被饿死的场景。

为了解决这个问题,提出了RR 仲裁器, RR仲裁器会在每一次请求被taken之后,将当前请求的优先级调整为最低,从而达到仲裁的公平性。

1. 思路1

    最简单的思路就是在master不多时,根据上一次的grant来对req进行移位,得到req_shift,之后采用固定优先级仲裁器直接执行得到新的grant_shift,之后再复位回去,得到最终的grant;

2. 思路2

    在讲固定优先级仲裁器时,最后有提到采用req-1 取反来找第一个1的时候,这个思路是可以扩展的,采用req - onehot_a 是可以找到以onehot_a为开始的第一个1,此时就可以得到:

grant = req & ~(req-onehot_a);

  这里会有个问题:onehot_a是可能比req大的,从因此这里扩展req来解决这个问题

grant_ext = {req, req} & ~({req,req}-onehot_a)
grant_ext = grant_h | grant_l;

当我们有了这个基础之后,那么就可以实现对应的功能了。

a. 获取onehot_a: 按照RR的概念,onehot_a可以通过grant左移一位来表示,注意grant代表的是当前选择的req,在下一轮的仲裁中它的下一个bit才是优先级最高的bit,因此这个需要左移grant;

always @(posedge clk) beginif(!rstn) onthot_a <= {{NUM_REQ-1{1'b0}}, 1'b1};elseif(|req)onehot_a <= {grant[NUM_REQ-2:0, grant[NUM_REQ-1]}; end

这个思路和前一个思路的缺点一样,就是看着功能是实现了,但是timing和面积在req较多时比较差。现在基本上的实现都是采用mask的方式来实现,也就是下面介绍的思路3

3. 思路3

思路2本质上是没有动req,想通过调整优先级的方式来实现仲裁。而与之对应就是,优先级不变,对req进行处理来完成对应的操作。

在RR 仲裁中的实现思路目前看起来都是采用掩码 mask的方式来实现,将已经给过grant的req 位mask掉,得到mask req,再将mask req放入固定优先级仲裁器中选择,得到mask grant,轮询一周后,mask grant变为0, 采用新的req从新开始。

那么,怎么找mask呢?

我们先看mask的特征吧,mask的目的是将比当前选择请求的优先级低的所有请求都保留下来,

req[3:0] = 4'b0010
pre_req[3:0] = 4'b1100pre_req[0] = 0;
per_req[1] = req[0] | pre_req[0];
...
pre_req[n-1] = req[n-2] | pre_req[n-2]so
pre_req[n-1:1] = req[n-2:0] | pre_req[n-2:0]

知道了怎么获得mask,下面就看怎么更新mask吧:

1,默认情况下, mask为all 1,都可以放进来请求;

2. 当req_mask有效时,更新mask为前一次的mask侧请求的mask;

3. 当req_mask无效时,但是req有效时,更新mask为当前这一轮unmask侧的mask;

4. 都无效,mask保持不变

// mask updatealways @ (posedge clk) beginif (rst) beginmask_q <= {N{1'b1}};end else beginif (|req_mask) beginmask_q <= pre_mask;end else beginif (|req) begin  mask_q <= pre_unmask;end else beginmask_q <= mask_q ;endendendend

再看完mask的产生和更新逻辑之后,看看怎么利用mask 实现RR吧!

1. MASK 侧

  根据上述pre_req的逻辑, 这里pre_req为mask, 这里的req也应该是mask之后的req,因此,这里伪代码变为:

  表示当req mask有效时,将当前最新的mask更新到mask_q中;

req_mask = req & mask_q;
pre_mask[n-1:1] = req_mask[n-2:0] & pre_mask[n-2:0]grant_mask = req & ~ pre_mask;

2. UNMASK侧


pre_unmask[n-1:1] = req[n-2:0] & pre_unmask[n-2:0]
pre_unmask[0] = 1'b0;grant_unmask = req & ~ pre_unmask;

3. Grant

最后根据 req_mask选择grant 即可。

http://www.lryc.cn/news/620036.html

相关文章:

  • 2025 开源语音合成模型全景解析:从工业级性能到创新架构的技术图谱
  • hutool 作为http 客户端工具调用的一点点总结
  • 理解RESTful架构:构建优雅高效的Web服务
  • 《Unity Shader入门精要》学习笔记一
  • Dimensional Analysis量纲分析入门
  • 【Excel】被保护的文档如何显示隐藏的行或列
  • MongoDB 入门指南二:索引 —— 让查询速度飞起来
  • 随想记-excel报表美化
  • 选择排序专栏
  • 使用 6 种方法将文件从 Android 无缝传输到iPad
  • C# 反射和特性(获取Type对象)
  • 攒钱学概论:5、创业术
  • window显示驱动开发—DirectX 9 资源创建
  • 《AVL树的原理与C++实现:详解平衡二叉搜索树的高效构建与操作》
  • 【自动化运维神器Ansible】playbook主机清单变量深度解析:主机变量与组变量的实战应用
  • JavaWeb-Servlet基础
  • CodeBuddy在AI开发方面的一些特色
  • 1.Cursor快速入门与配置
  • PyTorch Tensor完全指南:深度学习数据操作的核心艺术
  • Matlab(4)
  • C++ stack and queue
  • 【OSPP 开源之夏】Good First issue 第一步—— openEuler Embedded 计划
  • 机器视觉的零件误差检测系统:基于多角度点云融合的圆柱体零件尺寸测量
  • 5. synchronized 关键字 - 监视器锁 monitor lock
  • InnoDB如何解决脏读、不可重复读和幻读的?
  • mysql - 查询重复数据,不区分大小重复问题解决
  • 服务器查看 GPU 占用情况的方法
  • 安全点(Safepoint)完成后唤醒暂停线程的过程
  • 响应式对象的类型及其使用场景
  • 量子安全新纪元:F5发布全新AI驱动的全栈式后量子加密AI安全方案