多通道的AXI仲裁方法【第三版】:互联状态机

参考:

循环优先级仲裁~位屏蔽仲裁算法_循环优先级仲裁器-CSDN博客

真的写出来以后比想象的简单很多~

读仲裁:

module  Aribe_state_rd #(

    )(
        
);

    //-----------------------------------------------------------------//
        localparam  state_idle  = 10'b0000_0000_01;
        localparam  state_aribe = 10'b0000_0000_10;

        localparam  state_ch0_0 = 10'b0000_0001_00;
        localparam  state_ch0_1 = 10'b0000_0010_00;

        localparam  state_ch1_0 = 10'b0000_0100_00;
        localparam  state_ch1_1 = 10'b0000_1000_00;

        localparam  state_ch2_0 = 10'b0001_0000_00;
        localparam  state_ch2_1 = 10'b0010_0000_00;

        localparam  state_ch3_0 = 10'b0100_0000_00;
        localparam  state_ch3_1 = 10'b1000_0000_00;

    //-----------------------------------------------------------------//

    async_reset_n  u_async_reset_n (
        .sys_clk                 ( I_clk         ),
        .async_rst_n             ( I_Rst_n       ),

        .sync_rst_n              ( sync_rst_n    )
    );


    assign  single_req_Concat = {I_ch3_req, I_ch2_req, I_ch1_req, I_ch0_req};
    assign  aribe_start  = |single_req_Concat;
    assign  aribe_step   = (aribe_start == 1'b1 && aribe_cycle == 1'b0);

    assign  aribe_ch0_end = (I_ch0_end == 1'b1)&&(state == state_ch0_1);
    assign  aribe_ch1_end = (I_ch1_end == 1'b1)&&(state == state_ch1_1);
    assign  aribe_ch2_end = (I_ch2_end == 1'b1)&&(state == state_ch2_1);
    assign  aribe_ch3_end = (I_ch3_end == 1'b1)&&(state == state_ch3_1);

    assign O_ch0_vaild  = reg_ch0_vaild;
    assign O_ch1_vaild  = reg_ch1_vaild;
    assign O_ch2_vaild  = reg_ch2_vaild;
    assign O_ch3_vaild  = reg_ch3_vaild;

    always @(posedge I_clk) begin
        step[3:0] <= {step[2:0],aribe_step};
    end

    // Pose
    always @(posedge I_clk) begin
        {r2_ch0_start,r1_ch0_start} <= {r1_ch0_start,I_ch0_start};
        {r2_ch1_start,r1_ch1_start} <= {r1_ch1_start,I_ch1_start};
        {r2_ch2_start,r1_ch2_start} <= {r1_ch2_start,I_ch2_start};
        {r2_ch3_start,r1_ch3_start} <= {r1_ch3_start,I_ch3_start};
    end

    // aribe_cycle
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            aribe_cycle <= 1'b0;
        end else if(aribe_ch0_end|aribe_ch1_end|aribe_ch2_end|aribe_ch3_end) begin
            aribe_cycle <= 1'b0;
        end else if(aribe_start == 1'b1 && aribe_cycle == 1'b0 && state == state_idle) begin
            aribe_cycle <= 1'b1;
        end else begin
            aribe_cycle <= aribe_cycle;
        end
    end

    // step.0
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            double_req_Concat <= 'd0;
        end else if(aribe_step == 1'b1 && step[0] == 1'b0) begin
            double_req_Concat <= {2{I_ch3_req, I_ch2_req, I_ch1_req, I_ch0_req}};
        end else begin
            double_req_Concat <= double_req_Concat;
        end
    end

    // step.1
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            S1_req_Concat <= 'd0;
        end else if(step[0] == 1'b1 && step[1] == 1'b0) begin
            S1_req_Concat <= ~(double_req_Concat - {4'b0,aribe_value});
        end else begin
            S1_req_Concat <= S1_req_Concat;
        end
    end

    // step.2  
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            S2_req_Concat <= 'd0;
        end else if(step[1] == 1'b1 && step[2] == 1'b0) begin
            S2_req_Concat <= (S1_req_Concat & double_req_Concat);
        end else begin
            S2_req_Concat <= S2_req_Concat;
        end
    end

    assign S3_req_Concat = ((S2_req_Concat[3:0])|(S2_req_Concat[7:4]));

    // aribe_value
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            aribe_value <= {3'b0,1'b1};
        end else if(aribe_value[3] == 1'b1 && step[0] == 1'b1 && step[1] == 1'b0) begin
            aribe_value <= {3'b0,1'b1};
        end else if(step[0] == 1'b1 && step[1] == 1'b0) begin
            aribe_value <= aribe_value << 1;
        end else begin
            aribe_value <= aribe_value;
        end
    end

    //req
    //ch0
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch0_vaild <= 1'b0;
        end else if(state == state_ch0_0 && (r1_ch0_start == 1'b1 && r2_ch0_start == 1'b0)) begin
            reg_ch0_vaild <= 1'b0;
        end else if(state == state_ch0_0 && reg_ch0_vaild == 1'b0) begin
            reg_ch0_vaild <= 1'b1;
        end
    end
    //ch1
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch1_vaild <= 1'b0;
        end else if(state == state_ch1_0 && (r1_ch1_start == 1'b1 && r2_ch1_start == 1'b0)) begin
            reg_ch1_vaild <= 1'b0;
        end else if(state == state_ch1_0 && reg_ch1_vaild == 1'b0) begin
            reg_ch1_vaild <= 1'b1;
        end
    end
    //ch2
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch2_vaild <= 1'b0;
        end else if(state == state_ch2_0 && (r1_ch2_start == 1'b1 && r2_ch2_start == 1'b0)) begin
            reg_ch2_vaild <= 1'b0;
        end else if(state == state_ch2_0 && reg_ch2_vaild == 1'b0) begin
            reg_ch2_vaild <= 1'b1;
        end
    end
    //ch3
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch3_vaild <= 1'b0;
        end else if(state == state_ch3_0 && (r1_ch3_start == 1'b1 && r2_ch3_start == 1'b0)) begin
            reg_ch3_vaild <= 1'b0;
        end else if(state == state_ch3_0 && reg_ch3_vaild == 1'b0) begin
            reg_ch3_vaild <= 1'b1;
        end
    end

    //state
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state <= state_idle;
        end else begin
            case (state)
                state_idle: begin
                    if(aribe_start == 1'b1 && aribe_cycle == 1'b0) begin
                        state <= state_aribe;
                    end else begin
                        state <= state_idle;
                    end
                end
                state_aribe:begin
                    if(step[2] == 1'b1 && step[3] == 1'b0) begin
                        case (S3_req_Concat)
                            4'b0001:begin
                                state <= state_ch0_0;
                            end 
                            4'b0010:begin
                                state <= state_ch1_0;
                            end 
                            4'b0100:begin
                                state <= state_ch2_0;
                            end 
                            4'b1000:begin
                                state <= state_ch3_0;
                            end 
                            default: state <= state_aribe;
                        endcase
                    end else begin
                        state <= state_aribe;
                    end
                end
                // state.step.0
                state_ch0_0:begin
                    if((r1_ch0_start == 1'b1 && r2_ch0_start == 1'b0)) begin
                        state <= state_ch0_1;
                    end else begin
                        state <= state_ch0_0;
                    end
                end
                state_ch1_0:begin
                    if((r1_ch1_start == 1'b1 && r2_ch1_start == 1'b0)) begin
                        state <= state_ch1_1;
                    end else begin
                        state <= state_ch1_0;
                    end
                end
                state_ch2_0:begin
                    if((r1_ch2_start == 1'b1 && r2_ch2_start == 1'b0)) begin
                        state <= state_ch2_1;
                    end else begin
                        state <= state_ch2_0;
                    end
                end
                state_ch3_0:begin
                    if((r1_ch3_start == 1'b1 && r2_ch3_start == 1'b0)) begin
                        state <= state_ch3_1;
                    end else begin
                        state <= state_ch3_0;
                    end
                end

                // state.step.1
                state_ch0_1:begin
                    if(I_ch0_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch0_1;
                    end
                end
                state_ch1_1:begin
                    if(I_ch1_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch1_1;
                    end
                end
                state_ch2_1:begin
                    if(I_ch2_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch2_1;
                    end
                end
                state_ch3_1:begin
                    if(I_ch3_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch3_1;
                    end
                end
                default: begin
                    state <= state_idle;
                end
            endcase
        end
    end  

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch0_flag <= 1'b0;
        end else if(state == state_ch0_1 && I_ch0_end == 1'b1) begin
            state_ch0_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0001) begin
            state_ch0_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch1_flag <= 1'b0;
        end else if(state == state_ch1_1 && I_ch1_end == 1'b1) begin
            state_ch1_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0010) begin
            state_ch1_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch2_flag <= 1'b0;
        end else if(state == state_ch2_1 && I_ch2_end == 1'b1) begin
            state_ch2_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0100) begin
            state_ch2_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch3_flag <= 1'b0;
        end else if(state == state_ch3_1 && I_ch3_end == 1'b1) begin
            state_ch3_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b1000) begin
            state_ch3_flag <= 1'b1;
        end
    end

endmodule
View Code

写仲裁:

module  Aribe_state_wr #(       
    )(

);


    async_reset_n  u_async_reset_n (
        .sys_clk                 ( I_clk         ),
        .async_rst_n             ( I_Rst_n       ),

        .sync_rst_n              ( sync_rst_n    )
    );


    assign  single_req_Concat = {I_ch3_req, I_ch2_req, I_ch1_req, I_ch0_req};
    assign  aribe_start  = |single_req_Concat;
    assign  aribe_step   = (aribe_start == 1'b1 && aribe_cycle == 1'b0);

    assign  aribe_ch0_end = (I_ch0_end == 1'b1)&&(state == state_ch0_1);
    assign  aribe_ch1_end = (I_ch1_end == 1'b1)&&(state == state_ch1_1);
    assign  aribe_ch2_end = (I_ch2_end == 1'b1)&&(state == state_ch2_1);
    assign  aribe_ch3_end = (I_ch3_end == 1'b1)&&(state == state_ch3_1);

    assign O_ch0_vaild  = reg_ch0_vaild;
    assign O_ch1_vaild  = reg_ch1_vaild;
    assign O_ch2_vaild  = reg_ch2_vaild;
    assign O_ch3_vaild  = reg_ch3_vaild;

    always @(posedge I_clk) begin
        step[3:0] <= {step[2:0],aribe_step};
    end

    // Pose
    always @(posedge I_clk) begin
        {r2_ch0_start,r1_ch0_start} <= {r1_ch0_start,I_ch0_start};
        {r2_ch1_start,r1_ch1_start} <= {r1_ch1_start,I_ch1_start};
        {r2_ch2_start,r1_ch2_start} <= {r1_ch2_start,I_ch2_start};
        {r2_ch3_start,r1_ch3_start} <= {r1_ch3_start,I_ch3_start};
    end

    // aribe_cycle
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            aribe_cycle <= 1'b0;
        end else if(aribe_ch0_end|aribe_ch1_end|aribe_ch2_end|aribe_ch3_end) begin
            aribe_cycle <= 1'b0;
        end else if(aribe_start == 1'b1 && aribe_cycle == 1'b0 && state == state_idle) begin
            aribe_cycle <= 1'b1;
        end else begin
            aribe_cycle <= aribe_cycle;
        end
    end

    // step.0
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            double_req_Concat <= 'd0;
        end else if(aribe_step == 1'b1 && step[0] == 1'b0) begin
            double_req_Concat <= {2{I_ch3_req, I_ch2_req, I_ch1_req, I_ch0_req}};
        end else begin
            double_req_Concat <= double_req_Concat;
        end
    end

    // step.1
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            S1_req_Concat <= 'd0;
        end else if(step[0] == 1'b1 && step[1] == 1'b0) begin
            S1_req_Concat <= ~(double_req_Concat - {4'b0,aribe_value});
        end else begin
            S1_req_Concat <= S1_req_Concat;
        end
    end

    // step.2  
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            S2_req_Concat <= 'd0;
        end else if(step[1] == 1'b1 && step[2] == 1'b0) begin
            S2_req_Concat <= (S1_req_Concat & double_req_Concat);
        end else begin
            S2_req_Concat <= S2_req_Concat;
        end
    end

    assign S3_req_Concat = ((S2_req_Concat[3:0])|(S2_req_Concat[7:4]));

    // aribe_value
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            aribe_value <= {3'b0,1'b1};
        end else if(aribe_value[3] == 1'b1 && step[0] == 1'b1 && step[1] == 1'b0) begin
            aribe_value <= {3'b0,1'b1};
        end else if(step[0] == 1'b1 && step[1] == 1'b0) begin
            aribe_value <= aribe_value << 1;
        end else begin
            aribe_value <= aribe_value;
        end
    end

    //req
    //ch0
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch0_vaild <= 1'b0;
        end else if(state == state_ch0_0 && (r1_ch0_start == 1'b1 && r2_ch0_start == 1'b0)) begin
            reg_ch0_vaild <= 1'b0;
        end else if(state == state_ch0_0 && reg_ch0_vaild == 1'b0) begin
            reg_ch0_vaild <= 1'b1;
        end
    end
    //ch1
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch1_vaild <= 1'b0;
        end else if(state == state_ch1_0 && (r1_ch1_start == 1'b1 && r2_ch1_start == 1'b0)) begin
            reg_ch1_vaild <= 1'b0;
        end else if(state == state_ch1_0 && reg_ch1_vaild == 1'b0) begin
            reg_ch1_vaild <= 1'b1;
        end
    end
    //ch2
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch2_vaild <= 1'b0;
        end else if(state == state_ch2_0 && (r1_ch2_start == 1'b1 && r2_ch2_start == 1'b0)) begin
            reg_ch2_vaild <= 1'b0;
        end else if(state == state_ch2_0 && reg_ch2_vaild == 1'b0) begin
            reg_ch2_vaild <= 1'b1;
        end
    end
    //ch3
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            reg_ch3_vaild <= 1'b0;
        end else if(state == state_ch3_0 && (r1_ch3_start == 1'b1 && r2_ch3_start == 1'b0)) begin
            reg_ch3_vaild <= 1'b0;
        end else if(state == state_ch3_0 && reg_ch3_vaild == 1'b0) begin
            reg_ch3_vaild <= 1'b1;
        end
    end

    //state
    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state <= state_idle;
        end else begin
            case (state)
                state_idle: begin
                    if(aribe_start == 1'b1 && aribe_cycle == 1'b0) begin
                        state <= state_aribe;
                    end else begin
                        state <= state_idle;
                    end
                end
                state_aribe:begin
                    if(step[2] == 1'b1 && step[3] == 1'b0) begin
                        case (S3_req_Concat)
                            4'b0001:begin
                                state <= state_ch0_0;
                            end 
                            4'b0010:begin
                                state <= state_ch1_0;
                            end 
                            4'b0100:begin
                                state <= state_ch2_0;
                            end 
                            4'b1000:begin
                                state <= state_ch3_0;
                            end 
                            default: state <= state_aribe;
                        endcase
                    end else begin
                        state <= state_aribe;
                    end
                end
                // state.step.0
                state_ch0_0:begin
                    if((r1_ch0_start == 1'b1 && r2_ch0_start == 1'b0)) begin
                        state <= state_ch0_1;
                    end else begin
                        state <= state_ch0_0;
                    end
                end
                state_ch1_0:begin
                    if((r1_ch1_start == 1'b1 && r2_ch1_start == 1'b0)) begin
                        state <= state_ch1_1;
                    end else begin
                        state <= state_ch1_0;
                    end
                end
                state_ch2_0:begin
                    if((r1_ch2_start == 1'b1 && r2_ch2_start == 1'b0)) begin
                        state <= state_ch2_1;
                    end else begin
                        state <= state_ch2_0;
                    end
                end
                state_ch3_0:begin
                    if((r1_ch3_start == 1'b1 && r2_ch3_start == 1'b0)) begin
                        state <= state_ch3_1;
                    end else begin
                        state <= state_ch3_0;
                    end
                end

                // state.step.1
                state_ch0_1:begin
                    if(I_ch0_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch0_1;
                    end
                end
                state_ch1_1:begin
                    if(I_ch1_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch1_1;
                    end
                end
                state_ch2_1:begin
                    if(I_ch2_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch2_1;
                    end
                end
                state_ch3_1:begin
                    if(I_ch3_end == 1'b1) begin
                        state <= state_idle;
                    end else begin
                        state <= state_ch3_1;
                    end
                end
                default: begin
                    state <= state_idle;
                end
            endcase
        end
    end  

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch0_flag <= 1'b0;
        end else if(state == state_ch0_1 && I_ch0_end == 1'b1) begin
            state_ch0_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0001) begin
            state_ch0_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch1_flag <= 1'b0;
        end else if(state == state_ch1_1 && I_ch1_end == 1'b1) begin
            state_ch1_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0010) begin
            state_ch1_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch2_flag <= 1'b0;
        end else if(state == state_ch2_1 && I_ch2_end == 1'b1) begin
            state_ch2_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b0100) begin
            state_ch2_flag <= 1'b1;
        end
    end

    always @(posedge I_clk) begin
        if(sync_rst_n == 1'b0) begin
            state_ch3_flag <= 1'b0;
        end else if(state == state_ch3_1 && I_ch3_end == 1'b1) begin
            state_ch3_flag <= 1'b0; 
        end else if(state == state_aribe &&  step[2] == 1'b1 && step[3] == 1'b0 && S3_req_Concat == 4'b1000) begin
            state_ch3_flag <= 1'b1;
        end
    end

endmodule
View Code

 

posted @ 2024-04-13 13:14  NoNounknow  阅读(133)  评论(0编辑  收藏  举报