Skip to content

Commit

Permalink
axi_dmac: preparation work for reporting length of partial transfers
Browse files Browse the repository at this point in the history
Length of partial transfers are stored in a queue for SW reads.
The presence of partial transfer is indicated by a status bit.

The reporting can be enabled by a control bit.

The progress of any transfer can be followed by a debug register.
  • Loading branch information
ronagyl committed Sep 7, 2018
1 parent 0203cd6 commit eb40b42
Show file tree
Hide file tree
Showing 16 changed files with 619 additions and 70 deletions.
43 changes: 40 additions & 3 deletions library/axi_dmac/2d_transfer.v
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module dmac_2d_transfer #(

parameter DMA_AXI_ADDR_WIDTH = 32,
parameter DMA_LENGTH_WIDTH = 24,
parameter BYTES_PER_BURST_WIDTH = 7,
parameter BYTES_PER_BEAT_WIDTH_SRC = 3,
parameter BYTES_PER_BEAT_WIDTH_DEST = 3)(

Expand All @@ -53,17 +54,28 @@ module dmac_2d_transfer #(
input [DMA_LENGTH_WIDTH-1:0] req_dest_stride,
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
input req_sync_transfer_start,
output reg req_eot,
input req_last,

output reg req_eot,
output reg [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length,
output reg req_response_partial,
output reg req_response_valid,
input req_response_ready,

output reg out_req_valid,
input out_req_ready,
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] out_req_dest_address,
output [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] out_req_src_address,
output [DMA_LENGTH_WIDTH-1:0] out_req_length,
output reg out_req_sync_transfer_start,
output out_req_last,
input out_eot

input out_eot,
input [BYTES_PER_BURST_WIDTH-1:0] out_measured_burst_length,
input out_response_partial,
input out_response_valid,
output reg out_response_ready = 1'b1

);

reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dest_address = 'h00;
Expand Down Expand Up @@ -96,7 +108,7 @@ always @(posedge req_aclk) begin
req_id <= req_id + 1'b1;
end

