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
module axi_dac_interpolate(
module axi_dac_interpolate #(
parameter CORRECTION_DISABLE = 1) (
input dac_clk,
input dac_rst,
@ -94,12 +96,19 @@ module axi_dac_interpolate(
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
assign up_clk = s_axi_aclk;
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_rst (dac_rst),
@ -111,10 +120,14 @@ module axi_dac_interpolate(
.filter_mask (filter_mask_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_rst (dac_rst),
@ -126,7 +139,9 @@ module axi_dac_interpolate(
.filter_mask (filter_mask_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 (
@ -139,6 +154,10 @@ module axi_dac_interpolate(
.dac_filter_mask_b (filter_mask_b),
.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_clk (up_clk),

View File

@ -36,7 +36,10 @@
`timescale 1ns/100ps
module axi_dac_interpolate_filter (
module axi_dac_interpolate_filter #(
parameter CORRECTION_DISABLE = 1) (
input dac_clk,
input dac_rst,
@ -48,6 +51,8 @@ module axi_dac_interpolate_filter (
input [ 2:0] filter_mask,
input [31:0] interpolation_ratio,
input [15:0] dac_correction_coefficient,
input dac_correction_enable,
input dma_transfer_suspend
);
@ -61,23 +66,39 @@ module axi_dac_interpolate_filter (
reg filter_enable = 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;
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 (
.clk (dac_clk),
.clk_enable (dac_cic_valid),
.reset (dac_rst | dma_transfer_suspend),
.filter_in (dac_data),
.filter_in (dac_data_corrected),
.filter_out (dac_fir_data),
.ce_out (dac_fir_valid));
cic_interp cic_interpolation (
.clk (dac_clk),
.clk_enable (dac_valid),
.clk_enable (dac_valid_corrected),
.reset (dac_rst | cic_change_rate | dma_transfer_suspend),
.rate (interp_rate_cic),
.load_rate (1'b0),
@ -121,12 +142,12 @@ module axi_dac_interpolate_filter (
always @(*) begin
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];
endcase
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;
endcase

View File

@ -7,6 +7,8 @@ adi_ip_create axi_dac_interpolate
adi_ip_files axi_dac_interpolate [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" \
"$ad_hdl_dir/library/xilinx/common/ad_mul.v" \
"axi_dac_interpolate_constr.xdc" \
"cic_interp.v" \
"fir_interp.v" \

View File

@ -44,6 +44,10 @@ module axi_dac_interpolate_reg(
output [31:0] dac_interpolation_ratio_b,
output [ 2:0] dac_filter_mask_b,
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
@ -67,7 +71,10 @@ module axi_dac_interpolate_reg(
reg [ 2:0] up_filter_mask_a = 3'h0;
reg [31:0] up_interpolation_ratio_b = 32'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
if (up_rstn == 0) begin
@ -78,6 +85,9 @@ module axi_dac_interpolate_reg(
up_interpolation_ratio_b <= 'd0;
up_filter_mask_b <= 'd0;
up_flags <= '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
@ -96,7 +106,16 @@ module axi_dac_interpolate_reg(
up_filter_mask_b <= up_wdata[2:0];
end
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
@ -114,10 +133,13 @@ module axi_dac_interpolate_reg(
5'h0: up_rdata <= up_version;
5'h1: up_rdata <= up_scratch;
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'h13: up_rdata <= up_filter_mask_b;
5'h14: up_rdata <= up_flags;
5'h13: up_rdata <= {29'h0,up_filter_mask_b};
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;
endcase
end else begin
@ -126,23 +148,31 @@ module axi_dac_interpolate_reg(
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_clk (up_clk),
.up_data_cntrl ({ up_flags[0], // 1
up_interpolation_ratio_b, // 32
up_interpolation_ratio_a, // 32
up_filter_mask_b, // 3
up_filter_mask_a}), // 3
.up_data_cntrl ({ up_config[1], // 1
up_config[0], // 1
up_correction_coefficient_b,// 16
up_correction_coefficient_a,// 16
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 (),
.d_rst (1'b0),
.d_clk (clk),
.d_data_cntrl ({ dma_transfer_suspend, // 1
dac_interpolation_ratio_b, // 32
dac_interpolation_ratio_a, // 32
dac_filter_mask_b, // 3
dac_filter_mask_a})); // 3
.d_data_cntrl ({ dac_correction_enable_b, // 1
dac_correction_enable_a, // 1
dac_correction_coefficient_b, // 16
dac_correction_coefficient_a, // 16
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