module frame_arbiter( input clk, input rst_n, input wframe_valid, input [159:0] wframe_data, output wframe_ready, input rframe_valid, input [159:0] rframe_data, output rframe_ready, output axi2array_frame_valid, output [152:0] axi2array_frame_data, input axi2array_frame_ready, input mc_work_en, input [1:0] axi_bus_rw_priority ); reg [1:0] cur_state,next_state; localparam [1:0] FARB_IDLE = 2'b00; localparam [1:0] FARB_WR = 2'b01; localparam [1:0] FARB_RD = 2'b10; reg rw_round_robin; reg [6:0] frame_cnt; wire rw_flag; wire [151:0] frame; wire [7:0] len; assign axi2array_frame_valid = (cur_state == FARB_WR) && wframe_valid || (cur_state == FARB_RD) && rframe_valid; assign axi2array_frame_data = {rw_flag,frame}; assign wframe_ready = (cur_state == FARB_WR) && axi2array_frame_ready; assign rframe_ready = (cur_state == FARB_RD) && axi2array_frame_ready; assign rw_flag = (cur_state == FARB_WR); assign frame = (cur_state == FARB_WR) ? wframe_data[159:8]: rframe_data[159:8]; assign len = (cur_state == FARB_WR) ? wframe_data[7:0]: rframe_data[7:0]; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cur_state <= 'd0; end else begin cur_state <= next_state; end end always@(*) begin case(cur_state) FARB_IDLE : begin if(wframe_valid && rframe_valid) begin case(axi_bus_rw_priority) 2'b00: begin next_state = FARB_RD; end 2'b01: begin next_state = FARB_WR; end 2'b10: begin next_state = rw_round_robin ? FARB_WR : FARB_RD; end endcase end else if (wframe_valid) begin next_state = FARB_WR; end else if (rframe_valid) begin next_state = FARB_RD; end else begin next_state = FARB_IDLE; end end FARB_WR : begin if (axi2array_frame_valid && axi2array_frame_ready && (frame_cnt == (len>>1))) begin next_state = FARB_IDLE; end else begin next_state = FARB_WR; end end FARB_RD :begin if (axi2array_frame_valid && axi2array_frame_ready && (frame_cnt == (len>>1))) begin next_state = FARB_IDLE; end else begin next_state = FARB_RD; end end default : begin next_state = FARB_IDLE; end endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rw_round_robin <= 1'b1; end else if(wframe_valid && rframe_valid && (cur_state == FARB_IDLE)) begin rw_round_robin <= ~rw_round_robin; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin frame_cnt <= 'd0; end else if (axi2array_frame_valid && axi2array_frame_ready) begin if(frame_cnt == (len >> 1)) begin frame_cnt <= 'd0; end else begin frame_cnt <= frame_cnt + 1'b1; end end end endmodule