OpenCores
URL https://opencores.org/ocsvn/scalable_arbiter/scalable_arbiter/trunk

Subversion Repositories scalable_arbiter

[/] [scalable_arbiter/] [trunk/] [rtl/] [verilog/] [arbiter.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 kendallc
/*
2
 * Copyright (c) 2008-2009, Kendall Correll
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
 
17
`timescale 1ns / 1ps
18
 
19
// Two synchronous arbiter implementations are provided:
20
// 'arbiter' and 'arbiter_x2'. Both are round-robin arbiters
21
// with a configurable number of inputs. The algorithm used is
22
// recursive in that you can build a larger arbiter from a
23
// tree of smaller arbiters. 'arbiter_x2' is a tree of
24
// 'arbiter' modules, 'arbiter' is a tree of 'arbiter_node'
25
// modules, and 'arbiter_node' is the primitive of the
26
// algorithm, a two input round-robin arbiter.
27
//
28
// Both 'arbiter' and 'arbiter_x2' can take multiple clocks
29
// to grant a request. (Of course, neither arbiter should
30
// assert an invalid grant while changing state.) 'arbiter'
31
// can take up to three clocks to grant a req, and 'arbiter_x2'
32
// can take up to five clocks. 'arbiter_x2' is probably only
33
// necessary for configurations over a thousand inputs.
34
// Presently, the width of both 'arbiter' and 'arbiter_x2'
35
// must be power of two due to the way they instantiate a tree
36
// of sub-arbiters. Extra inputs can be assigned to zero, and
37
// extra outputs can be left disconnected.
38
//
39
// Parameters for 'arbiter' and 'arbiter_x2':
40
//   'width' is width of the 'req' and 'grant' ports, which
41
//     must be a power of two.
42
//   'select_width' is the width of the 'select' port, which
43
//     should be the log base two of 'width'.
44
//
45
// Ports for 'arbiter' and 'arbiter_x2':
46
//   'enable' masks the 'grant' outputs. It is used to chain
47
//     arbiters together, but it might be useful otherwise.
48
//     It can be left disconnected if not needed.
49
//   'req' are the input lines asserted to request access to
50
//     the arbitrated resource.
51
//   'grant' are the output lines asserted to grant each
52
//     requestor access to the arbitrated resource.
53
//   'select' is a binary encoding of the bitwise 'grant'
54
//     output. It is useful to control a mux that connects
55
//     requestor outputs to the arbitrated resource. It can
56
//     be left disconnected if not needed.
57
//   'valid' is asserted when any 'req' is asserted. It is
58
//     used to chain arbiters together, but it might be
59
//     otherwise useful. It can be left disconnected if not
60
//     needed.
61
 
62
// 'arbiter_x2' is a two-level tree of arbiters made from
63
// registered 'arbiter' modules. It allows a faster clock in
64
// large configurations by breaking the arbiter into two
65
// registered stages. For most uses, the standard 'arbiter'
66
// module is plenty fast. See the 'demo_arbiter' module for
67
// some implemntation results.
68
 
69
module arbiter_x2 #(
70
        parameter width = 0,
71
        parameter select_width = 1
72
)(
73
        input enable,
74
        input [width-1:0] req,
75
        output reg [width-1:0] grant,
76
        output reg [select_width-1:0] select,
77
        output reg valid,
78
 
79
        input clock,
80
        input reset
81
);
82
 
83
`include "functions.v"
84
 
85
// 'width1' is the width of the first stage arbiters, which
86
// is the square root of 'width' rounded up to the nearest
87
// power of 2, calculated as: exp2(ceiling(log2(width)/2))
88
parameter width1 = 1 << ((clog2(width)/2) + (clog2(width)%2));
89
parameter select_width1 = clog2(width1);
90
 
91
// 'width0' is the the width of the second stage arbiter,
92
// which is the number of arbiters in the first stage.
93
parameter width0 = width/width1;
94
parameter select_width0 = clog2(width0);
95
 
96
genvar g;
97
 
98
wire [width-1:0] grant1;
99
wire [(width0*select_width1)-1:0] select1;
100
wire [width0-1:0] enable1;
101
wire [width0-1:0] req0;
102
wire [width0-1:0] grant0;
103
wire [select_width0-1:0] select0;
104
wire valid0;
105
wire [select_width1-1:0] select_mux[width0-1:0];
106
 
107
assign enable1 = grant0 & req0;
108
 
109
// Register the outputs.
110
always @(posedge clock, posedge reset)
111
begin
112
        if(reset)
113
        begin
114
                valid <= 0;
115
                grant <= 0;
116
                select <= 0;
117
        end
118
        else
119
        begin
120
                valid <= valid0;
121
                grant <= grant1;
122
                select <= { select0, select_mux[select0] };
123
        end
124
end
125
 
126
// Instantiate the first stage of the arbiter tree.
127
arbiter #(
128
        .width(width1),
129
        .select_width(select_width1)
130
) stage1_arbs[width0-1:0] (
131
        .enable(enable1),
132
        .req(req),
133
        .grant(grant1),
134
        .select(select1),
135
        .valid(req0),
136
 
137
        .clock(clock),
138
        .reset(reset)
139
);
140
 
141
// Instantiate the second stage of the arbiter tree.
142
arbiter #(
143
        .width(width0),
144
        .select_width(select_width0)
145
) stage0_arb (
146
        .enable(enable),
147
        .req(req0),
148
        .grant(grant0),
149
        .select(select0),
150
        .valid(valid0),
151
 
152
        .clock(clock),
153
        .reset(reset)
154
);
155
 
156
// Generate muxes for the select outputs.
157
generate
158
for(g = 0; g < width0; g = g + 1)
159
begin: gen_mux
160
        assign select_mux[g] = select1[((g+1)*select_width1)-1-:select_width1];
161
end
162
endgenerate
163
 
164
endmodule
165
 
166
// 'arbiter' is a tree made from unregistered 'arbiter_node'
167
// modules. Unregistered carries between nodes allows
168
// the tree to change state on the same clock. The tree
169
// contains (width - 1) nodes, so resource usage of the
170
// arbiter grows linearly. The number of levels and thus the
171
// propogation delay down the tree grows with log2(width).
172
// The logarithmic delay scaling makes this arbiter suitable
173
// for large configuations. This module can take up to three
174
// clocks to grant the next requestor after its inputs change
175
// (two clocks for the 'arbiter_node' modules and one clock
176
// for the output registers).
177
 
178
module arbiter #(
179
        parameter width = 0,
180
        parameter select_width = 1
181
)(
182
        input enable,
183
        input [width-1:0] req,
184
        output reg [width-1:0] grant,
185
        output reg [select_width-1:0] select,
186
        output reg valid,
187
 
188
        input clock,
189
        input reset
190
);
191
 
192
`include "functions.v"
193
 
194
genvar g;
195
 
196
// These wires interconnect arbiter nodes.
197
wire [2*width-2:0] interconnect_req;
198
wire [2*width-2:0] interconnect_grant;
199
wire [width-2:0] interconnect_select;
200
wire [mux_sum(width,clog2(width))-1:0] interconnect_mux;
201
 
202
// Assign inputs to some interconnects.
203
assign interconnect_req[2*width-2-:width] = req;
204
assign interconnect_grant[0] = enable;
205
 
206
// Assign the select outputs of the first arbiter stage to
207
// the first mux stage.
208
assign interconnect_mux[mux_sum(width,clog2(width))-1-:width/2] = interconnect_select[width-2-:width/2];
209
 
210
// Register some interconnects as outputs.
211
always @(posedge clock, posedge reset)
212
begin
213
        if(reset)
214
        begin
215
                valid <= 0;
216
                grant <= 0;
217
                select <= 0;
218
        end
219
        else
220
        begin
221
                valid <= interconnect_req[0];
222
                grant <= interconnect_grant[2*width-2-:width];
223
                select <= interconnect_mux[clog2(width)-1:0];
224
        end
225
end
226
 
227
// Generate the stages of the arbiter tree. Each stage is
228
// instantiated as an array of 'abiter_node' modules and
229
// is half the width of the previous stage. Some simple
230
// arithmetic part-selects the interconnects for each stage.
231
// See the "Request/Grant Interconnections" diagram of an
232
// arbiter in the documentation.
233
generate
234
for(g = width; g >= 2; g = g / 2)
235
begin: gen_arb
236
        arbiter_node nodes[(g/2)-1:0] (
237
                .enable(interconnect_grant[g-2-:g/2]),
238
                .req(interconnect_req[2*g-2-:g]),
239
                .grant(interconnect_grant[2*g-2-:g]),
240
                .select(interconnect_select[g-2-:g/2]),
241
                .valid(interconnect_req[g-2-:g/2]),
242
 
243
                .clock(clock),
244
                .reset(reset)
245
        );
246
end
247
endgenerate
248
 
249
// Generate the select muxes for each stage of the arbiter
250
// tree. The generate begins on the second stage because
251
// there are no muxes in the first stage. Each stage is
252
// a two dimensional array of muxes, where the dimensions
253
// are number of arbiter nodes in the stage times the
254
// number of preceeding stages. It takes some tricky
255
// arithmetic to part-select the interconnects for each
256
// stage. See the "Select Interconnections" diagram of an
257
// arbiter in the documentation.
258
generate
259
for(g = width/2; g >= 2; g = g / 2)
260
begin: gen_mux
261
        mux_array #(
262
                .width(g/2)
263
        ) mux_array[clog2(width/g)-1:0] (
264
                .in(interconnect_mux[mux_sum(g,clog2(width))-1-:clog2(width/g)*g]),
265
                .select(interconnect_select[g-2-:g/2]),
266
                .out(interconnect_mux[mux_sum(g/2,clog2(width))-(g/2)-1-:clog2(width/g)*g/2])
267
        );
268
        assign interconnect_mux[mux_sum(g/2,clog2(width))-1-:g/2] = interconnect_select[g-2-:g/2];
269
end
270
endgenerate
271
 
272
endmodule
273
 
274
module mux_array #(
275
        parameter width = 0
276
)(
277
        input [(2*width)-1:0] in,
278
        input [width-1:0] select,
279
        output [width-1:0] out
280
);
281
 
282
mux_node nodes[width-1:0] (
283
        .in(in),
284
        .select(select),
285
        .out(out)
286
        );
287
 
288
endmodule
289
 
290
module mux_node (
291
        input [1:0] in,
292
        input select,
293
        output out
294
);
295
 
296
assign out = select ?  in[1] : in[0];
297
 
298
endmodule
299
 
300
// This is a two input round-robin arbiter with the
301
// addition of the 'valid' and 'enable' signals
302
// that allow multiple nodes to be connected to form a
303
// larger arbiter. Outputs are not registered to allow
304
// interconnected nodes to change state on the same clock.
305
 
306
module arbiter_node (
307
        input enable,
308
        input [1:0] req,
309
        output [1:0] grant,
310
        output select,
311
        output valid,
312
 
313
        input clock,
314
        input reset
315
);
316
 
317
// The state determines which 'req' is granted. State '0'
318
// grants 'req[0]', state '1' grants 'req[1]'.
319
reg grant_state;
320
wire next_state;
321
 
322
// The 'grant' of this stage is masked by 'enable', which
323
// carries the grants of the subsequent stages back to this
324
// stage. The 'grant' is also masked by 'req' to ensure that
325
// 'grant' is dropped as soon 'req' goes away.
326
assign grant[0] = req[0] & ~grant_state & enable;
327
assign grant[1] = req[1] & grant_state & enable;
328
 
329
// Select is a binary value that tracks grant. It could
330
// be used to control a mux on the arbitrated resource.
331
assign select = grant_state;
332
 
333
// The 'valid' carries reqs to subsequent stages. It is
334
// high when the 'req's are high, except during 1-to-0 state
335
// transistions when it's dropped for a cycle to allow
336
// subsequent arbiter stages to make progress. This causes a
337
// two cycle turnaround for 1-to-0 state transistions.
338
/*
339
always @(grant_state, next_state, req)
340
begin
341
        if(grant_state & ~next_state)
342
                valid <= 0;
343
        else if(req[0] | req[1])
344
                valid <= 1;
345
        else
346
                valid <= 0;
347
end
348
*/
349
// reduced 'valid' logic
350
assign valid = (req[0] & ~grant_state) | req[1];
351
 
352
// The 'next_state' logic implements round-robin fairness
353
// for two inputs. When both reqs are asserted, 'req[0]' is
354
// granted first. This state machine along with some output
355
// logic can be cascaded to implement round-robin fairness
356
// for many inputs.
357
/*
358
always @(grant_state, req)
359
begin
360
        case(grant_state)
361
        0:
362
                if(req[0])
363
                        next_state <= 0;
364
                else if(req[1])
365
                        next_state <= 1;
366
                else
367
                        next_state <= 0;
368
        1:
369
                if(req[1])
370
                        next_state <= 1;
371
                else
372
                        next_state <= 0;
373
        endcase
374
end
375
*/
376
// reduced next state logic
377
assign next_state = (req[1] & ~req[0]) | (req[1] & grant_state);
378
 
379
// state register
380
always @(posedge clock, posedge reset)
381
begin
382
        if(reset)
383
                grant_state <= 0;
384
        else
385
                grant_state <= next_state;
386
end
387
 
388
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.