related articles
Digital IC front-end study notes: LSFR (Linear Feedback Shift Register)
Digital IC front-end study notes: cross-clock domain signal synchronization
Digital IC front-end study notes: signal synchronization and edge detection
Digital IC front-end study notes: synthesis of latch Latch
Digital IC front-end study notes: Verilog implementation of FIFO (1)
Digital IC front-end study notes: Verilog implementation of FIFO (2)
Digital IC front-end study notes: arbitration polling (1)
Digital IC front-end study notes: arbitration polling (2)
Digital IC front-end study notes: arbitration polling (3)
Digital IC front-end study notes: arbitration polling (4)
Digital IC front-end study notes: arbitration polling (5)
Digital IC front-end study notes: least recently used (LRU) algorithm
8. Group polling
In some applications, users are divided into two groups: a fast group and a slow group. As shown in the figure below, users in the fast group have the same priority, and a fair polling method is adopted internally. Similarly, users in the slow group also have the same priority, and a fair round-robin method is also adopted in the slow group. However, there is a nested relationship between the fast group and the slow group, that is, the entire slow group is regarded as a user of the fast group. For example, the fast group has two users (A,B) and the slow group has two users (C,D). If all users make requests, the polling sequence is:
A,B,C,A,B,D,A,B,C,A,B,D ......
The codes and simulation results of the two groups of polling are as follows.
module arbiter_twogroups(clk, resetb,
req_vec_groupa,
end_access_vec_groupa,
req_vec_groupb,
end_access_vec_groupb,
gnt_vec_groupa,
gnt_vec_groupb);
input clk;
input resetb;
input [1:0] req_vec_groupa;
input [1:0] end_access_vec_groupa;
input [1:0] req_vec_groupb;
input [1:0] end_access_vec_groupb;
output [1:0] gnt_vec_groupa;
output [1:0] gnt_vec_groupb;
reg [1:0] arbiter_state, arbiter_state_nxt;
reg [2:0] gnt_vec, gnt_vec_nxt;
reg [2:0] relative_req_vec;
wire any_req_asserted;
reg [1:0] grant_posn, grant_posn_nxt;
wire any_req_asserted_slow;
wire [1:0] gnt_vec_groupa;
wire [1:0] gnt_vec_groupb;
reg [1:0] grant_posn_slow, grant_posn_slow_nxt;
parameter IDLE = 2'b01;
parameter END_ACCESS = 2'b10;
assign any_req_asserted = (req_vec_groupa != 0) || (req_vec_groupb != 0);
assign any_req_asserted_slow = (req_vec_groupb != 0);
assign gnt_vec_groupa = gnt_vec[1:0];
assign gnt_vec_groupb[0] = gnt_vec[2] & grant_posn_slow[0];
assign gnt_vec_groupb[1] = gnt_vec[2] & grant_posn_slow[1];
always@(*) begin
relative_req_vec = {any_req_asserted_slow,
req_vec_groupa[1],
req_vec_groupa[0]};
case(grant_posn)
2'd0: relative_req_vec = {req_vec_groupa[0],
any_req_asserted_slow,
req_vec_groupa[1]};
2'd1: relative_req_vec = {req_vec_groupa[1],
req_vec_groupa[0],
any_req_asserted_slow};
2'd2: relative_req_vec = {any_req_asserted_slow,
req_vec_groupa[1],
req_vec_groupa[0]};
endcase
end
always@(*) begin
arbiter_state_nxt = arbiter_state;
grant_posn_nxt = grant_posn;
gnt_vec_nxt = gnt_vec;
grant_posn_slow_nxt = grant_posn_nxt;
case(arbiter_state)
IDLE: begin
if(((gnt_vec_groupa == 0) && (gnt_vec_groupb == 0))||
(end_access_vec_groupa[0] & gnt_vec_groupa[0]) ||
(end_access_vec_groupa[1] & gnt_vec_groupa[1]) ||
(end_access_vec_groupb[0] & gnt_vec_groupb[0]) ||
(end_access_vec_groupb[1] & gnt_vec_groupb[1])) begin
if(any_req_asserted)
arbiter_state_nxt = END_ACCESS;
if(relative_req_vec[0]) begin
case(grant_posn)
2'd0: gnt_vec_nxt = 3'b010;
2'd1:begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd2: gnt_vec_nxt = 3'b001;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 1;
2'd1: grant_posn_nxt = 2;
2'd2: grant_posn_nxt = 0;
endcase
end
else if(relative_req_vec[1]) begin
case(grant_posn)
2'd0: begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd1: gnt_vec_nxt = 3'b001;
2'd2: gnt_vec_nxt = 3'b010;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 2;
2'd1: grant_posn_nxt = 0;
2'd2: grant_posn_nxt = 1;
endcase
end
else if(relative_req_vec[2]) begin
case(grant_posn)
2'd2: begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd0: gnt_vec_nxt = 3'b001;
2'd1: gnt_vec_nxt = 3'b010;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 0;
2'd1: grant_posn_nxt = 1;
2'd2: grant_posn_nxt = 2;
endcase
end
end
end
END_ACCESS: begin
if((end_access_vec_groupa[0] & gnt_vec_groupa[0]) ||
(end_access_vec_groupa[1] & gnt_vec_groupa[1]) ||
(end_access_vec_groupb[0] & gnt_vec_groupb[0]) ||
(end_access_vec_groupb[1] & gnt_vec_groupb[1])) begin
arbiter_state_nxt = IDLE;
if(relative_req_vec[0]) begin
case(grant_posn)
2'd0: gnt_vec_nxt = 3'b010;
2'd1: begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd2: gnt_vec_nxt = 3'b001;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 1;
2'd1: grant_posn_nxt = 2;
2'd2: grant_posn_nxt = 0;
endcase
end
else if(relative_req_vec[1]) begin
case(grant_posn)
2'd0: begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd1: gnt_vec_nxt = 3'b001;
2'd2: gnt_vec_nxt = 3'b010;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 2;
2'd1: grant_posn_nxt = 0;
2'd2: grant_posn_nxt = 1;
endcase
end
else if(relative_req_vec[2]) begin
case(grant_posn)
2'd2: begin
gnt_vec_nxt = 3'b100;
if(grant_posn_slow[0]) begin
if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
else if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
end
else if(grant_posn_slow[1]) begin
if(req_vec_groupb[0])
grant_posn_slow_nxt = 2'b01;
else if(req_vec_groupb[1])
grant_posn_slow_nxt = 2'b10;
end
end
2'd0: gnt_vec_nxt = 3'b001;
2'd1: gnt_vec_nxt = 3'b010;
endcase
case(grant_posn)
2'd0: grant_posn_nxt = 0;
2'd1: grant_posn_nxt = 1;
2'd2: grant_posn_nxt = 2;
endcase
end
end
end
endcase
end
always@(posedge clk, negedge resetb) begin
if(!resetb) begin
arbiter_state <= IDLE;
gnt_vec <= 0;
grant_posn <= 2;
grant_posn_slow <= 2;
end
else begin
arbiter_state <= arbiter_state_nxt;
gnt_vec <= gnt_vec_nxt;
grant_posn <= grant_posn_nxt;
grant_posn_slow <= grant_posn_slow_nxt;
end
end
endmodule
The above content comes from "Verilog Advanced Digital System Design Technology and Example Analysis"