module axi_bridge( input clk, input reset, output reg[ 3:0] arid, output reg[31:0] araddr, output reg[ 7:0] arlen, output reg[ 2:0] arsize, output [ 1:0] arburst, output [ 1:0] arlock, output [ 3:0] arcache, output [ 2:0] arprot, output reg arvalid, input arready, input [ 3:0] rid, input [31:0] rdata, input [ 1:0] rresp, input rlast, input rvalid, output reg rready, output [ 3:0] awid, output reg[31:0] awaddr, output reg[ 7:0] awlen, output reg[ 2:0] awsize, output [ 1:0] awburst, output [ 1:0] awlock, output [ 3:0] awcache, output [ 2:0] awprot, output reg awvalid, input awready, output [ 3:0] wid, output reg[31:0] wdata, output reg[ 3:0] wstrb, output reg wlast, output reg wvalid, input wready, input [ 3:0] bid, input [ 1:0] bresp, input bvalid, output reg bready, //cache sign input inst_rd_req , input [ 2:0] inst_rd_type , input [31:0] inst_rd_addr , output inst_rd_rdy , output inst_ret_valid , output inst_ret_last , output [31:0] inst_ret_data , input inst_wr_req , input [ 2:0] inst_wr_type , input [31:0] inst_wr_addr , input [ 3:0] inst_wr_wstrb , input [127:0] inst_wr_data , output inst_wr_rdy , input data_rd_req , input [ 2:0] data_rd_type , input [31:0] data_rd_addr , output data_rd_rdy , output data_ret_valid , output data_ret_last , output [31:0] data_ret_data , input data_wr_req , input [ 2:0] data_wr_type , input [31:0] data_wr_addr , input [ 3:0] data_wr_wstrb , input [127:0] data_wr_data , output data_wr_rdy , output write_buffer_empty ); //fixed signal assign arburst = 2'b1; assign arlock = 2'b0; assign arcache = 4'b0; assign arprot = 3'b0; assign awid = 4'b1; assign awburst = 2'b1; assign awlock = 2'b0; assign awcache = 4'b0; assign awprot = 3'b0; assign wid = 4'b1; assign inst_wr_rdy = 1'b1; localparam read_requst_empty = 1'b0; localparam read_requst_ready = 1'b1; localparam read_respond_empty = 1'b0; localparam read_respond_transfer = 1'b1; localparam write_request_empty = 3'b000; localparam write_addr_ready = 3'b001; localparam write_data_ready = 3'b010; localparam write_all_ready = 3'b011; localparam write_data_transform = 3'b100; localparam write_data_wait = 3'b101; localparam write_wait_b = 3'b110; reg read_requst_state; reg read_respond_state; reg [2:0] write_requst_state; wire write_wait_enable; wire rd_requst_state_is_empty; wire rd_requst_can_receive; assign rd_requst_state_is_empty = read_requst_state == read_requst_empty; wire data_rd_cache_line; wire inst_rd_cache_line; wire [ 2:0] data_real_rd_size; wire [ 7:0] data_real_rd_len ; wire [ 2:0] inst_real_rd_size; wire [ 7:0] inst_real_rd_len ; wire data_wr_cache_line; wire [ 2:0] data_real_wr_size; wire [ 7:0] data_real_wr_len ; reg [127:0] write_buffer_data; reg [ 2:0] write_buffer_num; wire write_buffer_last; assign write_buffer_empty = (write_buffer_num == 3'b0) && !write_wait_enable; assign rd_requst_can_receive = rd_requst_state_is_empty && !(write_wait_enable && !(bvalid && bready)); assign data_rd_rdy = rd_requst_can_receive; assign inst_rd_rdy = !data_rd_req && rd_requst_can_receive; //read type must be cache line assign data_rd_cache_line = data_rd_type == 3'b100 ; assign data_real_rd_size = data_rd_cache_line ? 3'b10 : data_rd_type; assign data_real_rd_len = data_rd_cache_line ? 8'b11 : 8'b0 ; assign inst_rd_cache_line = inst_rd_type == 3'b100 ; assign inst_real_rd_size = inst_rd_cache_line ? 3'b10 : inst_rd_type; assign inst_real_rd_len = inst_rd_cache_line ? 8'b11 : 8'b0 ; //write size can be special assign data_wr_cache_line = data_wr_type == 3'b100; assign data_real_wr_size = data_wr_cache_line ? 3'b10 : data_wr_type; assign data_real_wr_len = data_wr_cache_line ? 8'b11 : 8'b0 ; assign inst_ret_valid = !rid[0] && rvalid; assign inst_ret_last = !rid[0] && rlast; assign inst_ret_data = rdata; //this signal needed buffer??? assign data_ret_valid = rid[0] && rvalid; assign data_ret_last = rid[0] && rlast; assign data_ret_data = rdata; assign data_wr_rdy = (write_requst_state == write_request_empty); assign write_buffer_last = write_buffer_num == 3'b1; always @(posedge clk) begin if (reset) begin read_requst_state <= read_requst_empty; arvalid <= 1'b0; end else case (read_requst_state) read_requst_empty: begin if (data_rd_req) begin if (write_wait_enable) begin if (bvalid && bready) begin //when wait write back, stop send read request. easiest way. read_requst_state <= read_requst_ready; arid <= 4'b1; araddr <= data_rd_addr; arsize <= data_real_rd_size; arlen <= data_real_rd_len; arvalid <= 1'b1; end end else begin read_requst_state <= read_requst_ready; arid <= 4'b1; araddr <= data_rd_addr; arsize <= data_real_rd_size; arlen <= data_real_rd_len; arvalid <= 1'b1; end end else if (inst_rd_req) begin if (write_wait_enable) begin if (bvalid && bready) begin read_requst_state <= read_requst_ready; arid <= 4'b0; araddr <= inst_rd_addr; arsize <= inst_real_rd_size; arlen <= inst_real_rd_len; arvalid <= 1'b1; end end else begin read_requst_state <= read_requst_ready; arid <= 4'b0; araddr <= inst_rd_addr; arsize <= inst_real_rd_size; arlen <= inst_real_rd_len; arvalid <= 1'b1; end end end read_requst_ready: begin if (arready && arid[0]) begin read_requst_state <= read_requst_empty; arvalid <= 1'b0; end else if (arready && !arid[0]) begin read_requst_state <= read_requst_empty; arvalid <= 1'b0; end end endcase end always @(posedge clk) begin if (reset) begin read_respond_state <= read_respond_empty; rready <= 1'b1; end else case (read_respond_state) read_respond_empty: begin if (rvalid && rready) begin read_respond_state <= read_respond_transfer; end end read_respond_transfer: begin if (rlast && rvalid) begin read_respond_state <= read_respond_empty; end end endcase end always @(posedge clk) begin if (reset) begin write_requst_state <= write_request_empty; awvalid <= 1'b0; wvalid <= 1'b0; wlast <= 1'b0; bready <= 1'b0; write_buffer_num <= 3'b0; write_buffer_data <= 128'b0; end else case (write_requst_state) write_request_empty: begin if (data_wr_req) begin write_requst_state <= write_data_wait; //end awaddr <= data_wr_addr; awsize <= data_real_wr_size; awlen <= data_real_wr_len; awvalid <= 1'b1; wdata <= data_wr_data[31:0]; //from write 128 bit buffer wstrb <= data_wr_wstrb; write_buffer_data <= {32'b0, data_wr_data[127:32]}; if (data_wr_type == 3'b100) begin write_buffer_num <= 3'b011; end else begin write_buffer_num <= 3'b0; wlast <= 1'b1; end end end write_data_wait: begin if (awready) begin write_requst_state <= write_data_transform; awvalid <= 1'b0; wvalid <= 1'b1; end end write_data_transform: begin if (wready) begin if (wlast) begin write_requst_state <= write_wait_b; wvalid <= 1'b0; wlast <= 1'b0; bready <= 1'b1; end else begin if (write_buffer_last) begin wlast <= 1'b1; end write_requst_state <= write_data_transform; wdata <= write_buffer_data[31:0]; wvalid <= 1'b1; write_buffer_data <= {32'b0, write_buffer_data[127:32]}; write_buffer_num <= write_buffer_num - 3'b1; end end end write_wait_b: begin if (bvalid && bready) begin write_requst_state <= write_request_empty; bready <= 1'b0; end end default: begin write_requst_state <= write_request_empty; end endcase end assign write_wait_enable = ~(write_requst_state == write_request_empty); endmodule