-
-
Save ddm/4e6d6aa51724b4bae020d645b2f9232e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A round-robin priority arbiter for valid/ready signaling using carry chain logic. | |
module arbiter#(parameter N = 2) | |
( | |
input wire clk, | |
input wire [N-1:0] s_valid, | |
output wire [N-1:0] s_ready, | |
output wire m_valid, | |
input wire m_ready | |
); | |
// This mask has a bit set when the corresponding lane is deprioritized this cycle. | |
reg [N-1:0] mask = 0; | |
// Isolate the highest priority valid lane (lower bits are higher priority). | |
wire [N-1:0] valid_isolated = s_valid & -s_valid; | |
// Mask out any deprioritized lanes. | |
wire [N-1:0] valid_prioritized = s_valid & ~mask; | |
// Isolate the highest priority prioritized valid lane. | |
wire [N-1:0] valid_prioritized_isolated = valid_prioritized & -valid_prioritized; | |
// Pick the highest priority prioritized lane. If none exists, include deprioritized lanes as well. | |
wire [N-1:0] valid = |valid_prioritized_isolated ? valid_prioritized_isolated : valid_isolated; | |
// You'd probably want to register these outputs since there's a lot of logic hanging off of them. | |
assign m_valid = |s_valid; | |
assign s_ready = {N{m_ready}} & valid; | |
always @(posedge clk) | |
// Deprioritize the chosen lane and all higher priority lanes in the next cycle. | |
// If s_ready is zero then all lanes will be deprioritized, which is a no-op. | |
mask <= (s_ready << 1) - 1; | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment