diff --git a/library/axi_dmac/axi_dmac_burst_memory.v b/library/axi_dmac/axi_dmac_burst_memory.v index c05485d1f..beae1e303 100644 --- a/library/axi_dmac/axi_dmac_burst_memory.v +++ b/library/axi_dmac/axi_dmac_burst_memory.v @@ -95,15 +95,7 @@ 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; +localparam BYTES_PER_BEAT_WIDTH = BYTES_PER_BURST_WIDTH - BURST_LEN_WIDTH; /* * The burst memory is separated into 2**(ID_WIDTH-1) segments. Each segment can @@ -157,6 +149,8 @@ wire [ID_WIDTH-2:0] src_id_reduced; wire src_mem_data_valid; wire src_mem_data_last; wire [DATA_WIDTH-1:0] src_mem_data; +wire [BYTES_PER_BEAT_WIDTH-1:0] src_mem_data_valid_bytes; +wire src_mem_data_partial_burst; wire dest_beat; wire dest_last_beat; @@ -323,53 +317,13 @@ 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) + .BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC), + .DATA_WIDTH_MEM (DATA_WIDTH), + .BYTES_PER_BEAT_WIDTH_MEM (BYTES_PER_BEAT_WIDTH) ) i_resize_src ( .clk (src_clk), .reset (src_reset), @@ -377,12 +331,20 @@ axi_dmac_resize_src #( .src_data_valid (src_data_valid), .src_data (src_data), .src_data_last (src_data_last), + .src_data_valid_bytes (src_data_valid_bytes), + .src_data_partial_burst (src_data_partial_burst), .mem_data_valid (src_mem_data_valid), .mem_data (src_mem_data), - .mem_data_last (src_mem_data_last) + .mem_data_last (src_mem_data_last), + .mem_data_valid_bytes (src_mem_data_valid_bytes), + .mem_data_partial_burst (src_mem_data_partial_burst) ); +assign src_burst_len_data = {src_mem_data_partial_burst, + src_beat_counter, + src_mem_data_valid_bytes}; + ad_mem #( .DATA_WIDTH (DATA_WIDTH), .ADDRESS_WIDTH (ADDRESS_WIDTH) diff --git a/library/axi_dmac/axi_dmac_resize_src.v b/library/axi_dmac/axi_dmac_resize_src.v index 24f696f08..1a2b90537 100644 --- a/library/axi_dmac/axi_dmac_resize_src.v +++ b/library/axi_dmac/axi_dmac_resize_src.v @@ -42,7 +42,9 @@ module axi_dmac_resize_src #( parameter DATA_WIDTH_SRC = 64, - parameter DATA_WIDTH_MEM = 64 + parameter BYTES_PER_BEAT_WIDTH_SRC = 3, + parameter DATA_WIDTH_MEM = 64, + parameter BYTES_PER_BEAT_WIDTH_MEM = 3 ) ( input clk, input reset, @@ -50,24 +52,39 @@ module axi_dmac_resize_src #( 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 mem_data_valid, output [DATA_WIDTH_MEM-1:0] mem_data, - output mem_data_last + output mem_data_last, + output [BYTES_PER_BEAT_WIDTH_MEM-1:0] mem_data_valid_bytes, + output mem_data_partial_burst ); generate if (DATA_WIDTH_SRC == DATA_WIDTH_MEM) begin assign mem_data_valid = src_data_valid; assign mem_data = src_data; assign mem_data_last = src_data_last; + assign mem_data_valid_bytes = src_data_valid_bytes; + assign mem_data_partial_burst = src_data_partial_burst; end else begin localparam RATIO = DATA_WIDTH_MEM / DATA_WIDTH_SRC; + localparam RATIO_WIDTH = RATIO > 64 ? 7 : + RATIO > 32 ? 6 : + RATIO > 16 ? 5 : + RATIO > 8 ? 4 : + RATIO > 4 ? 3 : + RATIO > 2 ? 2 : 1; reg [RATIO-1:0] mask = 'h1; reg valid = 1'b0; reg last = 1'b0; reg [DATA_WIDTH_MEM-1:0] data = 'h0; + reg [BYTES_PER_BEAT_WIDTH_SRC-1:0] valid_bytes; + reg partial_burst; + reg [RATIO_WIDTH-1:0] num_beats = {RATIO_WIDTH{1'b1}}; always @(posedge clk) begin if (reset == 1'b1) begin @@ -85,6 +102,22 @@ end else begin end end + // This counter will hold the number of source beat in a destination beat + // minus one + always @(posedge clk) begin + if (reset == 1'b1) begin + num_beats <= {RATIO_WIDTH{1'b1}}; + end else if (valid == 1'b1 && last == 1'b1) begin + if (src_data_valid == 1'b1) begin + num_beats <= {RATIO_WIDTH{1'b0}}; + end else begin + num_beats <= {RATIO_WIDTH{1'b1}}; + end + end else if (src_data_valid == 1'b1) begin + num_beats <= num_beats + 1'b1; + end + end + integer i; always @(posedge clk) begin @@ -93,12 +126,20 @@ end else begin data[i*DATA_WIDTH_SRC+:DATA_WIDTH_SRC] <= src_data; end end + + // Compensate for the one clock cycle pipeline delay of the data last <= src_data_last; + if (src_data_valid == 1'b1) begin + valid_bytes <= src_data_valid_bytes; + partial_burst <= src_data_partial_burst; + end end assign mem_data_valid = valid; assign mem_data = data; assign mem_data_last = last; + assign mem_data_valid_bytes = {num_beats,valid_bytes}; + assign mem_data_partial_burst = partial_burst; end endgenerate