Verilog权重轮询仲裁器设计——Weighted Round Robin Arbiter

前两篇讲了固定优先级仲裁器的设计、轮询仲裁器的设计

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_areq_breq_creq_dgrant
cycle 11101a
cycle 20010c
cycle 31011c
cycle 41110a
cycle 50110b

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

仲裁器进阶:

verilog多因素影响仲裁器设计_weixin_42330305的博客-CSDN博客

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值