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/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 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 (), 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