WRR:Weight Round-Robin, 即在RR调度基础上增加权重。在多个输入数据时,且每个通道都配置有独立的权重值,当输入有效通道的权重值不为0时,按RR调度进行输出,且每输出一个数据的该通道的权重值减0,当所有通道的权重值为0时,则完成一次WRR调度,权重值被重新初始化。
1.1 实现原理
待补
1.2 verilog 代码
module WRR #(NUM = 4) (
input wire clk,
input wire rst_n,
input wire [NUM -1:0] i_weight[NUM -1:0],
input wire [NUM -1:0] i_valid,
output wire [NUM -1:0] o_grant,
output wire o_grant_vld
);
wire [NUM -1:0] valid_lsb1;
wire [NUM -1:0] rr_i_valid;
wire [NUM -1:0] rr_i_grant;
wire [NUM -1:0] rr_o_grant;
wire rr_o_grant_vld;
wire [NUM -1:0] sel_chn;
reg [NUM*NUM -1:0] weight_vec;
reg [NUM*NUM -1:0] weight_cnt;
//switch channel number
assign sel_chn = (o_grant_vld) ? (i_valid & o_grant) : {WD{1'b0}};
generate
genvar i;
for(i=0; i<NUM; i=i+1) begin : array_to_vector
assign weight_vec[i*NUM+NUM-1:i*NUM] = i_weight[i];
end
for(i=0; i<NUM; i=i+1) begin : caculate_weight
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
weight_cnt[i*NUM+NUM-1:i*NUM] <= weight_vec[i*NUM+NUM-1:i*NUM];
else if(~|weight_cnt) // all of channels weight are 0
weight_cnt[i*NUM+NUM-1:i*NUM] <= weight_vec[i*NUM+NUM-1:i*NUM];
else if(sel_chn[i] & (weight_cnt[i*NUM+NUM-1:i*NUM] != {{(WD-1){1'b0}},1'b0})) //valid channel, and weight value is not 0
weight_cnt[i*NUM+NUM-1:i*NUM] <= weight_cnt[i*NUM+NUM-1:i*NUM] -{{(WD-1){1'b0}},1'b1};
end
end
for(i=0; i<NUM; i=i+1) begin : gen_valid
assign rr_i_valid[i] = (weight_cnt[i*NUM+NUM-1:i*NUM] !=0 & i_valid[i]);
end
endgenerate
assign o_grant = rr_o_grant;
assign o_grant_vld = rr_o_grant_vld;
u_RR RR #(.NUM(NUM)) (
.clk (clk),
.rst_n (rst_n),
.i_valid (rr_i_valid),
.o_grant (rr_o_grant),
.o_grant_vld (rr_o_grant_vld)
);
endmodule