m2k: use DMA streaming interface

The previous mechanism was "probing" the DMAs for valid data. Better said,
each interpolation channel enabled it's DMA until a valid data was received,
then it disabled the DMA read and waited for the adjacent channel(DMA) to
receive a valid data. Only when for both channels had valid data on the
DMAs interfaces was the transmission started. This added an undesired and
redundant complexity to the interpolation channels. Furthermore, for continuous
transmission, using the above mechanism lead to a fixed phase(sample)
shift between the two channels at each start.

By using the streaming mechanism the interface is simplified and the
above problems are solved.
main
AndreiGrozav 2020-02-27 13:20:06 +02:00 committed by AndreiGrozav
parent dd47e30431
commit e1353d5291
3 changed files with 48 additions and 40 deletions

View File

@ -49,11 +49,14 @@ module axi_dac_interpolate #(
input dma_valid_a,
input dma_valid_b,
output dma_ready_a,
output dma_ready_b,
input dac_enable_a,
input dac_enable_b,
output [15:0] dac_int_data_a,
output [15:0] dac_int_data_b,
output dac_int_valid_a,
output dac_int_valid_b,
output underflow,
input [ 1:0] trigger_i,
input trigger_adc,
@ -140,6 +143,8 @@ module axi_dac_interpolate #(
wire trigger_active;
wire ext_trigger;
wire underflow_a;
wire underflow_b;
// signal name changes
@ -190,6 +195,7 @@ module axi_dac_interpolate #(
low_level_trigger <= ~trigger_i_m3 & low_level;
end
assign underflow = underflow_a | underflow_b;
axi_dac_interpolate_filter #(
.CORRECTION_DISABLE(CORRECTION_DISABLE))
@ -200,8 +206,10 @@ module axi_dac_interpolate #(
.dac_data (dac_data_a),
.dac_valid (dac_valid_a),
.dac_enable (dac_enable_a),
.dac_int_data (dac_int_data_a),
.dac_int_valid (dac_int_valid_a),
.dma_ready (dma_ready_a),
.underflow (underflow_a),
.filter_mask (filter_mask_a),
.interpolation_ratio (interpolation_ratio_a),
@ -223,9 +231,11 @@ module axi_dac_interpolate #(
.dac_data (dac_data_b),
.dac_valid (dac_valid_b),
.underflow (underflow_b),
.dac_enable (dac_enable_b),
.dac_int_data (dac_int_data_b),
.dac_int_valid (dac_int_valid_b),
.dma_ready (dma_ready_b),
.filter_mask (filter_mask_b),
.interpolation_ratio (interpolation_ratio_b),

View File

