diff --git a/docs/projects/ad7405_fmc/ad7405_zed_cmos_diagram.svg b/docs/projects/ad7405_fmc/ad7405_zed_cmos_diagram.svg index 27a958a520..7b51e67a6b 100644 --- a/docs/projects/ad7405_fmc/ad7405_zed_cmos_diagram.svg +++ b/docs/projects/ad7405_fmc/ad7405_zed_cmos_diagram.svg @@ -2,15 +2,16 @@ + inkscape:current-layer="layer1" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> + + + + + + + + + + @@ -637,12 +693,12 @@ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.29167px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:0.858696;stroke-width:0.264583px" id="tspan3725">ZedBoard @@ -651,7 +707,7 @@ id="rect4488" width="7.645824" height="84.076927" - x="188.3338" + x="196.27119" y="92.270683" inkscape:export-xdpi="224.36" inkscape:export-ydpi="224.36" @@ -660,7 +716,7 @@ xml:space="preserve" style="font-style:normal;font-weight:normal;font-size:3.175px;line-height:0%;font-family:Arial;letter-spacing:0px;word-spacing:0px;display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;shape-rendering:crispEdges;enable-background:new" x="-156.85475" - y="193.74075" + y="201.67815" id="text4491" transform="rotate(-90)" inkscape:export-xdpi="224.36" @@ -669,7 +725,7 @@ sodipodi:role="line" id="tspan4493" x="-156.85475" - y="193.74075" + y="201.67815" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.63021px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial Bold';stroke-width:0.264583px">FMC CONNECTOR adc_clk 16 + width="40.022354" + height="12.661736" + x="107.17424" + y="119.35708" + inkscape:label="rect19131" /> util_dec256sinc24b + style="stroke-width:0.246507" + x="115.21629" + y="130.23114">sinc3 filter + width="55.060951" + height="24.375071" + x="99.62545" + y="110.57105" /> UTIL_DEC256SINC24B + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.15252px;font-family:Arial;-inkscape-font-specification:'Arial, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.264583" + x="117.3166" + y="116.88174">AXI_AD7405 + d="m 196.19734,125.47785 h -38.8062" + style="fill:none;stroke:#000000;stroke-width:0.538949;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1216-71);shape-rendering:crispEdges" /> adc_data ADC clock=20MHz + y="165.88783">ADC clock=50MHz + diff --git a/docs/projects/ad7405_fmc/ad7405_zed_lvds_diagram.svg b/docs/projects/ad7405_fmc/ad7405_zed_lvds_diagram.svg index 3360f08e58..421a1c3d92 100644 --- a/docs/projects/ad7405_fmc/ad7405_zed_lvds_diagram.svg +++ b/docs/projects/ad7405_fmc/ad7405_zed_lvds_diagram.svg @@ -7,8 +7,8 @@ viewBox="0 0 161.18021 164.51407" version="1.1" id="svg5" - sodipodi:docname="ad7405_zed_diff_block_diagram.svg" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + sodipodi:docname="ad7405_zed_lvds_diagram.svg" + inkscape:version="1.3 (0e150ed6c4, 2023-07-21)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" @@ -23,15 +23,17 @@ inkscape:pagecheckerboard="0" inkscape:document-units="mm" showgrid="false" - inkscape:zoom="11.844781" - inkscape:cx="219.37932" - inkscape:cy="518.92052" + inkscape:zoom="1.4805976" + inkscape:cx="414.02201" + inkscape:cy="324.19341" inkscape:window-width="1920" - inkscape:window-height="990" - inkscape:window-x="0" - inkscape:window-y="28" + inkscape:window-height="1122" + inkscape:window-x="-8" + inkscape:window-y="1342" inkscape:window-maximized="1" - inkscape:current-layer="layer1" /> + inkscape:current-layer="layer1" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> ADC clock=20MHz + y="177.97098">ADC clock=50MHz + diff --git a/docs/projects/ad7405_fmc/index.rst b/docs/projects/ad7405_fmc/index.rst index 9ad3f244b3..f3dc722437 100644 --- a/docs/projects/ad7405_fmc/index.rst +++ b/docs/projects/ad7405_fmc/index.rst @@ -10,11 +10,11 @@ The :adi:`EVAL-AD7405` is a full-featured evaluation board designed to allow the user to easily evaluate all features of the :adi:`AD7405` isolated analog-to-digital converter (ADC). -The provided HDL reference design supports the :adi:`AD7405` , :adi:`AD7403` -and :adi:`ADuM7701` devices. +The provided HDL reference design supports the :adi:`AD7405`, :adi:`AD7403` and +:adi:`ADuM7701` devices. One of the main differences between these devices is the type of the digital -data lines. In the case of :adi:`ADuM7701` and :adi:`AD7403`, it is -single-ended, and for :adi:`AD7405` is differential. +data lines. In the case of :adi:`ADuM7701` and :adi:`AD7403`, it is single-ended, +and for :adi:`AD7405` is differential. Supported boards ------------------------------------------------------------------------------- @@ -91,38 +91,11 @@ added to the base address from HDL (see more at :ref:`architecture`). ==================== =============== Instance Zynq/Microblaze ==================== =============== +axi_ad7405 0x44A0_0000 axi_ad7405_dma 0x44A3_0000 axi_adc_clkgen 0x44A4_0000 ==================== =============== -GPIOs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. list-table:: - :widths: 25 20 20 20 15 - :header-rows: 2 - - * - GPIO signal - - Direction - - HDL GPIO EMIO - - Software GPIO - - Software GPIO - * - - - (from FPGA view) - - - - Zynq-7000 - - Zynq MP - * - filter_reset - - INOUT - - 48 - - 102 - - 124 - * - decimation_ratio[15:0] - - INOUT - - 47:32 - - 101:86 - - 125:110 - Interrupts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -196,6 +169,9 @@ HDL related * - IP name - Source code link - Documentation link + * - AXI_AD7405 + - :git-hdl:`library/axi_ad7405` + - --- * - AXI_CLKGEN - :git-hdl:`library/axi_clkgen` - :ref:`axi_clkgen` @@ -223,11 +199,15 @@ HDL related * - UTIL_I2C_MIXER - :git-hdl:`library/util_i2c_mixer` - --- + * - UTIL_CDC + - :git-hdl:`library/util_cdc` + - --- Software related ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * No-OS driver at :git-no-os:`legacy/adum7701_fmc` +* Linux driver at :git-linux:`drivers/iio/adc/admc_adc.c` .. include:: ../common/more_information.rst diff --git a/library/axi_ad7405/Makefile b/library/axi_ad7405/Makefile new file mode 100644 index 0000000000..3331defc71 --- /dev/null +++ b/library/axi_ad7405/Makefile @@ -0,0 +1,32 @@ +#################################################################################### +## Copyright (c) 2024 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_ad7405 + +GENERIC_DEPS += ../common/ad_datafmt.v +GENERIC_DEPS += ../common/ad_edge_detect.v +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += ../common/up_adc_channel.v +GENERIC_DEPS += ../common/up_adc_common.v +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += ../common/up_clock_mon.v +GENERIC_DEPS += ../common/up_delay_cntrl.v +GENERIC_DEPS += ../common/up_xfer_cntrl.v +GENERIC_DEPS += ../common/up_xfer_status.v +GENERIC_DEPS += ../util_cdc/sync_data.v +GENERIC_DEPS += axi_ad7405.v +GENERIC_DEPS += ../common/util_dec256sinc24b.v + +XILINX_DEPS += ../xilinx/common/ad_dcfilter.v +XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc +XILINX_DEPS += ../xilinx/common/up_clock_mon_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_cntrl_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_status_constr.xdc +XILINX_DEPS += axi_ad7405_ip.tcl + +XILINX_LIB_DEPS += util_cdc + +include ../scripts/library.mk diff --git a/library/axi_ad7405/axi_ad7405.v b/library/axi_ad7405/axi_ad7405.v new file mode 100644 index 0000000000..79231fb3ed --- /dev/null +++ b/library/axi_ad7405/axi_ad7405.v @@ -0,0 +1,312 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2023-2024 Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/main/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_ad7405 ( + +input adc_data_in, /* input data to be filtered */ +output [15:0] adc_data_out, /* filtered output */ +output adc_data_en, + +// AXI Slave Memory Map + +input s_axi_aclk, +input s_axi_aresetn, +input s_axi_awvalid, +input [15:0] s_axi_awaddr, +input [ 2:0] s_axi_awprot, +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 [15:0] s_axi_araddr, +input [ 2:0] s_axi_arprot, +output s_axi_arready, +output s_axi_rvalid, +output [ 1:0] s_axi_rresp, +output [31:0] s_axi_rdata, +input s_axi_rready, + +input clk_in +); + +localparam [31:0] RD_RAW_CAP = 32'h2000; + +// internal registers + +reg up_wack = 1'b0; +reg up_rack = 1'b0; +reg [31:0] up_rdata = 32'b0; +reg [31:0] up_rdata_r; +reg up_rack_r; +reg up_wack_r; +wire [15:0] up_dec_rate; +wire [15:0] adc_dec_rate; + +wire adc_reset_s; +wire adc_clk_s; + +wire up_clk; +wire up_rstn; +wire up_rst; +wire up_rreq_s; +wire [13:0] up_raddr_s; +wire up_wreq_s; +wire [13:0] up_waddr_s; +wire [31:0] up_wdata_s; +wire [31:0] up_rdata_s[0:1]; +wire [ 1:0] up_rack_s; +wire [ 1:0] up_wack_s; + +wire [15:0] dma_data; +wire dma_dvalid; +wire [15:0] adc_data_out_s; + +wire adc_dfmt_enable_s; +wire adc_dfmt_type_s; +wire adc_dfmt_se_s; + +assign adc_clk_s = clk_in; +assign up_clk = s_axi_aclk; +assign up_rstn = s_axi_aresetn; + + // processor read interface + +integer j; + +always @(*) begin + up_rdata_r = 'h00; + up_rack_r = 'h00; + up_wack_r = 'h00; + for (j = 0; j <= 1; j=j+1) begin + up_rack_r = up_rack_r | up_rack_s[j]; + up_wack_r = up_wack_r | up_wack_s[j]; + up_rdata_r = up_rdata_r | up_rdata_s[j]; + end +end + +always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 0) begin + up_rdata <= 'd0; + up_rack <= 'd0; + up_wack <= 'd0; + end else begin + up_rdata <= up_rdata_r; + up_rack <= up_rack_r; + up_wack <= up_wack_r; + end +end + + sync_data #( + .NUM_OF_BITS (16), + .ASYNC_CLK (1) + ) i_cdc_status ( + .in_clk (up_clk), + .in_data (up_dec_rate), + .out_clk (adc_clk_s), + .out_data (adc_dec_rate)); + + up_adc_channel #( + .CHANNEL_ID(0) + ) i_up_adc_channel ( + .adc_clk (adc_clk_s), + .adc_rst (adc_reset_s), + .adc_enable (), + .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_dcfilt_offset (), + .adc_dcfilt_coeff (), + .adc_iqcor_coeff_1 (), + .adc_iqcor_coeff_2 (), + .adc_pnseq_sel (), + .adc_data_sel (), + .adc_pn_err (1'b0), + .adc_pn_oos (1'b0), + .adc_or (1'b0), + .adc_read_data ({16'd0,adc_data_out}), + .adc_status_header(), + .adc_crc_err(), + .up_adc_pn_err (), + .up_adc_pn_oos (), + .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 (up_dec_rate), + .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 (up_dec_rate), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s[0]), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s[0]), + .up_rack (up_rack_s[0])); + + ad_datafmt #( + .DATA_WIDTH (16), + .BITS_PER_SAMPLE (16) + ) i_datafmt ( + .clk (adc_clk_s), + .valid (1'b1), + .data (adc_data_out_s[15:0]), + .valid_out (dma_dvalid), + .data_out (dma_data[15:0]), + .dfmt_enable (adc_dfmt_enable_s), + .dfmt_type (adc_dfmt_type_s), + .dfmt_se (adc_dfmt_se_s)); + + util_dec256sinc24b #( + ) i_util_dec256sinc24b_interface ( + .mclk1 (adc_clk_s), + .reset (adc_reset_s), + .mdata1 (adc_data_in), + .DATA (adc_data_out_s), + .data_en (adc_data_en), + .dec_rate (adc_dec_rate)); + + assign adc_data_out = dma_data[15:0]; + + up_adc_common #( + .CONFIG (RD_RAW_CAP) + ) i_up_adc_common ( + .mmcm_rst (), + .adc_clk (adc_clk_s), + .adc_rst (adc_reset_s), + .adc_r1_mode (), + .adc_ddr_edgesel (), + .adc_pin_mode (), + .adc_status (), + .adc_sync_status (1'b1), + .adc_status_ovf (1'b0), + .adc_clk_ratio (), + .adc_start_code (), + .adc_sref_sync (), + .adc_sync (), + .adc_ext_sync_arm (), + .adc_ext_sync_disarm (), + .adc_ext_sync_manual_req (), + .adc_num_lanes (), + .adc_custom_control (), + .adc_crc_enable (), + .adc_sdr_ddr_n (), + .adc_symb_op (), + .adc_symb_8_16b (), + .up_pps_rcounter (), + .up_pps_status (), + .up_pps_irq_mask (), + .up_adc_r1_mode (), + .up_status_pn_err (), + .up_status_pn_oos (), + .up_status_or (), + .up_drp_sel (), + .up_drp_wr (), + .up_drp_addr (), + .up_drp_wdata (), + .up_drp_rdata (), + .up_drp_ready (), + .up_drp_locked (1'b1), + .adc_config_wr (), + .adc_config_ctrl (), + .adc_config_rd ({16'd0, adc_data_out}), + .adc_ctrl_status (1'b1), + .up_adc_gpio_in (), + .up_adc_gpio_out (), + .up_adc_ce (), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s[1]), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s[1]), + .up_rack (up_rack_s[1])); + +// up bus interface + + up_axi #( + .AXI_ADDRESS_WIDTH (16) +) 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_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata), + .up_rack (up_rack)); + +endmodule diff --git a/library/axi_ad7405/axi_ad7405_ip.tcl b/library/axi_ad7405/axi_ad7405_ip.tcl new file mode 100644 index 0000000000..74f493cbe5 --- /dev/null +++ b/library/axi_ad7405/axi_ad7405_ip.tcl @@ -0,0 +1,39 @@ +############################################################################### +## Copyright (C) 2024 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +source ../../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl + +global VIVADO_IP_LIBRARY + +adi_ip_create axi_ad7405 + +adi_ip_files axi_ad7405 [list \ + "$ad_hdl_dir/library/common/ad_edge_detect.v" \ + "$ad_hdl_dir/library/common/ad_rst.v" \ + "$ad_hdl_dir/library/common/up_axi.v" \ + "$ad_hdl_dir/library/xilinx/common/ad_dcfilter.v" \ + "$ad_hdl_dir/library/common/ad_datafmt.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_delay_cntrl.v" \ + "$ad_hdl_dir/library/common/up_adc_channel.v" \ + "$ad_hdl_dir/library/common/up_adc_common.v" \ + "$ad_hdl_dir/library/util_cdc/sync_data.v" \ + "$ad_hdl_dir/library/util_cdc/sync_bits.v" \ + "$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/ad_rst_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/up_xfer_status_constr.xdc" \ + "$ad_hdl_dir/library/xilinx/common/up_clock_mon_constr.xdc" \ + "$ad_hdl_dir/library/common/util_dec256sinc24b.v" \ + "axi_ad7405.v" ] + +adi_ip_properties axi_ad7405 + +set cc [ipx::current_core] + +ipx::create_xgui_files $cc +ipx::save_core $cc diff --git a/library/common/util_dec256sinc24b.v b/library/common/util_dec256sinc24b.v index 9bdbe374f7..882140e42e 100644 --- a/library/common/util_dec256sinc24b.v +++ b/library/common/util_dec256sinc24b.v @@ -36,170 +36,146 @@ `timescale 1ns/100ps module util_dec256sinc24b ( - - input clk, /* used to clk filter */ - input reset, /* used to reset filter */ - input data_in, /* input data to be filtered */ - output reg [15:0] data_out, /* filtered output */ - output reg data_en, - input [15:0] dec_rate + input mclk1, /* used to clk filter */ + input reset, /* used to reGset filter */ + input mdata1, /* input data to be filtered */ + output reg [15:0] DATA, /* filtered output */ + output reg data_en, + input [15:0] dec_rate ); - - /* Data is read on positive clk edge */ - - reg [36:0] data_int = 37'h0; - reg [36:0] acc1 = 37'h0; - reg [36:0] acc2 = 37'h0; - reg [36:0] acc3 = 37'h0; - reg [36:0] acc3_d = 37'h0; - reg [36:0] diff1_d = 37'h0; - reg [36:0] diff2_d = 37'h0; - reg [15:0] word_count = 16'h0; - reg word_en = 1'b0; - reg enable = 1'b0; - - wire [36:0] acc1_s; - wire [36:0] acc2_s; - wire [36:0] acc3_s; - wire [36:0] diff1_s; - wire [36:0] diff2_s; - wire [36:0] diff3_s; - - /* Perform the Sinc action */ - - always @(data_in) begin - if (data_in==0) - data_int <= 37'd0; - else /* change 0 to a -1 for twos complement */ - data_int <= 37'd1; - end - - /* Accumulator (Integrator) Perform the accumulation (IIR) at the speed of - * the modulator. Z = one sample delay MCLKOUT = modulators conversion - * bit rate */ - - always @(negedge clk) begin - if (reset == 1'b1) begin +/* Data is read on positive clk edge */ + reg [36:0] ip_data1; + reg [36:0] acc1; + reg [36:0] acc2; + reg [36:0] acc3; + reg [36:0] acc3_d2; + reg [36:0] diff1; + reg [36:0] diff2; + reg [36:0] diff3; + reg [36:0] diff1_d; + reg [36:0] diff2_d; + reg [15:0] word_count; + reg word_clk; + reg enable; + + /*Perform the Sinc action*/ + always @ (mdata1) + if(mdata1==0) + ip_data1 <= 37'd0; + /* change 0 to a -1 for twos complement*/ + else + ip_data1 <= 37'd1; + + /*Accumulator (Integrator) + Perform the accumulation (IIR) at the speed of the modulator. + Z = one sample delay MCLKOUT = modulators conversion bit rate */ + + always @ (negedge mclk1, posedge reset) begin + if (reset) begin /* initialize acc registers on reset */ acc1 <= 37'd0; acc2 <= 37'd0; acc3 <= 37'd0; end else begin - /* perform accumulation process */ - acc1 <= acc1_s; - acc2 <= acc2_s; - acc3 <= acc3_s; + /*perform accumulation process */ + acc1 <= acc1 + ip_data1; + acc2 <= acc2 + acc1; + acc3 <= acc3 + acc2; end end - assign acc1_s = acc1 + data_int; - assign acc2_s = acc2 + acc1; - assign acc3_s = acc3 + acc2; - - /* decimation stage (MCLKOUT/WORD_CLK) */ - always @(posedge clk) begin - if (reset == 1'b1) begin + /*decimation stage (MCLKOUT/WORD_CLK) */ + always @ (posedge mclk1, posedge reset) begin + if (reset) + word_count <= 16'd0; + else begin + if ( word_count == dec_rate - 1 ) word_count <= 16'd0; - end else begin - if (word_count == (dec_rate - 1)) - word_count <= 16'd0; - else - word_count <= word_count + 16'b1; + else + word_count <= word_count + 16'b1; end end - always @(posedge clk) begin - if (reset == 1'b1) begin - word_en <= 1'b0; - end else begin - if (word_count == (dec_rate/2 - 1)) - word_en <= 1'b1; - else - word_en <= 1'b0; + always @ ( posedge mclk1, posedge reset ) begin + if ( reset ) + word_clk <= 1'b0; + else begin if ( word_count == dec_rate/2 - 1 ) + word_clk <= 1'b1; + else if ( word_count == dec_rate - 1 ) + word_clk <= 1'b0; end end - /* Differentiator (including decimation stage) - * Perform the differentiation stage (FIR) at a lower speed. - * Z = one sample delay WORD_EN = output word rate */ + /*Differentiator (including decimation stage) + Perform the differentiation stage (FIR) at a lower speed. + Z = one sample delay WORD_CLK = output word rate */ - always @(posedge clk) begin - if (reset == 1'b1) begin + always @ (posedge word_clk, posedge reset) begin + if(reset) begin + acc3_d2 <= 37'd0; diff1_d <= 37'd0; diff2_d <= 37'd0; - acc3_d <= 37'b0; - end else if (word_en == 1'b1) begin - acc3_d <= acc3; - diff1_d <= diff1_s; - diff2_d <= diff2_s; + diff1 <= 37'd0; + diff2 <= 37'd0; + diff3 <= 37'd0; + end else begin + diff1 <= acc3 - acc3_d2; + diff2 <= diff1 - diff1_d; + diff3 <= diff2 - diff2_d; + acc3_d2 <= acc3; + diff1_d <= diff1; + diff2_d <= diff2; end end - assign diff1_s = acc3_s - acc3; - assign diff2_s = diff1_s - diff1_d; - assign diff3_s = diff2_s - diff2_d; - /* Clock the Sinc output into an output register - * WORD_EN = output word rate */ - - always @(posedge clk) begin - if (word_en == 1'b1) begin - case (dec_rate) - - 16'd32: begin - data_out <= (diff3_s[15:0] == 16'h8000) ? 16'hFFFF : {diff3_s[14:0], 1'b0}; - end - - 16'd64: begin - data_out <= (diff3_s[18:2] == 17'h10000) ? 16'hFFFF : diff3_s[17:2]; - end - - 16'd128: begin - data_out <= (diff3_s[21:5] == 17'h10000) ? 16'hFFFF : diff3_s[20:5]; - end - - 16'd256: begin - data_out <= (diff3_s[24:8] == 17'h10000) ? 16'hFFFF : diff3_s[23:8]; - end - - 16'd512: begin - data_out <= (diff3_s[27:11] == 17'h10000) ? 16'hFFFF : diff3_s[26:11]; - end - - 16'd1024: begin - data_out <= (diff3_s[30:14] == 17'h10000) ? 16'hFFFF : diff3_s[29:14]; - end - - 16'd2048: begin - data_out <= (diff3_s[33:17] == 17'h10000) ? 16'hFFFF : diff3_s[32:17]; - end - - 16'd4096: begin - data_out <= (diff3_s[36:20] == 17'h10000) ? 16'hFFFF : diff3_s[35:20]; - end - - default:begin - data_out <= (diff3_s[24:8] == 17'h10000) ? 16'hFFFF : diff3_s[23:8]; - end - endcase - end + /* Clock the Sinc output into an output register WORD_CLK = output word rate */ + + always @ ( posedge word_clk ) begin + case ( dec_rate ) + 16'd32: begin + DATA <= (diff3[15:0] == 16'h8000) ? 16'hFFFF : {diff3[14:0], 1'b0}; + end + 16'd64: begin + DATA <= (diff3[18:2] == 17'h10000) ? 16'hFFFF : diff3[17:2]; + end + 16'd128: begin + DATA <= (diff3[21:5] == 17'h10000) ? 16'hFFFF : diff3[20:5]; + end + 16'd256: begin + DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[23:8]; + end + 16'd512: begin + DATA <= (diff3[27:11] == 17'h10000) ? 16'hFFFF : diff3[26:11]; + end + 16'd1024: begin + DATA <= (diff3[30:14] == 17'h10000) ? 16'hFFFF : diff3[29:14]; + end + 16'd2048: begin + DATA <= (diff3[33:17] == 17'h10000) ? 16'hFFFF : diff3[32:17]; + end + 16'd4096: begin + DATA <= (diff3[36:20] == 17'h10000) ? 16'hFFFF : diff3[35:20]; + end + default: begin + DATA <= (diff3[24:8] == 17'h10000) ? 16'hFFFF : diff3[23:8]; + end + endcase end - /* Synchronize Data Output */ - - always @(posedge clk) begin - if (reset == 1'b1) begin + /* Synchronize Data Output*/ + always@ ( posedge mclk1, posedge reset ) begin + if ( reset ) begin data_en <= 1'b0; enable <= 1'b1; end else begin - if ((word_count == (dec_rate/2 - 1)) && (enable == 1'b1)) begin + if ( (word_count == dec_rate/2 - 1) && enable ) begin data_en <= 1'b1; enable <= 1'b0; - end else if ((word_count == (dec_rate - 1)) && (enable == 1'b0)) begin + end else if ( (word_count == dec_rate - 1) && ~enable ) begin data_en <= 1'b0; enable <= 1'b1; end else data_en <= 1'b0; end end - endmodule diff --git a/library/util_dec256sinc24b/util_dec256sinc24b_ip.tcl b/library/util_dec256sinc24b/util_dec256sinc24b_ip.tcl index cbdb869fe8..57bc5de5dd 100644 --- a/library/util_dec256sinc24b/util_dec256sinc24b_ip.tcl +++ b/library/util_dec256sinc24b/util_dec256sinc24b_ip.tcl @@ -17,4 +17,3 @@ ipx::infer_bus_interface clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core] ipx::infer_bus_interface reset xilinx.com:signal:reset_rtl:1.0 [ipx::current_core] ipx::save_core [ipx::current_core] - diff --git a/projects/ad7405_fmc/common/ad7405_bd.tcl b/projects/ad7405_fmc/common/ad7405_bd.tcl index 0b535d1e69..4ae006425e 100644 --- a/projects/ad7405_fmc/common/ad7405_bd.tcl +++ b/projects/ad7405_fmc/common/ad7405_bd.tcl @@ -6,46 +6,48 @@ create_bd_port -dir O adc_clk create_bd_port -dir I adc_data -create_bd_port -dir I -from 15 -to 0 filter_decimation_ratio -create_bd_port -dir I filter_reset - -ad_ip_instance util_dec256sinc24b sync3 - # ADC's DMA ad_ip_instance axi_dmac axi_ad7405_dma ad_ip_parameter axi_ad7405_dma CONFIG.DMA_TYPE_SRC 2 ad_ip_parameter axi_ad7405_dma CONFIG.DMA_TYPE_DEST 0 ad_ip_parameter axi_ad7405_dma CONFIG.CYCLIC 0 -ad_ip_parameter axi_ad7405_dma CONFIG.SYNC_TRANSFER_START 0 +ad_ip_parameter axi_ad7405_dma CONFIG.SYNC_TRANSFER_START 1 ad_ip_parameter axi_ad7405_dma CONFIG.AXI_SLICE_SRC 0 ad_ip_parameter axi_ad7405_dma CONFIG.AXI_SLICE_DEST 1 ad_ip_parameter axi_ad7405_dma CONFIG.DMA_2D_TRANSFER 0 ad_ip_parameter axi_ad7405_dma CONFIG.DMA_DATA_WIDTH_SRC 16 ad_ip_parameter axi_ad7405_dma CONFIG.DMA_DATA_WIDTH_DEST 64 -# MCLK generation 50 MHz +# MCLK generation 40 MHz ad_ip_instance axi_clkgen axi_adc_clkgen ad_ip_parameter axi_adc_clkgen CONFIG.VCO_DIV 1 ad_ip_parameter axi_adc_clkgen CONFIG.VCO_MUL 10 -ad_ip_parameter axi_adc_clkgen CONFIG.CLK0_DIV 20 +ad_ip_parameter axi_adc_clkgen CONFIG.CLK0_DIV 25 + +ad_ip_instance axi_ad7405 axi_ad7405 ad_connect adc_clk axi_adc_clkgen/clk_0 ad_connect sys_cpu_clk axi_adc_clkgen/clk -ad_connect sync3/clk axi_adc_clkgen/clk_0 +ad_connect axi_ad7405/clk_in axi_adc_clkgen/clk_0 ad_connect axi_ad7405_dma/fifo_wr_clk axi_adc_clkgen/clk_0 -ad_connect filter_reset sync3/reset -ad_connect adc_data sync3/data_in -ad_connect sync3/data_out axi_ad7405_dma/fifo_wr_din -ad_connect sync3/data_en axi_ad7405_dma/fifo_wr_en -ad_connect filter_decimation_ratio sync3/dec_rate +ad_connect adc_data axi_ad7405/adc_data_in +ad_connect axi_ad7405/adc_data_out axi_ad7405_dma/fifo_wr_din +ad_connect axi_ad7405/adc_data_en axi_ad7405_dma/fifo_wr_en +# interconnect + +ad_cpu_interconnect 0x44a00000 axi_ad7405 ad_cpu_interconnect 0x44a30000 axi_ad7405_dma ad_cpu_interconnect 0x44a40000 axi_adc_clkgen +# memory interconnect + ad_mem_hp2_interconnect sys_cpu_clk sys_ps7/S_AXI_HP2 ad_mem_hp2_interconnect sys_cpu_clk axi_ad7405_dma/m_dest_axi +# interrupt + ad_cpu_interrupt "ps-13" "mb-13" axi_ad7405_dma/irq diff --git a/projects/ad7405_fmc/zed/Makefile b/projects/ad7405_fmc/zed/Makefile index 514b453e74..a60f3a342f 100644 --- a/projects/ad7405_fmc/zed/Makefile +++ b/projects/ad7405_fmc/zed/Makefile @@ -13,7 +13,9 @@ M_DEPS += ../../scripts/adi_pd.tcl M_DEPS += ../../common/zed/zed_system_constr.xdc M_DEPS += ../../common/zed/zed_system_bd.tcl M_DEPS += ../../../library/common/ad_iobuf.v +M_DEPS += ../../../library/util_cdc/sync_data.v +LIB_DEPS += axi_ad7405 LIB_DEPS += axi_clkgen LIB_DEPS += axi_dmac LIB_DEPS += axi_hdmi_tx @@ -21,7 +23,6 @@ LIB_DEPS += axi_i2s_adi LIB_DEPS += axi_spdif_tx LIB_DEPS += axi_sysid LIB_DEPS += sysid_rom -LIB_DEPS += util_dec256sinc24b LIB_DEPS += util_i2c_mixer include ../../scripts/project-xilinx.mk diff --git a/projects/ad7405_fmc/zed/system_constr_cmos.xdc b/projects/ad7405_fmc/zed/system_constr_cmos.xdc index 03546ee2f2..232032102b 100644 --- a/projects/ad7405_fmc/zed/system_constr_cmos.xdc +++ b/projects/ad7405_fmc/zed/system_constr_cmos.xdc @@ -5,3 +5,11 @@ set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS25} [get_ports adc_clk] ; ## G6 FMC_LA00_CC_P set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS25} [get_ports adc_data] ; ## G7 FMC_LA00_CC_N + +set input_clock mmcm_clk_0_s +set input_clock_period 20.000; # Period of input clock +set dv_bre 10.000; # Data valid before the rising clock edge +set dv_are 3.000 +set input_ports adc_data +set_input_delay -clock $input_clock -max [expr $input_clock_period - $dv_bre] [get_ports $input_ports]; +set_input_delay -clock $input_clock -min $dv_are [get_ports $input_ports]; diff --git a/projects/ad7405_fmc/zed/system_top_cmos.v b/projects/ad7405_fmc/zed/system_top_cmos.v index e2b271c348..86cca2059e 100644 --- a/projects/ad7405_fmc/zed/system_top_cmos.v +++ b/projects/ad7405_fmc/zed/system_top_cmos.v @@ -92,8 +92,6 @@ module system_top ( wire [63:0] gpio_i; wire [63:0] gpio_o; wire [63:0] gpio_t; - wire [15:0] decimation_ratio; - wire filter_reset; wire [ 1:0] iic_mux_scl_i_s; wire [ 1:0] iic_mux_scl_o_s; wire iic_mux_scl_t_s; @@ -103,7 +101,7 @@ module system_top ( // instantiations - assign gpio_i[63:49] = 15'b0; + assign gpio_i[63:32] = 15'b0; ad_iobuf #( .DATA_WIDTH(32) @@ -113,22 +111,6 @@ module system_top ( .dio_o(gpio_i[31:0]), .dio_p(gpio_bd)); - ad_iobuf #( - .DATA_WIDTH(1) - ) i_iobuf_filter_reset ( - .dio_t(gpio_t[48]), - .dio_i(gpio_o[48]), - .dio_o(gpio_i[48]), - .dio_p(filter_reset)); - - ad_iobuf #( - .DATA_WIDTH(16) - ) i_iobuf_dec_ratio ( - .dio_t(gpio_t[47:32]), - .dio_i(gpio_o[47:32]), - .dio_o(gpio_i[47:32]), - .dio_p(decimation_ratio)); - ad_iobuf #( .DATA_WIDTH(2) ) i_iic_mux_scl ( @@ -208,8 +190,6 @@ module system_top ( .spi1_sdo_o (), .adc_clk (adc_clk), .adc_data (adc_data), - .filter_decimation_ratio (decimation_ratio), - .filter_reset (filter_reset), .otg_vbusoc (otg_vbusoc), .spdif (spdif)); diff --git a/projects/ad7405_fmc/zed/system_top_lvds.v b/projects/ad7405_fmc/zed/system_top_lvds.v index e94808e8e3..c48bc64b3f 100644 --- a/projects/ad7405_fmc/zed/system_top_lvds.v +++ b/projects/ad7405_fmc/zed/system_top_lvds.v @@ -96,8 +96,6 @@ module system_top ( wire [63:0] gpio_i; wire [63:0] gpio_o; wire [63:0] gpio_t; - wire [15:0] decimation_ratio; - wire filter_reset; wire [ 1:0] iic_mux_scl_i_s; wire [ 1:0] iic_mux_scl_o_s; wire iic_mux_scl_t_s; @@ -105,6 +103,8 @@ module system_top ( wire [ 1:0] iic_mux_sda_o_s; wire iic_mux_sda_t_s; + assign gpio_i[63:32] = gpio_o[63:32] ; + // instantiations OBUFDS i_adc_clk_obuf ( @@ -117,8 +117,6 @@ module system_top ( .IB (adc_data_n), .O (adc_data_s)); - assign gpio_i[63:49] = 15'b0; - ad_iobuf #( .DATA_WIDTH(32) ) i_iobuf ( @@ -127,22 +125,6 @@ module system_top ( .dio_o(gpio_i[31:0]), .dio_p(gpio_bd)); - ad_iobuf #( - .DATA_WIDTH(1) - ) i_iobuf_filter_reset ( - .dio_t(gpio_t[48]), - .dio_i(gpio_o[48]), - .dio_o(gpio_i[48]), - .dio_p(filter_reset)); - - ad_iobuf #( - .DATA_WIDTH(16) - ) i_iobuf_dec_ratio ( - .dio_t(gpio_t[47:32]), - .dio_i(gpio_o[47:32]), - .dio_o(gpio_i[47:32]), - .dio_p(decimation_ratio)); - ad_iobuf #( .DATA_WIDTH(2) ) i_iic_mux_scl ( @@ -222,8 +204,6 @@ module system_top ( .spi1_sdo_o (), .adc_clk (adc_clk_s), .adc_data (adc_data_s), - .filter_decimation_ratio (decimation_ratio), - .filter_reset (filter_reset), .otg_vbusoc (otg_vbusoc), .spdif (spdif));