芯片IC设计(二)--调度器(RR调度)

 一、概述

        RR(Round Robin)为轮询调度器,该类型的调度器与上一章节的SP调度器的实现原理有些相似,但是RR调度的功能与SP调度相差较大,RR调度器主要解决在调度过程中多个请求调度源的公平性问题,相较于SP调度,RR调度器通过轮询各请求源判断请求源的访问情况,当某一请求源被成功调度后,该请求源在下一拍的调度信用降至最低,而此时请求源的左边的信用度增至最高,所以RR调度可以解决调度的公平性问题,常用于多个 通道同时申请调度,在数字芯片设计过程中经常使用。

二、实现重点

        RR调度实现的原理前面已经说了一部分,而实现RR调度小编认为有几个地方需要注意:

        1、记录当前调度指针的位置,该指针的右边的调度源在下一次调度的时候需要被屏蔽;

        2、当调度请求源有效时,通过计算得到需要屏蔽的调度源,并找到左右两侧的首1(与SP相似);

三、RR调度器的Verilog代码

        话不多说,直接上verilog代码:

module RR_SH#(
	parameter SH_NUM = 8             // RR调度器的请求端口数量
)(
	input				   clk     ,
	input				   rst_n   ,
	input [SH_NUM - 1 : 0] sh_req  , //调度源
	input				   sh_en   , //调度使能,高电平有效,调度器在该信号有效时进行工作
	output[SH_NUM - 1 : 0] sh_grant, //调度结果,该接口为独热码输出
	output 				   sh_vld    //调度结果有效标识,高有效表示调度结果有效
);

    wire  [SH_NUM - 1 : 0] 	 right_grant      ;//调度器右侧调度结果,当调度指针左侧没有访问源时有效
    wire  [SH_NUM - 1 : 0]   rr_req           ;//调度使能有效时的调度请求
    wire  [SH_NUM - 1 : 0]	 next_mask_ptr    ;//当次调度掩码,每一bit代表一个访问源,为0时屏蔽访问源
    reg   [SH_NUM - 1 : 0]   next_mask_ptr_ff1;//记录每次的调度掩码
    wire  [SH_NUM - 1 : 0]	 left_req         ;//调度指针左侧的调度源,该请求源为屏蔽后的请求源
    wire  [SH_NUM - 1 : 0]	 left_grant       ;//左侧调度结果
    wire  [SH_NUM - 1 : 0]   right_mask       ;//右侧调度掩码
    wire  [SH_NUM - 1 : 0]   left_mask        ;//左侧调度掩码

assign sh_vld        = sh_en == 1'b1 ? |sh_req : 1'b0         ;
assign rr_req        = sh_en == 1'b0 ? {SH_NUM{1'b0}} : sh_req;
assign left_req      = (next_mask_ptr_ff1) & rr_req           ; 
assign right_grant   = rr_req & (~(rr_req - 1'b1))            ;//找首1
assign left_grant    = left_req & (~(left_req - 1'b1))        ;//找首1
assign right_mask[0] = 1'b0                                   ;
assign left_mask[0]  = 1'b0                                   ;

genvar i;
generate
	for(i=1;i<SH_NUM;i=i+1)begin:MASK_GEN
		assign right_mask[i] = |rr_req[i-1:0]  ;
		assign left_mask[i]  = |left_req[i-1:0];
	end
endgenerate

assign sh_grant      = left_req == {SH_NUM{1'b0}} ? right_grant : left_grant;
assign next_mask_ptr = left_req == {SH_NUM{1'b0}} ? right_mask : left_mask  ;

always @(posedge clk or negedge rst_n)begin
	if(rst_n == 1'b0)
		next_mask_ptr_ff1 <= {SH_NUM{1'b0}};
	else if(sh_vld == 1'b1)
		next_mask_ptr_ff1 <= next_mask_ptr;
	else ;
end

endmodule

  四、实现说明与约束

        1、由于上述代码可以实现在调度源有效的当拍出调度结果,该电路实现的过程中使用组合逻辑实现,所以端口数量不能设置过大,一般小于128,否则对时序压力、后端实现的压力较大。

        2、调度器最开始从LSB开始轮询。

 五、RR调度器仿真结果示意图

小编是使用vivado TCL进行仿真,TCL脚本放在下方了,当然也可以自己编写TB进行仿真哦

add_force {/test/clk} -radix hex {1 0ns} {0 5000ps} -repeat_every 10000ps
add_force {/test/rst_n} -radix hex {0 0ns}
run 100 ns
add_force {/test/sh_req} -radix hex {0 0ns}
add_force {/test/sh_en} -radix hex {0 0ns}
run 40 ns
add_force {/test/rst_n} -radix hex {1 0ns}
run 30 ns
add_force {/test/sh_req} -radix hex {1 0ns}
add_force {/test/sh_en} -radix hex {1 0ns}
run 10 ns
add_force {/test/sh_req} -radix hex {2 0ns}
run 10 ns
add_force {/test/sh_req} -radix hex {3 0ns}
run 10 ns
add_force {/test/sh_req} -radix hex {4 0ns}
run 10 ns
add_force {/test/sh_req} -radix hex {5 0ns}
run 10 ns
run 10 ns
add_force {/test/sh_req} -radix hex {6 0ns}
run 10 ns
add_force {/test/sh_en} -radix hex {0 0ns}
run 50 ns
add_force {/test/sh_req} -radix hex {7 0ns}
run 10 ns
add_force {/test/sh_en} -radix hex {1 0ns}
run 10 ns

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值