@ -46,8 +46,10 @@ module axi_dac_interpolate_filter #(
input [15:0] dac_data,
input dac_valid,
input dac_enable,
output reg [15:0] dac_int_data,
output dac_int_valid,
output dma_ready,
output underflow,
input [ 2:0] filter_mask,
input [31:0] interpolation_ratio,
@ -63,26 +65,25 @@ module axi_dac_interpolate_filter #(
// internal signals
reg dac_int_valid_d;
reg dac_int_ready;
reg dac_filt_int_valid;
reg [15:0] interp_rate_cic;
reg [ 2:0] filter_mask_d1;
reg cic_change_rate;
reg [31:0] interpolation_counter;
reg transmit_ready = 1'b1;
reg transmit_ready = 1'b0;
reg dma_data_valid = 1'b0;
reg dma_data_valid_adjacent = 1'b0;
reg filter_enable = 1'b0;
reg triggered = 1'b0;
reg transfer = 1'b0;
wire dac_valid_corrected;
wire [15:0] dac_data_corrected;
wire dac_fir_valid;
wire [35:0] dac_fir_data;
wire dac_cic_valid;
wire [109:0] dac_cic_data;
@ -127,51 +128,46 @@ module axi_dac_interpolate_filter #(
end
end
// - for start synchronized, if the channels run until the DMA has data valid
// then if the case wait for second channel DMA to have valid data
// - for start synchronized, wait until the DMA has valid data on both channels
// - for non synchronized channels the start of transmission gets the 2 data
// paths randomly ready. Only valid for the case of loading data buffers
// paths randomly ready, only when using data buffers
always @(posedge dac_clk) begin
if (interpolation_ratio == 0 || interpolation_ratio == 1) begin
dac_int_valid_d <= dac_filt_int_valid;
dac_int_ready <= dac_filt_int_valid;
end else begin
if (dac_filt_int_valid &
(!start_sync_channels | !dma_data_valid |
(dma_data_valid & dma_data_valid_adjacent))) begin
(!start_sync_channels & dma_valid |
(dma_valid & dma_valid_adjacent))) begin
if (interpolation_counter < interpolation_ratio) begin
interpolation_counter <= interpolation_counter + 1;
dac_int_valid_d <= 1'b0;
dac_int_ready <= 1'b0;
end else begin
interpolation_counter <= 0;
dac_int_valid_d <= 1'b1;
dac_int_ready <= 1'b1;
end
end else begin
dac_int_valid_d <= 1'b0;
dac_int_ready <= 1'b0;
interpolation_counter <= 0;
end
end
end
always @(posedge dac_clk) begin
if (dma_transfer_suspend) begin
dma_data_valid <= 1'b0;
dma_data_valid_adjacent <= 1'b0;
triggered <= 1'b0;
if (dma_transfer_suspend == 1'b0) begin
transfer <= trigger ? 1'b1 : transfer | !trigger_active;
end else begin
dma_data_valid <= dma_valid ? 1'b1 : dma_data_valid;
dma_data_valid_adjacent <= dma_valid_adjacent ? 1'b1 : dma_data_valid_adjacent;
triggered <= trigger ? 1'b1 : triggered | !trigger_active;
transfer <= 1'b0;
end
if (start_sync_channels == 1'b0) begin
transmit_ready <= triggered;
transmit_ready <= dma_valid & transfer;
end else begin
transmit_ready <= (dma_data_valid & dma_data_valid_adjacent) ? triggered : ~dma_data_valid;
transmit_ready <= dma_valid & dma_valid_adjacent & transfer;
end
end
assign dac_int_valid = transmit_ready ? dac_int_valid_d : 1'b0;
assign dma_ready = transmit_ready ? dac_int_ready : 1'b0;
assign underflow = dac_enable & dma_ready & ~dma_valid;
always @(posedge dac_clk) begin
case (filter_mask)

View File

@ -113,7 +113,7 @@ ad_ip_parameter ad9963_adc_dmac CONFIG.SYNC_TRANSFER_START true
ad_ip_parameter ad9963_adc_dmac CONFIG.DISABLE_DEBUG_REGISTERS $DISABLE_DMAC_DEBUG
ad_ip_instance axi_dmac ad9963_dac_dmac_a
ad_ip_parameter ad9963_dac_dmac_a CONFIG.DMA_TYPE_DEST 2
ad_ip_parameter ad9963_dac_dmac_a CONFIG.DMA_TYPE_DEST 1
ad_ip_parameter ad9963_dac_dmac_a CONFIG.DMA_TYPE_SRC 0
ad_ip_parameter ad9963_dac_dmac_a CONFIG.DMA_AXI_PROTOCOL_SRC 1
ad_ip_parameter ad9963_dac_dmac_a CONFIG.MAX_BYTES_PER_BURST 128
@ -123,7 +123,7 @@ ad_ip_parameter ad9963_dac_dmac_a CONFIG.CYCLIC {true}
ad_ip_parameter ad9963_dac_dmac_a CONFIG.DISABLE_DEBUG_REGISTERS $DISABLE_DMAC_DEBUG
ad_ip_instance axi_dmac ad9963_dac_dmac_b
ad_ip_parameter ad9963_dac_dmac_b CONFIG.DMA_TYPE_DEST 2
ad_ip_parameter ad9963_dac_dmac_b CONFIG.DMA_TYPE_DEST 1
ad_ip_parameter ad9963_dac_dmac_b CONFIG.DMA_TYPE_SRC 0
ad_ip_parameter ad9963_dac_dmac_b CONFIG.DMA_AXI_PROTOCOL_SRC 1
ad_ip_parameter ad9963_dac_dmac_b CONFIG.MAX_BYTES_PER_BURST 128
@ -245,15 +245,17 @@ ad_connect axi_dac_interpolate/dac_valid_b axi_ad9963/dac_valid_q
ad_connect axi_dac_interpolate/dac_int_data_a axi_ad9963/dac_data_i
ad_connect axi_dac_interpolate/dac_int_data_b axi_ad9963/dac_data_q
ad_connect ad9963_dac_dmac_a/fifo_rd_clk axi_ad9963/dac_clk
ad_connect ad9963_dac_dmac_b/fifo_rd_clk axi_ad9963/dac_clk
ad_connect ad9963_dac_dmac_a/m_axis_aclk axi_ad9963/dac_clk
ad_connect ad9963_dac_dmac_b/m_axis_aclk axi_ad9963/dac_clk
ad_connect axi_dac_interpolate/dac_data_a ad9963_dac_dmac_a/fifo_rd_dout
ad_connect axi_dac_interpolate/dac_int_valid_a ad9963_dac_dmac_a/fifo_rd_en
ad_connect ad9963_dac_dmac_a/fifo_rd_valid axi_dac_interpolate/dma_valid_a
ad_connect axi_dac_interpolate/dac_data_b ad9963_dac_dmac_b/fifo_rd_dout
ad_connect axi_dac_interpolate/dac_int_valid_b ad9963_dac_dmac_b/fifo_rd_en
ad_connect ad9963_dac_dmac_b/fifo_rd_valid axi_dac_interpolate/dma_valid_b
ad_connect axi_dac_interpolate/dac_data_a ad9963_dac_dmac_a/m_axis_data
ad_connect axi_dac_interpolate/dma_ready_a ad9963_dac_dmac_a/m_axis_ready
ad_connect axi_dac_interpolate/dac_enable_a axi_ad9963/dac_enable_i
ad_connect ad9963_dac_dmac_a/m_axis_valid axi_dac_interpolate/dma_valid_a
ad_connect axi_dac_interpolate/dac_data_b ad9963_dac_dmac_b/m_axis_data
ad_connect axi_dac_interpolate/dma_ready_b ad9963_dac_dmac_b/m_axis_ready
ad_connect axi_dac_interpolate/dac_enable_b axi_ad9963/dac_enable_q
ad_connect ad9963_dac_dmac_b/m_axis_valid axi_dac_interpolate/dma_valid_b
ad_connect axi_dac_interpolate/trigger_i trigger_i
ad_connect axi_dac_interpolate/trigger_adc adc_trigger/trigger_out_la
@ -278,7 +280,7 @@ ad_connect trigger_t adc_trigger/trigger_t
ad_connect axi_ad9963/dac_sync_in axi_ad9963/dac_sync_out
ad_connect axi_ad9963/adc_dovf ad9963_adc_dmac/fifo_wr_overflow
ad_connect axi_ad9963/dac_dunf ad9963_dac_dmac_a/fifo_rd_underflow
ad_connect axi_ad9963/dac_dunf axi_dac_interpolate/underflow
# interconnects