`include "VX_define.vh" module VX_avs_wrapper #( parameter AVS_DATA_WIDTH = 1, parameter AVS_ADDR_WIDTH = 1, parameter AVS_BURST_WIDTH = 1, parameter AVS_BANKS = 1, parameter REQ_TAG_WIDTH = 1, parameter RD_QUEUE_SIZE = 1, parameter AVS_BYTEENW = (AVS_DATA_WIDTH / 8), parameter RD_QUEUE_ADDR_WIDTH = $clog2(RD_QUEUE_SIZE+1) ) ( input wire clk, input wire reset, // Memory request input wire mem_req_valid, input wire mem_req_rw, input wire [AVS_BYTEENW-1:0] mem_req_byteen, input wire [AVS_ADDR_WIDTH-1:0] mem_req_addr, input wire [AVS_DATA_WIDTH-1:0] mem_req_data, input wire [REQ_TAG_WIDTH-1:0] mem_req_tag, output wire mem_req_ready, // Memory response output wire mem_rsp_valid, output wire [AVS_DATA_WIDTH-1:0] mem_rsp_data, output wire [REQ_TAG_WIDTH-1:0] mem_rsp_tag, input wire mem_rsp_ready, // AVS bus output wire [AVS_DATA_WIDTH-1:0] avs_writedata [AVS_BANKS], input wire [AVS_DATA_WIDTH-1:0] avs_readdata [AVS_BANKS], output wire [AVS_ADDR_WIDTH-1:0] avs_address [AVS_BANKS], input wire avs_waitrequest [AVS_BANKS], output wire avs_write [AVS_BANKS], output wire avs_read [AVS_BANKS], output wire [AVS_BYTEENW-1:0] avs_byteenable [AVS_BANKS], output wire [AVS_BURST_WIDTH-1:0] avs_burstcount [AVS_BANKS], input avs_readdatavalid [AVS_BANKS] ); localparam BANK_ADDRW = `LOG2UP(AVS_BANKS); // Requests handling wire [AVS_BANKS-1:0] avs_reqq_push, avs_reqq_pop, avs_reqq_ready; wire [AVS_BANKS-1:0][REQ_TAG_WIDTH-1:0] avs_reqq_tag_out; wire [AVS_BANKS-1:0] req_queue_going_full; wire [AVS_BANKS-1:0][RD_QUEUE_ADDR_WIDTH-1:0] req_queue_size; wire [BANK_ADDRW-1:0] req_bank_sel; if (AVS_BANKS >= 2) begin assign req_bank_sel = mem_req_addr[BANK_ADDRW-1:0]; end else begin assign req_bank_sel = 0; end for (genvar i = 0; i < AVS_BANKS; i++) begin assign avs_reqq_ready[i] = !req_queue_going_full[i] && !avs_waitrequest[i]; assign avs_reqq_push[i] = mem_req_valid && !mem_req_rw && avs_reqq_ready[i] && (req_bank_sel == i); end for (genvar i = 0; i < AVS_BANKS; i++) begin VX_pending_size #( .SIZE (RD_QUEUE_SIZE) ) pending_size ( .clk (clk), .reset (reset), .incr (avs_reqq_push[i]), .decr (avs_reqq_pop[i]), .full (req_queue_going_full[i]), .size (req_queue_size[i]), `UNUSED_PIN (empty) ); `UNUSED_VAR (req_queue_size) VX_fifo_queue #( .DATAW (REQ_TAG_WIDTH), .SIZE (RD_QUEUE_SIZE) ) rd_req_queue ( .clk (clk), .reset (reset), .push (avs_reqq_push[i]), .pop (avs_reqq_pop[i]), .data_in (mem_req_tag), .data_out (avs_reqq_tag_out[i]), `UNUSED_PIN (empty), `UNUSED_PIN (full), `UNUSED_PIN (alm_empty), `UNUSED_PIN (alm_full), `UNUSED_PIN (size) ); end for (genvar i = 0; i < AVS_BANKS; i++) begin assign avs_read[i] = mem_req_valid && !mem_req_rw && !req_queue_going_full[i] && (req_bank_sel == i); assign avs_write[i] = mem_req_valid && mem_req_rw && !req_queue_going_full[i] && (req_bank_sel == i); assign avs_address[i] = mem_req_addr; assign avs_byteenable[i] = mem_req_byteen; assign avs_writedata[i] = mem_req_data; assign avs_burstcount[i] = AVS_BURST_WIDTH'(1); end if (AVS_BANKS >= 2) begin assign mem_req_ready = avs_reqq_ready[req_bank_sel]; end else begin assign mem_req_ready = avs_reqq_ready; end // Responses handling wire [AVS_BANKS-1:0] rsp_arb_valid_in; wire [AVS_BANKS-1:0][AVS_DATA_WIDTH+REQ_TAG_WIDTH-1:0] rsp_arb_data_in; wire [AVS_BANKS-1:0] rsp_arb_ready_in; wire [AVS_BANKS-1:0][AVS_DATA_WIDTH-1:0] avs_rspq_data_out; wire [AVS_BANKS-1:0] avs_rspq_empty; for (genvar i = 0; i < AVS_BANKS; i++) begin VX_fifo_queue #( .DATAW (AVS_DATA_WIDTH), .SIZE (RD_QUEUE_SIZE) ) rd_rsp_queue ( .clk (clk), .reset (reset), .push (avs_readdatavalid[i]), .pop (avs_reqq_pop[i]), .data_in (avs_readdata[i]), .data_out (avs_rspq_data_out[i]), .empty (avs_rspq_empty[i]), `UNUSED_PIN (full), `UNUSED_PIN (alm_empty), `UNUSED_PIN (alm_full), `UNUSED_PIN (size) ); end for (genvar i = 0; i < AVS_BANKS; i++) begin assign rsp_arb_valid_in[i] = !avs_rspq_empty[i]; assign rsp_arb_data_in[i] = {avs_rspq_data_out[i], avs_reqq_tag_out[i]}; assign avs_reqq_pop[i] = rsp_arb_valid_in[i] && rsp_arb_ready_in[i]; end VX_stream_arbiter #( .NUM_REQS (AVS_BANKS), .DATAW (AVS_DATA_WIDTH + REQ_TAG_WIDTH), .TYPE ("R") ) rsp_arb ( .clk (clk), .reset (reset), .valid_in (rsp_arb_valid_in), .data_in (rsp_arb_data_in), .ready_in (rsp_arb_ready_in), .valid_out (mem_rsp_valid), .data_out ({mem_rsp_data, mem_rsp_tag}), .ready_out (mem_rsp_ready) ); `ifdef DBG_TRACE_AFU always @(posedge clk) begin if (mem_req_valid && mem_req_ready) begin if (mem_req_rw) begin dpi_trace("%d: AVS Wr Req: addr=%0h, byteen=%0h, tag=%0h, data=%0h\n", $time, `TO_FULL_ADDR(mem_req_addr), mem_req_byteen, mem_req_tag, mem_req_data); end else begin dpi_trace("%d: AVS Rd Req: addr=%0h, byteen=%0h, tag=%0h, pending=%0d\n", $time, `TO_FULL_ADDR(mem_req_addr), mem_req_byteen, mem_req_tag, req_queue_size); end end if (mem_rsp_valid && mem_rsp_ready) begin dpi_trace("%d: AVS Rd Rsp: tag=%0h, data=%0h, pending=%0d\n", $time, mem_rsp_tag, mem_rsp_data, req_queue_size); end end `endif endmodule