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 compensatedmain
parent
cf25aeacf5
commit
4d6c45eb83
|
@ -35,7 +35,9 @@
|
||||||
|
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module axi_adc_decimate(
|
module axi_adc_decimate #(
|
||||||
|
|
||||||
|
parameter CORRECTION_DISABLE = 1) (
|
||||||
|
|
||||||
input adc_clk,
|
input adc_clk,
|
||||||
input adc_rst,
|
input adc_rst,
|
||||||
|
@ -89,18 +91,28 @@ module axi_adc_decimate(
|
||||||
|
|
||||||
wire [31:0] decimation_ratio;
|
wire [31:0] decimation_ratio;
|
||||||
wire [ 2:0] filter_mask;
|
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
|
// 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_adc_decimate_filter axi_adc_decimate_filter (
|
axi_adc_decimate_filter #(
|
||||||
|
.CORRECTION_DISABLE(CORRECTION_DISABLE)
|
||||||
|
) axi_adc_decimate_filter (
|
||||||
.adc_clk (adc_clk),
|
.adc_clk (adc_clk),
|
||||||
.adc_rst (adc_rst),
|
.adc_rst (adc_rst),
|
||||||
|
|
||||||
.decimation_ratio (decimation_ratio),
|
.decimation_ratio (decimation_ratio),
|
||||||
.filter_mask (filter_mask),
|
.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_a(adc_valid_a),
|
||||||
.adc_valid_b(adc_valid_b),
|
.adc_valid_b(adc_valid_b),
|
||||||
|
@ -119,6 +131,11 @@ module axi_adc_decimate(
|
||||||
.adc_decimation_ratio (decimation_ratio),
|
.adc_decimation_ratio (decimation_ratio),
|
||||||
.adc_filter_mask (filter_mask),
|
.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_rstn (up_rstn),
|
||||||
.up_clk (up_clk),
|
.up_clk (up_clk),
|
||||||
.up_wreq (up_wreq),
|
.up_wreq (up_wreq),
|
||||||
|
|
|
@ -36,22 +36,30 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
|
|
||||||
module axi_adc_decimate_filter (
|
module axi_adc_decimate_filter #(
|
||||||
|
|
||||||
|
parameter CORRECTION_DISABLE = 1) (
|
||||||
|
|
||||||
input adc_clk,
|
input adc_clk,
|
||||||
input adc_rst,
|
input adc_rst,
|
||||||
|
|
||||||
input [31:0] decimation_ratio,
|
input [31:0] decimation_ratio,
|
||||||
input [ 2:0] filter_mask,
|
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_a,
|
||||||
input adc_valid_b,
|
input adc_valid_b,
|
||||||
input [11:0] adc_data_a,
|
input [11:0] adc_data_a,
|
||||||
input [11:0] adc_data_b,
|
input [11:0] adc_data_b,
|
||||||
|
|
||||||
output reg [15:0] adc_dec_data_a,
|
output [15:0] adc_dec_data_a,
|
||||||
output reg [15:0] adc_dec_data_b,
|
output [15:0] adc_dec_data_b,
|
||||||
output reg adc_dec_valid_a,
|
output adc_dec_valid_a,
|
||||||
output reg adc_dec_valid_b
|
output adc_dec_valid_b
|
||||||
);
|
);
|
||||||
|
|
||||||
// internal signals
|
// internal signals
|
||||||
|
@ -63,6 +71,11 @@ module axi_adc_decimate_filter (
|
||||||
|
|
||||||
reg [4:0] filter_enable = 5'h00;
|
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 [25:0] adc_fir_data_a;
|
||||||
wire adc_fir_valid_a;
|
wire adc_fir_valid_a;
|
||||||
wire [25:0] adc_fir_data_b;
|
wire [25:0] adc_fir_data_b;
|
||||||
|
@ -109,6 +122,34 @@ module axi_adc_decimate_filter (
|
||||||
.filter_out(adc_fir_data_b),
|
.filter_out(adc_fir_data_b),
|
||||||
.ce_out(adc_fir_valid_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
|
always @(posedge adc_clk) begin
|
||||||
case (filter_mask)
|
case (filter_mask)
|
||||||
3'h1: filter_enable <= 5'b00001;
|
3'h1: filter_enable <= 5'b00001;
|
||||||
|
@ -122,8 +163,8 @@ module axi_adc_decimate_filter (
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
case (filter_enable[0])
|
case (filter_enable[0])
|
||||||
1'b0: adc_dec_data_a = {{4{adc_data_a[11]}},adc_data_a};
|
1'b0: adc_dec_data_a_r = {{4{adc_data_a[11]}},adc_data_a};
|
||||||
default: adc_dec_data_a = {adc_fir_data_a[25], adc_fir_data_a[25:11]};
|
default: adc_dec_data_a_r = {adc_fir_data_a[25], adc_fir_data_a[25:11]};
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
case (filter_enable[0])
|
case (filter_enable[0])
|
||||||
|
@ -132,8 +173,8 @@ module axi_adc_decimate_filter (
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
case (filter_enable[0])
|
case (filter_enable[0])
|
||||||
1'b0: adc_dec_data_b = {{4{adc_data_b[11]}},adc_data_b};
|
1'b0: adc_dec_data_b_r = {{4{adc_data_b[11]}},adc_data_b};
|
||||||
default adc_dec_data_b = {adc_fir_data_b[25], adc_fir_data_b[25:11]};
|
default adc_dec_data_b_r = {adc_fir_data_b[25], adc_fir_data_b[25:11]};
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
case (filter_enable[0])
|
case (filter_enable[0])
|
||||||
|
@ -145,25 +186,24 @@ module axi_adc_decimate_filter (
|
||||||
always @(posedge adc_clk) begin
|
always @(posedge adc_clk) begin
|
||||||
if (adc_rst == 1'b1) begin
|
if (adc_rst == 1'b1) begin
|
||||||
decimation_counter <= 32'b0;
|
decimation_counter <= 32'b0;
|
||||||
adc_dec_valid_a <= 1'b0;
|
adc_dec_valid_a_r <= 1'b0;
|
||||||
adc_dec_valid_b <= 1'b0;
|
adc_dec_valid_b_r <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (adc_dec_valid_a_filter == 1'b1) begin
|
if (adc_dec_valid_a_filter == 1'b1) begin
|
||||||
if (decimation_counter < decimation_ratio) begin
|
if (decimation_counter < decimation_ratio) begin
|
||||||
decimation_counter <= decimation_counter + 1;
|
decimation_counter <= decimation_counter + 1;
|
||||||
adc_dec_valid_a <= 1'b0;
|
adc_dec_valid_a_r <= 1'b0;
|
||||||
adc_dec_valid_b <= 1'b0;
|
adc_dec_valid_b_r <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
decimation_counter <= 0;
|
decimation_counter <= 0;
|
||||||
adc_dec_valid_a <= 1'b1;
|
adc_dec_valid_a_r <= 1'b1;
|
||||||
adc_dec_valid_b <= 1'b1;
|
adc_dec_valid_b_r <= 1'b1;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
adc_dec_valid_a <= 1'b0;
|
adc_dec_valid_a_r <= 1'b0;
|
||||||
adc_dec_valid_b <= 1'b0;
|
adc_dec_valid_b_r <= 1'b0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -7,6 +7,7 @@ adi_ip_create axi_adc_decimate
|
||||||
adi_ip_files axi_adc_decimate [list \
|
adi_ip_files axi_adc_decimate [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" \
|
||||||
"axi_adc_decimate_constr.xdc" \
|
"axi_adc_decimate_constr.xdc" \
|
||||||
"fir_decim.v" \
|
"fir_decim.v" \
|
||||||
"cic_decim.v" \
|
"cic_decim.v" \
|
||||||
|
|
|
@ -42,6 +42,11 @@ module axi_adc_decimate_reg(
|
||||||
output [31:0] adc_decimation_ratio,
|
output [31:0] adc_decimation_ratio,
|
||||||
output [ 2:0] adc_filter_mask,
|
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
|
// bus interface
|
||||||
|
|
||||||
input up_rstn,
|
input up_rstn,
|
||||||
|
@ -63,12 +68,19 @@ module axi_adc_decimate_reg(
|
||||||
reg [31:0] up_decimation_ratio = 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
|
always @(negedge up_rstn or posedge up_clk) begin
|
||||||
if (up_rstn == 0) begin
|
if (up_rstn == 0) begin
|
||||||
up_wack <= 'd0;
|
up_wack <= 'd0;
|
||||||
up_scratch <= 'd0;
|
up_scratch <= 'd0;
|
||||||
up_decimation_ratio <= 'd0;
|
up_decimation_ratio <= 'd0;
|
||||||
up_filter_mask <= 'd0;
|
up_filter_mask <= '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
|
||||||
|
@ -80,6 +92,15 @@ module axi_adc_decimate_reg(
|
||||||
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h11)) begin
|
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h11)) begin
|
||||||
up_filter_mask <= up_wdata[2:0];
|
up_filter_mask <= up_wdata[2:0];
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,7 +117,10 @@ module axi_adc_decimate_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_decimation_ratio;
|
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;
|
default: up_rdata <= 0;
|
||||||
endcase
|
endcase
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -105,16 +129,24 @@ module axi_adc_decimate_reg(
|
||||||
end
|
end
|
||||||
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_rstn (up_rstn),
|
||||||
.up_clk (up_clk),
|
.up_clk (up_clk),
|
||||||
.up_data_cntrl ({ up_decimation_ratio, // 32
|
.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_filter_mask}), // 3
|
||||||
|
|
||||||
.up_xfer_done (),
|
.up_xfer_done (),
|
||||||
.d_rst (1'b0),
|
.d_rst (1'b0),
|
||||||
.d_clk (clk),
|
.d_clk (clk),
|
||||||
.d_data_cntrl ({ adc_decimation_ratio, // 32
|
.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
|
adc_filter_mask})); // 3
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue