// rr_arbiter.sv — N-way round-robin arbiter, combinational grant module rr_arbiter #( parameter int N = 4 ) ( input logic clk, input logic rst, input logic [N-1:0] req, output logic [N-1:0] gnt ); localparam int PW = (N > 1) ? $clog2(N) : 1; logic [PW-1:0] ptr; // requester with the highest priority // Grant the first requester at or after ptr (wrapping around) always_comb begin gnt = '0; for (int k = N - 1; k >= 0; k--) begin // lowest k wins: last assignment sticks if (req[(int'(ptr) + k) % N]) begin gnt = '0; gnt[(int'(ptr) + k) % N] = 1'b1; end end end // After a grant, the requester just after the winner gets top priority always_ff @(posedge clk) begin if (rst) begin ptr <= '0; end else begin for (int i = 0; i < N; i++) if (gnt[i]) ptr <= PW'((i + 1) % N); end end endmodule