diff --git a/rtl/ip/Bus_interconnects/axi2sram_sp_external.v b/rtl/ip/Bus_interconnects/axi2sram_sp_external.v index 1bb30d1..192b1c1 100644 --- a/rtl/ip/Bus_interconnects/axi2sram_sp_external.v +++ b/rtl/ip/Bus_interconnects/axi2sram_sp_external.v @@ -104,6 +104,10 @@ module axi2sram_sp_external #( reg [AXI_ADDR_WIDTH-1:0] req_addr_d, req_addr_q; reg [7:0] cnt_d, cnt_q; + reg [AXI_DATA_WIDTH-1:0] rdata_q; + reg rlast_q; + reg read_capture; + reg read_capture_last; function automatic [AXI_ADDR_WIDTH-1:0] get_wrap_boundary; input [AXI_ADDR_WIDTH-1:0] unaligned_address; @@ -146,6 +150,8 @@ module axi2sram_sp_external #( ax_req_d_burst = ax_req_q_burst; req_addr_d = req_addr_q; cnt_d = cnt_q; + read_capture = 1'b0; + read_capture_last = 1'b0; // Memory default assignments data_o = s_wdata; be_o = s_wstrb; @@ -158,6 +164,7 @@ module axi2sram_sp_external #( s_arready = 1'b0; // read response channel s_rvalid = 1'b0; + s_rdata = 'h0; s_rresp = 'h0; s_rlast = 'h0; s_rid = ax_req_q_id; @@ -183,7 +190,7 @@ module axi2sram_sp_external #( ax_req_d_len = s_arlen; ax_req_d_size = s_arsize; ax_req_d_burst = s_arburst; - state_d = READ; + state_d = READ_ADDR; // we can request the first address, this saves us time req_o = 1'b1; addr_o = s_araddr; @@ -230,14 +237,11 @@ module axi2sram_sp_external #( end READ: begin - // keep request to memory high - req_o = 1'b1; - addr_o = req_addr_q; // send the response s_rvalid = 1'b1; - s_rdata = data_i; + s_rdata = rdata_q; s_rid = ax_req_q_id; - s_rlast = (cnt_q == ax_req_q_len + 1); + s_rlast = rlast_q; // check that the master is ready, the slave must not wait on this if (s_rready) begin // we sent the last byte -> go back to idle @@ -246,7 +250,24 @@ module axi2sram_sp_external #( // we already got everything end else begin - state_d = READ_ADDR; + req_o = 1'b1; + case (ax_req_q_burst) + FIXED, INCR: addr_o = cons_addr; + WRAP: begin + if (cons_addr == upper_wrap_boundary) begin + addr_o = wrap_boundary; + end else if (cons_addr > upper_wrap_boundary) begin + addr_o = ax_req_q_addr + ((cnt_q - ax_req_q_len) << LOG_NR_BYTES); + end else begin + addr_o = cons_addr; + end + end + endcase + cnt_d = cnt_q + 1; + req_addr_d = addr_o; + read_capture = 1'b1; + read_capture_last = (cnt_d == ax_req_q_len + 1); + state_d = READ; end end end @@ -254,32 +275,9 @@ module axi2sram_sp_external #( READ_ADDR: begin // keep request to memory high req_o = 1'b1; - // send the response - s_rvalid = 1'b0; - // ---------------------------- - // Next address generation - // ---------------------------- - // handle the correct burst type - case (ax_req_q_burst) - FIXED, INCR: addr_o = cons_addr; - WRAP: begin - // check if the address reached warp boundary - if (cons_addr == upper_wrap_boundary) begin - addr_o = wrap_boundary; - // address warped beyond boundary - end else if (cons_addr > upper_wrap_boundary) begin - addr_o = ax_req_q_addr + ((cnt_q - ax_req_q_len) << LOG_NR_BYTES); - // we are still in the incremental regime - end else begin - addr_o = cons_addr; - end - end - endcase - // we need to change the address here for the upcoming request - // we can decrease the counter as the master has consumed the read data - cnt_d = cnt_q + 1; - // save the request address for the next cycle - req_addr_d = addr_o; + addr_o = req_addr_q; + read_capture = 1'b1; + read_capture_last = (cnt_q == ax_req_q_len + 1); state_d = READ; end @@ -352,6 +350,8 @@ module axi2sram_sp_external #( ax_req_q_size <= 3'h0; req_addr_q <= 'h0; cnt_q <= 8'h0; + rdata_q <= 'h0; + rlast_q <= 1'b0; end else begin state_q <= state_d; ax_req_q_addr <= ax_req_d_addr; @@ -361,6 +361,10 @@ module axi2sram_sp_external #( ax_req_q_size <= ax_req_d_size; req_addr_q <= req_addr_d; cnt_q <= cnt_d; + if (read_capture) begin + rdata_q <= data_i; + rlast_q <= read_capture_last; + end end end @@ -377,4 +381,3 @@ module axi2sram_sp_external #( // end endmodule -