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_AXI_ADDR_WIDTH = 32,
|
||||||
parameter DMA_LENGTH_WIDTH = 24,
|
parameter DMA_LENGTH_WIDTH = 24,
|
||||||
|
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 3,
|
parameter BYTES_PER_BEAT_WIDTH_SRC = 3,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 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_dest_stride,
|
||||||
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
|
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
|
||||||
input req_sync_transfer_start,
|
input req_sync_transfer_start,
|
||||||
output reg req_eot,
|
|
||||||
input req_last,
|
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,
|
output reg out_req_valid,
|
||||||
input out_req_ready,
|
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_DEST] out_req_dest_address,
|
||||||
|
@ -63,7 +69,13 @@ module dmac_2d_transfer #(
|
||||||
output [DMA_LENGTH_WIDTH-1:0] out_req_length,
|
output [DMA_LENGTH_WIDTH-1:0] out_req_length,
|
||||||
output reg out_req_sync_transfer_start,
|
output reg out_req_sync_transfer_start,
|
||||||
output out_req_last,
|
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;
|
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;
|
req_id <= req_id + 1'b1;
|
||||||
end
|
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;
|
eot_id <= eot_id + 1'b1;
|
||||||
req_eot <= last_req[eot_id];
|
req_eot <= last_req[eot_id];
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -111,6 +123,31 @@ always @(posedge req_aclk) begin
|
||||||
end
|
end
|
||||||
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
|
always @(posedge req_aclk) begin
|
||||||
if (req_ready == 1'b1 && req_valid == 1'b1) begin
|
if (req_ready == 1'b1 && req_valid == 1'b1) begin
|
||||||
dest_address <= req_dest_address;
|
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_reset_manager.v
|
||||||
GENERIC_DEPS += axi_dmac_resize_dest.v
|
GENERIC_DEPS += axi_dmac_resize_dest.v
|
||||||
GENERIC_DEPS += axi_dmac_resize_src.v
|
GENERIC_DEPS += axi_dmac_resize_src.v
|
||||||
|
GENERIC_DEPS += axi_dmac_response_manager.v
|
||||||
GENERIC_DEPS += axi_dmac_transfer.v
|
GENERIC_DEPS += axi_dmac_transfer.v
|
||||||
GENERIC_DEPS += axi_register_slice.v
|
GENERIC_DEPS += axi_register_slice.v
|
||||||
GENERIC_DEPS += data_mover.v
|
GENERIC_DEPS += data_mover.v
|
||||||
|
@ -46,6 +47,7 @@ XILINX_LIB_DEPS += util_axis_fifo
|
||||||
XILINX_LIB_DEPS += util_cdc
|
XILINX_LIB_DEPS += util_cdc
|
||||||
|
|
||||||
ALTERA_DEPS += ../util_axis_fifo/util_axis_fifo.v
|
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 += ../util_cdc/sync_bits.v
|
||||||
ALTERA_DEPS += axi_dmac_constr.sdc
|
ALTERA_DEPS += axi_dmac_constr.sdc
|
||||||
ALTERA_DEPS += axi_dmac_hw.tcl
|
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_DEST < BYTES_PER_BEAT_WIDTH_SRC ?
|
||||||
BYTES_PER_BEAT_WIDTH_SRC : BYTES_PER_BEAT_WIDTH_DEST;
|
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
|
// ID signals from the DMAC, just for debugging
|
||||||
wire [ID_WIDTH-1:0] dest_request_id;
|
wire [ID_WIDTH-1:0] dest_request_id;
|
||||||
wire [ID_WIDTH-1:0] dest_data_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;
|
assign m_src_axi_arlock = 'h0;
|
||||||
|
|
||||||
wire up_req_eot;
|
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_enable;
|
||||||
wire ctrl_pause;
|
wire ctrl_pause;
|
||||||
|
@ -358,6 +375,7 @@ axi_dmac_regmap #(
|
||||||
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
||||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
.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_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||||
|
@ -410,6 +428,10 @@ axi_dmac_regmap #(
|
||||||
|
|
||||||
// DMA response interface
|
// DMA response interface
|
||||||
.response_eot(up_req_eot),
|
.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
|
// Debug interface
|
||||||
.dbg_dest_addr(m_dest_axi_awaddr),
|
.dbg_dest_addr(m_dest_axi_awaddr),
|
||||||
|
@ -425,6 +447,7 @@ axi_dmac_transfer #(
|
||||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
.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_DEST(DMA_TYPE_DEST),
|
||||||
.DMA_TYPE_SRC(DMA_TYPE_SRC),
|
.DMA_TYPE_SRC(DMA_TYPE_SRC),
|
||||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||||
|
@ -459,6 +482,10 @@ axi_dmac_transfer #(
|
||||||
.req_last(up_dma_req_last),
|
.req_last(up_dma_req_last),
|
||||||
|
|
||||||
.req_eot(up_req_eot),
|
.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_aclk(m_dest_axi_aclk),
|
||||||
.m_dest_axi_aresetn(m_dest_axi_aresetn),
|
.m_dest_axi_aresetn(m_dest_axi_aresetn),
|
||||||
|
|
|
@ -39,6 +39,8 @@ module axi_dmac_burst_memory #(
|
||||||
parameter ID_WIDTH = 3,
|
parameter ID_WIDTH = 3,
|
||||||
parameter MAX_BYTES_PER_BURST = 128,
|
parameter MAX_BYTES_PER_BURST = 128,
|
||||||
parameter ASYNC_CLK = 1,
|
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
|
parameter ENABLE_DIAGNOSTICS_IF = 0
|
||||||
) (
|
) (
|
||||||
input src_clk,
|
input src_clk,
|
||||||
|
@ -47,6 +49,8 @@ module axi_dmac_burst_memory #(
|
||||||
input src_data_valid,
|
input src_data_valid,
|
||||||
input [DATA_WIDTH_SRC-1:0] src_data,
|
input [DATA_WIDTH_SRC-1:0] src_data,
|
||||||
input src_data_last,
|
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,
|
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 [DATA_WIDTH_DEST-1:0] dest_data,
|
||||||
output dest_data_last,
|
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,
|
output [ID_WIDTH-1:0] dest_request_id,
|
||||||
input [ID_WIDTH-1:0] dest_data_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,
|
||||||
|
@ -83,6 +92,16 @@ localparam ADDRESS_WIDTH = BURST_LEN_WIDTH + ID_WIDTH - 1;
|
||||||
|
|
||||||
localparam AUX_FIFO_SIZE = 2**(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
|
* 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
|
* 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 dest_id_reduced_msb = 1'b0;
|
||||||
reg [ID_WIDTH-1:0] dest_id = 'h0;
|
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_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_valid = 1'b0;
|
||||||
reg dest_mem_data_valid = 1'b0;
|
reg dest_mem_data_valid = 1'b0;
|
||||||
reg dest_mem_data_last = 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_beat;
|
||||||
wire src_last_beat;
|
wire src_last_beat;
|
||||||
|
@ -193,7 +215,7 @@ end
|
||||||
|
|
||||||
always @(posedge src_clk) begin
|
always @(posedge src_clk) begin
|
||||||
if (src_last_beat == 1'b1) 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -271,7 +293,7 @@ end
|
||||||
|
|
||||||
always @(posedge dest_clk) begin
|
always @(posedge dest_clk) begin
|
||||||
if (dest_burst_valid == 1'b1 && dest_burst_ready == 1'b1) 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -290,6 +312,58 @@ always @(posedge dest_clk) begin
|
||||||
end
|
end
|
||||||
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 #(
|
axi_dmac_resize_src #(
|
||||||
.DATA_WIDTH_SRC (DATA_WIDTH_SRC),
|
.DATA_WIDTH_SRC (DATA_WIDTH_SRC),
|
||||||
.DATA_WIDTH_MEM (DATA_WIDTH)
|
.DATA_WIDTH_MEM (DATA_WIDTH)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
set_false_path -to [get_registers *axi_dmac*cdc_sync_stage1*]
|
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*cdc_sync_fifo_ram*]
|
||||||
set_false_path -from [get_registers *axi_dmac*eot_mem*]
|
set_false_path -from [get_registers *axi_dmac*eot_mem*]
|
||||||
|
set_false_path -from [get_registers *axi_dmac*bl_mem*]
|
||||||
|
|
||||||
# Burst memory
|
# Burst memory
|
||||||
set_false_path -from [get_registers *axi_dmac*burst_len_mem*]
|
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/util_cdc/sync_bits.v \
|
||||||
$ad_hdl_dir/library/common/up_axi.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/util_axis_fifo.v \
|
||||||
|
$ad_hdl_dir/library/util_axis_fifo/address_sync.v \
|
||||||
$ad_hdl_dir/library/common/ad_mem.v \
|
$ad_hdl_dir/library/common/ad_mem.v \
|
||||||
inc_id.vh \
|
inc_id.vh \
|
||||||
resp.vh \
|
resp.vh \
|
||||||
|
@ -27,6 +28,7 @@ ad_ip_files axi_dmac [list \
|
||||||
axi_dmac_reset_manager.v \
|
axi_dmac_reset_manager.v \
|
||||||
axi_dmac_resize_dest.v \
|
axi_dmac_resize_dest.v \
|
||||||
axi_dmac_resize_src.v \
|
axi_dmac_resize_src.v \
|
||||||
|
axi_dmac_response_manager.v \
|
||||||
axi_dmac_transfer.v \
|
axi_dmac_transfer.v \
|
||||||
address_generator.v \
|
address_generator.v \
|
||||||
data_mover.v \
|
data_mover.v \
|
||||||
|
|
|
@ -15,6 +15,7 @@ adi_ip_files axi_dmac [list \
|
||||||
"axi_dmac_reset_manager.v" \
|
"axi_dmac_reset_manager.v" \
|
||||||
"axi_dmac_resize_dest.v" \
|
"axi_dmac_resize_dest.v" \
|
||||||
"axi_dmac_resize_src.v" \
|
"axi_dmac_resize_src.v" \
|
||||||
|
"axi_dmac_response_manager.v" \
|
||||||
"axi_dmac_transfer.v" \
|
"axi_dmac_transfer.v" \
|
||||||
"address_generator.v" \
|
"address_generator.v" \
|
||||||
"data_mover.v" \
|
"data_mover.v" \
|
||||||
|
|
|
@ -38,6 +38,7 @@ module axi_dmac_regmap #(
|
||||||
parameter DISABLE_DEBUG_REGISTERS = 0,
|
parameter DISABLE_DEBUG_REGISTERS = 0,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
||||||
|
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||||
parameter DMA_LENGTH_WIDTH = 24,
|
parameter DMA_LENGTH_WIDTH = 24,
|
||||||
parameter DMA_LENGTH_ALIGN = 3,
|
parameter DMA_LENGTH_ALIGN = 3,
|
||||||
|
@ -95,6 +96,10 @@ module axi_dmac_regmap #(
|
||||||
|
|
||||||
// DMA response interface
|
// 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 response_ready,
|
||||||
|
|
||||||
// Debug interface
|
// Debug interface
|
||||||
input [DMA_AXI_ADDR_WIDTH-1:0] dbg_src_addr,
|
input [DMA_AXI_ADDR_WIDTH-1:0] dbg_src_addr,
|
||||||
|
@ -104,7 +109,7 @@ module axi_dmac_regmap #(
|
||||||
input [31:0] dbg_ids1
|
input [31:0] dbg_ids1
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam PCORE_VERSION = 'h00040161;
|
localparam PCORE_VERSION = 'h00040261;
|
||||||
|
|
||||||
// Register interface signals
|
// Register interface signals
|
||||||
reg [31:0] up_rdata = 32'h00;
|
reg [31:0] up_rdata = 32'h00;
|
||||||
|
@ -209,6 +214,7 @@ axi_dmac_regmap_request #(
|
||||||
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
.DISABLE_DEBUG_REGISTERS(DISABLE_DEBUG_REGISTERS),
|
||||||
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
.BYTES_PER_BEAT_WIDTH_DEST(BYTES_PER_BEAT_WIDTH_DEST),
|
||||||
.BYTES_PER_BEAT_WIDTH_SRC(BYTES_PER_BEAT_WIDTH_SRC),
|
.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_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||||
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
.DMA_LENGTH_WIDTH(DMA_LENGTH_WIDTH),
|
||||||
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
.DMA_LENGTH_ALIGN(DMA_LENGTH_ALIGN),
|
||||||
|
@ -224,6 +230,7 @@ axi_dmac_regmap_request #(
|
||||||
.up_eot(up_eot),
|
.up_eot(up_eot),
|
||||||
|
|
||||||
.up_wreq(up_wreq),
|
.up_wreq(up_wreq),
|
||||||
|
.up_rreq(up_rreq),
|
||||||
.up_waddr(up_waddr),
|
.up_waddr(up_waddr),
|
||||||
.up_wdata(up_wdata),
|
.up_wdata(up_wdata),
|
||||||
.up_raddr(up_raddr),
|
.up_raddr(up_raddr),
|
||||||
|
@ -242,7 +249,11 @@ axi_dmac_regmap_request #(
|
||||||
.request_sync_transfer_start(request_sync_transfer_start),
|
.request_sync_transfer_start(request_sync_transfer_start),
|
||||||
.request_last(request_last),
|
.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 #(
|
up_axi #(
|
||||||
|
|
|
@ -37,6 +37,7 @@ module axi_dmac_regmap_request #(
|
||||||
parameter DISABLE_DEBUG_REGISTERS = 0,
|
parameter DISABLE_DEBUG_REGISTERS = 0,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
parameter BYTES_PER_BEAT_WIDTH_DEST = 1,
|
||||||
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
parameter BYTES_PER_BEAT_WIDTH_SRC = 1,
|
||||||
|
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||||
parameter DMA_AXI_ADDR_WIDTH = 32,
|
parameter DMA_AXI_ADDR_WIDTH = 32,
|
||||||
parameter DMA_LENGTH_WIDTH = 24,
|
parameter DMA_LENGTH_WIDTH = 24,
|
||||||
parameter DMA_LENGTH_ALIGN = 3,
|
parameter DMA_LENGTH_ALIGN = 3,
|
||||||
|
@ -55,6 +56,7 @@ module axi_dmac_regmap_request #(
|
||||||
|
|
||||||
// Register map interface
|
// Register map interface
|
||||||
input up_wreq,
|
input up_wreq,
|
||||||
|
input up_rreq,
|
||||||
input [8:0] up_waddr,
|
input [8:0] up_waddr,
|
||||||
input [31:0] up_wdata,
|
input [31:0] up_wdata,
|
||||||
input [8:0] up_raddr,
|
input [8:0] up_raddr,
|
||||||
|
@ -76,9 +78,16 @@ module axi_dmac_regmap_request #(
|
||||||
output request_last,
|
output request_last,
|
||||||
|
|
||||||
// DMA response interface
|
// 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
|
// DMA transfer signals
|
||||||
reg up_dma_req_valid = 1'b0;
|
reg up_dma_req_valid = 1'b0;
|
||||||
wire up_dma_req_ready;
|
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 [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_cyclic = DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||||
reg up_dma_last = 1'b1;
|
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_dest_address = up_dma_dest_address;
|
||||||
assign request_src_address = up_dma_src_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_req_valid <= 1'b0;
|
||||||
up_dma_cyclic <= DMA_CYCLIC ? 1'b1 : 1'b0;
|
up_dma_cyclic <= DMA_CYCLIC ? 1'b1 : 1'b0;
|
||||||
up_dma_last <= 1'b1;
|
up_dma_last <= 1'b1;
|
||||||
|
up_dma_enable_tlen_reporting <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (ctrl_enable == 1'b1) begin
|
if (ctrl_enable == 1'b1) begin
|
||||||
if (up_wreq == 1'b1 && up_waddr == 9'h102) begin
|
if (up_wreq == 1'b1 && up_waddr == 9'h102) begin
|
||||||
|
@ -123,6 +147,7 @@ always @(posedge clk) begin
|
||||||
9'h103: begin
|
9'h103: begin
|
||||||
if (DMA_CYCLIC) up_dma_cyclic <= up_wdata[0];
|
if (DMA_CYCLIC) up_dma_cyclic <= up_wdata[0];
|
||||||
up_dma_last <= up_wdata[1];
|
up_dma_last <= up_wdata[1];
|
||||||
|
up_dma_enable_tlen_reporting <= up_wdata[2];
|
||||||
end
|
end
|
||||||
9'h104: up_dma_dest_address <= up_wdata[DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST];
|
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'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)
|
case (up_raddr)
|
||||||
9'h101: up_rdata <= up_transfer_id;
|
9'h101: up_rdata <= up_transfer_id;
|
||||||
9'h102: up_rdata <= up_dma_req_valid;
|
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'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'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'h106: up_rdata <= up_dma_x_length;
|
||||||
9'h107: up_rdata <= request_y_length;
|
9'h107: up_rdata <= request_y_length;
|
||||||
9'h108: up_rdata <= request_dest_stride;
|
9'h108: up_rdata <= request_dest_stride;
|
||||||
9'h109: up_rdata <= request_src_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'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;
|
default: up_rdata <= 32'h00;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -180,7 +209,7 @@ endgenerate
|
||||||
|
|
||||||
// In cyclic mode the same transfer is submitted over and over again
|
// 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_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 request_valid = up_dma_req_valid;
|
||||||
assign up_dma_req_ready = request_ready;
|
assign up_dma_req_ready = request_ready;
|
||||||
|
@ -204,4 +233,74 @@ always @(posedge clk) begin
|
||||||
end
|
end
|
||||||
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
|
endmodule
|
||||||
|
|
|
@ -72,8 +72,12 @@ end else begin
|
||||||
valid <= 1'b0;
|
valid <= 1'b0;
|
||||||
mask <= 'h1;
|
mask <= 'h1;
|
||||||
end else if (src_data_valid == 1'b1) begin
|
end else if (src_data_valid == 1'b1) begin
|
||||||
valid <= mask[RATIO-1];
|
valid <= mask[RATIO-1] || src_data_last;
|
||||||
mask <= {mask[RATIO-2:0],mask[RATIO-1]};
|
if (src_data_last) begin
|
||||||
|
mask <= 'h1;
|
||||||
|
end else begin
|
||||||
|
mask <= {mask[RATIO-2:0],mask[RATIO-1]};
|
||||||
|
end
|
||||||
end else begin
|
end else begin
|
||||||
valid <= 1'b0;
|
valid <= 1'b0;
|
||||||
end
|
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_DEST = 0,
|
||||||
parameter AXI_SLICE_SRC = 0,
|
parameter AXI_SLICE_SRC = 0,
|
||||||
parameter MAX_BYTES_PER_BURST = 128,
|
parameter MAX_BYTES_PER_BURST = 128,
|
||||||
|
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||||
parameter FIFO_SIZE = 8,
|
parameter FIFO_SIZE = 8,
|
||||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||||
|
@ -74,6 +75,10 @@ module axi_dmac_transfer #(
|
||||||
input req_last,
|
input req_last,
|
||||||
|
|
||||||
output req_eot,
|
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
|
// Master AXI interface
|
||||||
input m_dest_axi_aclk,
|
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_DEST] dma_req_dest_address;
|
||||||
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] dma_req_src_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 [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_req_eot;
|
||||||
|
wire dma_response_valid;
|
||||||
|
wire dma_response_ready;
|
||||||
|
wire dma_response_partial;
|
||||||
wire dma_req_sync_transfer_start;
|
wire dma_req_sync_transfer_start;
|
||||||
wire dma_req_last;
|
wire dma_req_last;
|
||||||
|
|
||||||
|
@ -196,6 +205,7 @@ wire src_enabled;
|
||||||
wire req_valid_gated;
|
wire req_valid_gated;
|
||||||
wire req_ready_gated;
|
wire req_ready_gated;
|
||||||
|
|
||||||
|
|
||||||
axi_dmac_reset_manager #(
|
axi_dmac_reset_manager #(
|
||||||
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
|
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
|
||||||
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
|
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
|
||||||
|
@ -240,6 +250,7 @@ generate if (DMA_2D_TRANSFER == 1) begin
|
||||||
dmac_2d_transfer #(
|
dmac_2d_transfer #(
|
||||||
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
.DMA_AXI_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||||
.DMA_LENGTH_WIDTH (DMA_LENGTH_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_DEST (BYTES_PER_BEAT_WIDTH_DEST),
|
||||||
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC)
|
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC)
|
||||||
) i_2d_transfer (
|
) i_2d_transfer (
|
||||||
|
@ -247,6 +258,10 @@ dmac_2d_transfer #(
|
||||||
.req_aresetn (req_resetn),
|
.req_aresetn (req_resetn),
|
||||||
|
|
||||||
.req_eot (req_eot),
|
.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_valid (req_valid_gated),
|
||||||
.req_ready (req_ready_gated),
|
.req_ready (req_ready_gated),
|
||||||
|
@ -266,8 +281,12 @@ dmac_2d_transfer #(
|
||||||
.out_req_length (dma_req_length),
|
.out_req_length (dma_req_length),
|
||||||
.out_req_sync_transfer_start (dma_req_sync_transfer_start),
|
.out_req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||||
.out_req_last (dma_req_last),
|
.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
|
end else begin
|
||||||
|
|
||||||
|
@ -283,6 +302,10 @@ assign dma_req_last = req_last;
|
||||||
|
|
||||||
/* Response */
|
/* Response */
|
||||||
assign req_eot = dma_req_eot;
|
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
|
end endgenerate
|
||||||
|
|
||||||
|
@ -301,6 +324,7 @@ dmac_request_arb #(
|
||||||
.AXI_SLICE_DEST (AXI_SLICE_DEST),
|
.AXI_SLICE_DEST (AXI_SLICE_DEST),
|
||||||
.AXI_SLICE_SRC (AXI_SLICE_SRC),
|
.AXI_SLICE_SRC (AXI_SLICE_SRC),
|
||||||
.MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST),
|
.MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST),
|
||||||
|
.BYTES_PER_BURST_WIDTH (BYTES_PER_BURST_WIDTH),
|
||||||
.FIFO_SIZE (FIFO_SIZE),
|
.FIFO_SIZE (FIFO_SIZE),
|
||||||
.ID_WIDTH (ID_WIDTH),
|
.ID_WIDTH (ID_WIDTH),
|
||||||
.AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST),
|
.AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST),
|
||||||
|
@ -319,6 +343,10 @@ dmac_request_arb #(
|
||||||
.req_sync_transfer_start (dma_req_sync_transfer_start),
|
.req_sync_transfer_start (dma_req_sync_transfer_start),
|
||||||
|
|
||||||
.eot (dma_req_eot),
|
.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),
|
.req_enable (req_enable),
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ module dmac_data_mover #(
|
||||||
output m_axi_valid,
|
output m_axi_valid,
|
||||||
output [DATA_WIDTH-1:0] m_axi_data,
|
output [DATA_WIDTH-1:0] m_axi_data,
|
||||||
output m_axi_last,
|
output m_axi_last,
|
||||||
|
output m_axi_partial_burst,
|
||||||
|
|
||||||
input req_valid,
|
input req_valid,
|
||||||
output req_ready,
|
output req_ready,
|
||||||
|
@ -140,9 +141,12 @@ generate if (ALLOW_ABORT == 1) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
assign transfer_abort_s = transfer_abort;
|
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
|
end else begin
|
||||||
assign transfer_abort_s = 1'b0;
|
assign transfer_abort_s = 1'b0;
|
||||||
|
assign m_axi_partial_burst = 1'b0;
|
||||||
end endgenerate
|
end endgenerate
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -40,6 +40,8 @@ module dmac_dest_mm_axi #(
|
||||||
parameter DMA_ADDR_WIDTH = 32,
|
parameter DMA_ADDR_WIDTH = 32,
|
||||||
parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8),
|
parameter BYTES_PER_BEAT_WIDTH = $clog2(DMA_DATA_WIDTH/8),
|
||||||
parameter BEATS_PER_BURST_WIDTH = 4,
|
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)(
|
parameter AXI_LENGTH_WIDTH = 8)(
|
||||||
|
|
||||||
input m_axi_aclk,
|
input m_axi_aclk,
|
||||||
|
@ -60,6 +62,8 @@ module dmac_dest_mm_axi #(
|
||||||
input response_ready,
|
input response_ready,
|
||||||
output [1:0] response_resp,
|
output [1:0] response_resp,
|
||||||
output response_resp_eot,
|
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,
|
input [ID_WIDTH-1:0] request_id,
|
||||||
output [ID_WIDTH-1:0] response_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 [DMA_DATA_WIDTH-1:0] fifo_data,
|
||||||
input fifo_last,
|
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
|
// Write address
|
||||||
input m_axi_awready,
|
input m_axi_awready,
|
||||||
output m_axi_awvalid,
|
output m_axi_awvalid,
|
||||||
|
@ -165,4 +173,17 @@ dmac_response_handler #(
|
||||||
.resp_eot(response_resp_eot)
|
.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
|
endmodule
|
||||||
|
|
|
@ -48,6 +48,7 @@ module dmac_request_arb #(
|
||||||
parameter AXI_SLICE_DEST = 0,
|
parameter AXI_SLICE_DEST = 0,
|
||||||
parameter AXI_SLICE_SRC = 0,
|
parameter AXI_SLICE_SRC = 0,
|
||||||
parameter MAX_BYTES_PER_BURST = 128,
|
parameter MAX_BYTES_PER_BURST = 128,
|
||||||
|
parameter BYTES_PER_BURST_WIDTH = 7,
|
||||||
parameter FIFO_SIZE = 8,
|
parameter FIFO_SIZE = 8,
|
||||||
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
|
||||||
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
parameter AXI_LENGTH_WIDTH_SRC = 8,
|
||||||
|
@ -65,7 +66,11 @@ module dmac_request_arb #(
|
||||||
input req_xlast,
|
input req_xlast,
|
||||||
input req_sync_transfer_start,
|
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
|
// Master AXI interface
|
||||||
input m_dest_axi_aclk,
|
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
|
// Bytes per burst is the same for both dest and src, but bytes per beat may
|
||||||
// differ, so beats per burst may also differ
|
// 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_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 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;
|
localparam BURSTS_PER_TRANSFER_WIDTH = DMA_LENGTH_WIDTH - BYTES_PER_BURST_WIDTH;
|
||||||
|
|
||||||
|
|
||||||
reg eot_mem_src[0:2**ID_WIDTH-1];
|
reg eot_mem_src[0:2**ID_WIDTH-1];
|
||||||
reg eot_mem_dest[0:2**ID_WIDTH-1];
|
reg eot_mem_dest[0:2**ID_WIDTH-1];
|
||||||
wire request_eot;
|
wire request_eot;
|
||||||
|
@ -224,9 +219,10 @@ wire dest_req_xlast;
|
||||||
|
|
||||||
wire dest_response_valid;
|
wire dest_response_valid;
|
||||||
wire dest_response_ready;
|
wire dest_response_ready;
|
||||||
wire dest_response_empty;
|
|
||||||
wire [1:0] dest_response_resp;
|
wire [1:0] dest_response_resp;
|
||||||
wire dest_response_resp_eot;
|
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_request_id;
|
||||||
wire [ID_WIDTH-1:0] dest_data_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 src_valid;
|
||||||
wire [DMA_DATA_WIDTH_SRC-1:0] src_data;
|
wire [DMA_DATA_WIDTH_SRC-1:0] src_data;
|
||||||
wire src_last;
|
wire src_last;
|
||||||
|
wire src_partial_burst;
|
||||||
wire src_fifo_valid;
|
wire src_fifo_valid;
|
||||||
wire [DMA_DATA_WIDTH_SRC-1:0] src_fifo_data;
|
wire [DMA_DATA_WIDTH_SRC-1:0] src_fifo_data;
|
||||||
wire src_fifo_last;
|
wire src_fifo_last;
|
||||||
|
wire src_fifo_partial_burst;
|
||||||
wire response_dest_valid;
|
|
||||||
wire response_dest_ready = 1'b1;
|
|
||||||
wire [1:0] response_dest_resp;
|
|
||||||
wire response_dest_resp_eot;
|
|
||||||
|
|
||||||
wire src_bl_valid;
|
wire src_bl_valid;
|
||||||
wire src_bl_ready;
|
wire src_bl_ready;
|
||||||
wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_burst_length;
|
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
|
/* Unused for now
|
||||||
wire response_src_valid;
|
wire response_src_valid;
|
||||||
wire response_src_ready = 1'b1;
|
wire response_src_ready = 1'b1;
|
||||||
|
@ -299,14 +297,6 @@ begin
|
||||||
eot_mem_dest[source_id] <= source_eot;
|
eot_mem_dest[source_id] <= source_eot;
|
||||||
end
|
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
|
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),
|
.DMA_ADDR_WIDTH(DMA_AXI_ADDR_WIDTH),
|
||||||
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST),
|
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST),
|
||||||
.BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_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)
|
.AXI_LENGTH_WIDTH(AXI_LENGTH_WIDTH_DEST)
|
||||||
) i_dest_dma_mm (
|
) i_dest_dma_mm (
|
||||||
.m_axi_aclk(m_dest_axi_aclk),
|
.m_axi_aclk(m_dest_axi_aclk),
|
||||||
|
@ -353,6 +345,8 @@ dmac_dest_mm_axi #(
|
||||||
.response_ready(dest_response_ready),
|
.response_ready(dest_response_ready),
|
||||||
.response_resp(dest_response_resp),
|
.response_resp(dest_response_resp),
|
||||||
.response_resp_eot(dest_response_resp_eot),
|
.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),
|
.request_id(dest_request_id),
|
||||||
.response_id(dest_response_id),
|
.response_id(dest_response_id),
|
||||||
|
@ -367,6 +361,11 @@ dmac_dest_mm_axi #(
|
||||||
.fifo_data(dest_data),
|
.fifo_data(dest_data),
|
||||||
.fifo_last(dest_last),
|
.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_awready(m_axi_awready),
|
||||||
.m_axi_awvalid(m_axi_awvalid),
|
.m_axi_awvalid(m_axi_awvalid),
|
||||||
.m_axi_awaddr(m_axi_awaddr),
|
.m_axi_awaddr(m_axi_awaddr),
|
||||||
|
@ -441,6 +440,9 @@ assign m_axi_bready = 1'b0;
|
||||||
|
|
||||||
assign src_bl_ready = 1'b1;
|
assign src_bl_ready = 1'b1;
|
||||||
|
|
||||||
|
assign dest_response_partial = 1'b0;
|
||||||
|
assign dest_response_data_burst_length = 'h0;
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin
|
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_address_id = 'h00;
|
||||||
assign dbg_dest_data_id = data_id;
|
assign dbg_dest_data_id = data_id;
|
||||||
|
|
||||||
|
|
||||||
dmac_dest_axi_stream #(
|
dmac_dest_axi_stream #(
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(ID_WIDTH),
|
||||||
.S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_DEST),
|
.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_address_id = src_address_id;
|
||||||
assign dbg_src_data_id = src_data_id;
|
assign dbg_src_data_id = src_data_id;
|
||||||
|
|
||||||
|
assign src_partial_burst = 1'b0;
|
||||||
|
|
||||||
dmac_src_mm_axi #(
|
dmac_src_mm_axi #(
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(ID_WIDTH),
|
||||||
.DMA_DATA_WIDTH(DMA_DATA_WIDTH_SRC),
|
.DMA_DATA_WIDTH(DMA_DATA_WIDTH_SRC),
|
||||||
|
@ -697,6 +702,7 @@ dmac_src_axi_stream #(
|
||||||
.fifo_valid(src_valid),
|
.fifo_valid(src_valid),
|
||||||
.fifo_data(src_data),
|
.fifo_data(src_data),
|
||||||
.fifo_last(src_last),
|
.fifo_last(src_last),
|
||||||
|
.fifo_partial_burst(src_partial_burst),
|
||||||
|
|
||||||
.s_axis_valid(s_axis_valid),
|
.s_axis_valid(s_axis_valid),
|
||||||
.s_axis_ready(s_axis_ready),
|
.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_valid = 1'b0;
|
||||||
assign src_response_resp = 2'b0;
|
assign src_response_resp = 2'b0;
|
||||||
*/
|
*/
|
||||||
|
assign src_partial_burst = 1'b0;
|
||||||
|
|
||||||
dmac_src_fifo_inf #(
|
dmac_src_fifo_inf #(
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(ID_WIDTH),
|
||||||
|
@ -828,7 +835,7 @@ sync_bits #(
|
||||||
);
|
);
|
||||||
|
|
||||||
axi_register_slice #(
|
axi_register_slice #(
|
||||||
.DATA_WIDTH(DMA_DATA_WIDTH_SRC + 1),
|
.DATA_WIDTH(DMA_DATA_WIDTH_SRC + 2),
|
||||||
.FORWARD_REGISTERED(AXI_SLICE_SRC),
|
.FORWARD_REGISTERED(AXI_SLICE_SRC),
|
||||||
.BACKWARD_REGISTERED(0)
|
.BACKWARD_REGISTERED(0)
|
||||||
) i_src_slice (
|
) i_src_slice (
|
||||||
|
@ -836,10 +843,10 @@ axi_register_slice #(
|
||||||
.resetn(src_resetn),
|
.resetn(src_resetn),
|
||||||
.s_axi_valid(src_valid),
|
.s_axi_valid(src_valid),
|
||||||
.s_axi_ready(),
|
.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_valid(src_fifo_valid),
|
||||||
.m_axi_ready(1'b1), /* No backpressure */
|
.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 #(
|
axi_dmac_burst_memory #(
|
||||||
|
@ -848,6 +855,8 @@ axi_dmac_burst_memory #(
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(ID_WIDTH),
|
||||||
.MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST),
|
.MAX_BYTES_PER_BURST(MAX_BYTES_PER_BURST),
|
||||||
.ASYNC_CLK(ASYNC_CLK_SRC_DEST),
|
.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)
|
.ENABLE_DIAGNOSTICS_IF(ENABLE_DIAGNOSTICS_IF)
|
||||||
) i_store_and_forward (
|
) i_store_and_forward (
|
||||||
.src_clk(src_clk),
|
.src_clk(src_clk),
|
||||||
|
@ -855,6 +864,8 @@ axi_dmac_burst_memory #(
|
||||||
.src_data_valid(src_fifo_valid),
|
.src_data_valid(src_fifo_valid),
|
||||||
.src_data(src_fifo_data),
|
.src_data(src_fifo_data),
|
||||||
.src_data_last(src_fifo_last),
|
.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),
|
.src_data_request_id(src_data_request_id),
|
||||||
|
|
||||||
|
@ -865,6 +876,11 @@ axi_dmac_burst_memory #(
|
||||||
.dest_data(dest_fifo_data),
|
.dest_data(dest_fifo_data),
|
||||||
.dest_data_last(dest_fifo_last),
|
.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_request_id(dest_request_id),
|
||||||
.dest_data_request_id(dest_data_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),
|
||||||
|
@ -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
|
/* Unused for now
|
||||||
util_axis_fifo #(
|
util_axis_fifo #(
|
||||||
.DATA_WIDTH(2),
|
.DATA_WIDTH(2),
|
||||||
|
@ -1050,4 +1044,31 @@ dmac_request_generator #(
|
||||||
.eot(request_eot)
|
.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
|
endmodule
|
||||||
|
|
|
@ -67,6 +67,7 @@ module dmac_src_axi_stream #(
|
||||||
output fifo_valid,
|
output fifo_valid,
|
||||||
output [S_AXIS_DATA_WIDTH-1:0] fifo_data,
|
output [S_AXIS_DATA_WIDTH-1:0] fifo_data,
|
||||||
output fifo_last,
|
output fifo_last,
|
||||||
|
output fifo_partial_burst,
|
||||||
|
|
||||||
input req_valid,
|
input req_valid,
|
||||||
output req_ready,
|
output req_ready,
|
||||||
|
@ -113,7 +114,8 @@ dmac_data_mover # (
|
||||||
|
|
||||||
.m_axi_valid(fifo_valid),
|
.m_axi_valid(fifo_valid),
|
||||||
.m_axi_data(fifo_data),
|
.m_axi_data(fifo_data),
|
||||||
.m_axi_last(fifo_last)
|
.m_axi_last(fifo_last),
|
||||||
|
.m_axi_partial_burst(fifo_partial_burst)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue