From 4f4a4208cd3fd9c1784c609df142643efe143204 Mon Sep 17 00:00:00 2001 From: AndreiGrozav Date: Fri, 28 Aug 2020 23:51:18 +0300 Subject: [PATCH] axi_dac_interpolate: Add last sample support This feature will allow the user to hold(indefinitely) the last sample, from an ongoing DMA transfer, simple or cyclic(stooped by user or trigger). This commit also adds as functionality option: -synchronized stop between the two channels(DMAs) -stop by trigger --- .../axi_dac_interpolate/axi_dac_interpolate.v | 29 +++++++++++++++-- .../axi_dac_interpolate_filter.v | 31 ++++++++++++++++++- .../axi_dac_interpolate_reg.v | 11 ++++++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/library/axi_dac_interpolate/axi_dac_interpolate.v b/library/axi_dac_interpolate/axi_dac_interpolate.v index 766687bfc..f72226c6b 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate.v @@ -56,6 +56,9 @@ module axi_dac_interpolate #( input dac_enable_b, output [15:0] dac_int_data_a, output [15:0] dac_int_data_b, + output dac_valid_out_a, + output dac_valid_out_b, + output hold_last_sample, output underflow, input [ 1:0] trigger_i, @@ -130,6 +133,8 @@ module axi_dac_interpolate #( wire [15:0] dac_correction_coefficient_b; wire [19:0] trigger_config; + wire en_start_trigger; + wire en_stop_trigger; wire [ 1:0] en_trigger_pins; wire en_trigger_adc; wire en_trigger_la; @@ -141,11 +146,15 @@ module axi_dac_interpolate #( wire [ 1:0] fall_edge; wire trigger_active; + wire trigger; wire ext_trigger; wire underflow_a; wire underflow_b; + wire [ 1:0] lsample_hold_config; + wire sync_stop_channels; + // signal name changes assign up_clk = s_axi_aclk; @@ -159,9 +168,11 @@ module axi_dac_interpolate #( assign rise_edge = trigger_config[7:6]; assign fall_edge = trigger_config[9:8]; - assign en_trigger_pins = trigger_config[17:16]; - assign en_trigger_adc = trigger_config[18]; - assign en_trigger_la = trigger_config[19]; + assign en_start_trigger = trigger_config[14]; + assign en_stop_trigger = trigger_config[15]; + assign en_trigger_pins = trigger_config[17:16]; + assign en_trigger_adc = trigger_config[18]; + assign en_trigger_la = trigger_config[19]; assign trigger_active = |trigger_config[19:16]; assign trigger = (ext_trigger & en_trigger_pins) | @@ -195,6 +206,9 @@ module axi_dac_interpolate #( low_level_trigger <= ~trigger_i_m3 & low_level; end + assign hold_last_sample = lsample_hold_config[0]; + assign sync_stop_channels = lsample_hold_config[1]; + assign underflow = underflow_a | underflow_b; axi_dac_interpolate_filter #( @@ -205,6 +219,8 @@ module axi_dac_interpolate #( .dac_data (dac_data_a), .dac_valid (dac_valid_a), + .dac_valid_out (dac_valid_out_a), + .sync_stop_channels (sync_stop_channels), .dac_enable (dac_enable_a), .dac_int_data (dac_int_data_a), @@ -217,6 +233,8 @@ module axi_dac_interpolate #( .start_sync_channels (start_sync_channels), .trigger (trigger), .trigger_active (trigger_active), + .en_start_trigger (en_start_trigger), + .en_stop_trigger (en_stop_trigger), .dma_valid (dma_valid_a), .dma_valid_adjacent (dma_valid_b), .dac_correction_enable(dac_correction_enable_a), @@ -231,6 +249,8 @@ module axi_dac_interpolate #( .dac_data (dac_data_b), .dac_valid (dac_valid_b), + .dac_valid_out (dac_valid_out_b), + .sync_stop_channels (sync_stop_channels), .underflow (underflow_b), .dac_enable (dac_enable_b), @@ -243,6 +263,8 @@ module axi_dac_interpolate #( .start_sync_channels (start_sync_channels), .trigger (trigger), .trigger_active (trigger_active), + .en_start_trigger (en_start_trigger), + .en_stop_trigger (en_stop_trigger), .dma_valid (dma_valid_b), .dma_valid_adjacent (dma_valid_a), .dac_correction_enable(dac_correction_enable_b), @@ -265,6 +287,7 @@ module axi_dac_interpolate #( .dac_correction_coefficient_a(dac_correction_coefficient_a), .dac_correction_coefficient_b(dac_correction_coefficient_b), .trigger_config (trigger_config), + .lsample_hold_config (lsample_hold_config), .up_rstn (up_rstn), .up_clk (up_clk), diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v index f8304dec3..4a8e6ab40 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v @@ -49,6 +49,8 @@ module axi_dac_interpolate_filter #( input dac_enable, output reg [15:0] dac_int_data, output dma_ready, + output dac_valid_out, + input sync_stop_channels, output underflow, input [ 2:0] filter_mask, @@ -59,6 +61,8 @@ module axi_dac_interpolate_filter #( input start_sync_channels, input trigger, input trigger_active, + input en_start_trigger, + input en_stop_trigger, input dma_valid, input dma_valid_adjacent ); @@ -78,6 +82,8 @@ module axi_dac_interpolate_filter #( reg filter_enable = 1'b0; reg transfer = 1'b0; + reg [15:0] dma_valid_m = 16'd0; + reg stop_transfer = 1'd0; wire dac_valid_corrected; wire [15:0] dac_data_corrected; @@ -87,6 +93,9 @@ module axi_dac_interpolate_filter #( wire dac_cic_valid; wire [109:0] dac_cic_data; + wire dma_valid_ch_sync; + wire dma_valid_ch; + ad_iqcor #(.Q_OR_I_N (0), .DISABLE(CORRECTION_DISABLE), .SCALE_ONLY(1)) @@ -119,6 +128,21 @@ module axi_dac_interpolate_filter #( .filter_out (dac_cic_data), .ce_out (dac_cic_valid)); + assign dma_valid_ch_sync = sync_stop_channels ? + dma_valid & dma_valid_adjacent & !dma_transfer_suspend : + dma_valid & !dma_transfer_suspend; + + assign dma_valid_ch = dma_valid_ch_sync & !stop_transfer; + always @(posedge dac_clk) begin + if (dac_rst == 1'b1) begin + dma_valid_m <= 'd0; + end else begin + dma_valid_m <= {dma_valid_m[14:0], dma_valid_ch}; + end + end + + assign dac_valid_out = dma_valid_m[4'h5]; + always @(posedge dac_clk) begin filter_mask_d1 <= filter_mask; if (filter_mask_d1 != filter_mask) begin @@ -151,7 +175,7 @@ module axi_dac_interpolate_filter #( always @(posedge dac_clk) begin if (dma_transfer_suspend == 1'b0) begin - transfer <= trigger ? 1'b1 : transfer | !trigger_active; + transfer <= trigger ? 1'b1 : transfer | !(trigger_active & en_start_trigger); end else begin transfer <= 1'b0; end @@ -162,6 +186,11 @@ module axi_dac_interpolate_filter #( end end + always @(posedge dac_clk) begin + stop_transfer <= !en_stop_trigger | dma_transfer_suspend ? 1'b0 : + stop_transfer | (trigger_active & trigger & transfer); + end + assign dma_ready = transmit_ready ? dac_int_ready : 1'b0; assign underflow = dac_enable & dma_ready & ~dma_valid; diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v index 3e4871e22..b5a8d00ff 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v @@ -50,6 +50,7 @@ module axi_dac_interpolate_reg( output [15:0] dac_correction_coefficient_a, output [15:0] dac_correction_coefficient_b, output [19:0] trigger_config, + output [ 1:0] lsample_hold_config, // bus interface input up_rstn, @@ -77,6 +78,7 @@ module axi_dac_interpolate_reg( reg [15:0] up_correction_coefficient_a = 16'h0; reg [15:0] up_correction_coefficient_b = 16'h0; reg [19:0] up_trigger_config = 20'h0; + reg [ 1:0] up_lsample_hold_config = 2'h0; wire [ 1:0] flags; @@ -96,6 +98,7 @@ module axi_dac_interpolate_reg( up_correction_coefficient_a <= 'd0; up_correction_coefficient_b <= 'd0; up_trigger_config <= 'd0; + up_lsample_hold_config <= 'h0; end else begin up_wack <= up_wreq; if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin @@ -128,6 +131,9 @@ module axi_dac_interpolate_reg( if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h18)) begin up_trigger_config <= up_wdata[19:0]; end + if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h19)) begin + up_lsample_hold_config <= up_wdata[1:0]; + end end end @@ -152,6 +158,7 @@ module axi_dac_interpolate_reg( 5'h16: up_rdata <= {16'h0,up_correction_coefficient_a}; 5'h17: up_rdata <= {16'h0,up_correction_coefficient_b}; 5'h18: up_rdata <= {12'h0,up_trigger_config}; + 5'h19: up_rdata <= {30'h0,up_lsample_hold_config}; default: up_rdata <= 0; endcase end else begin @@ -160,7 +167,7 @@ module axi_dac_interpolate_reg( end end - up_xfer_cntrl #(.DATA_WIDTH(126)) i_xfer_cntrl ( + up_xfer_cntrl #(.DATA_WIDTH(128)) i_xfer_cntrl ( .up_rstn (up_rstn), .up_clk (up_clk), .up_data_cntrl ({ up_config[1], // 1 @@ -168,6 +175,7 @@ module axi_dac_interpolate_reg( up_correction_coefficient_b,// 16 up_correction_coefficient_a,// 16 up_trigger_config, // 20 + up_lsample_hold_config, // 2 up_flags, // 2 up_interpolation_ratio_b, // 32 up_interpolation_ratio_a, // 32 @@ -182,6 +190,7 @@ module axi_dac_interpolate_reg( dac_correction_coefficient_b, // 16 dac_correction_coefficient_a, // 16 trigger_config, // 20 + lsample_hold_config, // 2 flags, // 2 dac_interpolation_ratio_b, // 32 dac_interpolation_ratio_a, // 32