OpenCores
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

powered by: WebSVN 2.1.0

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