From 0ddb08070a9a0c75884472e1bfa92d35e4784c23 Mon Sep 17 00:00:00 2001 From: AndreiGrozav Date: Fri, 28 Aug 2020 23:30:08 +0300 Subject: [PATCH] axi_ad9963: Add last sample hold support The mechanism is controlled by axi_dac_interpolate. --- library/axi_ad9963/axi_ad9963.v | 16 +++++++++++--- library/axi_ad9963/axi_ad9963_if.v | 25 ++++++++++++++++++---- library/axi_ad9963/axi_ad9963_tx.v | 19 ++++++++++------ library/axi_ad9963/axi_ad9963_tx_channel.v | 14 +++++++++--- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/library/axi_ad9963/axi_ad9963.v b/library/axi_ad9963/axi_ad9963.v index bd54ffd01..6389d1b5c 100644 --- a/library/axi_ad9963/axi_ad9963.v +++ b/library/axi_ad9963/axi_ad9963.v @@ -99,11 +99,15 @@ module axi_ad9963 #( output dac_enable_i, output dac_valid_i, input [15:0] dac_data_i, + input dma_valid_i, output dac_enable_q, output dac_valid_q, input [15:0] dac_data_q, + input dma_valid_q, input dac_dunf, + input hold_last_sample, + // axi interface input s_axi_aclk, @@ -145,7 +149,6 @@ module axi_ad9963 #( wire adc_valid_s; wire [23:0] adc_data_s; wire adc_status_s; - wire dac_valid_s; wire [23:0] dac_data_s; wire [12:0] up_adc_dld_s; wire [64:0] up_adc_dwdata_s; @@ -164,6 +167,8 @@ module axi_ad9963 #( wire up_rack_tx_s; wire up_adc_ce; wire up_dac_ce; + wire valid_out_q_s; + wire valid_out_i_s; // signal name changes @@ -200,9 +205,11 @@ module axi_ad9963 #( .adc_data (adc_data_s), .adc_status (adc_status_s), .up_adc_ce(up_adc_ce), - .dac_valid (dac_valid_s), .dac_data (dac_data_s), + .out_valid_q (valid_out_q_s), + .out_valid_i (valid_out_i_s), .up_dac_ce(up_dac_ce), + .tx_sample_hold (hold_last_sample), .up_clk (up_clk), .up_adc_dld (up_adc_dld_s), .up_adc_dwdata (up_adc_dwdata_s), @@ -271,7 +278,6 @@ module axi_ad9963 #( i_tx ( .dac_clk (dac_clk), .dac_rst (dac_rst), - .dac_valid (dac_valid_s), .dac_data (dac_data_s), .adc_data (adc_data_s), .dac_sync_in (dac_sync_in), @@ -279,9 +285,13 @@ module axi_ad9963 #( .dac_enable_i (dac_enable_i), .dac_valid_i (dac_valid_i), .dac_data_i (dac_data_i), + .dma_valid_i (dma_valid_i), + .out_valid_i (valid_out_i_s), .dac_enable_q (dac_enable_q), .dac_valid_q (dac_valid_q), .dac_data_q (dac_data_q), + .dma_valid_q (dma_valid_q), + .out_valid_q (valid_out_q_s), .dac_dunf(dac_dunf), .up_dac_ce(up_dac_ce), .up_rstn (up_rstn), diff --git a/library/axi_ad9963/axi_ad9963_if.v b/library/axi_ad9963/axi_ad9963_if.v index 259a65ea5..df1599893 100644 --- a/library/axi_ad9963/axi_ad9963_if.v +++ b/library/axi_ad9963/axi_ad9963_if.v @@ -72,9 +72,11 @@ module axi_ad9963_if #( // transmit data path interface - input dac_valid, + input out_valid_q, + input out_valid_i, input [23:0] dac_data, input up_dac_ce, + input tx_sample_hold, // delay interface @@ -91,6 +93,7 @@ module axi_ad9963_if #( reg [11:0] rx_data_p = 0; reg [11:0] tx_data_p = 'd0; reg [11:0] tx_data_n = 'd0; + reg [23:0] constant_sample = 'd0; // internal signals @@ -115,9 +118,23 @@ module axi_ad9963_if #( end always @(posedge dac_clk) begin - if(dac_valid == 1'b1) begin - tx_data_p <= dac_data[11:0] ; - tx_data_n <= dac_data[23:12]; + if (dac_rst == 1'b1) begin + tx_data_p <= 24'd0; + tx_data_n <= 24'd0; + constant_sample <= 24'd0; + end else begin + if(out_valid_i == 1'b1) begin + tx_data_p <= dac_data[11: 0]; + constant_sample[11: 0] <= tx_sample_hold ? dac_data[11: 0] : 12'd0; + end else begin + tx_data_p <= constant_sample[11:0] ; + end + if(out_valid_q == 1'b1) begin + tx_data_n <= dac_data[23:12]; + constant_sample[23:12] <= tx_sample_hold ? dac_data[23:12] : 12'd0; + end else begin + tx_data_n <= constant_sample[23:12]; + end end end diff --git a/library/axi_ad9963/axi_ad9963_tx.v b/library/axi_ad9963/axi_ad9963_tx.v index 112610f7d..1accfc755 100644 --- a/library/axi_ad9963/axi_ad9963_tx.v +++ b/library/axi_ad9963/axi_ad9963_tx.v @@ -53,7 +53,6 @@ module axi_ad9963_tx #( input dac_clk, output dac_rst, - output reg dac_valid, output [23:0] dac_data, input [23:0] adc_data, @@ -67,9 +66,13 @@ module axi_ad9963_tx #( output dac_enable_i, output reg dac_valid_i, input [15:0] dac_data_i, + input dma_valid_i, + output out_valid_i, output dac_enable_q, output reg dac_valid_q, input [15:0] dac_data_q, + input dma_valid_q, + output out_valid_q, input dac_dunf, output up_dac_ce, @@ -104,13 +107,11 @@ module axi_ad9963_tx #( always @(posedge dac_clk) begin if (dac_rst == 1'b1) begin - dac_valid <= 1'b0; dac_valid_i <= 1'b0; dac_valid_q <= 1'b0; end else begin - dac_valid <= 1'b1; - dac_valid_i <= dac_valid; - dac_valid_q <= dac_valid; + dac_valid_i <= 1'b1; + dac_valid_q <= 1'b1; end end @@ -134,7 +135,7 @@ module axi_ad9963_tx #( i_tx_channel_0 ( .dac_clk (dac_clk), .dac_rst (dac_rst), - .dac_valid (dac_valid), + .dac_valid (dac_valid_i), .dma_data (dac_data_i), .adc_data (adc_data[11:0]), .dac_data (dac_data[11:0]), @@ -143,6 +144,8 @@ module axi_ad9963_tx #( .dac_enable (dac_enable_i), .dac_data_sync (dac_data_sync_s), .dac_dds_format (dac_dds_format_s), + .dma_valid (dma_valid_i), + .out_data_valid (out_valid_i), .up_rstn (up_rstn), .up_clk (up_clk), .up_wreq (up_wreq), @@ -166,7 +169,7 @@ module axi_ad9963_tx #( i_tx_channel_1 ( .dac_clk (dac_clk), .dac_rst (dac_rst), - .dac_valid (dac_valid), + .dac_valid (dac_valid_q), .dma_data (dac_data_q), .adc_data (adc_data[23:12]), .dac_data (dac_data[23:12]), @@ -175,6 +178,8 @@ module axi_ad9963_tx #( .dac_enable (dac_enable_q), .dac_data_sync (dac_data_sync_s), .dac_dds_format (dac_dds_format_s), + .dma_valid (dma_valid_q), + .out_data_valid (out_valid_q), .up_rstn (up_rstn), .up_clk (up_clk), .up_wreq (up_wreq), diff --git a/library/axi_ad9963/axi_ad9963_tx_channel.v b/library/axi_ad9963/axi_ad9963_tx_channel.v index 4d301716b..fa2d3719d 100644 --- a/library/axi_ad9963/axi_ad9963_tx_channel.v +++ b/library/axi_ad9963/axi_ad9963_tx_channel.v @@ -56,6 +56,8 @@ module axi_ad9963_tx_channel #( output reg [11:0] dac_data, output reg [11:0] dac_data_out, input [11:0] dac_data_in, + input dma_valid, + output out_data_valid, // processor interface @@ -85,9 +87,11 @@ module axi_ad9963_tx_channel #( // internal registers reg dac_valid_sel = 'd0; + reg data_source_valid = 'd0; reg [23:0] dac_test_data = 'd0; reg [15:0] dac_test_counter = 'd0; reg [15:0] dac_pat_data = 'd0; + reg dma_valid_m = 1'd0; // internal signals @@ -107,9 +111,12 @@ module axi_ad9963_tx_channel #( wire [15:0] dac_iqcor_coeff_1_s; wire [15:0] dac_iqcor_coeff_2_s; + assign out_data_valid = dac_iqcor_valid_s; + // dac iq correction always @(posedge dac_clk) begin + data_source_valid <= dac_data_sel_s == 4'h2 ? dma_valid_m : dac_valid; dac_enable <= (dac_data_sel_s == 4'h2) ? 1'b1 : 1'b0; if (dac_iqcor_valid_s == 1'b1) begin dac_data <= dac_iqcor_data_s[15:4]; @@ -118,12 +125,12 @@ module axi_ad9963_tx_channel #( generate if (DATAPATH_DISABLE == 1) begin - assign dac_iqcor_valid_s = dac_valid; + assign dac_iqcor_valid_s = data_source_valid; assign dac_iqcor_data_s = {dac_data_out, 4'd0}; end else begin ad_iqcor #(.Q_OR_I_N (Q_OR_I_N)) i_ad_iqcor ( .clk (dac_clk), - .valid (dac_valid), + .valid (data_source_valid), .data_in ({dac_data_out, 4'd0}), .data_iq ({dac_data_in, 4'd0}), .valid_out (dac_iqcor_valid_s), @@ -146,6 +153,7 @@ module axi_ad9963_tx_channel #( 4'h1: dac_data_out <= dac_pat_data[15:4]; default: dac_data_out <= dac_dds_data_s; endcase + dma_valid_m <= dma_valid; end function [23:0] pn23; @@ -202,7 +210,7 @@ module axi_ad9963_tx_channel #( .clk (dac_clk), .dac_dds_format (dac_dds_format), .dac_data_sync (dac_data_sync), - .dac_valid (1'b1), + .dac_valid (dac_valid), .tone_1_scale (dac_dds_scale_1_s), .tone_2_scale (dac_dds_scale_2_s), .tone_1_init_offset (dac_dds_init_1_s),