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.
main
Laszlo Nagy 2018-06-07 14:20:27 +01:00 committed by Laszlo Nagy
parent 1b1f83d328
commit 0d0989da39
6 changed files with 80 additions and 14 deletions

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -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]

View File

@ -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

View File

@ -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 #(