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
parent
dd47e30431
commit
e1353d5291
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue