library:axi_adrv9001: Initial version

ADRV9001 interfacing IP supports the following modes on Xilinx devices:

A              B  C       D       E       F      G        H
CSSI__1-lane   1  32      80      80      2.5    SDR      8
CSSI__1-lane   1  32      160     80      5      DDR      4
CSSI__4-lane   4  8       80      80      10     SDR      2
CSSI__4-lane   4  8       160     80      20     DDR      1
LSSI__1-lane   1  32      983.04  491.52  30.72  DDR      4
LSSI__2-lane   2  16      983.04  491.52  61.44  DDR      2

Columns description:
A - SSI Modes
B - Data Lanes Per Channel
C - Serialization factor Per data lane
D - Max data lane rate(MHz)
E - Max Clock rate (MHz)
F - Max Sample Rate for I/Q (MHz)
G - Data Type
H - DDS Rate

CSSI - CMOS Source Synchronous Interface
LSSI - LVDS Source Synchronous Interface

Intel devices supports only CSSI modes.
main
Laszlo Nagy 2020-06-02 07:27:27 +01:00 committed by Laszlo Nagy
parent 8e243b6d32
commit 64f6762a05
22 changed files with 4747 additions and 0 deletions

View File

@ -33,6 +33,7 @@ clean:
$(MAKE) -C axi_ad9963 clean $(MAKE) -C axi_ad9963 clean
$(MAKE) -C axi_adc_decimate clean $(MAKE) -C axi_adc_decimate clean
$(MAKE) -C axi_adc_trigger clean $(MAKE) -C axi_adc_trigger clean
$(MAKE) -C axi_adrv9001 clean
$(MAKE) -C axi_adrv9009 clean $(MAKE) -C axi_adrv9009 clean
$(MAKE) -C axi_clkgen clean $(MAKE) -C axi_clkgen clean
$(MAKE) -C axi_dac_interpolate clean $(MAKE) -C axi_dac_interpolate clean
@ -146,6 +147,7 @@ lib:
$(MAKE) -C axi_ad9963 $(MAKE) -C axi_ad9963
$(MAKE) -C axi_adc_decimate $(MAKE) -C axi_adc_decimate
$(MAKE) -C axi_adc_trigger $(MAKE) -C axi_adc_trigger
$(MAKE) -C axi_adrv9001
$(MAKE) -C axi_adrv9009 $(MAKE) -C axi_adrv9009
$(MAKE) -C axi_clkgen $(MAKE) -C axi_clkgen
$(MAKE) -C axi_dac_interpolate $(MAKE) -C axi_dac_interpolate

View File

@ -0,0 +1,66 @@
####################################################################################
## Copyright 2018(c) Analog Devices, Inc.
## Auto-generated, do not modify!
####################################################################################
LIBRARY_NAME := axi_adrv9001
GENERIC_DEPS += adrv9001_rx.v
GENERIC_DEPS += adrv9001_rx_link.v
GENERIC_DEPS += adrv9001_tx.v
GENERIC_DEPS += adrv9001_tx_link.v
GENERIC_DEPS += adrv9001_aligner4.v
GENERIC_DEPS += adrv9001_aligner8.v
GENERIC_DEPS += axi_adrv9001.v
GENERIC_DEPS += axi_adrv9001_core.v
GENERIC_DEPS += axi_adrv9001_if.v
GENERIC_DEPS += axi_adrv9001_rx.v
GENERIC_DEPS += axi_adrv9001_rx_channel.v
GENERIC_DEPS += axi_adrv9001_tx.v
GENERIC_DEPS += axi_adrv9001_tx_channel.v
GENERIC_DEPS += adrv9001_pack.v
XILINX_DEPS += ../common/ad_datafmt.v
XILINX_DEPS += ../common/ad_dds.v
XILINX_DEPS += ../common/ad_dds_1.v
XILINX_DEPS += ../common/ad_dds_2.v
XILINX_DEPS += ../common/ad_dds_cordic_pipe.v
XILINX_DEPS += ../common/ad_dds_sine.v
XILINX_DEPS += ../common/ad_dds_sine_cordic.v
XILINX_DEPS += ../common/ad_pngen.v
XILINX_DEPS += ../common/ad_pnmon.v
XILINX_DEPS += ../common/ad_rst.v
XILINX_DEPS += ../common/up_adc_channel.v
XILINX_DEPS += ../common/up_adc_common.v
XILINX_DEPS += ../common/up_axi.v
XILINX_DEPS += ../common/up_clock_mon.v
XILINX_DEPS += ../common/up_dac_channel.v
XILINX_DEPS += ../common/up_dac_common.v
XILINX_DEPS += ../common/up_delay_cntrl.v
XILINX_DEPS += ../common/up_xfer_cntrl.v
XILINX_DEPS += ../common/up_xfer_status.v
XILINX_DEPS += ../xilinx/common/ad_mmcm_drp.v
XILINX_DEPS += ../xilinx/common/ad_mul.v
XILINX_DEPS += ../xilinx/common/ad_rst_constr.xdc
XILINX_DEPS += ../xilinx/common/ad_serdes_clk.v
XILINX_DEPS += ../xilinx/common/ad_serdes_in.v
XILINX_DEPS += ../xilinx/common/ad_serdes_out.v
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_adrv9001_constr.xdc
XILINX_DEPS += axi_adrv9001_ip.tcl
XILINX_LIB_DEPS += util_cdc
INTEL_DEPS += ../intel/common/ad_mul.v
INTEL_DEPS += ../intel/common/up_clock_mon_constr.sdc
INTEL_DEPS += ../intel/common/up_rst_constr.sdc
INTEL_DEPS += ../intel/common/up_xfer_cntrl_constr.sdc
INTEL_DEPS += ../intel/common/up_xfer_status_constr.sdc
INTEL_DEPS += intel/adrv9001_rx.v
INTEL_DEPS += intel/adrv9001_tx.v
INTEL_DEPS += axi_adrv9001_constr.sdc
INTEL_DEPS += axi_adrv9001_hw.tcl
include ../scripts/library.mk

View File

@ -0,0 +1,82 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_aligner4 (
input clk,
input [3:0] idata,
input ivalid,
input [3:0] strobe,
output reg [3:0] odata,
output ovalid
);
reg [3:0] idata_d = 'b0;
reg ivalid_d = 'b0;
always @(posedge clk) begin
if (ivalid) begin
idata_d <= idata;
end
ivalid_d <= ivalid;
end
reg [1:0] phase = 'h0;
always @(posedge clk) begin
if (ivalid) begin
if ((strobe != 'b1111) && (strobe != 'b0000)) begin
casex (strobe)
'b1xxx : phase <= 0;
'b01xx : phase <= 1;
'b001x : phase <= 2;
'b0001 : phase <= 3;
default : phase <= phase;
endcase
end
end
end
always @(posedge clk) begin
case (phase)
0 : odata <= idata_d;
1 : odata <= {idata_d[2:0],idata[3:3]};
2 : odata <= {idata_d[1:0],idata[3:2]};
3 : odata <= {idata_d[0:0],idata[3:1]};
endcase
end
assign ovalid = ivalid_d;
endmodule

View File

@ -0,0 +1,90 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_aligner8 (
input clk,
input [7:0] idata,
input ivalid,
input [7:0] strobe,
output reg [7:0] odata,
output ovalid
);
reg [7:0] idata_d = 'b0;
reg ivalid_d = 'b0;
always @(posedge clk) begin
if (ivalid) begin
idata_d <= idata;
end
ivalid_d <= ivalid;
end
reg [2:0] phase = 'h0;
always @(posedge clk) begin
if (ivalid) begin
if ((strobe != 'b1111_1111) && (strobe != 'b0000_0000)) begin
casex (strobe)
'b1xxx_xxxx : phase <= 0;
'b01xx_xxxx : phase <= 1;
'b001x_xxxx : phase <= 2;
'b0001_xxxx : phase <= 3;
'b0000_1xxx : phase <= 4;
'b0000_01xx : phase <= 5;
'b0000_001x : phase <= 6;
'b0000_0001 : phase <= 7;
default : phase <= phase;
endcase
end
end
end
always @(posedge clk) begin
case (phase)
0 : odata <= idata_d;
1 : odata <= {idata_d[6:0],idata[7:7]};
2 : odata <= {idata_d[5:0],idata[7:6]};
3 : odata <= {idata_d[4:0],idata[7:5]};
4 : odata <= {idata_d[3:0],idata[7:4]};
5 : odata <= {idata_d[2:0],idata[7:3]};
6 : odata <= {idata_d[1:0],idata[7:2]};
7 : odata <= {idata_d[0:0],idata[7:1]};
endcase
end
assign ovalid = ivalid_d;
endmodule

View File

