From 0d0989da39ea8a1cbf054f9584d92446679f70d8 Mon Sep 17 00:00:00 2001 From: Laszlo Nagy Date: Thu, 7 Jun 2018 14:20:27 +0100 Subject: [PATCH] axi_dmac: diagnostic interface in bursts This change adds a diagnostic interface to the DMAC core. The interface exposes internal information about the core, information which can't be exposed through AXI registers due the latency and update rate. Such information is the fullness of the internal buffer. For this is exposed in bursts and is driven from the destination clock domain, as this is reflected in its name. The signal has a fixed size and is dimensioned by taking in account the supported maximum number of bursts of 128. --- library/axi_dmac/axi_dmac.v | 15 +++++++++---- library/axi_dmac/axi_dmac_burst_memory.v | 27 ++++++++++++++++++++++-- library/axi_dmac/axi_dmac_hw.tcl | 13 ++++++++++++ library/axi_dmac/axi_dmac_ip.tcl | 9 ++++++++ library/axi_dmac/axi_dmac_transfer.v | 15 +++++++++---- library/axi_dmac/request_arb.v | 15 +++++++++---- 6 files changed, 80 insertions(+), 14 deletions(-) diff --git a/library/axi_dmac/axi_dmac.v b/library/axi_dmac/axi_dmac.v index 31866f06e..00ccf6e16 100644 --- a/library/axi_dmac/axi_dmac.v +++ b/library/axi_dmac/axi_dmac.v @@ -56,7 +56,8 @@ module axi_dmac #( parameter FIFO_SIZE = 8, // In bursts parameter AXI_ID_WIDTH_SRC = 4, parameter AXI_ID_WIDTH_DEST = 4, - parameter DISABLE_DEBUG_REGISTERS = 0)( + parameter DISABLE_DEBUG_REGISTERS = 0, + parameter ENABLE_DIAGNOSTICS_IF = 0)( // Slave AXI interface input s_axi_aclk, input s_axi_aresetn, @@ -211,7 +212,10 @@ module axi_dmac #( output fifo_rd_valid, output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout, output fifo_rd_underflow, - output fifo_rd_xfer_req + output fifo_rd_xfer_req, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts ); @@ -434,7 +438,8 @@ axi_dmac_transfer #( .FIFO_SIZE(FIFO_SIZE), .ID_WIDTH(ID_WIDTH), .AXI_LENGTH_WIDTH_SRC(8-(4*DMA_AXI_PROTOCOL_SRC)), - .AXI_LENGTH_WIDTH_DEST(8-(4*DMA_AXI_PROTOCOL_DEST)) + .AXI_LENGTH_WIDTH_DEST(8-(4*DMA_AXI_PROTOCOL_DEST)), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) ) i_transfer ( .ctrl_clk(s_axi_aclk), .ctrl_resetn(s_axi_aresetn), @@ -532,7 +537,9 @@ axi_dmac_transfer #( .dbg_src_address_id(src_address_id), .dbg_src_data_id(src_data_id), .dbg_src_response_id(src_response_id), - .dbg_status(dbg_status) + .dbg_status(dbg_status), + + .dest_diag_level_bursts(dest_diag_level_bursts) ); assign m_dest_axi_arvalid = 1'b0; diff --git a/library/axi_dmac/axi_dmac_burst_memory.v b/library/axi_dmac/axi_dmac_burst_memory.v index f18796781..5c6606000 100644 --- a/library/axi_dmac/axi_dmac_burst_memory.v +++ b/library/axi_dmac/axi_dmac_burst_memory.v @@ -38,7 +38,8 @@ module axi_dmac_burst_memory #( parameter DATA_WIDTH_DEST = 64, parameter ID_WIDTH = 3, parameter MAX_BYTES_PER_BURST = 128, - parameter ASYNC_CLK = 1 + parameter ASYNC_CLK = 1, + parameter ENABLE_DIAGNOSTICS_IF = 0 ) ( input src_clk, input src_reset, @@ -59,7 +60,10 @@ module axi_dmac_burst_memory #( output [ID_WIDTH-1:0] dest_request_id, input [ID_WIDTH-1:0] dest_data_request_id, - output [ID_WIDTH-1:0] dest_data_response_id + output [ID_WIDTH-1:0] dest_data_response_id, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts ); localparam DATA_WIDTH = DATA_WIDTH_SRC > DATA_WIDTH_DEST ? @@ -358,4 +362,23 @@ sync_bits #( assign dest_request_id = dest_src_id; assign dest_data_response_id = dest_id; +generate if (ENABLE_DIAGNOSTICS_IF == 1) begin + + reg [ID_WIDTH-1:0] _dest_diag_level_bursts = 'h0; + + // calculate buffer fullness in bursts + always @(posedge dest_clk) begin + if (dest_reset == 1'b1) begin + _dest_diag_level_bursts <= 'h0; + end else begin + _dest_diag_level_bursts <= g2b(dest_src_id) - g2b(dest_id); + end + end + assign dest_diag_level_bursts = {{{8-ID_WIDTH}{1'b0}},_dest_diag_level_bursts}; + +end else begin + assign dest_diag_level_bursts = 'h0; +end +endgenerate + endmodule diff --git a/library/axi_dmac/axi_dmac_hw.tcl b/library/axi_dmac/axi_dmac_hw.tcl index d63ec8d04..98047c9a5 100644 --- a/library/axi_dmac/axi_dmac_hw.tcl +++ b/library/axi_dmac/axi_dmac_hw.tcl @@ -468,6 +468,10 @@ proc axi_dmac_elaborate {} { set_port_property fifo_wr_sync termination_value 1 } + if {[get_parameter_value ENABLE_DIAGNOSTICS_IF] != 1} { + lappend disabled_intfs diagnostics_if + } + foreach intf $disabled_intfs { set_interface_property $intf ENABLED false } @@ -480,3 +484,12 @@ set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_NAME "Disable debug regis set_parameter_property DISABLE_DEBUG_REGISTERS DISPLAY_HINT boolean set_parameter_property DISABLE_DEBUG_REGISTERS HDL_PARAMETER false set_parameter_property DISABLE_DEBUG_REGISTERS GROUP $group + +add_parameter ENABLE_DIAGNOSTICS_IF INTEGER 0 +set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_NAME "Enable Diagnostics Interface" +set_parameter_property ENABLE_DIAGNOSTICS_IF DISPLAY_HINT boolean +set_parameter_property ENABLE_DIAGNOSTICS_IF HDL_PARAMETER true +set_parameter_property ENABLE_DIAGNOSTICS_IF GROUP $group + +add_interface diagnostics_if conduit end +add_interface_port diagnostics_if dest_diag_level_bursts dest_diag_level_bursts Output "8" diff --git a/library/axi_dmac/axi_dmac_ip.tcl b/library/axi_dmac/axi_dmac_ip.tcl index 743b9b6e5..8d360a10e 100644 --- a/library/axi_dmac/axi_dmac_ip.tcl +++ b/library/axi_dmac/axi_dmac_ip.tcl @@ -77,6 +77,8 @@ adi_set_bus_dependency "m_axis" "m_axis" \ "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 1)" adi_set_ports_dependency "fifo_rd" \ "(spirit:decode(id('MODELPARAM_VALUE.DMA_TYPE_DEST')) = 2)" +adi_set_ports_dependency "dest_diag_level_bursts" \ + "(spirit:decode(id('MODELPARAM_VALUE.ENABLE_DIAGNOSTICS_IF')) = 1)" # These are in the design to keep the Altera tools happy which can't handle # uni-directional AXI interfaces. The Xilinx tools can and do a better job when @@ -217,6 +219,7 @@ foreach {k v} { \ "AXI_SLICE_SRC" "false" \ "AXI_SLICE_DEST" "false" \ "DISABLE_DEBUG_REGISTERS" "false" \ + "ENABLE_DIAGNOSTICS_IF" "false" \ } { \ set_property -dict [list \ "value_format" "bool" \ @@ -376,6 +379,12 @@ set_property -dict [list \ "display_name" "Disable Debug Registers" \ ] $p +set p [ipgui::get_guiparamspec -name "ENABLE_DIAGNOSTICS_IF" -component $cc] +ipgui::move_param -component $cc -order 1 $p -parent $dbg_group +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] diff --git a/library/axi_dmac/axi_dmac_transfer.v b/library/axi_dmac/axi_dmac_transfer.v index 312981cd3..050cfe5c4 100644 --- a/library/axi_dmac/axi_dmac_transfer.v +++ b/library/axi_dmac/axi_dmac_transfer.v @@ -52,7 +52,8 @@ module axi_dmac_transfer #( parameter FIFO_SIZE = 8, parameter ID_WIDTH = $clog2(FIFO_SIZE*2), parameter AXI_LENGTH_WIDTH_SRC = 8, - parameter AXI_LENGTH_WIDTH_DEST = 8 + parameter AXI_LENGTH_WIDTH_DEST = 8, + parameter ENABLE_DIAGNOSTICS_IF = 0 ) ( input ctrl_clk, input ctrl_resetn, @@ -160,7 +161,10 @@ module axi_dmac_transfer #( output [ID_WIDTH-1:0] dbg_src_address_id, output [ID_WIDTH-1:0] dbg_src_data_id, output [ID_WIDTH-1:0] dbg_src_response_id, - output [11:0] dbg_status + output [11:0] dbg_status, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts ); wire dma_req_valid; @@ -299,7 +303,8 @@ dmac_request_arb #( .FIFO_SIZE (FIFO_SIZE), .ID_WIDTH (ID_WIDTH), .AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST), - .AXI_LENGTH_WIDTH_SRC (AXI_LENGTH_WIDTH_SRC) + .AXI_LENGTH_WIDTH_SRC (AXI_LENGTH_WIDTH_SRC), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) ) i_request_arb ( .req_clk (req_clk), .req_resetn (req_resetn), @@ -403,7 +408,9 @@ dmac_request_arb #( .dbg_src_request_id (dbg_src_request_id), .dbg_src_address_id (dbg_src_address_id), .dbg_src_data_id (dbg_src_data_id), - .dbg_src_response_id (dbg_src_response_id) + .dbg_src_response_id (dbg_src_response_id), + + .dest_diag_level_bursts(dest_diag_level_bursts) ); endmodule diff --git a/library/axi_dmac/request_arb.v b/library/axi_dmac/request_arb.v index 4faac6695..ef86bfa50 100644 --- a/library/axi_dmac/request_arb.v +++ b/library/axi_dmac/request_arb.v @@ -51,7 +51,8 @@ module dmac_request_arb #( parameter FIFO_SIZE = 8, parameter ID_WIDTH = $clog2(FIFO_SIZE*2), parameter AXI_LENGTH_WIDTH_SRC = 8, - parameter AXI_LENGTH_WIDTH_DEST = 8)( + parameter AXI_LENGTH_WIDTH_DEST = 8, + parameter ENABLE_DIAGNOSTICS_IF = 0)( input req_clk, input req_resetn, @@ -165,7 +166,10 @@ module dmac_request_arb #( input src_resetn, output src_ext_resetn, input src_enable, - output src_enabled + output src_enabled, + + // Diagnostics interface + output [7:0] dest_diag_level_bursts ); localparam DMA_TYPE_MM_AXI = 0; @@ -765,7 +769,8 @@ axi_dmac_burst_memory #( .DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST), .ID_WIDTH(ID_WIDTH), .MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST), - .ASYNC_CLK(ASYNC_CLK_SRC_DEST) + .ASYNC_CLK(ASYNC_CLK_SRC_DEST), + .ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF) ) i_store_and_forward ( .src_clk(src_clk), .src_reset(~src_resetn), @@ -784,7 +789,9 @@ axi_dmac_burst_memory #( .dest_request_id(dest_request_id), .dest_data_request_id(dest_data_request_id), - .dest_data_response_id(dest_data_response_id) + .dest_data_response_id(dest_data_response_id), + + .dest_diag_level_bursts(dest_diag_level_bursts) ); axi_register_slice #(