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
parent
8e243b6d32
commit
64f6762a05
|
@ -33,6 +33,7 @@ clean:
|
|||
$(MAKE) -C axi_ad9963 clean
|
||||
$(MAKE) -C axi_adc_decimate clean
|
||||
$(MAKE) -C axi_adc_trigger clean
|
||||
$(MAKE) -C axi_adrv9001 clean
|
||||
$(MAKE) -C axi_adrv9009 clean
|
||||
$(MAKE) -C axi_clkgen clean
|
||||
$(MAKE) -C axi_dac_interpolate clean
|
||||
|
@ -146,6 +147,7 @@ lib:
|
|||
$(MAKE) -C axi_ad9963
|
||||
$(MAKE) -C axi_adc_decimate
|
||||
$(MAKE) -C axi_adc_trigger
|
||||
$(MAKE) -C axi_adrv9001
|
||||
$(MAKE) -C axi_adrv9009
|
||||
$(MAKE) -C axi_clkgen
|
||||
$(MAKE) -C axi_dac_interpolate
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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*]
|
|
@ -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]
|
|
@ -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
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
|
@ -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
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
|
@ -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
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
|
@ -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
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue