From 8937c365a05b0490d32479c73d3b28ee52ab8e1a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 8 Sep 2017 11:12:44 +0200 Subject: [PATCH] axi_dmac: Hook up rlast for MM-AXI source interface For the memory-mapped AXI read interface the slave asserts rlast for the last beat in a burst. This means we don't have to count the number of beats to know when the burst is completed but instead can use rlast. This slightly reduces the amount of resources needed for the MM-AXI source module and given that the beat_counter is often the bottleneck timing wise this should also improve the timing. Signed-off-by: Lars-Peter Clausen --- library/axi_dmac/axi_dmac.v | 1 + library/axi_dmac/axi_dmac_hw.tcl | 4 +- library/axi_dmac/axi_dmac_ip.tcl | 1 - library/axi_dmac/axi_dmac_transfer.v | 2 + library/axi_dmac/request_arb.v | 4 +- library/axi_dmac/src_axi_mm.v | 92 +++++++++------------- library/axi_dmac/tb/dma_read_shutdown_tb.v | 1 + library/axi_dmac/tb/dma_read_tb.v | 1 + 8 files changed, 49 insertions(+), 57 deletions(-) diff --git a/library/axi_dmac/axi_dmac.v b/library/axi_dmac/axi_dmac.v index 1193b83c23..9008ffce5a 100644 --- a/library/axi_dmac/axi_dmac.v +++ b/library/axi_dmac/axi_dmac.v @@ -485,6 +485,7 @@ axi_dmac_transfer #( .m_axi_rdata(m_src_axi_rdata), .m_axi_rready(m_src_axi_rready), .m_axi_rvalid(m_src_axi_rvalid), + .m_axi_rlast(m_src_axi_rlast), .m_axi_rresp(m_src_axi_rresp), .s_axis_aclk(s_axis_aclk), diff --git a/library/axi_dmac/axi_dmac_hw.tcl b/library/axi_dmac/axi_dmac_hw.tcl index 15665f5fba..3ae53b0112 100644 --- a/library/axi_dmac/axi_dmac_hw.tcl +++ b/library/axi_dmac/axi_dmac_hw.tcl @@ -370,7 +370,9 @@ proc add_axi_master_interface {axi_type port suffix} { set_port_property ${port}_arlock TERMINATION true set_port_property ${port}_rid TERMINATION true set_port_property ${port}_bid TERMINATION true - set_port_property ${port}_rlast TERMINATION true + if {$port == "m_dest_axi"} { + set_port_property ${port}_rlast TERMINATION true + } } } proc axi_dmac_elaborate {} { diff --git a/library/axi_dmac/axi_dmac_ip.tcl b/library/axi_dmac/axi_dmac_ip.tcl index 04e7b1cc09..649d306d28 100644 --- a/library/axi_dmac/axi_dmac_ip.tcl +++ b/library/axi_dmac/axi_dmac_ip.tcl @@ -125,7 +125,6 @@ lappend dummy_axi_ports \ "m_src_axi_arid" \ "m_src_axi_arlock" \ "m_src_axi_rid" \ - "m_src_axi_rlast" \ "m_src_axi_awid" \ "m_src_axi_awlock" \ "m_src_axi_wid" \ diff --git a/library/axi_dmac/axi_dmac_transfer.v b/library/axi_dmac/axi_dmac_transfer.v index 851abe2912..312981cd37 100644 --- a/library/axi_dmac/axi_dmac_transfer.v +++ b/library/axi_dmac/axi_dmac_transfer.v @@ -114,6 +114,7 @@ module axi_dmac_transfer #( // Read data and response input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata, + input m_axi_rlast, output m_axi_rready, input m_axi_rvalid, input [1:0] m_axi_rresp, @@ -363,6 +364,7 @@ dmac_request_arb #( .m_axi_rready (m_axi_rready), .m_axi_rvalid (m_axi_rvalid), .m_axi_rdata (m_axi_rdata), + .m_axi_rlast (m_axi_rlast), .m_axi_rresp (m_axi_rresp), .s_axis_aclk (s_axis_aclk), diff --git a/library/axi_dmac/request_arb.v b/library/axi_dmac/request_arb.v index 029db8e94f..1f1c4a7a46 100644 --- a/library/axi_dmac/request_arb.v +++ b/library/axi_dmac/request_arb.v @@ -108,6 +108,7 @@ module dmac_request_arb #( input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata, output m_axi_rready, input m_axi_rvalid, + input m_axi_rlast, input [ 1:0] m_axi_rresp, // Slave streaming AXI interface @@ -515,7 +516,6 @@ assign src_ext_resetn = m_src_axi_aresetn; wire [ID_WIDTH-1:0] src_data_id; wire [ID_WIDTH-1:0] src_address_id; wire src_address_eot = eot_mem[src_address_id]; -wire src_data_eot = eot_mem[src_data_id]; assign dbg_src_address_id = src_address_id; assign dbg_src_data_id = src_data_id; @@ -551,7 +551,6 @@ dmac_src_mm_axi #( .data_id(src_data_id), .address_eot(src_address_eot), - .data_eot(src_data_eot), .fifo_valid(src_valid), .fifo_ready(src_ready), @@ -569,6 +568,7 @@ dmac_src_mm_axi #( .m_axi_rready(m_axi_rready), .m_axi_rvalid(m_axi_rvalid), .m_axi_rdata(m_axi_rdata), + .m_axi_rlast(m_axi_rlast), .m_axi_rresp(m_axi_rresp) ); diff --git a/library/axi_dmac/src_axi_mm.v b/library/axi_dmac/src_axi_mm.v index e926969056..0042623669 100644 --- a/library/axi_dmac/src_axi_mm.v +++ b/library/axi_dmac/src_axi_mm.v @@ -51,7 +51,7 @@ module dmac_src_mm_axi #( input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, input enable, - output enabled, + output reg enabled = 1'b0, /* output response_valid, @@ -64,7 +64,6 @@ module dmac_src_mm_axi #( output [ID_WIDTH-1:0] data_id, output [ID_WIDTH-1:0] address_id, - input data_eot, input address_eot, output fifo_valid, @@ -85,34 +84,18 @@ module dmac_src_mm_axi #( input [DMA_DATA_WIDTH-1:0] m_axi_rdata, output m_axi_rready, input m_axi_rvalid, + input m_axi_rlast, input [ 1:0] m_axi_rresp ); -wire address_enabled; +`include "inc_id.h" -wire address_req_valid; -wire address_req_ready; -wire data_req_valid; -wire data_req_ready; +reg [ID_WIDTH-1:0] id = 'h00; -assign response_id = data_id; +wire address_enabled; -splitter #( - .NUM_M(2) -) i_req_splitter ( - .clk(m_axi_aclk), - .resetn(m_axi_aresetn), - .s_valid(req_valid), - .s_ready(req_ready), - .m_valid({ - address_req_valid, - data_req_valid - }), - .m_ready({ - address_req_ready, - data_req_ready - }) -); +assign data_id = id; +assign response_id = id; dmac_address_generator #( .ID_WIDTH(ID_WIDTH), @@ -131,8 +114,8 @@ dmac_address_generator #( .request_id(request_id), .id(address_id), - .req_valid(address_req_valid), - .req_ready(address_req_ready), + .req_valid(req_valid), + .req_ready(req_ready), .req_address(req_address), .req_last_burst_length(req_last_burst_length), @@ -148,35 +131,38 @@ dmac_address_generator #( .cache(m_axi_arcache) ); -dmac_data_mover # ( - .ID_WIDTH(ID_WIDTH), - .DATA_WIDTH(DMA_DATA_WIDTH), - .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH) -) i_data_mover ( - .clk(m_axi_aclk), - .resetn(m_axi_aresetn), - - .enable(address_enabled), - .enabled(enabled), - - .xfer_req(), +assign fifo_valid = m_axi_rvalid; +assign m_axi_rready = fifo_ready; +assign fifo_data = m_axi_rdata; - .request_id(address_id), - .response_id(data_id), - .eot(data_eot), - - .req_valid(data_req_valid), - .req_ready(data_req_ready), - .req_last_burst_length(req_last_burst_length), +/* + * There is a requirement that data_id <= address_id (modulo 2**ID_WIDTH). We + * know that we will never receive data before we have requested it so there is + * an implicit dependency between data_id and address_id and no need to + * explicitly track it. + */ +always @(posedge m_axi_aclk) begin + if (m_axi_aresetn == 1'b0) begin + id <= 'h00; + end else if (m_axi_rvalid == 1'b1 && m_axi_rready == 1'b1 && + m_axi_rlast == 1'b1) begin + id <= inc_id(id); + end +end - .s_axi_valid(m_axi_rvalid), - .s_axi_ready(m_axi_rready), - .s_axi_data(m_axi_rdata), - .m_axi_valid(fifo_valid), - .m_axi_ready(fifo_ready), - .m_axi_data(fifo_data), - .m_axi_last() -); +/* + * We need to complete all bursts for which an address has been put onto the + * AXI-MM interface. + */ +always @(posedge m_axi_aclk) begin + if (m_axi_aresetn == 1'b0) begin + enabled <= 1'b0; + end else if (address_enabled == 1'b1) begin + enabled <= 1'b1; + end else if (id == address_id) begin + enabled <= 1'b0; + end +end /* TODO `include "resp.h" diff --git a/library/axi_dmac/tb/dma_read_shutdown_tb.v b/library/axi_dmac/tb/dma_read_shutdown_tb.v index c0face1369..d1d0ec6e11 100644 --- a/library/axi_dmac/tb/dma_read_shutdown_tb.v +++ b/library/axi_dmac/tb/dma_read_shutdown_tb.v @@ -128,6 +128,7 @@ module dmac_dma_read_shutdown_tb; .m_axi_rready(rready), .m_axi_rvalid(rvalid), .m_axi_rdata(rdata), + .m_axi_rlast(rlast), .m_axi_rresp(rresp), .ctrl_clk(clk), diff --git a/library/axi_dmac/tb/dma_read_tb.v b/library/axi_dmac/tb/dma_read_tb.v index 567468ecf5..18075e7828 100644 --- a/library/axi_dmac/tb/dma_read_tb.v +++ b/library/axi_dmac/tb/dma_read_tb.v @@ -121,6 +121,7 @@ module dmac_dma_read_tb; .m_axi_rready(rready), .m_axi_rvalid(rvalid), .m_axi_rdata(rdata), + .m_axi_rlast(rlast), .m_axi_rresp(rresp), .ctrl_clk(clk),