调度(Scheduling)又称流控/选择和分配。RR调度指的是在一次轮询响应请求中,每个请求信号都会获得响应。
RR调度器真值表如下(4 channel为例)
如上图所示:
i_valid为输入;
mask_req_pe为掩码,0:表示先调度输出,1表示下次调度输出;
unmask_req_pe为掩码, 当mask_req无效时候,采用从0-3通道的顺序重新轮询;
o_grant:指示选择哪路输出;
o_grant_vld:指示当前调度输出有效。
RTL代码如下:
module RR #(parameter WD = 4)
(
input clk,
input rst_n,
input i_schedule_en,
input [WD -1:0] i_valid,
input o_grant_vld,
input [WD -1:0] o_grant
);
reg [WD -1:0] point_ff;
reg [WD -1:0] grant_ff;
wire [WD -1:0] mask_req;
wire [WD -1:0] mask_req_pe;
wire [WD -1:0] unmask_req_pe;
wire [WD -1:0] next_pointer;
wire [WD -1:0] valid_pe;
assign valid_pe = grant_ff & i_valid;
always @(posedge clk or negedge rst_n) begin
if(~rst_n)
point_ff <= {WD{1'b0}};
else
if(o_grant_vld == 1'b1)
point_ff <= next_pointer;
end
assign mask_req = point_ff & valid_pe;
generate
genvar i;
for(i=0; i<WD; i=i+1) begin
if(i==0) begin
assign mask_req_pe[0] = 1'b0;
assign unmask_req_pe[0] = 1'b0;
end
else begin
assign unmask_req_pe[i] = (|valid_pe[i-1:0]);
assign mask_req_pe[i] = (|mask_req[i-1:0]);
end
end
endgenerate
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
grant_ff <= {WD{1'b0}};
else
grant_ff <= ~next_point & valid_pe; //grant_ff <= o_grant
end
assign next_pointer = (mask_req == {WD{1’b0}}) ? unmask_req_pe : mask_req_pe;
assign o_grant = ~next_point & valid_pe;
assign o_grant_vld = (|valid_pe) & i_schedule_en;
endmodule