多通道的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
写仲裁:
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