axi_dac_interpolate: Move processing pipeline to own sub-module
Move the processing pipeline of the axi_adc_decimate core to its own sub-module. This makes it easier to simulate the processing independent of the register map. Also since the filter is two instances of the same logic, one for each channel, let the new sub-module model one channel and instantiate it twice. This allows to change the implementation without having to change the same code twice. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>main
parent
a02a763139
commit
9c2c50728c
|
@ -47,10 +47,10 @@ module axi_dac_interpolate(
|
||||||
input dac_valid_a,
|
input dac_valid_a,
|
||||||
input dac_valid_b,
|
input dac_valid_b,
|
||||||
|
|
||||||
output reg [15:0] dac_int_data_a,
|
output [15:0] dac_int_data_a,
|
||||||
output reg [15:0] dac_int_data_b,
|
output [15:0] dac_int_data_b,
|
||||||
output reg dac_int_valid_a,
|
output dac_int_valid_a,
|
||||||
output reg dac_int_valid_b,
|
output dac_int_valid_b,
|
||||||
|
|
||||||
// axi interface
|
// axi interface
|
||||||
|
|
||||||
|
@ -94,176 +94,42 @@ module axi_dac_interpolate(
|
||||||
wire [31:0] filter_mask_a;
|
wire [31:0] filter_mask_a;
|
||||||
wire [31:0] filter_mask_b;
|
wire [31:0] filter_mask_b;
|
||||||
|
|
||||||
wire dac_fir_valid_a;
|
|
||||||
wire [35:0] dac_fir_data_a;
|
|
||||||
wire dac_fir_valid_b;
|
|
||||||
wire [35:0] dac_fir_data_b;
|
|
||||||
|
|
||||||
wire dac_cic_valid_a;
|
|
||||||
wire [109:0] dac_cic_data_a;
|
|
||||||
wire dac_cic_valid_b;
|
|
||||||
wire [109:0] dac_cic_data_b;
|
|
||||||
|
|
||||||
wire dma_transfer_suspend;
|
wire dma_transfer_suspend;
|
||||||
|
|
||||||
reg dac_filt_int_valid_a;
|
|
||||||
reg dac_filt_int_valid_b;
|
|
||||||
reg [15:0] interp_rate_cic_a;
|
|
||||||
reg [15:0] interp_rate_cic_b;
|
|
||||||
reg [31:0] filter_mask_a_d1;
|
|
||||||
reg [31:0] filter_mask_b_d1;
|
|
||||||
reg cic_change_rate_a;
|
|
||||||
reg cic_change_rate_b;
|
|
||||||
reg [31:0] interpolation_counter_a;
|
|
||||||
reg [31:0] interpolation_counter_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;
|
||||||
|
|
||||||
fir_interp fir_interpolation_a (
|
axi_dac_interpolate_filter i_filter_a (
|
||||||
.clk (dac_clk),
|
.dac_clk (dac_clk),
|
||||||
.clk_enable (dac_cic_valid_a),
|
.dac_rst (dac_rst),
|
||||||
.reset (dac_rst | dma_transfer_suspend),
|
|
||||||
.filter_in (dac_data_a),
|
|
||||||
.filter_out (dac_fir_data_a),
|
|
||||||
.ce_out (dac_fir_valid_a));
|
|
||||||
|
|
||||||
fir_interp fir_interpolation_b (
|
.dac_data (dac_data_a),
|
||||||
.clk (dac_clk),
|
.dac_valid (dac_valid_a),
|
||||||
.clk_enable (dac_cic_valid_b),
|
|
||||||
.reset (dac_rst | dma_transfer_suspend),
|
|
||||||
.filter_in (dac_data_b),
|
|
||||||
.filter_out (dac_fir_data_b),
|
|
||||||
.ce_out (dac_fir_valid_b));
|
|
||||||
|
|
||||||
cic_interp cic_interpolation_a (
|
.dac_int_data (dac_int_data_a),
|
||||||
.clk (dac_clk),
|
.dac_int_valid (dac_int_valid_a),
|
||||||
.clk_enable (dac_valid_a),
|
|
||||||
.reset (dac_rst | cic_change_rate_a | dma_transfer_suspend),
|
|
||||||
.rate (interp_rate_cic_a),
|
|
||||||
.load_rate (1'b0),
|
|
||||||
.filter_in (dac_fir_data_a[30:0]),
|
|
||||||
.filter_out (dac_cic_data_a),
|
|
||||||
.ce_out (dac_cic_valid_a));
|
|
||||||
|
|
||||||
cic_interp cic_interpolation_b (
|
.filter_mask (filter_mask_a),
|
||||||
.clk (dac_clk),
|
.interpolation_ratio (interpolation_ratio_a),
|
||||||
.clk_enable (dac_valid_b),
|
.dma_transfer_suspend (dma_transfer_suspend)
|
||||||
.reset (dac_rst | cic_change_rate_b | dma_transfer_suspend),
|
);
|
||||||
.rate (interp_rate_cic_b),
|
|
||||||
.load_rate (1'b0),
|
|
||||||
.filter_in (dac_fir_data_b[30:0]),
|
|
||||||
.filter_out (dac_cic_data_b),
|
|
||||||
.ce_out (dac_cic_valid_b));
|
|
||||||
|
|
||||||
always @(posedge dac_clk) begin
|
axi_dac_interpolate_filter i_filter_b (
|
||||||
filter_mask_a_d1 <= filter_mask_a;
|
.dac_clk (dac_clk),
|
||||||
filter_mask_b_d1 <= filter_mask_b;
|
.dac_rst (dac_rst),
|
||||||
if (filter_mask_a_d1 != filter_mask_a) begin
|
|
||||||
cic_change_rate_a <= 1'b1;
|
|
||||||
end else begin
|
|
||||||
cic_change_rate_a <= 1'b0;
|
|
||||||
end
|
|
||||||
if (filter_mask_b_d1 != filter_mask_b) begin
|
|
||||||
cic_change_rate_b <= 1'b1;
|
|
||||||
end else begin
|
|
||||||
cic_change_rate_b <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge dac_clk) begin
|
.dac_data (dac_data_b),
|
||||||
if (interpolation_ratio_a == 0 || interpolation_ratio_a == 1) begin
|
.dac_valid (dac_valid_b),
|
||||||
dac_int_valid_a <= dac_filt_int_valid_a;
|
|
||||||
end else begin
|
|
||||||
if (dac_filt_int_valid_a == 1'b1) begin
|
|
||||||
if (interpolation_counter_a < interpolation_ratio_a) begin
|
|
||||||
interpolation_counter_a <= interpolation_counter_a + 1;
|
|
||||||
dac_int_valid_a <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
interpolation_counter_a <= 0;
|
|
||||||
dac_int_valid_a <= 1'b1;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
dac_int_valid_a <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge dac_clk) begin
|
.dac_int_data (dac_int_data_b),
|
||||||
if (interpolation_ratio_b == 0 || interpolation_ratio_b == 1) begin
|
.dac_int_valid (dac_int_valid_b),
|
||||||
dac_int_valid_b <= dac_filt_int_valid_b;
|
|
||||||
end else begin
|
|
||||||
if (dac_filt_int_valid_b == 1'b1) begin
|
|
||||||
if (interpolation_counter_b < interpolation_ratio_b) begin
|
|
||||||
interpolation_counter_b <= interpolation_counter_b + 1;
|
|
||||||
dac_int_valid_b <= 1'b0;
|
|
||||||
end else begin
|
|
||||||
interpolation_counter_b <= 0;
|
|
||||||
dac_int_valid_b <= 1'b1;
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
dac_int_valid_b <= 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(*) begin
|
.filter_mask (filter_mask_b),
|
||||||
case (filter_mask_a)
|
.interpolation_ratio (interpolation_ratio_b),
|
||||||
16'h1: dac_int_data_a = dac_cic_data_a[31:16];
|
.dma_transfer_suspend (dma_transfer_suspend)
|
||||||
16'h2: dac_int_data_a = dac_cic_data_a[31:16];
|
);
|
||||||
16'h3: dac_int_data_a = dac_cic_data_a[31:16];
|
|
||||||
16'h6: dac_int_data_a = dac_cic_data_a[31:16];
|
|
||||||
16'h7: dac_int_data_a = dac_cic_data_a[31:16];
|
|
||||||
default: dac_int_data_a = dac_data_a;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
case (filter_mask_a)
|
|
||||||
16'h1: dac_filt_int_valid_a = dac_fir_valid_a;
|
|
||||||
16'h2: dac_filt_int_valid_a = dac_fir_valid_a;
|
|
||||||
16'h3: dac_filt_int_valid_a = dac_fir_valid_a;
|
|
||||||
16'h6: dac_filt_int_valid_a = dac_fir_valid_a;
|
|
||||||
16'h7: dac_filt_int_valid_a = dac_fir_valid_a;
|
|
||||||
default: dac_filt_int_valid_a = dac_valid_a & !dma_transfer_suspend;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
case (filter_mask_b)
|
|
||||||
16'h1: dac_int_data_b = dac_cic_data_b[31:16];
|
|
||||||
16'h2: dac_int_data_b = dac_cic_data_b[31:16];
|
|
||||||
16'h3: dac_int_data_b = dac_cic_data_b[31:16];
|
|
||||||
16'h6: dac_int_data_b = dac_cic_data_b[31:16];
|
|
||||||
16'h7: dac_int_data_b = dac_cic_data_b[31:16];
|
|
||||||
default: dac_int_data_b = dac_data_b;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
case (filter_mask_b)
|
|
||||||
16'h1: dac_filt_int_valid_b = dac_fir_valid_b;
|
|
||||||
16'h2: dac_filt_int_valid_b = dac_fir_valid_b;
|
|
||||||
16'h3: dac_filt_int_valid_b = dac_fir_valid_b;
|
|
||||||
16'h6: dac_filt_int_valid_b = dac_fir_valid_b;
|
|
||||||
16'h7: dac_filt_int_valid_b = dac_fir_valid_b;
|
|
||||||
default: dac_filt_int_valid_b = dac_valid_b & !dma_transfer_suspend;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
case (filter_mask_a)
|
|
||||||
16'h1: interp_rate_cic_a = 16'd5;
|
|
||||||
16'h2: interp_rate_cic_a = 16'd50;
|
|
||||||
16'h3: interp_rate_cic_a = 16'd500;
|
|
||||||
16'h6: interp_rate_cic_a = 16'd5000;
|
|
||||||
16'h7: interp_rate_cic_a = 16'd50000;
|
|
||||||
default: interp_rate_cic_a = 16'd1;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
case (filter_mask_b)
|
|
||||||
16'h1: interp_rate_cic_b = 16'd5;
|
|
||||||
16'h2: interp_rate_cic_b = 16'd50;
|
|
||||||
16'h3: interp_rate_cic_b = 16'd500;
|
|
||||||
16'h6: interp_rate_cic_b = 16'd5000;
|
|
||||||
16'h7: interp_rate_cic_b = 16'd50000;
|
|
||||||
default: interp_rate_cic_b = 16'd1;
|
|
||||||
endcase
|
|
||||||
end
|
|
||||||
|
|
||||||
axi_dac_interpolate_reg axi_dac_interpolate_reg_inst (
|
axi_dac_interpolate_reg axi_dac_interpolate_reg_inst (
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
// ***************************************************************************
|
||||||
|
// ***************************************************************************
|
||||||
|
// Copyright 2017(c) Analog Devices, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
// are permitted provided that the following conditions are met:
|
||||||
|
// - Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// - Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in
|
||||||
|
// the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// - Neither the name of Analog Devices, Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
// - The use of this software may or may not infringe the patent rights
|
||||||
|
// of one or more patent holders. This license does not release you
|
||||||
|
// from the requirement that you obtain separate licenses from these
|
||||||
|
// patent holders to use this software.
|
||||||
|
// - Use of the software either in source or binary form, must be run
|
||||||
|
// on or directly connected to an Analog Devices Inc. component.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
//
|
||||||
|
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
|
||||||
|
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
// ***************************************************************************
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
|
|
||||||
|
module axi_dac_interpolate_filter (
|
||||||
|
input dac_clk,
|
||||||
|
input dac_rst,
|
||||||
|
|
||||||
|
input [15:0] dac_data,
|
||||||
|
input dac_valid,
|
||||||
|
|
||||||
|
output reg [15:0] dac_int_data,
|
||||||
|
output reg dac_int_valid,
|
||||||
|
|
||||||
|
input [31:0] filter_mask,
|
||||||
|
input [31:0] interpolation_ratio,
|
||||||
|
input dma_transfer_suspend
|
||||||
|
);
|
||||||
|
|
||||||
|
// internal signals
|
||||||
|
|
||||||
|
reg dac_filt_int_valid;
|
||||||
|
reg [15:0] interp_rate_cic;
|
||||||
|
reg [31:0] filter_mask_d1;
|
||||||
|
reg cic_change_rate;
|
||||||
|
reg [31:0] interpolation_counter;
|
||||||
|
|
||||||
|
wire dac_fir_valid;
|
||||||
|
wire [35:0] dac_fir_data;
|
||||||
|
|
||||||
|
wire dac_cic_valid;
|
||||||
|
wire [109:0] dac_cic_data;
|
||||||
|
|
||||||
|
fir_interp fir_interpolation (
|
||||||
|
.clk (dac_clk),
|
||||||
|
.clk_enable (dac_cic_valid),
|
||||||
|
.reset (dac_rst | dma_transfer_suspend),
|
||||||
|
.filter_in (dac_data),
|
||||||
|
.filter_out (dac_fir_data),
|
||||||
|
.ce_out (dac_fir_valid));
|
||||||
|
|
||||||
|
cic_interp cic_interpolation (
|
||||||
|
.clk (dac_clk),
|
||||||
|
.clk_enable (dac_valid),
|
||||||
|
.reset (dac_rst | cic_change_rate | dma_transfer_suspend),
|
||||||
|
.rate (interp_rate_cic),
|
||||||
|
.load_rate (1'b0),
|
||||||
|
.filter_in (dac_fir_data[30:0]),
|
||||||
|
.filter_out (dac_cic_data),
|
||||||
|
.ce_out (dac_cic_valid));
|
||||||
|
|
||||||
|
always @(posedge dac_clk) begin
|
||||||
|
filter_mask_d1 <= filter_mask;
|
||||||
|
if (filter_mask_d1 != filter_mask) begin
|
||||||
|
cic_change_rate <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
cic_change_rate <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge dac_clk) begin
|
||||||
|
if (interpolation_ratio == 0 || interpolation_ratio == 1) begin
|
||||||
|
dac_int_valid <= dac_filt_int_valid;
|
||||||
|
end else begin
|
||||||
|
if (dac_filt_int_valid == 1'b1) begin
|
||||||
|
if (interpolation_counter < interpolation_ratio) begin
|
||||||
|
interpolation_counter <= interpolation_counter + 1;
|
||||||
|
dac_int_valid <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
interpolation_counter <= 0;
|
||||||
|
dac_int_valid <= 1'b1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
dac_int_valid <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
case (filter_mask)
|
||||||
|
16'h1: dac_int_data = dac_cic_data[31:16];
|
||||||
|
16'h2: dac_int_data = dac_cic_data[31:16];
|
||||||
|
16'h3: dac_int_data = dac_cic_data[31:16];
|
||||||
|
16'h6: dac_int_data = dac_cic_data[31:16];
|
||||||
|
16'h7: dac_int_data = dac_cic_data[31:16];
|
||||||
|
default: dac_int_data = dac_data;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
case (filter_mask)
|
||||||
|
16'h1: dac_filt_int_valid = dac_fir_valid;
|
||||||
|
16'h2: dac_filt_int_valid = dac_fir_valid;
|
||||||
|
16'h3: dac_filt_int_valid = dac_fir_valid;
|
||||||
|
16'h6: dac_filt_int_valid = dac_fir_valid;
|
||||||
|
16'h7: dac_filt_int_valid = dac_fir_valid;
|
||||||
|
default: dac_filt_int_valid = dac_valid & !dma_transfer_suspend;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
case (filter_mask)
|
||||||
|
16'h1: interp_rate_cic = 16'd5;
|
||||||
|
16'h2: interp_rate_cic = 16'd50;
|
||||||
|
16'h3: interp_rate_cic = 16'd500;
|
||||||
|
16'h6: interp_rate_cic = 16'd5000;
|
||||||
|
16'h7: interp_rate_cic = 16'd50000;
|
||||||
|
default: interp_rate_cic = 16'd1;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -11,6 +11,7 @@ adi_ip_files axi_dac_interpolate [list \
|
||||||
"cic_interp.v" \
|
"cic_interp.v" \
|
||||||
"fir_interp.v" \
|
"fir_interp.v" \
|
||||||
"axi_dac_interpolate_reg.v" \
|
"axi_dac_interpolate_reg.v" \
|
||||||
|
"axi_dac_interpolate_filter.v" \
|
||||||
"axi_dac_interpolate.v" ]
|
"axi_dac_interpolate.v" ]
|
||||||
|
|
||||||
adi_ip_properties axi_dac_interpolate
|
adi_ip_properties axi_dac_interpolate
|
||||||
|
|
Loading…
Reference in New Issue