-
Notifications
You must be signed in to change notification settings - Fork 22
/
round_robin_arbiter3.v
77 lines (67 loc) · 1.61 KB
/
round_robin_arbiter3.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//Using Two Simple Priority Arbiters with a Mask - scalable
//author: [email protected]
module round_robin_arbiter (
rst_an,
clk,
req,
grant
);
parameter N = 4;
input rst_an;
input clk;
input [N-1:0] req;
output [N-1:0] grant;
reg [N-1:0] rotate_ptr;
wire [N-1:0] mask_req;
wire [N-1:0] mask_grant;
wire [N-1:0] grant_comb;
reg [N-1:0] grant;
wire no_mask_req;
wire [N-1:0] nomask_grant;
wire update_ptr;
genvar i;
// rotate pointer update logic
assign update_ptr = |grant[N-1:0];
always @ (posedge clk or negedge rst_an)
begin
if (!rst_an)
rotate_ptr[N-1:0] <= {N{1'b1}};
else if (update_ptr)
begin
// note: N must be at least 2
rotate_ptr[0] <= grant[N-1];
rotate_ptr[1] <= grant[N-1] | grant[0];
end
end
generate
for (i=2;i<N;i=i+1)
always @ (posedge clk or negedge rst_an)
begin
if (!rst_an)
rotate_ptr[i] <= 1'b1;
else if (update_ptr)
rotate_ptr[i] <= grant[N-1] | (|grant[i-1:0]);
end
endgenerate
// mask grant generation logic
assign mask_req[N-1:0] = req[N-1:0] & rotate_ptr[N-1:0];
assign mask_grant[0] = mask_req[0];
generate
for (i=1;i<N;i=i+1)
assign mask_grant[i] = (~|mask_req[i-1:0]) & mask_req[i];
endgenerate
// non-mask grant generation logic
assign nomask_grant[0] = req[0];
generate
for (i=1;i<N;i=i+1)
assign nomask_grant[i] = (~|req[i-1:0]) & req[i];
endgenerate
// grant generation logic
assign no_mask_req = ~|mask_req[N-1:0];
assign grant_comb[N-1:0] = mask_grant[N-1:0] | (nomask_grant[N-1:0] & {N{no_mask_req}});
always @ (posedge clk or negedge rst_an)
begin
if (!rst_an) grant[N-1:0] <= {N{1'b0}};
else grant[N-1:0] <= grant_comb[N-1:0] & ~grant[N-1:0];
end
endmodule