前两篇讲了固定优先级仲裁器的设计、轮询仲裁器的设计
Verilog固定优先级仲裁器——Fixed Priority Arbiter_weixin_42330305的博客-CSDN博客
Verilog轮询仲裁器设计——Round Robin Arbiter_weixin_42330305的博客-CSDN博客
权重轮询仲裁器就是在轮询仲裁器的基础上,当grant次数等于weight时,再切换最高优先级。
一、原理
我们在轮询的基础上加上一些权重,仲裁器虽然轮询的去serve requestor的 请求,但是完成一圈轮询后,requestor被serve的次数并不完全相同。
假设requestor有A、B、C、D三个,权值分别为4、3、2、1,假设它们的request一直为高,且从A开始轮询。则A被serve 4 次后B 才能被serve,依次类推。即weighted round robin则是要把weight计数器消耗光之后才轮换。
如果A被serve的次数不够4次,此时request被拉低了呢?
这个时候,我们不能等待A,而是要serve其他request为高的source,不然如果A后面不再发出有request,其他source的request就会永远不能被serve,就会挂死。
因此,当source的counter与weight相同,或者是正在被serve的source request被拉低,则重新load权值。
举个例子:
req_a | req_b | req_c | req_d | grant | |
cycle 1 | 1 | 1 | 0 | 1 | a |
cycle 2 | 0 | 0 | 1 | 0 | c |
cycle 3 | 1 | 0 | 1 | 1 | c |
cycle 4 | 1 | 1 | 1 | 0 | a |
cycle 5 | 0 | 1 | 1 | 0 | b |
a、b、c、d的权值分别为:4、3、2、1
cycle 1:优先级a>b>c>d,a发出了request,count_a=0小于weight_a(4),因此serve a => count_a=1
cycle 2:优先级a>b>c>d,a没有发出request,count_a=0,
b没有发出request
c发出了request,count_c=0小于weight_c(2),因此serve c => count_c=1
cycle 3:优先级c>d>a>b,c发出了request,count_c=1小于weight_c(2),因此serve c => count_c=2
cycle 4:优先级d>a>b>c,因为count_c=2等于weight_c(2),触发了轮换
d没有发出request
a没有发出request
b发出了request,serve b
二、实现方法
我们先看轮询仲裁的rtl实现方法:
module round_arb
(
input clk,
input reset_n,
input [5:0] req,
output [5:0] grant
);
reg [5:0] round_priority;
always @(posedge clk or negedge reset_n)
begin
if(!reset_n)
round_priority <= 6'b1;
else if(|grant)
round_priority <= {grant[4:0],grant[5]};
end
wire [6*2-1:0] double_req = {req,req};
wire [6*2-1:0] req_sub_round_priority = double_req - round_priority;
wire [6*2-1:0] double_grant = double_req & (~req_sub_round_priority);
assign grant = double_grant[5:0] | double_grant[11:6];
endmodule
可以看出,当有source被grant,那么仲裁器发生轮询。
权重轮询仲裁器,是发生以上例子中的两种情况时,发生轮询。
module weight_round_arb
(
input clk,
input reset_n,
input [3:0] req,
output [3:0] grant
);
parameter integer WEIGHT[3:0] = {1,2,3,4};
reg [3:0] round_priority;
reg [3:0] count[3:0];
wire [3:0] round_cell_en[3:0];
wire [3:0] round_en;
genvar i;
generate
for(i=0;i<4;i++) begin: counter
always @(posedge clk or negedge reset_n) begin
if(!reset_n)
count[i] <= 4'b0;
else if(|grant) begin
if(grant[i])
count[i] <= count[i] + 1'b1;
else
count[i] <= 4'b0;
end
end
end
assign round_cell_en[i] = (count[i] ==WEIGHT[i]) | ((count[i]!=0) & (~req[i]));
endgenerate
assign round_en = (round_cell_en[3] | round_cell_en[2] | round_cell_en[1] | round_cell_en[0]) & (| req);
always @(posedge clk or negedge reset_n)
begin
if(!reset_n)
round_priority <= 4'b1;
else if(round_en)
round_priority <= {grant[2:0],grant[3]};
end
wire [4*2-1:0] double_req = {req,req};
wire [4*2-1:0] req_sub_round_priority = double_req - round_priority;
wire [4*2-1:0] double_grant = double_req & (~req_sub_round_priority);
assign grant = double_grant[3:0] | double_grant[7:4];
endmodule
仲裁器进阶:文章来源:https://www.toymoban.com/news/detail-620164.html
verilog多因素影响仲裁器设计_weixin_42330305的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-620164.html
到了这里,关于Verilog权重轮询仲裁器设计——Weighted Round Robin Arbiter的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!