循环优先级仲裁~位屏蔽仲裁算法

参考了FPGA奇哥(下列视频中UP主)的讲解。

        应该可以对多路读写DDR3进行操作,仅仲裁,不涉及DMA和Uibuf等。

2023年11月所写,暂未进行测试,日后补上。

第二天已完成测试,功能可行。

深入FPGA底层设计系列-循环优先级仲裁器算法:位屏蔽仲裁算法与Verilog代码编写_哔哩哔哩_bilibili

位屏蔽算法:

        描述:对输入的多通道请求进行仲裁。

        步骤:

        (1)原码减去对应位数(优先级最高的位次)

        (2)求得(1)中输出的反码

        (3)通过(2)中输出与原码进行相与,留下优先级最高的请求。 

举例:

        【1】

        四通道输入请求,ABCD。破解后为:4‘b1000,此时D通道优先级最高。

        4'b1000-4’b1 =4'b0111 ~4'b0111 = 4'b1000

        1000 & 1000 == 1000

        仲裁完成,准许A通道请求。 

        【2】

          四通道输入请求,ABCD。破解后为:4‘b1110,此时B通道优先级最高。

        1110 - 0100 = 1010

        ~1010 = 0101

        1110 & 0101 = 0100

        仲裁完成,准许B通道请求。 

Trick:

        此外,为了仲裁A通道,需要对输入的请求进行拼接操作,实现向高位借位的过程。

        每次完仲裁以后,都需要改变优先级最高的那一位的位次,完成循环。

自写代码参考:

module Fast_Aritbier_LoopPrior #(
    parameter In_Channel_Num = 8
)(
    input   wire                            Aritbier_Clk    ,
    input   wire                            Aritbier_Rst_n  ,
    input   wire    [In_Channel_Num-1:0]    I_req           ,
    input   wire                            I_Busy          ,
    output  wire    [In_Channel_Num-1:0]    O_Aritbier_Req 
);
        //Aritbier Value
            reg             Aritbier_Value      ;
        //Aritbier Flag
            wire            Aritbier_Begin      ;
            reg             Aritbier_Flag       ;
            reg     [3:0]   Aritbier_Flag_delay ; 
        //Busy
            reg             I_Busy_0;
            reg             I_Busy_1;
        //req
            reg     [(In_Channel_Num<<1)-1:0]   I_req_Double    ;
            reg     [In_Channel_Num-1:0]        r_O_Aritbier_Req;

    assign  Aritbier_Begin = |I_req;
    assign  O_Aritbier_Req = r_O_Aritbier_Req;
    assign  I_req_Double   = {I_req,I_req};

    always @(posedge Aritbier_Clk) begin
        {I_Busy_0, I_Busy_1} <= {I_Busy,I_Busy_0};
    end

    //Aritbier_Flag
    always @(posedge Aritbier_Clk or negedge Aritbier_Rst_n) begin
        if(Aritbier_Rst_n == 'd0) begin
            Aritbier_Flag <= 1'b0;
        end else if(Aritbier_Begin == 1'b1 && Aritbier_Flag == 1'b0) begin
            Aritbier_Flag <= 1'b1;
        end else if(!I_Busy_0 && I_Busy_1) begin
            Aritbier_Flag <= 1'b0;
        end
    end

    always @(posedge Aritbier_Clk) begin
        Aritbier_Flag_delay <= {Aritbier_Flag_delay[2:0],Aritbier_Flag};
    end

    always @(posedge Aritbier_Clk or negedge Aritbier_Rst_n) begin
        if(Aritbier_Rst_n == 'd0) begin
            Aritbier_Value <= {{(In_Channel_Num - 1){1'b0}},1'b1};
        end else if((!I_Busy_0 && I_Busy_1) && Aritbier_Value[In_Channel_Num - 1] == 1'b1) begin
            Aritbier_Value <= {{(In_Channel_Num - 1){1'b0}},1'b1};
        end else if(!I_Busy_0 && I_Busy_1)  begin
            Aritbier_Value <= Aritbier_Value << 1;
        end else begin
            Aritbier_Value <= Aritbier_Value;
        end
    end

    always @(posedge Aritbier_Clk or negedge Aritbier_Rst_n) begin
        if(Aritbier_Rst_n == 'd0) begin
            r_O_Aritbier_Req <= {(In_Channel_Num){1'b0}};
        end else if(Aritbier_Flag == 1'b1 && Aritbier_Flag_delay[0] == 1'b0) begin
            r_O_Aritbier_Req <= ((~(I_req_Double - {(In_Channel_Num){1'b0},Aritbier_Value}))&I_req);
        end
    end
endmodule

你可能感兴趣的:(AXI,读书笔记,小项目,仲裁)