if (out_eot == 1'b1) begin
if (out_eot == 1'b1 && out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
eot_id <= eot_id + 1'b1;
req_eot <= last_req[eot_id];
end else begin
Expand All @@ -111,6 +123,31 @@ always @(posedge req_aclk) begin
end
end

always @(posedge req_aclk) begin
if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
req_measured_burst_length <= out_measured_burst_length;
req_response_partial <= out_response_partial;
end
end

always @(posedge req_aclk) begin
if (out_response_valid == 1'b1 && out_response_ready == 1'b1) begin
req_response_valid <= 1'b1;
end else if (req_response_ready == 1'b1) begin
req_response_valid <= 1'b0;
end
end

always @(posedge req_aclk) begin
if (req_aresetn == 1'b0) begin
out_response_ready <= 1'b1;
end else if (out_response_ready == 1'b1) begin
out_response_ready <= ~out_response_valid;
end else if (req_response_ready == 1'b1) begin
out_response_ready <= 1'b1;
end
end

always @(posedge req_aclk) begin
if (req_ready == 1'b1 && req_valid == 1'b1) begin
dest_address <= req_dest_address;
Expand Down
2 changes: 2 additions & 0 deletions library/axi_dmac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ GENERIC_DEPS += axi_dmac_regmap_request.v
GENERIC_DEPS += axi_dmac_reset_manager.v
GENERIC_DEPS += axi_dmac_resize_dest.v
GENERIC_DEPS += axi_dmac_resize_src.v
GENERIC_DEPS += axi_dmac_response_manager.v
GENERIC_DEPS += axi_dmac_transfer.v
GENERIC_DEPS += axi_register_slice.v
GENERIC_DEPS += data_mover.v
Expand Down Expand Up @@ -46,6 +47,7 @@ XILINX_LIB_DEPS += util_axis_fifo
XILINX_LIB_DEPS += util_cdc

ALTERA_DEPS += ../util_axis_fifo/util_axis_fifo.v
ALTERA_DEPS += ../util_axis_fifo/address_sync.v
ALTERA_DEPS += ../util_cdc/sync_bits.v
ALTERA_DEPS += axi_dmac_constr.sdc
ALTERA_DEPS += axi_dmac_hw.tcl
Expand Down
27 changes: 27 additions & 0 deletions library/axi_dmac/axi_dmac.v
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,19 @@ localparam DMA_LENGTH_ALIGN =
BYTES_PER_BEAT_WIDTH_DEST < BYTES_PER_BEAT_WIDTH_SRC ?
BYTES_PER_BEAT_WIDTH_SRC : BYTES_PER_BEAT_WIDTH_DEST;

localparam BYTES_PER_BURST_WIDTH =
REAL_MAX_BYTES_PER_BURST > 2048 ? 12 :
REAL_MAX_BYTES_PER_BURST > 1024 ? 11 :
REAL_MAX_BYTES_PER_BURST > 512 ? 10 :
REAL_MAX_BYTES_PER_BURST > 256 ? 9 :
REAL_MAX_BYTES_PER_BURST > 128 ? 8 :
REAL_MAX_BYTES_PER_BURST > 64 ? 7 :
REAL_MAX_BYTES_PER_BURST > 32 ? 6 :
REAL_MAX_BYTES_PER_BURST > 16 ? 5 :
REAL_MAX_BYTES_PER_BURST > 8 ? 4 :
REAL_MAX_BYTES_PER_BURST > 4 ? 3 :
REAL_MAX_BYTES_PER_BURST > 2 ? 2 : 1;

// ID signals from the DMAC, just for debugging
wire [ID_WIDTH-1:0] dest_request_id;
wire [ID_WIDTH-1:0] dest_data_id;
Expand Down Expand Up @@ -325,6 +338,10 @@ assign m_src_axi_arid = 'h0;
assign m_src_axi_arlock = 'h0;

wire up_req_eot;
wire [BYTES_PER_BURST_WIDTH-1:0] up_req_measured_burst_length;
wire up_response_partial;
wire up_response_valid;
wire up_response_ready;

wire ctrl_enable;
wire ctrl_pause;
Expand Down Expand Up @@ -358,6 +375,7 @@ axi_dmac_regmap #(
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
Expand Down Expand Up @@ -410,6 +428,10 @@ axi_dmac_regmap #(

// DMA response interface
.response_eot(up_req_eot),
.response_measured_burst_length(up_req_measured_burst_length),
.response_partial(up_response_partial),
.response_valid(up_response_valid),
.response_ready(up_response_ready),

// Debug interface
.dbg_dest_addr(m_dest_axi_awaddr),
Expand All @@ -425,6 +447,7 @@ axi_dmac_transfer #(
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
.DMA_TYPE_DEST(DMA_TYPE_DEST),
.DMA_TYPE_SRC(DMA_TYPE_SRC),
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
Expand Down Expand Up @@ -459,6 +482,10 @@ axi_dmac_transfer #(
.req_last(up_dma_req_last),

.req_eot(up_req_eot),
.req_measured_burst_length(up_req_measured_burst_length),
.req_response_partial(up_response_partial),
.req_response_valid(up_response_valid),
.req_response_ready(up_response_ready),

.m_dest_axi_aclk(m_dest_axi_aclk),
.m_dest_axi_aresetn(m_dest_axi_aresetn),
Expand Down
82 changes: 78 additions & 4 deletions library/axi_dmac/axi_dmac_burst_memory.v
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ module axi_dmac_burst_memory #(
parameter ID_WIDTH = 3,
parameter MAX_BYTES_PER_BURST = 128,
parameter ASYNC_CLK = 1,
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DATA_WIDTH_SRC/8),
parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST),
parameter ENABLE_DIAGNOSTICS_IF = 0
) (
input src_clk,
Expand All @@ -47,6 +49,8 @@ module axi_dmac_burst_memory #(
input src_data_valid,
input [DATA_WIDTH_SRC-1:0] src_data,
input src_data_last,
input [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes,
input src_data_partial_burst,

output [ID_WIDTH-1:0] src_data_request_id,

Expand All @@ -58,6 +62,11 @@ module axi_dmac_burst_memory #(
output [DATA_WIDTH_DEST-1:0] dest_data,
output dest_data_last,

output [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length,
output dest_burst_info_partial,
output [ID_WIDTH-1:0] dest_burst_info_id,
output reg dest_burst_info_write = 1'b0,

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,
Expand All @@ -83,6 +92,16 @@ localparam ADDRESS_WIDTH = BURST_LEN_WIDTH + ID_WIDTH - 1;

localparam AUX_FIFO_SIZE = 2**(ID_WIDTH-1);

localparam DEST_SRC_RATIO = DATA_WIDTH_DEST/DATA_WIDTH_SRC;

localparam DEST_SRC_RATIO_WIDTH = DEST_SRC_RATIO > 64 ? 7 :
DEST_SRC_RATIO > 32 ? 6 :
DEST_SRC_RATIO > 16 ? 5 :
DEST_SRC_RATIO > 8 ? 4 :
DEST_SRC_RATIO > 4 ? 3 :
DEST_SRC_RATIO > 2 ? 2 :
DEST_SRC_RATIO > 1 ? 1 : 0;

/*
* The burst memory is separated into 2**(ID_WIDTH-1) segments. Each segment can
* hold up to BURST_LEN beats. The addresses that are used to access the memory
Expand Down Expand Up @@ -117,12 +136,15 @@ reg dest_id_reduced_msb_next = 1'b0;
reg dest_id_reduced_msb = 1'b0;
reg [ID_WIDTH-1:0] dest_id = 'h0;
reg [BURST_LEN_WIDTH-1:0] dest_beat_counter = 'h00;
reg [BURST_LEN_WIDTH-1:0] dest_burst_len = 'h00;
wire [BURST_LEN_WIDTH-1:0] dest_burst_len;
reg dest_valid = 1'b0;
reg dest_mem_data_valid = 1'b0;
reg dest_mem_data_last = 1'b0;

reg [BURST_LEN_WIDTH-1:0] burst_len_mem[0:AUX_FIFO_SIZE-1];
reg [BYTES_PER_BURST_WIDTH+1-1:0] burst_len_mem[0:AUX_FIFO_SIZE-1];

wire [BYTES_PER_BURST_WIDTH+1-1:0] src_burst_len_data;
reg [BYTES_PER_BURST_WIDTH+1-1:0] dest_burst_len_data = 'h00;

wire src_beat;
wire src_last_beat;
Expand Down Expand Up @@ -193,7 +215,7 @@ end

always @(posedge src_clk) begin
if (src_last_beat == 1'b1) begin
burst_len_mem[src_id_reduced] <= src_beat_counter;
burst_len_mem[src_id_reduced] <= src_burst_len_data;
end
end

Expand Down Expand Up @@ -271,7 +293,7 @@ end

always @(posedge dest_clk) begin
if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) begin
dest_burst_len <= burst_len_mem[dest_id_reduced_next];
dest_burst_len_data <= burst_len_mem[dest_id_reduced_next];
end
end

Expand All @@ -290,6 +312,58 @@ always @(posedge dest_clk) begin
end
end

assign dest_burst_info_length = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1:0];
assign dest_burst_info_partial = dest_burst_len_data[BYTES_PER_BURST_WIDTH];
assign dest_burst_info_id = dest_id;

always @(posedge dest_clk) begin
dest_burst_info_write <= (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1);
end

// If destination is wider track the number of source beats in a destination
// beat in case the stream is not destination width aligned.
generate if (DATA_WIDTH_SRC < DATA_WIDTH_DEST) begin

reg [DEST_SRC_RATIO_WIDTH-1:0] src_num_beats = {DEST_SRC_RATIO_WIDTH{1'b1}};
reg [BYTES_PER_BEAT_WIDTH_SRC-1:0] src_data_valid_bytes_d = 'h00;
reg src_data_partial_burst_d = 'h0;

// This counter will hold the number of source beat in a destination beat
// minus one
always @(posedge src_clk) begin
if (src_mem_data_last == 1'b1 && src_mem_data_valid == 1'b1) begin
if (src_data_valid) begin
src_num_beats <= {DEST_SRC_RATIO_WIDTH{1'b0}};
end else begin
src_num_beats <= {DEST_SRC_RATIO_WIDTH{1'b1}};
end
end else if (src_data_valid) begin
src_num_beats <= src_num_beats + 1'b1;
end
end

// Compensate the delay through the resize block
always @(posedge src_clk) begin
if (src_data_valid == 1'b1) begin
src_data_valid_bytes_d <= src_data_valid_bytes;
src_data_partial_burst_d <= src_data_partial_burst;
end
end

assign src_burst_len_data = {src_data_partial_burst_d,
src_beat_counter,
src_num_beats,
src_data_valid_bytes_d};
end else begin

assign src_burst_len_data = {src_data_partial_burst,
src_beat_counter,
src_data_valid_bytes};
end
endgenerate

assign dest_burst_len = dest_burst_len_data[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH];

axi_dmac_resize_src #(
.DATA_WIDTH_SRC (DATA_WIDTH_SRC),
.DATA_WIDTH_MEM (DATA_WIDTH)
Expand Down
1 change: 1 addition & 0 deletions library/axi_dmac/axi_dmac_constr.sdc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set_false_path -to [get_registers *axi_dmac*cdc_sync_stage1*]
set_false_path -from [get_registers *axi_dmac*cdc_sync_fifo_ram*]
set_false_path -from [get_registers *axi_dmac*eot_mem*]
set_false_path -from [get_registers *axi_dmac*bl_mem*]

# Burst memory
set_false_path -from [get_registers *axi_dmac*burst_len_mem*]
Expand Down
2 changes: 2 additions & 0 deletions library/axi_dmac/axi_dmac_hw.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ad_ip_files axi_dmac [list \
$ad_hdl_dir/library/util_cdc/sync_bits.v \
$ad_hdl_dir/library/common/up_axi.v \
$ad_hdl_dir/library/util_axis_fifo/util_axis_fifo.v \
$ad_hdl_dir/library/util_axis_fifo/address_sync.v \
$ad_hdl_dir/library/common/ad_mem.v \
inc_id.vh \
resp.vh \
Expand All @@ -27,6 +28,7 @@ ad_ip_files axi_dmac [list \
axi_dmac_reset_manager.v \
axi_dmac_resize_dest.v \
axi_dmac_resize_src.v \
axi_dmac_response_manager.v \
axi_dmac_transfer.v \
address_generator.v \
data_mover.v \
Expand Down
1 change: 1 addition & 0 deletions library/axi_dmac/axi_dmac_ip.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ adi_ip_files axi_dmac [list \
"axi_dmac_reset_manager.v" \
"axi_dmac_resize_dest.v" \
"axi_dmac_resize_src.v" \
"axi_dmac_response_manager.v" \
"axi_dmac_transfer.v" \
"address_generator.v" \
"data_mover.v" \
Expand Down
15 changes: 13 additions & 2 deletions library/axi_dmac/axi_dmac_regmap.v
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module axi_dmac_regmap #(
parameter DISABLE_DEBUG_REGISTERS = 0,
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
parameter BYTES_PER_BURST_WIDTH = 7,
parameter DMA_AXI_ADDR_WIDTH = 32,
parameter DMA_LENGTH_WIDTH = 24,
parameter DMA_LENGTH_ALIGN = 3,
Expand Down Expand Up @@ -95,6 +96,10 @@ module axi_dmac_regmap #(

// DMA response interface
input response_eot,
input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length,
input response_partial,
input response_valid,
output response_ready,

// Debug interface
input [DMA_AXI_ADDR_WIDTH-1:0] dbg_src_addr,
Expand All @@ -104,7 +109,7 @@ module axi_dmac_regmap #(
input [31:0] dbg_ids1
);

localparam PCORE_VERSION = 'h00040161;
localparam PCORE_VERSION = 'h00040261;

// Register interface signals
reg [31:0] up_rdata = 32'h00;
Expand Down Expand Up @@ -209,6 +214,7 @@ axi_dmac_regmap_request #(
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
Expand All @@ -224,6 +230,7 @@ axi_dmac_regmap_request #(
.up_eot(up_eot),

.up_wreq(up_wreq),
.up_rreq(up_rreq),
.up_waddr(up_waddr),
.up_wdata(up_wdata),
.up_raddr(up_raddr),
Expand All @@ -242,7 +249,11 @@ axi_dmac_regmap_request #(
.request_sync_transfer_start(request_sync_transfer_start),
.request_last(request_last),

.response_eot(response_eot)
.response_eot(response_eot),
.response_measured_burst_length(response_measured_burst_length),
.response_partial(response_partial),
.response_valid(response_valid),
.response_ready(response_ready)
);

up_axi #(
Expand Down
Loading

0 comments on commit eb40b42

Please sign in to comment.