From cef4adb81daee17f9187c3003b86dd79230cef09 Mon Sep 17 00:00:00 2001 From: Filip Gherman Date: Wed, 14 Sep 2022 14:28:34 +0300 Subject: [PATCH] axi_dmac: Add suport for 64 bit address width New improvements for the ADI DMAC IP: 1)The capability to manually overwrite the DMA_AXI_ADDR_WIDTH(from GUI or from tcl) 2)DMA_AXI_ADDR_WIDTH attribute is now visible in the Vivado GUI: -"Auto mode": Automatically calculated by the core tcl files based on the existing attached address segments. -"Manual mode": Specify the desired dma_width between 32-64 bits. 3)Added two new debug registers that return higher part of the current source/destination address. Signed-off-by: Filip Gherman --- library/axi_dmac/axi_dmac_hw.tcl | 7 +++++++ library/axi_dmac/axi_dmac_ip.tcl | 14 ++++++++++++- library/axi_dmac/axi_dmac_regmap.v | 10 +++++++--- library/axi_dmac/axi_dmac_regmap_request.v | 23 +++++++++++++++++----- library/axi_dmac/bd/bd.tcl | 2 +- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/library/axi_dmac/axi_dmac_hw.tcl b/library/axi_dmac/axi_dmac_hw.tcl index 40aa8be76..ec3e534e2 100644 --- a/library/axi_dmac/axi_dmac_hw.tcl +++ b/library/axi_dmac/axi_dmac_hw.tcl @@ -80,6 +80,13 @@ set_parameter_property MAX_BYTES_PER_BURST DISPLAY_NAME "Maximum bytes per burst set_parameter_property MAX_BYTES_PER_BURST HDL_PARAMETER true set_parameter_property MAX_BYTES_PER_BURST GROUP $group +add_parameter DMA_AXI_ADDR_WIDTH INTEGER 32 +set_parameter_property DMA_AXI_ADDR_WIDTH DISPLAY_NAME "DMA AXI Address Width" +set_parameter_property DMA_AXI_ADDR_WIDTH UNITS Bits +set_parameter_property DMA_AXI_ADDR_WIDTH HDL_PARAMETER true +set_parameter_property DMA_AXI_ADDR_WIDTH ALLOWED_RANGES {16:64} +set_parameter_property DMA_AXI_ADDR_WIDTH GROUP $group + foreach {suffix group} { \ "SRC" "Source" \ "DEST" "Destination" \ diff --git a/library/axi_dmac/axi_dmac_ip.tcl b/library/axi_dmac/axi_dmac_ip.tcl index be74fd949..e55550d18 100644 --- a/library/axi_dmac/axi_dmac_ip.tcl +++ b/library/axi_dmac/axi_dmac_ip.tcl @@ -228,6 +228,13 @@ set_property -dict [list \ ] \ [ipx::get_user_parameters DMA_LENGTH_WIDTH -of_objects $cc] +set_property -dict [list \ + "value_validation_type" "range_long" \ + "value_validation_range_minimum" "16" \ + "value_validation_range_maximum" "64" \ + ] \ + [ipx::get_user_parameters DMA_AXI_ADDR_WIDTH -of_objects $cc] + foreach {k v} { \ "ASYNC_CLK_REQ_SRC" "true" \ "ASYNC_CLK_SRC_DEST" "true" \ @@ -367,6 +374,12 @@ set_property -dict [list \ "display_name" "Maximum Bytes per Burst" \ ] $p +set p [ipgui::get_guiparamspec -name "DMA_AXI_ADDR_WIDTH" -component $cc] +ipgui::move_param -component $cc -order 4 $p -parent $general_group +set_property -dict [list \ + "display_name" "DMA AXI Address Width" \ +] $p + set feature_group [ipgui::add_group -name "Features" -component $cc \ -parent $page0 -display_name "Features"] @@ -418,7 +431,6 @@ set_property -dict [list \ "display_name" "Enable Diagnostics Interface" \ ] $p -ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "DMA_AXI_ADDR_WIDTH" -component $cc] ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_SRC" -component $cc] ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "AXI_ID_WIDTH_DEST" -component $cc] ipgui::remove_param -component $cc [ipgui::get_guiparamspec -name "ALLOW_ASYM_MEM" -component $cc] diff --git a/library/axi_dmac/axi_dmac_regmap.v b/library/axi_dmac/axi_dmac_regmap.v index 9b510163c..05bc46789 100644 --- a/library/axi_dmac/axi_dmac_regmap.v +++ b/library/axi_dmac/axi_dmac_regmap.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright 2014 - 2022 (c) Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -117,6 +117,8 @@ module axi_dmac_regmap #( ); localparam PCORE_VERSION = 'h00040461; + localparam HAS_ADDR_HIGH = DMA_AXI_ADDR_WIDTH > 32; + localparam ADDR_LOW_MSB = HAS_ADDR_HIGH ? 31 : DMA_AXI_ADDR_WIDTH-1; // Register interface signals reg [31:0] up_rdata = 32'h00; @@ -212,11 +214,13 @@ module axi_dmac_regmap #( 9'h021: up_rdata <= up_irq_pending; 9'h022: up_rdata <= up_irq_source; 9'h100: up_rdata <= {ctrl_pause, ctrl_enable}; - 9'h10d: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_dest_addr; - 9'h10e: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_src_addr; + 9'h10d: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_dest_addr[ADDR_LOW_MSB:0]; + 9'h10e: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_src_addr[ADDR_LOW_MSB:0]; 9'h10f: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_status; 9'h110: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids0; 9'h111: up_rdata <= DISABLE_DEBUG_REGISTERS ? 32'h00 : dbg_ids1; + 9'h126: up_rdata <= (HAS_ADDR_HIGH && !DISABLE_DEBUG_REGISTERS) ? dbg_dest_addr[DMA_AXI_ADDR_WIDTH-1:32] : 32'h00; + 9'h127: up_rdata <= (HAS_ADDR_HIGH && !DISABLE_DEBUG_REGISTERS) ? dbg_src_addr[DMA_AXI_ADDR_WIDTH-1:32] : 32'h00; default: up_rdata <= up_rdata_request; endcase end diff --git a/library/axi_dmac/axi_dmac_regmap_request.v b/library/axi_dmac/axi_dmac_regmap_request.v index 438d1e04c..63f809683 100644 --- a/library/axi_dmac/axi_dmac_regmap_request.v +++ b/library/axi_dmac/axi_dmac_regmap_request.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved. +// Copyright 2014 - 2022 (c) Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -88,6 +88,9 @@ module axi_dmac_regmap_request #( ); localparam MEASURED_LENGTH_WIDTH = (DMA_2D_TRANSFER == 1) ? 32 : DMA_LENGTH_WIDTH; + localparam HAS_ADDR_HIGH = DMA_AXI_ADDR_WIDTH > 32; + localparam ADDR_LOW_MSB = HAS_ADDR_HIGH ? 31 : DMA_AXI_ADDR_WIDTH-1; + localparam ADDR_HIGH_MSB = HAS_ADDR_HIGH ? DMA_AXI_ADDR_WIDTH-32-1 : 0; // DMA transfer signals reg up_dma_req_valid = 1'b0; @@ -150,9 +153,17 @@ module axi_dmac_regmap_request #( up_dma_last <= up_wdata[1]; up_dma_enable_tlen_reporting <= up_wdata[2]; end - 9'h104: up_dma_dest_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST]; - 9'h105: up_dma_src_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC]; + 9'h104: up_dma_dest_address[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_DEST] <= up_wdata[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_DEST]; + 9'h105: up_dma_src_address[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_SRC] <= up_wdata[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_SRC]; 9'h106: up_dma_x_length[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN] <= up_wdata[DMA_LENGTH_WIDTH-1:DMA_LENGTH_ALIGN]; + 9'h124: + if (HAS_ADDR_HIGH) begin + up_dma_dest_address[DMA_AXI_ADDR_WIDTH-1:32] <= up_wdata[ADDR_HIGH_MSB:0]; + end + 9'h125: + if (HAS_ADDR_HIGH) begin + up_dma_src_address[DMA_AXI_ADDR_WIDTH-1:32] <= up_wdata[ADDR_HIGH_MSB:0]; + end endcase end end @@ -163,8 +174,8 @@ module axi_dmac_regmap_request #( 9'h101: up_rdata <= up_transfer_id; 9'h102: up_rdata <= up_dma_req_valid; 9'h103: up_rdata <= {29'h00, up_dma_enable_tlen_reporting, up_dma_last, up_dma_cyclic}; // Flags - 9'h104: up_rdata <= HAS_DEST_ADDR ? {up_dma_dest_address,{BYTES_PER_BEAT_WIDTH_DEST{1'b0}}} : 'h00; - 9'h105: up_rdata <= HAS_SRC_ADDR ? {up_dma_src_address,{BYTES_PER_BEAT_WIDTH_SRC{1'b0}}} : 'h00; + 9'h104: up_rdata <= HAS_DEST_ADDR ? {up_dma_dest_address[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_DEST],{BYTES_PER_BEAT_WIDTH_DEST{1'b0}}} : 'h00; + 9'h105: up_rdata <= HAS_SRC_ADDR ? {up_dma_src_address[ADDR_LOW_MSB:BYTES_PER_BEAT_WIDTH_SRC],{BYTES_PER_BEAT_WIDTH_SRC{1'b0}}} : 'h00; 9'h106: up_rdata <= up_dma_x_length; 9'h107: up_rdata <= request_y_length; 9'h108: up_rdata <= request_dest_stride; @@ -175,6 +186,8 @@ module axi_dmac_regmap_request #( 9'h112: up_rdata <= up_measured_transfer_length; 9'h113: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH-1 : 0]; // Length 9'h114: up_rdata <= up_tlf_data[MEASURED_LENGTH_WIDTH+: 2]; // ID + 9'h124: up_rdata <= (HAS_ADDR_HIGH && HAS_DEST_ADDR) ? up_dma_dest_address[DMA_AXI_ADDR_WIDTH-1:32] : 32'h00; + 9'h125: up_rdata <= (HAS_ADDR_HIGH && HAS_SRC_ADDR) ? up_dma_src_address[DMA_AXI_ADDR_WIDTH-1:32] : 32'h00; default: up_rdata <= 32'h00; endcase end diff --git a/library/axi_dmac/bd/bd.tcl b/library/axi_dmac/bd/bd.tcl index 641a880c8..6e8d987f6 100644 --- a/library/axi_dmac/bd/bd.tcl +++ b/library/axi_dmac/bd/bd.tcl @@ -5,7 +5,7 @@ proc init {cellpath otherInfo} { bd::mark_propagate_override $ip \ "ASYNC_CLK_REQ_SRC ASYNC_CLK_SRC_DEST ASYNC_CLK_DEST_REQ" - bd::mark_propagate_only $ip \ + bd::mark_propagate_override $ip \ "DMA_AXI_ADDR_WIDTH" # On ZYNQ the core is most likely connected to the AXI3 HP ports so use AXI3