@ -0,0 +1,86 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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
//
// Pack two input beats into one and align it based on start of frame
//
// Frame size 2 beats:
// Temporal ordering of input:
// idata : MS Beat, LS Beat, MS Beat, LS Beat, ...
// sof : 1, 0, 1, 0, ...
// Format of output beats: {MS Beat, LS Beat}
//
// Frame size 4 beats:
// Temporal ordering of input:
// idata : MS Beat, LS Beat, MS Beat, LS Beat, MS Beat, LS Beat, ...
// sof : 1, 0, 0, 0, 1, 0, ...
module adrv9001_pack #(
parameter WIDTH = 8
)(
input clk, // Input clock
input sof, // Start of frame indicator marking the MS Beat
input [WIDTH-1:0] idata, // Input data beat
input ivalid, // Input data qualifier
output reg [WIDTH*2-1:0] odata, // Output data beat
output reg ovalid, // Output data qualifier
output reg osof // Output Start of frame indicator
);
reg [WIDTH-1:0] idata_d = {WIDTH{1'b0}};
always @(posedge clk) begin
if (ivalid) begin
idata_d <= idata;
end
end
// Single clock mode:
reg [6:0] sof_d = 7'b000;
// Use sof_d[2] for frame size of 4 beats
// Use sof_d[4,6] for frame size of 8 beats
always @(posedge clk) begin
if (ivalid) begin
sof_d <= {sof_d[5:0],sof};
end
if (ivalid &(sof_d[0] | sof_d[2] | sof_d[4] | sof_d[6])) begin
odata <= {idata_d,idata};
end
ovalid <= ivalid & (sof_d[0] | sof_d[2] | sof_d[4] | sof_d[6]);
osof <= ivalid & sof_d[0];
end
endmodule

View File

@ -0,0 +1,270 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_rx #(
parameter CMOS_LVDS_N = 0,
parameter FPGA_TECHNOLOGY = 0,
parameter NUM_LANES = 3,
parameter DRP_WIDTH = 5,
parameter IODELAY_CTRL = 0,
parameter IO_DELAY_GROUP = "dev_if_delay_group"
) (
// device interface
input rx_dclk_in_n_NC,
input rx_dclk_in_p_dclk_in,
input rx_idata_in_n_idata0,
input rx_idata_in_p_idata1,
input rx_qdata_in_n_qdata2,
input rx_qdata_in_p_qdata3,
input rx_strobe_in_n_NC,
input rx_strobe_in_p_strobe_in,
// internal reset and clocks
input adc_rst,
output adc_clk,
output adc_clk_div,
output [7:0] adc_data_0,
output [7:0] adc_data_1,
output [7:0] adc_data_2,
output [7:0] adc_data_3,
output [7:0] adc_data_strobe,
output adc_valid,
// delay interface (for IDELAY macros)
input up_clk,
input [NUM_LANES-1:0] up_adc_dld,
input [DRP_WIDTH*NUM_LANES-1:0] up_adc_dwdata,
output [DRP_WIDTH*NUM_LANES-1:0] up_adc_drdata,
input delay_clk,
input delay_rst,
output delay_locked,
input mssi_sync,
output ssi_sync_out,
input ssi_sync_in,
output ssi_rst
);
// Use always DDR mode
localparam DDR_OR_SDR_N = 1;
localparam SEVEN_SERIES = 1;
localparam ULTRASCALE = 2;
localparam ULTRASCALE_PLUS = 3;
// internal wire
wire clk_in_s;
wire [NUM_LANES-1:0] serdes_in_p;
wire [NUM_LANES-1:0] serdes_in_n;
wire [NUM_LANES-1:0] data_s0;
wire [NUM_LANES-1:0] data_s1;
wire [NUM_LANES-1:0] data_s2;
wire [NUM_LANES-1:0] data_s3;
wire [NUM_LANES-1:0] data_s4;
wire [NUM_LANES-1:0] data_s5;
wire [NUM_LANES-1:0] data_s6;
wire [NUM_LANES-1:0] data_s7;
wire adc_clk_in_fast;
// internal registers
// data interface
ad_serdes_in #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.IODELAY_CTRL (IODELAY_CTRL),
.IODELAY_GROUP (IO_DELAY_GROUP),
.DDR_OR_SDR_N (DDR_OR_SDR_N),
.DATA_WIDTH (NUM_LANES),
.DRP_WIDTH (DRP_WIDTH),
.SERDES_FACTOR (8))
i_serdes (
.rst (adc_rst|ssi_rst),
.clk (adc_clk_in_fast),
.div_clk (adc_clk_div),
.loaden (1'b0),
.phase (8'b0),
.locked (1'b0),
.data_s0 (data_s0),
.data_s1 (data_s1),
.data_s2 (data_s2),
.data_s3 (data_s3),
.data_s4 (data_s4),
.data_s5 (data_s5),
.data_s6 (data_s6),
.data_s7 (data_s7),
.data_in_p (serdes_in_p),
.data_in_n (serdes_in_n),
.up_clk (up_clk),
.up_dld (up_adc_dld),
.up_dwdata (up_adc_dwdata),
.up_drdata (up_adc_drdata),
.delay_clk (delay_clk),
.delay_rst (delay_rst),
.delay_locked (delay_locked));
generate
if (CMOS_LVDS_N == 0) begin
IBUFGDS i_clk_in_ibuf (
.I (rx_dclk_in_p_dclk_in),
.IB (rx_dclk_in_n_NC),
.O (clk_in_s));
assign {adc_data_strobe[0],adc_data_1[0],adc_data_0[0]} = data_s0;
assign {adc_data_strobe[1],adc_data_1[1],adc_data_0[1]} = data_s1;
assign {adc_data_strobe[2],adc_data_1[2],adc_data_0[2]} = data_s2;
assign {adc_data_strobe[3],adc_data_1[3],adc_data_0[3]} = data_s3;
assign {adc_data_strobe[4],adc_data_1[4],adc_data_0[4]} = data_s4;
assign {adc_data_strobe[5],adc_data_1[5],adc_data_0[5]} = data_s5;
assign {adc_data_strobe[6],adc_data_1[6],adc_data_0[6]} = data_s6;
assign {adc_data_strobe[7],adc_data_1[7],adc_data_0[7]} = data_s7;
assign serdes_in_p = {rx_strobe_in_p_strobe_in,
rx_qdata_in_p_qdata3,
rx_idata_in_p_idata1};
assign serdes_in_n = {rx_strobe_in_n_NC,
rx_qdata_in_n_qdata2,
rx_idata_in_n_idata0};
end else begin
IBUF i_clk_in_ibuf (
.I (rx_dclk_in_p_dclk_in),
.O (clk_in_s));
assign {adc_data_strobe[0],adc_data_3[0],adc_data_2[0],adc_data_1[0],adc_data_0[0]} = data_s0;
assign {adc_data_strobe[1],adc_data_3[1],adc_data_2[1],adc_data_1[1],adc_data_0[1]} = data_s1;
assign {adc_data_strobe[2],adc_data_3[2],adc_data_2[2],adc_data_1[2],adc_data_0[2]} = data_s2;
assign {adc_data_strobe[3],adc_data_3[3],adc_data_2[3],adc_data_1[3],adc_data_0[3]} = data_s3;
assign {adc_data_strobe[4],adc_data_3[4],adc_data_2[4],adc_data_1[4],adc_data_0[4]} = data_s4;
assign {adc_data_strobe[5],adc_data_3[5],adc_data_2[5],adc_data_1[5],adc_data_0[5]} = data_s5;
assign {adc_data_strobe[6],adc_data_3[6],adc_data_2[6],adc_data_1[6],adc_data_0[6]} = data_s6;
assign {adc_data_strobe[7],adc_data_3[7],adc_data_2[7],adc_data_1[7],adc_data_0[7]} = data_s7;
assign serdes_in_p = {rx_strobe_in_p_strobe_in,
rx_qdata_in_p_qdata3,
rx_qdata_in_n_qdata2,
rx_idata_in_p_idata1,
rx_idata_in_n_idata0};
assign serdes_in_n = 5'b0;
end
endgenerate
generate
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
BUFIO i_clk_buf (
.I (clk_in_s),
.O (adc_clk_in_fast));
BUFR #(.BUFR_DIVIDE("4")) i_div_clk_buf (
.CLR (mssi_sync),
.CE (1'b1),
.I (clk_in_s),
.O (adc_clk_div));
assign ssi_rst = mssi_sync;
end else begin
wire adc_clk_in;
reg mssi_sync_d = 1'b0;
reg mssi_sync_2d = 1'b0;
reg mssi_sync_3d = 1'b0;
reg mssi_sync_edge = 1'b0;
reg mssi_sync_out_neg = 1'b0;
always @(posedge adc_clk_in) begin
mssi_sync_d <= mssi_sync;
mssi_sync_2d <= mssi_sync_d;
mssi_sync_3d <= mssi_sync_2d;
mssi_sync_edge <= mssi_sync_2d & ~mssi_sync_3d;
end
always @(negedge adc_clk_in) begin
mssi_sync_out_neg <= mssi_sync_edge;
end
assign ssi_sync_out = mssi_sync_out_neg;
reg ssi_rst_pos;
always @(posedge adc_clk_in) begin
ssi_rst_pos <= ssi_sync_in;
end
BUFGCE #(
.CE_TYPE ("SYNC"),
.IS_CE_INVERTED (1'b0),
.IS_I_INVERTED (1'b0)
) i_clk_buf (
.O (adc_clk_in),
.CE (1'b1),
.I (clk_in_s)
);
BUFGCE #(
.CE_TYPE ("SYNC"),
.IS_CE_INVERTED (1'b0),
.IS_I_INVERTED (1'b0)
) i_clk_buf_fast (
.O (adc_clk_in_fast),
.CE (1'b1),
.I (adc_clk_in)
);
BUFGCE_DIV #(
.BUFGCE_DIVIDE (4),
.IS_CE_INVERTED (1'b0),
.IS_CLR_INVERTED (1'b0),
.IS_I_INVERTED (1'b0)
) i_div_clk_buf (
.O (adc_clk_div),
.CE (1'b1),
.CLR (ssi_rst),
.I (adc_clk_in)
);
assign ssi_rst = ssi_rst_pos;
end
endgenerate
assign adc_clk = adc_clk_in_fast;
assign adc_valid = 1'b1;
endmodule

View File

@ -0,0 +1,325 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_rx_link #(
parameter CMOS_LVDS_N = 0
) (
input adc_clk_div,
input [7:0] adc_data_0,
input [7:0] adc_data_1,
input [7:0] adc_data_2,
input [7:0] adc_data_3,
input [7:0] adc_data_strobe,
input adc_valid,
// upper layer data interface
output rx_clk,
output rx_data_valid,
output [15:0] rx_data_i,
output [15:0] rx_data_q,
// Config interface
input rx_sdr_ddr_n,
input rx_single_lane
);
wire [7:0] data_0;
wire [7:0] data_1;
wire [7:0] data_2;
wire [7:0] data_3;
wire [7:0] data_strobe;
wire data_valid;
assign rx_clk = adc_clk_div;
// CMOS can operate in SDR or DDR mode
generate if (CMOS_LVDS_N) begin : cmos_4_to_8
wire [3:0] sdr_data_0;
wire [3:0] sdr_data_1;
wire [3:0] sdr_data_2;
wire [3:0] sdr_data_3;
wire [3:0] sdr_data_strobe;
wire sdr_data_valid;
wire [3:0] sdr_data_0_aligned;
wire [3:0] sdr_data_1_aligned;
wire [3:0] sdr_data_2_aligned;
wire [3:0] sdr_data_3_aligned;
wire [3:0] sdr_data_strobe_aligned;
wire [7:0] sdr_data_0_packed;
wire [7:0] sdr_data_1_packed;
wire [7:0] sdr_data_2_packed;
wire [7:0] sdr_data_3_packed;
wire [7:0] sdr_data_strobe_packed;
wire aligner4_ovalid;
// For SDR drop every second DDR bit
assign sdr_data_0 = {adc_data_0[7],adc_data_0[5],adc_data_0[3],adc_data_0[1]};
assign sdr_data_1 = {adc_data_1[7],adc_data_1[5],adc_data_1[3],adc_data_1[1]};
assign sdr_data_2 = {adc_data_2[7],adc_data_2[5],adc_data_2[3],adc_data_2[1]};
assign sdr_data_3 = {adc_data_3[7],adc_data_3[5],adc_data_3[3],adc_data_3[1]};
assign sdr_data_strobe = {adc_data_strobe[7],adc_data_strobe[5],adc_data_strobe[3],adc_data_strobe[1]};
adrv9001_aligner4 i_rx_aligner4_0 (
.clk (adc_clk_div),
.idata (sdr_data_0),
.ivalid (adc_valid),
.strobe (sdr_data_strobe),
.odata (sdr_data_0_aligned)
);
adrv9001_aligner4 i_rx_aligner4_1 (
.clk (adc_clk_div),
.idata (sdr_data_1),
.ivalid (adc_valid),
.strobe (sdr_data_strobe),
.odata (sdr_data_1_aligned)
);
adrv9001_aligner4 i_rx_aligner4_2 (
.clk (adc_clk_div),
.idata (sdr_data_2),
.ivalid (adc_valid),
.strobe (sdr_data_strobe),
.odata (sdr_data_2_aligned)
);
adrv9001_aligner4 i_rx_aligner4_3 (
.clk (adc_clk_div),
.idata (sdr_data_3),
.ivalid (adc_valid),
.strobe (sdr_data_strobe),
.odata (sdr_data_3_aligned)
);
adrv9001_aligner4 i_rx_aligner4_strobe (
.clk (adc_clk_div),
.idata (sdr_data_strobe),
.ivalid (adc_valid),
.strobe (sdr_data_strobe),
.ovalid (aligner4_ovalid),
.odata (sdr_data_strobe_aligned)
);
adrv9001_pack #(
.WIDTH(4)
) i_rx_pack_4_to_8_0 (
.clk (adc_clk_div),
.idata (sdr_data_0_aligned),
.ivalid (aligner4_ovalid),
.sof (sdr_data_strobe_aligned[3]),
.odata (sdr_data_0_packed),
.ovalid (sdr_data_valid)
);
adrv9001_pack #(
.WIDTH(4)
) i_rx_pack_4_to_8_1 (
.clk (adc_clk_div),
.idata (sdr_data_1_aligned),
.ivalid (aligner4_ovalid),
.sof (sdr_data_strobe_aligned[3]),
.odata (sdr_data_1_packed),
.ovalid ()
);
adrv9001_pack #(
.WIDTH(4)
) i_rx_pack_4_to_8_2 (
.clk (adc_clk_div),
.idata (sdr_data_2_aligned),
.ivalid (aligner4_ovalid),
.sof (sdr_data_strobe_aligned[3]),
.odata (sdr_data_2_packed),
.ovalid ()
);
adrv9001_pack #(
.WIDTH(4)
) i_rx_pack_4_to_8_3 (
.clk (adc_clk_div),
.idata (sdr_data_3_aligned),
.ivalid (aligner4_ovalid),
.sof (sdr_data_strobe_aligned[3]),
.odata (sdr_data_3_packed),
.ovalid ()
);
adrv9001_pack #(
.WIDTH(4)
) i_rx_pack_4_to_8_strobe (
.clk (adc_clk_div),
.idata (sdr_data_strobe_aligned),
.ivalid (aligner4_ovalid),
.sof (sdr_data_strobe_aligned[3]),
.odata (sdr_data_strobe_packed),
.ovalid ()
);
assign data_0 = rx_sdr_ddr_n ? sdr_data_0_packed : adc_data_0;
assign data_1 = rx_sdr_ddr_n ? sdr_data_1_packed : adc_data_1;
assign data_2 = rx_sdr_ddr_n ? sdr_data_2_packed : adc_data_2;
assign data_3 = rx_sdr_ddr_n ? sdr_data_3_packed : adc_data_3;
assign data_strobe = rx_sdr_ddr_n ? sdr_data_strobe_packed : adc_data_strobe;
assign data_valid = rx_sdr_ddr_n ? sdr_data_valid : adc_valid;
end else begin
assign data_0 = adc_data_0;
assign data_1 = adc_data_1;
assign data_2 = adc_data_2;
assign data_3 = adc_data_3;
assign data_strobe = adc_data_strobe;
assign data_valid = adc_valid;
end
endgenerate
// ADC
wire [7:0] rx_data8_0_aligned;
wire [7:0] rx_data8_1_aligned;
wire [7:0] rx_data8_2_aligned;
wire [7:0] rx_data8_3_aligned;
wire [7:0] rx_data8_strobe_aligned;
wire rx_data8_0_aligned_valid;
wire rx_data8_1_aligned_valid;
wire [15:0] rx_data16_0_packed;
wire [15:0] rx_data16_1_packed;
wire rx_data16_0_packed_valid;
wire rx_data16_0_packed_osof;
wire [31:0] rx_data32_0_packed;
wire rx_data32_0_packed_valid;
adrv9001_aligner8 i_rx_aligner8_0(
.clk (adc_clk_div),
.idata (data_0),
.ivalid (data_valid),
.strobe (data_strobe),
.odata (rx_data8_0_aligned),
.ovalid (rx_data8_0_aligned_valid)
);
adrv9001_aligner8 i_rx_aligner8_1(
.clk (adc_clk_div),
.ivalid (data_valid),
.idata (data_1),
.strobe (data_strobe),
.odata (rx_data8_1_aligned),
.ovalid (rx_data8_1_aligned_valid)
);
generate if (CMOS_LVDS_N) begin : cmos_aligner8
adrv9001_aligner8 i_rx_aligner8_2(
.clk (adc_clk_div),
.idata (data_2),
.ivalid (data_valid),
.strobe (data_strobe),
.odata (rx_data8_2_aligned)
);
adrv9001_aligner8 i_rx_aligner8_3(
.clk (adc_clk_div),
.idata (data_3),
.ivalid (data_valid),
.strobe (data_strobe),
.odata (rx_data8_3_aligned)
);
end
endgenerate
adrv9001_aligner8 i_rx_strobe_aligner(
.clk (adc_clk_div),
.idata (data_strobe),
.ivalid (data_valid),
.strobe (data_strobe),
.odata (rx_data8_strobe_aligned)
);
adrv9001_pack #(
.WIDTH (8)
) i_rx_pack_8_to_16_0 (
.clk (adc_clk_div),
.ivalid (rx_data8_0_aligned_valid),
.idata (rx_data8_0_aligned),
.sof (rx_data8_strobe_aligned[7]),
.odata (rx_data16_0_packed),
.ovalid (rx_data16_0_packed_valid),
.osof (rx_data16_0_packed_osof)
);
adrv9001_pack #(
.WIDTH (8)
) i_rx_pack_8_to_16_1 (
.clk (adc_clk_div),
.ivalid (rx_data8_1_aligned_valid),
.idata (rx_data8_1_aligned),
.sof (rx_data8_strobe_aligned[7]),
.odata (rx_data16_1_packed),
.ovalid ()
);
adrv9001_pack #(
.WIDTH (16)
) i_rx_pack_16_to_32_0 (
.clk (adc_clk_div),
.ivalid (rx_data16_0_packed_valid),
.idata (rx_data16_0_packed),
.sof (rx_data16_0_packed_osof),
.odata (rx_data32_0_packed),
.ovalid (rx_data32_0_packed_valid)
);
generate if (CMOS_LVDS_N) begin
assign rx_data_i = ~rx_single_lane ? {rx_data8_1_aligned,rx_data8_0_aligned} :
rx_data32_0_packed[31:16];
assign rx_data_q = ~rx_single_lane ? {rx_data8_3_aligned,rx_data8_2_aligned} :
rx_data32_0_packed[15:0];
assign rx_data_valid = ~rx_single_lane ? rx_data8_0_aligned_valid :
rx_data32_0_packed_valid;
end else begin
assign rx_data_i = ~rx_single_lane ? rx_data16_0_packed :
rx_data32_0_packed[31:16];
assign rx_data_q = ~rx_single_lane ? rx_data16_1_packed :
rx_data32_0_packed[15:0];
assign rx_data_valid = ~rx_single_lane ? rx_data16_0_packed_valid :
rx_data32_0_packed_valid;
end
endgenerate
endmodule

View File

@ -0,0 +1,238 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_tx #(
parameter CMOS_LVDS_N = 0,
parameter NUM_LANES = 4,
parameter FPGA_TECHNOLOGY = 0,
parameter USE_RX_CLK_FOR_TX = 0
) (
input ref_clk,
input up_clk,
input mssi_sync,
input tx_output_enable,
// physical interface (transmit)
output tx_dclk_out_n_NC,
output tx_dclk_out_p_dclk_out,
input tx_dclk_in_n_NC,
input tx_dclk_in_p_dclk_in,
output tx_idata_out_n_idata0,
output tx_idata_out_p_idata1,
output tx_qdata_out_n_qdata2,
output tx_qdata_out_p_qdata3,
output tx_strobe_out_n_NC,
output tx_strobe_out_p_strobe_out,
input rx_clk_div,
input rx_clk,
input rx_ssi_rst,
// internal resets and clocks
input dac_rst,
output dac_clk_div,
input [7:0] dac_data_0,
input [7:0] dac_data_1,
input [7:0] dac_data_2,
input [7:0] dac_data_3,
input [7:0] dac_data_strb,
input [7:0] dac_data_clk,
input dac_data_valid
);
localparam SEVEN_SERIES = 1;
localparam ULTRASCALE = 2;
localparam ULTRASCALE_PLUS = 3;
// internal wire
wire tx_dclk_in_s;
wire dac_fast_clk;
wire [NUM_LANES-1:0] serdes_out_p;
wire [NUM_LANES-1:0] serdes_out_n;
wire [NUM_LANES-1:0] data_s0;
wire [NUM_LANES-1:0] data_s1;
wire [NUM_LANES-1:0] data_s2;
wire [NUM_LANES-1:0] data_s3;
wire [NUM_LANES-1:0] data_s4;
wire [NUM_LANES-1:0] data_s5;
wire [NUM_LANES-1:0] data_s6;
wire [NUM_LANES-1:0] data_s7;
wire ssi_rst;
ad_serdes_out #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.DDR_OR_SDR_N(1),
.DATA_WIDTH(NUM_LANES),
.SERDES_FACTOR(8),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY))
i_serdes (
.rst (dac_rst|ssi_rst),
.clk (dac_fast_clk),
.div_clk (dac_clk_div),
.loaden (1'b0),
.data_oe (tx_output_enable),
.data_s0 (data_s0),
.data_s1 (data_s1),
.data_s2 (data_s2),
.data_s3 (data_s3),
.data_s4 (data_s4),
.data_s5 (data_s5),
.data_s6 (data_s6),
.data_s7 (data_s7),
.data_out_se (),
.data_out_p (serdes_out_p),
.data_out_n (serdes_out_n));
generate
if (CMOS_LVDS_N == 0) begin
IBUFGDS i_dac_clk_in_ibuf (
.I (tx_dclk_in_p_dclk_in),
.IB (tx_dclk_in_n_NC),
.O (tx_dclk_in_s));
assign data_s0 = {dac_data_clk[7],dac_data_strb[7],dac_data_1[7],dac_data_0[7]};
assign data_s1 = {dac_data_clk[6],dac_data_strb[6],dac_data_1[6],dac_data_0[6]};
assign data_s2 = {dac_data_clk[5],dac_data_strb[5],dac_data_1[5],dac_data_0[5]};
assign data_s3 = {dac_data_clk[4],dac_data_strb[4],dac_data_1[4],dac_data_0[4]};
assign data_s4 = {dac_data_clk[3],dac_data_strb[3],dac_data_1[3],dac_data_0[3]};
assign data_s5 = {dac_data_clk[2],dac_data_strb[2],dac_data_1[2],dac_data_0[2]};
assign data_s6 = {dac_data_clk[1],dac_data_strb[1],dac_data_1[1],dac_data_0[1]};
assign data_s7 = {dac_data_clk[0],dac_data_strb[0],dac_data_1[0],dac_data_0[0]};
assign {tx_dclk_out_p_dclk_out,
tx_strobe_out_p_strobe_out,
tx_qdata_out_p_qdata3,
tx_idata_out_p_idata1} = serdes_out_p;
assign {tx_dclk_out_n_NC,
tx_strobe_out_n_NC,
tx_qdata_out_n_qdata2,
tx_idata_out_n_idata0} = serdes_out_n;
end else begin
IBUF i_dac_clk_in_ibuf (
.I (tx_dclk_in_p_dclk_in),
.O (tx_dclk_in_s));
assign data_s0 = {dac_data_clk[7],dac_data_strb[7],dac_data_3[7],dac_data_2[7],dac_data_1[7],dac_data_0[7]};
assign data_s1 = {dac_data_clk[6],dac_data_strb[6],dac_data_3[6],dac_data_2[6],dac_data_1[6],dac_data_0[6]};
assign data_s2 = {dac_data_clk[5],dac_data_strb[5],dac_data_3[5],dac_data_2[5],dac_data_1[5],dac_data_0[5]};
assign data_s3 = {dac_data_clk[4],dac_data_strb[4],dac_data_3[4],dac_data_2[4],dac_data_1[4],dac_data_0[4]};
assign data_s4 = {dac_data_clk[3],dac_data_strb[3],dac_data_3[3],dac_data_2[3],dac_data_1[3],dac_data_0[3]};
assign data_s5 = {dac_data_clk[2],dac_data_strb[2],dac_data_3[2],dac_data_2[2],dac_data_1[2],dac_data_0[2]};
assign data_s6 = {dac_data_clk[1],dac_data_strb[1],dac_data_3[1],dac_data_2[1],dac_data_1[1],dac_data_0[1]};
assign data_s7 = {dac_data_clk[0],dac_data_strb[0],dac_data_3[0],dac_data_2[0],dac_data_1[0],dac_data_0[0]};
assign {tx_dclk_out_p_dclk_out,
tx_strobe_out_p_strobe_out,
tx_qdata_out_p_qdata3,
tx_qdata_out_n_qdata2,
tx_idata_out_p_idata1,
tx_idata_out_n_idata0} = serdes_out_p;
assign {tx_dclk_out_n_NC,
tx_strobe_out_n_NC} = 2'b0;
end
if (USE_RX_CLK_FOR_TX == 0) begin
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
// SERDES fast clock
BUFIO i_dac_clk_in_gbuf (
.I (tx_dclk_in_s),
.O (dac_fast_clk));
// SERDES slow clock
BUFR #(.BUFR_DIVIDE("4")) i_dac_div_clk_rbuf (
.CLR (mssi_sync),
.CE (1'b1),
.I (tx_dclk_in_s),
.O (dac_clk_div));
assign ssi_rst = mssi_sync;
end else begin
reg mssi_sync_d = 1'b0;
reg mssi_sync_2d = 1'b0;
always @(posedge dac_fast_clk) begin
mssi_sync_d <= mssi_sync;
mssi_sync_2d <= mssi_sync_d;
end
BUFGCE #(
.CE_TYPE ("SYNC"),
.IS_CE_INVERTED (1'b0),
.IS_I_INVERTED (1'b0)
) i_dac_clk_in_gbuf (
.O (dac_fast_clk),
.CE (1'b1),
.I (tx_dclk_in_s)
);
BUFGCE_DIV #(
.BUFGCE_DIVIDE (4),
.IS_CE_INVERTED (1'b0),
.IS_CLR_INVERTED (1'b0),
.IS_I_INVERTED (1'b0)
) i_dac_div_clk_rbuf (
.O (dac_clk_div),
.CE (1'b1),
.CLR (mssi_sync_2d),
.I (tx_dclk_in_s)
);
assign ssi_rst = mssi_sync_2d;
end
end else begin
assign dac_fast_clk = rx_clk;
assign dac_clk_div = rx_clk_div;
assign ssi_rst = rx_ssi_rst;
end
endgenerate
endmodule

View File

@ -0,0 +1,198 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_tx_link #(
parameter CMOS_LVDS_N = 0,
parameter CLK_DIV_IS_FAST_CLK = 0
) (
input dac_clk_div,
output [7:0] dac_data_0,
output [7:0] dac_data_1,
output [7:0] dac_data_2,
output [7:0] dac_data_3,
output [7:0] dac_data_strobe,
output [7:0] dac_data_clk,
output dac_data_valid,
// upper layer data interface
output tx_clk,
input tx_rst,
input tx_data_valid,
input [15:0] tx_data_i,
input [15:0] tx_data_q,
// Config interface
input tx_sdr_ddr_n,
input tx_single_lane
);
assign tx_clk = dac_clk_div;
wire [7:0] data32sdr;
wire [7:0] strobe32sdr;
wire [7:0] data8sdr_0;
wire [7:0] data8sdr_1;
wire [7:0] data8sdr_2;
wire [7:0] data8sdr_3;
wire [7:0] strobe8sdr;
wire ld_next;
reg [31:0] data32 = 32'b0;
reg [31:0] strobe32 = 32'b0;
reg [15:0] data16_0 = 16'b0;
reg [15:0] data16_1 = 16'b0;
reg [15:0] strobe16 = 16'b0;
reg [7:0] data8_0 = 8'b0;
reg [7:0] data8_1 = 8'b0;
reg [7:0] data8_2 = 8'b0;
reg [7:0] data8_3 = 8'b0;
reg [7:0] strobe8 = 8'b0;
reg [3:0] valid_gen = 4'b0;
// Serialization factor Per data lane 32
always @(posedge tx_clk) begin
if (tx_data_valid) begin
data32 <= {tx_data_i,tx_data_q};
strobe32 <= {1'b1,31'b0};
end else if (ld_next) begin
if (tx_sdr_ddr_n) begin
data32 <= {data32,4'b0};
strobe32 <= {strobe32,4'b0};
end else begin
data32 <= {data32,8'b0};
strobe32 <= {strobe32,8'b0};
end
end
end
// Double each bit due the DDR PHY
assign data32sdr = {data32[31],data32[31],
data32[30],data32[30],
data32[29],data32[29],
data32[28],data32[28]};
assign strobe32sdr = {strobe32[31],strobe32[31],
strobe32[30],strobe32[30],
strobe32[29],strobe32[29],
strobe32[28],strobe32[28]};
// Serialization factor Per data lane 16
always @(posedge tx_clk) begin
if (tx_data_valid) begin
data16_0 <= tx_data_i;
data16_1 <= tx_data_q;
strobe16 <= {1'b1,15'b0};
end else if (ld_next) begin
data16_0 <= {data16_0,8'b0};
data16_1 <= {data16_1,8'b0};
strobe16 <= {strobe16,8'b0};
end
end
// Serialization factor Per data lane 8
always @(posedge tx_clk) begin
if (tx_data_valid) begin
data8_0 <= tx_data_i[7:0];
data8_1 <= tx_data_i[15:8];
data8_2 <= tx_data_q[7:0];
data8_3 <= tx_data_q[15:8];
strobe8 <= {1'b1,7'b0};
end else if (ld_next) begin
data8_0 <= {data8_0,4'b0};
data8_1 <= {data8_1,4'b0};
data8_2 <= {data8_2,4'b0};
data8_3 <= {data8_3,4'b0};
strobe8 <= {strobe16,4'b0};
end
end
// Double each bit due the DDR PHY
assign data8sdr_0 = {data8_0[7],data8_0[7],
data8_0[6],data8_0[6],
data8_0[5],data8_0[5],
data8_0[4],data8_0[4]};
assign data8sdr_1 = {data8_1[7],data8_1[7],
data8_1[6],data8_1[6],
data8_1[5],data8_1[5],
data8_1[4],data8_1[4]};
assign data8sdr_2 = {data8_2[7],data8_2[7],
data8_2[6],data8_2[6],
data8_2[5],data8_2[5],
data8_2[4],data8_2[4]};
assign data8sdr_3 = {data8_3[7],data8_3[7],
data8_3[6],data8_3[6],
data8_3[5],data8_3[5],
data8_3[4],data8_3[4]};
assign strobe8sdr = {strobe8[7],strobe8[7],
strobe8[6],strobe8[6],
strobe8[5],strobe8[5],
strobe8[4],strobe8[4]};
assign dac_data_0 = tx_single_lane ? (tx_sdr_ddr_n ? data32sdr : data32[31-:8]) :
(CMOS_LVDS_N ? (tx_sdr_ddr_n ? data8sdr_0 : data8_0) :
data16_0[15-:8]);
assign dac_data_1 = tx_single_lane ? 'b0 :
(CMOS_LVDS_N ? (tx_sdr_ddr_n ? data8sdr_1 : data8_1) :
data16_1[15-:8]);
assign dac_data_2 = tx_single_lane ? 'b0 :
(CMOS_LVDS_N ? (tx_sdr_ddr_n ? data8sdr_2 : data8_2) :
1'b0);
assign dac_data_3 = tx_single_lane ? 'b0 :
(CMOS_LVDS_N ? (tx_sdr_ddr_n ? data8sdr_3 : data8_3) :
1'b0);
assign dac_data_strobe = tx_single_lane ? (tx_sdr_ddr_n ? strobe32sdr : strobe32[31-:8]) :
(CMOS_LVDS_N ? (tx_sdr_ddr_n ? strobe8sdr : strobe8) :
strobe16[15-:8]);
assign dac_data_clk = {4{1'b1,1'b0}};
assign dac_data_valid = (CLK_DIV_IS_FAST_CLK == 0) ? 1'b1 : valid_gen[3];
always @(posedge tx_clk) begin
if (tx_data_valid) begin
valid_gen <= 4'b1000;
end else begin
valid_gen <= {valid_gen[2:0],valid_gen[3]};
end
end
assign ld_next = (CLK_DIV_IS_FAST_CLK == 0) ? 1'b1 : valid_gen[2];
endmodule

View File

@ -0,0 +1,522 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001 #(
parameter ID = 0,
parameter CMOS_LVDS_N = 0,
parameter IO_DELAY_GROUP = "dev_if_delay_group",
parameter FPGA_TECHNOLOGY = 0,
parameter FPGA_FAMILY = 0,
parameter SPEED_GRADE = 0,
parameter DEV_PACKAGE = 0,
parameter USE_RX_CLK_FOR_TX = 0
) (
input ref_clk,
input mssi_sync,
input tx_output_enable,
// physical interface
input rx1_dclk_in_n_NC,
input rx1_dclk_in_p_dclk_in,
input rx1_idata_in_n_idata0,
input rx1_idata_in_p_idata1,
input rx1_qdata_in_n_qdata2,
input rx1_qdata_in_p_qdata3,
input rx1_strobe_in_n_NC,
input rx1_strobe_in_p_strobe_in,
input rx2_dclk_in_n_NC,
input rx2_dclk_in_p_dclk_in,
input rx2_idata_in_n_idata0,
input rx2_idata_in_p_idata1,
input rx2_qdata_in_n_qdata2,
input rx2_qdata_in_p_qdata3,
input rx2_strobe_in_n_NC,
input rx2_strobe_in_p_strobe_in,
output tx1_dclk_out_n_NC,
output tx1_dclk_out_p_dclk_out,
input tx1_dclk_in_n_NC,
input tx1_dclk_in_p_dclk_in,
output tx1_idata_out_n_idata0,
output tx1_idata_out_p_idata1,
output tx1_qdata_out_n_qdata2,
output tx1_qdata_out_p_qdata3,
output tx1_strobe_out_n_NC,
output tx1_strobe_out_p_strobe_out,
output tx2_dclk_out_n_NC,
output tx2_dclk_out_p_dclk_out,
input tx2_dclk_in_n_NC,
input tx2_dclk_in_p_dclk_in,
output tx2_idata_out_n_idata0,
output tx2_idata_out_p_idata1,
output tx2_qdata_out_n_qdata2,
output tx2_qdata_out_p_qdata3,
output tx2_strobe_out_n_NC,
output tx2_strobe_out_p_strobe_out,
input delay_clk,
// user interface
output adc_1_clk,
output adc_1_rst,
output adc_1_valid_i0,
output adc_1_enable_i0,
output [15:0] adc_1_data_i0,
output adc_1_valid_q0,
output adc_1_enable_q0,
output [15:0] adc_1_data_q0,
output adc_1_valid_i1,
output adc_1_enable_i1,
output [15:0] adc_1_data_i1,
output adc_1_valid_q1,
output adc_1_enable_q1,
output [15:0] adc_1_data_q1,
input adc_1_dovf,
output adc_2_clk,
output adc_2_rst,
output adc_2_valid_i0,
output adc_2_enable_i0,
output [15:0] adc_2_data_i0,
output adc_2_valid_q0,
output adc_2_enable_q0,
output [15:0] adc_2_data_q0,
input adc_2_dovf,
output dac_1_clk,
output dac_1_rst,
output dac_1_valid_i0,
output dac_1_enable_i0,
input [15:0] dac_1_data_i0,
output dac_1_valid_q0,
output dac_1_enable_q0,
input [15:0] dac_1_data_q0,
output dac_1_valid_i1,
output dac_1_enable_i1,
input [15:0] dac_1_data_i1,
output dac_1_valid_q1,
output dac_1_enable_q1,
input [15:0] dac_1_data_q1,
input dac_1_dunf,
output dac_2_clk,
output dac_2_rst,
output dac_2_valid_i0,
output dac_2_enable_i0,
input [15:0] dac_2_data_i0,
output dac_2_valid_q0,
output dac_2_enable_q0,
input [15:0] dac_2_data_q0,
input dac_2_dunf,
// axi interface
input s_axi_aclk,
input s_axi_aresetn,
input s_axi_awvalid,
input [15:0] s_axi_awaddr,
output s_axi_awready,
input s_axi_wvalid,
input [31:0] s_axi_wdata,
input [ 3:0] s_axi_wstrb,
output s_axi_wready,
output s_axi_bvalid,
output [ 1:0] s_axi_bresp,
input s_axi_bready,
input s_axi_arvalid,
input [15:0] s_axi_araddr,
output s_axi_arready,
output s_axi_rvalid,
output [ 1:0] s_axi_rresp,
output [31:0] s_axi_rdata,
input s_axi_rready,
input [ 2:0] s_axi_awprot,
input [ 2:0] s_axi_arprot
);
localparam SEVEN_SERIES = 1;
localparam ULTRASCALE = 2;
localparam ULTRASCALE_PLUS = 3;
localparam DRP_WIDTH = FPGA_TECHNOLOGY == ULTRASCALE ? 9 :
FPGA_TECHNOLOGY == ULTRASCALE_PLUS ? 9 : 5;
localparam NUM_LANES = CMOS_LVDS_N ? 5 : 3;
// internal signals
wire up_wreq_s;
wire up_rreq_s;
wire [13:0] up_waddr_s;
wire [13:0] up_raddr_s;
wire [31:0] up_wdata_s;
wire [31:0] up_rdata_s;
wire up_wack_s;
wire up_rack_s;
wire [15:0] rx1_data_i;
wire [15:0] rx1_data_q;
wire rx1_data_valid;
wire rx1_single_lane;
wire rx1_sdr_ddr_n;
wire [15:0] rx2_data_i;
wire [15:0] rx2_data_q;
wire rx2_data_valid;
wire rx2_single_lane;
wire rx2_sdr_ddr_n;
wire [15:0] tx1_data_i;
wire [15:0] tx1_data_q;
wire tx1_data_valid;
wire tx1_single_lane;
wire tx1_sdr_ddr_n;
wire [15:0] tx2_data_i;
wire [15:0] tx2_data_q;
wire tx2_data_valid;
wire tx2_single_lane;
wire tx2_sdr_ddr_n;
wire adc_1_valid;
wire adc_2_valid;
wire dac_1_valid;
wire dac_2_valid;
// internal clocks & resets
wire up_rstn;
wire up_clk;
// clock/reset assignments
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
wire [NUM_LANES-1:0] up_rx1_dld;
wire [DRP_WIDTH*NUM_LANES-1:0] up_rx1_dwdata;
wire [DRP_WIDTH*NUM_LANES-1:0] up_rx1_drdata;
wire [NUM_LANES-1:0] up_rx2_dld;
wire [DRP_WIDTH*NUM_LANES-1:0] up_rx2_dwdata;
wire [DRP_WIDTH*NUM_LANES-1:0] up_rx2_drdata;
wire delay_rx1_rst;
wire delay_rx2_rst;
wire delay_rx1_locked;
wire delay_rx2_locked;
axi_adrv9001_if #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.NUM_LANES (NUM_LANES),
.DRP_WIDTH (DRP_WIDTH),
.IO_DELAY_GROUP (IO_DELAY_GROUP),
.USE_RX_CLK_FOR_TX (USE_RX_CLK_FOR_TX)
) i_if(
//
// Physical interface
//
.ref_clk (ref_clk),
.mssi_sync (mssi_sync),
.tx_output_enable (tx_output_enable),
.rx1_dclk_in_n_NC (rx1_dclk_in_n_NC),
.rx1_dclk_in_p_dclk_in (rx1_dclk_in_p_dclk_in),
.rx1_idata_in_n_idata0 (rx1_idata_in_n_idata0),
.rx1_idata_in_p_idata1 (rx1_idata_in_p_idata1),
.rx1_qdata_in_n_qdata2 (rx1_qdata_in_n_qdata2),
.rx1_qdata_in_p_qdata3 (rx1_qdata_in_p_qdata3),
.rx1_strobe_in_n_NC (rx1_strobe_in_n_NC),
.rx1_strobe_in_p_strobe_in (rx1_strobe_in_p_strobe_in),
.rx2_dclk_in_n_NC (rx2_dclk_in_n_NC),
.rx2_dclk_in_p_dclk_in (rx2_dclk_in_p_dclk_in),
.rx2_idata_in_n_idata0 (rx2_idata_in_n_idata0),
.rx2_idata_in_p_idata1 (rx2_idata_in_p_idata1),
.rx2_qdata_in_n_qdata2 (rx2_qdata_in_n_qdata2),
.rx2_qdata_in_p_qdata3 (rx2_qdata_in_p_qdata3),
.rx2_strobe_in_n_NC (rx2_strobe_in_n_NC),
.rx2_strobe_in_p_strobe_in (rx2_strobe_in_p_strobe_in),
.tx1_dclk_out_n_NC (tx1_dclk_out_n_NC),
.tx1_dclk_out_p_dclk_out (tx1_dclk_out_p_dclk_out),
.tx1_dclk_in_n_NC (tx1_dclk_in_n_NC),
.tx1_dclk_in_p_dclk_in (tx1_dclk_in_p_dclk_in),
.tx1_idata_out_n_idata0 (tx1_idata_out_n_idata0),
.tx1_idata_out_p_idata1 (tx1_idata_out_p_idata1),
.tx1_qdata_out_n_qdata2 (tx1_qdata_out_n_qdata2),
.tx1_qdata_out_p_qdata3 (tx1_qdata_out_p_qdata3),
.tx1_strobe_out_n_NC (tx1_strobe_out_n_NC),
.tx1_strobe_out_p_strobe_out (tx1_strobe_out_p_strobe_out),
.tx2_dclk_out_n_NC (tx2_dclk_out_n_NC),
.tx2_dclk_out_p_dclk_out (tx2_dclk_out_p_dclk_out),
.tx2_dclk_in_n_NC (tx2_dclk_in_n_NC),
.tx2_dclk_in_p_dclk_in (tx2_dclk_in_p_dclk_in),
.tx2_idata_out_n_idata0 (tx2_idata_out_n_idata0),
.tx2_idata_out_p_idata1 (tx2_idata_out_p_idata1),
.tx2_qdata_out_n_qdata2 (tx2_qdata_out_n_qdata2),
.tx2_qdata_out_p_qdata3 (tx2_qdata_out_p_qdata3),
.tx2_strobe_out_n_NC (tx2_strobe_out_n_NC),
.tx2_strobe_out_p_strobe_out (tx2_strobe_out_p_strobe_out),
//
// Control interface
//
// delay interface (for IDELAY macros)
.delay_clk (delay_clk),
.delay_rx1_rst (delay_rx1_rst),
.delay_rx2_rst (delay_rx2_rst),
.delay_rx1_locked (delay_rx1_locked),
.delay_rx2_locked (delay_rx2_locked),
.up_clk (up_clk),
.up_rx1_dld (up_rx1_dld),
.up_rx1_dwdata (up_rx1_dwdata),
.up_rx1_drdata (up_rx1_drdata),
.up_rx2_dld (up_rx2_dld),
.up_rx2_dwdata (up_rx2_dwdata),
.up_rx2_drdata (up_rx2_drdata),
//
// Transport layer interface
//
// ADC interface
.rx1_clk (adc_1_clk),
.rx1_rst (adc_1_rst),
.rx1_data_valid (rx1_data_valid),
.rx1_data_i (rx1_data_i),
.rx1_data_q (rx1_data_q),
.rx1_single_lane (rx1_single_lane),
.rx1_sdr_ddr_n (rx1_sdr_ddr_n),
.rx2_clk (adc_2_clk),
.rx2_rst (adc_2_rst),
.rx2_data_valid (rx2_data_valid),
.rx2_data_i (rx2_data_i),
.rx2_data_q (rx2_data_q),
.rx2_single_lane (rx2_single_lane),
.rx2_sdr_ddr_n (rx2_sdr_ddr_n),
// DAC interface
.tx1_clk (dac_1_clk),
.tx1_rst (dac_1_rst),
.tx1_data_valid (tx1_data_valid),
.tx1_data_i (tx1_data_i),
.tx1_data_q (tx1_data_q),
.tx1_single_lane (tx1_single_lane),
.tx1_sdr_ddr_n (tx1_sdr_ddr_n),
.tx2_clk (dac_2_clk),
.tx2_rst (dac_2_rst),
.tx2_data_valid (tx2_data_valid),
.tx2_data_i (tx2_data_i),
.tx2_data_q (tx2_data_q),
.tx2_single_lane (tx2_single_lane),
.tx2_sdr_ddr_n (tx2_sdr_ddr_n)
);
// common processor control
axi_ad9001_core #(
.ID (ID),
.NUM_LANES (NUM_LANES),
.CMOS_LVDS_N (CMOS_LVDS_N),
.DRP_WIDTH (DRP_WIDTH),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE)
) i_core (
// ADC interface
.rx1_clk (adc_1_clk),
.rx1_rst (adc_1_rst),
.rx1_data_valid (rx1_data_valid),
.rx1_data_i (rx1_data_i),
.rx1_data_q (rx1_data_q),
.rx1_single_lane (rx1_single_lane),
.rx1_sdr_ddr_n (rx1_sdr_ddr_n),
.rx2_clk (adc_2_clk),
.rx2_rst (adc_2_rst),
.rx2_data_valid (rx2_data_valid),
.rx2_data_i (rx2_data_i),
.rx2_data_q (rx2_data_q),
.rx2_single_lane (rx2_single_lane),
.rx2_sdr_ddr_n (rx2_sdr_ddr_n),
//DAC interface
.tx1_clk (dac_1_clk),
.tx1_rst (dac_1_rst),
.tx1_data_valid (tx1_data_valid),
.tx1_data_i (tx1_data_i),
.tx1_data_q (tx1_data_q),
.tx1_single_lane (tx1_single_lane),
.tx1_sdr_ddr_n (tx1_sdr_ddr_n),
.tx2_clk (dac_2_clk),
.tx2_rst (dac_2_rst),
.tx2_data_valid (tx2_data_valid),
.tx2_data_i (tx2_data_i),
.tx2_data_q (tx2_data_q),
.tx2_single_lane (tx2_single_lane),
.tx2_sdr_ddr_n (tx2_sdr_ddr_n),
//
// User layer interface
//
.adc_1_valid (adc_1_valid),
.adc_1_enable_i0 (adc_1_enable_i0),
.adc_1_data_i0 (adc_1_data_i0),
.adc_1_enable_q0 (adc_1_enable_q0),
.adc_1_data_q0 (adc_1_data_q0),
.adc_1_enable_i1 (adc_1_enable_i1),
.adc_1_data_i1 (adc_1_data_i1),
.adc_1_enable_q1 (adc_1_enable_q1),
.adc_1_data_q1 (adc_1_data_q1),
.adc_1_dovf (adc_1_dovf),
.adc_2_valid (adc_2_valid),
.adc_2_enable_i (adc_2_enable_i0),
.adc_2_data_i (adc_2_data_i0),
.adc_2_enable_q (adc_2_enable_q0),
.adc_2_data_q (adc_2_data_q0),
.adc_2_dovf (adc_2_dovf),
.dac_1_valid (dac_1_valid),
.dac_1_enable_i0 (dac_1_enable_i0),
.dac_1_data_i0 (dac_1_data_i0),
.dac_1_enable_q0 (dac_1_enable_q0),
.dac_1_data_q0 (dac_1_data_q0),
.dac_1_enable_i1 (dac_1_enable_i1),
.dac_1_data_i1 (dac_1_data_i1),
.dac_1_enable_q1 (dac_1_enable_q1),
.dac_1_data_q1 (dac_1_data_q1),
.dac_1_dunf (dac_1_dunf),
.dac_2_valid (dac_2_valid),
.dac_2_enable_i0 (dac_2_enable_i0),
.dac_2_data_i0 (dac_2_data_i0),
.dac_2_enable_q0 (dac_2_enable_q0),
.dac_2_data_q0 (dac_2_data_q0),
.dac_2_dunf (dac_2_dunf),
.delay_clk (delay_clk),
.up_rx1_dld (up_rx1_dld),
.up_rx1_dwdata (up_rx1_dwdata),
.up_rx1_drdata (up_rx1_drdata),
.delay_rx1_rst (delay_rx1_rst),
.delay_rx1_locked (delay_rx1_locked),
.up_rx2_dld (up_rx2_dld),
.up_rx2_dwdata (up_rx2_dwdata),
.up_rx2_drdata (up_rx2_drdata),
.delay_rx2_rst (delay_rx2_rst),
.delay_rx2_locked (delay_rx2_locked),
.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)
);
assign adc_1_valid_i0 = adc_1_valid;
assign adc_1_valid_q0 = adc_1_valid;
assign adc_1_valid_i1 = adc_1_valid;
assign adc_1_valid_q1 = adc_1_valid;
assign adc_2_valid_i0 = adc_2_valid;
assign adc_2_valid_q0 = adc_2_valid;
assign dac_1_valid_i0 = dac_1_valid;
assign dac_1_valid_q0 = dac_1_valid;
assign dac_1_valid_i1 = dac_1_valid;
assign dac_1_valid_q1 = dac_1_valid;
assign dac_2_valid_i0 = dac_2_valid;
assign dac_2_valid_q0 = dac_2_valid;
// up bus interface
up_axi #(
.AXI_ADDRESS_WIDTH(15)
) i_up_axi (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_axi_awvalid (s_axi_awvalid),
.up_axi_awaddr (s_axi_awaddr[14:0]),
.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[14:0]),
.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[12:0]),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s),
.up_wack (up_wack_s),
.up_raddr (up_raddr_s[12:0]),
.up_rreq (up_rreq_s),
.up_rack (up_rack_s)
);
// Alias Rx/Tx peripherals @ 0x8000
assign up_raddr_s[13] = 1'b0;
assign up_waddr_s[13] = 1'b0;
endmodule

View File

@ -0,0 +1,6 @@
set_false_path -from [get_registers *i_dev_if|up_enable_int*] -to [get_registers *i_dev_if|enable_up_m1*]
set_false_path -from [get_registers *i_dev_if|up_txnrx_int*] -to [get_registers *i_dev_if|txnrx_up_m1*]
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_tdd_control|d_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_tdd_control|up_xfer_state_m1*]
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_tdd_control|up_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_tdd_control|d_xfer_toggle_m1*]
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_tdd_control|up_xfer_data*] -to [get_registers *up_xfer_cntrl:i_xfer_tdd_control|d_data_cntrl*]

View File

@ -0,0 +1,5 @@
set_false_path -quiet -from [get_cells -quiet -hier *in_toggle_d1_reg* -filter {NAME =~ *i_serdes* && IS_SEQUENTIAL}]
set_false_path -quiet -from [get_cells -quiet -hier *out_toggle_d1_reg* -filter {NAME =~ *i_serdes* && IS_SEQUENTIAL}]
set_false_path -through [get_pins -hier *i_idelay/CNTVALUEOUT]
set_false_path -through [get_pins -hier *i_idelay/CNTVALUEIN]

View File

@ -0,0 +1,501 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_ad9001_core #(
parameter ID = 0,
parameter CMOS_LVDS_N = 0,
parameter NUM_LANES = 3,
parameter DRP_WIDTH = 5,
parameter FPGA_TECHNOLOGY = 0,
parameter FPGA_FAMILY = 0,
parameter SPEED_GRADE = 0,
parameter DEV_PACKAGE = 0,
parameter DAC_DDS_TYPE = 1,
parameter DAC_DDS_CORDIC_DW = 20,
parameter DAC_DDS_CORDIC_PHASE_DW = 18
) (
// ADC interface
input rx1_clk,
output rx1_rst,
input rx1_data_valid,
input [15:0] rx1_data_i,
input [15:0] rx1_data_q,
output rx1_single_lane,
output rx1_sdr_ddr_n,
input rx2_clk,
output rx2_rst,
input rx2_data_valid,
input [15:0] rx2_data_i,
input [15:0] rx2_data_q,
output rx2_single_lane,
output rx2_sdr_ddr_n,
// DAC interface
input tx1_clk,
output tx1_rst,
output tx1_data_valid,
output [15:0] tx1_data_i,
output [15:0] tx1_data_q,
output tx1_single_lane,
output tx1_sdr_ddr_n,
input tx2_clk,
output tx2_rst,
output tx2_data_valid,
output [15:0] tx2_data_i,
output [15:0] tx2_data_q,
output tx2_single_lane,
output tx2_sdr_ddr_n,
// DMA interface
output adc_1_valid,
output adc_1_enable_i0,
output [15:0] adc_1_data_i0,
output adc_1_enable_q0,
output [15:0] adc_1_data_q0,
output adc_1_enable_i1,
output [15:0] adc_1_data_i1,
output adc_1_enable_q1,
output [15:0] adc_1_data_q1,
input adc_1_dovf,
output adc_2_valid,
output adc_2_enable_i,
output [15:0] adc_2_data_i,
output adc_2_enable_q,
output [15:0] adc_2_data_q,
input adc_2_dovf,
output dac_1_valid,
output dac_1_enable_i0,
input [15:0] dac_1_data_i0,
output dac_1_enable_q0,
input [15:0] dac_1_data_q0,
output dac_1_enable_i1,
input [15:0] dac_1_data_i1,
output dac_1_enable_q1,
input [15:0] dac_1_data_q1,
input dac_1_dunf,
output dac_2_valid,
output dac_2_enable_i0,
input [15:0] dac_2_data_i0,
output dac_2_enable_q0,
input [15:0] dac_2_data_q0,
input dac_2_dunf,
// delay interface
input delay_clk,
output delay_rx1_rst,
input delay_rx1_locked,
output delay_rx2_rst,
input delay_rx2_locked,
output [NUM_LANES-1:0] up_rx1_dld,
output [DRP_WIDTH*NUM_LANES-1:0] up_rx1_dwdata,
input [DRP_WIDTH*NUM_LANES-1:0] up_rx1_drdata,
output [NUM_LANES-1:0] up_rx2_dld,
output [DRP_WIDTH*NUM_LANES-1:0] up_rx2_dwdata,
input [DRP_WIDTH*NUM_LANES-1:0] up_rx2_drdata,
// 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 up_wack_s[0:5];
wire [31:0] up_rdata_s[0:5];
wire up_rack_s[0:5];
wire tx1_data_valid_A;
wire [15:0] tx1_data_i_A;
wire [15:0] tx1_data_q_A;
wire tx1_data_valid_B;
wire [15:0] tx1_data_i_B;
wire [15:0] tx1_data_q_B;
wire tx2_data_valid_A;
wire [15:0] tx2_data_i_A;
wire [15:0] tx2_data_q_A;
wire rx1_r1_mode;
wire rx2_rst_loc;
wire rx2_single_lane_loc;
wire rx2_sdr_ddr_n_loc;
wire tx1_r1_mode;
wire tx2_rst_loc;
wire tx2_single_lane_loc;
wire tx2_sdr_ddr_n_loc;
reg tx1_data_valid_A_d;
reg [15:0] tx1_data_i_A_d;
reg [15:0] tx1_data_q_A_d;
reg tx1_data_valid_B_d;
reg [15:0] tx1_data_i_B_d;
reg [15:0] tx1_data_q_B_d;
reg tx2_data_valid_A_d;
reg [15:0] tx2_data_i_A_d;
reg [15:0] tx2_data_q_A_d;
// rx1_r1_mode and tx1_r1_mode considered static during operation
// rx1_r1_mode should be 0 only when rx1_clk and rx2_clk have the same frequency
// tx1_r1_mode should be 0 only when tx1_clk and tx2_clk have the same frequency
assign rx2_rst = rx1_r1_mode ? rx2_rst_loc : rx1_rst;
assign rx2_single_lane = rx1_r1_mode ? rx2_single_lane_loc : rx1_single_lane;
assign rx2_sdr_ddr_n = rx1_r1_mode ? rx2_sdr_ddr_n_loc : rx1_sdr_ddr_n;
assign tx2_rst = tx1_r1_mode ? tx2_rst_loc : tx1_rst;
assign tx2_single_lane = tx1_r1_mode ? tx2_single_lane_loc : tx1_single_lane;
assign tx2_sdr_ddr_n = tx1_r1_mode ? tx2_sdr_ddr_n_loc : tx1_sdr_ddr_n;
assign tx1_data_valid = tx1_data_valid_A_d;
assign tx1_data_i = tx1_data_i_A_d;
assign tx1_data_q = tx1_data_q_A_d;
assign tx2_data_valid = tx1_r1_mode ? tx2_data_valid_A_d : tx1_data_valid_B_d;
assign tx2_data_i = tx1_r1_mode ? tx2_data_i_A_d : tx1_data_i_B_d;
assign tx2_data_q = tx1_r1_mode ? tx2_data_q_A_d : tx1_data_q_B_d;
always @(posedge tx1_clk) begin
tx1_data_valid_A_d <= tx1_data_valid_A;
tx1_data_i_A_d <= tx1_data_i_A;
tx1_data_q_A_d <= tx1_data_q_A;
end
always @(posedge tx2_clk) begin
tx2_data_valid_A_d <= tx2_data_valid_A;
tx2_data_i_A_d <= tx2_data_i_A;
tx2_data_q_A_d <= tx2_data_q_A;
end
// Use tx1_r1_mode as clock enable when the two clocks have different frequency
always @(posedge tx2_clk) begin
if (tx1_r1_mode==0) begin
tx1_data_valid_B_d <= tx1_data_valid_B;
tx1_data_i_B_d <= tx1_data_i_B;
tx1_data_q_B_d <= tx1_data_q_B;
end
end
// 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[0] | up_rdata_s[1] | up_rdata_s[2] | up_rdata_s[3] | up_rdata_s[4] | up_rdata_s[5];
up_rack <= up_rack_s[0] | up_rack_s[1] | up_rack_s[2] | up_rack_s[3] | up_rack_s[4] | up_rack_s[5];
up_wack <= up_wack_s[0] | up_wack_s[1] | up_wack_s[2] | up_wack_s[3] | up_wack_s[4] | up_wack_s[5];
end
end
axi_adrv9001_rx #(
.ID (ID),
.CMOS_LVDS_N (CMOS_LVDS_N),
.COMMON_BASE_ADDR(6'h00),
.CHANNEL_BASE_ADDR(6'h01),
.MODE_R1 (0),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE),
.DATAFORMAT_DISABLE (0),
.DCFILTER_DISABLE (1),
.IQCORRECTION_DISABLE (1))
i_rx1 (
.adc_rst (rx1_rst),
.adc_clk (rx1_clk),
.adc_valid_A (rx1_data_valid),
.adc_data_i_A (rx1_data_i),
.adc_data_q_A (rx1_data_q),
.adc_valid_B (rx2_data_valid),
.adc_data_i_B (rx2_data_i),
.adc_data_q_B (rx2_data_q),
.adc_single_lane (rx1_single_lane),
.adc_sdr_ddr_n (rx1_sdr_ddr_n),
.adc_r1_mode (rx1_r1_mode),
.dac_data_valid_A (tx1_data_valid_A),
.dac_data_i_A (tx1_data_i_A),
.dac_data_q_A (tx1_data_q_A),
.dac_data_valid_B (tx1_data_valid_B),
.dac_data_i_B (tx1_data_i_B),
.dac_data_q_B (tx1_data_q_B),
.adc_valid (adc_1_valid),
.adc_enable_i0 (adc_1_enable_i0),
.adc_data_i0 (adc_1_data_i0[15:0]),
.adc_enable_q0 (adc_1_enable_q0),
.adc_data_q0 (adc_1_data_q0[15:0]),
.adc_enable_i1 (adc_1_enable_i1),
.adc_data_i1 (adc_1_data_i1[15:0]),
.adc_enable_q1 (adc_1_enable_q1),
.adc_data_q1 (adc_1_data_q1[15:0]),
.adc_dovf (adc_1_dovf),
.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[0]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[0]),
.up_rack (up_rack_s[0]));
axi_adrv9001_rx #(
.ID (ID),
.CMOS_LVDS_N (CMOS_LVDS_N),
.COMMON_BASE_ADDR(6'h04),
.CHANNEL_BASE_ADDR(6'h05),
.MODE_R1 (1),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE),
.DATAFORMAT_DISABLE (0),
.DCFILTER_DISABLE (1),
.IQCORRECTION_DISABLE (1))
i_rx2 (
.adc_rst (rx2_rst_loc),
.adc_clk (rx2_clk),
.adc_valid_A (rx2_data_valid),
.adc_data_i_A (rx2_data_i),
.adc_data_q_A (rx2_data_q),
.adc_valid_B (1'b0),
.adc_data_i_B (16'b0),
.adc_data_q_B (16'b0),
.adc_single_lane (rx2_single_lane_loc),
.adc_sdr_ddr_n (rx2_sdr_ddr_n_loc),
.dac_data_valid_A (tx2_data_valid_A),
.dac_data_i_A (tx2_data_i_A),
.dac_data_q_A (tx2_data_q_A),
.dac_data_valid_B (1'b0),
.dac_data_i_B (16'b0),
.dac_data_q_B (16'b0),
.adc_valid (adc_2_valid),
.adc_enable_i0 (adc_2_enable_i),
.adc_data_i0 (adc_2_data_i[15:0]),
.adc_enable_q0 (adc_2_enable_q),
.adc_data_q0 (adc_2_data_q[15:0]),
.adc_dovf (adc_2_dovf),
.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[1]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[1]),
.up_rack (up_rack_s[1]));
axi_adrv9001_tx #(
.ID (ID),
.CMOS_LVDS_N (CMOS_LVDS_N),
.COMMON_BASE_ADDR ('h08),
.CHANNEL_BASE_ADDR ('h09),
.MODE_R1 (0),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE),
.DDS_DISABLE (0),
.IQCORRECTION_DISABLE (1),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx1 (
.dac_rst (tx1_rst),
.dac_clk (tx1_clk),
.dac_data_valid_A (tx1_data_valid_A),
.dac_data_i_A (tx1_data_i_A),
.dac_data_q_A (tx1_data_q_A),
.dac_data_valid_B (tx1_data_valid_B),
.dac_data_i_B (tx1_data_i_B),
.dac_data_q_B (tx1_data_q_B),
.dac_single_lane (tx1_single_lane),
.dac_sdr_ddr_n (tx1_sdr_ddr_n),
.dac_r1_mode (tx1_r1_mode),
.dac_sync_in (1'b0),
.dac_sync_out (),
.dac_enable_i0 (dac_1_enable_i0),
.dac_valid (dac_1_valid),
.dac_data_i0 (dac_1_data_i0[15:0]),
.dac_enable_q0 (dac_1_enable_q0),
.dac_data_q0 (dac_1_data_q0[15:0]),
.dac_enable_i1 (dac_1_enable_i1),
.dac_data_i1 (dac_1_data_i1[15:0]),
.dac_enable_q1 (dac_1_enable_q1),
.dac_data_q1 (dac_1_data_q1[15:0]),
.dac_dunf (dac_1_dunf),
.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[2]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[2]),
.up_rack (up_rack_s[2]));
axi_adrv9001_tx #(
.ID (ID),
.CMOS_LVDS_N (CMOS_LVDS_N),
.COMMON_BASE_ADDR ('h10),
.CHANNEL_BASE_ADDR ('h11),
.MODE_R1 (1),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE),
.DDS_DISABLE (0),
.IQCORRECTION_DISABLE (1),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx2 (
.dac_rst (tx2_rst_loc),
.dac_clk (tx2_clk),
.dac_data_valid_A (tx2_data_valid_A),
.dac_data_i_A (tx2_data_i_A),
.dac_data_q_A (tx2_data_q_A),
.dac_data_valid_B (),
.dac_data_i_B (),
.dac_data_q_B (),
.dac_single_lane (tx2_single_lane_loc),
.dac_sdr_ddr_n (tx2_sdr_ddr_n_loc),
.dac_sync_in (1'b0),
.dac_sync_out (),
.dac_valid (dac_2_valid),
.dac_enable_i0 (dac_2_enable_i0),
.dac_data_i0 (dac_2_data_i0[15:0]),
.dac_enable_q0 (dac_2_enable_q0),
.dac_data_q0 (dac_2_data_q0[15:0]),
.dac_enable_i1 (),
.dac_data_i1 (16'b0),
.dac_enable_q1 (),
.dac_data_q1 (16'b0),
.dac_dunf (dac_2_dunf),
.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[3]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[3]),
.up_rack (up_rack_s[3]));
// adc delay control
up_delay_cntrl #(
.DATA_WIDTH(NUM_LANES),
.DRP_WIDTH(DRP_WIDTH),
.BASE_ADDRESS(6'h02))
i_delay_cntrl_rx1 (
.delay_clk (delay_clk),
.delay_rst (delay_rx1_rst),
.delay_locked (delay_rx1_locked),
.up_dld (up_rx1_dld),
.up_dwdata (up_rx1_dwdata),
.up_drdata (up_rx1_drdata),
.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[4]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[4]),
.up_rack (up_rack_s[4]));
up_delay_cntrl #(
.DATA_WIDTH(NUM_LANES),
.DRP_WIDTH(DRP_WIDTH),
.BASE_ADDRESS(6'h06))
i_delay_cntrl_rx2 (
.delay_clk (delay_clk),
.delay_rst (delay_rx2_rst),
.delay_locked (delay_rx2_locked),
.up_dld (up_rx2_dld),
.up_dwdata (up_rx2_dwdata),
.up_drdata (up_rx2_drdata),
.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[5]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[5]),
.up_rack (up_rack_s[5]));
endmodule

View File

@ -0,0 +1,225 @@
package require qsys
package require quartus::device
source ../scripts/adi_env.tcl
source ../scripts/adi_ip_intel.tcl
ad_ip_create axi_adrv9001 {AXI ADRV9001 Interface} axi_adrv9001_elab
set_module_property VALIDATION_CALLBACK info_param_validate
ad_ip_files axi_adrv9001 [list\
"$ad_hdl_dir/library/intel/common/ad_mul.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_1.v" \
"$ad_hdl_dir/library/common/ad_dds_2.v" \
"$ad_hdl_dir/library/common/ad_dds.v" \
"$ad_hdl_dir/library/common/ad_datafmt.v" \
"$ad_hdl_dir/library/common/ad_rst.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_common.v" \
"$ad_hdl_dir/library/common/up_adc_channel.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_pnmon.v" \
"$ad_hdl_dir/library/common/ad_pngen.v" \
"$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/intel/common/up_xfer_cntrl_constr.sdc" \
"$ad_hdl_dir/library/intel/common/up_xfer_status_constr.sdc" \
"$ad_hdl_dir/library/intel/common/up_clock_mon_constr.sdc" \
"$ad_hdl_dir/library/intel/common/up_rst_constr.sdc" \
"intel/adrv9001_rx.v" \
"intel/adrv9001_tx.v" \
"adrv9001_pack.v" \
"adrv9001_aligner4.v" \
"adrv9001_aligner8.v" \
"adrv9001_rx_link.v" \
"adrv9001_tx_link.v" \
"axi_adrv9001_rx.v" \
"axi_adrv9001_rx_channel.v" \
"axi_adrv9001_if.v" \
"axi_adrv9001_tx.v" \
"axi_adrv9001_tx_channel.v" \
"axi_adrv9001_core.v" \
"axi_adrv9001_constr.sdc" \
"axi_adrv9001.v" ]
# parameters
ad_ip_parameter ID INTEGER 0
ad_ip_parameter CMOS_LVDS_N INTEGER 0
ad_ip_parameter IO_DELAY_GROUP STRING {dev_if_delay_group}
adi_add_auto_fpga_spec_params
# interfaces
ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn
#ad_interface clock delay_clk input 1
ad_interface clock adc_1_clk output 1
ad_interface clock adc_2_clk output 1
ad_interface clock dac_1_clk output 1
ad_interface clock dac_2_clk output 1
ad_interface reset adc_1_rst output 1 if_adc_1_clk
ad_interface reset adc_2_rst output 1 if_adc_2_clk
ad_interface reset dac_1_rst output 1 if_dac_1_clk
ad_interface reset dac_2_rst output 1 if_dac_2_clk
add_interface adc_1_ch_0 conduit end
add_interface_port adc_1_ch_0 adc_1_enable_i0 enable Output 1
add_interface_port adc_1_ch_0 adc_1_valid_i0 valid Output 1
add_interface_port adc_1_ch_0 adc_1_data_i0 data Output 16
add_interface adc_1_ch_1 conduit end
add_interface_port adc_1_ch_1 adc_1_enable_q0 enable Output 1
add_interface_port adc_1_ch_1 adc_1_valid_q0 valid Output 1
add_interface_port adc_1_ch_1 adc_1_data_q0 data Output 16
add_interface adc_1_ch_2 conduit end
add_interface_port adc_1_ch_2 adc_1_enable_i1 enable Output 1
add_interface_port adc_1_ch_2 adc_1_valid_i1 valid Output 1
add_interface_port adc_1_ch_2 adc_1_data_i1 data Output 16
add_interface adc_1_ch_3 conduit end
add_interface_port adc_1_ch_3 adc_1_enable_q1 enable Output 1
add_interface_port adc_1_ch_3 adc_1_valid_q1 valid Output 1
add_interface_port adc_1_ch_3 adc_1_data_q1 data Output 16
ad_interface signal adc_1_dovf input 1 ovf
set_interface_property adc_1_ch_0 associatedClock if_adc_1_clk
set_interface_property adc_1_ch_1 associatedClock if_adc_1_clk
set_interface_property adc_1_ch_2 associatedClock if_adc_1_clk
set_interface_property adc_1_ch_3 associatedClock if_adc_1_clk
set_interface_property adc_1_ch_0 associatedReset adc_1_rst
set_interface_property adc_1_ch_1 associatedReset adc_1_rst
set_interface_property adc_1_ch_2 associatedReset adc_1_rst
set_interface_property adc_1_ch_3 associatedReset adc_1_rst
add_interface adc_2_ch_0 conduit end
add_interface_port adc_2_ch_0 adc_2_enable_i0 enable Output 1
add_interface_port adc_2_ch_0 adc_2_valid_i0 valid Output 1
add_interface_port adc_2_ch_0 adc_2_data_i0 data Output 16
add_interface adc_2_ch_1 conduit end
add_interface_port adc_2_ch_1 adc_2_enable_q0 enable Output 1
add_interface_port adc_2_ch_1 adc_2_valid_q0 valid Output 1
add_interface_port adc_2_ch_1 adc_2_data_q0 data Output 16
ad_interface signal adc_2_dovf input 1 ovf
set_interface_property adc_2_ch_0 associatedClock if_adc_2_clk
set_interface_property adc_2_ch_1 associatedClock if_adc_2_clk
set_interface_property adc_2_ch_0 associatedReset adc_2_rst
set_interface_property adc_2_ch_1 associatedReset adc_2_rst
# DAC interfaces
add_interface dac_1_ch_0 conduit end
add_interface_port dac_1_ch_0 dac_1_enable_i0 enable Output 1
add_interface_port dac_1_ch_0 dac_1_valid_i0 valid Output 1
add_interface_port dac_1_ch_0 dac_1_data_i0 data Input 16
add_interface dac_1_ch_1 conduit end
add_interface_port dac_1_ch_1 dac_1_enable_q0 enable Output 1
add_interface_port dac_1_ch_1 dac_1_valid_q0 valid Output 1
add_interface_port dac_1_ch_1 dac_1_data_q0 data Input 16
add_interface dac_1_ch_2 conduit end
add_interface_port dac_1_ch_2 dac_1_enable_i1 enable Output 1
add_interface_port dac_1_ch_2 dac_1_valid_i1 valid Output 1
add_interface_port dac_1_ch_2 dac_1_data_i1 data Input 16
add_interface dac_1_ch_3 conduit end
add_interface_port dac_1_ch_3 dac_1_enable_q1 enable Output 1
add_interface_port dac_1_ch_3 dac_1_valid_q1 valid Output 1
add_interface_port dac_1_ch_3 dac_1_data_q1 data Input 16
set_interface_property dac_1_ch_0 associatedClock if_dac_1_clk
set_interface_property dac_1_ch_1 associatedClock if_dac_1_clk
set_interface_property dac_1_ch_2 associatedClock if_dac_1_clk
set_interface_property dac_1_ch_3 associatedClock if_dac_1_clk
set_interface_property dac_1_ch_0 associatedReset dac_1_rst
set_interface_property dac_1_ch_1 associatedReset dac_1_rst
set_interface_property dac_1_ch_2 associatedReset dac_1_rst
set_interface_property dac_1_ch_3 associatedReset dac_1_rst
ad_interface signal dac_1_dunf input 1 unf
add_interface dac_2_ch_0 conduit end
add_interface_port dac_2_ch_0 dac_2_enable_i0 enable Output 1
add_interface_port dac_2_ch_0 dac_2_valid_i0 valid Output 1
add_interface_port dac_2_ch_0 dac_2_data_i0 data Input 16
add_interface dac_2_ch_1 conduit end
add_interface_port dac_2_ch_1 dac_2_enable_q0 enable Output 1
add_interface_port dac_2_ch_1 dac_2_valid_q0 valid Output 1
add_interface_port dac_2_ch_1 dac_2_data_q0 data Input 16
ad_interface signal dac_2_dunf input 1 unf
# updates
proc axi_adrv9001_elab {} {
set m_fpga_technology [get_parameter_value "FPGA_TECHNOLOGY"]
set m_cmos_lvds_n [get_parameter_value "CMOS_LVDS_N"]
add_hdl_instance adrv9001_gpio_in altera_gpio
set_instance_parameter_value adrv9001_gpio_in {DEVICE_FAMILY} {Arria 10}
set_instance_parameter_value adrv9001_gpio_in {PIN_TYPE_GUI} {Input}
set_instance_parameter_value adrv9001_gpio_in {SIZE} {1}
set_instance_parameter_value adrv9001_gpio_in {gui_io_reg_mode} {DDIO}
add_hdl_instance adrv9001_gpio_out altera_gpio
set_instance_parameter_value adrv9001_gpio_out {DEVICE_FAMILY} {Arria 10}
set_instance_parameter_value adrv9001_gpio_out {PIN_TYPE_GUI} {Output}
set_instance_parameter_value adrv9001_gpio_out {SIZE} {1}
set_instance_parameter_value adrv9001_gpio_out {gui_io_reg_mode} {DDIO}
add_hdl_instance periphery_clk_buf altclkctrl
set_instance_parameter_value periphery_clk_buf {DEVICE_FAMILY} {Arria 10}
set_instance_parameter_value periphery_clk_buf {CLOCK_TYPE} {Periphery Clock}
add_interface device_if conduit end
set_interface_property device_if associatedClock none
set_interface_property device_if associatedReset none
if {$m_cmos_lvds_n == 1} {
add_interface_port device_if rx1_dclk_in_p_dclk_in rx1_dclk_in_p_dclk_in Input 1
add_interface_port device_if rx1_idata_in_n_idata0 rx1_idata_in_n_idata0 Input 1
add_interface_port device_if rx1_idata_in_p_idata1 rx1_idata_in_p_idata1 Input 1
add_interface_port device_if rx1_qdata_in_n_qdata2 rx1_qdata_in_n_qdata2 Input 1
add_interface_port device_if rx1_qdata_in_p_qdata3 rx1_qdata_in_p_qdata3 Input 1
add_interface_port device_if rx1_strobe_in_p_strobe_in rx1_strobe_in_p_strobe_in Input 1
add_interface_port device_if rx2_dclk_in_p_dclk_in rx2_dclk_in_p_dclk_in Input 1
add_interface_port device_if rx2_idata_in_n_idata0 rx2_idata_in_n_idata0 Input 1
add_interface_port device_if rx2_idata_in_p_idata1 rx2_idata_in_p_idata1 Input 1
add_interface_port device_if rx2_qdata_in_n_qdata2 rx2_qdata_in_n_qdata2 Input 1
add_interface_port device_if rx2_qdata_in_p_qdata3 rx2_qdata_in_p_qdata3 Input 1
add_interface_port device_if rx2_strobe_in_p_strobe_in rx2_strobe_in_p_strobe_in Input 1
add_interface_port device_if tx1_dclk_out_p_dclk_out tx1_dclk_out_p_dclk_out Output 1
add_interface_port device_if tx1_dclk_in_p_dclk_in tx1_dclk_in_p_dclk_in Input 1
add_interface_port device_if tx1_idata_out_n_idata0 tx1_idata_out_n_idata0 Output 1
add_interface_port device_if tx1_idata_out_p_idata1 tx1_idata_out_p_idata1 Output 1
add_interface_port device_if tx1_qdata_out_n_qdata2 tx1_qdata_out_n_qdata2 Output 1
add_interface_port device_if tx1_qdata_out_p_qdata3 tx1_qdata_out_p_qdata3 Output 1
add_interface_port device_if tx1_strobe_out_p_strobe_out tx1_strobe_out_p_strobe_out Output 1
add_interface_port device_if tx2_dclk_out_p_dclk_out tx2_dclk_out_p_dclk_out Output 1
add_interface_port device_if tx2_dclk_in_p_dclk_in tx2_dclk_in_p_dclk_in Input 1
add_interface_port device_if tx2_idata_out_n_idata0 tx2_idata_out_n_idata0 Output 1
add_interface_port device_if tx2_idata_out_p_idata1 tx2_idata_out_p_idata1 Output 1
add_interface_port device_if tx2_qdata_out_n_qdata2 tx2_qdata_out_n_qdata2 Output 1
add_interface_port device_if tx2_qdata_out_p_qdata3 tx2_qdata_out_p_qdata3 Output 1
add_interface_port device_if tx2_strobe_out_p_strobe_out tx2_strobe_out_p_strobe_out Output 1
}
}

View File

@ -0,0 +1,438 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001_if #(
parameter CMOS_LVDS_N = 0,
parameter FPGA_TECHNOLOGY = 0,
parameter NUM_LANES = 3,
parameter DRP_WIDTH = 5,
parameter IO_DELAY_GROUP = "dev_if_delay_group",
parameter USE_RX_CLK_FOR_TX = 0
) (
input ref_clk,
input tx_output_enable,
input mssi_sync,
// device interface
input rx1_dclk_in_n_NC,
input rx1_dclk_in_p_dclk_in,
input rx1_idata_in_n_idata0,
input rx1_idata_in_p_idata1,
input rx1_qdata_in_n_qdata2,
input rx1_qdata_in_p_qdata3,
input rx1_strobe_in_n_NC,
input rx1_strobe_in_p_strobe_in,
input rx2_dclk_in_n_NC,
input rx2_dclk_in_p_dclk_in,
input rx2_idata_in_n_idata0,
input rx2_idata_in_p_idata1,
input rx2_qdata_in_n_qdata2,
input rx2_qdata_in_p_qdata3,
input rx2_strobe_in_n_NC,
input rx2_strobe_in_p_strobe_in,
output tx1_dclk_out_n_NC,
output tx1_dclk_out_p_dclk_out,
input tx1_dclk_in_n_NC,
input tx1_dclk_in_p_dclk_in,
output tx1_idata_out_n_idata0,
output tx1_idata_out_p_idata1,
output tx1_qdata_out_n_qdata2,
output tx1_qdata_out_p_qdata3,
output tx1_strobe_out_n_NC,
output tx1_strobe_out_p_strobe_out,
output tx2_dclk_out_n_NC,
output tx2_dclk_out_p_dclk_out,
input tx2_dclk_in_n_NC,
input tx2_dclk_in_p_dclk_in,
output tx2_idata_out_n_idata0,
output tx2_idata_out_p_idata1,
output tx2_qdata_out_n_qdata2,
output tx2_qdata_out_p_qdata3,
output tx2_strobe_out_n_NC,
output tx2_strobe_out_p_strobe_out,
// delay interface (for IDELAY macros)
input delay_clk,
input delay_rx1_rst,
input delay_rx2_rst,
output delay_rx1_locked,
output delay_rx2_locked,
input up_clk,
input [NUM_LANES-1:0] up_rx1_dld,
input [DRP_WIDTH*NUM_LANES-1:0] up_rx1_dwdata,
output [DRP_WIDTH*NUM_LANES-1:0] up_rx1_drdata,
input [NUM_LANES-1:0] up_rx2_dld,
input [DRP_WIDTH*NUM_LANES-1:0] up_rx2_dwdata,
output [DRP_WIDTH*NUM_LANES-1:0] up_rx2_drdata,
// upper layer data interface
output rx1_clk,
input rx1_rst,
output rx1_data_valid,
output [15:0] rx1_data_i,
output [15:0] rx1_data_q,
input rx1_single_lane,
input rx1_sdr_ddr_n,
output rx2_clk,
input rx2_rst,
output rx2_data_valid,
output [15:0] rx2_data_i,
output [15:0] rx2_data_q,
input rx2_single_lane,
input rx2_sdr_ddr_n,
output tx1_clk,
input tx1_rst,
input tx1_data_valid,
input [15:0] tx1_data_i,
input [15:0] tx1_data_q,
input tx1_single_lane,
input tx1_sdr_ddr_n,
output tx2_clk,
input tx2_rst,
input tx2_data_valid,
input [15:0] tx2_data_i,
input [15:0] tx2_data_q,
input tx2_single_lane,
input tx2_sdr_ddr_n
);
// Tx has an extra lane to drive the clock
localparam TX_NUM_LANES = NUM_LANES + 1;
wire adc_1_clk_div;
wire [7:0] adc_1_data_0;
wire [7:0] adc_1_data_1;
wire [7:0] adc_1_data_2;
wire [7:0] adc_1_data_3;
wire [7:0] adc_1_data_strobe;
wire adc_1_clk;
wire adc_1_valid;
wire adc_1_ssi_rst;
wire adc_2_clk_div;
wire [7:0] adc_2_data_0;
wire [7:0] adc_2_data_1;
wire [7:0] adc_2_data_2;
wire [7:0] adc_2_data_3;
wire [7:0] adc_2_data_strobe;
wire adc_2_clk;
wire adc_2_valid;
wire adc_2_ssi_rst;
wire dac_1_clk_div;
wire [7:0] dac_1_data_0;
wire [7:0] dac_1_data_1;
wire [7:0] dac_1_data_2;
wire [7:0] dac_1_data_3;
wire [7:0] dac_1_data_strobe;
wire [7:0] dac_1_data_clk;
wire dac_1_data_valid;
wire dac_2_clk_div;
wire [7:0] dac_2_data_0;
wire [7:0] dac_2_data_1;
wire [7:0] dac_2_data_2;
wire [7:0] dac_2_data_3;
wire [7:0] dac_2_data_strobe;
wire [7:0] dac_2_data_clk;
wire dac_2_data_valid;
wire rx_ssi_sync_out;
adrv9001_rx
#(.CMOS_LVDS_N (CMOS_LVDS_N),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.NUM_LANES (NUM_LANES),
.DRP_WIDTH (DRP_WIDTH),
.IODELAY_CTRL (1),
.IO_DELAY_GROUP ({IO_DELAY_GROUP,"_rx"})
) i_rx_1_phy (
.rx_dclk_in_n_NC (rx1_dclk_in_n_NC),
.rx_dclk_in_p_dclk_in (rx1_dclk_in_p_dclk_in),
.rx_idata_in_n_idata0 (rx1_idata_in_n_idata0),
.rx_idata_in_p_idata1 (rx1_idata_in_p_idata1),
.rx_qdata_in_n_qdata2 (rx1_qdata_in_n_qdata2),
.rx_qdata_in_p_qdata3 (rx1_qdata_in_p_qdata3),
.rx_strobe_in_n_NC (rx1_strobe_in_n_NC),
.rx_strobe_in_p_strobe_in (rx1_strobe_in_p_strobe_in),
.adc_rst (rx1_rst),
.adc_clk (adc_1_clk),
.adc_clk_div (adc_1_clk_div),
.adc_data_0 (adc_1_data_0),
.adc_data_1 (adc_1_data_1),
.adc_data_2 (adc_1_data_2),
.adc_data_3 (adc_1_data_3),
.adc_data_strobe (adc_1_data_strobe),
.adc_valid (adc_1_valid),
.up_clk (up_clk),
.up_adc_dld (up_rx1_dld),
.up_adc_dwdata (up_rx1_dwdata),
.up_adc_drdata (up_rx1_drdata),
.delay_clk (delay_clk),
.delay_rst (delay_rx1_rst),
.delay_locked (delay_rx1_locked),
.mssi_sync (mssi_sync),
.ssi_sync_out (rx_ssi_sync_out),
.ssi_sync_in (rx_ssi_sync_out),
.ssi_rst (adc_1_ssi_rst)
);
adrv9001_rx_link #(
.CMOS_LVDS_N (CMOS_LVDS_N)
) i_rx_1_link (
.adc_clk_div (adc_1_clk_div),
.adc_data_0 (adc_1_data_0),
.adc_data_1 (adc_1_data_1),
.adc_data_2 (adc_1_data_2),
.adc_data_3 (adc_1_data_3),
.adc_data_strobe (adc_1_data_strobe),
.adc_valid (adc_1_valid),
// ADC interface
.rx_clk (rx1_clk),
.rx_data_valid (rx1_data_valid),
.rx_data_i (rx1_data_i),
.rx_data_q (rx1_data_q),
.rx_single_lane (rx1_single_lane),
.rx_sdr_ddr_n (rx1_sdr_ddr_n)
);
adrv9001_rx
#(.CMOS_LVDS_N (CMOS_LVDS_N),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.NUM_LANES (NUM_LANES),
.DRP_WIDTH (DRP_WIDTH),
.IODELAY_CTRL (0),
.IO_DELAY_GROUP ({IO_DELAY_GROUP,"_rx"})
) i_rx_2_phy (
.rx_dclk_in_n_NC (rx2_dclk_in_n_NC),
.rx_dclk_in_p_dclk_in (rx2_dclk_in_p_dclk_in),
.rx_idata_in_n_idata0 (rx2_idata_in_n_idata0),
.rx_idata_in_p_idata1 (rx2_idata_in_p_idata1),
.rx_qdata_in_n_qdata2 (rx2_qdata_in_n_qdata2),
.rx_qdata_in_p_qdata3 (rx2_qdata_in_p_qdata3),
.rx_strobe_in_n_NC (rx2_strobe_in_n_NC),
.rx_strobe_in_p_strobe_in (rx2_strobe_in_p_strobe_in),
.adc_rst (rx2_rst),
.adc_clk (adc_2_clk),
.adc_clk_div (adc_2_clk_div),
.adc_data_0 (adc_2_data_0),
.adc_data_1 (adc_2_data_1),
.adc_data_2 (adc_2_data_2),
.adc_data_3 (adc_2_data_3),
.adc_data_strobe (adc_2_data_strobe),
.adc_valid (adc_2_valid),
.up_clk (up_clk),
.up_adc_dld (up_rx2_dld),
.up_adc_dwdata (up_rx2_dwdata),
.up_adc_drdata (up_rx2_drdata),
.delay_clk (delay_clk),
.delay_rst (delay_rx2_rst),
.delay_locked (delay_rx2_locked),
.mssi_sync (1'b0),
.ssi_sync_out (),
.ssi_sync_in (rx_ssi_sync_out),
.ssi_rst (adc_2_ssi_rst)
);
adrv9001_rx_link #(
.CMOS_LVDS_N (CMOS_LVDS_N)
) i_rx_2_link (
.adc_clk_div (adc_2_clk_div),
.adc_data_0 (adc_2_data_0),
.adc_data_1 (adc_2_data_1),
.adc_data_2 (adc_2_data_2),
.adc_data_3 (adc_2_data_3),
.adc_data_strobe (adc_2_data_strobe),
.adc_valid (adc_2_valid),
// ADC interface
.rx_clk (rx2_clk),
.rx_data_valid (rx2_data_valid),
.rx_data_i (rx2_data_i),
.rx_data_q (rx2_data_q),
.rx_single_lane (rx2_single_lane),
.rx_sdr_ddr_n (rx2_sdr_ddr_n)
);
adrv9001_tx #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.NUM_LANES (TX_NUM_LANES),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.USE_RX_CLK_FOR_TX (USE_RX_CLK_FOR_TX)
) i_tx_1_phy (
.ref_clk (ref_clk),
.up_clk (up_clk),
.tx_output_enable(tx_output_enable),
.tx_dclk_out_n_NC (tx1_dclk_out_n_NC),
.tx_dclk_out_p_dclk_out (tx1_dclk_out_p_dclk_out),
.tx_dclk_in_n_NC (tx1_dclk_in_n_NC),
.tx_dclk_in_p_dclk_in (tx1_dclk_in_p_dclk_in),
.tx_idata_out_n_idata0 (tx1_idata_out_n_idata0),
.tx_idata_out_p_idata1 (tx1_idata_out_p_idata1),
.tx_qdata_out_n_qdata2 (tx1_qdata_out_n_qdata2),
.tx_qdata_out_p_qdata3 (tx1_qdata_out_p_qdata3),
.tx_strobe_out_n_NC (tx1_strobe_out_n_NC),
.tx_strobe_out_p_strobe_out (tx1_strobe_out_p_strobe_out),
.rx_clk_div (adc_1_clk_div),
.rx_clk (adc_1_clk),
.rx_ssi_rst (adc_1_ssi_rst),
.dac_rst (tx1_rst),
.dac_clk_div (dac_1_clk_div),
.dac_data_0 (dac_1_data_0),
.dac_data_1 (dac_1_data_1),
.dac_data_2 (dac_1_data_2),
.dac_data_3 (dac_1_data_3),
.dac_data_strb (dac_1_data_strobe),
.dac_data_clk (dac_1_data_clk),
.dac_data_valid (dac_1_data_valid),
.mssi_sync (mssi_sync)
);
adrv9001_tx_link #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.CLK_DIV_IS_FAST_CLK (FPGA_TECHNOLOGY >= 100)
) i_tx_1_link (
.dac_clk_div (dac_1_clk_div),
.dac_data_0 (dac_1_data_0),
.dac_data_1 (dac_1_data_1),
.dac_data_2 (dac_1_data_2),
.dac_data_3 (dac_1_data_3),
.dac_data_strobe (dac_1_data_strobe),
.dac_data_clk (dac_1_data_clk),
.dac_data_valid (dac_1_data_valid),
// DAC interface
.tx_clk (tx1_clk),
.tx_rst (tx1_rst),
.tx_data_valid (tx1_data_valid),
.tx_data_i (tx1_data_i),
.tx_data_q (tx1_data_q),
.tx_sdr_ddr_n (tx1_sdr_ddr_n),
.tx_single_lane (tx1_single_lane)
);
adrv9001_tx #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.NUM_LANES (TX_NUM_LANES),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.USE_RX_CLK_FOR_TX (USE_RX_CLK_FOR_TX)
) i_tx_2_phy (
.ref_clk (ref_clk),
.up_clk (up_clk),
.tx_output_enable(tx_output_enable),
.tx_dclk_out_n_NC (tx2_dclk_out_n_NC),
.tx_dclk_out_p_dclk_out (tx2_dclk_out_p_dclk_out),
.tx_dclk_in_n_NC (tx2_dclk_in_n_NC),
.tx_dclk_in_p_dclk_in (tx2_dclk_in_p_dclk_in),
.tx_idata_out_n_idata0 (tx2_idata_out_n_idata0),
.tx_idata_out_p_idata1 (tx2_idata_out_p_idata1),
.tx_qdata_out_n_qdata2 (tx2_qdata_out_n_qdata2),
.tx_qdata_out_p_qdata3 (tx2_qdata_out_p_qdata3),
.tx_strobe_out_n_NC (tx2_strobe_out_n_NC),
.tx_strobe_out_p_strobe_out (tx2_strobe_out_p_strobe_out),
.rx_clk_div (adc_2_clk_div),
.rx_clk (adc_2_clk),
.rx_ssi_rst (adc_2_ssi_rst),
.dac_rst (tx2_rst),
.dac_clk_div (dac_2_clk_div),
.dac_data_0 (dac_2_data_0),
.dac_data_1 (dac_2_data_1),
.dac_data_2 (dac_2_data_2),
.dac_data_3 (dac_2_data_3),
.dac_data_strb (dac_2_data_strobe),
.dac_data_clk (dac_2_data_clk),
.dac_data_valid (dac_2_data_valid),
.mssi_sync (mssi_sync)
);
adrv9001_tx_link #(
.CMOS_LVDS_N (CMOS_LVDS_N),
.CLK_DIV_IS_FAST_CLK (FPGA_TECHNOLOGY >= 100)
) i_tx_2_link (
.dac_clk_div (dac_2_clk_div),
.dac_data_0 (dac_2_data_0),
.dac_data_1 (dac_2_data_1),
.dac_data_2 (dac_2_data_2),
.dac_data_3 (dac_2_data_3),
.dac_data_strobe (dac_2_data_strobe),
.dac_data_clk (dac_2_data_clk),
.dac_data_valid (dac_2_data_valid),
// DAC interface
.tx_clk (tx2_clk),
.tx_rst (tx2_rst),
.tx_data_valid (tx2_data_valid),
.tx_data_i (tx2_data_i),
.tx_data_q (tx2_data_q),
.tx_sdr_ddr_n (tx2_sdr_ddr_n),
.tx_single_lane (tx2_single_lane)
);
endmodule

View File

@ -0,0 +1,80 @@
# ip
source ../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl
adi_ip_create axi_adrv9001
adi_ip_files axi_adrv9001 [list \
"$ad_hdl_dir/library/xilinx/common/ad_serdes_clk.v" \
"$ad_hdl_dir/library/xilinx/common/ad_mmcm_drp.v" \
"$ad_hdl_dir/library/xilinx/common/ad_serdes_in.v" \
"$ad_hdl_dir/library/xilinx/common/ad_serdes_out.v" \
"$ad_hdl_dir/library/xilinx/common/ad_mul.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_1.v" \
"$ad_hdl_dir/library/common/ad_dds_2.v" \
"$ad_hdl_dir/library/common/ad_dds.v" \
"$ad_hdl_dir/library/common/ad_datafmt.v" \
"$ad_hdl_dir/library/common/ad_rst.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_common.v" \
"$ad_hdl_dir/library/common/up_adc_channel.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_pnmon.v" \
"$ad_hdl_dir/library/common/ad_pngen.v" \
"$ad_hdl_dir/library/common/up_axi.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" \
"adrv9001_rx.v" \
"adrv9001_tx.v" \
"adrv9001_pack.v" \
"adrv9001_aligner4.v" \
"adrv9001_aligner8.v" \
"adrv9001_rx_link.v" \
"adrv9001_tx_link.v" \
"axi_adrv9001_rx.v" \
"axi_adrv9001_rx_channel.v" \
"axi_adrv9001_if.v" \
"axi_adrv9001_tx.v" \
"axi_adrv9001_tx_channel.v" \
"axi_adrv9001_core.v" \
"axi_adrv9001_constr.xdc" \
"axi_adrv9001.v" ]
adi_ip_properties axi_adrv9001
adi_init_bd_tcl
adi_ip_bd axi_adrv9001 "bd/bd.tcl"
adi_ip_add_core_dependencies { \
analog.com:user:util_cdc:1.0 \
}
ipx::infer_bus_interface delay_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface adc_1_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface adc_2_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface dac_1_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface dac_2_clk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface adc_1_rst xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface adc_2_rst xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface dac_1_rst xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]
ipx::infer_bus_interface dac_2_rst xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]
ipx::add_bus_parameter POLARITY [ipx::get_bus_interfaces adc_1_rst -of_objects [ipx::current_core]]
ipx::add_bus_parameter POLARITY [ipx::get_bus_interfaces adc_2_rst -of_objects [ipx::current_core]]
ipx::add_bus_parameter POLARITY [ipx::get_bus_interfaces dac_1_rst -of_objects [ipx::current_core]]
ipx::add_bus_parameter POLARITY [ipx::get_bus_interfaces dac_2_rst -of_objects [ipx::current_core]]
adi_add_auto_fpga_spec_params
ipx::create_xgui_files [ipx::current_core]
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,372 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001_rx #(
parameter ID = 0,
parameter CMOS_LVDS_N = 0,
parameter COMMON_BASE_ADDR = 'h00,
parameter CHANNEL_BASE_ADDR = 'h01,
parameter MODE_R1 = 1,
parameter FPGA_TECHNOLOGY = 0,
parameter FPGA_FAMILY = 0,
parameter SPEED_GRADE = 0,
parameter DEV_PACKAGE = 0,
parameter DATAFORMAT_DISABLE = 0,
parameter DCFILTER_DISABLE = 0,
parameter IQCORRECTION_DISABLE = 1
) (
// adc interface
output adc_rst,
input adc_clk,
input adc_valid_A,
input [ 15:0] adc_data_i_A,
input [ 15:0] adc_data_q_A,
input adc_valid_B,
input [ 15:0] adc_data_i_B,
input [ 15:0] adc_data_q_B,
output adc_single_lane,
output adc_sdr_ddr_n,
output adc_r1_mode,
// dac loopback interface
input dac_data_valid_A,
input [ 15:0] dac_data_i_A,
input [ 15:0] dac_data_q_A,
input dac_data_valid_B,
input [ 15:0] dac_data_i_B,
input [ 15:0] dac_data_q_B,
// dma interface
output adc_valid,
output adc_enable_i0,
output [ 15:0] adc_data_i0,
output adc_enable_q0,
output [ 15:0] adc_data_q0,
output adc_enable_i1,
output [ 15:0] adc_data_i1,
output adc_enable_q1,
output [ 15:0] adc_data_q1,
input adc_dovf,
// 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
);
// configuration settings
localparam CONFIG = (CMOS_LVDS_N * 128) +
(MODE_R1 * 16) +
(DATAFORMAT_DISABLE * 4) +
(DCFILTER_DISABLE * 2) +
(IQCORRECTION_DISABLE * 1);
// internal registers
reg up_status_pn_err = 'd0;
reg up_status_pn_oos = 'd0;
reg up_status_or = 'd0;
// internal signals
wire [ 15:0] adc_data_iq_i0_s;
wire [ 15:0] adc_data_iq_q0_s;
wire [ 15:0] adc_data_iq_i1_s;
wire [ 15:0] adc_data_iq_q1_s;
wire [ 4:0] adc_num_lanes;
wire [ 3:0] up_adc_pn_err_s;
wire [ 3:0] up_adc_pn_oos_s;
wire [ 3:0] up_adc_or_s;
wire [ 4:0] up_wack_s;
wire [ 4:0] up_rack_s;
wire [ 31:0] up_rdata_s[0:4];
wire up_adc_r1_mode;
wire adc_valid_out_i0;
wire adc_valid_out_i1;
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_status_pn_err <= 'd0;
up_status_pn_oos <= 'd0;
up_status_or <= 'd0;
up_wack <= 'd0;
up_rack <= 'd0;
up_rdata <= 'd0;
end else begin
up_status_pn_err <= up_adc_r1_mode ? | up_adc_pn_err_s[1:0] : | up_adc_pn_err_s[3:0];
up_status_pn_oos <= up_adc_r1_mode ? | up_adc_pn_oos_s[1:0] : | up_adc_pn_oos_s[3:0];
up_status_or <= | up_adc_or_s;
up_wack <= | up_wack_s;
up_rack <= | up_rack_s;
up_rdata <= up_rdata_s[0] | up_rdata_s[1] | up_rdata_s[2] |
up_rdata_s[3] | up_rdata_s[4];
end
end
// channel width is 32 bits
assign adc_valid = adc_enable_i0 ? adc_valid_out_i0 : adc_valid_out_i1;
// channel 0 (i)
axi_adrv9001_rx_channel #(
.Q_OR_I_N (0),
.COMMON_ID (CHANNEL_BASE_ADDR),
.DISABLE (0),
.DATAFORMAT_DISABLE (DATAFORMAT_DISABLE),
.DCFILTER_DISABLE (DCFILTER_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DATA_WIDTH (16))
i_rx_channel_0 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid_in (adc_valid_A),
.adc_data_in (adc_data_i_A[15:0]),
.adc_valid_out (adc_valid_out_i0),
.adc_data_out (adc_data_i0),
.adc_data_iq_in (adc_data_iq_q0_s),
.adc_data_iq_out (adc_data_iq_i0_s),
.adc_enable (adc_enable_i0),
.dac_valid_in (dac_data_valid_A),
.dac_data_in (dac_data_i_A),
.up_adc_pn_err (up_adc_pn_err_s[0]),
.up_adc_pn_oos (up_adc_pn_oos_s[0]),
.up_adc_or (up_adc_or_s[0]),
.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[0]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[0]),
.up_rack (up_rack_s[0]));
// channel 1 (q)
axi_adrv9001_rx_channel #(
.Q_OR_I_N (1),
.COMMON_ID (CHANNEL_BASE_ADDR),
.CHANNEL_ID (1),
.DISABLE (0),
.DATAFORMAT_DISABLE (DATAFORMAT_DISABLE),
.DCFILTER_DISABLE (DCFILTER_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DATA_WIDTH (16))
i_rx_channel_1 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid_in (adc_valid_A),
.adc_data_in (adc_data_q_A[15:0]),
.adc_valid_out (),
.adc_data_out (adc_data_q0),
.adc_data_iq_in (adc_data_iq_i0_s),
.adc_data_iq_out (adc_data_iq_q0_s),
.adc_enable (adc_enable_q0),
.dac_valid_in (dac_data_valid_A),
.dac_data_in (dac_data_q_A),
.up_adc_pn_err (up_adc_pn_err_s[1]),
.up_adc_pn_oos (up_adc_pn_oos_s[1]),
.up_adc_or (up_adc_or_s[1]),
.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[1]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[1]),
.up_rack (up_rack_s[1]));
// channel 2 (i)
axi_adrv9001_rx_channel #(
.Q_OR_I_N (0),
.COMMON_ID (CHANNEL_BASE_ADDR),
.CHANNEL_ID (2),
.DISABLE (MODE_R1),
.DATAFORMAT_DISABLE (DATAFORMAT_DISABLE),
.DCFILTER_DISABLE (DCFILTER_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DATA_WIDTH (16))
i_rx_channel_2 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid_in (adc_valid_B),
.adc_data_in (adc_data_i_B[15:0]),
.adc_valid_out (adc_valid_out_i1),
.adc_data_out (adc_data_i1),
.adc_data_iq_in (adc_data_iq_q1_s),
.adc_data_iq_out (adc_data_iq_i1_s),
.adc_enable (adc_enable_i1),
.dac_valid_in (dac_data_valid_B),
.dac_data_in (dac_data_i_B),
.up_adc_pn_err (up_adc_pn_err_s[2]),
.up_adc_pn_oos (up_adc_pn_oos_s[2]),
.up_adc_or (up_adc_or_s[2]),
.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[2]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[2]),
.up_rack (up_rack_s[2]));
// channel 3 (q)
axi_adrv9001_rx_channel #(
.Q_OR_I_N (1),
.COMMON_ID (CHANNEL_BASE_ADDR),
.CHANNEL_ID (3),
.DISABLE (MODE_R1),
.DATAFORMAT_DISABLE (DATAFORMAT_DISABLE),
.DCFILTER_DISABLE (DCFILTER_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DATA_WIDTH (16))
i_rx_channel_3 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid_in (adc_valid_B),
.adc_data_in (adc_data_q_B[15:0]),
.adc_valid_out (),
.adc_data_out (adc_data_q1),
.adc_data_iq_in (adc_data_iq_i1_s),
.adc_data_iq_out (adc_data_iq_q1_s),
.adc_enable (adc_enable_q1),
.dac_valid_in (dac_data_valid_B),
.dac_data_in (dac_data_q_B),
.up_adc_pn_err (up_adc_pn_err_s[3]),
.up_adc_pn_oos (up_adc_pn_oos_s[3]),
.up_adc_or (up_adc_or_s[3]),
.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[3]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[3]),
.up_rack (up_rack_s[3]));
// common processor control
up_adc_common #(
.ID (ID),
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
.FPGA_FAMILY (FPGA_FAMILY),
.SPEED_GRADE (SPEED_GRADE),
.DEV_PACKAGE (DEV_PACKAGE),
.COMMON_ID (COMMON_BASE_ADDR),
.CONFIG(CONFIG),
.DRP_DISABLE(1),
.USERPORTS_DISABLE(1),
.GPIO_DISABLE(1),
.START_CODE_DISABLE(1))
i_up_adc_common (
.mmcm_rst (),
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_r1_mode (adc_r1_mode),
.adc_ddr_edgesel (),
.adc_pin_mode (),
.adc_status (1'b1),
.adc_sync_status (1'd0),
.adc_status_ovf (adc_dovf),
.adc_clk_ratio (32'd1),
.adc_start_code (),
.adc_sref_sync (),
.adc_sync (),
.adc_num_lanes (adc_num_lanes),
.adc_sdr_ddr_n (adc_sdr_ddr_n),
.up_pps_rcounter(32'h0),
.up_pps_status(1'b0),
.up_pps_irq_mask(),
.up_adc_r1_mode (up_adc_r1_mode),
.up_adc_ce (),
.up_status_pn_err (up_status_pn_err),
.up_status_pn_oos (up_status_pn_oos),
.up_status_or (up_status_or),
.up_drp_sel (),
.up_drp_wr (),
.up_drp_addr (),
.up_drp_wdata (),
.up_drp_rdata (32'd0),
.up_drp_ready (1'd0),
.up_drp_locked (1'd1),
.up_usr_chanmax_out (),
.up_usr_chanmax_in (8'd3),
.up_adc_gpio_in (32'd0),
.up_adc_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[4]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[4]),
.up_rack (up_rack_s[4]));
assign adc_single_lane = adc_num_lanes[0];
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,324 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001_rx_channel #(
parameter Q_OR_I_N = 0,
parameter COMMON_ID = 0,
parameter CHANNEL_ID = 0,
parameter DISABLE = 0,
parameter DATAFORMAT_DISABLE = 0,
parameter DCFILTER_DISABLE = 0,
parameter IQCORRECTION_DISABLE = 0,
parameter DATA_WIDTH = 16
) (
// adc interface
input adc_clk,
input adc_rst,
input adc_valid_in,
input [(DATA_WIDTH-1):0] adc_data_in,
output adc_valid_out,
output [(DATA_WIDTH-1):0] adc_data_out,
input [(DATA_WIDTH-1):0] adc_data_iq_in,
output [(DATA_WIDTH-1):0] adc_data_iq_out,
output adc_enable,
input dac_valid_in,
input [(DATA_WIDTH-1):0] dac_data_in,
// channel interface
output up_adc_pn_err,
output up_adc_pn_oos,
output up_adc_or,
// processor 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
);
localparam NUM_OF_SAMPLES = DATA_WIDTH/16;
// internal signals
wire [(NUM_OF_SAMPLES-1):0] adc_dfmt_valid_s;
wire [(DATA_WIDTH-1):0] adc_dfmt_data_s;
wire [(NUM_OF_SAMPLES-1):0] adc_dcfilter_valid_s;
wire [(DATA_WIDTH-1):0] adc_dcfilter_data_s;
wire [(NUM_OF_SAMPLES-1):0] adc_valid_out_s;
wire adc_pn_err_s;
wire adc_pn_oos_s;
wire [3:0] adc_pnseq_sel;
wire adc_dfmt_se_s;
wire adc_dfmt_type_s;
wire adc_dfmt_enable_s;
wire adc_dcfilt_enb_s;
wire [15:0] adc_dcfilt_offset_s;
wire [15:0] adc_dcfilt_coeff_s;
wire adc_iqcor_enb_s;
wire [15:0] adc_iqcor_coeff_1_s;
wire [15:0] adc_iqcor_coeff_2_s;
wire [(DATA_WIDTH-1):0] adc_data_pn;
wire [(DATA_WIDTH-1):0] pn7_data;
wire [(DATA_WIDTH-1):0] pn15_data;
wire [ 3:0] adc_data_sel_s;
wire [15:0] adc_data_in_s;
wire adc_valid_in_s;
reg [15:0] full_ramp_counter = 'd0;
reg adc_valid_in_d = 'h0;
reg adc_valid_in_2d = 'h0;
reg [(DATA_WIDTH-1):0] adc_data_in_d = 'h0;
reg [(DATA_WIDTH-1):0] adc_data_in_2d = 'h0;
reg dac_valid_in_d = 'h0;
reg dac_valid_in_2d = 'h0;
reg [(DATA_WIDTH-1):0] dac_data_in_d = 'h0;
reg [(DATA_WIDTH-1):0] dac_data_in_2d = 'h0;
// variables
genvar n;
// input pipeline stage to protect logic if data comes from an async clock domain
always @(posedge adc_clk) begin
adc_valid_in_d <= adc_valid_in;
adc_valid_in_2d <= adc_valid_in_d;
adc_data_in_d <= adc_data_in;
adc_data_in_2d <= adc_data_in_d;
end
always @(posedge adc_clk) begin
dac_valid_in_d <= dac_valid_in;
dac_valid_in_2d <= dac_valid_in_d;
dac_data_in_d <= dac_data_in;
dac_data_in_2d <= dac_data_in_d;
end
assign adc_data_in_s = (adc_data_sel_s == 4'h0) ? adc_data_in_2d : dac_data_in_2d;
assign adc_valid_in_s = (adc_data_sel_s == 4'h0) ? adc_valid_in_2d : dac_valid_in_2d;
// iq correction inputs
generate
for (n = 0; n < NUM_OF_SAMPLES; n = n + 1) begin: g_datafmt
if (DISABLE == 1 || DATAFORMAT_DISABLE == 1) begin
assign adc_dfmt_valid_s[n] = adc_valid_in_s;
assign adc_dfmt_data_s[((16*n)+15):(16*n)] = adc_data_in_s[((16*n)+15):(16*n)];
end else begin
ad_datafmt #(.DATA_WIDTH (16)) i_ad_datafmt (
.clk (adc_clk),
.valid (adc_valid_in_s),
.data (adc_data_in_s[((16*n)+15):(16*n)]),
.valid_out (adc_dfmt_valid_s[n]),
.data_out (adc_dfmt_data_s[((16*n)+15):(16*n)]),
.dfmt_enable (adc_dfmt_enable_s),
.dfmt_type (adc_dfmt_type_s),
.dfmt_se (adc_dfmt_se_s));
end
end
for (n = 0; n < NUM_OF_SAMPLES; n = n + 1) begin: g_dcfilter
if (DISABLE == 1 || DCFILTER_DISABLE == 1) begin
assign adc_dcfilter_valid_s[n] = adc_dfmt_valid_s[n];
assign adc_dcfilter_data_s[((16*n)+15):(16*n)] = adc_dfmt_data_s[((16*n)+15):(16*n)];
end else begin
ad_dcfilter i_ad_dcfilter (
.clk (adc_clk),
.valid (adc_dfmt_valid_s[n]),
.data (adc_dfmt_data_s[((16*n)+15):(16*n)]),
.valid_out (adc_dcfilter_valid_s[n]),
.data_out (adc_dcfilter_data_s[((16*n)+15):(16*n)]),
.dcfilt_enb (adc_dcfilt_enb_s),
.dcfilt_coeff (adc_dcfilt_coeff_s),
.dcfilt_offset (adc_dcfilt_offset_s));
end
end
assign adc_valid_out = adc_valid_out_s[0];
assign adc_data_iq_out = adc_dcfilter_data_s;
for (n = 0; n < NUM_OF_SAMPLES; n = n + 1) begin: g_iqcor
if (DISABLE == 1 || IQCORRECTION_DISABLE == 1) begin
assign adc_valid_out_s[n] = adc_dcfilter_valid_s[n];
assign adc_data_out[((16*n)+15):(16*n)] = adc_dcfilter_data_s[((16*n)+15):(16*n)];
end else begin
ad_iqcor #(.Q_OR_I_N (Q_OR_I_N)) i_ad_iqcor (
.clk (adc_clk),
.valid (adc_dcfilter_valid_s[n]),
.data_in (adc_dcfilter_data_s[((16*n)+15):(16*n)]),
.data_iq (adc_data_iq_in[((16*n)+15):(16*n)]),
.valid_out (adc_valid_out_s[n]),
.data_out (adc_data_out[((16*n)+15):(16*n)]),
.iqcor_enable (adc_iqcor_enb_s),
.iqcor_coeff_1 (adc_iqcor_coeff_1_s),
.iqcor_coeff_2 (adc_iqcor_coeff_2_s));
end
end
if (DISABLE == 1) begin
assign adc_enable = 1'b0;
assign up_adc_pn_err = 1'b0;
assign up_adc_pn_oos = 1'b0;
assign up_adc_or = 1'b0;
assign up_wack = 1'b0;
assign up_rdata = 32'b0;
assign up_rack = 1'b0;
end else begin
// pn oos & pn err
// PN7 x^7 + x^6 + 1
ad_pngen #(
.POL_MASK ( (1<<7) | (1<<6) ),
.POL_W (7),
.DW (16)
) PN7_gen (
.clk (adc_clk),
.reset (adc_rst),
.clk_en (adc_valid_in_s),
.pn_init (adc_pn_oos_s),
.pn_data_in (adc_data_in_s),
.pn_data_out (pn7_data)
);
// PN15 x^15 + x^14 + 1
ad_pngen #(
.POL_MASK ( (1<<15) | (1<<14) ),
.POL_W (15),
.DW (16)
) PN15_gen (
.clk (adc_clk),
.reset (adc_rst),
.clk_en (adc_valid_in_s),
.pn_init (adc_pn_oos_s),
.pn_data_in (adc_data_in_s),
.pn_data_out (pn15_data)
);
// reference nibble ramp and full ramp generator
always @(posedge adc_clk) begin
if (adc_pn_oos_s) begin
full_ramp_counter <= adc_data_in_s + 16'd1;
end else if (adc_valid_in_s) begin
full_ramp_counter <= full_ramp_counter + 16'd1;
end
end
assign adc_data_pn = adc_pnseq_sel == 4'd4 ? pn7_data :
adc_pnseq_sel == 4'd5 ? pn15_data :
adc_pnseq_sel == 4'd10 ? {4{full_ramp_counter[3:0]}} :
adc_pnseq_sel == 4'd11 ? full_ramp_counter : 'h0;
ad_pnmon #(
.DATA_WIDTH (DATA_WIDTH),
.OOS_THRESHOLD (8),
.ALLOW_ZERO_MASKING(1)
) i_pnmon (
.adc_clk (adc_clk),
.adc_valid_in (adc_valid_in_s),
.adc_data_in (adc_data_in_s),
.adc_data_pn (adc_data_pn),
.adc_pattern_has_zero (adc_pnseq_sel[3]),
.adc_pn_oos (adc_pn_oos_s),
.adc_pn_err (adc_pn_err_s)
);
up_adc_channel #(
.COMMON_ID (COMMON_ID),
.CHANNEL_ID (CHANNEL_ID),
.USERPORTS_DISABLE(1),
.DATAFORMAT_DISABLE(DATAFORMAT_DISABLE),
.DCFILTER_DISABLE(DCFILTER_DISABLE),
.IQCORRECTION_DISABLE(IQCORRECTION_DISABLE))
i_up_adc_channel (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_enable (adc_enable),
.adc_iqcor_enb (adc_iqcor_enb_s),
.adc_dcfilt_enb (adc_dcfilt_enb_s),
.adc_dfmt_se (adc_dfmt_se_s),
.adc_dfmt_type (adc_dfmt_type_s),
.adc_dfmt_enable (adc_dfmt_enable_s),
.adc_dcfilt_offset (adc_dcfilt_offset_s),
.adc_dcfilt_coeff (adc_dcfilt_coeff_s),
.adc_iqcor_coeff_1 (adc_iqcor_coeff_1_s),
.adc_iqcor_coeff_2 (adc_iqcor_coeff_2_s),
.adc_pnseq_sel (adc_pnseq_sel),
.adc_data_sel (adc_data_sel_s),
.adc_pn_err (adc_pn_err_s),
.adc_pn_oos (adc_pn_oos_s),
.adc_or (1'd0),
.up_adc_pn_err (up_adc_pn_err),
.up_adc_pn_oos (up_adc_pn_oos),
.up_adc_or (up_adc_or),
.up_usr_datatype_be (),
.up_usr_datatype_signed (),
.up_usr_datatype_shift (),
.up_usr_datatype_total_bits (),
.up_usr_datatype_bits (),
.up_usr_decimation_m (),
.up_usr_decimation_n (),
.adc_usr_datatype_be (1'b0),
.adc_usr_datatype_signed (1'b1),
.adc_usr_datatype_shift (8'd0),
.adc_usr_datatype_total_bits (8'd16),
.adc_usr_datatype_bits (8'd16),
.adc_usr_decimation_m (16'd1),
.adc_usr_decimation_n (16'd1),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_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));
end
endgenerate
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,381 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001_tx #(
parameter ID = 0,
parameter CMOS_LVDS_N = 0,
parameter COMMON_BASE_ADDR = 'h10,
parameter CHANNEL_BASE_ADDR = 'h11,
parameter MODE_R1 = 1,
parameter FPGA_TECHNOLOGY = 0,
parameter FPGA_FAMILY = 0,
parameter SPEED_GRADE = 0,
parameter DEV_PACKAGE = 0,
parameter DISABLE = 0,
parameter DDS_DISABLE = 0,
parameter IQCORRECTION_DISABLE = 0,
parameter DAC_DDS_TYPE = 1,
parameter DAC_DDS_CORDIC_DW = 20,
parameter DAC_DDS_CORDIC_PHASE_DW = 18
) (
// dac interface
output dac_rst,
input dac_clk,
output dac_data_valid_A,
output [15:0] dac_data_i_A,
output [15:0] dac_data_q_A,
output dac_data_valid_B,
output [15:0] dac_data_i_B,
output [15:0] dac_data_q_B,
output dac_single_lane,
output dac_sdr_ddr_n,
output dac_r1_mode,
// master/slave
input dac_sync_in,
output dac_sync_out,
// dma interface
output dac_valid,
output dac_enable_i0,
input [ 15:0] dac_data_i0,
output dac_enable_q0,
input [ 15:0] dac_data_q0,
output dac_enable_i1,
input [ 15:0] dac_data_i1,
output dac_enable_q1,
input [ 15:0] dac_data_q1,
input dac_dunf,
// 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
);
// configuration settings
localparam CONFIG = (CMOS_LVDS_N * 128) +
(MODE_R1 * 16) +
(DDS_DISABLE * 64) +
(IQCORRECTION_DISABLE * 1);
// internal registers
reg dac_data_sync = 'd0;
reg [15:0] dac_rate_cnt = 'd0;
reg dac_valid_int = 'd0;
// internal signals
wire dac_data_sync_s;
wire [ 15:0] dac_data_iq_i0_s;
wire [ 15:0] dac_data_iq_q0_s;
wire [ 15:0] dac_data_iq_i1_s;
wire [ 15:0] dac_data_iq_q1_s;
wire dac_dds_format_s;
wire [ 15:0] dac_datarate_s;
wire [4:0] dac_num_lanes;
wire [ 4:0] up_wack_s;
wire [ 4:0] up_rack_s;
wire [ 31:0] up_rdata_s[0:4];
// master/slave
assign dac_data_sync_s = (ID == 0) ? dac_sync_out : dac_sync_in;
always @(posedge dac_clk) begin
dac_data_sync <= dac_data_sync_s;
end
// rate counters and data sync signals
always @(posedge dac_clk) begin
if (dac_rst == 1'b1) begin
dac_rate_cnt <= 16'b0;
end else begin
if ((dac_data_sync == 1'b1) || (dac_rate_cnt == 16'd0)) begin
dac_rate_cnt <= dac_datarate_s;
end else begin
dac_rate_cnt <= dac_rate_cnt - 1'b1;
end
end
end
// dma interface
assign dac_data_valid_A = dac_valid_int;
assign dac_data_valid_B = dac_valid_int;
always @(posedge dac_clk) begin
if (dac_rst == 1'b1) begin
dac_valid_int <= 1'b0;
end else begin
dac_valid_int <= (dac_rate_cnt == 16'd0) ? 1'b1 : 1'b0;
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_wack <= 'd0;
up_rack <= 'd0;
up_rdata <= 'd0;
end else begin
up_wack <= | up_wack_s;
up_rack <= | up_rack_s;
up_rdata <= up_rdata_s[0] | up_rdata_s[1] | up_rdata_s[2] |
up_rdata_s[3] | up_rdata_s[4];
end
end
// dac channel 0
axi_adrv9001_tx_channel #(
.CHANNEL_ID (0),
.COMMON_ID (CHANNEL_BASE_ADDR),
.Q_OR_I_N (0),
.DISABLE (DISABLE),
.DDS_DISABLE (DDS_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx_channel_0 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_data_in_req (dac_valid),
.dac_data_in (dac_data_i0),
.dac_data_out_req (dac_data_valid_A),
.dac_data_out (dac_data_i_A[15:0]),
.dac_data_iq_in (dac_data_iq_q0_s),
.dac_data_iq_out (dac_data_iq_i0_s),
.dac_enable (dac_enable_i0),
.dac_data_sync (dac_data_sync),
.dac_dds_format (dac_dds_format_s),
.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[0]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[0]),
.up_rack (up_rack_s[0]));
// dac channel 1
axi_adrv9001_tx_channel #(
.CHANNEL_ID (1),
.COMMON_ID (CHANNEL_BASE_ADDR),
.Q_OR_I_N (1),
.DISABLE (DISABLE),
.DDS_DISABLE (DDS_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx_channel_1 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_data_in_req (),
.dac_data_in (dac_data_q0),
.dac_data_out_req (dac_data_valid_A),
.dac_data_out (dac_data_q_A[15:0]),
.dac_data_iq_in (dac_data_iq_i0_s),
.dac_data_iq_out (dac_data_iq_q0_s),
.dac_enable (dac_enable_q0),
.dac_data_sync (dac_data_sync),
.dac_dds_format (dac_dds_format_s),
.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[1]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[1]),
.up_rack (up_rack_s[1]));
// dac channel 2 - disabled in 1R1T mode
axi_adrv9001_tx_channel #(
.CHANNEL_ID (2),
.COMMON_ID (CHANNEL_BASE_ADDR),
.Q_OR_I_N (0),
.DISABLE (MODE_R1),
.DDS_DISABLE (DDS_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx_channel_2 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_data_in_req (),
.dac_data_in (dac_data_i1),
.dac_data_out_req (dac_data_valid_B),
.dac_data_out (dac_data_i_B[15:0]),
.dac_data_iq_in (dac_data_iq_q1_s),
.dac_data_iq_out (dac_data_iq_i1_s),
.dac_enable (dac_enable_i1),
.dac_data_sync (dac_data_sync),
.dac_dds_format (dac_dds_format_s),
.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[2]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[2]),
.up_rack (up_rack_s[2]));
// dac channel 3 - disabled in 1R1T mode
axi_adrv9001_tx_channel #(
.CHANNEL_ID (3),
.COMMON_ID (CHANNEL_BASE_ADDR),
.Q_OR_I_N (1),
.DISABLE (MODE_R1),
.DDS_DISABLE (DDS_DISABLE),
.IQCORRECTION_DISABLE (IQCORRECTION_DISABLE),
.DAC_DDS_TYPE (DAC_DDS_TYPE),
.DAC_DDS_CORDIC_DW (DAC_DDS_CORDIC_DW),
.DAC_DDS_CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW))
i_tx_channel_3 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_data_in_req (),
.dac_data_in (dac_data_q0),
.dac_data_out_req (dac_data_valid_B),
.dac_data_out (dac_data_q_B[15:0]),
.dac_data_iq_in (dac_data_iq_i1_s),
.dac_data_iq_out (dac_data_iq_q1_s),
.dac_enable (dac_enable_q1),
.dac_data_sync (dac_data_sync),
.dac_dds_format (dac_dds_format_s),
.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[3]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[3]),
.up_rack (up_rack_s[3]));
// 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),
.CONFIG(CONFIG),
.CLK_EDGE_SEL(0),
.COMMON_ID(COMMON_BASE_ADDR),
.DRP_DISABLE(1),
.USERPORTS_DISABLE(1),
.GPIO_DISABLE(1))
i_up_dac_common (
.mmcm_rst (),
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_num_lanes (dac_num_lanes),
.dac_sdr_ddr_n (dac_sdr_ddr_n),
.dac_sync (dac_sync_out),
.dac_frame (),
.dac_clksel (),
.dac_par_type (),
.dac_par_enb (),
.dac_r1_mode (dac_r1_mode),
.dac_datafmt (dac_dds_format_s),
.dac_datarate (dac_datarate_s),
.dac_status (1'b1),
.dac_status_unf (dac_dunf),
.dac_clk_ratio (32'd2),
.up_dac_ce (),
.up_pps_rcounter(32'h0),
.up_pps_status(1'b0),
.up_pps_irq_mask(),
.up_drp_sel (),
.up_drp_wr (),
.up_drp_addr (),
.up_drp_wdata (),
.up_drp_rdata (32'd0),
.up_drp_ready (1'd0),
.up_drp_locked (1'd1),
.up_usr_chanmax (),
.dac_usr_chanmax (8'd3),
.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[4]),
.up_rreq (up_rreq),
.up_raddr (up_raddr),
.up_rdata (up_rdata_s[4]),
.up_rack (up_rack_s[4]));
assign dac_single_lane = dac_num_lanes[0];
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,251 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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_adrv9001_tx_channel #(
parameter COMMON_ID = 6'h11,
parameter CHANNEL_ID = 32'h0,
parameter Q_OR_I_N = 0,
parameter DISABLE = 0,
parameter DDS_DISABLE = 0,
parameter IQCORRECTION_DISABLE = 0,
parameter DAC_DDS_TYPE = 1,
parameter DAC_DDS_CORDIC_DW = 20,
parameter DAC_DDS_CORDIC_PHASE_DW = 18
) (
// dac interface
input dac_clk,
input dac_rst,
output dac_data_in_req,
input [15:0] dac_data_in,
input dac_data_out_req,
output [15:0] dac_data_out,
input [15:0] dac_data_iq_in,
output reg [15:0] dac_data_iq_out,
// processor interface
output reg dac_enable = 1'b0,
input dac_data_sync,
input dac_dds_format,
// 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 registers
reg [15:0] dac_pat_data = 'd0;
reg [15:0] full_ramp_counter = 'd0;
// internal signals
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;
wire [ 3:0] dac_data_sel_s;
wire dac_iqcor_enb_s;
wire [15:0] dac_iqcor_coeff_1_s;
wire [15:0] dac_iqcor_coeff_2_s;
wire [15:0] pn7_data;
wire [15:0] pn15_data;
// dac iq correction
generate
if (DISABLE == 1 || IQCORRECTION_DISABLE == 1) begin
assign dac_data_out = dac_data_iq_out;
assign dac_data_in_req = dac_data_out_req;
end else begin
ad_iqcor #(.Q_OR_I_N (Q_OR_I_N)) i_ad_iqcor_0 (
.clk (dac_clk),
.valid (dac_data_out_req),
.data_in (dac_data_iq_out[15:0]),
.data_iq (dac_data_iq_in[15:0]),
.valid_out (dac_data_in_req),
.data_out (dac_data_out[15:0]),
.iqcor_enable (dac_iqcor_enb_s),
.iqcor_coeff_1 (dac_iqcor_coeff_1_s),
.iqcor_coeff_2 (dac_iqcor_coeff_2_s));
end
if (DISABLE == 1) begin
assign up_wack = 1'b0;
assign up_rdata = 32'b0;
assign up_rack = 1'b0;
end else begin
// PN7 x^7 + x^6 + 1
ad_pngen #(
.POL_MASK ((1<<7) | (1<<6)),
.POL_W (7),
.DW (16)
) PN7_gen (
.clk (dac_clk),
.reset (dac_rst),
.clk_en (dac_data_in_req),
.pn_init (1'b0),
.pn_data_out (pn7_data)
);
// PN15 x^15 + x^14 + 1
ad_pngen #(
.POL_MASK ((1<<15) | (1<<14)),
.POL_W (15),
.DW (16)
) PN15_gen (
.clk (dac_clk),
.reset (dac_rst),
.clk_en (dac_data_in_req),
.pn_init (1'b0),
.pn_data_out (pn15_data)
);
// full ramp generator
always @(posedge dac_clk) begin
if (dac_data_sync) begin
full_ramp_counter <= 'h0;
end else if (dac_data_in_req) begin
full_ramp_counter <= full_ramp_counter + 16'd1;
end
end
// dac mux
always @(posedge dac_clk) begin
dac_enable <= (dac_data_sel_s == 4'h2) ? 1'b1 : 1'b0;
case (dac_data_sel_s)
4'hB: dac_data_iq_out <= full_ramp_counter; // full ramp
4'hA: dac_data_iq_out <= {4{full_ramp_counter[3:0]}}; // nibble ramp
4'h7: dac_data_iq_out <= pn15_data;
4'h6: dac_data_iq_out <= pn7_data;
4'h3: dac_data_iq_out <= 16'd0;
4'h2: dac_data_iq_out <= dac_data_in;
4'h1: dac_data_iq_out <= dac_pat_data_1_s;
default: dac_data_iq_out <= dac_dds_data_s;
endcase
end
// dds
ad_dds #(
.DISABLE (DDS_DISABLE),
.DDS_DW (16),
.PHASE_DW (16),
.DDS_TYPE (DAC_DDS_TYPE),
.CORDIC_DW (DAC_DDS_CORDIC_DW),
.CORDIC_PHASE_DW (DAC_DDS_CORDIC_PHASE_DW),
.CLK_RATIO (1))
i_dds (
.clk (dac_clk),
.dac_dds_format (dac_dds_format),
.dac_data_sync (dac_data_sync),
.dac_valid (dac_data_out_req),
.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 #(
.COMMON_ID(COMMON_ID),
.CHANNEL_ID (CHANNEL_ID),
.DDS_DISABLE(DDS_DISABLE),
.USERPORTS_DISABLE(1),
.IQCORRECTION_DISABLE(IQCORRECTION_DISABLE))
i_up_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_iq_mode (),
.dac_iqcor_enb (dac_iqcor_enb_s),
.dac_iqcor_coeff_1 (dac_iqcor_coeff_1_s),
.dac_iqcor_coeff_2 (dac_iqcor_coeff_2_s),
.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'b0),
.dac_usr_datatype_signed (1'b1),
.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));
end
endgenerate
endmodule

View File

@ -0,0 +1,150 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_rx #(
parameter CMOS_LVDS_N = 0,
parameter FPGA_TECHNOLOGY = 0,
parameter NUM_LANES = 3,
parameter DRP_WIDTH = 5,
parameter IODELAY_CTRL = 0,
parameter IO_DELAY_GROUP = "dev_if_delay_group"
) (
// device interface
input rx_dclk_in_n_NC,
input rx_dclk_in_p_dclk_in,
input rx_idata_in_n_idata0,
input rx_idata_in_p_idata1,
input rx_qdata_in_n_qdata2,
input rx_qdata_in_p_qdata3,
input rx_strobe_in_n_NC,
input rx_strobe_in_p_strobe_in,
// internal reset and clocks
input adc_rst,
output adc_clk,
output adc_clk_div,
output [7:0] adc_data_0,
output [7:0] adc_data_1,
output [7:0] adc_data_2,
output [7:0] adc_data_3,
output [7:0] adc_data_strobe,
output adc_valid,
// delay interface (for IDELAY macros)
input up_clk,
input [NUM_LANES-1:0] up_adc_dld,
input [DRP_WIDTH*NUM_LANES-1:0] up_adc_dwdata,
output [DRP_WIDTH*NUM_LANES-1:0] up_adc_drdata,
input delay_clk,
input delay_rst,
output delay_locked,
input mssi_sync,
output ssi_sync_out,
input ssi_sync_in,
output ssi_rst
);
reg [3:0] valid_gen = 4'b0001;
wire [4:0] gpio_in;
wire [39:0] deser_out;
periphery_clk_buf rx_clk_buf(
.inclk (rx_dclk_in_p_dclk_in),
.outclk (rx_clk)
);
assign gpio_in = {rx_strobe_in_p_strobe_in,
rx_qdata_in_p_qdata3,
rx_qdata_in_n_qdata2,
rx_idata_in_p_idata1,
rx_idata_in_n_idata0};
assign {adc_data_strobe,
adc_data_3,
adc_data_2,
adc_data_1,
adc_data_0} = deser_out;
genvar i;
generate
for (i = 0; i <= 4; i = i + 1) begin: g_ddr_i
reg [7:0] shift_reg = 8'b0;
wire [1:0] gpio_out;
// DDR input
adrv9001_gpio_in gpio_rx_in (
.ck (rx_clk),
.dout (gpio_out),
.pad_in (gpio_in[i])
);
// Temporal ordering:
// MSB - oldest received bit;
// LSB - newest received bit;
always @(posedge rx_clk) begin
shift_reg <= {shift_reg[5:0],gpio_out[0],gpio_out[1]};
end
assign deser_out[i*8+:8] = shift_reg;
end
endgenerate
always @(posedge rx_clk) begin
if (adc_rst) begin
valid_gen <= 4'b0001;
end else begin
valid_gen <= {valid_gen[2:0],valid_gen[3]};
end
end
assign adc_valid = valid_gen[3];
// No clock divider, qualifier used instead
assign adc_clk_div = rx_clk;
assign adc_clk = rx_clk;
// Drive unused signals
assign delay_locked = 'b0;
assign up_adc_drdata = 'b0;
assign ssi_sync_out = 'b0;
assign ssi_rst = 'b0;
endmodule

View File

@ -0,0 +1,135 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2020 (c) 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:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// 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 adrv9001_tx #(
parameter CMOS_LVDS_N = 0,
parameter NUM_LANES = 4,
parameter FPGA_TECHNOLOGY = 0,
parameter USE_RX_CLK_FOR_TX = 0
) (
input ref_clk,
input up_clk,
input mssi_sync,
input tx_output_enable,
// physical interface (transmit)
output tx_dclk_out_n_NC,
output tx_dclk_out_p_dclk_out,
input tx_dclk_in_n_NC,
input tx_dclk_in_p_dclk_in,
output tx_idata_out_n_idata0,
output tx_idata_out_p_idata1,
output tx_qdata_out_n_qdata2,
output tx_qdata_out_p_qdata3,
output tx_strobe_out_n_NC,
output tx_strobe_out_p_strobe_out,
input rx_clk_div,
input rx_clk,
input rx_ssi_rst,
// internal resets and clocks
input dac_rst,
output dac_clk_div,
input [7:0] dac_data_0,
input [7:0] dac_data_1,
input [7:0] dac_data_2,
input [7:0] dac_data_3,
input [7:0] dac_data_strb,
input [7:0] dac_data_clk,
input dac_data_valid
);
wire [6*8-1:0] serdes_in;
wire [5:0] gpio_out;
periphery_clk_buf tx_clk_buf(
.inclk (tx_dclk_in_p_dclk_in),
.outclk (tx_clk)
);
assign serdes_in = {dac_data_clk,
dac_data_strb,
dac_data_3,
dac_data_2,
dac_data_1,
dac_data_0};
assign {tx_dclk_out_p_dclk_out,
tx_strobe_out_p_strobe_out,
tx_qdata_out_p_qdata3,
tx_qdata_out_n_qdata2,
tx_idata_out_p_idata1,
tx_idata_out_n_idata0} = gpio_out;
genvar i;
generate
for (i = 0; i <= 5; i = i + 1) begin: g_ddr_o
reg [7:0] shift_reg = 8'b0;
wire [1:0] gpio_in;
// DDR output
adrv9001_gpio_out gpio_tx_out (
.ck(tx_clk),
.din(gpio_in),
.pad_out(gpio_out[i])
);
always @(posedge tx_clk) begin
if (dac_data_valid) begin
shift_reg <= serdes_in[i*8+:8];
end else begin
shift_reg <= {shift_reg[5:0],2'b0};
end
end
// Order of transmission:
// gpio_in[0] - first
// gpio_in[1] - last
assign gpio_in = {shift_reg[6],shift_reg[7]};
end
endgenerate
// No clock divider, qualifier used instead
assign dac_clk_div = tx_clk;
assign dac_clk = tx_clk;
endmodule