相关文章
数字IC前端学习笔记:LSFR(线性反馈移位寄存器)
数字IC前端学习笔记:跨时钟域信号同步
数字IC前端学习笔记:信号同步和边沿检测
数字IC前端学习笔记:锁存器Latch的综合
数字IC前端学习笔记:格雷码(含Verilog实现的二进制格雷码转换器)
数字IC前端学习笔记:FIFO的Verilog实现(一)
数字IC前端学习笔记:FIFO的Verilog实现(二)
数字IC前端学习笔记:仲裁轮询(一)
数字IC前端学习笔记:仲裁轮询(二)
数字IC前端学习笔记:仲裁轮询(三)
数字IC前端学习笔记:仲裁轮询(四)
数字IC前端学习笔记:仲裁轮询(五)
8.分组轮询
在一些应用中,用户被分成两组:快组和慢组。如下图所示,快组内的用户具有相同的优先级,内部采用公平轮询方式。类似地,慢组内的用户也具有相同优先级,慢组内部也采用公平轮询方式。但快组慢组之间是嵌套的关系,即整个慢组被当做是快组的一个用户。例如,快组有两个用户(A,B),慢组也有两个用户(C,D)。如果所有用户都发出请求,那么轮询序列为:
A,B,C,A,B,D,A,B,C,A,B,D ......
两组轮询的代码及仿真结果如下。
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