Latency(CLK) | 0 |
module rrArbiter(iVld, iStall, oVld, oStall, oArb, reset, clk);
parameter R = 3;
parameter N = 1<<R;
input [N-1:0] iVld;
output [N-1:0] iStall;
output oVld;
input oStall;
output [R-1:0] oArb;
input reset;
input clk;
reg [R-1:0] oPtr; // Round-Robin Pointer
wire [N-1:0] oVec = 1'b1 << rrArb;
// 0: Park, 1: Not Park
wire oInc = 1'b1;
always @(posedge clk)
if (reset)
oPtr <= #1 {R{1'b0}};
else if (oVld & !oStall)
oPtr <= #1 oArb + oInc;
assign iStall = {N{oStall}} & ~oVec;
assign oVld = |iVld;
assign oArb = arbFunc(iVld, oPtr);
function [R-1:0] arbFunc;
input [N-1:0] vld;
input [R-1:0] ptr;
reg [R-1:0] idx;
reg [R-1:0] num[N-1:0];
integer i, j;
begin
for (i=0; i<N; i=i+1) begin
num[i] = {R{1'bx}};
for (j=0; j<N; j=j+1) begin
idx = i[R-1:0] + ~j[R-1:0];
if (vld[idx])
num[i] = idx;
end
end
arbFunc = num[ptr];
end
endfunction
endmodule
|