URL
https://opencores.org/ocsvn/round_robin_arbiter/round_robin_arbiter/trunk
Subversion Repositories round_robin_arbiter
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/round_robin_arbiter/trunk/round_robin_arbiter3.v
0,0 → 1,77
//Using Two Simple Priority Arbiters with a Mask - scalable |
//author: dongjun_luo@hotmail.com |
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 |
/round_robin_arbiter/trunk/tb.v
0,0 → 1,50
module tb(); |
|
reg clk; |
reg req0; |
reg req1; |
reg req2; |
reg req3; |
reg rst_an; |
|
round_robin_arbiter dut ( |
.req({req3,req2,req1,req0}), |
.grant({grant3,grant2,grant1,grant0}), |
.clk(clk), |
.rst_an(rst_an) |
); |
|
initial |
begin |
clk = 0; |
req3 = 0; |
req2 = 0; |
req1 = 0; |
req0 = 0; |
rst_an = 1'b1; |
#10 rst_an = 0; |
#10 rst_an = 1; |
repeat (1) @ (posedge clk); |
req0 <= 1; |
repeat (1) @ (posedge clk); |
req0 <= 0; |
repeat (1) @ (posedge clk); |
req0 <= 1; |
req1 <= 1; |
repeat (1) @ (posedge clk); |
req2 <= 1; |
req1 <= 0; |
repeat (1) @ (posedge clk); |
req3 <= 1; |
req2 <= 0; |
repeat (1) @ (posedge clk); |
req3 <= 0; |
repeat (1) @ (posedge clk); |
req0 <= 0; |
repeat (1) @ (posedge clk); |
#10 $finish; |
|
end |
|
always #1 clk = ~clk; |
endmodule |
/round_robin_arbiter/trunk/readme.txt
0,0 → 1,9
arbiter1: rotate->priority->rotate (4 request lines) |
arbiter2: two simple priority arbiter with a mask (4 request lines) |
arbiter3: two simple priority arbiter with a mask (N request lines) |
|
These arbiters can be used for any purposes. |
contact if any problems: dongjun_luo@hotmail.com |
|
Reference: |
[1] Matt Weber, "Arbiters: Design Ideas and Coding Styles" |
/round_robin_arbiter/trunk/round_robin_arbiter.v
0,0 → 1,74
//Rotate -> Priority -> Rotate |
//author: dongjun_luo@hotmail.com |
module round_robin_arbiter ( |
rst_an, |
clk, |
req, |
grant |
); |
|
|
input rst_an; |
input clk; |
input [3:0] req; |
output [3:0] grant; |
|
reg [1:0] rotate_ptr; |
reg [3:0] shift_req; |
reg [3:0] shift_grant; |
reg [3:0] grant_comb; |
reg [3:0] grant; |
|
// shift req to round robin the current priority |
always @ (*) |
begin |
case (rotate_ptr[1:0]) |
2'b00: shift_req[3:0] = req[3:0]; |
2'b01: shift_req[3:0] = {req[0],req[3:1]}; |
2'b10: shift_req[3:0] = {req[1:0],req[3:2]}; |
2'b11: shift_req[3:0] = {req[2:0],req[3]}; |
endcase |
end |
|
// simple priority arbiter |
always @ (*) |
begin |
shift_grant[3:0] = 4'b0; |
if (shift_req[0]) shift_grant[0] = 1'b1; |
else if (shift_req[1]) shift_grant[1] = 1'b1; |
else if (shift_req[2]) shift_grant[2] = 1'b1; |
else if (shift_req[3]) shift_grant[3] = 1'b1; |
end |
|
// generate grant signal |
always @ (*) |
begin |
case (rotate_ptr[1:0]) |
2'b00: grant_comb[3:0] = shift_grant[3:0]; |
2'b01: grant_comb[3:0] = {shift_grant[2:0],shift_grant[3]}; |
2'b10: grant_comb[3:0] = {shift_grant[1:0],shift_grant[3:2]}; |
2'b11: grant_comb[3:0] = {shift_grant[0],shift_grant[3:1]}; |
endcase |
end |
|
always @ (posedge clk or negedge rst_an) |
begin |
if (!rst_an) grant[3:0] <= 4'b0; |
else grant[3:0] <= grant_comb[3:0] & ~grant[3:0]; |
end |
|
// update the rotate pointer |
// rotate pointer will move to the one after the current granted |
always @ (posedge clk or negedge rst_an) |
begin |
if (!rst_an) |
rotate_ptr[1:0] <= 2'b0; |
else |
case (1'b1) // synthesis parallel_case |
grant[0]: rotate_ptr[1:0] <= 2'd1; |
grant[1]: rotate_ptr[1:0] <= 2'd2; |
grant[2]: rotate_ptr[1:0] <= 2'd3; |
grant[3]: rotate_ptr[1:0] <= 2'd0; |
endcase |
end |
endmodule |
/round_robin_arbiter/trunk/round_robin_arbiter2.v
0,0 → 1,68
//Using Two Simple Priority Arbiters with a Mask |
//author: dongjun_luo@hotmail.com |
module round_robin_arbiter ( |
rst_an, |
clk, |
req, |
grant |
); |
|
|
input rst_an; |
input clk; |
input [3:0] req; |
output [3:0] grant; |
|
reg [3:0] rotate_ptr; |
wire [3:0] mask_req; |
reg [3:0] mask_grant; |
wire [3:0] grant_comb; |
reg [3:0] grant; |
wire no_mask_req; |
reg [3:0] nomask_grant; |
|
always @ (posedge clk or negedge rst_an) |
begin |
if (!rst_an) |
rotate_ptr[3:0] <= 4'b1111; |
else |
case (1'b1) // synthesis parallel_case |
grant[0]: rotate_ptr[3:0] <= 4'b1110; |
grant[1]: rotate_ptr[3:0] <= 4'b1100; |
grant[2]: rotate_ptr[3:0] <= 4'b1000; |
grant[3]: rotate_ptr[3:0] <= 4'b1111; |
endcase |
end |
|
assign mask_req[3:0] = req[3:0] & rotate_ptr[3:0]; |
|
// simple priority arbiter for mask req |
always @ (*) |
begin |
mask_grant[3:0] = 4'b0; |
if (mask_req[0]) mask_grant[0] = 1'b1; |
else if (mask_req[1]) mask_grant[1] = 1'b1; |
else if (mask_req[2]) mask_grant[2] = 1'b1; |
else if (mask_req[3]) mask_grant[3] = 1'b1; |
end |
|
// simple priority arbiter for no mask req |
always @ (*) |
begin |
nomask_grant[3:0] = 4'b0; |
if (req[0]) nomask_grant[0] = 1'b1; |
else if (req[1]) nomask_grant[1] = 1'b1; |
else if (req[2]) nomask_grant[2] = 1'b1; |
else if (req[3]) nomask_grant[3] = 1'b1; |
end |
|
assign no_mask_req = ~|mask_req[3:0]; |
//assign grant_comb[3:0] = no_mask_req ? nomask_grant[3:0] : mask_grant[3:0]; |
assign grant_comb[3:0] = (nomask_grant[3:0] & {4{no_mask_req}}) | mask_grant[3:0]; |
|
always @ (posedge clk or negedge rst_an) |
begin |
if (!rst_an) grant[3:0] <= 4'b0; |
else grant[3:0] <= grant_comb[3:0] & ~grant[3:0]; |
end |
endmodule |