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
|
||||
|
||||
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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" \
|
||||
|
|
|
@ -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,
|
||||
|
@ -63,12 +68,19 @@ module axi_adc_decimate_reg(
|
|||
reg [31:0] up_decimation_ratio = 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
|
||||
up_wack <= 'd0;
|
||||
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,16 +129,24 @@ 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_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
|
||||
.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
|
||||
|
|
Loading…
Reference in New Issue