From d80e1b28a313bc51089ab765b812f45ea4970082 Mon Sep 17 00:00:00 2001 From: Blaise Tine Date: Thu, 20 May 2021 05:36:09 -0700 Subject: [PATCH] fixes for multi-channel memory support --- hw/rtl/afu/VX_avs_wrapper.v | 36 +++--- hw/rtl/afu/vortex_afu.sv | 220 ++++++++++++++++++------------------ 2 files changed, 130 insertions(+), 126 deletions(-) diff --git a/hw/rtl/afu/VX_avs_wrapper.v b/hw/rtl/afu/VX_avs_wrapper.v index 16947179..b3d0a5d5 100644 --- a/hw/rtl/afu/VX_avs_wrapper.v +++ b/hw/rtl/afu/VX_avs_wrapper.v @@ -47,37 +47,39 @@ module VX_avs_wrapper #( // Requests handling - wire [NUM_BANKS-1:0] avs_reqq_pop; + wire [NUM_BANKS-1:0] avs_reqq_push, avs_reqq_pop, avs_reqq_ready; wire [NUM_BANKS-1:0] req_queue_going_full; wire [NUM_BANKS-1:0][RD_QUEUE_ADDR_WIDTH-1:0] req_queue_size; wire [NUM_BANKS-1:0][REQ_TAG_WIDTH-1:0] avs_reqq_data_out; - wire [BANK_ADDRW-1:0] req_bank_sel = (NUM_BANKS >= 2) ? mem_req_addr [BANK_ADDRW-1:0] : '0; - - wire avs_reqq_push = mem_req_valid && !mem_req_rw && mem_req_ready; + wire [BANK_ADDRW-1:0] req_bank_sel = (NUM_BANKS >= 2) ? mem_req_addr[BANK_ADDRW-1:0] : '0; for (genvar i = 0; i < NUM_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 < NUM_BANKS; i++) begin VX_pending_size #( .SIZE (RD_QUEUE_SIZE) ) pending_size ( .clk (clk), .reset (reset), - .push (avs_reqq_push && (req_bank_sel == i)), - .pop (avs_reqq_pop[i]), - `UNUSED_PIN (empty), + .push (avs_reqq_push[i]), + .pop (avs_reqq_pop[i]), .full (req_queue_going_full[i]), - .size (req_queue_size[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) + .DATAW (REQ_TAG_WIDTH), + .SIZE (RD_QUEUE_SIZE) ) rd_req_queue ( .clk (clk), .reset (reset), - .push (avs_reqq_push && (req_bank_sel == i)), + .push (avs_reqq_push[i]), .pop (avs_reqq_pop[i]), .data_in (mem_req_tag), .data_out (avs_reqq_data_out[i]), @@ -98,7 +100,7 @@ module VX_avs_wrapper #( assign avs_burstcount[i] = AVS_BURST_WIDTH'(1); end - assign mem_req_ready = !(avs_waitrequest[req_bank_sel] || req_queue_going_full[req_bank_sel]); + assign mem_req_ready = avs_reqq_ready[req_bank_sel]; // Responses handling @@ -110,10 +112,9 @@ module VX_avs_wrapper #( wire [NUM_BANKS-1:0] avs_rspq_empty; for (genvar i = 0; i < NUM_BANKS; i++) begin - VX_fifo_queue #( - .DATAW (AVS_DATA_WIDTH), - .SIZE (RD_QUEUE_SIZE) + .DATAW (AVS_DATA_WIDTH), + .SIZE (RD_QUEUE_SIZE) ) rd_rsp_queue ( .clk (clk), .reset (reset), @@ -127,7 +128,6 @@ module VX_avs_wrapper #( `UNUSED_PIN (alm_full), `UNUSED_PIN (size) ); - end for (genvar i = 0; i < NUM_BANKS; i++) begin @@ -138,8 +138,8 @@ module VX_avs_wrapper #( VX_stream_arbiter #( .NUM_REQS (NUM_BANKS), - .DATAW (AVS_DATA_WIDTH+REQ_TAG_WIDTH), - .BUFFERED (0) + .DATAW (AVS_DATA_WIDTH + REQ_TAG_WIDTH), + .BUFFERED (NUM_BANKS > 2) ) rsp_arb ( .clk (clk), .reset (reset), diff --git a/hw/rtl/afu/vortex_afu.sv b/hw/rtl/afu/vortex_afu.sv index fbd0cbfe..39bc970d 100644 --- a/hw/rtl/afu/vortex_afu.sv +++ b/hw/rtl/afu/vortex_afu.sv @@ -48,7 +48,10 @@ localparam CCI_LINE_SIZE = CCI_LINE_WIDTH / 8; localparam CCI_ADDR_WIDTH = 32 - $clog2(CCI_LINE_WIDTH / 8); localparam AVS_RD_QUEUE_SIZE = 16; -localparam AVS_REQ_TAGW = `MAX(`VX_MEM_TAG_WIDTH, `VX_MEM_TAG_WIDTH + ($clog2(LMEM_LINE_WIDTH) - $clog2(`VX_MEM_LINE_WIDTH))); +localparam AVS_REQ_TAGW_VX = `MAX(`VX_MEM_TAG_WIDTH, `VX_MEM_TAG_WIDTH + $clog2(LMEM_LINE_WIDTH) - $clog2(`VX_MEM_LINE_WIDTH)); +localparam AVS_REQ_TAGW_CCI = `MAX(CCI_ADDR_WIDTH, CCI_ADDR_WIDTH + $clog2(LMEM_LINE_WIDTH) - $clog2(CCI_LINE_WIDTH)); +localparam AVS_REQ_TAGW = `MAX(AVS_REQ_TAGW_VX, AVS_REQ_TAGW_CCI); + localparam CCI_RD_WINDOW_SIZE = 8; localparam CCI_RD_QUEUE_SIZE = 2 * CCI_RD_WINDOW_SIZE; @@ -448,27 +451,19 @@ end wire cci_mem_rd_req_valid; wire cci_mem_wr_req_valid; -wire [CCI_ADDR_WIDTH-1:0] cci_mem_rd_req_addr; -wire [CCI_ADDR_WIDTH-1:0] cci_mem_wr_req_addr; wire [CCI_RD_RQ_DATAW-1:0] cci_rdq_dout; -wire cci_mem_req_ready; wire cci_mem_req_valid; wire cci_mem_req_rw; wire [CCI_ADDR_WIDTH-1:0] cci_mem_req_addr; -wire cci_mem_req_tag = 1'b0; +wire [CCI_ADDR_WIDTH-1:0] cci_mem_req_tag; +wire cci_mem_req_ready; wire cci_mem_rsp_valid; wire [CCI_LINE_WIDTH-1:0] cci_mem_rsp_data; -wire cci_mem_rsp_tag; +wire [CCI_ADDR_WIDTH-1:0] cci_mem_rsp_tag; wire cci_mem_rsp_ready; -`UNUSED_VAR (cci_mem_rsp_tag) - -assign cci_mem_req_rw = (CMD_MEM_WRITE == state); -assign cci_mem_req_valid = cci_mem_req_rw ? cci_mem_wr_req_valid : cci_mem_rd_req_valid; -assign cci_mem_req_addr = cci_mem_req_rw ? cci_mem_wr_req_addr : cci_mem_rd_req_addr; - //-- wire cci_mem_req_arb_valid; @@ -489,7 +484,7 @@ VX_to_mem #( .DST_DATA_WIDTH (LMEM_LINE_WIDTH), .SRC_ADDR_WIDTH (CCI_ADDR_WIDTH), .DST_ADDR_WIDTH (LMEM_ADDR_WIDTH), - .SRC_TAG_WIDTH (1), + .SRC_TAG_WIDTH (CCI_ADDR_WIDTH), .DST_TAG_WIDTH (AVS_REQ_TAGW) ) cci_to_mem ( .clk (clk), @@ -675,13 +670,15 @@ VX_avs_wrapper #( // CCI-P Read Request /////////////////////////////////////////////////////////// reg [CCI_ADDR_WIDTH-1:0] cci_mem_wr_req_ctr; -reg [CCI_ADDR_WIDTH-1:0] cci_rd_req_ctr; -wire [CCI_ADDR_WIDTH-1:0] cci_rd_req_ctr_next; +wire [CCI_ADDR_WIDTH-1:0] cci_mem_wr_req_addr; reg [CCI_ADDR_WIDTH-1:0] cci_mem_wr_req_addr_unqual; -wire [CCI_RD_RQ_TAGW-1:0] cci_rd_req_tag, cci_rd_rsp_tag; +reg [CCI_ADDR_WIDTH-1:0] cci_rd_req_ctr; +wire [CCI_RD_RQ_TAGW-1:0] cci_rd_req_tag; +wire [CCI_RD_RQ_TAGW-1:0] cci_rd_rsp_tag; reg [CCI_RD_RQ_TAGW-1:0] cci_rd_rsp_ctr; -t_ccip_clAddr cci_rd_req_addr; +wire cci_rd_req_fire; +t_ccip_clAddr cci_rd_req_addr; reg cci_rd_req_enable, cci_rd_req_wait; wire cci_rdq_push, cci_rdq_pop; @@ -689,6 +686,7 @@ wire [CCI_RD_RQ_DATAW-1:0] cci_rdq_din; wire cci_rdq_empty; always @(*) begin + af2cp_sTxPort.c0.valid = cci_rd_req_fire; af2cp_sTxPort.c0.hdr = t_ccip_c0_ReqMemHdr'(0); af2cp_sTxPort.c0.hdr.address = cci_rd_req_addr; af2cp_sTxPort.c0.hdr.mdata = t_ccip_mdata'(cci_rd_req_tag); @@ -696,8 +694,6 @@ end wire cci_mem_wr_req_fire = cci_mem_wr_req_valid && cci_mem_req_ready; -wire cci_rd_req_fire = af2cp_sTxPort.c0.valid; - wire cci_rd_rsp_fire = (STATE_WRITE == state) && cp2af_sRxPort.c0.rspValid && (cp2af_sRxPort.c0.hdr.resp_type == eRSP_RDLINE); @@ -705,10 +701,8 @@ wire cci_rd_rsp_fire = (STATE_WRITE == state) assign cci_rd_req_tag = CCI_RD_RQ_TAGW'(cci_rd_req_ctr); assign cci_rd_rsp_tag = CCI_RD_RQ_TAGW'(cp2af_sRxPort.c0.hdr.mdata); -assign cci_rd_req_ctr_next = cci_rd_req_ctr + CCI_ADDR_WIDTH'(cci_rd_req_fire ? 1 : 0); - -assign cci_rdq_pop = cci_mem_wr_req_fire; assign cci_rdq_push = cci_rd_rsp_fire; +assign cci_rdq_pop = cci_mem_wr_req_fire; assign cci_rdq_din = {cp2af_sRxPort.c0.data, cci_rd_rsp_tag}; wire [$clog2(CCI_RD_QUEUE_SIZE+1)-1:0] cci_pending_reads; @@ -726,72 +720,72 @@ VX_pending_size #( ); `UNUSED_VAR (cci_pending_reads) +assign cci_rd_req_fire = cci_rd_req_enable && !(cci_rd_req_wait || cci_pending_reads_full); + assign cci_mem_wr_req_valid = !cci_rdq_empty; assign cci_mem_wr_req_addr = cci_mem_wr_req_addr_unqual + (CCI_ADDR_WIDTH'(CCI_RD_RQ_TAGW'(cci_rdq_dout))); -assign af2cp_sTxPort.c0.valid = cci_rd_req_enable && !(cci_rd_req_wait || cci_pending_reads_full); - assign cmd_write_done = (cci_mem_wr_req_ctr == cmd_data_size); // Send read requests to CCI always @(posedge clk) begin if (reset) begin - cci_rd_req_addr <= 0; - cci_rd_req_ctr <= 0; - cci_rd_rsp_ctr <= 0; - cci_rd_req_enable <= 0; - cci_rd_req_wait <= 0; - cci_mem_wr_req_ctr <= 0; - cci_mem_wr_req_addr_unqual <= 0; - end - else begin + cci_rd_req_enable <= 0; + cci_rd_req_wait <= 0; + end else begin if ((STATE_IDLE == state) && (CMD_MEM_WRITE == cmd_type)) begin - cci_rd_req_addr <= cmd_io_addr; - cci_rd_req_ctr <= 0; - cci_rd_rsp_ctr <= 0; - cci_rd_req_enable <= (cmd_data_size != 0); - cci_rd_req_wait <= 0; - cci_mem_wr_req_ctr <= 0; - cci_mem_wr_req_addr_unqual <= cmd_mem_addr; + cci_rd_req_enable <= (cmd_data_size != 0); + cci_rd_req_wait <= 0; end cci_rd_req_enable <= (STATE_WRITE == state) - && (cci_rd_req_ctr_next != cmd_data_size) + && (cci_rd_req_ctr != cmd_data_size) && !cp2af_sRxPort.c0TxAlmFull; - if (cci_rd_req_fire) begin - cci_rd_req_addr <= cci_rd_req_addr + 1; - cci_rd_req_ctr <= cci_rd_req_ctr_next; - if (cci_rd_req_tag == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1)) begin - cci_rd_req_wait <= 1; // end current request batch - end - `ifdef DBG_PRINT_OPAE - $display("%t: CCI Rd Req: addr=%0h, tag=%0h, rem=%0d, pending=%0d", $time, cci_rd_req_addr, cci_rd_req_tag, (cmd_data_size - cci_rd_req_ctr_next), cci_pending_reads); - `endif + if (cci_rd_req_fire && (cci_rd_req_tag == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1))) begin + cci_rd_req_wait <= 1; // end current request batch end - if (cci_rd_rsp_fire) begin - cci_rd_rsp_ctr <= cci_rd_rsp_ctr + CCI_RD_RQ_TAGW'(1); - if (cci_rd_rsp_ctr == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1)) begin - cci_rd_req_wait <= 0; // restart new request batch - end - `ifdef DBG_PRINT_OPAE - $display("%t: CCI Rd Rsp: idx=%0d, ctr=%0d, data=%0h", $time, cci_rd_rsp_tag, cci_rd_rsp_ctr, cp2af_sRxPort.c0.data); - `endif - end + if (cci_rd_rsp_fire && (cci_rd_rsp_ctr == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1))) begin + cci_rd_req_wait <= 0; // begin new request batch + end + end - /*if (cci_rdq_pop) begin - `ifdef DBG_PRINT_OPAE - $display("%t: CCI Rd Queue Pop: pending=%0d", $time, cci_pending_reads); - `endif - end*/ + if ((STATE_IDLE == state) + && (CMD_MEM_WRITE == cmd_type)) begin + cci_rd_req_addr <= cmd_io_addr; + cci_rd_req_ctr <= 0; + cci_rd_rsp_ctr <= 0; + cci_mem_wr_req_ctr <= 0; + cci_mem_wr_req_addr_unqual <= cmd_mem_addr; + end - if (cci_mem_wr_req_fire) begin - cci_mem_wr_req_addr_unqual <= cci_mem_wr_req_addr_unqual + ((CCI_RD_RQ_TAGW'(cci_mem_wr_req_ctr) == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1)) ? CCI_ADDR_WIDTH'(CCI_RD_WINDOW_SIZE) : CCI_ADDR_WIDTH'(0)); - cci_mem_wr_req_ctr <= cci_mem_wr_req_ctr + CCI_ADDR_WIDTH'(1); - end + if (cci_rd_req_fire) begin + cci_rd_req_addr <= cci_rd_req_addr + 1; + cci_rd_req_ctr <= cci_rd_req_ctr + 1; + `ifdef DBG_PRINT_OPAE + $display("%t: CCI Rd Req: addr=%0h, tag=%0h, rem=%0d, pending=%0d", $time, cci_rd_req_addr, cci_rd_req_tag, (cmd_data_size - cci_rd_req_ctr - 1), cci_pending_reads); + `endif + end + + if (cci_rd_rsp_fire) begin + cci_rd_rsp_ctr <= cci_rd_rsp_ctr + CCI_RD_RQ_TAGW'(1); + `ifdef DBG_PRINT_OPAE + $display("%t: CCI Rd Rsp: idx=%0d, ctr=%0d, data=%0h", $time, cci_rd_rsp_tag, cci_rd_rsp_ctr, cp2af_sRxPort.c0.data); + `endif + end + + if (cci_rdq_pop) begin + `ifdef DBG_PRINT_OPAE + $display("%t: CCI Rd Queue Pop: pending=%0d", $time, cci_pending_reads); + `endif + end + + if (cci_mem_wr_req_fire) begin + cci_mem_wr_req_addr_unqual <= cci_mem_wr_req_addr_unqual + ((CCI_RD_RQ_TAGW'(cci_mem_wr_req_ctr) == CCI_RD_RQ_TAGW'(CCI_RD_WINDOW_SIZE-1)) ? CCI_ADDR_WIDTH'(CCI_RD_WINDOW_SIZE) : CCI_ADDR_WIDTH'(0)); + cci_mem_wr_req_ctr <= cci_mem_wr_req_ctr + CCI_ADDR_WIDTH'(1); end end @@ -835,22 +829,24 @@ VX_fifo_queue #( // CCI-P Write Request ////////////////////////////////////////////////////////// reg [CCI_ADDR_WIDTH-1:0] cci_mem_rd_req_ctr; +reg [CCI_ADDR_WIDTH-1:0] cci_mem_rd_req_addr; reg [CCI_ADDR_WIDTH-1:0] cci_wr_req_ctr; -reg [CCI_ADDR_WIDTH-1:0] cci_mem_rd_req_addr_r; + +reg cci_wr_req_fire; t_ccip_clAddr cci_wr_req_addr; +t_ccip_clData cci_wr_req_data; always @(*) begin + af2cp_sTxPort.c1.valid = cci_wr_req_fire; af2cp_sTxPort.c1.hdr = t_ccip_c1_ReqMemHdr'(0); - af2cp_sTxPort.c1.hdr.address = cci_wr_req_addr; af2cp_sTxPort.c1.hdr.sop = 1; // single line write mode - af2cp_sTxPort.c1.data = t_ccip_clData'(cci_mem_rsp_data); + af2cp_sTxPort.c1.hdr.address = cci_wr_req_addr; + af2cp_sTxPort.c1.data = cci_wr_req_data; end wire cci_mem_rd_req_fire = cci_mem_rd_req_valid && cci_mem_req_ready; wire cci_mem_rd_rsp_fire = cci_mem_rsp_valid && cci_mem_rsp_ready; -wire cci_wr_req_fire = cci_mem_rd_rsp_fire; - wire cci_wr_rsp_fire = (STATE_READ == state) && cp2af_sRxPort.c1.rspValid && (cp2af_sRxPort.c1.hdr.resp_type == eRSP_WRLINE); @@ -858,12 +854,13 @@ wire cci_wr_rsp_fire = (STATE_READ == state) wire [$clog2(CCI_RW_PENDING_SIZE+1)-1:0] cci_pending_writes; wire cci_pending_writes_empty; wire cci_pending_writes_full; + VX_pending_size #( .SIZE (CCI_RW_PENDING_SIZE) ) cci_wr_pending_size ( .clk (clk), .reset (reset), - .push (cci_wr_req_fire), + .push (cci_mem_rd_rsp_fire), .pop (cci_wr_rsp_fire), .empty (cci_pending_writes_empty), .full (cci_pending_writes_full), @@ -871,54 +868,61 @@ VX_pending_size #( ); `UNUSED_VAR (cci_pending_writes) -assign cci_mem_rd_req_valid = (cci_mem_rd_req_ctr != 0); -assign cci_mem_rd_req_addr = cci_mem_rd_req_addr_r; +assign cci_mem_rd_req_valid = (STATE_READ == state) + && (cci_mem_rd_req_ctr != cmd_data_size); -assign af2cp_sTxPort.c1.valid = cci_mem_rd_rsp_fire; -assign cci_mem_rsp_ready = !cp2af_sRxPort.c1TxAlmFull && !cci_pending_writes_full; +assign cci_mem_rsp_ready = !cp2af_sRxPort.c1TxAlmFull + && !cci_pending_writes_full; -assign cmd_read_done = (0 == cci_wr_req_ctr) && cci_pending_writes_empty; +assign cmd_read_done = (0 == cci_wr_req_ctr) + && cci_pending_writes_empty; // Send write requests to CCI always @(posedge clk) begin if (reset) begin - cci_wr_req_addr <= 0; - cci_wr_req_ctr <= 0; - cci_mem_rd_req_ctr <= 0; - cci_mem_rd_req_addr_r <= 0; + cci_wr_req_fire <= 0; + end else begin + cci_wr_req_fire <= cci_mem_rd_rsp_fire; end - else begin - if ((STATE_IDLE == state) - && (CMD_MEM_READ == cmd_type)) begin - cci_wr_req_addr <= cmd_io_addr; - cci_wr_req_ctr <= cmd_data_size; - cci_mem_rd_req_ctr <= cmd_data_size; - cci_mem_rd_req_addr_r <= cmd_mem_addr; - end + + if ((STATE_IDLE == state) + && (CMD_MEM_READ == cmd_type)) begin + cci_mem_rd_req_ctr <= 0; + cci_mem_rd_req_addr <= cmd_mem_addr; + cci_wr_req_ctr <= cmd_data_size; + end - if (cci_wr_req_fire) begin - assert(cci_wr_req_ctr != 0); - cci_wr_req_addr <= cci_wr_req_addr + t_ccip_clAddr'(1); - cci_wr_req_ctr <= cci_wr_req_ctr - CCI_ADDR_WIDTH'(1); - `ifdef DBG_PRINT_OPAE - $display("%t: CCI Wr Req: addr=%0h, rem=%0d, pending=%0d, data=%0h", $time, cci_wr_req_addr, (cci_wr_req_ctr - 1), cci_pending_writes, af2cp_sTxPort.c1.data); - `endif - end + if (cci_mem_rd_req_fire) begin + cci_mem_rd_req_addr <= cci_mem_rd_req_addr + CCI_ADDR_WIDTH'(1); + cci_mem_rd_req_ctr <= cci_mem_rd_req_ctr + CCI_ADDR_WIDTH'(1); + end - /*`ifdef DBG_PRINT_OPAE - if (cci_wr_rsp_fire) begin - $display("%t: CCI Wr Rsp: pending=%0d", $time, cci_pending_writes); - end - `endif*/ + cci_wr_req_addr <= cmd_io_addr + t_ccip_clAddr'(cci_mem_rsp_tag); + cci_wr_req_data <= t_ccip_clData'(cci_mem_rsp_data); - if (cci_mem_rd_req_fire) begin - cci_mem_rd_req_addr_r <= cci_mem_rd_req_addr_r + CCI_ADDR_WIDTH'(1); - cci_mem_rd_req_ctr <= cci_mem_rd_req_ctr - CCI_ADDR_WIDTH'(1); - end + if (cci_wr_req_fire) begin + assert(cci_wr_req_ctr != 0); + cci_wr_req_ctr <= cci_wr_req_ctr - CCI_ADDR_WIDTH'(1); + `ifdef DBG_PRINT_OPAE + $display("%t: CCI Wr Req: addr=%0h, rem=%0d, pending=%0d, data=%0h", $time, cci_wr_req_addr, (cci_wr_req_ctr - 1), cci_pending_writes, af2cp_sTxPort.c1.data); + `endif + end + + if (cci_wr_rsp_fire) begin + `ifdef DBG_PRINT_OPAE + $display("%t: CCI Wr Rsp: pending=%0d", $time, cci_pending_writes); + `endif end end +//-- + +assign cci_mem_req_rw = (CMD_MEM_WRITE == state); +assign cci_mem_req_valid = cci_mem_req_rw ? cci_mem_wr_req_valid : cci_mem_rd_req_valid; +assign cci_mem_req_addr = cci_mem_req_rw ? cci_mem_wr_req_addr : cci_mem_rd_req_addr; +assign cci_mem_req_tag = cci_mem_req_rw ? cci_mem_wr_req_ctr : cci_mem_rd_req_ctr; + // CSRs /////////////////////////////////////////////////////////////////////// reg csr_io_req_sent;