From faf88adf85e5ab45f028192f1b53f0f08cec4294 Mon Sep 17 00:00:00 2001 From: AndreiGrozav Date: Tue, 9 Apr 2024 19:41:13 +0300 Subject: [PATCH] axi_dac_interpolate: Fix low sampling rate issues Intermittently DAC channel data is 0 after multiple new buffers. Due to the low sampling rate and DMA flushing, it happens that the transfer SM gets stuck in flushing mode right before the transmission should start. Another frequent issue happens when a new transmission is started. A buffer must be pushed independently for each channel because of separate DMAs. After the first buffer is pushed the Linux driver deactivates the start_sync flag. Not knowing if the other channel/buffer will be active/pushed. The start_sync will be re-enabled with the second buffer. The issue was that the SM of the first buffer went one step further before the push if the second buffer,not being stopped by the start_sync. Signed-off-by: AndreiGrozav --- .../axi_dac_interpolate_filter.v | 13 +++++++------ .../axi_dac_interpolate/axi_dac_interpolate_reg.v | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v index 83b2af984..28d03cf59 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v @@ -85,12 +85,10 @@ module axi_dac_interpolate_filter #( reg cic_change_rate; reg [31:0] interpolation_counter; - reg dma_data_valid = 1'b0; - reg dma_data_valid_adjacent = 1'b0; - reg filter_enable = 1'b0; reg [15:0] dma_valid_m = 16'd0; reg stop_transfer = 1'd0; + reg clear_stop_flag = 1'd0; reg transfer = 1'd0; reg [ 1:0] transfer_sm = 2'd0; @@ -196,11 +194,12 @@ module axi_dac_interpolate_filter #( assign transfer_ready = start_sync_channels ? dma_valid & dma_valid_adjacent : dma_valid; - assign transfer_start = !(en_start_trigger ^ trigger) & transfer_ready; + assign transfer_start = !(en_start_trigger ^ trigger) & + transfer_ready & !dma_transfer_suspend; always @(posedge dac_clk) begin stop_transfer <= transfer_sm == IDLE ? 1'b0 : - stop_transfer | + (stop_transfer & !clear_stop_flag) | dma_transfer_suspend | (en_stop_trigger & trigger) | (sync_stop_channels & dma_valid & dma_valid_adjacent); @@ -211,17 +210,19 @@ module axi_dac_interpolate_filter #( case (transfer_sm) IDLE: begin transfer <= 1'b0; - if (dac_int_ready) begin + if (dac_int_ready & !dma_transfer_suspend) begin transfer_sm_next <= WAIT; end end WAIT: begin transfer <= 1'b0; if (transfer_start) begin + clear_stop_flag <= 1'b1; transfer_sm_next <= TRANSFER; end end TRANSFER: begin + clear_stop_flag <= 1'b0; transfer <= 1'b1; if (stop_transfer) begin if (flush_dma_in) begin diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v index d0468cda5..04006665e 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v @@ -72,7 +72,7 @@ module axi_dac_interpolate_reg( // internal registers reg [31:0] up_version = {16'h0002, /* MAJOR */ - 8'h03, /* MINOR */ + 8'h04, /* MINOR */ 8'h00}; /* PATCH */ reg [31:0] up_scratch = 32'h0;