module rchannel ( input clk, input rst_n, input axi_s_arvalid, input [7:0] axi_s_arlen, input [25:0] axi_s_araddr, output axi_s_arready, output axi_s_rvalid, output axi_s_rlast, output [63:0] axi_s_rdata, output rframe_valid, output [159:0] rframe_data, input rframe_ready, input array2axi_rdata_valid, input [127:0] array2axi_rdata ); wire rsof,reof; reg [15:0] rraddr; reg [5:0] rcaddr; wire [127:0] wdata; wire [7:0] arlen; wire [15:0] arraddr; wire [5:0] arcaddr; reg [6:0] rframe_cnt; reg [7:0] rdata_cnt; reg [1:0] cur_state,next_state; localparam [1:0] RCH_IDLE = 2'b00; localparam [1:0] RCH_GET_RADDR = 2'b01; localparam [1:0] RCH_SD_RADDR = 2'b10; wire sync_fifo_ar_wr_en; wire sync_fifo_ar_rd_en; wire sync_fifo_ar_full; wire sync_fifo_ar_empty; wire [29:0] sync_fifo_ar_wr_data; wire [29:0] sync_fifo_ar_rd_data; sync_fifo #(.DATA_WIDTH(30), .FIFO_DEPTH(4) ) sync_fifo_ar ( .clk (clk), .rst_n (rst_n), .wr_en (sync_fifo_ar_wr_en), .wr_data (sync_fifo_ar_wr_data), .full (sync_fifo_ar_full), .rd_en (sync_fifo_ar_rd_en), .rd_data (sync_fifo_ar_rd_data), .empty (sync_fifo_ar_empty) ); wire sync_fifo_arlen_wr_en; wire sync_fifo_arlen_rd_en; wire sync_fifo_arlen_full; wire sync_fifo_arlen_empty; wire [7:0] sync_fifo_arlen_wr_data; wire [7:0] sync_fifo_arlen_rd_data; sync_fifo #(.DATA_WIDTH(8), .FIFO_DEPTH(4) ) sync_fifo_arlen ( .clk (clk), .rst_n (rst_n), .wr_en (sync_fifo_arlen_wr_en), .wr_data (sync_fifo_arlen_wr_data), .full (sync_fifo_arlen_full), .rd_en (sync_fifo_arlen_rd_en), .rd_data (sync_fifo_arlen_rd_data), .empty (sync_fifo_arlen_empty) ); wire sync_fifo_r_wr_en; wire sync_fifo_r_rd_en; wire sync_fifo_r_full; wire sync_fifo_r_empty; wire [127:0]sync_fifo_r_wr_data; wire [63:0] sync_fifo_r_rd_data; sync_fifo_128_to_64 #(.DATA_IN_WIDTH(128), .FIFO_DEPTH(8), .DATA_OUT_WIDTH(64) ) sync_fifo_r ( .clk (clk), .rst_n (rst_n), .wr_en (sync_fifo_r_wr_en), .wr_data (sync_fifo_r_wr_data), .full (sync_fifo_r_full), .rd_en (sync_fifo_r_rd_en), .rd_data (sync_fifo_r_rd_data), .empty (sync_fifo_r_empty) ); assign axi_s_arready = !sync_fifo_ar_full; assign rframe_valid = (cur_state == RCH_SD_RADDR); assign rframe_data = {rsof,reof,rraddr,rcaddr,128'b0,arlen}; assign axi_s_rvalid = !sync_fifo_r_empty; assign axi_s_rdata = sync_fifo_r_rd_data; assign axi_s_rlast = axi_s_rvalid && (rdata_cnt == sync_fifo_arlen_rd_data); assign sync_fifo_ar_wr_en = axi_s_arvalid && axi_s_arready; assign sync_fifo_ar_wr_data = {axi_s_araddr[25:4],axi_s_arlen}; assign sync_fifo_ar_rd_en = rframe_ready && rframe_valid && rframe_cnt == arlen>>1'b1 && !sync_fifo_ar_empty; assign {arraddr , arcaddr, arlen} = sync_fifo_ar_rd_data; assign sync_fifo_arlen_wr_en = rframe_valid && rframe_ready && rframe_cnt == arlen >> 1'b1; assign sync_fifo_arlen_wr_data = arlen; assign sync_fifo_arlen_rd_en = axi_s_rlast && axi_s_rvalid; assign rsof = rframe_valid && (rframe_cnt == 7'b0 || rcaddr == 6'd0); assign reof = rframe_valid && (rframe_cnt == arlen >>1'b1 || rcaddr == 6'h3f); assign sync_fifo_r_wr_en = array2axi_rdata_valid && !sync_fifo_r_full; assign sync_fifo_r_wr_data = array2axi_rdata; assign sync_fifo_r_rd_en = !sync_fifo_r_empty; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cur_state <= RCH_IDLE; end else begin cur_state <= next_state; end end always@(*) begin case(cur_state) RCH_IDLE: begin if(sync_fifo_ar_wr_en) begin next_state <= RCH_GET_RADDR; end else begin next_state <= RCH_IDLE; end end RCH_GET_RADDR: begin next_state <= RCH_SD_RADDR; end RCH_SD_RADDR: begin if(rframe_ready && rframe_valid && rframe_cnt == arlen >>1) begin next_state <= RCH_IDLE; end else begin next_state <= RCH_SD_RADDR; end end endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rraddr <= 'd0; end else if(cur_state == RCH_GET_RADDR) begin rraddr <= arraddr; if(rframe_valid && rframe_ready) begin if(rcaddr == 6'b111111) begin rraddr <= rraddr + 1'b1; end else begin rraddr <= rraddr; end end end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rcaddr <= 'd0; end else if (cur_state == RCH_GET_RADDR) begin rcaddr <= arcaddr; if(rframe_valid && rframe_ready) begin if(rcaddr == 6'b111111) begin rcaddr <= 'd0; end else begin rcaddr <= rcaddr + 1; end end end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rframe_cnt <= 'd0; end else if (rframe_valid && rframe_ready) begin if(rframe_cnt == arlen>>1'b1) begin rframe_cnt <= 'd0; end else begin rframe_cnt <= rframe_cnt + 1'b1; end end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rdata_cnt <= 'd0; end else if(axi_s_rvalid) begin if(rdata_cnt == sync_fifo_arlen_rd_data) begin rdata_cnt <= 'd0; end else begin rdata_cnt <= rdata_cnt + 1'b1; end end end endmodule