-
Notifications
You must be signed in to change notification settings - Fork 43
/
Arbiter_Priority.html
149 lines (130 loc) · 5.83 KB
/
Arbiter_Priority.html
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Arbiter_Priority.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Returns a one-hot grant bitmask of the least-significant bit set in a word, where bit 0 can be viewed as having highest priority. *A grant is held until the request is released.*">
<title>Arbiter Priority</title>
</head>
<body>
<p class="inline bordered"><b><a href="./Arbiter_Priority.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>
<h1>A Priority Arbiter</h1>
<p>Returns a one-hot grant bitmask of the least-significant bit set in a word,
where bit 0 can be viewed as having highest priority. <em>A grant is held
until the request is released.</em></p>
<p>The requestors must raise and hold a <code>requests</code> bit and wait until the
corresponding <code>grant</code> bit rises to begin their transaction. <em>Grants are
calculated combinationally from the requests</em>, so pipeline as necessary.
The highest priority pending and unmasked request is granted once the
currently granted request is released. The grant remains for as long as
the request is held without interruption. Requesters can raise or drop
their requests before their turn comes, but this must be done synchronously
to the clock.</p>
<h2>Usage</h2>
<p>A common use-case for an arbiter is to drive a <a href="./Multiplexer_One_Hot.html">one-hot
multiplexer</a> to select one of multiple senders
requesting for one receiver, or one of multiple receivers requesting from
one sender. This arrangement requires that the requestors can raise and
hold a <code>requests</code> bit, wait until they receive the correspondig <code>grant</code> bit
to begin their transaction, and to drop their <code>requests</code> bit only once they
are done. This is very similar to a ready/valid handshake, except that the
transaction cannot be interrupted, else the granted access is lost.</p>
<h2>Fairness</h2>
<p><strong>A Priority Arbiter is not fair:</strong> if a higher-priority request happens too
frequently it will starve lower-priority requests, and if a lower-priority
request holds its grant too long it will starve higher-priority requests,
causing priority inversion. To distribute the grants fairly, you need
a <a href="./Arbiter_Round_Robin.html">Round-Robin Arbiter</a>.</p>
<h3>Customizations</h3>
<p>To enable the creation of custom fairness adjustments, the <code>requests_mask</code>
input can be used to exclude one or more requests from being granted in the
current cycle, and must be updated synchronously to the <code>clock</code>. The
<code>requests_mask</code> is arbitrary, and if desired can be calculated from the
current <code>requests</code>, the <code>grant_previous</code> one-hot output which holds the
<code>grant</code> from the previous clock cycle, and the current one-hot <code>grant</code>
output.</p>
<ul>
<li>Since a grant typically lasts longer than one cycle and won't get granted
again for several cycles, taking multiple cycles to compute the next
<code>requests_mask</code> is a valid option.</li>
<li>The <code>requests_mask</code> is applied combinationally to the <code>requests</code> input
and to the internal <code>grant_previous</code>, both of which have a combinational
path to <code>grant</code>, so pipeline as necessary. </li>
</ul>
<p>If unused, leave <code>requests_mask</code> set to all-ones, and the masking logic
will optimize away.</p>
<pre>
`default_nettype none
module <a href="./Arbiter_Priority.html">Arbiter_Priority</a>
#(
parameter INPUT_COUNT = 0
)
(
input wire clock,
input wire clear,
input wire [INPUT_COUNT-1:0] requests,
input wire [INPUT_COUNT-1:0] requests_mask, // Set to all-ones if unused.
output wire [INPUT_COUNT-1:0] grant_previous,
output reg [INPUT_COUNT-1:0] grant
);
localparam INPUT_ZERO = {INPUT_COUNT{1'b0}};
initial begin
grant = INPUT_ZERO;
end
</pre>
<p>First we filter the requests, masking off any externally disabled requestst
(<code>requests_mask</code> bit is 0)</p>
<pre>
reg [INPUT_COUNT-1:0] requests_masked = INPUT_ZERO;
always @(*) begin
requests_masked = requests & requests_mask;
end
</pre>
<p>Then, from the remaining requests, we further mask out all but the highest
priority (lowest bit) set request. This is the new grant candidate.</p>
<pre>
wire [INPUT_COUNT-1:0] grant_candidate;
<a href="./Bitmask_Isolate_Rightmost_1_Bit.html">Bitmask_Isolate_Rightmost_1_Bit</a>
#(
.WORD_WIDTH (INPUT_COUNT)
)
priority_mask
(
.word_in (requests_masked),
.word_out (grant_candidate)
);
</pre>
<p>If the request granted on the previous clock cycle is still active, hold it.
Else, select the current candidate. </p>
<pre>
always @(*) begin
grant = ((requests & grant_previous) != INPUT_ZERO) ? grant_previous : grant_candidate;
end
</pre>
<p>A grant cannot be interrupted by a higher priority request until the current
granted request is released. We need a register to store the current grant
for the next clock cycle.</p>
<pre>
<a href="./Register.html">Register</a>
#(
.WORD_WIDTH (INPUT_COUNT),
.RESET_VALUE (INPUT_ZERO)
)
previously_granted_request
(
.clock (clock),
.clock_enable (1'b1),
.clear (clear),
.data_in (grant),
.data_out (grant_previous)
);
endmodule
</pre>
<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>