> 技术文档 > Round-Robin仲裁器

Round-Robin仲裁器


Round-Robin仲裁器

概念:Round-Robin仲裁器是一种公平的仲裁方式,每个请求者按照固定的顺序轮流获得授权。当授权信号释放后,授权将传给下一个请求者(每次授权后,上一次被授权的请求者在下一轮优先级最低)。

Round-Robin仲裁器基本概念

  • 功能:公平地在多个请求者之间轮流授权,避免低优先级请求者饥饿

  • 机制:

    • 记录上一次被授权的请求者(last_grant寄存器)
    • 下一次仲裁从last_grant的下一位开始循环搜索
  • 操作:

    1.根据 last_grant 生成优先级屏蔽掩码

    2.将请求分为高低优先级区域

    3.优先处理高优先级区域的请求

先实现简单的固定优先级仲裁器,再改进为Round-Robin仲裁器。

代码实现

1.生成优先级屏蔽掩码

// 寄存器:记录上一次授权reg [3:0] last_grant;// 组合逻辑:生成优先级屏蔽掩码wire [3:0] mask = last_grant == 4\'b0000 ? 4\'b0000 :  ~((last_grant - 1) | last_grant);

说明: 根据上一次的授权信号 last_grant 计算出一个掩码 mask 用于在下一轮仲裁中屏蔽优先级低于或等于 last_grant 的请求,确保高优先级的请求能够被优先处理。

结果如下:

last_grant 二进制运算 生成的 mask 0000 特殊处理 0000 0001 ~(0000 OR 0001) 1110 0010 ~(0001 OR 0010) 1100 0100 ~(0011 OR 0100) 1000 1000 ~(0111 OR 1000) 0000

last_grant=0010mask=1100 :屏蔽低两位,保留高两位

2.分割高低优先级请求区域

// 分割高低优先级请求区域wire [3:0] high_pri_req = req & mask;wire [3:0] low_pri_req = req & ~mask;

高优先级请求:仅保留比 last_grant 优先级高的请求

低优先级请求:保留优先级≤ last_grant 的请求

设计目的:避免低优先级请求“饿死”。每次授权后,下一轮会优先服务更高优先级的请求,若不存在则再处理低优先级请求。

3.仲裁逻辑

// 仲裁逻辑wire [3:0] high_pri_grant = high_pri_req & -high_pri_req;wire [3:0] low_pri_grant = low_pri_req & -low_pri_req;wire [3:0] grant_next = |high_pri_req ? high_pri_grant : low_pri_grant;

代码说明: -high_pri_req 表示 high_pri_req 的补码(取反+1)。

high_pri_grant = high_pri_req & -high_pri_req;

作用:在高优先级组内选择最低位的1。(表明该仲裁器是从最低位开始选择)

原理:X & -X 保留X中最低位的1。

grant_next = |high_pri_req ? high_pri_grant : low_pri_grant;

逻辑:若 |high_pri_req 为真(high_pri_req不为0,高优先级组存在请求),授权 high_pri_grant ;否则授权 low_pri_grant

意义:确保高优先级组绝对优先,避免低优先级请求饿死


最终程序:

module test ( input clk, input rst_n, input [3:0] req, // 4位请求信号 output [3:0] grant // 4位授权信号);// 寄存器:记录上一次授权reg [3:0] last_grant;// 组合逻辑:生成优先级屏蔽掩码wire [3:0] mask = last_grant == 4\'b0000 ? 4\'b0000 :  ~((last_grant - 1) | last_grant);// 分割高低优先级请求区域wire [3:0] high_pri_req = req & mask;wire [3:0] low_pri_req = req & ~mask;// 仲裁逻辑wire [3:0] high_pri_grant = high_pri_req & -high_pri_req;wire [3:0] low_pri_grant = low_pri_req & -low_pri_req;wire [3:0] grant_next = |high_pri_req ? high_pri_grant : low_pri_grant;// 时序逻辑更新授权状态always @(posedge clk or negedge rst_n) begin if (!rst_n)  last_grant <= 4\'b0000; // 复位清零 else if (req != 0)  last_grant <= grant_next; // 有请求时更新endassign grant = grant_next;endmodule

测试

`timescale 1ns / 1psmodule sim();reg clk ; reg rst_n ; reg [3:0] req ;wire [3:0] grant;initial clk = 1;always #10 clk <= ~clk;test u_test ( .clk (clk ), .rst_n (rst_n ), .req (req ), .grant (grant ) );initial begin rst_n = 0; req = 4\'b0000; // 初始化 #50; rst_n = 1; // 持续请求测试 req = 4\'b1011; // A、B、D请求 #100; // 请求变化测试 req = 4\'b0100; // 仅C请求 #50; // 边界测试 req = 4\'b1000; // 仅最高位 #50;endendmodule

在这里插入图片描述