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 (6)
Digital IC front-end study notes: least recently used (LRU) algorithm
7. Round robin with weights (Part 2)
In the previous part, we designed Verilog for the first licensing method of the first method of arbitration, and then we will use Verilog to design the second licensing method of the first method, that is, when all users make requests, authorization sequence is
A,B,C,A,B,A B,C,A,B,A,A ......
The following is the code and simulation results.
module arbiter_wrr_2(clk,resetb,
req_vec,
req_vec_wt_0,
req_vec_wt_1,
req_vec_wt_2,
req_n_valid,
end_access_vec,
gnt_vec);
input clk;
input resetb;
input [2:0] req_vec;
input [3:0] req_vec_wt_0;
input [3:0] req_vec_wt_1;
input [3:0] req_vec_wt_2;
input req_n_valid;
input [2:0] end_access_vec;
output [2:0] gnt_vec;
reg [2:0] arbiter_state, arbiter_state_nxt;
reg [2:0] gnt_vec, gnt_vec_nxt;
reg [3:0] count_req_vec [2:0];
reg [3:0] count_req_vec_nxt [2:0];
wire [2:0] cnt_reqdone_vec;
reg [2:0] relative_req_vec;
reg [1:0] grant_posn, grant_posn_nxt;
reg [2:0] relative_cntdone_vec;
reg [3:0] req_vec_wt_stored [2:0];
reg [3:0] req_vec_wt_stored_nxt [2:0];
wire [3:0] req_vec_wt [2:0];
parameter IDLE = 3'b001;
parameter ARM_VALUE = 3'b010;
parameter END_ACCESS = 3'b100;
assign req_vec_wt[0] = req_vec_wt_0;
assign req_vec_wt[1] = req_vec_wt_1;
assign req_vec_wt[2] = req_vec_wt_2;
always@(*) begin
relative_req_vec = req_vec;
relative_cntdone_vec = cnt_reqdone_vec;
case(grant_posn)
2'd0: begin relative_req_vec = {req_vec[0], req_vec[2:1]};
relative_cntdone_vec = {cnt_reqdone_vec[0],cnt_reqdone_vec[2:1]}; end
2'd1: begin relative_req_vec = {req_vec[1:0],req_vec[2]};
relative_cntdone_vec = {cnt_reqdone_vec[1:0],cnt_reqdone_vec[2]}; end
2'd2: begin relative_req_vec = {req_vec[2:0]};
relative_cntdone_vec = {cnt_reqdone_vec[2:0]}; end
endcase
end
always@(*) begin
arbiter_state_nxt = arbiter_state;
gnt_vec_nxt = gnt_vec;
count_req_vec_nxt[0] = count_req_vec[0];
count_req_vec_nxt[1] = count_req_vec[1];
count_req_vec_nxt[2] = count_req_vec[2];
grant_posn_nxt = grant_posn;
case(arbiter_state)
IDLE:begin
if(req_n_valid) begin
arbiter_state_nxt = ARM_VALUE;
count_req_vec_nxt[0] = req_vec_wt[0];
count_req_vec_nxt[1] = req_vec_wt[1];
count_req_vec_nxt[2] = req_vec_wt[2];
gnt_vec_nxt = 3'b0;
end
end
ARM_VALUE:begin
if((gnt_vec == 0) ||
(end_access_vec[0] & gnt_vec[0]) ||
(end_access_vec[1] & gnt_vec[1]) ||
(end_access_vec[2] & gnt_vec[2])) begin
if(relative_req_vec[0] & !relative_cntdone_vec[0]) begin
arbiter_state_nxt = END_ACCESS;
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
2'd1:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
2'd2:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
endcase
end
else if(relative_req_vec[1] & !relative_cntdone_vec[1]) begin
arbiter_state_nxt = END_ACCESS;
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
2'd1:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
2'd2:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
endcase
end
else if(relative_req_vec[2] & !relative_cntdone_vec[2]) begin
arbiter_state_nxt = END_ACCESS;
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
2'd1:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
2'd2:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
endcase
end
else begin
gnt_vec_nxt = 3'b0;
count_req_vec_nxt[0] = req_vec_wt_stored[0];
count_req_vec_nxt[1] = req_vec_wt_stored[1];
count_req_vec_nxt[2] = req_vec_wt_stored[2];
end
end
end
END_ACCESS:begin
if((end_access_vec[0] & gnt_vec[0]) ||
(end_access_vec[1] & gnt_vec[1]) ||
(end_access_vec[2] & gnt_vec[2])) begin
arbiter_state_nxt = ARM_VALUE;
if(relative_req_vec[0] & !relative_cntdone_vec[0]) begin
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
2'd1:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
2'd2:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
endcase
end
else if(relative_req_vec[1] & !relative_cntdone_vec[1]) begin
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
2'd1:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
2'd2:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
endcase
end
else if(relative_req_vec[2] & !relative_cntdone_vec[2]) begin
case(grant_posn)
2'd0:begin gnt_vec_nxt = 3'b001;
count_req_vec_nxt[0] = count_req_vec[0] - 1'b1;
grant_posn_nxt = 0; end
2'd1:begin gnt_vec_nxt = 3'b010;
count_req_vec_nxt[1] = count_req_vec[1] - 1'b1;
grant_posn_nxt = 1; end
2'd2:begin gnt_vec_nxt = 3'b100;
count_req_vec_nxt[2] = count_req_vec[2] - 1'b1;
grant_posn_nxt = 2; end
endcase
end
else begin
gnt_vec_nxt = 3'b0;
count_req_vec_nxt[0] = req_vec_wt_stored[0];
count_req_vec_nxt[1] = req_vec_wt_stored[1];
count_req_vec_nxt[2] = req_vec_wt_stored[2];
end
end
end
endcase
end
assign cnt_reqdone_vec[0] = (count_req_vec[0] == 0);
assign cnt_reqdone_vec[1] = (count_req_vec[1] == 0);
assign cnt_reqdone_vec[2] = (count_req_vec[2] == 0);
always@(posedge clk, negedge resetb) begin
if(!resetb) begin
arbiter_state <= IDLE;
gnt_vec <= 0;
count_req_vec[0] <= 0;
count_req_vec[1] <= 0;
count_req_vec[2] <= 0;
req_vec_wt_stored[0] <= 0;
req_vec_wt_stored[1] <= 0;
req_vec_wt_stored[2] <= 0;
grant_posn <= 2;
end
else begin
arbiter_state <= arbiter_state_nxt;
gnt_vec <= gnt_vec_nxt;
count_req_vec[0] <= count_req_vec_nxt[0];
count_req_vec[1] <= count_req_vec_nxt[1];
count_req_vec[2] <= count_req_vec_nxt[2];
req_vec_wt_stored[0] <= req_vec_wt_stored_nxt[0];
req_vec_wt_stored[1] <= req_vec_wt_stored_nxt[1];
req_vec_wt_stored[2] <= req_vec_wt_stored_nxt[2];
grant_posn <= grant_posn_nxt;
end
end
endmodule
The code uses a code similar to fair polling, but at this time the relative_cntdone_vec signal is also used to save the remaining number of requests for each user. Note: once there is a gap period, the remaining number of requests for all users will be reset.
The above content comes from "Verilog Advanced Digital System Design Technology and Example Analysis"