/** * Module: arbiter * * Description: * A look ahead, round-robing parameterized arbiter. * * <> request * each bit is controlled by an actor and each actor can 'request' ownership * of the shared resource by bring high its request bit. * * <> grant * when an actor has been given ownership of shared resource its 'grant' bit * is driven high * * <> select * binary representation of the grant signal (optional use) * * <> active * is brought high by the arbiter when (any) actor has been given ownership * of shared resource. * * * Created: Sat Jun 1 20:26:44 EDT 2013 * * Author: Berin Martini // berin.martini@gmail.com */ `ifndef _arbiter_ `define _arbiter_ `include "../util/clog2.vh" module arbiter #(parameter NUM_PORTS = 6, SEL_WIDTH = ((NUM_PORTS > 1) ? `CLOG2(NUM_PORTS) : 1)) (input wire clk, input wire rst, input wire [NUM_PORTS-1:0] request, output reg [NUM_PORTS-1:0] grant, output reg [SEL_WIDTH-1:0] select, output reg active ); /** * Local parameters */ localparam WRAP_LENGTH = 2*NUM_PORTS; // Find First 1 - Start from MSB and count downwards, returns 0 when no // bit set function [SEL_WIDTH-1:0] ff1 ( input [NUM_PORTS-1:0] in ); reg set; integer i; begin set = 1'b0; ff1 = 'b0; for (i = 0; i < NUM_PORTS; i = i + 1) begin if (in[i] & ~set) begin set = 1'b1; ff1 = i[0 +: SEL_WIDTH]; end end end endfunction `ifdef VERBOSE initial $display("Bus arbiter with %d units", NUM_PORTS); `endif /** * Internal signals */ integer yy; wire next; wire [NUM_PORTS-1:0] order; reg [NUM_PORTS-1:0] token; wire [NUM_PORTS-1:0] token_lookahead [NUM_PORTS-1:0]; wire [WRAP_LENGTH-1:0] token_wrap; /** * Implementation */ assign token_wrap = {token, token}; assign next = ~|(token & request); always @(posedge clk) grant <= token & request; always @(posedge clk) select <= ff1(token & request); always @(posedge clk) active <= |(token & request); always @(posedge clk) if (rst) token <= 'b1; else if (next) begin for (yy = 0; yy < NUM_PORTS; yy = yy + 1) begin : TOKEN_ if (order[yy]) begin token <= token_lookahead[yy]; end end end genvar xx; generate for (xx = 0; xx < NUM_PORTS; xx = xx + 1) begin : ORDER_ assign token_lookahead[xx] = token_wrap[xx +: NUM_PORTS]; assign order[xx] = |(token_lookahead[xx] & request); end endgenerate endmodule `endif // `ifndef _arbiter_