diff --git a/library/axi_ad9671/axi_ad9671.v b/library/axi_ad9671/axi_ad9671.v new file mode 100755 index 000000000..5549dcbb6 --- /dev/null +++ b/library/axi_ad9671/axi_ad9671.v @@ -0,0 +1,425 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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_ad9671 ( + + // jesd interface + // rx_clk is (line-rate/40) + + rx_clk, + rx_data, + + // dma interface + + adc_clk, + adc_dwr, + adc_ddata, + adc_dsync, + adc_dovf, + adc_dunf, + + // axi interface + + s_axi_aclk, + s_axi_aresetn, + s_axi_awvalid, + s_axi_awaddr, + s_axi_awready, + s_axi_wvalid, + s_axi_wdata, + s_axi_wstrb, + s_axi_wready, + s_axi_bvalid, + s_axi_bresp, + s_axi_bready, + s_axi_arvalid, + s_axi_araddr, + s_axi_arready, + s_axi_rvalid, + s_axi_rresp, + s_axi_rdata, + s_axi_rready, + + // debug signals + + adc_mon_valid, + adc_mon_data); + + parameter PCORE_ID = 0; + parameter PCORE_DEVICE_TYPE = 0; + parameter PCORE_4L_2L_N = 1; + parameter PCORE_IODELAY_GROUP = "adc_if_delay_group"; + parameter C_S_AXI_MIN_SIZE = 32'hffff; + parameter C_BASEADDR = 32'hffffffff; + parameter C_HIGHADDR = 32'h00000000; + + // jesd interface + // rx_clk is the jesd clock (ref_clk/2) + + input rx_clk; + input [(64*PCORE_4L_2L_N)+63:0] rx_data; + + // dma interface + + output adc_clk; + output adc_dwr; + output [127:0] adc_ddata; + output adc_dsync; + input adc_dovf; + input adc_dunf; + + // axi interface + + input s_axi_aclk; + input s_axi_aresetn; + input s_axi_awvalid; + input [ 31:0] s_axi_awaddr; + output s_axi_awready; + input s_axi_wvalid; + input [ 31:0] s_axi_wdata; + input [ 3:0] s_axi_wstrb; + output s_axi_wready; + output s_axi_bvalid; + output [ 1:0] s_axi_bresp; + input s_axi_bready; + input s_axi_arvalid; + input [ 31:0] s_axi_araddr; + output s_axi_arready; + output s_axi_rvalid; + output [ 1:0] s_axi_rresp; + output [ 31:0] s_axi_rdata; + input s_axi_rready; + + // debug signals + + output adc_mon_valid; + output [127:0] adc_mon_data; + + // internal registers + + reg [ 2:0] adc_data_cnt = 'd0; + reg adc_dwr = 'd0; + reg adc_dsync = 'd0; + reg [127:0] adc_ddata = 'd0; + reg up_adc_status_pn_err = 'd0; + reg up_adc_status_pn_oos = 'd0; + reg up_adc_status_or = 'd0; + reg up_ack = 'd0; + reg [ 31:0] up_rdata = 'd0; + + // internal clocks & resets + + wire adc_rst; + wire up_rstn; + wire up_clk; + + // internal signals + + wire adc_status_s; + wire adc_valid_s; + wire [ 15:0] adc_data_s[7:0]; + wire [ 7:0] adc_or_s; + wire [ 7:0] adc_dfmt_valid_s; + wire [ 15:0] adc_dfmt_data_s[7:0]; + wire [ 7:0] adc_enable_s; + wire [ 7:0] up_adc_pn_err_s; + wire [ 7:0] up_adc_pn_oos_s; + wire [ 7:0] up_adc_or_s; + wire [ 31:0] up_adc_channel_rdata_s[7:0]; + wire [ 7:0] up_adc_channel_ack_s; + wire up_sel_s; + wire up_wr_s; + wire [ 13:0] up_addr_s; + wire [ 31:0] up_wdata_s; + wire [ 31:0] up_adc_common_rdata_s; + wire up_adc_common_ack_s; + + // signal name changes + + assign up_clk = s_axi_aclk; + assign up_rstn = s_axi_aresetn; + + // monitor signals + + assign adc_mon_valid = 1'b1; + assign adc_mon_data[ 15: 0] = adc_dfmt_data_s[0]; + assign adc_mon_data[ 31: 16] = adc_dfmt_data_s[1]; + assign adc_mon_data[ 47: 32] = adc_dfmt_data_s[2]; + assign adc_mon_data[ 63: 48] = adc_dfmt_data_s[3]; + assign adc_mon_data[ 79: 64] = adc_dfmt_data_s[4]; + assign adc_mon_data[ 95: 80] = adc_dfmt_data_s[5]; + assign adc_mon_data[111: 96] = adc_dfmt_data_s[6]; + assign adc_mon_data[127:112] = adc_dfmt_data_s[7]; + + // adc channels - dma interface + + always @(posedge adc_clk) begin + if (adc_dfmt_valid_s == 8'hff) begin + adc_data_cnt <= adc_data_cnt + 1'b1; + case (adc_enable_s) + 8'b11111111: begin + adc_dwr <= 1'b1; + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[7], + adc_dfmt_data_s[6], + adc_dfmt_data_s[5], + adc_dfmt_data_s[4], + adc_dfmt_data_s[3], + adc_dfmt_data_s[2], + adc_dfmt_data_s[1], + adc_dfmt_data_s[0]}; + end + 8'b10000000: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[0], adc_ddata[127:16]}; + end + 8'b01000000: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[1], adc_ddata[127:16]}; + end + 8'b00100000: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[2], adc_ddata[127:16]}; + end + 8'b00010000: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[3], adc_ddata[127:16]}; + end + 8'b00001000: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[4], adc_ddata[127:16]}; + end + 8'b00000100: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[5], adc_ddata[127:16]}; + end + 8'b00000010: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[6], adc_ddata[127:16]}; + end + 8'b00000001: begin + adc_dwr <= (& adc_data_cnt); + adc_dsync <= 1'b1; + adc_ddata <= {adc_dfmt_data_s[7], adc_ddata[127:16]}; + end + default: begin + adc_dwr <= 1'b1; + adc_dsync <= 1'b1; + adc_ddata <= {8{16'hdead}}; + end + endcase + end else begin + adc_data_cnt <= adc_data_cnt; + adc_dwr <= 1'b0; + adc_dsync <= 1'b0; + adc_ddata <= 128'd0; + end + end + + // processor read interface + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_adc_status_pn_err <= 'd0; + up_adc_status_pn_oos <= 'd0; + up_adc_status_or <= 'd0; + up_ack <= 'd0; + up_rdata <= 'd0; + end else begin + up_adc_status_pn_err <= | up_adc_pn_err_s; + up_adc_status_pn_oos <= | up_adc_pn_oos_s; + up_adc_status_or <= | up_adc_or_s; + up_ack <= up_adc_common_ack_s | (| up_adc_channel_ack_s); + up_rdata <= up_adc_common_rdata_s | + up_adc_channel_rdata_s[0] | + up_adc_channel_rdata_s[1] | + up_adc_channel_rdata_s[2] | + up_adc_channel_rdata_s[3] | + up_adc_channel_rdata_s[4] | + up_adc_channel_rdata_s[5] | + up_adc_channel_rdata_s[6] | + up_adc_channel_rdata_s[7]; + end + end + + // main (device interface) + + axi_ad9671_if #(.PCORE_4L_2L_N(PCORE_4L_2L_N)) i_if ( + .rx_clk (rx_clk), + .rx_data (rx_data), + .adc_clk (adc_clk), + .adc_rst (adc_rst), + .adc_valid (adc_valid_s), + .adc_data_a (adc_data_s[0]), + .adc_or_a (adc_or_s[0]), + .adc_data_b (adc_data_s[1]), + .adc_or_b (adc_or_s[1]), + .adc_data_c (adc_data_s[2]), + .adc_or_c (adc_or_s[2]), + .adc_data_d (adc_data_s[3]), + .adc_or_d (adc_or_s[3]), + .adc_data_e (adc_data_s[4]), + .adc_or_e (adc_or_s[4]), + .adc_data_f (adc_data_s[5]), + .adc_or_f (adc_or_s[5]), + .adc_data_g (adc_data_s[6]), + .adc_or_g (adc_or_s[6]), + .adc_data_h (adc_data_s[7]), + .adc_or_h (adc_or_s[7]), + .adc_status (adc_status_s)); + + // channels + + genvar n; + generate + for (n = 0; n < 8; n = n + 1) begin: g_channel + axi_ad9671_channel #(.CHID(n)) i_channel ( + .adc_clk (adc_clk), + .adc_rst (adc_rst), + .adc_valid (adc_valid_s), + .adc_data (adc_data_s[n]), + .adc_or (adc_or_s[n]), + .adc_dfmt_valid (adc_dfmt_valid_s[n]), + .adc_dfmt_data (adc_dfmt_data_s[n]), + .adc_enable (adc_enable_s[n]), + .up_adc_pn_err (up_adc_pn_err_s[n]), + .up_adc_pn_oos (up_adc_pn_oos_s[n]), + .up_adc_or (up_adc_or_s[n]), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_sel (up_sel_s), + .up_wr (up_wr_s), + .up_addr (up_addr_s), + .up_wdata (up_wdata_s), + .up_rdata (up_adc_channel_rdata_s[n]), + .up_ack (up_adc_channel_ack_s[n])); + end + endgenerate + + // common processor control + + up_adc_common #(.PCORE_ID(PCORE_ID)) i_up_adc_common ( + .mmcm_rst (), + .adc_clk (adc_clk), + .adc_rst (adc_rst), + .adc_r1_mode (), + .adc_ddr_edgesel (), + .adc_pin_mode (), + .adc_status (adc_status_s), + .adc_status_pn_err (up_adc_status_pn_err), + .adc_status_pn_oos (up_adc_status_pn_oos), + .adc_status_or (up_adc_status_or), + .adc_status_ovf (adc_dovf), + .adc_status_unf (adc_dunf), + .adc_clk_ratio (32'd1), + .delay_clk (1'b0), + .delay_rst (), + .delay_sel (), + .delay_rwn (), + .delay_addr (), + .delay_wdata (), + .delay_rdata (5'd0), + .delay_ack_t (1'b0), + .delay_locked (1'b0), + .drp_clk (1'd0), + .drp_rst (), + .drp_sel (), + .drp_wr (), + .drp_addr (), + .drp_wdata (), + .drp_rdata (16'd0), + .drp_ready (1'd0), + .drp_locked (1'd0), + .up_usr_chanmax (), + .adc_usr_chanmax (8'd7), + .dma_bw (32'd128), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_sel (up_sel_s), + .up_wr (up_wr_s), + .up_addr (up_addr_s), + .up_wdata (up_wdata_s), + .up_rdata (up_adc_common_rdata_s), + .up_ack (up_adc_common_ack_s)); + + // up bus interface + + up_axi #( + .PCORE_BASEADDR (C_BASEADDR), + .PCORE_HIGHADDR (C_HIGHADDR)) + i_up_axi ( + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_axi_awvalid (s_axi_awvalid), + .up_axi_awaddr (s_axi_awaddr), + .up_axi_awready (s_axi_awready), + .up_axi_wvalid (s_axi_wvalid), + .up_axi_wdata (s_axi_wdata), + .up_axi_wstrb (s_axi_wstrb), + .up_axi_wready (s_axi_wready), + .up_axi_bvalid (s_axi_bvalid), + .up_axi_bresp (s_axi_bresp), + .up_axi_bready (s_axi_bready), + .up_axi_arvalid (s_axi_arvalid), + .up_axi_araddr (s_axi_araddr), + .up_axi_arready (s_axi_arready), + .up_axi_rvalid (s_axi_rvalid), + .up_axi_rresp (s_axi_rresp), + .up_axi_rdata (s_axi_rdata), + .up_axi_rready (s_axi_rready), + .up_sel (up_sel_s), + .up_wr (up_wr_s), + .up_addr (up_addr_s), + .up_wdata (up_wdata_s), + .up_rdata (up_rdata), + .up_ack (up_ack)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_ad9671/axi_ad9671_channel.v b/library/axi_ad9671/axi_ad9671_channel.v new file mode 100755 index 000000000..efb122351 --- /dev/null +++ b/library/axi_ad9671/axi_ad9671_channel.v @@ -0,0 +1,182 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// ADC channel- + +`timescale 1ns/100ps + +module axi_ad9671_channel ( + + // adc interface + + adc_clk, + adc_rst, + adc_valid, + adc_data, + adc_or, + + // channel interface + + adc_dfmt_valid, + adc_dfmt_data, + adc_enable, + up_adc_pn_err, + up_adc_pn_oos, + up_adc_or, + + // processor interface + + up_rstn, + up_clk, + up_sel, + up_wr, + up_addr, + up_wdata, + up_rdata, + up_ack); + + // parameters + + parameter CHID = 0; + + // adc interface + + input adc_clk; + input adc_rst; + input adc_valid; + input [15:0] adc_data; + input adc_or; + + // channel interface + + output adc_dfmt_valid; + output [15:0] adc_dfmt_data; + output adc_enable; + output up_adc_pn_err; + output up_adc_pn_oos; + output up_adc_or; + + // processor interface + + input up_rstn; + input up_clk; + input up_sel; + input up_wr; + input [13:0] up_addr; + input [31:0] up_wdata; + output [31:0] up_rdata; + output up_ack; + + // internal signals + + wire adc_dfmt_se_s; + wire adc_dfmt_type_s; + wire adc_dfmt_enable_s; + wire adc_pn_type_s; + wire adc_pn_err_s; + wire adc_pn_oos_s; + + // instantiations + + axi_ad9671_pnmon i_pnmon ( + .adc_clk (adc_clk), + .adc_valid (adc_valid), + .adc_data (adc_data), + .adc_pn_oos (adc_pn_oos_s), + .adc_pn_err (adc_pn_err_s), + .adc_pn_type (adc_pn_type_s)); + + ad_datafmt #(.DATA_WIDTH(16)) i_ad_datafmt ( + .clk (adc_clk), + .valid (adc_valid), + .data (adc_data), + .valid_out (adc_dfmt_valid), + .data_out (adc_dfmt_data), + .dfmt_enable (adc_dfmt_enable_s), + .dfmt_type (adc_dfmt_type_s), + .dfmt_se (adc_dfmt_se_s)); + + up_adc_channel #(.PCORE_ADC_CHID(CHID)) i_up_adc_channel ( + .adc_clk (adc_clk), + .adc_rst (adc_rst), + .adc_enable (adc_enable), + .adc_pn_sel (), + .adc_iqcor_enb (), + .adc_dcfilt_enb (), + .adc_dfmt_se (adc_dfmt_se_s), + .adc_dfmt_type (adc_dfmt_type_s), + .adc_dfmt_enable (adc_dfmt_enable_s), + .adc_pn_type (adc_pn_type_s), + .adc_dcfilt_offset (), + .adc_dcfilt_coeff (), + .adc_iqcor_coeff_1 (), + .adc_iqcor_coeff_2 (), + .adc_pn_err (adc_pn_err_s), + .adc_pn_oos (adc_pn_oos_s), + .adc_or (adc_or), + .up_adc_pn_err (up_adc_pn_err), + .up_adc_pn_oos (up_adc_pn_oos), + .up_adc_or (up_adc_or), + .up_usr_datatype_be (), + .up_usr_datatype_signed (), + .up_usr_datatype_shift (), + .up_usr_datatype_total_bits (), + .up_usr_datatype_bits (), + .up_usr_decimation_m (), + .up_usr_decimation_n (), + .adc_usr_datatype_be (1'b0), + .adc_usr_datatype_signed (1'b1), + .adc_usr_datatype_shift (8'd0), + .adc_usr_datatype_total_bits (8'd16), + .adc_usr_datatype_bits (8'd16), + .adc_usr_decimation_m (16'd1), + .adc_usr_decimation_n (16'd1), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_sel (up_sel), + .up_wr (up_wr), + .up_addr (up_addr), + .up_wdata (up_wdata), + .up_rdata (up_rdata), + .up_ack (up_ack)); + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/library/axi_ad9671/axi_ad9671_if.v b/library/axi_ad9671/axi_ad9671_if.v new file mode 100755 index 000000000..b05003a6a --- /dev/null +++ b/library/axi_ad9671/axi_ad9671_if.v @@ -0,0 +1,158 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// This is the LVDS/DDR interface + +`timescale 1ns/100ps + +module axi_ad9671_if ( + + // jesd interface + // rx_clk is (line-rate/40) + + rx_clk, + rx_data, + + // adc data output + + adc_clk, + adc_rst, + adc_valid, + adc_data_a, + adc_or_a, + adc_data_b, + adc_or_b, + adc_data_c, + adc_or_c, + adc_data_d, + adc_or_d, + adc_data_e, + adc_or_e, + adc_data_f, + adc_or_f, + adc_data_g, + adc_or_g, + adc_data_h, + adc_or_h, + adc_status); + + // parameters + + parameter PCORE_4L_2L_N = 1; + + // jesd interface + // rx_clk is (line-rate/40) + + input rx_clk; + input [(64*PCORE_4L_2L_N)+63:0] rx_data; + + // adc data output + + output adc_clk; + input adc_rst; + output adc_valid; + output [ 15:0] adc_data_a; + output adc_or_a; + output [ 15:0] adc_data_b; + output adc_or_b; + output [ 15:0] adc_data_c; + output adc_or_c; + output [ 15:0] adc_data_d; + output adc_or_d; + output [ 15:0] adc_data_e; + output adc_or_e; + output [ 15:0] adc_data_f; + output adc_or_f; + output [ 15:0] adc_data_g; + output adc_or_g; + output [ 15:0] adc_data_h; + output adc_or_h; + output adc_status; + + // internal registers + + reg int_valid = 'd0; + reg [127:0] int_data = 'd0; + reg adc_status = 'd0; + + // adc clock & valid + + assign adc_clk = rx_clk; + assign adc_valid = int_valid; + + assign adc_or_a = 'd0; + assign adc_or_b = 'd0; + assign adc_or_c = 'd0; + assign adc_or_d = 'd0; + assign adc_or_e = 'd0; + assign adc_or_f = 'd0; + assign adc_or_g = 'd0; + assign adc_or_h = 'd0; + + assign adc_data_a = {int_data[ 7: 0], int_data[ 15: 8]}; + assign adc_data_b = {int_data[ 23: 16], int_data[ 31: 24]}; + assign adc_data_c = {int_data[ 39: 32], int_data[ 47: 40]}; + assign adc_data_d = {int_data[ 55: 48], int_data[ 63: 56]}; + assign adc_data_e = {int_data[ 71: 64], int_data[ 79: 72]}; + assign adc_data_f = {int_data[ 87: 80], int_data[ 95: 88]}; + assign adc_data_g = {int_data[103: 96], int_data[111:104]}; + assign adc_data_h = {int_data[119:112], int_data[127:120]}; + + always @(posedge rx_clk) begin + if (PCORE_4L_2L_N == 1'b1) begin + int_valid <= 1'b1; + int_data <= rx_data; + end else begin + int_valid <= ~int_valid; + int_data <= {rx_data[63:0], int_data[127:64]}; + end + end + + always @(posedge rx_clk) begin + if (adc_rst == 1'b1) begin + adc_status <= 1'b0; + end else begin + adc_status <= 1'b1; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/library/axi_ad9671/axi_ad9671_ip.tcl b/library/axi_ad9671/axi_ad9671_ip.tcl new file mode 100755 index 000000000..35b1da4e0 --- /dev/null +++ b/library/axi_ad9671/axi_ad9671_ip.tcl @@ -0,0 +1,26 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_ad9671 +adi_ip_files axi_ad9671 [list \ + "$ad_hdl_dir/library/common/ad_rst.v" \ + "$ad_hdl_dir/library/common/ad_datafmt.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ + "$ad_hdl_dir/library/common/up_xfer_status.v" \ + "$ad_hdl_dir/library/common/up_clock_mon.v" \ + "$ad_hdl_dir/library/common/up_drp_cntrl.v" \ + "$ad_hdl_dir/library/common/up_delay_cntrl.v" \ + "$ad_hdl_dir/library/common/up_adc_common.v" \ + "$ad_hdl_dir/library/common/up_adc_channel.v" \ + "axi_ad9671_pnmon.v" \ + "axi_ad9671_channel.v" \ + "axi_ad9671_if.v" \ + "axi_ad9671.v" ] + +adi_ip_properties axi_ad9671 + +ipx::save_core [ipx::current_core] + diff --git a/library/axi_ad9671/axi_ad9671_pnmon.v b/library/axi_ad9671/axi_ad9671_pnmon.v new file mode 100755 index 000000000..0497b3856 --- /dev/null +++ b/library/axi_ad9671/axi_ad9671_pnmon.v @@ -0,0 +1,251 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// PN monitors + +`timescale 1ns/100ps + +module axi_ad9671_pnmon ( + + // adc interface + + adc_clk, + adc_valid, + adc_data, + + // pn out of sync and error + + adc_pn_oos, + adc_pn_err, + + // processor interface PN9 (0x0), PN23 (0x1) + + adc_pn_type); + + // adc interface + + input adc_clk; + input adc_valid; + input [15:0] adc_data; + + // pn out of sync and error + + output adc_pn_oos; + output adc_pn_err; + + // processor interface PN9 (0x0), PN23 (0x1) + + input adc_pn_type; + + // internal registers + + reg adc_pn_en = 'd0; + reg [15:0] adc_data_d = 'd0; + reg [31:0] adc_pn_data = 'd0; + reg adc_pn_valid = 'd0; + reg adc_pn_match_d_1 = 'd0; + reg adc_pn_match_d_0 = 'd0; + reg adc_pn_match_z = 'd0; + reg adc_pn_err = 'd0; + reg [ 6:0] adc_pn_oos_count = 'd0; + reg adc_pn_oos = 'd0; + + // internal signals + + wire adc_pn_valid_s; + wire [31:0] adc_pn_data_in_s; + wire adc_pn_match_d_1_s; + wire adc_pn_match_d_0_s; + wire adc_pn_match_z_s; + wire adc_pn_match_s; + wire [31:0] adc_pn_data_s; + wire adc_pn_update_s; + wire adc_pn_err_s; + + // PN23 function + + function [31:0] pn23; + input [31:0] din; + reg [31:0] dout; + begin + dout[31] = din[22] ^ din[17]; + dout[30] = din[21] ^ din[16]; + dout[29] = din[20] ^ din[15]; + dout[28] = din[19] ^ din[14]; + dout[27] = din[18] ^ din[13]; + dout[26] = din[17] ^ din[12]; + dout[25] = din[16] ^ din[11]; + dout[24] = din[15] ^ din[10]; + dout[23] = din[14] ^ din[ 9]; + dout[22] = din[13] ^ din[ 8]; + dout[21] = din[12] ^ din[ 7]; + dout[20] = din[11] ^ din[ 6]; + dout[19] = din[10] ^ din[ 5]; + dout[18] = din[ 9] ^ din[ 4]; + dout[17] = din[ 8] ^ din[ 3]; + dout[16] = din[ 7] ^ din[ 2]; + dout[15] = din[ 6] ^ din[ 1]; + dout[14] = din[ 5] ^ din[ 0]; + dout[13] = din[ 4] ^ din[22] ^ din[17]; + dout[12] = din[ 3] ^ din[21] ^ din[16]; + dout[11] = din[ 2] ^ din[20] ^ din[15]; + dout[10] = din[ 1] ^ din[19] ^ din[14]; + dout[ 9] = din[ 0] ^ din[18] ^ din[13]; + dout[ 8] = din[22] ^ din[12]; + dout[ 7] = din[21] ^ din[11]; + dout[ 6] = din[20] ^ din[10]; + dout[ 5] = din[19] ^ din[ 9]; + dout[ 4] = din[18] ^ din[ 8]; + dout[ 3] = din[17] ^ din[ 7]; + dout[ 2] = din[16] ^ din[ 6]; + dout[ 1] = din[15] ^ din[ 5]; + dout[ 0] = din[14] ^ din[ 4]; + pn23 = dout; + end + endfunction + + // PN9 function + + function [31:0] pn9; + input [31:0] din; + reg [31:0] dout; + begin + dout[31] = din[ 8] ^ din[ 4]; + dout[30] = din[ 7] ^ din[ 3]; + dout[29] = din[ 6] ^ din[ 2]; + dout[28] = din[ 5] ^ din[ 1]; + dout[27] = din[ 4] ^ din[ 0]; + dout[26] = din[ 3] ^ din[ 8] ^ din[ 4]; + dout[25] = din[ 2] ^ din[ 7] ^ din[ 3]; + dout[24] = din[ 1] ^ din[ 6] ^ din[ 2]; + dout[23] = din[ 0] ^ din[ 5] ^ din[ 1]; + dout[22] = din[ 8] ^ din[ 0]; + dout[21] = din[ 7] ^ din[ 8] ^ din[ 4]; + dout[20] = din[ 6] ^ din[ 7] ^ din[ 3]; + dout[19] = din[ 5] ^ din[ 6] ^ din[ 2]; + dout[18] = din[ 4] ^ din[ 5] ^ din[ 1]; + dout[17] = din[ 3] ^ din[ 4] ^ din[ 0]; + dout[16] = din[ 2] ^ din[ 3] ^ din[ 8] ^ din[ 4]; + dout[15] = din[ 1] ^ din[ 2] ^ din[ 7] ^ din[ 3]; + dout[14] = din[ 0] ^ din[ 1] ^ din[ 6] ^ din[ 2]; + dout[13] = din[ 8] ^ din[ 0] ^ din[ 4] ^ din[ 5] ^ din[ 1]; + dout[12] = din[ 7] ^ din[ 8] ^ din[ 3] ^ din[ 0]; + dout[11] = din[ 6] ^ din[ 7] ^ din[ 2] ^ din[ 8] ^ din[ 4]; + dout[10] = din[ 5] ^ din[ 6] ^ din[ 1] ^ din[ 7] ^ din[ 3]; + dout[ 9] = din[ 4] ^ din[ 5] ^ din[ 0] ^ din[ 6] ^ din[ 2]; + dout[ 8] = din[ 3] ^ din[ 8] ^ din[ 5] ^ din[ 1]; + dout[ 7] = din[ 2] ^ din[ 4] ^ din[ 7] ^ din[ 0]; + dout[ 6] = din[ 1] ^ din[ 3] ^ din[ 6] ^ din[ 8] ^ din[ 4]; + dout[ 5] = din[ 0] ^ din[ 2] ^ din[ 5] ^ din[ 7] ^ din[ 3]; + dout[ 4] = din[ 8] ^ din[ 1] ^ din[ 6] ^ din[ 2]; + dout[ 3] = din[ 7] ^ din[ 0] ^ din[ 5] ^ din[ 1]; + dout[ 2] = din[ 6] ^ din[ 8] ^ din[ 0]; + dout[ 1] = din[ 5] ^ din[ 7] ^ din[ 8] ^ din[ 4]; + dout[ 0] = din[ 4] ^ din[ 6] ^ din[ 7] ^ din[ 3]; + pn9 = dout; + end + endfunction + + // pn sequence checking algorithm is commonly used in most applications. + // if oos is asserted (pn is out of sync): + // the next sequence is generated from the incoming data. + // if 16 sequences match consecutively, oos is cleared (de-asserted). + // if oos is de-asserted (pn is in sync) + // the next sequence is generated from the current sequence. + // if 64 sequences mismatch consecutively, oos is set (asserted). + // if oos is de-asserted, any spurious mismatches sets the error register. + // ideally, processor should make sure both oos == 0x0 and err == 0x0. + + assign adc_pn_valid_s = adc_valid & adc_pn_en; + assign adc_pn_data_in_s = {~adc_data[15], adc_data[14:0], ~adc_data_d[15], adc_data_d[14:0]}; + assign adc_pn_match_d_1_s = (adc_pn_data_in_s[31:16] == adc_pn_data[31:16]) ? 1'b1 : 1'b0; + assign adc_pn_match_d_0_s = (adc_pn_data_in_s[15: 0] == adc_pn_data[15: 0]) ? 1'b1 : 1'b0; + assign adc_pn_match_z_s = (adc_pn_data_in_s == 32'd0) ? 1'b0 : 1'b1; + assign adc_pn_match_s = adc_pn_match_d_1 & adc_pn_match_d_0 & adc_pn_match_z; + assign adc_pn_data_s = (adc_pn_oos == 1'b1) ? adc_pn_data_in_s : adc_pn_data; + assign adc_pn_update_s = ~(adc_pn_oos ^ adc_pn_match_s); + assign adc_pn_err_s = ~(adc_pn_oos | adc_pn_match_s); + + // pn running sequence + + always @(posedge adc_clk) begin + if (adc_valid == 1'b1) begin + adc_pn_en <= ~adc_pn_en; + adc_data_d <= adc_data; + end + end + + always @(posedge adc_clk) begin + if (adc_pn_valid_s == 1'b1) begin + if (adc_pn_type == 1'b0) begin + adc_pn_data <= pn9(adc_pn_data_s); + end else begin + adc_pn_data <= pn23(adc_pn_data_s); + end + end + end + + // pn oos and counters (64 to clear and set). + + always @(posedge adc_clk) begin + adc_pn_valid <= adc_pn_valid_s; + adc_pn_match_d_1 <= adc_pn_match_d_1_s; + adc_pn_match_d_0 <= adc_pn_match_d_0_s; + adc_pn_match_z <= adc_pn_match_z_s; + adc_pn_err <= adc_pn_valid & adc_pn_err_s; + if (adc_pn_valid == 1'b1) begin + if (adc_pn_update_s == 1'b1) begin + if (adc_pn_oos_count >= 16) begin + adc_pn_oos_count <= 'd0; + adc_pn_oos <= ~adc_pn_oos; + end else begin + adc_pn_oos_count <= adc_pn_oos_count + 1'b1; + adc_pn_oos <= adc_pn_oos; + end + end else begin + adc_pn_oos_count <= 'd0; + adc_pn_oos <= adc_pn_oos; + end + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** +