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

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 (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"

Guess you like

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