From 357b58d786ac6696b8b9b3dafe144f81f6383d79 Mon Sep 17 00:00:00 2001 From: Pop Ioan Daniel Date: Thu, 28 Nov 2024 16:10:35 +0200 Subject: [PATCH] library: axi_ad7616: Add AXI ADC Signed-off-by: Pop Ioan Daniel --- library/axi_ad7616/Makefile | 17 +- library/axi_ad7616/axi_ad7616.v | 420 +++++++++++++++++++----- library/axi_ad7616/axi_ad7616_control.v | 159 --------- library/axi_ad7616/axi_ad7616_ip.tcl | 26 +- library/axi_ad7616/axi_ad7616_pif.v | 211 ++++++++---- 5 files changed, 535 insertions(+), 298 deletions(-) delete mode 100644 library/axi_ad7616/axi_ad7616_control.v diff --git a/library/axi_ad7616/Makefile b/library/axi_ad7616/Makefile index d49c6265c1..a6d38786ef 100644 --- a/library/axi_ad7616/Makefile +++ b/library/axi_ad7616/Makefile @@ -1,16 +1,29 @@ #################################################################################### -## Copyright (c) 2018 - 2023 Analog Devices, Inc. +## Copyright (c) 2018 - 2024 Analog Devices, Inc. ### SPDX short identifier: BSD-1-Clause ## Auto-generated, do not modify! #################################################################################### LIBRARY_NAME := axi_ad7616 +GENERIC_DEPS += ../common/ad_datafmt.v +GENERIC_DEPS += ../common/ad_edge_detect.v +GENERIC_DEPS += ../common/ad_rst.v +GENERIC_DEPS += ../common/up_adc_channel.v +GENERIC_DEPS += ../common/up_adc_common.v GENERIC_DEPS += ../common/up_axi.v +GENERIC_DEPS += ../common/up_clock_mon.v +GENERIC_DEPS += ../common/up_delay_cntrl.v +GENERIC_DEPS += ../common/up_xfer_cntrl.v +GENERIC_DEPS += ../common/up_xfer_status.v GENERIC_DEPS += axi_ad7616.v -GENERIC_DEPS += axi_ad7616_control.v GENERIC_DEPS += axi_ad7616_pif.v +XILINX_DEPS += ../xilinx/common/ad_dcfilter.v +XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc +XILINX_DEPS += ../xilinx/common/up_clock_mon_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_cntrl_constr.xdc +XILINX_DEPS += ../xilinx/common/up_xfer_status_constr.xdc XILINX_DEPS += axi_ad7616_ip.tcl include ../scripts/library.mk diff --git a/library/axi_ad7616/axi_ad7616.v b/library/axi_ad7616/axi_ad7616.v index f93ff54074..04bd5dfb5a 100644 --- a/library/axi_ad7616/axi_ad7616.v +++ b/library/axi_ad7616/axi_ad7616.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2015-2023 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2023-2024 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -37,142 +37,406 @@ module axi_ad7616 #( - parameter ID = 0 + parameter ID = 0 ) ( // physical data interface - output rx_cs_n, - output [15:0] rx_db_o, - input [15:0] rx_db_i, - output rx_db_t, - output rx_rd_n, - output rx_wr_n, + output rx_cs_n, + output [15:0] rx_db_o, + input [15:0] rx_db_i, + output rx_db_t, + output rx_rd_n, + output rx_wr_n, // physical control interface - input rx_trigger, + input rx_trigger, // AXI Slave Memory Map - input s_axi_aclk, - input s_axi_aresetn, - input s_axi_awvalid, - input [15:0] s_axi_awaddr, - input [ 2:0] s_axi_awprot, - output s_axi_awready, - input s_axi_wvalid, - input [31:0] s_axi_wdata, - input [ 3:0] s_axi_wstrb, - output s_axi_wready, - output s_axi_bvalid, - output [ 1:0] s_axi_bresp, - input s_axi_bready, - input s_axi_arvalid, - input [15:0] s_axi_araddr, - input [ 2:0] s_axi_arprot, - output s_axi_arready, - output s_axi_rvalid, - output [ 1:0] s_axi_rresp, - output [31:0] s_axi_rdata, - input s_axi_rready, - - // Write FIFO interface - - output adc_valid, - output [15:0] adc_data, - output adc_sync + 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, + + output adc_valid, + output adc_clk, + input adc_dovf, + + output [15:0] adc_data_0, + output [15:0] adc_data_1, + output [15:0] adc_data_2, + output [15:0] adc_data_3, + output [15:0] adc_data_4, + output [15:0] adc_data_5, + output [15:0] adc_data_6, + output [15:0] adc_data_7, + output [15:0] adc_data_8, + output [15:0] adc_data_9, + output [15:0] adc_data_10, + output [15:0] adc_data_11, + output [15:0] adc_data_12, + output [15:0] adc_data_13, + output [15:0] adc_data_14, + output [15:0] adc_data_15, + + output adc_enable_0, + output adc_enable_1, + output adc_enable_2, + output adc_enable_3, + output adc_enable_4, + output adc_enable_5, + output adc_enable_6, + output adc_enable_7, + output adc_enable_8, + output adc_enable_9, + output adc_enable_10, + output adc_enable_11, + output adc_enable_12, + output adc_enable_13, + output adc_enable_14, + output adc_enable_15, + output adc_reset ); + localparam [31:0] RD_RAW_CAP = 32'h2000; + // internal registers - reg up_wack = 1'b0; - reg up_rack = 1'b0; - reg [31:0] up_rdata = 32'b0; + reg up_wack = 1'b0; + reg up_rack = 1'b0; + reg [31:0] up_rdata = 32'b0; + reg [31:0] up_rdata_r; + reg up_rack_r; + reg up_wack_r; // internal signals - wire up_clk; - wire up_rstn; - wire up_rst; - wire up_rreq_s; - wire [13:0] up_raddr_s; - wire up_wreq_s; - wire [13:0] up_waddr_s; - wire [31:0] up_wdata_s; + wire [15:0] adc_data_0_s; + wire [15:0] adc_data_1_s; + wire [15:0] adc_data_2_s; + wire [15:0] adc_data_3_s; + wire [15:0] adc_data_4_s; + wire [15:0] adc_data_5_s; + wire [15:0] adc_data_6_s; + wire [15:0] adc_data_7_s; + wire [15:0] adc_data_8_s; + wire [15:0] adc_data_9_s; + wire [15:0] adc_data_10_s; + wire [15:0] adc_data_11_s; + wire [15:0] adc_data_12_s; + wire [15:0] adc_data_13_s; + wire [15:0] adc_data_14_s; + wire [15:0] adc_data_15_s; + + wire [255:0] adc_data_s; + wire [ 7:0] adc_custom_control; + + wire adc_dfmt_enable_s[0:15]; + wire adc_dfmt_type_s[0:15]; + wire adc_dfmt_se_s[0:15]; + + wire [15:0] adc_enable; + wire adc_reset_s; - wire up_wack_cntrl_s; - wire up_rack_cntrl_s; - wire [31:0] up_rdata_cntrl_s; + wire [255:0] dma_data; + wire dma_dvalid; - wire trigger_s; + wire up_clk; + wire up_rstn; + wire up_rst; + wire up_rreq_s; + wire [13:0] up_raddr_s; + wire up_wreq_s; + wire [13:0] up_waddr_s; + wire [31:0] up_wdata_s; + wire [31:0] up_rdata_s[0:16]; + wire [16:0] up_rack_s; + wire [16:0] up_wack_s; - wire rd_req_s; - wire wr_req_s; - wire [15:0] wr_data_s; - wire [15:0] rd_data_s; - wire rd_valid_s; - wire [ 4:0] burst_length_s; + wire up_wack_cntrl_s; + wire up_rack_cntrl_s; + wire [31:0] up_rdata_cntrl_s; + + wire trigger_s; + + wire rd_req_s; + wire wr_req_s; + wire [31:0] wr_data_s; + wire [15:0] rd_data_s; + wire rd_valid_s; + wire [ 4:0] burst_length_s; + + wire [31:0] adc_config_ctrl_s; + wire adc_ctrl_status_s; + wire m_axis_ready_s; + wire m_axis_valid_s; + wire [15:0] m_axis_data_s; + wire m_axis_xfer_req_s; + + wire [31:0] adc_config_ctrl; // defaults + assign adc_clk = s_axi_aclk; assign up_clk = s_axi_aclk; assign up_rstn = s_axi_aresetn; assign up_rst = ~s_axi_aresetn; + assign adc_reset = adc_reset_s; + + assign adc_enable_0 = adc_enable[0]; + assign adc_enable_1 = adc_enable[1]; + assign adc_enable_2 = adc_enable[2]; + assign adc_enable_3 = adc_enable[3]; + assign adc_enable_4 = adc_enable[4]; + assign adc_enable_5 = adc_enable[5]; + assign adc_enable_6 = adc_enable[6]; + assign adc_enable_7 = adc_enable[7]; + assign adc_enable_8 = adc_enable[8]; + assign adc_enable_9 = adc_enable[9]; + assign adc_enable_10 = adc_enable[10]; + assign adc_enable_11 = adc_enable[11]; + assign adc_enable_12 = adc_enable[12]; + assign adc_enable_13 = adc_enable[13]; + assign adc_enable_14 = adc_enable[14]; + assign adc_enable_15 = adc_enable[15]; // processor read interface + integer j; + + always @(*) begin + up_rdata_r = 'h00; + up_rack_r = 'h00; + up_wack_r = 'h00; + for (j = 0; j <= 16; j=j+1) begin + up_rack_r = up_rack_r | up_rack_s[j]; + up_wack_r = up_wack_r | up_wack_s[j]; + up_rdata_r = up_rdata_r | up_rdata_s[j]; + end + end + always @(negedge up_rstn or posedge up_clk) begin if (up_rstn == 0) begin - up_wack <= 'd0; - up_rack <= 'd0; up_rdata <= 'd0; + up_rack <= 'd0; + up_wack <= 'd0; end else begin - up_wack <= up_wack_cntrl_s; - up_rack <= up_rack_cntrl_s; - up_rdata <= up_rdata_cntrl_s; + up_rdata <= up_rdata_r; + up_rack <= up_rack_r; + up_wack <= up_wack_r; end end - axi_ad7616_pif i_ad7616_parallel_interface ( + generate + genvar i; + for (i = 0; i < 16; i = i + 1) begin + up_adc_channel #( + .CHANNEL_ID(i) + ) i_up_adc_channel ( + .adc_clk (up_clk), + .adc_rst (adc_reset_s), + .adc_enable (adc_enable[i]), + .adc_iqcor_enb (), + .adc_dcfilt_enb (), + .adc_dfmt_se (adc_dfmt_se_s[i]), + .adc_dfmt_type (adc_dfmt_type_s[i]), + .adc_dfmt_enable (adc_dfmt_enable_s[i]), + .adc_dcfilt_offset (), + .adc_dcfilt_coeff (), + .adc_iqcor_coeff_1 (), + .adc_iqcor_coeff_2 (), + .adc_pnseq_sel (), + .adc_data_sel (), + .adc_pn_err (1'b0), + .adc_pn_oos (1'b0), + .adc_or (1'b0), + .adc_read_data ({16'd0,rd_data_s}), + .adc_status_header(), + .adc_crc_err(), + .up_adc_pn_err (), + .up_adc_pn_oos (), + .up_adc_or (), + .up_usr_datatype_be (), + .up_usr_datatype_signed (), + .up_usr_datatype_shift (), + .up_usr_datatype_total_bits (), + .up_usr_datatype_bits (), + .up_usr_decimation_m (), + .up_usr_decimation_n (), + .adc_usr_datatype_be (1'b0), + .adc_usr_datatype_signed (1'b1), + .adc_usr_datatype_shift (8'd0), + .adc_usr_datatype_total_bits (8'd16), + .adc_usr_datatype_bits (8'd16), + .adc_usr_decimation_m (16'd1), + .adc_usr_decimation_n (16'd1), + .up_rstn (up_rstn), + .up_clk (up_clk), + .up_wreq (up_wreq_s), + .up_waddr (up_waddr_s), + .up_wdata (up_wdata_s), + .up_wack (up_wack_s[i]), + .up_rreq (up_rreq_s), + .up_raddr (up_raddr_s), + .up_rdata (up_rdata_s[i]), + .up_rack (up_rack_s[i])); + end + endgenerate + + genvar k; + generate + for (k = 0;k < 16;k = k + 1) begin + ad_datafmt #( + .DATA_WIDTH (16), + .BITS_PER_SAMPLE (16) + ) i_datafmt ( + .clk (up_clk), + .valid (1'b1), + .data (adc_data_s[k*16+15:k*16]), + .valid_out (dma_dvalid), + .data_out (dma_data[k*16+15:k*16]), + .dfmt_enable (adc_dfmt_enable_s[k]), + .dfmt_type (adc_dfmt_type_s[k]), + .dfmt_se (adc_dfmt_se_s[k])); + end + endgenerate + + axi_ad7616_pif #( + .UP_ADDRESS_WIDTH(14) + ) i_ad7616_parallel_interface ( .cs_n (rx_cs_n), .db_o (rx_db_o), .db_i (rx_db_i), .db_t (rx_db_t), .rd_n (rx_rd_n), .wr_n (rx_wr_n), - .adc_data (adc_data), + .adc_data_0 (adc_data_0_s), + .adc_data_1 (adc_data_1_s), + .adc_data_2 (adc_data_2_s), + .adc_data_3 (adc_data_3_s), + .adc_data_4 (adc_data_4_s), + .adc_data_5 (adc_data_5_s), + .adc_data_6 (adc_data_6_s), + .adc_data_7 (adc_data_7_s), + .adc_data_8 (adc_data_8_s), + .adc_data_9 (adc_data_9_s), + .adc_data_10 (adc_data_10_s), + .adc_data_11 (adc_data_11_s), + .adc_data_12 (adc_data_12_s), + .adc_data_13 (adc_data_13_s), + .adc_data_14 (adc_data_14_s), + .adc_data_15 (adc_data_15_s), .adc_valid (adc_valid), - .adc_sync (adc_sync), .end_of_conv (rx_trigger), .burst_length(burst_length_s), .clk (up_clk), .rstn (up_rstn), .rd_req (rd_req_s), .wr_req (wr_req_s), - .wr_data (wr_data_s), + .wr_data (wr_data_s[15:0]), .rd_data (rd_data_s), .rd_valid (rd_valid_s)); - axi_ad7616_control #( - .ID(ID) - ) i_ad7616_control ( - .up_burst_length (burst_length_s), - .up_read_data (rd_data_s), - .up_read_valid (rd_valid_s), - .up_write_data (wr_data_s), - .up_read_req (rd_req_s), - .up_write_req (wr_req_s), + assign adc_data_s = {adc_data_0_s,adc_data_1_s,adc_data_2_s,adc_data_3_s,adc_data_4_s,adc_data_5_s,adc_data_6_s,adc_data_7_s,adc_data_8_s,adc_data_9_s, + adc_data_10_s,adc_data_11_s,adc_data_12_s,adc_data_13_s,adc_data_14_s,adc_data_15_s}; + + assign adc_data_15 = dma_data[0*16+15:0*16]; + assign adc_data_14 = dma_data[1*16+15:1*16]; + assign adc_data_13 = dma_data[2*16+15:2*16]; + assign adc_data_12 = dma_data[3*16+15:3*16]; + assign adc_data_11 = dma_data[4*16+15:4*16]; + assign adc_data_10 = dma_data[5*16+15:5*16]; + assign adc_data_9 = dma_data[6*16+15:6*16]; + assign adc_data_8 = dma_data[7*16+15:7*16]; + assign adc_data_7 = dma_data[8*16+15:8*16]; + assign adc_data_6 = dma_data[9*16+15:9*16]; + assign adc_data_5 = dma_data[10*16+15:10*16]; + assign adc_data_4 = dma_data[11*16+15:11*16]; + assign adc_data_3 = dma_data[12*16+15:12*16]; + assign adc_data_2 = dma_data[13*16+15:13*16]; + assign adc_data_1 = dma_data[14*16+15:14*16]; + assign adc_data_0 = dma_data[15*16+15:15*16]; + + assign wr_req_s = adc_config_ctrl[0]; + assign rd_req_s = adc_config_ctrl[1]; + assign burst_length_s = adc_custom_control[4:0]; + + up_adc_common #( + .ID (ID), + .CONFIG (RD_RAW_CAP) + ) i_up_adc_common ( + .mmcm_rst (), + .adc_clk (up_clk), + .adc_rst (adc_reset_s), + .adc_r1_mode (), + .adc_ddr_edgesel (), + .adc_pin_mode (), + .adc_status (), + .adc_sync_status (1'b1), + .adc_status_ovf (adc_dovf), + .adc_clk_ratio (), + .adc_start_code (), + .adc_sref_sync (), + .adc_sync (), + .adc_ext_sync_arm (), + .adc_ext_sync_disarm (), + .adc_ext_sync_manual_req (), + .adc_num_lanes (), + .adc_custom_control (adc_custom_control), + .adc_crc_enable (), + .adc_sdr_ddr_n (), + .adc_symb_op (), + .adc_symb_8_16b (), + .up_pps_rcounter (), + .up_pps_status (), + .up_pps_irq_mask (), + .up_adc_r1_mode (), + .up_status_pn_err (), + .up_status_pn_oos (), + .up_status_or (), + .up_drp_sel (), + .up_drp_wr (), + .up_drp_addr (), + .up_drp_wdata (), + .up_drp_rdata (), + .up_drp_ready (), + .up_drp_locked (1'b1), + .adc_config_wr (wr_data_s), + .adc_config_ctrl (adc_config_ctrl), + .adc_config_rd ({16'd0, rd_data_s}), + .adc_ctrl_status (1'b1), + .up_adc_gpio_in (), + .up_adc_gpio_out (), + .up_adc_ce (), .up_rstn (up_rstn), .up_clk (up_clk), .up_wreq (up_wreq_s), .up_waddr (up_waddr_s), .up_wdata (up_wdata_s), - .up_wack (up_wack_cntrl_s), + .up_wack (up_wack_s[16]), .up_rreq (up_rreq_s), .up_raddr (up_raddr_s), - .up_rdata (up_rdata_cntrl_s), - .up_rack (up_rack_cntrl_s)); + .up_rdata (up_rdata_s[16]), + .up_rack (up_rack_s[16])); // up bus interface diff --git a/library/axi_ad7616/axi_ad7616_control.v b/library/axi_ad7616/axi_ad7616_control.v deleted file mode 100644 index 3283922a10..0000000000 --- a/library/axi_ad7616/axi_ad7616_control.v +++ /dev/null @@ -1,159 +0,0 @@ -// *************************************************************************** -// *************************************************************************** -// Copyright (C) 2015-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/main/LICENSE_ADIBSD -// This will allow to generate bit files and not release the source code, -// as long as it attaches to an ADI device. -// -// *************************************************************************** -// *************************************************************************** - -`timescale 1ns/100ps - -module axi_ad7616_control #( - - parameter ID = 0 -) ( - - // control signals - - input [15:0] up_read_data, - input up_read_valid, - output reg [15:0] up_write_data, - output up_read_req, - output up_write_req, - - output reg [ 4:0] up_burst_length, - - // bus 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 -); - - localparam PCORE_VERSION = 'h00001002; - localparam POS_EDGE = 0; - localparam NEG_EDGE = 1; - - // internal signals - - reg [31:0] up_scratch = 32'b0; - reg up_resetn = 1'b0; - reg up_cnvst_en = 1'b0; - reg [31:0] up_conv_rate = 32'b0; - - reg [31:0] cnvst_counter = 32'b0; - reg [ 3:0] pulse_counter = 8'b0; - reg cnvst_buf = 1'b0; - reg cnvst_pulse = 1'b0; - reg [ 2:0] chsel_ff = 3'b0; - - wire up_rst; - wire up_rack_s; - - wire [31:0] up_read_data_s; - wire up_read_valid_s; - - // the up_[read/write]_data interfaces are valid just in parallel mode - - assign up_read_valid_s = up_read_valid; - assign up_read_data_s = {16'h0, up_read_data}; - - // processor write interface - - always @(negedge up_rstn or posedge up_clk) begin - if (up_rstn == 0) begin - up_wack <= 1'h0; - up_scratch <= 32'b0; - up_resetn <= 1'b0; - up_cnvst_en <= 1'b0; - up_conv_rate <= 32'b0; - up_burst_length <= 5'h0; - up_write_data <= 16'h0; - end else begin - up_wack <= up_wreq; - if ((up_wreq == 1'b1) && (up_waddr[8:0] == 9'h102)) begin - up_scratch <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr[8:0] == 9'h110)) begin - up_resetn <= up_wdata[0]; - up_cnvst_en <= up_wdata[1]; - end - if ((up_wreq == 1'b1) && (up_waddr[8:0] == 9'h111)) begin - up_conv_rate <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr[8:0] == 9'h112)) begin - up_burst_length <= up_wdata; - end - if ((up_wreq == 1'b1) && (up_waddr[8:0] == 9'h114)) begin - up_write_data <= up_wdata; - end - end - end - - assign up_write_req = (up_waddr[8:0] == 9'h114) ? up_wreq : 1'h0; - - // processor read interface - - assign up_rack_s = (up_raddr[8:0] == 9'h113) ? up_read_valid_s : up_rreq; - assign up_read_req = (up_raddr[8:0] == 9'h113) ? up_rreq : 1'b0; - - always @(negedge up_rstn or posedge up_clk) begin - if (up_rstn == 0) begin - up_rack <= 1'b0; - up_rdata <= 32'b0; - end else begin - up_rack <= up_rack_s; - if (up_rack_s == 1'b1) begin - case (up_raddr[8:0]) - 9'h100 : up_rdata <= PCORE_VERSION; - 9'h101 : up_rdata <= ID; - 9'h102 : up_rdata <= up_scratch; - 9'h110 : up_rdata <= {29'b0, up_cnvst_en, up_resetn}; - 9'h111 : up_rdata <= up_conv_rate; - 9'h112 : up_rdata <= {27'b0, up_burst_length}; - 9'h113 : up_rdata <= up_read_data_s; - default : up_rdata <= 'h0; - endcase - end - end - end - - // instantiations - - assign up_rst = ~up_rstn; - -endmodule diff --git a/library/axi_ad7616/axi_ad7616_ip.tcl b/library/axi_ad7616/axi_ad7616_ip.tcl index ca1c98e2a2..987195455f 100644 --- a/library/axi_ad7616/axi_ad7616_ip.tcl +++ b/library/axi_ad7616/axi_ad7616_ip.tcl @@ -1,5 +1,5 @@ ############################################################################### -## Copyright (C) 2015-2023 Analog Devices, Inc. All rights reserved. +## Copyright (C) 2015-2024 Analog Devices, Inc. All rights reserved. ### SPDX short identifier: ADIBSD ############################################################################### @@ -10,9 +10,23 @@ source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl global VIVADO_IP_LIBRARY adi_ip_create axi_ad7616 + adi_ip_files axi_ad7616 [list \ + "$ad_hdl_dir/library/common/ad_edge_detect.v" \ + "$ad_hdl_dir/library/common/ad_rst.v" \ "$ad_hdl_dir/library/common/up_axi.v" \ - "axi_ad7616_control.v" \ + "$ad_hdl_dir/library/xilinx/common/ad_dcfilter.v" \ + "$ad_hdl_dir/library/common/ad_datafmt.v" \ + "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ + "$ad_hdl_dir/library/common/up_xfer_status.v" \ + "$ad_hdl_dir/library/common/up_clock_mon.v" \ + "$ad_hdl_dir/library/common/up_delay_cntrl.v" \ + "$ad_hdl_dir/library/common/up_adc_channel.v" \ + "$ad_hdl_dir/library/common/up_adc_common.v" \ + "$ad_hdl_dir/library/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_ad7616_pif.v" \ "axi_ad7616.v" ] @@ -20,6 +34,12 @@ adi_ip_properties axi_ad7616 set_property company_url {https://wiki.analog.com/resources/fpga/docs/axi_ad7616} [ipx::current_core] +set cc [ipx::current_core] + set_property DRIVER_VALUE "0" [ipx::get_ports rx_db_i] -ipx::save_core [ipx::current_core] +set_property display_name "AXI AD7616" $cc +set_property description "AXI AD7616 HDL interface" $cc + +ipx::create_xgui_files $cc +ipx::save_core $cc diff --git a/library/axi_ad7616/axi_ad7616_pif.v b/library/axi_ad7616/axi_ad7616_pif.v index 4ad8a4a4a1..863337345b 100644 --- a/library/axi_ad7616/axi_ad7616_pif.v +++ b/library/axi_ad7616/axi_ad7616_pif.v @@ -1,6 +1,6 @@ // *************************************************************************** // *************************************************************************** -// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved. +// Copyright (C) 2014-2024 Analog Devices, Inc. All rights reserved. // // In this HDL repository, there are many different and unique modules, consisting // of various HDL (Verilog or VHDL) components. The individual modules are @@ -42,64 +42,89 @@ module axi_ad7616_pif #( // physical interface - output cs_n, - output [15:0] db_o, - input [15:0] db_i, - output db_t, - output rd_n, - output wr_n, + output cs_n, + output [15:0] db_o, + input [15:0] db_i, + output db_t, + output rd_n, + output wr_n, // FIFO interface - output [15:0] adc_data, - output adc_valid, - output reg adc_sync, + output reg [15:0] adc_data_0 = 16'b0, + output reg [15:0] adc_data_1 = 16'b0, + output reg [15:0] adc_data_2 = 16'b0, + output reg [15:0] adc_data_3 = 16'b0, + output reg [15:0] adc_data_4 = 16'b0, + output reg [15:0] adc_data_5 = 16'b0, + output reg [15:0] adc_data_6 = 16'b0, + output reg [15:0] adc_data_7 = 16'b0, + output reg [15:0] adc_data_8 = 16'b0, + output reg [15:0] adc_data_9 = 16'b0, + output reg [15:0] adc_data_10 = 16'b0, + output reg [15:0] adc_data_11 = 16'b0, + output reg [15:0] adc_data_12 = 16'b0, + output reg [15:0] adc_data_13 = 16'b0, + output reg [15:0] adc_data_14 = 16'b0, + output reg [15:0] adc_data_15 = 16'b0, + + output adc_valid, // end of convertion - input end_of_conv, - input [ 4:0] burst_length, + input end_of_conv, + input [ 4:0] burst_length, // register access - input clk, - input rstn, - input rd_req, - input wr_req, - input [15:0] wr_data, - output reg [15:0] rd_data, - output reg rd_valid + input clk, + input rstn, + input rd_req, + input wr_req, + input [15:0] wr_data, + output reg [15:0] rd_data, + output reg rd_valid ); // state registers - localparam [ 2:0] IDLE = 3'h0, - CS_LOW = 3'h1, - CNTRL0_LOW = 3'h2, - CNTRL0_HIGH = 3'h3, - CNTRL1_LOW = 3'h4, - CNTRL1_HIGH = 3'h5, - CS_HIGH = 3'h6; + localparam [ 2:0] IDLE = 3'h0, + CS_LOW = 3'h1, + CNTRL0_LOW = 3'h2, + CNTRL0_HIGH = 3'h3, + CNTRL1_LOW = 3'h4, + CNTRL1_HIGH = 3'h5, + CS_HIGH = 3'h6; // internal registers - reg [ 2:0] transfer_state = 3'h0; - reg [ 2:0] transfer_state_next = 3'h0; - reg [ 1:0] width_counter = 2'h0; - reg [ 4:0] burst_counter = 5'h0; + reg [ 2:0] transfer_state = 3'h0; + reg [ 2:0] transfer_state_next = 3'h0; + reg [ 1:0] width_counter = 2'h0; + reg [ 4:0] burst_counter = 5'h0; - reg wr_req_d = 1'h0; - reg rd_req_d = 1'h0; - reg rd_conv_d = 1'h0; + reg wr_req_d = 1'h0; + reg rd_req_d = 1'h0; + reg rd_conv_d = 1'h0; - reg xfer_req_d = 1'h0; + reg xfer_req_d = 1'h0; - reg rd_valid_d = 1'h0; + reg rd_valid_d = 1'h0; + + reg [ 4:0] channel_counter = 5'h0; + reg [ 4:0] nr_rd_burst = 5'd16; + reg wr_req_edge = 1'h0; + reg wr_req_edge_d = 1'h0; + reg rd_req_edge = 1'h0; + reg rd_req_edge_d = 1'h0; + reg adc_valid_s = 1'h0; // internal wires - wire start_transfer_s; - wire rd_valid_s; + wire rd_new_data_s; + wire start_transfer_s; + wire rd_valid_s; + wire adc_valid_d; // FSM state register @@ -138,14 +163,90 @@ module axi_ad7616_pif #( end end - always @(negedge clk) begin - if (transfer_state == IDLE) begin + always @(posedge clk) begin wr_req_d <= wr_req; + wr_req_edge <= (wr_req && !wr_req_d); rd_req_d <= rd_req; + rd_req_edge <= (rd_req && !rd_req_d); + if (transfer_state == IDLE) begin rd_conv_d <= end_of_conv; end end + //delay with 1 clk + + always @(posedge clk) begin + wr_req_edge_d <= wr_req_edge; + rd_req_edge_d <= rd_req_edge; + end + + always @(posedge clk) begin + if (rstn == 1'b0) begin + channel_counter <= 5'h0; + end else begin + if (rd_new_data_s == 1'b1 && rd_conv_d == 1'b1) begin + channel_counter <= channel_counter + 1; + end else if (channel_counter == nr_rd_burst) begin + channel_counter <= 5'h0; + end + end + end + + always @(posedge clk) begin + if (rd_conv_d == 1'b1 && rd_new_data_s == 1'b1) begin + case (channel_counter) + 5'd0 : begin + adc_data_0 <= rd_data; + end + 5'd1 : begin + adc_data_1 <= rd_data; + end + 5'd2 : begin + adc_data_2 <= rd_data; + end + 5'd3 : begin + adc_data_3 <= rd_data; + end + 5'd4 : begin + adc_data_4 <= rd_data; + end + 5'd5 : begin + adc_data_5 <= rd_data; + end + 5'd6 : begin + adc_data_6 <= rd_data; + end + 5'd7 : begin + adc_data_7 <= rd_data; + end + 5'd8 : begin + adc_data_8 <= rd_data; + end + 5'd9 : begin + adc_data_9 <= rd_data; + end + 5'd10 : begin + adc_data_10 <= rd_data; + end + 5'd11 : begin + adc_data_11 <= rd_data; + end + 5'd12 : begin + adc_data_12 <= rd_data; + end + 5'd13 : begin + adc_data_13 <= rd_data; + end + 5'd14 : begin + adc_data_14 <= rd_data; + end + 5'd15 : begin + adc_data_15 <= rd_data; + end + endcase + end + end + // FSM next state logic always @(*) begin @@ -161,7 +262,7 @@ module axi_ad7616_pif #( end CNTRL0_HIGH : begin transfer_state_next <= (width_counter != 2'b11) ? CNTRL0_HIGH : - ((wr_req_d == 1'b1) || (rd_req_d == 1'b1)) ? CS_HIGH : CNTRL1_LOW; + ((wr_req_edge_d == 1'b1) || (rd_req_edge_d == 1'b1)) ? CS_HIGH : CNTRL1_LOW; end CNTRL1_LOW : begin transfer_state_next <= (width_counter != 2'b11) ? CNTRL1_LOW : CNTRL1_HIGH; @@ -170,7 +271,7 @@ module axi_ad7616_pif #( transfer_state_next <= (width_counter != 2'b11) ? CNTRL1_HIGH : CS_HIGH; end CS_HIGH : begin - transfer_state_next <= (burst_length == burst_counter) ? IDLE : CNTRL0_LOW; + transfer_state_next <= (burst_length == burst_counter || channel_counter == nr_rd_burst) ? IDLE : CNTRL0_LOW; end default : begin transfer_state_next <= IDLE; @@ -181,35 +282,33 @@ module axi_ad7616_pif #( // data valid for the register access and m_axis interface assign rd_valid_s = (((transfer_state == CNTRL0_HIGH) || (transfer_state == CNTRL1_HIGH)) && - ((rd_req_d == 1'b1) || (rd_conv_d == 1'b1))) ? 1'b1 : 1'b0; + ((rd_req_edge_d == 1'b1) || (rd_conv_d == 1'b1))) ? 1'b1 : 1'b0; // FSM output logic assign db_o = wr_data; + assign rd_new_data_s = rd_valid_s & ~rd_valid_d; + always @(posedge clk) begin rd_data <= (rd_valid_s & ~rd_valid_d) ? db_i : rd_data; rd_valid_d <= rd_valid_s; rd_valid <= rd_valid_s & ~rd_valid_d; end - assign adc_valid = rd_valid; - assign adc_data = rd_data; + assign adc_valid_d = (channel_counter == 5'd16) ? rd_valid : 1'b0; - assign cs_n = (transfer_state == IDLE) ? 1'b1 : 1'b0; - assign db_t = ~wr_req_d; - assign rd_n = (((transfer_state == CNTRL0_LOW) && ((rd_conv_d == 1'b1) || rd_req_d == 1'b1)) || - (transfer_state == CNTRL1_LOW)) ? 1'b0 : 1'b1; - assign wr_n = ((transfer_state == CNTRL0_LOW) && (wr_req_d == 1'b1)) ? 1'b0 : 1'b1; - - // sync will be asserted at the first valid data right after the convertion start + //delay with 1 clk always @(posedge clk) begin - if (end_of_conv == 1'b1) begin - adc_sync <= 1'b1; - end else if (rd_valid == 1'b1) begin - adc_sync <= 1'b0; - end + adc_valid_s <= adc_valid_d; end + assign adc_valid = adc_valid_s; + assign cs_n = (transfer_state == IDLE) ? 1'b1 : 1'b0; + assign db_t = ~wr_req_edge_d; + assign rd_n = (((transfer_state == CNTRL0_LOW) && ((rd_conv_d == 1'b1) || rd_req_edge_d == 1'b1)) || + (transfer_state == CNTRL1_LOW)) ? 1'b0 : 1'b1; + assign wr_n = ((transfer_state == CNTRL0_LOW) && (wr_req_edge_d == 1'b1)) ? 1'b0 : 1'b1; + endmodule