diff options
Diffstat (limited to 'arbiter.v')
| -rw-r--r-- | arbiter.v | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/arbiter.v b/arbiter.v new file mode 100644 index 0000000..0e83403 --- /dev/null +++ b/arbiter.v @@ -0,0 +1,67 @@ +/* Arbiter + * A module that grants access to a shared ressource (e.g a bus) + * to an arbitrary amount of drivers. A driver of the shared resource + * has a bit on the `request` line and fires it up when it wants to use + * the resource. The arbiter fires the corresponding `grant` bit when + * the driver is allowed to use the resource */ +module arbiter #( + parameter NUM_CLIENTS = 4 +) ( + input clk, + + // Request bits, each driver has its request line + input[NUM_CLIENTS-1:0] request, + + // Grant bits, each driver has its grant line + output[NUM_CLIENTS-1:0] grant +); + // The current round of the arbiter + reg[NUM_CLIENTS-1:0] round = 1; + + // A circle of wires used by the arbiter to + // indicate that a driver that has the priority + // to use the resource yields it to the next driver + // because it doesn't need to use the resource + wire pass_on_rollover; + /* verilator lint_off UNOPTFLAT */ + logic pass_on; + assign pass_on_rollover = pass_on; // NOTE: assign is applied on last assignment to wire + + // Logic bitfield used to generate the grant bus + logic[NUM_CLIENTS-1:0] grant_gen; + assign grant = grant_gen; + + always @(posedge clk) begin + // Keep current grant as round, allowing a selected driver + // to freeze the arbiter during the entire duration of its + // resource utilization + round <= |grant ? + grant : { round[NUM_CLIENTS-2:0], round[NUM_CLIENTS-1] }; + end + + always_comb begin + pass_on = pass_on_rollover; + + for (integer i = 0; i < NUM_CLIENTS; i++) begin + logic has_priority; + + // Current driver has priority if it's its round + // or previous driver has passed on its + has_priority = round[i] || pass_on; + + // By default, do not grant to driver + grant_gen[i] = 0; + + // By default, do not pass on priority + // to next driver (current may not have it) + pass_on = 0; + + if (has_priority) begin + if (request[i]) + grant_gen[i] = 1; + else + pass_on = 1; + end + end + end +endmodule
\ No newline at end of file |
