diff --git a/library/axi_dmac/address_generator.v b/library/axi_dmac/address_generator.v index 27513a2c8..02ffcc1fb 100644 --- a/library/axi_dmac/address_generator.v +++ b/library/axi_dmac/address_generator.v @@ -48,11 +48,14 @@ module dmac_address_generator #( input req_valid, output reg req_ready, input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address, - input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, output reg [ID_WIDTH-1:0] id, input [ID_WIDTH-1:0] request_id, + input bl_valid, + output reg bl_ready, + input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + input eot, input enable, @@ -105,6 +108,12 @@ always @(posedge clk) begin end end +always @(posedge clk) begin + if (bl_valid == 1'b1 && bl_ready == 1'b1) begin + last_burst_len <= measured_last_burst_length; + end +end + always @(posedge clk) begin if (addr_valid == 1'b0) begin last <= eot; @@ -119,12 +128,26 @@ end always @(posedge clk) begin if (req_ready == 1'b1) begin address <= req_address; - last_burst_len <= req_last_burst_length; end else if (addr_valid == 1'b1 && addr_ready == 1'b1) begin address <= address + MAX_BEATS_PER_BURST; end end +always @(posedge clk) begin + if (resetn == 1'b0) begin + bl_ready <= 1'b1; + end else begin + if (bl_ready == 1'b1) begin + bl_ready <= ~bl_valid; + end else if (addr_valid == 1'b0 && eot == 1'b1) begin + // assert bl_ready only when the addr_valid asserts in the next cycle + if (id != request_id && enable == 1'b1) begin + bl_ready <= 1'b1; + end + end + end +end + always @(posedge clk) begin if (resetn == 1'b0) begin req_ready <= 1'b1; @@ -136,7 +159,10 @@ always @(posedge clk) begin addr_valid <= 1'b0; req_ready <= last; end else if (id != request_id && enable == 1'b1) begin - addr_valid <= 1'b1; + // if eot wait until the last_burst_len gets synced over + if (eot == 1'b0 || (eot == 1'b1 && bl_ready == 1'b0)) begin + addr_valid <= 1'b1; + end end end end diff --git a/library/axi_dmac/axi_dmac_constr.ttcl b/library/axi_dmac/axi_dmac_constr.ttcl index abc762751..b73011fae 100644 --- a/library/axi_dmac/axi_dmac_constr.ttcl +++ b/library/axi_dmac/axi_dmac_constr.ttcl @@ -78,24 +78,6 @@ set_false_path -quiet \ -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ -filter {NAME =~ *i_sync_control_dest* && IS_SEQUENTIAL}] -set_max_delay -quiet -datapath_only \ - -from $req_clk \ - -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ - -filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ - [get_property -min PERIOD $req_clk] - -set_max_delay -quiet -datapath_only \ - -from $dest_clk \ - -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ - -filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ - [get_property -min PERIOD $dest_clk] - -set_max_delay -quiet -datapath_only \ - -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ - -filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \ - -to $dest_clk \ - [get_property -min PERIOD $dest_clk] - set_max_delay -quiet -datapath_only \ -from $dest_clk \ -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ @@ -147,6 +129,41 @@ set_max_delay -quiet -datapath_only \ -to $dest_clk \ [get_property -min PERIOD $dest_clk] +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_req_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_dest_req_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_dest_req_fifo* && IS_SEQUENTIAL}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from $src_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo/i_waddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $src_clk] + +set_max_delay -quiet -datapath_only \ + -from $dest_clk \ + -to [get_cells -quiet -hier *cdc_sync_stage1_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo/i_raddr_sync* && IS_SEQUENTIAL}] \ + [get_property -min PERIOD $dest_clk] + +set_max_delay -quiet -datapath_only \ + -from [get_cells -quiet -hier *cdc_sync_fifo_ram_reg* \ + -filter {NAME =~ *i_src_dest_bl_fifo* && IS_SEQUENTIAL}] \ + -to $dest_clk \ + [get_property -min PERIOD $dest_clk] <: } :> # Reset signals set_false_path -quiet \ diff --git a/library/axi_dmac/data_mover.v b/library/axi_dmac/data_mover.v index 192030489..b1f3970f9 100644 --- a/library/axi_dmac/data_mover.v +++ b/library/axi_dmac/data_mover.v @@ -47,6 +47,10 @@ module dmac_data_mover #( output [ID_WIDTH-1:0] response_id, input eot, + output reg bl_valid = 'b0, + input bl_ready, + output reg [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + output xfer_req, output s_axi_ready, @@ -72,6 +76,7 @@ localparam BEAT_COUNTER_MAX = {BEATS_PER_BURST_WIDTH{1'b1}}; reg [BEATS_PER_BURST_WIDTH-1:0] last_burst_length = 'h00; reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter = 'h00; +reg [BEATS_PER_BURST_WIDTH-1:0] beat_counter_minus_one = 'h0; reg [ID_WIDTH-1:0] id = 'h00; reg [ID_WIDTH-1:0] id_next = 'h00; @@ -168,6 +173,23 @@ always @(posedge clk) begin last_burst_length <= req_last_burst_length; end +always @(posedge clk) begin + if (req_ready) begin + beat_counter_minus_one <= 'h0; + end else if (m_axi_valid == 1'b1) begin + beat_counter_minus_one <= beat_counter; + end +end + +always @(posedge clk) begin + if (last_load) begin + bl_valid <= 1'b1; + measured_last_burst_length <= beat_counter_minus_one; + end else if (bl_ready) begin + bl_valid <= 1'b0; + end +end + always @(posedge clk) begin if (resetn == 1'b0) begin active <= 1'b0; diff --git a/library/axi_dmac/dest_axi_mm.v b/library/axi_dmac/dest_axi_mm.v index 9a8a22811..5609a0220 100644 --- a/library/axi_dmac/dest_axi_mm.v +++ b/library/axi_dmac/dest_axi_mm.v @@ -48,7 +48,10 @@ module dmac_dest_mm_axi #( input req_valid, output req_ready, input [DMA_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH] req_address, - input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, + + input bl_valid, + output bl_ready, + input [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, input enable, output enabled, @@ -115,7 +118,10 @@ dmac_address_generator #( .req_valid(req_valid), .req_ready(req_ready), .req_address(req_address), - .req_last_burst_length(req_last_burst_length), + + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), .eot(address_eot), diff --git a/library/axi_dmac/dest_axi_stream.v b/library/axi_dmac/dest_axi_stream.v index 078f1323b..261c93b53 100644 --- a/library/axi_dmac/dest_axi_stream.v +++ b/library/axi_dmac/dest_axi_stream.v @@ -63,7 +63,6 @@ module dmac_dest_axi_stream #( input req_valid, output req_ready, - input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length, input req_xlast, output response_valid, diff --git a/library/axi_dmac/request_arb.v b/library/axi_dmac/request_arb.v index f952ba536..337e4ef23 100644 --- a/library/axi_dmac/request_arb.v +++ b/library/axi_dmac/request_arb.v @@ -209,15 +209,14 @@ wire enabled_dest; wire req_gen_valid; wire req_gen_ready; -wire req_dest_valid; -wire req_dest_ready; +wire src_dest_valid; +wire src_dest_ready; wire req_src_valid; wire req_src_ready; wire dest_req_valid; wire dest_req_ready; -wire [DMA_ADDRESS_WIDTH_DEST-1:0] dest_req_address; -wire [BEATS_PER_BURST_WIDTH_DEST-1:0] dest_req_last_burst_length; +wire [DMA_ADDRESS_WIDTH_DEST-1:0] dest_req_dest_address; wire dest_req_xlast; wire dest_response_valid; @@ -242,7 +241,8 @@ wire dest_fifo_last; wire src_req_valid; wire src_req_ready; -wire [DMA_ADDRESS_WIDTH_SRC-1:0] src_req_address; +wire [DMA_ADDRESS_WIDTH_DEST-1:0] src_req_dest_address; +wire [DMA_ADDRESS_WIDTH_SRC-1:0] src_req_src_address; wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_req_last_burst_length; wire src_req_sync_transfer_start; wire src_req_xlast; @@ -271,6 +271,10 @@ wire response_dest_ready = 1'b1; wire [1:0] response_dest_resp; wire response_dest_resp_eot; +wire src_bl_valid; +wire src_bl_ready; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_burst_length; + /* Unused for now wire response_src_valid; wire response_src_ready = 1'b1; @@ -298,6 +302,11 @@ end generate if (DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin +wire dest_bl_valid; +wire dest_bl_ready; +wire [BEATS_PER_BURST_WIDTH_DEST-1:0] dest_burst_length; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] dest_src_burst_length; + assign dest_clk = m_dest_axi_aclk; assign dest_ext_resetn = m_dest_axi_aresetn; @@ -326,8 +335,11 @@ dmac_dest_mm_axi #( .req_valid(dest_req_valid), .req_ready(dest_req_ready), - .req_address(dest_req_address), - .req_last_burst_length(dest_req_last_burst_length), + .req_address(dest_req_dest_address), + + .bl_valid(dest_bl_valid), + .bl_ready(dest_bl_ready), + .measured_last_burst_length(dest_burst_length), .response_valid(dest_response_valid), .response_ready(dest_response_ready), @@ -366,6 +378,42 @@ dmac_dest_mm_axi #( .m_axi_bready(m_axi_bready) ); +util_axis_fifo #( + .DATA_WIDTH(BEATS_PER_BURST_WIDTH_SRC), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) +) i_src_dest_bl_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_bl_valid), + .s_axis_ready(src_bl_ready), + .s_axis_empty(), + .s_axis_data(src_burst_length), + .s_axis_room(), + + .m_axis_aclk(dest_clk), + .m_axis_aresetn(dest_resetn), + .m_axis_valid(dest_bl_valid), + .m_axis_ready(dest_bl_ready), + .m_axis_data(dest_src_burst_length), + .m_axis_level() +); + +// Adapt burst length from source width to destination width by either +// truncation or completion with ones. +if (BEATS_PER_BURST_WIDTH_SRC == BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = dest_src_burst_length; +end + +if (BEATS_PER_BURST_WIDTH_SRC < BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = {dest_src_burst_length, + {BEATS_PER_BURST_WIDTH_DEST - BEATS_PER_BURST_WIDTH_SRC{1'b1}}}; +end + +if (BEATS_PER_BURST_WIDTH_SRC > BEATS_PER_BURST_WIDTH_DEST) begin +assign dest_burst_length = dest_src_burst_length[BEATS_PER_BURST_WIDTH_SRC-1 -: BEATS_PER_BURST_WIDTH_DEST]; +end + end else begin assign m_axi_awvalid = 1'b0; @@ -383,6 +431,8 @@ assign m_axi_wlast = 1'b0; assign m_axi_bready = 1'b0; +assign src_bl_ready = 1'b1; + end if (DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin @@ -413,7 +463,6 @@ dmac_dest_axi_stream #( .req_valid(dest_req_valid), .req_ready(dest_req_ready), - .req_last_burst_length(dest_req_last_burst_length), .req_xlast(dest_req_xlast), .response_valid(dest_response_valid), @@ -537,9 +586,13 @@ dmac_src_mm_axi #( .req_valid(src_req_valid), .req_ready(src_req_ready), - .req_address(src_req_address), + .req_address(src_req_src_address), .req_last_burst_length(src_req_last_burst_length), + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + /* TODO .response_valid(src_response_valid), .response_ready(src_response_ready), @@ -623,6 +676,10 @@ dmac_src_axi_stream #( .eot(src_eot), + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + .fifo_valid(src_valid), .fifo_data(src_data), .fifo_last(src_last), @@ -678,6 +735,10 @@ dmac_src_fifo_inf #( .eot(src_eot), + .bl_valid(src_bl_valid), + .bl_ready(src_bl_ready), + .measured_last_burst_length(src_burst_length), + .fifo_valid(src_valid), .fifo_data(src_data), .fifo_last(src_last), @@ -816,7 +877,7 @@ axi_register_slice #( ); splitter #( - .NUM_M(3) + .NUM_M(2) ) i_req_splitter ( .clk(req_clk), .resetn(req_resetn), @@ -824,30 +885,27 @@ splitter #( .s_ready(req_ready), .m_valid({ req_gen_valid, - req_dest_valid, req_src_valid }), .m_ready({ req_gen_ready, - req_dest_ready, req_src_ready }) ); util_axis_fifo #( - .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + BEATS_PER_BURST_WIDTH_DEST + 1), + .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + 1), .ADDRESS_WIDTH(0), - .ASYNC_CLK(ASYNC_CLK_DEST_REQ) + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) ) i_dest_req_fifo ( - .s_axis_aclk(req_clk), - .s_axis_aresetn(req_resetn), - .s_axis_valid(req_dest_valid), - .s_axis_ready(req_dest_ready), + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_dest_valid), + .s_axis_ready(src_dest_ready), .s_axis_empty(), .s_axis_data({ - req_dest_address, - req_length[BYTES_PER_BURST_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST], - req_xlast + src_req_dest_address, + src_req_xlast }), .s_axis_room(), @@ -856,15 +914,14 @@ util_axis_fifo #( .m_axis_valid(dest_req_valid), .m_axis_ready(dest_req_ready), .m_axis_data({ - dest_req_address, - dest_req_last_burst_length, + dest_req_dest_address, dest_req_xlast }), .m_axis_level() ); util_axis_fifo #( - .DATA_WIDTH(DMA_ADDRESS_WIDTH_SRC + BEATS_PER_BURST_WIDTH_SRC + 2), + .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + DMA_ADDRESS_WIDTH_SRC + BEATS_PER_BURST_WIDTH_SRC + 2), .ADDRESS_WIDTH(0), .ASYNC_CLK(ASYNC_CLK_REQ_SRC) ) i_src_req_fifo ( @@ -874,6 +931,7 @@ util_axis_fifo #( .s_axis_ready(req_src_ready), .s_axis_empty(), .s_axis_data({ + req_dest_address, req_src_address, req_length[BYTES_PER_BURST_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC], req_sync_transfer_start, @@ -883,10 +941,11 @@ util_axis_fifo #( .m_axis_aclk(src_clk), .m_axis_aresetn(src_resetn), - .m_axis_valid(src_req_valid), - .m_axis_ready(src_req_ready), + .m_axis_valid(src_req_spltr_valid), + .m_axis_ready(src_req_spltr_ready), .m_axis_data({ - src_req_address, + src_req_dest_address, + src_req_src_address, src_req_last_burst_length, src_req_sync_transfer_start, src_req_xlast @@ -894,6 +953,23 @@ util_axis_fifo #( .m_axis_level() ); +splitter #( + .NUM_M(2) +) i_src_splitter ( + .clk(src_clk), + .resetn(src_resetn), + .s_valid(src_req_spltr_valid), + .s_ready(src_req_spltr_ready), + .m_valid({ + src_req_valid, + src_dest_valid + }), + .m_ready({ + src_req_ready, + src_dest_ready + }) +); + util_axis_fifo #( .DATA_WIDTH(1), .ADDRESS_WIDTH(0), @@ -915,6 +991,7 @@ util_axis_fifo #( .m_axis_level() ); + /* Unused for now util_axis_fifo #( .DATA_WIDTH(2), diff --git a/library/axi_dmac/src_axi_mm.v b/library/axi_dmac/src_axi_mm.v index 347fbb109..4e1930b03 100644 --- a/library/axi_dmac/src_axi_mm.v +++ b/library/axi_dmac/src_axi_mm.v @@ -53,6 +53,9 @@ module dmac_src_mm_axi #( input enable, output reg enabled = 1'b0, + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, /* output response_valid, input response_ready, @@ -93,10 +96,35 @@ module dmac_src_mm_axi #( reg [ID_WIDTH-1:0] id = 'h00; wire address_enabled; +wire req_ready_ag; +wire req_valid_ag; +wire bl_ready_ag; +wire bl_valid_ag; assign data_id = id; assign response_id = id; +assign measured_last_burst_length = req_last_burst_length; + +splitter #( + .NUM_M(3) +) i_req_splitter ( + .clk(m_axi_aclk), + .resetn(m_axi_aresetn), + .s_valid(req_valid), + .s_ready(req_ready), + .m_valid({ + bl_valid, + bl_valid_ag, + req_valid_ag + }), + .m_ready({ + bl_ready, + bl_ready_ag, + req_ready_ag + }) +); + dmac_address_generator #( .ID_WIDTH(ID_WIDTH), .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH), @@ -114,10 +142,13 @@ dmac_address_generator #( .request_id(request_id), .id(address_id), - .req_valid(req_valid), - .req_ready(req_ready), + .req_valid(req_valid_ag), + .req_ready(req_ready_ag), .req_address(req_address), - .req_last_burst_length(req_last_burst_length), + + .bl_valid(bl_valid_ag), + .bl_ready(bl_ready_ag), + .measured_last_burst_length(req_last_burst_length), .eot(address_eot), diff --git a/library/axi_dmac/src_axi_stream.v b/library/axi_dmac/src_axi_stream.v index 7ed016668..523dc57da 100644 --- a/library/axi_dmac/src_axi_stream.v +++ b/library/axi_dmac/src_axi_stream.v @@ -50,6 +50,10 @@ module dmac_src_axi_stream #( output [ID_WIDTH-1:0] response_id, input eot, + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + output s_axis_ready, input s_axis_valid, input [S_AXIS_DATA_WIDTH-1:0] s_axis_data, @@ -85,6 +89,10 @@ dmac_data_mover # ( .response_id(response_id), .eot(eot), + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), + .req_valid(req_valid), .req_ready(req_ready), .req_last_burst_length(req_last_burst_length), diff --git a/library/axi_dmac/src_fifo_inf.v b/library/axi_dmac/src_fifo_inf.v index c8c7146c1..70d1b188b 100644 --- a/library/axi_dmac/src_fifo_inf.v +++ b/library/axi_dmac/src_fifo_inf.v @@ -49,6 +49,10 @@ module dmac_src_fifo_inf #( output [ID_WIDTH-1:0] response_id, input eot, + output bl_valid, + input bl_ready, + output [BEATS_PER_BURST_WIDTH-1:0] measured_last_burst_length, + input en, input [DATA_WIDTH-1:0] din, output reg overflow, @@ -95,6 +99,10 @@ dmac_data_mover # ( .response_id(response_id), .eot(eot), + .bl_valid(bl_valid), + .bl_ready(bl_ready), + .measured_last_burst_length(measured_last_burst_length), + .req_valid(req_valid), .req_ready(req_ready), .req_last_burst_length(req_last_burst_length),