From 4d6c45eb83e0f14de594c666b67f73dd8bce43cc Mon Sep 17 00:00:00 2001 From: Adrian Costina Date: Fri, 4 Aug 2017 14:28:37 +0300 Subject: [PATCH] axi_adc_decimate: Add correction at the end of the decimation chain The CIC filter introduces different amplifications depending on the decimation ratio. By adding a multiplier in the decimation chain the amplification can be compensated --- library/axi_adc_decimate/axi_adc_decimate.v | 21 ++++- .../axi_adc_decimate_filter.v | 76 ++++++++++++++----- .../axi_adc_decimate/axi_adc_decimate_ip.tcl | 1 + .../axi_adc_decimate/axi_adc_decimate_reg.v | 46 +++++++++-- 4 files changed, 117 insertions(+), 27 deletions(-) diff --git a/library/axi_adc_decimate/axi_adc_decimate.v b/library/axi_adc_decimate/axi_adc_decimate.v index 3aff82c45..af562ed05 100644 --- a/library/axi_adc_decimate/axi_adc_decimate.v +++ b/library/axi_adc_decimate/axi_adc_decimate.v @@ -35,7 +35,9 @@ `timescale 1ns/100ps -module axi_adc_decimate( +module axi_adc_decimate #( + + parameter CORRECTION_DISABLE = 1) ( input adc_clk, input adc_rst, @@ -89,18 +91,28 @@ module axi_adc_decimate( wire [31:0] decimation_ratio; wire [ 2:0] filter_mask; + wire adc_correction_enable_a; + wire adc_correction_enable_b; + wire [15:0] adc_correction_coefficient_a; + wire [15:0] adc_correction_coefficient_b; // signal name changes assign up_clk = s_axi_aclk; assign up_rstn = s_axi_aresetn; - axi_adc_decimate_filter axi_adc_decimate_filter ( + axi_adc_decimate_filter #( + .CORRECTION_DISABLE(CORRECTION_DISABLE) + ) axi_adc_decimate_filter ( .adc_clk (adc_clk), .adc_rst (adc_rst), .decimation_ratio (decimation_ratio), .filter_mask (filter_mask), + .adc_correction_enable_a(adc_correction_enable_a), + .adc_correction_enable_b(adc_correction_enable_b), + .adc_correction_coefficient_a(adc_correction_coefficient_a), + .adc_correction_coefficient_b(adc_correction_coefficient_b), .adc_valid_a(adc_valid_a), .adc_valid_b(adc_valid_b), @@ -119,6 +131,11 @@ module axi_adc_decimate( .adc_decimation_ratio (decimation_ratio), .adc_filter_mask (filter_mask), + .adc_correction_enable_a(adc_correction_enable_a), + .adc_correction_enable_b(adc_correction_enable_b), + .adc_correction_coefficient_a(adc_correction_coefficient_a), + .adc_correction_coefficient_b(adc_correction_coefficient_b), + .up_rstn (up_rstn), .up_clk (up_clk), .up_wreq (up_wreq), diff --git a/library/axi_adc_decimate/axi_adc_decimate_filter.v b/library/axi_adc_decimate/axi_adc_decimate_filter.v index a7261c80f..571b5fa79 100644 --- a/library/axi_adc_decimate/axi_adc_decimate_filter.v +++ b/library/axi_adc_decimate/axi_adc_decimate_filter.v @@ -36,22 +36,30 @@ `timescale 1ns/100ps -module axi_adc_decimate_filter ( +module axi_adc_decimate_filter #( + + parameter CORRECTION_DISABLE = 1) ( + input adc_clk, input adc_rst, input [31:0] decimation_ratio, input [ 2:0] filter_mask, + input adc_correction_enable_a, + input adc_correction_enable_b, + input [15:0] adc_correction_coefficient_a, + input [15:0] adc_correction_coefficient_b, + input adc_valid_a, input adc_valid_b, input [11:0] adc_data_a, input [11:0] adc_data_b, - output reg [15:0] adc_dec_data_a, - output reg [15:0] adc_dec_data_b, - output reg adc_dec_valid_a, - output reg adc_dec_valid_b + output [15:0] adc_dec_data_a, + output [15:0] adc_dec_data_b, + output adc_dec_valid_a, + output adc_dec_valid_b ); // internal signals @@ -63,6 +71,11 @@ module axi_adc_decimate_filter ( reg [4:0] filter_enable = 5'h00; + reg [15:0] adc_dec_data_a_r; + reg [15:0] adc_dec_data_b_r; + reg adc_dec_valid_a_r; + reg adc_dec_valid_b_r; + wire [25:0] adc_fir_data_a; wire adc_fir_valid_a; wire [25:0] adc_fir_data_b; @@ -109,6 +122,34 @@ module axi_adc_decimate_filter ( .filter_out(adc_fir_data_b), .ce_out(adc_fir_valid_b)); + ad_iqcor #(.Q_OR_I_N (0), + .DISABLE(CORRECTION_DISABLE), + .SCALE_ONLY(1) + ) i_scale_correction_a ( + .clk (adc_clk), + .valid (adc_dec_valid_a_r), + .data_in (adc_dec_data_a_r), + .data_iq (16'h0), + .valid_out (adc_dec_valid_a), + .data_out (adc_dec_data_a), + .iqcor_enable (adc_correction_enable_a), + .iqcor_coeff_1 (adc_correction_coefficient_a), + .iqcor_coeff_2 (16'h0)); + + ad_iqcor #(.Q_OR_I_N (0), + .DISABLE(CORRECTION_DISABLE), + .SCALE_ONLY(1) + ) i_scale_correction_b ( + .clk (adc_clk), + .valid (adc_dec_valid_b_r), + .data_in (adc_dec_data_b_r), + .data_iq (16'h0), + .valid_out (adc_dec_valid_b), + .data_out (adc_dec_data_b), + .iqcor_enable (adc_correction_enable_b), + .iqcor_coeff_1 (adc_correction_coefficient_b), + .iqcor_coeff_2 (16'h0)); + always @(posedge adc_clk) begin case (filter_mask) 3'h1: filter_enable <= 5'b00001; @@ -122,8 +163,8 @@ module axi_adc_decimate_filter ( always @(*) begin case (filter_enable[0]) - 1'b0: adc_dec_data_a = {{4{adc_data_a[11]}},adc_data_a}; - default: adc_dec_data_a = {adc_fir_data_a[25], adc_fir_data_a[25:11]}; + 1'b0: adc_dec_data_a_r = {{4{adc_data_a[11]}},adc_data_a}; + default: adc_dec_data_a_r = {adc_fir_data_a[25], adc_fir_data_a[25:11]}; endcase case (filter_enable[0]) @@ -132,8 +173,8 @@ module axi_adc_decimate_filter ( endcase case (filter_enable[0]) - 1'b0: adc_dec_data_b = {{4{adc_data_b[11]}},adc_data_b}; - default adc_dec_data_b = {adc_fir_data_b[25], adc_fir_data_b[25:11]}; + 1'b0: adc_dec_data_b_r = {{4{adc_data_b[11]}},adc_data_b}; + default adc_dec_data_b_r = {adc_fir_data_b[25], adc_fir_data_b[25:11]}; endcase case (filter_enable[0]) @@ -145,25 +186,24 @@ module axi_adc_decimate_filter ( always @(posedge adc_clk) begin if (adc_rst == 1'b1) begin decimation_counter <= 32'b0; - adc_dec_valid_a <= 1'b0; - adc_dec_valid_b <= 1'b0; + adc_dec_valid_a_r <= 1'b0; + adc_dec_valid_b_r <= 1'b0; end else begin if (adc_dec_valid_a_filter == 1'b1) begin if (decimation_counter < decimation_ratio) begin decimation_counter <= decimation_counter + 1; - adc_dec_valid_a <= 1'b0; - adc_dec_valid_b <= 1'b0; + adc_dec_valid_a_r <= 1'b0; + adc_dec_valid_b_r <= 1'b0; end else begin decimation_counter <= 0; - adc_dec_valid_a <= 1'b1; - adc_dec_valid_b <= 1'b1; + adc_dec_valid_a_r <= 1'b1; + adc_dec_valid_b_r <= 1'b1; end end else begin - adc_dec_valid_a <= 1'b0; - adc_dec_valid_b <= 1'b0; + adc_dec_valid_a_r <= 1'b0; + adc_dec_valid_b_r <= 1'b0; end end end - endmodule diff --git a/library/axi_adc_decimate/axi_adc_decimate_ip.tcl b/library/axi_adc_decimate/axi_adc_decimate_ip.tcl index dd64ca54f..927f37969 100644 --- a/library/axi_adc_decimate/axi_adc_decimate_ip.tcl +++ b/library/axi_adc_decimate/axi_adc_decimate_ip.tcl @@ -7,6 +7,7 @@ adi_ip_create axi_adc_decimate adi_ip_files axi_adc_decimate [list \ "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/common/ad_iqcor.v" \ "axi_adc_decimate_constr.xdc" \ "fir_decim.v" \ "cic_decim.v" \ diff --git a/library/axi_adc_decimate/axi_adc_decimate_reg.v b/library/axi_adc_decimate/axi_adc_decimate_reg.v index 09d6f58cf..038ba81a9 100644 --- a/library/axi_adc_decimate/axi_adc_decimate_reg.v +++ b/library/axi_adc_decimate/axi_adc_decimate_reg.v @@ -42,6 +42,11 @@ module axi_adc_decimate_reg( output [31:0] adc_decimation_ratio, output [ 2:0] adc_filter_mask, + output adc_correction_enable_a, + output adc_correction_enable_b, + output [15:0] adc_correction_coefficient_a, + output [15:0] adc_correction_coefficient_b, + // bus interface input up_rstn, @@ -61,7 +66,11 @@ module axi_adc_decimate_reg( reg [31:0] up_scratch = 32'h0; reg [31:0] up_decimation_ratio = 32'h0; - reg [ 2:0] up_filter_mask = 32'h0; + reg [ 2:0] up_filter_mask = 32'h0; + + reg [ 1:0] up_config = 1'h0; + reg [15:0] up_correction_coefficient_a = 16'h0; + reg [15:0] up_correction_coefficient_b = 16'h0; always @(negedge up_rstn or posedge up_clk) begin if (up_rstn == 0) begin @@ -69,6 +78,9 @@ module axi_adc_decimate_reg( up_scratch <= 'd0; up_decimation_ratio <= 'd0; up_filter_mask <= 'd0; + up_config <= 'd0; + up_correction_coefficient_a <= 'd0; + up_correction_coefficient_b <= 'd0; end else begin up_wack <= up_wreq; if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin @@ -80,6 +92,15 @@ module axi_adc_decimate_reg( if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h11)) begin up_filter_mask <= up_wdata[2:0]; end + if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h12)) begin + up_config <= up_wdata[1:0]; + end + if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h13)) begin + up_correction_coefficient_a <= up_wdata[15:0]; + end + if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h14)) begin + up_correction_coefficient_b <= up_wdata[15:0]; + end end end @@ -96,7 +117,10 @@ module axi_adc_decimate_reg( 5'h0: up_rdata <= up_version; 5'h1: up_rdata <= up_scratch; 5'h10: up_rdata <= up_decimation_ratio; - 5'h11: up_rdata <= up_filter_mask; + 5'h11: up_rdata <= { 29'h0, up_filter_mask }; + 5'h12: up_rdata <= { 30'h0, up_config }; + 5'h13: up_rdata <= { 16'h0, up_correction_coefficient_a }; + 5'h14: up_rdata <= { 16'h0, up_correction_coefficient_b }; default: up_rdata <= 0; endcase end else begin @@ -105,17 +129,25 @@ module axi_adc_decimate_reg( end end - up_xfer_cntrl #(.DATA_WIDTH(35)) i_xfer_cntrl ( + up_xfer_cntrl #(.DATA_WIDTH(69)) i_xfer_cntrl ( .up_rstn (up_rstn), .up_clk (up_clk), - .up_data_cntrl ({ up_decimation_ratio, // 32 - up_filter_mask}), // 3 + .up_data_cntrl ({ up_config[1], // 1 + up_config[0], // 1 + up_correction_coefficient_b, // 16 + up_correction_coefficient_a, // 16 + up_decimation_ratio, // 32 + up_filter_mask}), // 3 .up_xfer_done (), .d_rst (1'b0), .d_clk (clk), - .d_data_cntrl ({ adc_decimation_ratio, // 32 - adc_filter_mask})); // 3 + .d_data_cntrl ({ adc_correction_enable_b, // 1 + adc_correction_enable_a, // 1 + adc_correction_coefficient_b, // 16 + adc_correction_coefficient_a, // 16 + adc_decimation_ratio, // 32 + adc_filter_mask})); // 3 endmodule