From 41f4d392c222cf628fe90ee8542da95b70ee28e1 Mon Sep 17 00:00:00 2001 From: PopPaul2021 Date: Mon, 20 Feb 2023 14:33:45 +0200 Subject: [PATCH 1/3] library/common: Added DAC custom read/write interface in up_dac_common. The DAC common regmap was updated with 3 registers(rd/wr/ctrl) and 1 interface status flag for converters with custom control interface. --- docs/regmap/adi_regmap_dac.txt | 55 ++++++++++++++++++ library/axi_ad5766/axi_ad5766.v | 4 ++ library/axi_ad9122/axi_ad9122_core.v | 4 ++ library/axi_ad9361/axi_ad9361_tx.v | 4 ++ library/axi_ad9739a/axi_ad9739a_core.v | 4 ++ library/axi_ad9783/axi_ad9783_core.v | 4 ++ library/axi_ad9963/axi_ad9963_tx.v | 4 ++ library/axi_adrv9001/axi_adrv9001_tx.v | 4 ++ library/common/up_dac_common.v | 56 +++++++++++++++---- .../ad_ip_jesd204_tpl_dac_regmap.v | 4 ++ 10 files changed, 132 insertions(+), 11 deletions(-) diff --git a/docs/regmap/adi_regmap_dac.txt b/docs/regmap/adi_regmap_dac.txt index b5b95aa2e8..6386ed022c 100644 --- a/docs/regmap/adi_regmap_dac.txt +++ b/docs/regmap/adi_regmap_dac.txt @@ -378,12 +378,51 @@ ENDFIELD ############################################################################################ ############################################################################################ +REG +0x0020 +REG_DAC_CUSTOM_RD +DAC Read Configuration Data +ENDREG + +FIELD +[31:0] 0x00000000 +DAC_CUSTOM_RD[31:0] +RO +Custom Read of the available registers. +ENDFIELD + +############################################################################################ +############################################################################################ + +REG +0x0021 +REG_DAC_CUSTOM_WR +DAC Write Configuration Data +ENDREG + +FIELD +[31:0] 0x00000000 +DAC_CUSTOM_WR[31:0] +RW +Custom Write of the available registers. +ENDFIELD + +############################################################################################ +############################################################################################ + REG 0x0022 REG_UI_STATUS User Interface Status ENDREG +FIELD +[4] 0x0 +IF_BUSY +RO +Interface busy. If set, indicates that the data interface is busy. +ENDFIELD + FIELD [1] 0x0 UI_OVF @@ -405,6 +444,22 @@ ENDFIELD ############################################################################################ ############################################################################################ +REG +0x0023 +REG_DAC_CUSTOM_CTRL +DAC Control Configuration Data +ENDREG + +FIELD +[31:0] 0x00000000 +DAC_CUSTOM_CTRL[31:0] +RW +Custom Control of the available registers. +ENDFIELD + +############################################################################################ +############################################################################################ + REG 0x0028 REG_USR_CNTRL_1 diff --git a/library/axi_ad5766/axi_ad5766.v b/library/axi_ad5766/axi_ad5766.v index a3abaf4d6d..172eabeed8 100644 --- a/library/axi_ad5766/axi_ad5766.v +++ b/library/axi_ad5766/axi_ad5766.v @@ -363,6 +363,10 @@ module axi_ad5766 #( .dac_sync (), .dac_frame (), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/axi_ad9122/axi_ad9122_core.v b/library/axi_ad9122/axi_ad9122_core.v index 5be766ae59..4b701488bc 100644 --- a/library/axi_ad9122/axi_ad9122_core.v +++ b/library/axi_ad9122/axi_ad9122_core.v @@ -232,6 +232,10 @@ module axi_ad9122_core #( .dac_sync (dac_sync_out), .dac_frame (dac_frame_s), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/axi_ad9361/axi_ad9361_tx.v b/library/axi_ad9361/axi_ad9361_tx.v index ac0232ecf1..07c3008d42 100644 --- a/library/axi_ad9361/axi_ad9361_tx.v +++ b/library/axi_ad9361/axi_ad9361_tx.v @@ -385,6 +385,10 @@ module axi_ad9361_tx #( .dac_sync (dac_sync), .dac_frame (), .dac_clksel (dac_clksel), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (dac_r1_mode), diff --git a/library/axi_ad9739a/axi_ad9739a_core.v b/library/axi_ad9739a/axi_ad9739a_core.v index 6ab99833cf..3a31641f03 100644 --- a/library/axi_ad9739a/axi_ad9739a_core.v +++ b/library/axi_ad9739a/axi_ad9739a_core.v @@ -179,6 +179,10 @@ module axi_ad9739a_core #( .dac_sync (dac_sync_s), .dac_frame (), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/axi_ad9783/axi_ad9783_core.v b/library/axi_ad9783/axi_ad9783_core.v index 3f99661ffe..749c7cb167 100755 --- a/library/axi_ad9783/axi_ad9783_core.v +++ b/library/axi_ad9783/axi_ad9783_core.v @@ -196,6 +196,10 @@ module axi_ad9783_core #( .dac_sync (dac_sync_s), .dac_frame (), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/axi_ad9963/axi_ad9963_tx.v b/library/axi_ad9963/axi_ad9963_tx.v index 36b7e421f8..a428345e9b 100644 --- a/library/axi_ad9963/axi_ad9963_tx.v +++ b/library/axi_ad9963/axi_ad9963_tx.v @@ -216,6 +216,10 @@ module axi_ad9963_tx #( .dac_sync (dac_sync_out), .dac_frame (), .dac_clksel(), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/axi_adrv9001/axi_adrv9001_tx.v b/library/axi_adrv9001/axi_adrv9001_tx.v index 3e37b455b6..00b337fea0 100644 --- a/library/axi_adrv9001/axi_adrv9001_tx.v +++ b/library/axi_adrv9001/axi_adrv9001_tx.v @@ -384,6 +384,10 @@ module axi_adrv9001_tx #( .dac_ext_sync_arm (dac_ext_sync_arm), .dac_frame (), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), diff --git a/library/common/up_dac_common.v b/library/common/up_dac_common.v index 4f284a77a9..8053b9acf7 100644 --- a/library/common/up_dac_common.v +++ b/library/common/up_dac_common.v @@ -95,6 +95,13 @@ module up_dac_common #( input up_drp_ready, input up_drp_locked, + // DAC custom read/write interface + + output [31:0] dac_custom_wr, + output [31:0] dac_custom_control, + input [31:0] dac_custom_rd, + input dac_status_if_busy, + // user channel control output [ 7:0] up_usr_chanmax, @@ -144,6 +151,8 @@ module up_dac_common #( reg [15:0] up_dac_datarate = 'd0; reg up_dac_frame = 'd0; reg up_dac_clksel = CLK_EDGE_SEL; + reg [31:0] up_dac_custom_wr = 'd0; + reg [31:0] up_dac_custom_control = 'd0; reg up_status_unf = 'd0; reg [ 7:0] up_usr_chanmax_int = 'd0; reg [31:0] up_dac_gpio_out_int = 'd0; @@ -164,6 +173,8 @@ module up_dac_common #( wire up_rreq_s; wire up_xfer_done_s; wire up_status_s; + wire [31:0] up_dac_custom_rd; + wire up_status_if_busy; wire up_sync_in_status; wire up_status_unf_s; wire dac_sync_s; @@ -212,6 +223,7 @@ module up_dac_common #( up_dac_datarate <= 'd0; up_dac_frame <= 'd0; up_dac_clksel <= CLK_EDGE_SEL; + up_dac_custom_control <= 'd0; up_pps_irq_mask <= 1'b1; end else begin up_dac_clk_enb_int <= ~up_dac_clk_enb; @@ -280,6 +292,9 @@ module up_dac_common #( if ((up_wreq_s == 1'b1) && (up_waddr[6:0] == 7'h18)) begin up_dac_clksel <= up_wdata[0]; end + if ((up_wreq_s == 1'b1) && (up_waddr[6:0] == 7'h23)) begin + up_dac_custom_control <= up_wdata; + end end end @@ -350,6 +365,16 @@ module up_dac_common #( end endgenerate + always @(posedge up_clk) begin + if (up_rstn == 0) begin + up_dac_custom_wr <= 'd0; + end else begin + if ((up_wreq_s == 1'b1) && (up_waddr[6:0] == 7'h21)) begin + up_dac_custom_wr <= up_wdata; + end + end + end + always @(negedge up_rstn or posedge up_clk) begin if (up_rstn == 0) begin up_status_unf <= 'd0; @@ -439,11 +464,9 @@ module up_dac_common #( 3'b0, up_dac_ext_sync_manual_req, 4'b0, 1'b0, up_dac_ext_sync_disarm, up_dac_ext_sync_arm, up_dac_sync}; - 7'h12: up_rdata_int <= {15'd0, up_dac_sdr_ddr_n, - up_dac_symb_op, up_dac_symb_8_16b, - 1'd0, up_dac_num_lanes, - up_dac_par_type, up_dac_par_enb, up_dac_r1_mode, up_dac_datafmt, - 4'd0}; + 7'h12: up_rdata_int <= {15'd0, up_dac_sdr_ddr_n, up_dac_symb_op, up_dac_symb_8_16b, 1'd0, + up_dac_num_lanes, up_dac_par_type, up_dac_par_enb, up_dac_r1_mode, + up_dac_datafmt, 4'd0}; 7'h13: up_rdata_int <= {16'd0, up_dac_datarate}; 7'h14: up_rdata_int <= {31'd0, up_dac_frame}; 7'h15: up_rdata_int <= up_dac_clk_count_s; @@ -455,12 +478,15 @@ module up_dac_common #( 7'h1d: up_rdata_int <= {14'd0, up_drp_locked, up_drp_status_s, 16'b0}; 7'h1e: up_rdata_int <= up_drp_wdata; 7'h1f: up_rdata_int <= up_drp_rdata_hold_s; - 7'h22: up_rdata_int <= {31'd0, up_status_unf}; + 7'h20: up_rdata_int <= up_dac_custom_rd; + 7'h21: up_rdata_int <= up_dac_custom_wr; + 7'h22: up_rdata_int <= {27'd0, up_status_if_busy, 3'd0, up_status_unf}; + 7'h23: up_rdata_int <= up_dac_custom_control; 7'h28: up_rdata_int <= {24'd0, dac_usr_chanmax}; 7'h2e: up_rdata_int <= up_dac_gpio_in; 7'h2f: up_rdata_int <= up_dac_gpio_out_int; 7'h30: up_rdata_int <= up_pps_rcounter; - 7'h31: up_rdata_int <= up_pps_status; + 7'h31: up_rdata_int <= {31'd0,up_pps_status}; 7'h40: up_rdata_int <= up_timer; default: up_rdata_int <= 0; endcase @@ -487,7 +513,7 @@ module up_dac_common #( // dac control & status up_xfer_cntrl #( - .DATA_WIDTH(35) + .DATA_WIDTH(99) ) i_xfer_cntrl ( .up_rstn (up_rstn), .up_clk (up_clk), @@ -500,6 +526,8 @@ module up_dac_common #( up_dac_ext_sync_manual_req, up_dac_sync, up_dac_clksel, + up_dac_custom_wr, + up_dac_custom_control, up_dac_frame, up_dac_par_type, up_dac_par_enb, @@ -519,6 +547,8 @@ module up_dac_common #( dac_ext_sync_manual_req, dac_sync_s, dac_clksel, + dac_custom_wr, + dac_custom_control, dac_frame_s, dac_par_type, dac_par_enb, @@ -533,18 +563,22 @@ module up_dac_common #( assign dac_rst = ~dac_rst_n; up_xfer_status #( - .DATA_WIDTH(3) + .DATA_WIDTH(36) ) i_xfer_status ( .up_rstn (up_rstn), .up_clk (up_clk), .up_data_status ({up_sync_in_status, up_status_s, - up_status_unf_s}), + up_status_unf_s, + up_status_if_busy, + up_dac_custom_rd}), .d_rst (dac_rst_s), .d_clk (dac_clk), .d_data_status ({ dac_sync_in_status, dac_status, - dac_status_unf})); + dac_status_unf, + dac_status_if_busy, + dac_custom_rd})); // generate frame and enable diff --git a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v index 4b7f2e9fc7..c89d5c205d 100644 --- a/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v +++ b/library/jesd204/ad_ip_jesd204_tpl_dac/ad_ip_jesd204_tpl_dac_regmap.v @@ -232,6 +232,10 @@ module ad_ip_jesd204_tpl_dac_regmap #( .dac_sync_in_status (dac_sync_in_status), .dac_frame (), .dac_clksel (), + .dac_custom_wr(), + .dac_custom_rd(32'b0), + .dac_custom_control(), + .dac_status_if_busy(1'b0), .dac_par_type (), .dac_par_enb (), .dac_r1_mode (), From df24b297d5f4e7835e94f4d4a9ebf96425cbfcb3 Mon Sep 17 00:00:00 2001 From: PopPaul2021 Date: Thu, 7 Sep 2023 09:14:35 +0300 Subject: [PATCH 2/3] library/axi_ad3552r: Added interface IP for Xilinx projects. The custom interface IP for AD3552R DAC has more operation capabilities: - 8b register read/write SDR/DDR - 16b register read/write SDR/DDR - data stream SDR/DDR ( clk_in/8 or clk_in/4 update rate) - selectable input source : DMA/ADC/TEST_RAMP - data out clock(SCLK) has clk_in/8 frequency when the converter is configured and clk_in/2 when the converter is in stream mode - the IP reference clock (clk_in) can have a maximum frequency of 132MHz - the IP has multiple device synchronization capability when the DMA is set as an input data source Signed-off-by: PopPaul2021 --- library/Makefile | 2 + library/axi_ad3552r/Makefile | 35 +++ library/axi_ad3552r/axi_ad3552r.v | 233 ++++++++++++++++ library/axi_ad3552r/axi_ad3552r_channel.v | 227 ++++++++++++++++ library/axi_ad3552r/axi_ad3552r_core.v | 261 ++++++++++++++++++ library/axi_ad3552r/axi_ad3552r_if.v | 316 ++++++++++++++++++++++ library/axi_ad3552r/axi_ad3552r_if_tb | 7 + library/axi_ad3552r/axi_ad3552r_if_tb.v | 239 ++++++++++++++++ library/axi_ad3552r/axi_ad3552r_ip.tcl | 51 ++++ 9 files changed, 1371 insertions(+) create mode 100755 library/axi_ad3552r/Makefile create mode 100755 library/axi_ad3552r/axi_ad3552r.v create mode 100755 library/axi_ad3552r/axi_ad3552r_channel.v create mode 100755 library/axi_ad3552r/axi_ad3552r_core.v create mode 100755 library/axi_ad3552r/axi_ad3552r_if.v create mode 100755 library/axi_ad3552r/axi_ad3552r_if_tb create mode 100755 library/axi_ad3552r/axi_ad3552r_if_tb.v create mode 100755 library/axi_ad3552r/axi_ad3552r_ip.tcl diff --git a/library/Makefile b/library/Makefile index d98dc2924c..65234a0d46 100644 --- a/library/Makefile +++ b/library/Makefile @@ -14,6 +14,7 @@ all: lib clean: $(MAKE) -C ad463x_data_capture clean + $(MAKE) -C axi_ad3552r clean $(MAKE) -C axi_ad5766 clean $(MAKE) -C axi_ad7606x clean $(MAKE) -C axi_ad7616 clean @@ -136,6 +137,7 @@ clean-all:clean lib: $(MAKE) -C ad463x_data_capture + $(MAKE) -C axi_ad3552r $(MAKE) -C axi_ad5766 $(MAKE) -C axi_ad7606x $(MAKE) -C axi_ad7616 diff --git a/library/axi_ad3552r/Makefile b/library/axi_ad3552r/Makefile new file mode 100755 index 0000000000..3970c74819 --- /dev/null +++ b/library/axi_ad3552r/Makefile @@ -0,0 +1,35 @@ +#################################################################################### +## Copyright (c) 2018 - 2023 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### + +LIBRARY_NAME := axi_ad3552r + +GENERIC_DEPS += ../common/ad_addsub.v +GENERIC_DEPS += ../common/ad_dds.v +GENERIC_DEPS += ../common/ad_dds_1.v +GENERIC_DEPS += ../common/ad_dds_2.v +GENERIC_DEPS += ../common/ad_dds_cordic_pipe.v +GENERIC_DEPS += ../common/ad_dds_sine.v +GENERIC_DEPS += ../common/ad_dds_sine_cordic.v +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += ../common/up_clock_mon.v +GENERIC_DEPS += ../common/up_dac_channel.v +GENERIC_DEPS += ../common/up_dac_common.v +GENERIC_DEPS += ../common/up_xfer_cntrl.v +GENERIC_DEPS += ../common/up_xfer_status.v +GENERIC_DEPS += axi_ad3552r.v +GENERIC_DEPS += axi_ad3552r_channel.v +GENERIC_DEPS += axi_ad3552r_core.v +GENERIC_DEPS += axi_ad3552r_if.v + +XILINX_DEPS += ../xilinx/common/ad_mul.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_ad3552r_ip.tcl + +include ../scripts/library.mk diff --git a/library/axi_ad3552r/axi_ad3552r.v b/library/axi_ad3552r/axi_ad3552r.v new file mode 100755 index 0000000000..2f4c4e20a0 --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r.v @@ -0,0 +1,233 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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/master/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_ad3552r #( + + parameter ID = 0, + parameter FPGA_TECHNOLOGY = 0, + parameter FPGA_FAMILY = 0, + parameter SPEED_GRADE = 0, + parameter DEV_PACKAGE = 0, + parameter DDS_DISABLE = 0, + parameter DDS_TYPE = 1, + parameter DDS_CORDIC_DW = 16, + parameter DDS_CORDIC_PHASE_DW = 16 +) ( + + // DAC INTERFACE + + input dac_clk, + + input [31:0] dma_data, + input valid_in_dma, + input valid_in_dma_sec, + output dac_data_ready, + + input [15:0] data_in_a, + input [15:0] data_in_b, + input valid_in_a, + input valid_in_b, + + output dac_sclk, + output dac_csn, + input [ 3:0] sdio_i, + output [ 3:0] sdio_o, + output sdio_t, + + // sync transfer between 2 DAC'S + + input external_sync, + output sync_ext_device, + + // axi interface + + 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 +); + + // internal clocks and resets + + wire dac_rst_s; + wire up_clk; + wire up_rstn; + + // internal signals + + wire up_wreq_s; + wire [13:0] up_waddr_s; + wire [31:0] up_wdata_s; + wire up_wack_s; + wire up_rreq_s; + wire [13:0] up_raddr_s; + wire [31:0] up_rdata_s; + wire up_rack_s; + + wire [ 7:0] address; + wire [23:0] data_read; + wire [23:0] data_write; + wire ddr_sdr_n; + wire symb_8_16b; + wire transfer_data; + wire stream; + wire [31:0] dac_data; + wire dac_valid; + wire if_busy; + wire dac_ext_sync_arm; + + // signal name changes + + assign up_clk = s_axi_aclk; + assign up_rstn = s_axi_aresetn; + + // device interface + axi_ad3552r_if axi_ad3552r_interface ( + .clk_in(dac_clk), + .reset_in(dac_rst_s), + .dac_data(dac_data), + .dac_data_valid(dac_valid), + .dac_data_valid_ext(valid_in_dma_sec), + .dac_data_ready(dac_data_ready), + .address(address), + .data_read(data_read), + .data_write(data_write), + .sdr_ddr_n(sdr_ddr_n), + .symb_8_16b(symb_8_16b), + .transfer_data(transfer_data), + .stream(stream), + .if_busy(if_busy), + .external_sync(external_sync), + .external_sync_arm(dac_ext_sync_arm), + .sync_ext_device(sync_ext_device), + .sclk(dac_sclk), + .csn(dac_csn), + .sdio_i(sdio_i), + .sdio_o(sdio_o), + .sdio_t(sdio_t)); + + // core + axi_ad3552r_core #( + .ID(ID), + .FPGA_TECHNOLOGY(FPGA_TECHNOLOGY), + .FPGA_FAMILY(FPGA_FAMILY), + .SPEED_GRADE(SPEED_GRADE), + .DEV_PACKAGE(DEV_PACKAGE), + .DDS_DISABLE(DDS_DISABLE), + .DDS_TYPE(DDS_TYPE), + .DDS_CORDIC_DW(DDS_CORDIC_DW), + .DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW) + ) axi_ad3552r_up_core ( + .dac_clk(dac_clk), + .dac_rst(dac_rst_s), + .adc_data_in_a(data_in_a), + .adc_data_in_b(data_in_b), + .dma_data(dma_data), + .adc_valid_in_a(valid_in_a), + .adc_valid_in_b(valid_in_b), + .valid_in_dma(valid_in_dma), + .dac_data_ready(dac_data_ready), + .dac_data(dac_data), + .dac_valid(dac_valid), + .address(address), + .data_read(data_read), + .data_write(data_write), + .sdr_ddr_n(sdr_ddr_n), + .symb_8_16b(symb_8_16b), + .transfer_data(transfer_data), + .stream(stream), + .dac_ext_sync_arm(dac_ext_sync_arm), + .if_busy(if_busy), + .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), + .up_rreq(up_rreq_s), + .up_raddr(up_raddr_s), + .up_rdata(up_rdata_s), + .up_rack(up_rack_s)); + + // up bus interface + + up_axi 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_s), + .up_rreq(up_rreq_s), + .up_raddr(up_raddr_s), + .up_rdata(up_rdata_s), + .up_rack(up_rack_s)); +endmodule diff --git a/library/axi_ad3552r/axi_ad3552r_channel.v b/library/axi_ad3552r/axi_ad3552r_channel.v new file mode 100755 index 0000000000..0a73e9d065 --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_channel.v @@ -0,0 +1,227 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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 modificat +// 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/master/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_ad3552r_channel #( + + parameter CHANNEL_ID = 32'h0, + parameter DDS_DISABLE = 0, + parameter DDS_TYPE = 1, + parameter DDS_CORDIC_DW = 16, + parameter DDS_CORDIC_PHASE_DW = 16 +) ( + + // dac interface + + input dac_clk, + input dac_rst, + output dac_data_valid, + output [15:0] dac_data, + + // input sources + + input [15:0] dma_data, + input [15:0] adc_data, + input valid_in_adc, + input valid_in_dma, + input dac_data_ready, + + // processor interface + + input dac_data_sync, + input dac_dfmt_type, + + // bus interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output up_wack, + input up_rreq, + input [13:0] up_raddr, + output [31:0] up_rdata, + output up_rack +); + + // internal signals + + wire [15:0] formatted_dma_data; + wire [15:0] formatted_adc_data; + wire [ 3:0] dac_data_sel_s; + + wire [15:0] dac_dds_data_s; + wire [15:0] dac_dds_scale_1_s; + wire [15:0] dac_dds_init_1_s; + wire [15:0] dac_dds_incr_1_s; + wire [15:0] dac_dds_scale_2_s; + wire [15:0] dac_dds_init_2_s; + wire [15:0] dac_dds_incr_2_s; + wire [15:0] dac_pat_data_1_s; + wire [15:0] dac_pat_data_2_s; + + reg [15:0] ramp_pattern = 16'h0000; + reg ramp_valid = 1'b0; + reg [15:0] dac_data_int; + reg dac_data_valid_int; + + assign dac_data = dac_data_int; + assign dac_data_valid = dac_data_valid_int; + + assign formatted_dma_data [15] = dac_dfmt_type ^ dma_data[15]; + assign formatted_dma_data [14:0] = dma_data[14:0]; + assign formatted_adc_data [15] = dac_dfmt_type ^ adc_data[15]; + assign formatted_adc_data [14:0] = adc_data[14:0]; + + always @ (*) begin + case(dac_data_sel_s) + 4'h0 : + begin + dac_data_int = dac_dds_data_s; + dac_data_valid_int = 1'b1; + end + 4'h2 : + begin + dac_data_int = formatted_dma_data; + dac_data_valid_int = valid_in_dma; + end + 4'h3 : + begin + dac_data_int = 16'b0; + dac_data_valid_int = 1'b1; + end + 4'h8 : + begin + dac_data_int = formatted_adc_data; + dac_data_valid_int = valid_in_adc; + end + 4'hb : + begin + dac_data_int = ramp_pattern; + dac_data_valid_int = ramp_valid; + end + default : + begin + dac_data_int = 16'b0; + dac_data_valid_int = 1'b1; + end + endcase + end + + // ramp generator + + always @(posedge dac_clk) begin + ramp_valid <= 1'b1; + if(dac_data_ready == 1'b1) begin + ramp_pattern <= ramp_pattern + 1'b1; + end else begin + ramp_pattern <= ramp_pattern; + end + if(ramp_pattern == 16'hffff || dac_rst == 1'b1) begin + ramp_pattern <= 16'h0; + end + end + + ad_dds #( + .DISABLE (DDS_DISABLE), + .DDS_DW (16), + .PHASE_DW (16), + .DDS_TYPE (DDS_TYPE), + .CORDIC_DW (DDS_CORDIC_DW), + .CORDIC_PHASE_DW (DDS_CORDIC_PHASE_DW), + .CLK_RATIO (1) + ) i_dds ( + .clk (dac_clk), + .dac_dds_format (dac_dfmt_type), + .dac_data_sync (dac_data_sync), + .dac_valid (dac_data_ready), + .tone_1_scale (dac_dds_scale_1_s), + .tone_2_scale (dac_dds_scale_2_s), + .tone_1_init_offset (dac_dds_init_1_s), + .tone_2_init_offset (dac_dds_init_2_s), + .tone_1_freq_word (dac_dds_incr_1_s), + .tone_2_freq_word (dac_dds_incr_2_s), + .dac_dds_data (dac_dds_data_s)); + + // single channel processor + + up_dac_channel #( + .CHANNEL_ID(CHANNEL_ID), + .COMMON_ID(6'h01) + ) dac_channel ( + .dac_clk(dac_clk), + .dac_rst(dac_rst), + .dac_dds_scale_1(dac_dds_scale_1_s), + .dac_dds_init_1(dac_dds_init_1_s), + .dac_dds_incr_1(dac_dds_incr_1_s), + .dac_dds_scale_2(dac_dds_scale_2_s), + .dac_dds_init_2(dac_dds_init_2_s), + .dac_dds_incr_2(dac_dds_incr_2_s), + .dac_pat_data_1(dac_pat_data_1_s), + .dac_pat_data_2(dac_pat_data_2_s), + .dac_data_sel(dac_data_sel_s), + .dac_mask_enable(), + .dac_iq_mode(), + .dac_iqcor_enb(), + .dac_iqcor_coeff_1(), + .dac_iqcor_coeff_2(), + .dac_src_chan_sel(), + .up_usr_datatype_be(), + .up_usr_datatype_signed(), + .up_usr_datatype_shift(), + .up_usr_datatype_total_bits(), + .up_usr_datatype_bits(), + .up_usr_interpolation_m(), + .up_usr_interpolation_n(), + .dac_usr_datatype_be(1'd0), + .dac_usr_datatype_signed(1'd1), + .dac_usr_datatype_shift(8'd0), + .dac_usr_datatype_total_bits(8'd16), + .dac_usr_datatype_bits(8'd16), + .dac_usr_interpolation_m(16'd1), + .dac_usr_interpolation_n(16'd1), + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_wreq(up_wreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_wack(up_wack), + .up_rreq(up_rreq), + .up_raddr(up_raddr), + .up_rdata(up_rdata), + .up_rack(up_rack)); +endmodule diff --git a/library/axi_ad3552r/axi_ad3552r_core.v b/library/axi_ad3552r/axi_ad3552r_core.v new file mode 100755 index 0000000000..a0fadfdd0d --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_core.v @@ -0,0 +1,261 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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/master/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_ad3552r_core #( + parameter ID = 0, + parameter FPGA_TECHNOLOGY = 0, + parameter FPGA_FAMILY = 0, + parameter SPEED_GRADE = 0, + parameter DEV_PACKAGE = 0, + parameter DDS_DISABLE = 0, + parameter DDS_TYPE = 1, + parameter DDS_CORDIC_DW = 16, + parameter DDS_CORDIC_PHASE_DW = 16 +) ( + + // dac interface + + input dac_clk, + output dac_rst, + input [15:0] adc_data_in_a, + input [15:0] adc_data_in_b, + input [31:0] dma_data, + input adc_valid_in_a, + input adc_valid_in_b, + input valid_in_dma, + output [31:0] dac_data, + output dac_valid, + input dac_data_ready, + + // output + + output [ 7:0] address, + input if_busy, + input [23:0] data_read, + output [23:0] data_write, + output sdr_ddr_n, + output symb_8_16b, + output transfer_data, + output stream, + output dac_ext_sync_arm, + + // processor interface + + input up_rstn, + input up_clk, + input up_wreq, + input [13:0] up_waddr, + input [31:0] up_wdata, + output reg up_wack, + input up_rreq, + input [13:0] up_raddr, + output reg [31:0] up_rdata, + output reg up_rack +); + + wire [31:0] up_rdata_0_s; + wire up_rack_0_s; + wire up_wack_0_s; + wire [31:0] up_rdata_1_s; + wire up_rack_1_s; + wire up_wack_1_s; + wire [31:0] up_rdata_s; + wire up_rack_s; + wire up_wack_s; + + wire [15:0] dac_data_channel_0; + wire [15:0] dac_data_channel_1; + wire dac_valid_channel_0; + wire dac_valid_channel_1; + wire dac_rst_s; + + wire [31:0] dac_data_control; + wire [31:0] dac_control; + + wire dac_data_sync; + wire dac_dfmt_type; + + // defaults + + assign dac_rst = dac_rst_s; + assign dac_data = {dac_data_channel_1 ,dac_data_channel_0}; + assign dac_valid = dac_valid_channel_0 | dac_valid_channel_1; + + assign data_write = dac_data_control[23:0]; + assign transfer_data = dac_control[0]; + assign stream = dac_control[1]; + assign address = dac_control[31:24]; + + // processor read interface + + 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_s | up_rdata_0_s | up_rdata_1_s; + up_rack <= up_rack_s | up_rack_0_s | up_rack_1_s; + up_wack <= up_wack_s | up_wack_0_s | up_wack_1_s; + end + end + + // DAC CHANNEL 0 + + axi_ad3552r_channel #( + .CHANNEL_ID(0), + .DDS_DISABLE(DDS_DISABLE), + .DDS_TYPE(DDS_TYPE), + .DDS_CORDIC_DW(DDS_CORDIC_DW), + .DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW) + ) axi_ad3552r_channel_0 ( + .dac_clk(dac_clk), + .dac_rst(dac_rst_s), + .dac_data_valid(dac_valid_channel_0), + .dac_data(dac_data_channel_0), + .dma_data(dma_data[15:0]), + .dac_data_ready(dac_data_ready), + .adc_data(adc_data_in_a), + .valid_in_adc(adc_valid_in_a), + .valid_in_dma(valid_in_dma), + .dac_data_sync(dac_data_sync), + .dac_dfmt_type(dac_dfmt_type), + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_wreq(up_wreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_wack(up_wack_0_s), + .up_rreq(up_rreq), + .up_raddr(up_raddr), + .up_rdata(up_rdata_0_s), + .up_rack(up_rack_0_s)); + + // DAC CHANNEL 1 + + axi_ad3552r_channel #( + .CHANNEL_ID(1), + .DDS_DISABLE(DDS_DISABLE), + .DDS_TYPE(DDS_TYPE), + .DDS_CORDIC_DW(DDS_CORDIC_DW), + .DDS_CORDIC_PHASE_DW(DDS_CORDIC_PHASE_DW) + ) axi_ad3552r_channel_1( + .dac_clk(dac_clk), + .dac_rst(dac_rst_s), + .dac_data_valid(dac_valid_channel_1), + .dac_data(dac_data_channel_1), + .dma_data(dma_data[31:16]), + .dac_data_ready(dac_data_ready), + .adc_data(adc_data_in_b), + .valid_in_adc(adc_valid_in_b), + .valid_in_dma(valid_in_dma), + .dac_data_sync(dac_data_sync), + .dac_dfmt_type(dac_dfmt_type), + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_wreq(up_wreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_wack(up_wack_1_s), + .up_rreq(up_rreq), + .up_raddr(up_raddr), + .up_rdata(up_rdata_1_s), + .up_rack(up_rack_1_s)); + + // dac common processor interface + + up_dac_common #( + .ID(ID), + .FPGA_TECHNOLOGY(FPGA_TECHNOLOGY), + .FPGA_FAMILY(FPGA_FAMILY), + .SPEED_GRADE(SPEED_GRADE), + .DEV_PACKAGE(DEV_PACKAGE), + .COMMON_ID(6'h00) + ) axi_ad3552r_common_core ( + .mmcm_rst(), + .dac_clk(dac_clk), + .dac_rst(dac_rst_s), + .dac_num_lanes(), + .dac_sdr_ddr_n(sdr_ddr_n), + .dac_symb_op(), + .dac_symb_8_16b(symb_8_16b), + .dac_sync(dac_data_sync), + .dac_ext_sync_arm(dac_ext_sync_arm), + .dac_ext_sync_disarm(), + .dac_ext_sync_manual_req(), + .dac_frame(), + .dac_clksel(), + .dac_custom_wr(dac_data_control), + .dac_custom_rd({8'b0, data_read}), + .dac_custom_control(dac_control), + .dac_status_if_busy(if_busy), + .dac_par_type(), + .dac_par_enb(), + .dac_r1_mode(), + .dac_datafmt(dac_dfmt_type), + .dac_datarate(), + .dac_status(), + .dac_sync_in_status(), + .dac_status_unf(), + .dac_clk_ratio(32'd1), + .up_dac_ce(), + .up_pps_rcounter(32'd0), + .up_pps_status(1'd0), + .up_pps_irq_mask(), + .up_dac_r1_mode(), + .up_drp_sel(), + .up_drp_wr(), + .up_drp_addr(), + .up_drp_wdata() , + .up_drp_rdata(32'd0), + .up_drp_ready(1'd1), + .up_drp_locked(1'd1), + .up_usr_chanmax(), + .dac_usr_chanmax(8'd1), + .up_dac_gpio_in(32'd0), + .up_dac_gpio_out(), + .up_rstn(up_rstn), + .up_clk(up_clk), + .up_wreq(up_wreq), + .up_waddr(up_waddr), + .up_wdata(up_wdata), + .up_wack(up_wack_s), + .up_rreq(up_rreq), + .up_raddr(up_raddr), + .up_rdata(up_rdata_s), + .up_rack (up_rack_s)); +endmodule diff --git a/library/axi_ad3552r/axi_ad3552r_if.v b/library/axi_ad3552r/axi_ad3552r_if.v new file mode 100755 index 0000000000..0b67b64c44 --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_if.v @@ -0,0 +1,316 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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/master/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_ad3552r_if ( + + input clk_in, // 120MHz + input reset_in, + input [31:0] dac_data, + input dac_data_valid, + input dac_data_valid_ext, + output dac_data_ready, + + input [ 7:0] address, + input [23:0] data_write, + input sdr_ddr_n, + input symb_8_16b, + input transfer_data, + input stream, + input external_sync, + input external_sync_arm, + + output if_busy, + output sync_ext_device, + output reg [23:0] data_read, + + // DAC control signals + + output sclk, + output reg csn, + input [ 3:0] sdio_i, + output [ 3:0] sdio_o, + output sdio_t +); + + wire transfer_data_s; + wire start_synced; + wire [31:0] dac_data_int; + wire dac_data_valid_synced; + wire external_sync_s; + + reg [55:0] transfer_reg = 56'h0; + reg [15:0] counter = 16'h0; + reg [ 2:0] transfer_state = 0; + reg [ 2:0] transfer_state_next = 0; + reg cycle_done = 1'b0; + reg transfer_step = 1'b0; + reg sclk_ddr = 1'b0; + reg full_speed = 1'b0; + reg transfer_data_d = 1'b0; + reg transfer_data_dd = 1'b0; + reg [ 3:0] valid_captured_d = 4'b0; + reg data_r_wn = 1'b0; + reg valid_captured = 1'b0; + reg start_transfer = 1'b0; + reg if_busy_reg = 1'b0; + reg dac_data_ready_s = 1'b0; + reg external_sync_arm_reg = 1'b0; + reg external_sync_reg = 1'b0; + + localparam [ 2:0] IDLE = 3'h0, + CS_LOW = 3'h1, + WRITE_ADDRESS = 3'h2, + TRANSFER_REGISTER = 3'h3, + READ_REGISTER = 3'h4, + STREAM = 3'h5, + CS_HIGH = 3'h6; + + assign if_busy = if_busy_reg; + + // transform the transfer data rising edge into a pulse + + assign transfer_data_s = transfer_data_d & ~transfer_data_dd; + + // start the data stream transfer after valid has been captured + + assign start_synced = valid_captured_d[1] & start_transfer & stream; + assign sync_ext_device = start_synced ; + + // use dac_data valid from an external source only if external_sync_arm_reg is 1 + + assign dac_data_valid_synced = (external_sync_arm_reg == 1'b1) ? (dac_data_valid & dac_data_valid_ext) : dac_data_valid ; + assign dac_data_ready = dac_data_ready_s & dac_data_valid_synced; + assign dac_data_int = dac_data; + + // sync the data only if the synchronizations has been armed in software + + assign external_sync_s = ~external_sync_arm_reg | external_sync_reg; + + always @(posedge clk_in) begin + if(reset_in == 1'b1) begin + transfer_data_d <= 'd0; + transfer_data_dd <= 'd0; + valid_captured_d <= 4'b0; + valid_captured <= 1'b0; + end else begin + transfer_data_d <= transfer_data; + transfer_data_dd <= transfer_data_d; + valid_captured_d <= {valid_captured_d[2:0], valid_captured}; + end + if(transfer_state == CS_HIGH || stream == 1'b0) begin + start_transfer <= 1'b0; + valid_captured <= 1'b0; + valid_captured_d <= 4'b0; + end + + // pulse to level conversion + + if(external_sync_arm == 1'b1) begin + external_sync_arm_reg <= 1'b1; + end + if(external_sync == 1'b1) begin + external_sync_reg <= 1'b1; + end + + if(transfer_state == CS_HIGH) begin + external_sync_arm_reg <= 1'b0; + external_sync_reg <= 1'b0; + end + + if(dac_data_valid == 1'b1 && start_transfer == 1'b1) begin + valid_captured <= 1'b1; + end + if(transfer_data == 1'b1) begin + start_transfer <= 1'b1; + end + + end + + always @(posedge clk_in) begin + if (reset_in == 1'b1) begin + transfer_state <= IDLE; + end else begin + transfer_state <= transfer_state_next; + end + end + + // FSM next state logic + + always @(*) begin + case (transfer_state) + IDLE : begin + // goes in to the next state only if the control is to transfer register or synced transfer(if it's armed in software) + transfer_state_next = ((transfer_data_s == 1'b1 && stream == 1'b0) || (start_synced == 1'b1 && external_sync_s)) ? CS_LOW : IDLE; + csn = 1'b1; + transfer_step = 0; + cycle_done = 0; + end + CS_LOW : begin + // brings CS down + // loads all configuration + // puts data on the SDIO pins + // needs 5 ns before risedge of the clock + transfer_state_next = WRITE_ADDRESS; + csn = 1'b0; + transfer_step = 0; + cycle_done = 0; + end + WRITE_ADDRESS : begin + // writes the address + // it works either at full speed (60 MHz) when streaming or normal + // speed (15 MHz) + // full speed - 2 clock cycles + // half speed 8 clock cycles + cycle_done = full_speed ? (counter == 16'h3) : (counter == 16'hf); + transfer_state_next = cycle_done ? (stream ? STREAM : TRANSFER_REGISTER) : WRITE_ADDRESS ; + csn = 1'b0; + // in streaming, change data on falledge. On regular transfer, change data on negedge. + //A single step should be done for 8 bit addressing + transfer_step = full_speed ? (counter[0]== 1'h1) : ((counter[4:0] == 5'h5)); + end + TRANSFER_REGISTER : begin + // always works at 15 MHz + // can be DDR or SDR + cycle_done = sdr_ddr_n ? (symb_8_16b ? (counter == 16'h10) : (counter == 16'h20)) : + (symb_8_16b ? (counter == 16'h09) : (counter == 16'h11)); + transfer_state_next = cycle_done ? CS_HIGH : TRANSFER_REGISTER; + csn = 1'b0; + // in DDR mode, change data on falledge + transfer_step = sdr_ddr_n ? (counter[2:0] == 3'h0) : (counter[1:0] == 2'h0); + end + STREAM : begin + // can be DDR or SDR + // in DDR mode needs to be make sure the clock and data is shifted by 2 ns + cycle_done = stream ? (sdr_ddr_n ? (counter == 16'h0f) : (counter == 16'h7)): + (sdr_ddr_n ? (counter == 16'h10) : (counter == 16'h7)); + transfer_state_next = (stream && external_sync_s) ? STREAM: ((cycle_done || external_sync_s == 1'b0) ? CS_HIGH :STREAM); + csn = 1'b0; + transfer_step = sdr_ddr_n ? counter[0] : 1'b1; + end + CS_HIGH : begin + cycle_done = 1'b1; + transfer_state_next = cycle_done ? IDLE : CS_HIGH; + csn = 1'b1; + transfer_step = 0; + end + default : begin + cycle_done = 0; + transfer_state_next = IDLE; + csn = 1'b1; + transfer_step = 0; + end + endcase + end + + // counter is used to time all states + // depends on number of clock cycles per phase + + always @(posedge clk_in) begin + if (transfer_state == IDLE || reset_in == 1'b1) begin + counter <= 'b0; + end else if (transfer_state == WRITE_ADDRESS | transfer_state == TRANSFER_REGISTER | transfer_state == STREAM) begin + if (cycle_done) begin + counter <= 0; + end else begin + counter <= counter + 1; + end + end + end + + always @(negedge clk_in) begin + if (transfer_state == STREAM | transfer_state == WRITE_ADDRESS) begin + sclk_ddr <= !sclk_ddr; + end else begin + sclk_ddr <= 0; + end + end + + // selection between 60 MHz and 15 MHz + + assign sclk = full_speed ? (sdr_ddr_n ? counter[0] : sclk_ddr) : counter[2]; + + always @(posedge clk_in) begin + if (transfer_state == CS_LOW) begin + data_r_wn <= address[7]; + end else if (transfer_state == CS_HIGH) begin + data_r_wn <=1'b0; + end + if (transfer_state == STREAM) begin + if (cycle_done == 1'b1) begin + dac_data_ready_s <= stream; + end else begin + dac_data_ready_s <= 1'b0; + end + end else begin + dac_data_ready_s <= 1'b0; + end + if (transfer_state == CS_LOW) begin + full_speed = stream; + if(stream) begin + transfer_reg <= {address,dac_data_int, 16'h0}; + end else begin + transfer_reg <= {address,data_write, 24'h0}; + end + end else if ((transfer_state == STREAM & cycle_done) || (transfer_state != STREAM && transfer_state_next == STREAM)) begin + transfer_reg <= {dac_data_int, 24'h0}; + end else if (transfer_step && transfer_state != CS_HIGH) begin + transfer_reg <= {transfer_reg[51:0], sdio_i}; + end + + if (transfer_state == CS_HIGH) begin + if (symb_8_16b == 1'b0) begin + data_read <= {8'h0,transfer_reg[15:0]}; + end else begin + data_read <= {16'h0,transfer_reg[7:0]}; + end + end else begin + data_read <= data_read; + end + if (transfer_state == CS_HIGH || transfer_state == IDLE) begin + if_busy_reg <= 1'b0; + end else begin + if_busy_reg <= 1'b1; + end + end + + // address[7] is r_wn : depends also on the state machine, input only when + // in TRANSFER register mode + + assign sdio_t = (data_r_wn & transfer_state == TRANSFER_REGISTER); + assign sdio_o = transfer_reg[55:52]; + +endmodule diff --git a/library/axi_ad3552r/axi_ad3552r_if_tb b/library/axi_ad3552r/axi_ad3552r_if_tb new file mode 100755 index 0000000000..485bf965a2 --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_if_tb @@ -0,0 +1,7 @@ +#!/bin/bash + +SOURCE="$0.v" +SOURCE+=" axi_ad3552r_if.v" + +cd `dirname $0` +source ../common/tb/run_tb.sh diff --git a/library/axi_ad3552r/axi_ad3552r_if_tb.v b/library/axi_ad3552r/axi_ad3552r_if_tb.v new file mode 100755 index 0000000000..16521acc61 --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_if_tb.v @@ -0,0 +1,239 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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/master/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_ad3552r_if_tb; + parameter VCD_FILE = "axi_ad3552r_if_tb.vcd"; + + `define TIMEOUT 9000 + `include "../common/tb/tb_base.v" + + wire [ 23:0] data_read; + wire dac_sclk; + wire dac_csn; + wire dac_data_ready; + wire [ 3:0] sdio_i; + wire [ 3:0] sdio_o; + wire sdio_t; + wire [31:0] dac_data_final; + wire [ 3:0] readback_data_shift; + wire [ 4:0] data_increment_valid; + wire if_busy; + + reg [ 7:0] address_write = 8'b0; + reg dac_clk = 1'b0; + reg reset_in = 1'b1; + reg transfer_data = 1'b0; + reg sdr_ddr_n = 1'b1; + reg reg_8b_16bn = 1'b0; + reg stream = 1'b0; + reg [23:0] data_write = 24'h0; + reg dac_data_valid = 1'b0; + reg [ 3:0] shift_count = 4'b0; + reg [31:0] transfer_reg = 32'h89abcdef; + reg [ 4:0] valid_counter = 5'b0; + reg [31:0] dac_data = 32'b0; + + always #4 dac_clk <= ~dac_clk; + + initial begin + + #100 reset_in = 1'b0; + + // Write 8 bit SDR + + address_write = 8'h2c; + data_write = 24'hab0000; + sdr_ddr_n = 1'b1; + reg_8b_16bn = 1'b1; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Read 8 bit SDR + + address_write = 8'hac; + data_write = 24'h000000; + sdr_ddr_n = 1'b1; + reg_8b_16bn = 1'b1; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Write 16 bit SDR + + address_write = 8'h2c; + data_write = 24'h123400; + sdr_ddr_n = 1'b1; + reg_8b_16bn = 1'b0; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Read 16 bit SDR + + address_write = 8'hac; + data_write = 24'h000000; + sdr_ddr_n = 1'b1; + reg_8b_16bn = 1'b0; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + #500; + + // Write 8 bit DDR + + address_write = 8'h2c; + data_write = 24'h120000; + sdr_ddr_n = 1'b0; + reg_8b_16bn = 1'b1; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Read 8 bit DDR + + address_write = 8'hac; + data_write = 24'h000000; + sdr_ddr_n = 1'b0; + reg_8b_16bn = 1'b1; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Write 16 bit DDR + + address_write = 8'h2c; + data_write = 24'h123400; + sdr_ddr_n = 1'b0; + reg_8b_16bn = 1'b0; + stream = 1'b0; + transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + // Read 16 bit DDR + + address_write = 8'hac; + data_write = 24'h000000; + sdr_ddr_n = 1'b0; + reg_8b_16bn = 1'b0; + stream = 1'b0; + #500 transfer_data = 1'b1; + #100 transfer_data = 1'b0; + + #500; + + // Stream SDR + + address_write = 8'h2c; + sdr_ddr_n = 1'b1; + reg_8b_16bn = 1'b0; + stream = 1'b1; + transfer_data = 1'b1; + #100 transfer_data = 1'b0; + #1000 stream = 1'b0; + + #500; + + // Stream DDR + + address_write = 8'h2c; + reg_8b_16bn = 1'b1; + sdr_ddr_n = 1'b0; + stream = 1'b1; + transfer_data = 1'b1; + #100 transfer_data = 1'b0; + #1000 stream = 1'b0; + + end + + // data is incremented at each complete cycle + + assign dac_data_final = (stream == 1'b1) ? dac_data : data_write; + assign data_increment_valid = (sdr_ddr_n ) ? 5'd16: 5'h8; + + always @(posedge dac_clk) begin + if (valid_counter == data_increment_valid) begin + dac_data <= dac_data + 32'h00010002; + valid_counter <= 3'b0; + dac_data_valid <= 1'b1; + end else begin + dac_data <= dac_data; + valid_counter <= valid_counter + 3'b1; + dac_data_valid <= 1'b0; + end + end + + // data is circullary shifted at every sampling edge + + assign readback_data_shift = (sdr_ddr_n ) ? 4'h8 : 4'h4; + assign sdio_i = (sdio_t === 1'b1) ? transfer_reg[31:28] : 4'b0; + + always @(posedge dac_clk) begin + if (shift_count == readback_data_shift) begin + transfer_reg <= {transfer_reg[27:0],transfer_reg[31:28]}; + end else if (sdio_t === 1'b1) begin + transfer_reg <= transfer_reg; + end + if (shift_count == readback_data_shift || dac_csn == 1'b1) begin + shift_count <= 3'b0; + end else if (sdio_t === 1'b1) begin + shift_count <= shift_count + 3'b1; + end + end + + axi_ad3552r_if axi_ad3552r_interface ( + .clk_in(dac_clk), + .reset_in(reset_in), + .dac_data(dac_data_final), + .dac_data_valid(dac_data_valid), + .address(address_write), + .data_read(data_read), + .data_write(data_write), + .sdr_ddr_n(sdr_ddr_n), + .symb_8_16b(reg_8b_16bn), + .transfer_data(transfer_data), + .stream(stream), + .dac_data_ready(dac_data_ready), + .if_busy(if_busy), + .sclk(dac_sclk), + .csn(dac_csn), + .sdio_i(sdio_i), + .sdio_o(sdio_o), + .sdio_t(sdio_t)); + +endmodule diff --git a/library/axi_ad3552r/axi_ad3552r_ip.tcl b/library/axi_ad3552r/axi_ad3552r_ip.tcl new file mode 100755 index 0000000000..561cca398d --- /dev/null +++ b/library/axi_ad3552r/axi_ad3552r_ip.tcl @@ -0,0 +1,51 @@ +############################################################################### +## Copyright (C) 2022-2023 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 + +adi_ip_create axi_ad3552r +adi_ip_files axi_ad3552r [list \ + "$ad_hdl_dir/library/xilinx/common/ad_mul.v" \ + "$ad_hdl_dir/library/common/ad_rst.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_dac_common.v" \ + "$ad_hdl_dir/library/common/up_dac_channel.v" \ + "$ad_hdl_dir/library/common/ad_dds_cordic_pipe.v" \ + "$ad_hdl_dir/library/common/ad_dds_sine_cordic.v" \ + "$ad_hdl_dir/library/common/ad_dds_sine.v" \ + "$ad_hdl_dir/library/common/ad_dds_2.v" \ + "$ad_hdl_dir/library/common/ad_dds_1.v" \ + "$ad_hdl_dir/library/common/ad_dds.v" \ + "$ad_hdl_dir/library/common/ad_addsub.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" \ + "axi_ad3552r_channel.v" \ + "axi_ad3552r_core.v" \ + "axi_ad3552r_if.v" \ + "axi_ad3552r.v" ] + +adi_ip_properties axi_ad3552r +adi_init_bd_tcl +adi_ip_bd axi_ad3552r "bd/bd.tcl" + +set cc [ipx::current_core] + +set_property company_url {https://wiki.analog.com/resources/fpga/docs/axi_ad3552r} $cc + +set_property driver_value 0 [ipx::get_ports *dac* -of_objects $cc] +set_property driver_value 0 [ipx::get_ports *data* -of_objects $cc] +set_property driver_value 0 [ipx::get_ports *valid* -of_objects $cc] +ipx::infer_bus_interface dac_clk xilinx.com:signal:clock_rtl:1.0 $cc + +adi_add_auto_fpga_spec_params + +ipx::create_xgui_files $cc +ipx::save_core $cc From debbc3e0b4bc6726542466a56513a6866976832e Mon Sep 17 00:00:00 2001 From: PopPaul2021 Date: Thu, 7 Sep 2023 09:20:25 +0300 Subject: [PATCH 3/3] projects/ad3552r_evb: Added project for AD3552R-EVB on ZedBoard. The project controls the AD3552R digital-to-analog converter and transmits data written in the DDR memory to the QSPI interface of the DAC. The reference clock is generated by an axi_clkgen IP and is configured to output a 133MHz signal. If both channels are enabled and data streaming is DDR the sample rate is 16.65MSPS. If just one channel is enabled and data streaming is DDR the sample rate is 33.3MSPS. The VADJ voltage should be set to 1.8V. Signed-off-by: PopPaul2021 --- projects/ad3552r_evb/Makefile | 7 + projects/ad3552r_evb/Readme.md | 8 + .../ad3552r_evb/common/ad3552r_evb_bd.tcl | 53 ++++ .../ad3552r_evb/common/ad3552r_evb_fmc.txt | 18 ++ projects/ad3552r_evb/zed/Makefile | 25 ++ projects/ad3552r_evb/zed/system_bd.tcl | 18 ++ projects/ad3552r_evb/zed/system_constr.xdc | 24 ++ projects/ad3552r_evb/zed/system_project.tcl | 17 ++ projects/ad3552r_evb/zed/system_top.v | 244 ++++++++++++++++++ 9 files changed, 414 insertions(+) create mode 100755 projects/ad3552r_evb/Makefile create mode 100755 projects/ad3552r_evb/Readme.md create mode 100755 projects/ad3552r_evb/common/ad3552r_evb_bd.tcl create mode 100755 projects/ad3552r_evb/common/ad3552r_evb_fmc.txt create mode 100755 projects/ad3552r_evb/zed/Makefile create mode 100755 projects/ad3552r_evb/zed/system_bd.tcl create mode 100755 projects/ad3552r_evb/zed/system_constr.xdc create mode 100755 projects/ad3552r_evb/zed/system_project.tcl create mode 100755 projects/ad3552r_evb/zed/system_top.v diff --git a/projects/ad3552r_evb/Makefile b/projects/ad3552r_evb/Makefile new file mode 100755 index 0000000000..1402069e10 --- /dev/null +++ b/projects/ad3552r_evb/Makefile @@ -0,0 +1,7 @@ +#################################################################################### +## Copyright (c) 2018 - 2023 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### + +include ../scripts/project-toplevel.mk diff --git a/projects/ad3552r_evb/Readme.md b/projects/ad3552r_evb/Readme.md new file mode 100755 index 0000000000..4c92e827e6 --- /dev/null +++ b/projects/ad3552r_evb/Readme.md @@ -0,0 +1,8 @@ +# AD3552R-EVB HDL Project + +Here are some pointers to help you: + * [Board Product Page](https://www.analog.com/eval-ad3552r) + * Parts : [ AD3552R Dual Channel, 16-Bit, 33 MUPS, Multispan, Multi-IO SPI DAC ](https://www.analog.com/en/products/ad3552r.html) + * Project Doc: https://wiki.analog.com/resources/eval/user-guides/dac/ad3552r_eval_zed + * HDL Doc: https://wiki.analog.com/resources/eval/user-guides/dac/ad3552r_eval_zed + * Linux Drivers: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-dac/axi-ad3552r \ No newline at end of file diff --git a/projects/ad3552r_evb/common/ad3552r_evb_bd.tcl b/projects/ad3552r_evb/common/ad3552r_evb_bd.tcl new file mode 100755 index 0000000000..34bdc812eb --- /dev/null +++ b/projects/ad3552r_evb/common/ad3552r_evb_bd.tcl @@ -0,0 +1,53 @@ +############################################################################### +## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +create_bd_port -dir O dac_sclk +create_bd_port -dir O dac_csn +create_bd_port -dir I -from 3 -to 0 dac_spi_sdi +create_bd_port -dir O -from 3 -to 0 dac_spi_sdo +create_bd_port -dir O dac_spi_sdo_t + +ad_ip_instance axi_dmac axi_dac_dma +ad_ip_parameter axi_dac_dma CONFIG.DMA_TYPE_SRC 0 +ad_ip_parameter axi_dac_dma CONFIG.DMA_TYPE_DEST 1 +ad_ip_parameter axi_dac_dma CONFIG.CYCLIC 1 +ad_ip_parameter axi_dac_dma CONFIG.SYNC_TRANSFER_START 0 +ad_ip_parameter axi_dac_dma CONFIG.AXI_SLICE_SRC 0 +ad_ip_parameter axi_dac_dma CONFIG.AXI_SLICE_DEST 0 +ad_ip_parameter axi_dac_dma CONFIG.DMA_2D_TRANSFER 0 +ad_ip_parameter axi_dac_dma CONFIG.DMA_DATA_WIDTH_SRC 32 +ad_ip_parameter axi_dac_dma CONFIG.DMA_DATA_WIDTH_DEST 32 + +ad_ip_instance axi_ad3552r axi_ad3552r_dac + +ad_connect axi_ad3552r_dac/dac_sclk dac_sclk +ad_connect axi_ad3552r_dac/dac_csn dac_csn +ad_connect axi_ad3552r_dac/sdio_i dac_spi_sdi +ad_connect axi_ad3552r_dac/sdio_o dac_spi_sdo +ad_connect axi_ad3552r_dac/sdio_t dac_spi_sdo_t +ad_connect axi_ad3552r_dac/dma_data axi_dac_dma/m_axis_data +ad_connect axi_ad3552r_dac/valid_in_dma axi_dac_dma/m_axis_valid +ad_connect axi_ad3552r_dac/dac_data_ready axi_dac_dma/m_axis_ready +ad_connect sys_rstgen/peripheral_aresetn axi_dac_dma/m_src_axi_aresetn + +ad_ip_instance axi_clkgen axi_clkgen +ad_ip_parameter axi_clkgen CONFIG.ID 1 +ad_ip_parameter axi_clkgen CONFIG.CLKIN_PERIOD 10 +ad_ip_parameter axi_clkgen CONFIG.VCO_DIV 1 +ad_ip_parameter axi_clkgen CONFIG.VCO_MUL 8 +ad_ip_parameter axi_clkgen CONFIG.CLK0_DIV 6 + + +ad_connect axi_clkgen/clk sys_ps7/FCLK_CLK0 +ad_connect axi_clkgen/clk_0 axi_ad3552r_dac/dac_clk +ad_connect axi_clkgen/clk_0 axi_dac_dma/m_axis_aclk + +ad_cpu_interconnect 0x44a30000 axi_dac_dma +ad_cpu_interconnect 0x44a70000 axi_ad3552r_dac +ad_cpu_interconnect 0x44B00000 axi_clkgen + +ad_cpu_interrupt "ps-13" "mb-13" axi_dac_dma/irq + +ad_mem_hp0_interconnect sys_cpu_clk axi_dac_dma/m_src_axi diff --git a/projects/ad3552r_evb/common/ad3552r_evb_fmc.txt b/projects/ad3552r_evb/common/ad3552r_evb_fmc.txt new file mode 100755 index 0000000000..9fe5aec7f3 --- /dev/null +++ b/projects/ad3552r_evb/common/ad3552r_evb_fmc.txt @@ -0,0 +1,18 @@ +# ad3552r + +FMC_pin FMC_port Schematic_name System_top_name IOSTANDARD Termination + + D12 FMC_LA05_N /RESET ad3552r_resetn LVCMOS25 #N/A + G6 FMC_LA00_CC_P SPI_SCLK ad3552r_spi_sclk LVCMOS25 #N/A + G7 FMC_LA00_CC_N SPI_/CS ad3552r_spi_cs LVCMOS25 #N/A + H7 FMC_LA02_P SPI_SDIO0 ad3552r_spi_sdio[0] LVCMOS25 #N/A + H8 FMC_LA02_N SPI_SDIO1 ad3552r_spi_sdio[1] LVCMOS25 #N/A + G9 FMC_LA03_P SPI_SDIO2 ad3552r_spi_sdio[2] LVCMOS25 #N/A + G10 FMC_LA03_N SPI_SDIO3 ad3552r_spi_sdio[3] LVCMOS25 #N/A + D11 FMC_LA05_P /LDAC ad3552r_ldacn LVCMOS25 #N/A + H10 FMC_LA04_P /ALERT ad3552r_alertn LVCMOS25 #N/A + H11 FMC_LA04_N SPI_QPI ad3552r_qspi_sel LVCMOS25 #N/A + C10 FMC_LA06_P GPIO_6 ad3552r_gpio_6 LVCMOS25 #N/A + C11 FMC_LA06_N GPIO_7 ad3552r_gpio_7 LVCMOS25 #N/A + H13 FMC_LA07_P GPIO_8 ad3552r_gpio_8 LVCMOS25 #N/A + H14 FMC_LA07_N GPIO_9 ad3552r_gpio_9 LVCMOS25 #N/A \ No newline at end of file diff --git a/projects/ad3552r_evb/zed/Makefile b/projects/ad3552r_evb/zed/Makefile new file mode 100755 index 0000000000..23b67010a7 --- /dev/null +++ b/projects/ad3552r_evb/zed/Makefile @@ -0,0 +1,25 @@ +#################################################################################### +## Copyright (c) 2018 - 2023 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### + +PROJECT_NAME := ad3552r_evb_zed + +M_DEPS += ../common/ad3552r_evb_bd.tcl +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 + +LIB_DEPS += axi_ad3552r +LIB_DEPS += axi_clkgen +LIB_DEPS += axi_dmac +LIB_DEPS += axi_hdmi_tx +LIB_DEPS += axi_i2s_adi +LIB_DEPS += axi_spdif_tx +LIB_DEPS += axi_sysid +LIB_DEPS += sysid_rom +LIB_DEPS += util_i2c_mixer + +include ../../scripts/project-xilinx.mk diff --git a/projects/ad3552r_evb/zed/system_bd.tcl b/projects/ad3552r_evb/zed/system_bd.tcl new file mode 100755 index 0000000000..5e5671b828 --- /dev/null +++ b/projects/ad3552r_evb/zed/system_bd.tcl @@ -0,0 +1,18 @@ +############################################################################### +## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +source $ad_hdl_dir/projects/common/zed/zed_system_bd.tcl +source $ad_hdl_dir/projects/scripts/adi_pd.tcl + +set mem_init_sys_path [get_env_param ADI_PROJECT_DIR ""]mem_init_sys.txt; + +#system ID +ad_ip_parameter axi_sysid_0 CONFIG.ROM_ADDR_BITS 9 +ad_ip_parameter rom_sys_0 CONFIG.PATH_TO_FILE "[pwd]/$mem_init_sys_path" +ad_ip_parameter rom_sys_0 CONFIG.ROM_ADDR_BITS 9 + +sysid_gen_sys_init_file + +source ../common/ad3552r_evb_bd.tcl diff --git a/projects/ad3552r_evb/zed/system_constr.xdc b/projects/ad3552r_evb/zed/system_constr.xdc new file mode 100755 index 0000000000..fcaa6473d5 --- /dev/null +++ b/projects/ad3552r_evb/zed/system_constr.xdc @@ -0,0 +1,24 @@ +############################################################################### +## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +# ad3552r_fmc SPI interface + +set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS25} [get_ports {ad3552r_spi_sdio[0]}] ; # FMC_LA02_P IO_L20P_T3_34 +set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS25} [get_ports {ad3552r_spi_sdio[1]}] ; # FMC_LA02_N IO_L20N_T3_34 +set_property -dict {PACKAGE_PIN N22 IOSTANDARD LVCMOS25} [get_ports {ad3552r_spi_sdio[2]}] ; # FMC_LA03_P IO_L16P_T2_34 +set_property -dict {PACKAGE_PIN P22 IOSTANDARD LVCMOS25} [get_ports {ad3552r_spi_sdio[3]}] ; # FMC_LA03_N IO_L16N_T2_34 + +set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS25 } [get_ports ad3552r_spi_sclk] ; # FMC_LA00_CC_P IO_L13P_T2_MRCC_34 +set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS25 } [get_ports ad3552r_spi_cs] ; # FMC_LA00_CC_N IO_L13N_T2_MRCC_34 + +set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS25} [get_ports ad3552r_ldacn] ; # FMC_LA05_P IO_L7P_T1_34 +set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS25} [get_ports ad3552r_resetn] ; # FMC_LA05_N IO_L7N_T1_34 +set_property -dict {PACKAGE_PIN M21 IOSTANDARD LVCMOS25} [get_ports ad3552r_alertn] ; # FMC_LA04_P IO_L15P_T2_DQS_34 +set_property -dict {PACKAGE_PIN M22 IOSTANDARD LVCMOS25} [get_ports ad3552r_qspi_sel] ; # FMC_LA04_N IO_L15N_T2_DQS_34 + +set_property -dict {PACKAGE_PIN L21 IOSTANDARD LVCMOS25} [get_ports ad3552r_gpio_6] ; # FMC_LA06_P IO_L10P_T1_34 +set_property -dict {PACKAGE_PIN L22 IOSTANDARD LVCMOS25} [get_ports ad3552r_gpio_7] ; # FMC_LA06_N IO_L10N_T1_34 +set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS25} [get_ports ad3552r_gpio_8] ; # FMC_LA07_P IO_L21P_T3_DQS_34 +set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS25} [get_ports ad3552r_gpio_9] ; # FMC_LA07_N IO_L21N_T3_DQS_34 diff --git a/projects/ad3552r_evb/zed/system_project.tcl b/projects/ad3552r_evb/zed/system_project.tcl new file mode 100755 index 0000000000..08440632b8 --- /dev/null +++ b/projects/ad3552r_evb/zed/system_project.tcl @@ -0,0 +1,17 @@ +############################################################################### +## Copyright (C) 2022-2023 Analog Devices, Inc. All rights reserved. +### SPDX short identifier: ADIBSD +############################################################################### + +source ../../../scripts/adi_env.tcl +source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl +source $ad_hdl_dir/projects/scripts/adi_board.tcl + +adi_project ad3552r_evb_zed +adi_project_files ad3552r_evb_zed [list \ + "system_top.v" \ + "system_constr.xdc" \ + "$ad_hdl_dir/projects/common/zed/zed_system_constr.xdc" \ + "$ad_hdl_dir/library/common/ad_iobuf.v" ] + +adi_project_run ad3552r_evb_zed diff --git a/projects/ad3552r_evb/zed/system_top.v b/projects/ad3552r_evb/zed/system_top.v new file mode 100755 index 0000000000..65685a0668 --- /dev/null +++ b/projects/ad3552r_evb/zed/system_top.v @@ -0,0 +1,244 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright (C) 2022-2023 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/master/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 system_top ( + + inout [14:0] ddr_addr, + inout [ 2:0] ddr_ba, + inout ddr_cas_n, + inout ddr_ck_n, + inout ddr_ck_p, + inout ddr_cke, + inout ddr_cs_n, + inout [ 3:0] ddr_dm, + inout [31:0] ddr_dq, + inout [ 3:0] ddr_dqs_n, + inout [ 3:0] ddr_dqs_p, + inout ddr_odt, + inout ddr_ras_n, + inout ddr_reset_n, + inout ddr_we_n, + + inout fixed_io_ddr_vrn, + inout fixed_io_ddr_vrp, + inout [53:0] fixed_io_mio, + inout fixed_io_ps_clk, + inout fixed_io_ps_porb, + inout fixed_io_ps_srstb, + + inout [31:0] gpio_bd, + + output hdmi_out_clk, + output hdmi_vsync, + output hdmi_hsync, + output hdmi_data_e, + output [15:0] hdmi_data, + + output spdif, + + output i2s_mclk, + output i2s_bclk, + output i2s_lrclk, + output i2s_sdata_out, + input i2s_sdata_in, + + inout iic_scl, + inout iic_sda, + inout [ 1:0] iic_mux_scl, + inout [ 1:0] iic_mux_sda, + + input otg_vbusoc, + + // dac interface + + inout ad3552r_ldacn, + inout ad3552r_alertn, + inout ad3552r_gpio_6, + inout ad3552r_gpio_7, + inout ad3552r_gpio_8, + inout ad3552r_gpio_9, + inout [ 3:0] ad3552r_spi_sdio, + output ad3552r_resetn, + output ad3552r_qspi_sel, + output ad3552r_spi_cs, + output ad3552r_spi_sclk +); + + // internal signals + + wire [63:0] gpio_i; + wire [63:0] gpio_o; + wire [63:0] gpio_t; + wire [ 1:0] iic_mux_scl_i_s; + wire [ 1:0] iic_mux_scl_o_s; + wire iic_mux_scl_t_s; + wire [ 1:0] iic_mux_sda_i_s; + wire [ 1:0] iic_mux_sda_o_s; + wire iic_mux_sda_t_s; + wire [ 3:0] ad3552r_spi_sdo; + wire [ 3:0] ad3552r_spi_sdi; + wire ad3552r_spi_t; + + assign gpio_i[63:39] = gpio_o[63:39]; + + assign ad3552r_qspi_sel = 1'b1; + assign ad3552r_resetn = gpio_o[38]; + + ad_iobuf #( + .DATA_WIDTH(4) + ) i_dac_0_spi_iobuf ( + .dio_t({4{ad3552r_spi_t}}), + .dio_i(ad3552r_spi_sdo), + .dio_o(ad3552r_spi_sdi), + .dio_p(ad3552r_spi_sdio)); + + ad_iobuf #( + .DATA_WIDTH(6) + ) i_ad3552r_iobuf ( + .dio_t(gpio_t[37:32]), + .dio_i(gpio_o[37:32]), + .dio_o(gpio_i[37:32]), + .dio_p({ad3552r_gpio_9, + ad3552r_gpio_8, + ad3552r_gpio_7, + ad3552r_gpio_6, + ad3552r_alertn, + ad3552r_ldacn})); + + ad_iobuf #( + .DATA_WIDTH (32) + ) i_iobuf ( + .dio_t (gpio_t[31:0]), + .dio_i (gpio_o[31:0]), + .dio_o (gpio_i[31:0]), + .dio_p (gpio_bd)); + + ad_iobuf #( + .DATA_WIDTH (2) + ) i_iic_mux_scl ( + .dio_t ({iic_mux_scl_t_s, iic_mux_scl_t_s}), + .dio_i (iic_mux_scl_o_s), + .dio_o (iic_mux_scl_i_s), + .dio_p (iic_mux_scl)); + + ad_iobuf #( + .DATA_WIDTH (2) + ) i_iic_mux_sda ( + .dio_t ({iic_mux_sda_t_s, iic_mux_sda_t_s}), + .dio_i (iic_mux_sda_o_s), + .dio_o (iic_mux_sda_i_s), + .dio_p (iic_mux_sda)); + + system_wrapper i_system_wrapper ( + .ddr_addr (ddr_addr), + .ddr_ba (ddr_ba), + .ddr_cas_n (ddr_cas_n), + .ddr_ck_n (ddr_ck_n), + .ddr_ck_p (ddr_ck_p), + .ddr_cke (ddr_cke), + .ddr_cs_n (ddr_cs_n), + .ddr_dm (ddr_dm), + .ddr_dq (ddr_dq), + .ddr_dqs_n (ddr_dqs_n), + .ddr_dqs_p (ddr_dqs_p), + .ddr_odt (ddr_odt), + .ddr_ras_n (ddr_ras_n), + .ddr_reset_n (ddr_reset_n), + .ddr_we_n (ddr_we_n), + + .fixed_io_ddr_vrn (fixed_io_ddr_vrn), + .fixed_io_ddr_vrp (fixed_io_ddr_vrp), + .fixed_io_mio (fixed_io_mio), + .fixed_io_ps_clk (fixed_io_ps_clk), + .fixed_io_ps_porb (fixed_io_ps_porb), + .fixed_io_ps_srstb (fixed_io_ps_srstb), + + .gpio_i (gpio_i), + .gpio_o (gpio_o), + .gpio_t (gpio_t), + + .hdmi_data (hdmi_data), + .hdmi_data_e (hdmi_data_e), + .hdmi_hsync (hdmi_hsync), + .hdmi_out_clk (hdmi_out_clk), + .hdmi_vsync (hdmi_vsync), + + .spdif (spdif), + + .i2s_bclk (i2s_bclk), + .i2s_lrclk (i2s_lrclk), + .i2s_mclk (i2s_mclk), + .i2s_sdata_in (i2s_sdata_in), + .i2s_sdata_out (i2s_sdata_out), + .iic_fmc_scl_io (iic_scl), + .iic_fmc_sda_io (iic_sda), + .iic_mux_scl_i (iic_mux_scl_i_s), + .iic_mux_scl_o (iic_mux_scl_o_s), + .iic_mux_scl_t (iic_mux_scl_t_s), + .iic_mux_sda_i (iic_mux_sda_i_s), + .iic_mux_sda_o (iic_mux_sda_o_s), + .iic_mux_sda_t (iic_mux_sda_t_s), + + .otg_vbusoc (otg_vbusoc), + + .spi0_clk_i (1'b0), + .spi0_clk_o (), + .spi0_csn_0_o (), + .spi0_csn_1_o (), + .spi0_csn_2_o (), + .spi0_csn_i (1'b1), + .spi0_sdi_i (1'b0), + .spi0_sdo_i (1'b0), + .spi0_sdo_o (), + .spi1_clk_i (1'b0), + .spi1_clk_o (), + .spi1_csn_0_o (), + .spi1_csn_1_o (), + .spi1_csn_2_o (), + .spi1_csn_i (1'b1), + .spi1_sdi_i (1'b0), + .spi1_sdo_i (1'b0), + .spi1_sdo_o (), + + //dac interface + + .dac_sclk(ad3552r_spi_sclk), + .dac_csn(ad3552r_spi_cs), + .dac_spi_sdi(ad3552r_spi_sdi), + .dac_spi_sdo(ad3552r_spi_sdo), + .dac_spi_sdo_t(ad3552r_spi_t)); +endmodule