数字IC前端学习笔记:仲裁轮询(三)

相关文章

数字IC前端学习笔记:LSFR(线性反馈移位寄存器)

数字IC前端学习笔记:跨时钟域信号同步

数字IC前端学习笔记:信号同步和边沿检测

数字IC前端学习笔记:锁存器Latch的综合

数字IC前端学习笔记:格雷码(含Verilog实现的二进制格雷码转换器)

数字IC前端学习笔记:FIFO的Verilog实现(一)

数字IC前端学习笔记:FIFO的Verilog实现(二)

数字IC前端学习笔记:仲裁轮询(一)

数字IC前端学习笔记:仲裁轮询(二)

数字IC前端学习笔记:仲裁轮询(四)

数字IC前端学习笔记:仲裁轮询(五)

数字IC前端学习笔记:仲裁轮询(六)

数字IC前端学习笔记:近期最少使用(LRU)算法


5.无死周期的公平轮询

        在前面公平轮询仲裁器的Verilog RTL代码中,每个用户有三个信号:request(请求)、grant(授权)、end_access(结束访问)。在总线使用时,我们能观察到总线上存在不能进行数据传输的死周期。当传输的数据包较长或每个突发较长时,其对传输效率影响不大。然而,当数据包很短时,死周期会影响到总线的使用效率。如下图所示为没有间隔的公平轮询仲裁波形。下面给出了一些方法,用于减少甚至消除死周期。

  • 第一种方案是当grant信号有效时,该用户的第一个数据已经准备好并且有效输出。原来的方案中,在用户的grant有效后,它在下一个周期输出数据,现在改为当grant采样为高时,在同一个周期就开始输出数据。此时需要用户提前从内部电路中读出第一个数据。采用这种方案时,仲裁器的设计不变,用户部分需要进行修改。
  • 第二种方法是增加额外的信号start_access,它和end_access一起使用。一个用户获得总线使用权并开始操作后,仲裁器通过将start_access置为有效表示开始新的仲裁过程,而不是等待end_access信号变高来开始新的仲裁过程,这样就减少了转换期间的死周期。当下一个用户被授权时,当前用户仍在使用总线,此时新的用户不能立即使用总线。仲裁器在当前用户完成操作时会给出end_access_out信号,新的授权用户此后就可以开始操作了。仲裁器在没有用户使用公共资源时,将resource_idle置为1。当resource_idle为1时,获得授权的用户不需要查看end_access_out信号就可以开始数据操作。

        没有死周期的公平轮询代码及仿真结果如下。

module arbiter_roundrobin(
            clk,resetb,
            req_vec,
            end_access_vec,
            gnt_vec,
            end_access_out);
    
    input clk, resetb;
    input [2:0] req_vec, end_access_vec;
    output [2:0] gnt_vec;
    output end_access_out;
    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;
    reg resource_idle_nxt, resource_idle;
    reg [2:0] start_access_vec, start_access_vec_nxt;
    parameter IDLE = 2'b00;
    parameter END_ACCESS = 2'b01;
    
    assign any_req_asserted = (req_vec != 0);
    assign end_access_out = |end_access_vec;
 
    always@(*) begin
        relative_req_vec = req_vec;
        case(grant_posn)
            2'd0: relative_req_vec = {req_vec[0], req_vec[2:1]};
            2'd1: relative_req_vec = {req_vec[1:0], req_vec[2]};
            2'd2: relative_req_vec = {req_vec[2:0]};
        endcase
    end
    always@(*) begin
        arbiter_state_nxt = arbiter_state;
        grant_posn_nxt = grant_posn;
        gnt_vec_nxt = gnt_vec;
        resource_idle_nxt = 1'b0;
        start_access_vec_nxt = 3'b0;
        case(arbiter_state)
            IDLE:begin
                    if(any_req_asserted)
                        arbiter_state_nxt = END_ACCESS;
                        resource_idle_nxt = 1'b1;
                    if(relative_req_vec[0])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                            2'd1: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                            2'd2: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                        endcase
                    else if(relative_req_vec[1])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                            2'd1: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                            2'd2: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                        endcase
                    else if(relative_req_vec[2])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                            2'd1: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                            2'd2: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                        endcase
                    else
                        gnt_vec_nxt = 3'b000;
            end
            END_ACCESS:begin  
                if((resource_idle == 1'b1) || (end_access_out == 1'b1))
                    start_access_vec_nxt = gnt_vec;
                if(start_access_vec != 0)begin
                    if(relative_req_vec[0])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                            2'd1: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                            2'd2: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                        endcase
                    else if(relative_req_vec[1])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                            2'd1: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                            2'd2: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                        endcase
                    else if(relative_req_vec[2])
                        case(grant_posn)
                            2'd0: begin gnt_vec_nxt = 3'b001; grant_posn_nxt = 3'd0; end
                            2'd1: begin gnt_vec_nxt = 3'b010; grant_posn_nxt = 3'd1; end
                            2'd2: begin gnt_vec_nxt = 3'b100; grant_posn_nxt = 3'd2; end
                        endcase
                    else begin
                        gnt_vec_nxt = 3'b000;   
                        arbiter_state_nxt = IDLE;
                    end         
                end
            end
        endcase
    end
    
    always@(posedge clk or negedge resetb)begin
        if(!resetb) begin
            arbiter_state <= IDLE;
            gnt_vec <= 0;
            grant_posn <= 0;
            resource_idle <= 0;
            start_access_vec <= 0;
        end  
        else begin
            arbiter_state <= arbiter_state_nxt;
            gnt_vec <= gnt_vec_nxt;
            grant_posn <= grant_posn_nxt;
            resource_idle <= resource_idle_nxt;
            start_access_vec <= start_access_vec_nxt;
        end
    end
endmodule

        在Verilog实现过程中,使用了两个状态IDLE和END_ACCESS,分别表示仲裁器处于无请求和仲裁器授权的状态。在IDLE状态时,任何请求信号能使状态转移至END_ACCESS状态,并将resource_idle信号置1(这是为了IDLE状态下start_access的置位而设计的信号),并根据请求信号给出相应授权。在END_ACCESS状态,会根据resource_idle或end_access_out信号使用gnt_vec对start_access置位。当start_access信号有效时,根据请求信号进行下一次授权。若此时没有请求信号,则状态回到IDLE等待。

以上内容来源于《Verilog高级数字系统设计技术和实例分析》,有删改

猜你喜欢

转载自blog.csdn.net/weixin_45791458/article/details/131339436