axi_dac_interpolate: Add correction at the begining of the interpolation chain

The CIC filter introduces different amplifications depending on the
interpolation ratio. By adding a multiplier in the interpolation chain
the amplification can be compensated
main
Adrian Costina 2017-08-03 17:06:47 +03:00
parent 7cdb11cc34
commit f2240633b2
4 changed files with 99 additions and 27 deletions

View File

@ -35,7 +35,9 @@
`timescale 1ns/100ps `timescale 1ns/100ps
module axi_dac_interpolate( module axi_dac_interpolate #(
parameter CORRECTION_DISABLE = 1) (
input dac_clk, input dac_clk,
input dac_rst, input dac_rst,
@ -94,12 +96,19 @@ module axi_dac_interpolate(
wire dma_transfer_suspend; wire dma_transfer_suspend;
wire dac_correction_enable_a;
wire dac_correction_enable_b;
wire [15:0] dac_correction_coefficient_a;
wire [15:0] dac_correction_coefficient_b;
// signal name changes // signal name changes
assign up_clk = s_axi_aclk; assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn; assign up_rstn = s_axi_aresetn;
axi_dac_interpolate_filter i_filter_a ( axi_dac_interpolate_filter #(
.CORRECTION_DISABLE(CORRECTION_DISABLE))
i_filter_a (
.dac_clk (dac_clk), .dac_clk (dac_clk),
.dac_rst (dac_rst), .dac_rst (dac_rst),
@ -111,10 +120,14 @@ module axi_dac_interpolate(
.filter_mask (filter_mask_a), .filter_mask (filter_mask_a),
.interpolation_ratio (interpolation_ratio_a), .interpolation_ratio (interpolation_ratio_a),
.dma_transfer_suspend (dma_transfer_suspend) .dma_transfer_suspend (dma_transfer_suspend),
.dac_correction_enable(dac_correction_enable_a),
.dac_correction_coefficient(dac_correction_coefficient_a)
); );
axi_dac_interpolate_filter i_filter_b ( axi_dac_interpolate_filter #(
.CORRECTION_DISABLE(CORRECTION_DISABLE))
i_filter_b (
.dac_clk (dac_clk), .dac_clk (dac_clk),
.dac_rst (dac_rst), .dac_rst (dac_rst),
@ -126,7 +139,9 @@ module axi_dac_interpolate(
.filter_mask (filter_mask_b), .filter_mask (filter_mask_b),
.interpolation_ratio (interpolation_ratio_b), .interpolation_ratio (interpolation_ratio_b),
.dma_transfer_suspend (dma_transfer_suspend) .dma_transfer_suspend (dma_transfer_suspend),
.dac_correction_enable(dac_correction_enable_b),
.dac_correction_coefficient(dac_correction_coefficient_b)
); );
axi_dac_interpolate_reg axi_dac_interpolate_reg_inst ( axi_dac_interpolate_reg axi_dac_interpolate_reg_inst (
@ -139,6 +154,10 @@ module axi_dac_interpolate(
.dac_filter_mask_b (filter_mask_b), .dac_filter_mask_b (filter_mask_b),
.dma_transfer_suspend (dma_transfer_suspend), .dma_transfer_suspend (dma_transfer_suspend),
.dac_correction_enable_a(dac_correction_enable_a),
.dac_correction_enable_b(dac_correction_enable_b),
.dac_correction_coefficient_a(dac_correction_coefficient_a),
.dac_correction_coefficient_b(dac_correction_coefficient_b),
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),

View File

@ -36,7 +36,10 @@
`timescale 1ns/100ps `timescale 1ns/100ps
module axi_dac_interpolate_filter ( module axi_dac_interpolate_filter #(
parameter CORRECTION_DISABLE = 1) (
input dac_clk, input dac_clk,
input dac_rst, input dac_rst,
@ -48,6 +51,8 @@ module axi_dac_interpolate_filter (
input [ 2:0] filter_mask, input [ 2:0] filter_mask,
input [31:0] interpolation_ratio, input [31:0] interpolation_ratio,
input [15:0] dac_correction_coefficient,
input dac_correction_enable,
input dma_transfer_suspend input dma_transfer_suspend
); );
@ -61,23 +66,39 @@ module axi_dac_interpolate_filter (
reg filter_enable = 1'b0; reg filter_enable = 1'b0;
wire dac_valid_corrected;
wire [15:0] dac_data_corrected;
wire dac_fir_valid; wire dac_fir_valid;
wire [35:0] dac_fir_data; wire [35:0] dac_fir_data;
wire dac_cic_valid; wire dac_cic_valid;
wire [109:0] dac_cic_data; wire [109:0] dac_cic_data;
ad_iqcor #(.Q_OR_I_N (0),
.DISABLE(CORRECTION_DISABLE),
.SCALE_ONLY(1))
i_ad_iqcor (
.clk (dac_clk),
.valid (dac_valid),
.data_in (dac_data),
.data_iq (16'h0),
.valid_out (dac_valid_corrected),
.data_out (dac_data_corrected),
.iqcor_enable (dac_correction_enable),
.iqcor_coeff_1 (dac_correction_coefficient),
.iqcor_coeff_2 (16'h0));
fir_interp fir_interpolation ( fir_interp fir_interpolation (
.clk (dac_clk), .clk (dac_clk),
.clk_enable (dac_cic_valid), .clk_enable (dac_cic_valid),
.reset (dac_rst | dma_transfer_suspend), .reset (dac_rst | dma_transfer_suspend),
.filter_in (dac_data), .filter_in (dac_data_corrected),
.filter_out (dac_fir_data), .filter_out (dac_fir_data),
.ce_out (dac_fir_valid)); .ce_out (dac_fir_valid));
cic_interp cic_interpolation ( cic_interp cic_interpolation (
.clk (dac_clk), .clk (dac_clk),
.clk_enable (dac_valid), .clk_enable (dac_valid_corrected),
.reset (dac_rst | cic_change_rate | dma_transfer_suspend), .reset (dac_rst | cic_change_rate | dma_transfer_suspend),
.rate (interp_rate_cic), .rate (interp_rate_cic),
.load_rate (1'b0), .load_rate (1'b0),
@ -121,12 +142,12 @@ module axi_dac_interpolate_filter (
always @(*) begin always @(*) begin
case (filter_enable) case (filter_enable)
1'b0: dac_int_data = dac_data; 1'b0: dac_int_data = dac_data_corrected;
default: dac_int_data = dac_cic_data[31:16]; default: dac_int_data = dac_cic_data[31:16];
endcase endcase
case (filter_mask) case (filter_mask)
1'b0: dac_filt_int_valid = dac_valid & !dma_transfer_suspend; 1'b0: dac_filt_int_valid = dac_valid_corrected & !dma_transfer_suspend;
default: dac_filt_int_valid = dac_fir_valid; default: dac_filt_int_valid = dac_fir_valid;
endcase endcase

View File

@ -7,6 +7,8 @@ adi_ip_create axi_dac_interpolate
adi_ip_files axi_dac_interpolate [list \ adi_ip_files axi_dac_interpolate [list \
"$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \
"$ad_hdl_dir/library/common/up_axi.v" \ "$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/common/ad_iqcor.v" \
"$ad_hdl_dir/library/xilinx/common/ad_mul.v" \
"axi_dac_interpolate_constr.xdc" \ "axi_dac_interpolate_constr.xdc" \
"cic_interp.v" \ "cic_interp.v" \
"fir_interp.v" \ "fir_interp.v" \

View File

@ -44,6 +44,10 @@ module axi_dac_interpolate_reg(
output [31:0] dac_interpolation_ratio_b, output [31:0] dac_interpolation_ratio_b,
output [ 2:0] dac_filter_mask_b, output [ 2:0] dac_filter_mask_b,
output dma_transfer_suspend, output dma_transfer_suspend,
output dac_correction_enable_a,
output dac_correction_enable_b,
output [15:0] dac_correction_coefficient_a,
output [15:0] dac_correction_coefficient_b,
// bus interface // bus interface
@ -67,7 +71,10 @@ module axi_dac_interpolate_reg(
reg [ 2:0] up_filter_mask_a = 3'h0; reg [ 2:0] up_filter_mask_a = 3'h0;
reg [31:0] up_interpolation_ratio_b = 32'h0; reg [31:0] up_interpolation_ratio_b = 32'h0;
reg [ 2:0] up_filter_mask_b = 3'h0; reg [ 2:0] up_filter_mask_b = 3'h0;
reg [31:0] up_flags = 32'h0; reg up_flags = 32'h0;
reg [1:0] up_config = 2'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 always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin if (up_rstn == 0) begin
@ -78,6 +85,9 @@ module axi_dac_interpolate_reg(
up_interpolation_ratio_b <= 'd0; up_interpolation_ratio_b <= 'd0;
up_filter_mask_b <= 'd0; up_filter_mask_b <= 'd0;
up_flags <= 'd0; up_flags <= 'd0;
up_config <= 'd0;
up_correction_coefficient_a <= 'd0;
up_correction_coefficient_b <= 'd0;
end else begin end else begin
up_wack <= up_wreq; up_wack <= up_wreq;
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin
@ -96,7 +106,16 @@ module axi_dac_interpolate_reg(
up_filter_mask_b <= up_wdata[2:0]; up_filter_mask_b <= up_wdata[2:0];
end end
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h14)) begin if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h14)) begin
up_flags <= up_wdata; up_flags <= {31'h0,up_wdata[0]};
end
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h15)) begin
up_config <= up_wdata[1:0];
end
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h16)) begin
up_correction_coefficient_a <= up_wdata[15:0];
end
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h17)) begin
up_correction_coefficient_b <= up_wdata[15:0];
end end
end end
end end
@ -114,10 +133,13 @@ module axi_dac_interpolate_reg(
5'h0: up_rdata <= up_version; 5'h0: up_rdata <= up_version;
5'h1: up_rdata <= up_scratch; 5'h1: up_rdata <= up_scratch;
5'h10: up_rdata <= up_interpolation_ratio_a; 5'h10: up_rdata <= up_interpolation_ratio_a;
5'h11: up_rdata <= up_filter_mask_a; 5'h11: up_rdata <= {29'h0,up_filter_mask_a};
5'h12: up_rdata <= up_interpolation_ratio_b; 5'h12: up_rdata <= up_interpolation_ratio_b;
5'h13: up_rdata <= up_filter_mask_b; 5'h13: up_rdata <= {29'h0,up_filter_mask_b};
5'h14: up_rdata <= up_flags; 5'h14: up_rdata <= {31'h0,up_flags};
5'h15: up_rdata <= {30'h0,up_config};
5'h16: up_rdata <= {16'h0,up_correction_coefficient_a};
5'h17: up_rdata <= {16'h0,up_correction_coefficient_b};
default: up_rdata <= 0; default: up_rdata <= 0;
endcase endcase
end else begin end else begin
@ -126,23 +148,31 @@ module axi_dac_interpolate_reg(
end end
end end
up_xfer_cntrl #(.DATA_WIDTH(71)) i_xfer_cntrl ( up_xfer_cntrl #(.DATA_WIDTH(105)) i_xfer_cntrl (
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),
.up_data_cntrl ({ up_flags[0], // 1 .up_data_cntrl ({ up_config[1], // 1
up_interpolation_ratio_b, // 32 up_config[0], // 1
up_interpolation_ratio_a, // 32 up_correction_coefficient_b,// 16
up_filter_mask_b, // 3 up_correction_coefficient_a,// 16
up_filter_mask_a}), // 3 up_flags, // 1
up_interpolation_ratio_b, // 32
up_interpolation_ratio_a, // 32
up_filter_mask_b, // 3
up_filter_mask_a}), // 3
.up_xfer_done (), .up_xfer_done (),
.d_rst (1'b0), .d_rst (1'b0),
.d_clk (clk), .d_clk (clk),
.d_data_cntrl ({ dma_transfer_suspend, // 1 .d_data_cntrl ({ dac_correction_enable_b, // 1
dac_interpolation_ratio_b, // 32 dac_correction_enable_a, // 1
dac_interpolation_ratio_a, // 32 dac_correction_coefficient_b, // 16
dac_filter_mask_b, // 3 dac_correction_coefficient_a, // 16
dac_filter_mask_a})); // 3 dma_transfer_suspend, // 1
dac_interpolation_ratio_b, // 32
dac_interpolation_ratio_a, // 32
dac_filter_mask_b, // 3
dac_filter_mask_a})); // 3
endmodule endmodule