axi_dmac: preparation work for reporting length of partial transfers
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.main
parent
0203cd6981
commit
eb40b42c88
|
@ -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)(
|
||||
|
||||
|
@ -53,9 +54,14 @@ 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,
|
||||
|
@ -63,7 +69,13 @@ module dmac_2d_transfer #(
|
|||
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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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*]
|
||||
|
|
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
|
|
@ -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" \
|
||||
|
|
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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 #(
|
||||
|
|
|
@ -37,6 +37,7 @@ module axi_dmac_regmap_request #(
|
|||
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,
|
||||
|
@ -55,6 +56,7 @@ module axi_dmac_regmap_request #(
|
|||
|
||||
// Register map interface
|
||||
input up_wreq,
|
||||
input up_rreq,
|
||||
input [8:0] up_waddr,
|
||||
input [31:0] up_wdata,
|
||||
input [8:0] up_raddr,
|
||||
|
@ -76,9 +78,16 @@ module axi_dmac_regmap_request #(
|
|||
output request_last,
|
||||
|
||||
// DMA response interface
|
||||
input response_eot
|
||||
input response_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] response_measured_burst_length,
|
||||
input response_partial,
|
||||
input response_valid,
|
||||
output reg response_ready = 1'b1
|
||||
|
||||
);
|
||||
|
||||
localparam MEASURED_LENGTH_WIDTH = (DMA_2D_TRANSFER == 1) ? 32 : DMA_LENGTH_WIDTH;
|
||||
|
||||
// DMA transfer signals
|
||||
reg up_dma_req_valid = 1'b0;
|
||||
wire up_dma_req_ready;
|
||||
|
@ -92,6 +101,20 @@ reg [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] up_dma_src_address = 'h00;
|
|||
reg [DMA_LENGTH_WIDTH-1:0] up_dma_x_length = {DMA_LENGTH_ALIGN{1'b1}};
|
||||
reg up_dma_cyclic = DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||
reg up_dma_last = 1'b1;
|
||||
reg up_dma_enable_tlen_reporting = 1'b0;
|
||||
|
||||
wire up_tlf_s_ready;
|
||||
reg up_tlf_s_valid = 1'b0;
|
||||
|
||||
wire [MEASURED_LENGTH_WIDTH+2-1:0] up_tlf_data;
|
||||
wire up_tlf_valid;
|
||||
wire up_tlf_rd;
|
||||
reg up_partial_length_valid = 1'b0;
|
||||
|
||||
reg [MEASURED_LENGTH_WIDTH-1:0] up_measured_transfer_length = 'h0;
|
||||
reg up_clear_tl = 1'b0;
|
||||
reg [1:0] up_transfer_id_eot_d = 'h0;
|
||||
wire up_bl_partial;
|
||||
|
||||
assign request_dest_address = up_dma_dest_address;
|
||||
assign request_src_address = up_dma_src_address;
|
||||
|
@ -107,6 +130,7 @@ always @(posedge clk) begin
|
|||
up_dma_req_valid <= 1'b0;
|
||||
up_dma_cyclic <= DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||
up_dma_last <= 1'b1;
|
||||
up_dma_enable_tlen_reporting <= 1'b0;
|
||||
end else begin
|
||||
if (ctrl_enable == 1'b1) begin
|
||||
if (up_wreq == 1'b1 && up_waddr == 9'h102) begin
|
||||
|
@ -123,6 +147,7 @@ always @(posedge clk) begin
|
|||
9'h103: begin
|
||||
if (DMA_CYCLIC) up_dma_cyclic <= up_wdata[0];
|
||||
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];
|
||||
|
@ -136,15 +161,19 @@ always @(*) begin
|
|||
case (up_raddr)
|
||||
9'h101: up_rdata <= up_transfer_id;
|
||||
9'h102: up_rdata <= up_dma_req_valid;
|
||||
9'h103: up_rdata <= {30'h00, up_dma_last, up_dma_cyclic}; // Flags
|
||||
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'h106: up_rdata <= up_dma_x_length;
|
||||
9'h107: up_rdata <= request_y_length;
|
||||
9'h108: up_rdata <= request_dest_stride;
|
||||
9'h109: up_rdata <= request_src_stride;
|
||||
9'h10a: up_rdata <= up_transfer_done_bitmap;
|
||||
9'h10a: up_rdata <= {up_partial_length_valid,27'b0,up_transfer_done_bitmap};
|
||||
9'h10b: up_rdata <= up_transfer_id_eot;
|
||||
9'h10c: up_rdata <= 32'h0;
|
||||
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
|
||||
default: up_rdata <= 32'h00;
|
||||
endcase
|
||||
end
|
||||
|
@ -180,7 +209,7 @@ endgenerate
|
|||
|
||||
// In cyclic mode the same transfer is submitted over and over again
|
||||
assign up_sot = up_dma_cyclic ? 1'b0 : up_dma_req_valid & up_dma_req_ready;
|
||||
assign up_eot = up_dma_cyclic ? 1'b0 : response_eot;
|
||||
assign up_eot = up_dma_cyclic ? 1'b0 : response_eot & response_valid & response_ready;
|
||||
|
||||
assign request_valid = up_dma_req_valid;
|
||||
assign up_dma_req_ready = request_ready;
|
||||
|
@ -204,4 +233,74 @@ always @(posedge clk) begin
|
|||
end
|
||||
end
|
||||
|
||||
assign up_tlf_rd = up_rreq && up_raddr == 'h114;
|
||||
assign up_bl_partial = response_valid & response_ready & response_partial & up_dma_enable_tlen_reporting;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
up_partial_length_valid <= 1'b0;
|
||||
end else begin
|
||||
if (up_bl_partial == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b1;
|
||||
end else if (up_tlf_rd == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b0;
|
||||
end else if (up_tlf_valid == 1'b1) begin
|
||||
up_partial_length_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (response_valid == 1'b1 & response_ready == 1'b1) begin
|
||||
up_measured_transfer_length <= up_measured_transfer_length + response_measured_burst_length + 1'b1;
|
||||
up_transfer_id_eot_d <= up_transfer_id_eot;
|
||||
end else if (up_clear_tl == 1'b1) begin
|
||||
up_measured_transfer_length <= 'h0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (ctrl_enable == 1'b0) begin
|
||||
response_ready <= 1'b1;
|
||||
end else if (response_ready == 1'b1) begin
|
||||
response_ready <= ~response_valid;
|
||||
end else if (up_tlf_s_ready == 1'b1) begin
|
||||
response_ready <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (response_valid == 1'b1 && response_ready == 1'b1) begin
|
||||
up_tlf_s_valid <= up_bl_partial;
|
||||
up_clear_tl <= up_eot;
|
||||
end else if (up_tlf_s_ready == 1'b1) begin
|
||||
up_tlf_s_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Buffer the length and transfer ID of partial transfers
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(MEASURED_LENGTH_WIDTH + 2),
|
||||
.ADDRESS_WIDTH(2),
|
||||
.ASYNC_CLK(0)
|
||||
) i_transfer_lenghts_fifo (
|
||||
.s_axis_aclk(clk),
|
||||
.s_axis_aresetn(ctrl_enable),
|
||||
.s_axis_valid(up_tlf_s_valid),
|
||||
.s_axis_ready(up_tlf_s_ready),
|
||||
.s_axis_empty(),
|
||||
.s_axis_data({up_transfer_id_eot_d, up_measured_transfer_length}),
|
||||
.s_axis_room(),
|
||||
|
||||
.m_axis_aclk(clk),
|
||||
.m_axis_aresetn(ctrl_enable),
|
||||
.m_axis_valid(up_tlf_valid),
|
||||
.m_axis_ready(up_tlf_rd & up_tlf_valid),
|
||||
.m_axis_data(up_tlf_data),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -72,8 +72,12 @@ end else begin
|
|||
valid <= 1'b0;
|
||||
mask <= 'h1;
|
||||
end else if (src_data_valid == 1'b1) begin
|
||||
valid <= mask[RATIO-1];
|
||||
valid <= mask[RATIO-1] || src_data_last;
|
||||
if (src_data_last) begin
|
||||
mask <= 'h1;
|
||||
end else begin
|
||||
mask <= {mask[RATIO-2:0],mask[RATIO-1]};
|
||||
end
|
||||
end else begin
|
||||
valid <= 1'b0;
|
||||
end
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (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
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
module axi_dmac_response_manager #(
|
||||
parameter DMA_DATA_WIDTH_SRC = 64,
|
||||
parameter DMA_DATA_WIDTH_DEST = 64,
|
||||
parameter DMA_LENGTH_WIDTH = 24,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8),
|
||||
parameter ASYNC_CLK_DEST_REQ = 1
|
||||
)(
|
||||
// Interface to destination side
|
||||
input dest_clk,
|
||||
input dest_resetn,
|
||||
|
||||
input dest_response_valid,
|
||||
output dest_response_ready,
|
||||
input [1:0] dest_response_resp,
|
||||
input dest_response_partial,
|
||||
input dest_response_resp_eot,
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] dest_response_data_burst_length,
|
||||
|
||||
// Interface to processor
|
||||
input req_clk,
|
||||
input req_resetn,
|
||||
|
||||
output response_eot,
|
||||
output reg [BYTES_PER_BURST_WIDTH-1:0] measured_burst_length = 'h0,
|
||||
output response_partial,
|
||||
output reg response_valid = 1'b0,
|
||||
input response_ready
|
||||
|
||||
// Interface to requester side
|
||||
);
|
||||
|
||||
localparam STATE_IDLE = 2'h0;
|
||||
localparam STATE_ACC = 2'h1;
|
||||
localparam STATE_WRITE_RESPR = 2'h2;
|
||||
|
||||
reg [1:0] state = STATE_IDLE;
|
||||
reg [1:0] nx_state;
|
||||
|
||||
localparam DEST_SRC_RATIO = DMA_DATA_WIDTH_DEST/DMA_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;
|
||||
|
||||
localparam BYTES_PER_BEAT_WIDTH = DEST_SRC_RATIO_WIDTH + BYTES_PER_BEAT_WIDTH_SRC;
|
||||
localparam BURST_LEN_WIDTH = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH;
|
||||
|
||||
wire do_acc_st;
|
||||
reg req_eot = 1'b0;
|
||||
reg req_response_partial = 1'b0;
|
||||
reg [BYTES_PER_BURST_WIDTH-1:0] req_response_dest_data_burst_length = 'h0;
|
||||
|
||||
wire response_dest_valid;
|
||||
reg response_dest_ready = 1'b1;
|
||||
wire [1:0] response_dest_resp;
|
||||
wire response_dest_resp_eot;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] response_dest_data_burst_length;
|
||||
|
||||
wire [BURST_LEN_WIDTH-1:0] burst_lenght;
|
||||
reg [BURST_LEN_WIDTH-1:0] burst_pointer_end;
|
||||
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(BYTES_PER_BURST_WIDTH+1+1),
|
||||
.ADDRESS_WIDTH(0),
|
||||
.ASYNC_CLK(ASYNC_CLK_DEST_REQ)
|
||||
) i_dest_response_fifo (
|
||||
.s_axis_aclk(dest_clk),
|
||||
.s_axis_aresetn(dest_resetn),
|
||||
.s_axis_valid(dest_response_valid),
|
||||
.s_axis_ready(dest_response_ready),
|
||||
.s_axis_empty(),
|
||||
.s_axis_data({dest_response_data_burst_length,
|
||||
dest_response_partial,
|
||||
dest_response_resp_eot}),
|
||||
.s_axis_room(),
|
||||
|
||||
.m_axis_aclk(req_clk),
|
||||
.m_axis_aresetn(req_resetn),
|
||||
.m_axis_valid(response_dest_valid),
|
||||
.m_axis_ready(response_dest_ready),
|
||||
.m_axis_data({response_dest_data_burst_length,
|
||||
response_dest_partial,
|
||||
response_dest_resp_eot}),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (response_dest_valid & response_dest_ready) begin
|
||||
req_eot <= response_dest_resp_eot;
|
||||
req_response_partial <= response_dest_partial;
|
||||
req_response_dest_data_burst_length <= response_dest_data_burst_length;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
response_dest_ready <= 1'b1;
|
||||
end else begin
|
||||
response_dest_ready <= (nx_state == STATE_IDLE);
|
||||
end
|
||||
end
|
||||
|
||||
assign response_eot = (state == STATE_WRITE_RESPR) ? req_eot : 1'b1;
|
||||
assign response_partial = (state == STATE_WRITE_RESPR) ? req_response_partial : 1'b0;
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
response_valid <= 1'b0;
|
||||
end else begin
|
||||
if (nx_state == STATE_WRITE_RESPR) begin
|
||||
response_valid <= 1'b1;
|
||||
end else if (response_ready == 1'b1) begin
|
||||
response_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// transform the free running pointer from burst memory into burst length
|
||||
assign burst_lenght = req_response_dest_data_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH] -
|
||||
burst_pointer_end - 1'b1;
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
burst_pointer_end <= {BURST_LEN_WIDTH{1'b1}};
|
||||
end else if (state == STATE_ACC) begin
|
||||
burst_pointer_end <= req_response_dest_data_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (state == STATE_ZERO_COMPL) begin
|
||||
measured_burst_length <= {BYTES_PER_BURST_WIDTH{1'b1}};
|
||||
end else if (state == STATE_ACC) begin
|
||||
measured_burst_length[BYTES_PER_BURST_WIDTH-1 -: BURST_LEN_WIDTH] <= burst_lenght;
|
||||
measured_burst_length[BYTES_PER_BEAT_WIDTH-1 : 0] <=
|
||||
req_response_dest_data_burst_length[BYTES_PER_BEAT_WIDTH-1: 0];
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
nx_state = state;
|
||||
case (state)
|
||||
STATE_IDLE: begin
|
||||
if (response_dest_valid == 1'b1) begin
|
||||
nx_state = STATE_ACC;
|
||||
end
|
||||
end
|
||||
STATE_ACC: begin
|
||||
nx_state = STATE_WRITE_RESPR;
|
||||
end
|
||||
STATE_WRITE_RESPR: begin
|
||||
if (response_ready == 1'b1) begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
nx_state = STATE_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge req_clk) begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
state <= STATE_IDLE;
|
||||
end else begin
|
||||
state <= nx_state;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -49,6 +49,7 @@ module axi_dmac_transfer #(
|
|||
parameter AXI_SLICE_DEST = 0,
|
||||
parameter AXI_SLICE_SRC = 0,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter FIFO_SIZE = 8,
|
||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||
|
@ -74,6 +75,10 @@ module axi_dmac_transfer #(
|
|||
input req_last,
|
||||
|
||||
output req_eot,
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] req_measured_burst_length,
|
||||
output req_response_partial,
|
||||
output req_response_valid,
|
||||
input req_response_ready,
|
||||
|
||||
// Master AXI interface
|
||||
input m_dest_axi_aclk,
|
||||
|
@ -172,7 +177,11 @@ wire dma_req_ready;
|
|||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dma_req_dest_address;
|
||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] dma_req_src_address;
|
||||
wire [DMA_LENGTH_WIDTH-1:0] dma_req_length;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] dma_req_measured_burst_length;
|
||||
wire dma_req_eot;
|
||||
wire dma_response_valid;
|
||||
wire dma_response_ready;
|
||||
wire dma_response_partial;
|
||||
wire dma_req_sync_transfer_start;
|
||||
wire dma_req_last;
|
||||
|
||||
|
@ -196,6 +205,7 @@ wire src_enabled;
|
|||
wire req_valid_gated;
|
||||
wire req_ready_gated;
|
||||
|
||||
|
||||
axi_dmac_reset_manager #(
|
||||
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
|
||||
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
|
||||
|
@ -240,6 +250,7 @@ generate if (DMA_2D_TRANSFER == 1) begin
|
|||
dmac_2d_transfer #(
|
||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH),
|
||||
.BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH),
|
||||
.BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC)
|
||||
) i_2d_transfer (
|
||||
|
@ -247,6 +258,10 @@ dmac_2d_transfer #(
|
|||
.req_aresetn (req_resetn),
|
||||
|
||||
.req_eot (req_eot),
|
||||
.req_measured_burst_length (req_measured_burst_length),
|
||||
.req_response_partial (req_response_partial),
|
||||
.req_response_valid (req_response_valid),
|
||||
.req_response_ready (req_response_ready),
|
||||
|
||||
.req_valid (req_valid_gated),
|
||||
.req_ready (req_ready_gated),
|
||||
|
@ -266,7 +281,11 @@ dmac_2d_transfer #(
|
|||
.out_req_length (dma_req_length),
|
||||
.out_req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||
.out_req_last (dma_req_last),
|
||||
.out_eot (dma_req_eot)
|
||||
.out_eot (dma_req_eot),
|
||||
.out_measured_burst_length (dma_req_measured_burst_length),
|
||||
.out_response_partial (dma_response_partial),
|
||||
.out_response_valid (dma_response_valid),
|
||||
.out_response_ready (dma_response_ready)
|
||||
);
|
||||
|
||||
end else begin
|
||||
|
@ -283,6 +302,10 @@ assign dma_req_last = req_last;
|
|||
|
||||
/* Response */
|
||||
assign req_eot = dma_req_eot;
|
||||
assign req_measured_burst_length = dma_req_measured_burst_length;
|
||||
assign req_response_partial = dma_response_partial;
|
||||
assign req_response_valid = dma_response_valid;
|
||||
assign dma_response_ready = req_response_ready;
|
||||
|
||||
end endgenerate
|
||||
|
||||
|
@ -301,6 +324,7 @@ dmac_request_arb #(
|
|||
.AXI_SLICE_DEST (AXI_SLICE_DEST),
|
||||
.AXI_SLICE_SRC (AXI_SLICE_SRC),
|
||||
.MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST),
|
||||
.BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH),
|
||||
.FIFO_SIZE (FIFO_SIZE),
|
||||
.ID_WIDTH (ID_WIDTH),
|
||||
.AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST),
|
||||
|
@ -319,6 +343,10 @@ dmac_request_arb #(
|
|||
.req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||
|
||||
.eot (dma_req_eot),
|
||||
.measured_burst_length(dma_req_measured_burst_length),
|
||||
.response_partial (dma_response_partial),
|
||||
.response_valid (dma_response_valid),
|
||||
.response_ready (dma_response_ready),
|
||||
|
||||
.req_enable (req_enable),
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ module dmac_data_mover #(
|
|||
output m_axi_valid,
|
||||
output [DATA_WIDTH-1:0] m_axi_data,
|
||||
output m_axi_last,
|
||||
output m_axi_partial_burst,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
|
@ -140,9 +141,12 @@ generate if (ALLOW_ABORT == 1) begin
|
|||
end
|
||||
|
||||
assign transfer_abort_s = transfer_abort;
|
||||
assign m_axi_partial_burst = (transfer_abort == 1'b0) && (s_axi_last == 1'b1) &&
|
||||
!(last == 1'b1 && eot == 1'b1 && req_xlast_d == 1'b1);
|
||||
|
||||
end else begin
|
||||
assign transfer_abort_s = 1'b0;
|
||||
assign m_axi_partial_burst = 1'b0;
|
||||
end endgenerate
|
||||
|
||||
/*
|
||||
|
|
|
@ -40,6 +40,8 @@ module dmac_dest_mm_axi #(
|
|||
parameter DMA_ADDR_WIDTH = 32,
|
||||
parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8),
|
||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST),
|
||||
parameter AXI_LENGTH_WIDTH = 8)(
|
||||
|
||||
input m_axi_aclk,
|
||||
|
@ -60,6 +62,8 @@ module dmac_dest_mm_axi #(
|
|||
input response_ready,
|
||||
output [1:0] response_resp,
|
||||
output response_resp_eot,
|
||||
output response_resp_partial,
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] response_data_burst_length,
|
||||
|
||||
input [ID_WIDTH-1:0] request_id,
|
||||
output [ID_WIDTH-1:0] response_id,
|
||||
|
@ -73,6 +77,10 @@ module dmac_dest_mm_axi #(
|
|||
input [DMA_DATA_WIDTH-1:0] fifo_data,
|
||||
input fifo_last,
|
||||
|
||||
input [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length,
|
||||
input dest_burst_info_partial,
|
||||
input [ID_WIDTH-1:0] dest_burst_info_id,
|
||||
input dest_burst_info_write,
|
||||
// Write address
|
||||
input m_axi_awready,
|
||||
output m_axi_awvalid,
|
||||
|
@ -165,4 +173,17 @@ dmac_response_handler #(
|
|||
.resp_eot(response_resp_eot)
|
||||
);
|
||||
|
||||
reg [BYTES_PER_BURST_WIDTH+1-1:0] bl_mem [0:2**(ID_WIDTH)-1];
|
||||
|
||||
assign {response_resp_partial,
|
||||
response_data_burst_length} = bl_mem[response_id];
|
||||
|
||||
always @(posedge m_axi_aclk) begin
|
||||
if (dest_burst_info_write) begin
|
||||
bl_mem[dest_burst_info_id] <= {dest_burst_info_partial,
|
||||
dest_burst_info_length};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -48,6 +48,7 @@ module dmac_request_arb #(
|
|||
parameter AXI_SLICE_DEST = 0,
|
||||
parameter AXI_SLICE_SRC = 0,
|
||||
parameter MAX_BYTES_PER_BURST = 128,
|
||||
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||
parameter FIFO_SIZE = 8,
|
||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||
|
@ -65,7 +66,11 @@ module dmac_request_arb #(
|
|||
input req_xlast,
|
||||
input req_sync_transfer_start,
|
||||
|
||||
output reg eot,
|
||||
output eot,
|
||||
output [BYTES_PER_BURST_WIDTH-1:0] measured_burst_length,
|
||||
output response_partial,
|
||||
output response_valid,
|
||||
input response_ready,
|
||||
|
||||
// Master AXI interface
|
||||
input m_dest_axi_aclk,
|
||||
|
@ -181,23 +186,13 @@ localparam DMA_ADDRESS_WIDTH_SRC = DMA_AXI_ADDR_WIDTH - BYTES_PER_BEAT_WIDTH_SRC
|
|||
|
||||
// Bytes per burst is the same for both dest and src, but bytes per beat may
|
||||
// differ, so beats per burst may also differ
|
||||
localparam BYTES_PER_BURST_WIDTH =
|
||||
MAX_BYTES_PER_BURST > 2048 ? 12 :
|
||||
MAX_BYTES_PER_BURST > 1024 ? 11 :
|
||||
MAX_BYTES_PER_BURST > 512 ? 10 :
|
||||
MAX_BYTES_PER_BURST > 256 ? 9 :
|
||||
MAX_BYTES_PER_BURST > 128 ? 8 :
|
||||
MAX_BYTES_PER_BURST > 64 ? 7 :
|
||||
MAX_BYTES_PER_BURST > 32 ? 6 :
|
||||
MAX_BYTES_PER_BURST > 16 ? 5 :
|
||||
MAX_BYTES_PER_BURST > 8 ? 4 :
|
||||
MAX_BYTES_PER_BURST > 4 ? 3 :
|
||||
MAX_BYTES_PER_BURST > 2 ? 2 : 1;
|
||||
|
||||
localparam BEATS_PER_BURST_WIDTH_SRC = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_SRC;
|
||||
localparam BEATS_PER_BURST_WIDTH_DEST = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_DEST;
|
||||
|
||||
localparam BURSTS_PER_TRANSFER_WIDTH = DMA_LENGTH_WIDTH - BYTES_PER_BURST_WIDTH;
|
||||
|
||||
|
||||
reg eot_mem_src[0:2**ID_WIDTH-1];
|
||||
reg eot_mem_dest[0:2**ID_WIDTH-1];
|
||||
wire request_eot;
|
||||
|
@ -224,9 +219,10 @@ wire dest_req_xlast;
|
|||
|
||||
wire dest_response_valid;
|
||||
wire dest_response_ready;
|
||||
wire dest_response_empty;
|
||||
wire [1:0] dest_response_resp;
|
||||
wire dest_response_resp_eot;
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] dest_response_data_burst_length;
|
||||
wire dest_response_partial;
|
||||
|
||||
wire [ID_WIDTH-1:0] dest_request_id;
|
||||
wire [ID_WIDTH-1:0] dest_data_request_id;
|
||||
|
@ -265,19 +261,21 @@ wire [ID_WIDTH-1:0] src_response_id;
|
|||
wire src_valid;
|
||||
wire [DMA_DATA_WIDTH_SRC-1:0] src_data;
|
||||
wire src_last;
|
||||
wire src_partial_burst;
|
||||
wire src_fifo_valid;
|
||||
wire [DMA_DATA_WIDTH_SRC-1:0] src_fifo_data;
|
||||
wire src_fifo_last;
|
||||
|
||||
wire response_dest_valid;
|
||||
wire response_dest_ready = 1'b1;
|
||||
wire [1:0] response_dest_resp;
|
||||
wire response_dest_resp_eot;
|
||||
wire src_fifo_partial_burst;
|
||||
|
||||
wire src_bl_valid;
|
||||
wire src_bl_ready;
|
||||
wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_burst_length;
|
||||
|
||||
wire [BYTES_PER_BURST_WIDTH-1:0] dest_burst_info_length;
|
||||
wire dest_burst_info_partial;
|
||||
wire [ID_WIDTH-1:0] dest_burst_info_id;
|
||||
wire dest_burst_info_write;
|
||||
|
||||
/* Unused for now
|
||||
wire response_src_valid;
|
||||
wire response_src_ready = 1'b1;
|
||||
|
@ -299,14 +297,6 @@ begin
|
|||
eot_mem_dest[source_id] <= source_eot;
|
||||
end
|
||||
|
||||
always @(posedge req_clk)
|
||||
begin
|
||||
if (req_resetn == 1'b0) begin
|
||||
eot <= 1'b0;
|
||||
end else begin
|
||||
eot <= response_dest_valid & response_dest_ready & response_dest_resp_eot;
|
||||
end
|
||||
end
|
||||
|
||||
generate if (DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin
|
||||
|
||||
|
@ -333,6 +323,8 @@ dmac_dest_mm_axi #(
|
|||
.DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_DEST),
|
||||
.MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_DEST)
|
||||
) i_dest_dma_mm (
|
||||
.m_axi_aclk(m_dest_axi_aclk),
|
||||
|
@ -353,6 +345,8 @@ dmac_dest_mm_axi #(
|
|||
.response_ready(dest_response_ready),
|
||||
.response_resp(dest_response_resp),
|
||||
.response_resp_eot(dest_response_resp_eot),
|
||||
.response_resp_partial(dest_response_partial),
|
||||
.response_data_burst_length(dest_response_data_burst_length),
|
||||
|
||||
.request_id(dest_request_id),
|
||||
.response_id(dest_response_id),
|
||||
|
@ -367,6 +361,11 @@ dmac_dest_mm_axi #(
|
|||
.fifo_data(dest_data),
|
||||
.fifo_last(dest_last),
|
||||
|
||||
.dest_burst_info_length(dest_burst_info_length),
|
||||
.dest_burst_info_partial(dest_burst_info_partial),
|
||||
.dest_burst_info_id(dest_burst_info_id),
|
||||
.dest_burst_info_write(dest_burst_info_write),
|
||||
|
||||
.m_axi_awready(m_axi_awready),
|
||||
.m_axi_awvalid(m_axi_awvalid),
|
||||
.m_axi_awaddr(m_axi_awaddr),
|
||||
|
@ -441,6 +440,9 @@ assign m_axi_bready = 1'b0;
|
|||
|
||||
assign src_bl_ready = 1'b1;
|
||||
|
||||
assign dest_response_partial = 1'b0;
|
||||
assign dest_response_data_burst_length = 'h0;
|
||||
|
||||
end
|
||||
|
||||
if (DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin
|
||||
|
@ -458,6 +460,7 @@ assign dest_data_request_id = dest_request_id;
|
|||
assign dbg_dest_address_id = 'h00;
|
||||
assign dbg_dest_data_id = data_id;
|
||||
|
||||
|
||||
dmac_dest_axi_stream #(
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_DEST),
|
||||
|
@ -581,6 +584,8 @@ wire src_address_eot = eot_mem_src[src_address_id];
|
|||
assign dbg_src_address_id = src_address_id;
|
||||
assign dbg_src_data_id = src_data_id;
|
||||
|
||||
assign src_partial_burst = 1'b0;
|
||||
|
||||
dmac_src_mm_axi #(
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
.DMA_DATA_WIDTH(DMA_DATA_WIDTH_SRC),
|
||||
|
@ -697,6 +702,7 @@ dmac_src_axi_stream #(
|
|||
.fifo_valid(src_valid),
|
||||
.fifo_data(src_data),
|
||||
.fifo_last(src_last),
|
||||
.fifo_partial_burst(src_partial_burst),
|
||||
|
||||
.s_axis_valid(s_axis_valid),
|
||||
.s_axis_ready(s_axis_ready),
|
||||
|
@ -730,6 +736,7 @@ assign dbg_src_data_id = 'h00;
|
|||
assign src_response_valid = 1'b0;
|
||||
assign src_response_resp = 2'b0;
|
||||
*/
|
||||
assign src_partial_burst = 1'b0;
|
||||
|
||||
dmac_src_fifo_inf #(
|
||||
.ID_WIDTH(ID_WIDTH),
|
||||
|
@ -828,7 +835,7 @@ sync_bits #(
|
|||
);
|
||||
|
||||
axi_register_slice #(
|
||||
.DATA_WIDTH(DMA_DATA_WIDTH_SRC + 1),
|
||||
.DATA_WIDTH(DMA_DATA_WIDTH_SRC + 2),
|
||||
.FORWARD_REGISTERED(AXI_SLICE_SRC),
|
||||
.BACKWARD_REGISTERED(0)
|
||||
) i_src_slice (
|
||||
|
@ -836,10 +843,10 @@ axi_register_slice #(
|
|||
.resetn(src_resetn),
|
||||
.s_axi_valid(src_valid),
|
||||
.s_axi_ready(),
|
||||
.s_axi_data({src_data,src_last}),
|
||||
.s_axi_data({src_data,src_last,src_partial_burst}),
|
||||
.m_axi_valid(src_fifo_valid),
|
||||
.m_axi_ready(1'b1), /* No backpressure */
|
||||
.m_axi_data({src_fifo_data,src_fifo_last})
|
||||
.m_axi_data({src_fifo_data,src_fifo_last,src_fifo_partial_burst})
|
||||
);
|
||||
|
||||
axi_dmac_burst_memory #(
|
||||
|
@ -848,6 +855,8 @@ axi_dmac_burst_memory #(
|
|||
.ID_WIDTH(ID_WIDTH),
|
||||
.MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST),
|
||||
.ASYNC_CLK(ASYNC_CLK_SRC_DEST),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF)
|
||||
) i_store_and_forward (
|
||||
.src_clk(src_clk),
|
||||
|
@ -855,6 +864,8 @@ axi_dmac_burst_memory #(
|
|||
.src_data_valid(src_fifo_valid),
|
||||
.src_data(src_fifo_data),
|
||||
.src_data_last(src_fifo_last),
|
||||
.src_data_valid_bytes({BYTES_PER_BEAT_WIDTH_SRC{1'b1}}),
|
||||
.src_data_partial_burst(src_fifo_partial_burst),
|
||||
|
||||
.src_data_request_id(src_data_request_id),
|
||||
|
||||
|
@ -865,6 +876,11 @@ axi_dmac_burst_memory #(
|
|||
.dest_data(dest_fifo_data),
|
||||
.dest_data_last(dest_fifo_last),
|
||||
|
||||
.dest_burst_info_length(dest_burst_info_length),
|
||||
.dest_burst_info_partial(dest_burst_info_partial),
|
||||
.dest_burst_info_id(dest_burst_info_id),
|
||||
.dest_burst_info_write(dest_burst_info_write),
|
||||
|
||||
.dest_request_id(dest_request_id),
|
||||
.dest_data_request_id(dest_data_request_id),
|
||||
.dest_data_response_id(dest_data_response_id),
|
||||
|
@ -987,28 +1003,6 @@ splitter #(
|
|||
})
|
||||
);
|
||||
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(1),
|
||||
.ADDRESS_WIDTH(0),
|
||||
.ASYNC_CLK(ASYNC_CLK_DEST_REQ)
|
||||
) i_dest_response_fifo (
|
||||
.s_axis_aclk(dest_clk),
|
||||
.s_axis_aresetn(dest_resetn),
|
||||
.s_axis_valid(dest_response_valid),
|
||||
.s_axis_ready(dest_response_ready),
|
||||
.s_axis_empty(dest_response_empty),
|
||||
.s_axis_data(dest_response_resp_eot),
|
||||
.s_axis_room(),
|
||||
|
||||
.m_axis_aclk(req_clk),
|
||||
.m_axis_aresetn(req_resetn),
|
||||
.m_axis_valid(response_dest_valid),
|
||||
.m_axis_ready(response_dest_ready),
|
||||
.m_axis_data(response_dest_resp_eot),
|
||||
.m_axis_level()
|
||||
);
|
||||
|
||||
|
||||
/* Unused for now
|
||||
util_axis_fifo #(
|
||||
.DATA_WIDTH(2),
|
||||
|
@ -1050,4 +1044,31 @@ dmac_request_generator #(
|
|||
.eot(request_eot)
|
||||
);
|
||||
|
||||
axi_dmac_response_manager #(
|
||||
.DMA_DATA_WIDTH_SRC(DMA_DATA_WIDTH_SRC),
|
||||
.DMA_DATA_WIDTH_DEST(DMA_DATA_WIDTH_DEST),
|
||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||
.BYTES_PER_BURST_WIDTH(BYTES_PER_BURST_WIDTH),
|
||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
||||
.ASYNC_CLK_DEST_REQ(ASYNC_CLK_DEST_REQ)
|
||||
) i_response_manager(
|
||||
.dest_clk(dest_clk),
|
||||
.dest_resetn(dest_resetn),
|
||||
.dest_response_valid(dest_response_valid),
|
||||
.dest_response_ready(dest_response_ready),
|
||||
.dest_response_resp(dest_response_resp),
|
||||
.dest_response_partial(dest_response_partial),
|
||||
.dest_response_resp_eot(dest_response_resp_eot),
|
||||
.dest_response_data_burst_length(dest_response_data_burst_length),
|
||||
|
||||
.req_clk(req_clk),
|
||||
.req_resetn(req_resetn),
|
||||
.response_eot(eot),
|
||||
.measured_burst_length(measured_burst_length),
|
||||
.response_partial(response_partial),
|
||||
.response_valid(response_valid),
|
||||
.response_ready(response_ready)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -67,6 +67,7 @@ module dmac_src_axi_stream #(
|
|||
output fifo_valid,
|
||||
output [S_AXIS_DATA_WIDTH-1:0] fifo_data,
|
||||
output fifo_last,
|
||||
output fifo_partial_burst,
|
||||
|
||||
input req_valid,
|
||||
output req_ready,
|
||||
|
@ -113,7 +114,8 @@ dmac_data_mover # (
|
|||
|
||||
.m_axi_valid(fifo_valid),
|
||||
.m_axi_data(fifo_data),
|
||||
.m_axi_last(fifo_last)
|
||||
.m_axi_last(fifo_last),
|
||||
.m_axi_partial_burst(fifo_partial_burst)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue