Digital IC front-end study notes: arbitration polling (5)

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: Gray code (including binary Gray code converter implemented by Verilog)

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" 

Guess you like

Origin blog.csdn.net/weixin_45791458/article/details/131398161