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=0010
, mask=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) beginif (!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 beginrst_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;
end
endmodule