module array_status_ctrl( input clk, input rst_n, input axi2array_frame_valid, input [152:0] axi2array_frame_data, output axi2array_frame_ready, output array_wr_frame_valid, output [151:0] array_wr_frame_data, input array_wr_frame_ready, input array_wr_done, output array_rd_frame_valid, output [151:0] array_rd_frame_data, input array_rd_frame_ready, input array_rd_done, output array_ref_start, input array_ref_done, output [1:0] array_mux_sel, input mc_work_en, input array_ref_en, input [24:0] array_inner_tref0, input [24:0] array_inner_tref1, input array_inner_ref_sel ); reg [1:0] cur_state,next_state; localparam [1:0] ARRAY_STA_IDLE = 2'b00; localparam [1:0] ARRAY_STA_WR = 2'b10; localparam [1:0] ARRAY_STA_RD = 2'b11; localparam [1:0] ARRAY_STA_REF = 2'b01; reg mc_work_en_r ,mc_work_en_sync; reg array_ref_en_r ,array_ref_en_sync; reg array_inner_ref_sel_r,array_inner_ref_sel_sync; reg array_ref_req; reg [24:0] array_ref_cnt; wire [24:0] array_inner_tref; wire array_wr_req ,array_rd_req; assign axi2array_frame_ready = ((cur_state == ARRAY_STA_WR) && array_wr_frame_ready) || ((cur_state == ARRAY_STA_RD) && array_rd_frame_ready); assign array_wr_frame_valid = ((cur_state == ARRAY_STA_WR) && axi2array_frame_valid); assign array_rd_frame_valid = ((cur_state == ARRAY_STA_RD) && axi2array_frame_valid); assign array_wr_frame_data = axi2array_frame_data[151:0]; assign array_rd_frame_data = axi2array_frame_data[151:0]; assign array_ref_start = ((cur_state == ARRAY_STA_IDLE && array_ref_req)); assign array_mux_sel = cur_state; assign array_inner_tref = array_inner_ref_sel_sync ?array_inner_tref1:array_inner_tref0; assign array_wr_req = axi2array_frame_valid && axi2array_frame_data[152]; assign array_rd_req = axi2array_frame_valid && !axi2array_frame_data[152]; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cur_state <= ARRAY_STA_IDLE; end else begin cur_state <= next_state; end end always@(*) begin case(cur_state) ARRAY_STA_IDLE : begin if(array_ref_req) begin next_state = ARRAY_STA_REF; end else if(array_wr_req) begin next_state = ARRAY_STA_WR; end else if(array_rd_req) begin next_state = ARRAY_STA_RD; end else begin next_state = ARRAY_STA_IDLE; end end ARRAY_STA_WR : begin if(array_wr_done) begin next_state = ARRAY_STA_IDLE; end else begin next_state = ARRAY_STA_WR; end end ARRAY_STA_RD : begin if(array_rd_done) begin next_state = ARRAY_STA_IDLE; end else begin next_state = ARRAY_STA_RD; end end ARRAY_STA_REF : begin if(array_ref_done) begin next_state = ARRAY_STA_IDLE; end else begin next_state = ARRAY_STA_REF; end end default : next_state = ARRAY_STA_IDLE; endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin mc_work_en_r <= 'd0; mc_work_en_sync <= 'd0; end else begin mc_work_en_r <= mc_work_en; mc_work_en_sync <= mc_work_en_r; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin array_ref_en_r <= 'd0; array_ref_en_sync <= 'd0; end else begin array_ref_en_r <= array_ref_en; array_ref_en_sync <= array_ref_en_r; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin array_inner_ref_sel_r <= 'd0; array_inner_ref_sel_sync <= 'd0; end else begin array_inner_ref_sel_r <= array_inner_ref_sel; array_inner_ref_sel_sync <= array_inner_ref_sel_r; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin array_ref_req <= 'd0; end else if(mc_work_en) begin array_ref_req <= (array_ref_cnt >= array_inner_tref && mc_work_en_sync && array_ref_en_sync) ? 1:0; end else if(cur_state == ARRAY_STA_IDLE) begin array_ref_req <= 'd0; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin array_ref_cnt <= 'd0; end else if(mc_work_en && array_ref_en) begin if(array_ref_cnt >= array_inner_tref) begin array_ref_cnt <= 'd0; end else begin array_ref_cnt <= array_ref_cnt + 1'b1; end end else begin array_ref_cnt <= 'd0; end end endmodule