initial commit, add dds_par module
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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 ad_data_clk #(
|
||||
|
||||
parameter SINGLE_ENDED = 0
|
||||
) (
|
||||
input rst,
|
||||
output locked,
|
||||
|
||||
input clk_in_p,
|
||||
input clk_in_n,
|
||||
output clk
|
||||
);
|
||||
|
||||
// internal signals
|
||||
|
||||
wire clk_ibuf_s;
|
||||
|
||||
// defaults
|
||||
|
||||
assign locked = 1'b1;
|
||||
|
||||
// instantiations
|
||||
|
||||
generate
|
||||
if (SINGLE_ENDED == 1) begin
|
||||
IBUFG i_rx_clk_ibuf (
|
||||
.I (clk_in_p),
|
||||
.O (clk_ibuf_s));
|
||||
end else begin
|
||||
IBUFGDS i_rx_clk_ibuf (
|
||||
.I (clk_in_p),
|
||||
.IB (clk_in_n),
|
||||
.O (clk_ibuf_s));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
BUFG i_clk_gbuf (
|
||||
.I (clk_ibuf_s),
|
||||
.O (clk));
|
||||
|
||||
endmodule
|
||||
Executable
+284
@@ -0,0 +1,284 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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 ad_data_in #(
|
||||
parameter SINGLE_ENDED = 0,
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter DDR_SDR_N = 1,
|
||||
parameter IDDR_CLK_EDGE ="SAME_EDGE",
|
||||
// for 7 series devices
|
||||
parameter IDELAY_TYPE = "VAR_LOAD",
|
||||
// for ultrascale devices
|
||||
parameter DELAY_FORMAT = "COUNT",
|
||||
parameter US_DELAY_TYPE = "VAR_LOAD",
|
||||
// for all
|
||||
parameter IODELAY_ENABLE = 1,
|
||||
parameter IODELAY_CTRL = 0,
|
||||
parameter IODELAY_GROUP = "dev_if_delay_group",
|
||||
parameter REFCLK_FREQUENCY = 200
|
||||
) (
|
||||
|
||||
// data interface
|
||||
|
||||
input rx_clk,
|
||||
input rx_data_in_p,
|
||||
input rx_data_in_n,
|
||||
output rx_data_p,
|
||||
output rx_data_n,
|
||||
|
||||
// delay-data interface
|
||||
|
||||
input up_clk,
|
||||
input up_dld,
|
||||
input [ 4:0] up_dwdata,
|
||||
output [ 4:0] up_drdata,
|
||||
|
||||
// delay-cntrl interface
|
||||
|
||||
input delay_clk,
|
||||
input delay_rst,
|
||||
output delay_locked
|
||||
);
|
||||
|
||||
// internal parameters
|
||||
|
||||
localparam NONE = -1;
|
||||
localparam SEVEN_SERIES = 1;
|
||||
localparam ULTRASCALE = 2;
|
||||
localparam ULTRASCALE_PLUS = 3;
|
||||
|
||||
// do not instantiate an IDELAYCTRL if no IDELAY is instantiated
|
||||
localparam IODELAY_CTRL_ENABLED = (IODELAY_ENABLE & IODELAY_CTRL);
|
||||
localparam IODELAY_CTRL_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE" :
|
||||
(FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";
|
||||
|
||||
localparam IODELAY_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS" :
|
||||
(FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";
|
||||
|
||||
/*
|
||||
* For 7 series, IDELAYCTRL is enabled ALWAYS, meaning in the following situations:
|
||||
* when IDELAY_TYPE = FIXED
|
||||
* when IDELAY_TYPE = VARIABLE
|
||||
* when IDELAY_TYPE = VAR_LOAD
|
||||
**/
|
||||
|
||||
/*
|
||||
* For UltraScale/UltraScale+:
|
||||
* when DELAY_FORMAT = TIME:
|
||||
* IDELAYCTRL must be used
|
||||
* REFCLK_FREQUENCY must reflect the clock frequency of REF_CLK applied to
|
||||
the IDELAYCTRL component
|
||||
* DELAY_VALUE attribute represents an amount in ps
|
||||
* The total delay through the IDELAYE3 is the align delay + DELAY_VALUE
|
||||
* EN_VTC depends on DELAY_TYPE attribute:
|
||||
* when FIXED mode: EN_VTC = 1
|
||||
* It must be actively manipulated when the delay line is used in
|
||||
VARIABLE or VAR_LOAD mode
|
||||
(this section is NOT IMPLEMENTED! More details in UG571, DELAY_TYPE = VAR_LOAD mode and VARIABLE mode)
|
||||
|
||||
* when DELAY_FORMAT = COUNT:
|
||||
* DO NOT use an IDELAYCTRL
|
||||
* REFCLK_FREQUENCY must be set to default frequency (300MHz)
|
||||
* Delay line represents an amount of taps (512 taps available)
|
||||
* CNTVALUEIN/OUT[8:0] values represent the amount of taps the delay line
|
||||
is set to
|
||||
* EN_VTC = 0
|
||||
**/
|
||||
|
||||
// internal signals
|
||||
|
||||
wire rx_data_ibuf_s;
|
||||
wire rx_data_idelay_s;
|
||||
wire [ 8:0] up_drdata_s;
|
||||
|
||||
// internal registers
|
||||
|
||||
reg en_vtc;
|
||||
|
||||
// determine EN_VTC (VAR_LOAD and VARIABLE modes not implemented as in UG571)
|
||||
|
||||
always @(posedge rx_clk) begin
|
||||
if (DELAY_FORMAT == "TIME") begin
|
||||
if (US_DELAY_TYPE == "FIXED") begin
|
||||
en_vtc <= 1'b1;
|
||||
end else begin // "VAR_LOAD", "VARIABLE"
|
||||
en_vtc <= ~up_dld;
|
||||
end
|
||||
end else begin // "COUNT"
|
||||
en_vtc <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// delay controller
|
||||
|
||||
generate
|
||||
if (IODELAY_CTRL_ENABLED == 0) begin
|
||||
assign delay_locked = 1'b1;
|
||||
end else begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYCTRL #(
|
||||
.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)
|
||||
) i_delay_ctrl (
|
||||
.RST (delay_rst),
|
||||
.REFCLK (delay_clk),
|
||||
.RDY (delay_locked));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// receive data interface, ibuf -> idelay -> iddr(if enabled)
|
||||
|
||||
// ibuf
|
||||
|
||||
generate
|
||||
if (SINGLE_ENDED == 1) begin
|
||||
IBUF i_rx_data_ibuf (
|
||||
.I (rx_data_in_p),
|
||||
.O (rx_data_ibuf_s));
|
||||
end else begin
|
||||
IBUFDS i_rx_data_ibuf (
|
||||
.I (rx_data_in_p),
|
||||
.IB (rx_data_in_n),
|
||||
.O (rx_data_ibuf_s));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// bypass IDELAY
|
||||
|
||||
generate
|
||||
if (IODELAY_ENABLE == 0) begin
|
||||
assign rx_data_idelay_s = rx_data_ibuf_s;
|
||||
assign up_drdata = 5'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// idelay
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES && IODELAY_ENABLE == 1) begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYE2 #(
|
||||
.CINVCTRL_SEL ("FALSE"),
|
||||
.DELAY_SRC ("IDATAIN"),
|
||||
.HIGH_PERFORMANCE_MODE ("FALSE"),
|
||||
.IDELAY_TYPE (IDELAY_TYPE),
|
||||
.IDELAY_VALUE (0),
|
||||
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
|
||||
.PIPE_SEL ("FALSE"),
|
||||
.SIGNAL_PATTERN ("DATA")
|
||||
) i_rx_data_idelay (
|
||||
.CE (1'b0),
|
||||
.INC (1'b0),
|
||||
.DATAIN (1'b0),
|
||||
.LDPIPEEN (1'b0),
|
||||
.CINVCTRL (1'b0),
|
||||
.REGRST (1'b0),
|
||||
.C (up_clk),
|
||||
.IDATAIN (rx_data_ibuf_s),
|
||||
.DATAOUT (rx_data_idelay_s),
|
||||
.LD (up_dld),
|
||||
.CNTVALUEIN (up_dwdata),
|
||||
.CNTVALUEOUT (up_drdata));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if ((FPGA_TECHNOLOGY == ULTRASCALE || FPGA_TECHNOLOGY == ULTRASCALE_PLUS)
|
||||
&& (IODELAY_ENABLE == 1)) begin
|
||||
|
||||
assign up_drdata = up_drdata_s[8:4];
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYE3 #(
|
||||
.SIM_DEVICE (IODELAY_SIM_DEVICE),
|
||||
.DELAY_SRC ("IDATAIN"),
|
||||
.DELAY_TYPE (US_DELAY_TYPE),
|
||||
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
|
||||
.DELAY_FORMAT (DELAY_FORMAT)
|
||||
) i_rx_data_idelay (
|
||||
.CASC_RETURN (1'b0),
|
||||
.CASC_IN (1'b0),
|
||||
.CASC_OUT (),
|
||||
.CE (1'b0),
|
||||
.CLK (up_clk),
|
||||
.INC (1'b0),
|
||||
.LOAD (up_dld),
|
||||
.CNTVALUEIN ({up_dwdata, 4'd0}),
|
||||
.CNTVALUEOUT (up_drdata_s),
|
||||
.DATAIN (1'b0),
|
||||
.IDATAIN (rx_data_ibuf_s),
|
||||
.DATAOUT (rx_data_idelay_s),
|
||||
.RST (1'b0),
|
||||
.EN_VTC (en_vtc));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// DDR or SDR
|
||||
|
||||
generate
|
||||
if (DDR_SDR_N == 1'b1) begin
|
||||
// iddr
|
||||
if (FPGA_TECHNOLOGY == ULTRASCALE || FPGA_TECHNOLOGY == ULTRASCALE_PLUS) begin
|
||||
IDDRE1 #(
|
||||
.DDR_CLK_EDGE (IDDR_CLK_EDGE)
|
||||
) i_rx_data_iddr (
|
||||
.R (1'b0),
|
||||
.C (rx_clk),
|
||||
.CB (~rx_clk),
|
||||
.D (rx_data_idelay_s),
|
||||
.Q1 (rx_data_p),
|
||||
.Q2 (rx_data_n));
|
||||
end
|
||||
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
|
||||
IDDR #(
|
||||
.DDR_CLK_EDGE (IDDR_CLK_EDGE)
|
||||
) i_rx_data_iddr (
|
||||
.CE (1'b1),
|
||||
.R (1'b0),
|
||||
.S (1'b0),
|
||||
.C (rx_clk),
|
||||
.D (rx_data_idelay_s),
|
||||
.Q1 (rx_data_p),
|
||||
.Q2 (rx_data_n));
|
||||
end
|
||||
// sdr
|
||||
end else begin
|
||||
assign rx_data_p = rx_data_idelay_s;
|
||||
assign rx_data_n = 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
Executable
+278
@@ -0,0 +1,278 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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 ad_data_out #(
|
||||
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter SINGLE_ENDED = 0,
|
||||
parameter IDDR_CLK_EDGE ="SAME_EDGE",
|
||||
// for 7 series devices
|
||||
parameter ODELAY_TYPE = "VAR_LOAD",
|
||||
// for ultrascale devices
|
||||
parameter DELAY_FORMAT = "COUNT",
|
||||
parameter US_DELAY_TYPE = "VAR_LOAD",
|
||||
// for all
|
||||
parameter IODELAY_ENABLE = 0,
|
||||
parameter IODELAY_CTRL = 0,
|
||||
parameter IODELAY_GROUP = "dev_if_delay_group",
|
||||
parameter REFCLK_FREQUENCY = 200
|
||||
) (
|
||||
|
||||
// data interface
|
||||
|
||||
input tx_clk,
|
||||
input tx_data_p,
|
||||
input tx_data_n,
|
||||
output tx_data_out_p,
|
||||
output tx_data_out_n,
|
||||
|
||||
// delay-data interface
|
||||
|
||||
input up_clk,
|
||||
input up_dld,
|
||||
input [ 4:0] up_dwdata,
|
||||
output [ 4:0] up_drdata,
|
||||
|
||||
// delay-cntrl interface
|
||||
|
||||
input delay_clk,
|
||||
input delay_rst,
|
||||
output delay_locked
|
||||
);
|
||||
|
||||
localparam NONE = -1;
|
||||
localparam SEVEN_SERIES = 1;
|
||||
localparam ULTRASCALE = 2;
|
||||
localparam ULTRASCALE_PLUS = 3;
|
||||
|
||||
// do not instantiate an IDELAYCTRL if no ODELAY is instantiated
|
||||
localparam IODELAY_CTRL_ENABLED = (IODELAY_ENABLE & IODELAY_CTRL);
|
||||
localparam IODELAY_CTRL_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE" :
|
||||
(FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";
|
||||
|
||||
localparam IODELAY_SIM_DEVICE = (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) ? "ULTRASCALE_PLUS" :
|
||||
(FPGA_TECHNOLOGY == ULTRASCALE) ? "ULTRASCALE" : "7SERIES";
|
||||
|
||||
/*
|
||||
* For 7 series, IDELAYCTRL is enabled ALWAYS, meaning in the following situations:
|
||||
* when ODELAY_TYPE = FIXED
|
||||
* when ODELAY_TYPE = VARIABLE
|
||||
* when ODELAY_TYPE = VAR_LOAD
|
||||
**/
|
||||
|
||||
/*
|
||||
* For UltraScale/UltraScale+:
|
||||
* when DELAY_FORMAT = TIME:
|
||||
* IDELAYCTRL must be used
|
||||
* REFCLK_FREQUENCY must reflect the clock frequency of REF_CLK applied to
|
||||
the IDELAYCTRL component
|
||||
* DELAY_VALUE attribute represents an amount in ps
|
||||
* The total delay through the IDELAYE3 is the align delay + DELAY_VALUE
|
||||
* EN_VTC depends on DELAY_TYPE attribute:
|
||||
* when FIXED mode: EN_VTC = 1
|
||||
* It must be actively manipulated when the delay line is used in
|
||||
VARIABLE or VAR_LOAD mode
|
||||
(this section is NOT IMPLEMENTED! More details in UG571, DELAY_TYPE = VAR_LOAD mode and VARIABLE mode)
|
||||
|
||||
* when DELAY_FORMAT = COUNT:
|
||||
* DO NOT use an IDELAYCTRL
|
||||
* REFCLK_FREQUENCY must be set to default frequency (300MHz)
|
||||
* Delay line represents an amount of taps (512 taps available)
|
||||
* CNTVALUEIN/OUT[8:0] values represent the amount of taps the delay line
|
||||
is set to
|
||||
* EN_VTC = 0
|
||||
**/
|
||||
|
||||
// internal signals
|
||||
|
||||
wire tx_data_oddr_s;
|
||||
wire tx_data_odelay_s;
|
||||
|
||||
// internal registers
|
||||
|
||||
reg en_vtc;
|
||||
|
||||
// determine EN_VTC (VAR_LOAD and VARIABLE modes not implemented as in UG571)
|
||||
|
||||
always @(posedge tx_clk) begin
|
||||
if (DELAY_FORMAT == "TIME") begin
|
||||
if (US_DELAY_TYPE == "FIXED") begin
|
||||
en_vtc <= 1'b1;
|
||||
end else begin // "VAR_LOAD", "VARIABLE"
|
||||
en_vtc <= ~up_dld;
|
||||
end
|
||||
end else begin // "COUNT"
|
||||
en_vtc <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// delay controller
|
||||
|
||||
generate
|
||||
if (IODELAY_CTRL_ENABLED == 0) begin
|
||||
assign delay_locked = 1'b1;
|
||||
end else begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYCTRL #(
|
||||
.SIM_DEVICE (IODELAY_CTRL_SIM_DEVICE)
|
||||
) i_delay_ctrl (
|
||||
.RST (delay_rst),
|
||||
.REFCLK (delay_clk),
|
||||
.RDY (delay_locked));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// bypass ODELAY
|
||||
|
||||
generate
|
||||
if (IODELAY_ENABLE == 0) begin
|
||||
assign tx_data_odelay_s = tx_data_oddr_s;
|
||||
assign up_drdata = 5'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// transmit data interface, oddr -> odelay -> obuf
|
||||
|
||||
// oddr
|
||||
|
||||
generate
|
||||
if ((FPGA_TECHNOLOGY == ULTRASCALE) || (FPGA_TECHNOLOGY == ULTRASCALE_PLUS)) begin
|
||||
ODDRE1 #(
|
||||
.SIM_DEVICE (IODELAY_SIM_DEVICE)
|
||||
) i_tx_data_oddr (
|
||||
.SR (1'b0),
|
||||
.C (tx_clk),
|
||||
.D1 (tx_data_n),
|
||||
.D2 (tx_data_p),
|
||||
.Q (tx_data_oddr_s));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
|
||||
ODDR #(
|
||||
.DDR_CLK_EDGE (IDDR_CLK_EDGE)
|
||||
) i_tx_data_oddr (
|
||||
.CE (1'b1),
|
||||
.R (1'b0),
|
||||
.S (1'b0),
|
||||
.C (tx_clk),
|
||||
.D1 (tx_data_n),
|
||||
.D2 (tx_data_p),
|
||||
.Q (tx_data_oddr_s));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// odelay
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES && IODELAY_ENABLE == 1) begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
ODELAYE2 #(
|
||||
.CINVCTRL_SEL ("FALSE"),
|
||||
.DELAY_SRC ("ODATAIN"),
|
||||
.HIGH_PERFORMANCE_MODE ("FALSE"),
|
||||
.ODELAY_TYPE (ODELAY_TYPE),
|
||||
.ODELAY_VALUE (0),
|
||||
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
|
||||
.PIPE_SEL ("FALSE"),
|
||||
.SIGNAL_PATTERN ("DATA")
|
||||
) i_tx_data_odelay (
|
||||
.CE (1'b0),
|
||||
.CLKIN (1'b0),
|
||||
.INC (1'b0),
|
||||
.LDPIPEEN (1'b0),
|
||||
.CINVCTRL (1'b0),
|
||||
.REGRST (1'b0),
|
||||
.C (up_clk),
|
||||
.ODATAIN (tx_data_oddr_s),
|
||||
.DATAOUT (tx_data_odelay_s),
|
||||
.LD (up_dld),
|
||||
.CNTVALUEIN (up_dwdata),
|
||||
.CNTVALUEOUT (up_drdata));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if ((FPGA_TECHNOLOGY == ULTRASCALE_PLUS || FPGA_TECHNOLOGY == ULTRASCALE)
|
||||
&& (IODELAY_ENABLE == 1)) begin
|
||||
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
ODELAYE3 #(
|
||||
.CASCADE ("NONE"),
|
||||
.DELAY_FORMAT (DELAY_FORMAT),
|
||||
.DELAY_TYPE (US_DELAY_TYPE),
|
||||
.DELAY_VALUE (0),
|
||||
.IS_CLK_INVERTED (1'b0),
|
||||
.IS_RST_INVERTED (1'b0),
|
||||
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
|
||||
.SIM_DEVICE (IODELAY_SIM_DEVICE),
|
||||
.UPDATE_MODE ("ASYNC")
|
||||
) i_tx_data_odelay (
|
||||
.CASC_RETURN (1'b0),
|
||||
.CASC_IN (1'b0),
|
||||
.CASC_OUT (),
|
||||
.CE (1'b0),
|
||||
.CLK (up_clk),
|
||||
.INC (1'b0),
|
||||
.LOAD (up_dld),
|
||||
.CNTVALUEIN (up_dwdata),
|
||||
.CNTVALUEOUT (up_drdata),
|
||||
.ODATAIN (tx_data_oddr_s),
|
||||
.DATAOUT (tx_data_odelay_s),
|
||||
.RST (1'b0),
|
||||
.EN_VTC (en_vtc));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// obuf
|
||||
|
||||
generate
|
||||
if (SINGLE_ENDED == 1) begin
|
||||
assign tx_data_out_n = 1'b0;
|
||||
OBUF i_tx_data_obuf (
|
||||
.I (tx_data_odelay_s),
|
||||
.O (tx_data_out_p));
|
||||
end else begin
|
||||
OBUFDS i_tx_data_obuf (
|
||||
.I (tx_data_odelay_s),
|
||||
.O (tx_data_out_p),
|
||||
.OB (tx_data_out_n));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,196 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// dc filter- y(n) = c*x(n) + (1-c)*y(n-1)
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module ad_dcfilter #(
|
||||
|
||||
// data path disable
|
||||
|
||||
parameter DISABLE = 0
|
||||
) (
|
||||
|
||||
// data interface
|
||||
|
||||
input clk,
|
||||
input valid,
|
||||
input [15:0] data,
|
||||
output valid_out,
|
||||
output [15:0] data_out,
|
||||
|
||||
// control interface
|
||||
|
||||
input dcfilt_enb,
|
||||
input [15:0] dcfilt_coeff,
|
||||
input [15:0] dcfilt_offset
|
||||
);
|
||||
|
||||
// internal registers
|
||||
|
||||
reg [15:0] dcfilt_coeff_d = 'd0;
|
||||
reg [47:0] dc_offset = 'd0;
|
||||
reg [47:0] dc_offset_d = 'd0;
|
||||
reg valid_d = 'd0;
|
||||
reg [15:0] data_d = 'd0;
|
||||
reg valid_2d = 'd0;
|
||||
reg [15:0] data_2d = 'd0;
|
||||
reg [15:0] data_dcfilt = 'd0;
|
||||
reg valid_int = 'd0;
|
||||
reg [15:0] data_int = 'd0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [47:0] dc_offset_s;
|
||||
|
||||
// data-path disable
|
||||
|
||||
generate
|
||||
if (DISABLE == 1) begin
|
||||
assign valid_out = valid;
|
||||
assign data_out = data;
|
||||
end else begin
|
||||
assign valid_out = valid_int;
|
||||
assign data_out = data_int;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// dcfilt_coeff is flopped so to remove warnings from vivado
|
||||
|
||||
always @(posedge clk) begin
|
||||
dcfilt_coeff_d <= dcfilt_coeff;
|
||||
end
|
||||
|
||||
// removing dc offset
|
||||
|
||||
always @(posedge clk) begin
|
||||
dc_offset <= dc_offset_s;
|
||||
dc_offset_d <= dc_offset;
|
||||
valid_d <= valid;
|
||||
if (valid == 1'b1) begin
|
||||
data_d <= data + dcfilt_offset;
|
||||
end
|
||||
valid_2d <= valid_d;
|
||||
data_2d <= data_d;
|
||||
data_dcfilt <= data_d - dc_offset[32:17];
|
||||
if (dcfilt_enb == 1'b1) begin
|
||||
valid_int <= valid_2d;
|
||||
data_int <= data_dcfilt;
|
||||
end else begin
|
||||
valid_int <= valid_2d;
|
||||
data_int <= data_2d;
|
||||
end
|
||||
end
|
||||
|
||||
// dsp slice instance ((D-A)*B)+C
|
||||
|
||||
DSP48E1 #(
|
||||
.ACASCREG (1),
|
||||
.ADREG (1),
|
||||
.ALUMODEREG (0),
|
||||
.AREG (1),
|
||||
.AUTORESET_PATDET ("NO_RESET"),
|
||||
.A_INPUT ("DIRECT"),
|
||||
.BCASCREG (1),
|
||||
.BREG (1),
|
||||
.B_INPUT ("DIRECT"),
|
||||
.CARRYINREG (0),
|
||||
.CARRYINSELREG (0),
|
||||
.CREG (1),
|
||||
.DREG (0),
|
||||
.INMODEREG (0),
|
||||
.MASK (48'h3fffffffffff),
|
||||
.MREG (1),
|
||||
.OPMODEREG (0),
|
||||
.PATTERN (48'h000000000000),
|
||||
.PREG (1),
|
||||
.SEL_MASK ("MASK"),
|
||||
.SEL_PATTERN ("PATTERN"),
|
||||
.USE_DPORT ("TRUE"),
|
||||
.USE_MULT ("MULTIPLY"),
|
||||
.USE_PATTERN_DETECT ("NO_PATDET"),
|
||||
.USE_SIMD ("ONE48")
|
||||
) i_dsp48e1 (
|
||||
.CLK (clk),
|
||||
.A ({{14{dc_offset_s[32]}}, dc_offset_s[32:17]}),
|
||||
.B ({{2{dcfilt_coeff_d[15]}}, dcfilt_coeff_d}),
|
||||
.C (dc_offset_d),
|
||||
.D ({{9{data_d[15]}}, data_d}),
|
||||
.MULTSIGNIN (1'd0),
|
||||
.CARRYIN (1'd0),
|
||||
.CARRYCASCIN (1'd0),
|
||||
.ACIN (30'd0),
|
||||
.BCIN (18'd0),
|
||||
.PCIN (48'd0),
|
||||
.P (dc_offset_s),
|
||||
.MULTSIGNOUT (),
|
||||
.CARRYOUT (),
|
||||
.CARRYCASCOUT (),
|
||||
.ACOUT (),
|
||||
.BCOUT (),
|
||||
.PCOUT (),
|
||||
.ALUMODE (4'd0),
|
||||
.CARRYINSEL (3'd0),
|
||||
.INMODE (5'b01100),
|
||||
.OPMODE (7'b0110101),
|
||||
.PATTERNBDETECT (),
|
||||
.PATTERNDETECT (),
|
||||
.OVERFLOW (),
|
||||
.UNDERFLOW (),
|
||||
.CEA1 (1'd0),
|
||||
.CEA2 (1'd1),
|
||||
.CEAD (1'd1),
|
||||
.CEALUMODE (1'd0),
|
||||
.CEB1 (1'd0),
|
||||
.CEB2 (1'd1),
|
||||
.CEC (1'd1),
|
||||
.CECARRYIN (1'd0),
|
||||
.CECTRL (1'd0),
|
||||
.CED (1'd1),
|
||||
.CEINMODE (1'd0),
|
||||
.CEM (1'd1),
|
||||
.CEP (1'd0),
|
||||
.RSTA (1'd0),
|
||||
.RSTALLCARRYIN (1'd0),
|
||||
.RSTALUMODE (1'd0),
|
||||
.RSTB (1'd0),
|
||||
.RSTC (1'd0),
|
||||
.RSTCTRL (1'd0),
|
||||
.RSTD (1'd0),
|
||||
.RSTINMODE (1'd0),
|
||||
.RSTM (1'd0),
|
||||
.RSTP (1'd0));
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,351 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// MMCM_OR_BUFR_N with DRP and device specific
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module ad_mmcm_drp #(
|
||||
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter MMCM_CLKIN_PERIOD = 1.667,
|
||||
parameter MMCM_CLKIN2_PERIOD = 1.667,
|
||||
parameter MMCM_VCO_DIV = 6,
|
||||
parameter MMCM_VCO_MUL = 12.000,
|
||||
parameter MMCM_CLK0_DIV = 2.000,
|
||||
parameter MMCM_CLK0_PHASE = 0.000,
|
||||
parameter MMCM_CLK1_DIV = 6,
|
||||
parameter MMCM_CLK1_PHASE = 0.000,
|
||||
parameter MMCM_CLK2_DIV = 2.000,
|
||||
parameter MMCM_CLK2_PHASE = 0.000
|
||||
) (
|
||||
|
||||
// clocks
|
||||
|
||||
input clk,
|
||||
input clk2,
|
||||
input clk_sel,
|
||||
input mmcm_rst,
|
||||
output mmcm_clk_0,
|
||||
output mmcm_clk_1,
|
||||
output mmcm_clk_2,
|
||||
|
||||
// drp interface
|
||||
|
||||
input up_clk,
|
||||
input up_rstn,
|
||||
input up_drp_sel,
|
||||
input up_drp_wr,
|
||||
input [11:0] up_drp_addr,
|
||||
input [15:0] up_drp_wdata,
|
||||
output reg [15:0] up_drp_rdata,
|
||||
output reg up_drp_ready,
|
||||
output reg up_drp_locked
|
||||
);
|
||||
|
||||
localparam SEVEN_SERIES = 1;
|
||||
localparam ULTRASCALE = 2;
|
||||
localparam ULTRASCALE_PLUS = 3;
|
||||
|
||||
// internal registers
|
||||
|
||||
reg up_drp_locked_m1 = 'd0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire bufg_fb_clk_s;
|
||||
wire mmcm_fb_clk_s;
|
||||
wire mmcm_clk_0_s;
|
||||
wire mmcm_clk_1_s;
|
||||
wire mmcm_clk_2_s;
|
||||
wire mmcm_locked_s;
|
||||
wire [15:0] up_drp_rdata_s;
|
||||
wire up_drp_ready_s;
|
||||
|
||||
// drp read and locked
|
||||
|
||||
always @(posedge up_clk) begin
|
||||
if (up_rstn == 1'b0) begin
|
||||
up_drp_rdata <= 'd0;
|
||||
up_drp_ready <= 'd0;
|
||||
up_drp_locked_m1 <= 1'd0;
|
||||
up_drp_locked <= 1'd0;
|
||||
end else begin
|
||||
up_drp_rdata <= up_drp_rdata_s;
|
||||
up_drp_ready <= up_drp_ready_s;
|
||||
up_drp_locked_m1 <= mmcm_locked_s;
|
||||
up_drp_locked <= up_drp_locked_m1;
|
||||
end
|
||||
end
|
||||
|
||||
// instantiations
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
|
||||
MMCME2_ADV #(
|
||||
.BANDWIDTH ("OPTIMIZED"),
|
||||
.CLKOUT4_CASCADE ("FALSE"),
|
||||
.COMPENSATION ("ZHOLD"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
.DIVCLK_DIVIDE (MMCM_VCO_DIV),
|
||||
.CLKFBOUT_MULT_F (MMCM_VCO_MUL),
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKFBOUT_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV),
|
||||
.CLKOUT0_PHASE (MMCM_CLK0_PHASE),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT0_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT1_DIVIDE (MMCM_CLK1_DIV),
|
||||
.CLKOUT1_PHASE (MMCM_CLK1_PHASE),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT2_DIVIDE (MMCM_CLK2_DIV),
|
||||
.CLKOUT2_PHASE (MMCM_CLK2_PHASE),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_USE_FINE_PS ("FALSE"),
|
||||
.CLKIN1_PERIOD (MMCM_CLKIN_PERIOD),
|
||||
.CLKIN2_PERIOD (MMCM_CLKIN2_PERIOD),
|
||||
.REF_JITTER1 (0.010)
|
||||
) i_mmcm (
|
||||
.CLKIN1 (clk),
|
||||
.CLKFBIN (bufg_fb_clk_s),
|
||||
.CLKFBOUT (mmcm_fb_clk_s),
|
||||
.CLKOUT0 (mmcm_clk_0_s),
|
||||
.CLKOUT1 (mmcm_clk_1_s),
|
||||
.CLKOUT2 (mmcm_clk_2_s),
|
||||
.LOCKED (mmcm_locked_s),
|
||||
.DCLK (up_clk),
|
||||
.DEN (up_drp_sel),
|
||||
.DADDR (up_drp_addr[6:0]),
|
||||
.DWE (up_drp_wr),
|
||||
.DI (up_drp_wdata),
|
||||
.DO (up_drp_rdata_s),
|
||||
.DRDY (up_drp_ready_s),
|
||||
.CLKFBOUTB (),
|
||||
.CLKOUT0B (),
|
||||
.CLKOUT1B (),
|
||||
.CLKOUT2B (),
|
||||
.CLKOUT3 (),
|
||||
.CLKOUT3B (),
|
||||
.CLKOUT4 (),
|
||||
.CLKOUT5 (),
|
||||
.CLKOUT6 (),
|
||||
.CLKIN2 (clk2),
|
||||
.CLKINSEL (clk_sel),
|
||||
.PSCLK (1'b0),
|
||||
.PSEN (1'b0),
|
||||
.PSINCDEC (1'b0),
|
||||
.PSDONE (),
|
||||
.CLKINSTOPPED (),
|
||||
.CLKFBSTOPPED (),
|
||||
.PWRDWN (1'b0),
|
||||
.RST (mmcm_rst));
|
||||
|
||||
BUFG i_fb_clk_bufg (
|
||||
.I (mmcm_fb_clk_s),
|
||||
.O (bufg_fb_clk_s));
|
||||
|
||||
BUFG i_clk_0_bufg (
|
||||
.I (mmcm_clk_0_s),
|
||||
.O (mmcm_clk_0));
|
||||
|
||||
BUFG i_clk_1_bufg (
|
||||
.I (mmcm_clk_1_s),
|
||||
.O (mmcm_clk_1));
|
||||
|
||||
BUFG i_clk_2_bufg (
|
||||
.I (mmcm_clk_2_s),
|
||||
.O (mmcm_clk_2));
|
||||
|
||||
end else if (FPGA_TECHNOLOGY == ULTRASCALE) begin
|
||||
MMCME3_ADV #(
|
||||
.BANDWIDTH ("OPTIMIZED"),
|
||||
.CLKOUT4_CASCADE ("FALSE"),
|
||||
.COMPENSATION ("AUTO"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
|
||||
.DIVCLK_DIVIDE (MMCM_VCO_DIV),
|
||||
.CLKFBOUT_MULT_F (MMCM_VCO_MUL),
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKFBOUT_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV),
|
||||
.CLKOUT0_PHASE (MMCM_CLK0_PHASE),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT0_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT1_DIVIDE (MMCM_CLK1_DIV),
|
||||
.CLKOUT1_PHASE (MMCM_CLK1_PHASE),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT2_DIVIDE (MMCM_CLK2_DIV),
|
||||
.CLKOUT2_PHASE (MMCM_CLK2_PHASE),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_USE_FINE_PS ("FALSE"),
|
||||
.CLKIN1_PERIOD (MMCM_CLKIN_PERIOD),
|
||||
.CLKIN2_PERIOD (MMCM_CLKIN2_PERIOD),
|
||||
.REF_JITTER1 (0.010)
|
||||
) i_mmcme3 (
|
||||
.CLKIN1 (clk),
|
||||
.CLKFBIN (bufg_fb_clk_s),
|
||||
.CLKFBOUT (mmcm_fb_clk_s),
|
||||
.CLKOUT0 (mmcm_clk_0_s),
|
||||
.CLKOUT1 (mmcm_clk_1_s),
|
||||
.CLKOUT2 (mmcm_clk_2_s),
|
||||
.LOCKED (mmcm_locked_s),
|
||||
.DCLK (up_clk),
|
||||
.DEN (up_drp_sel),
|
||||
.DADDR (up_drp_addr[6:0]),
|
||||
.DWE (up_drp_wr),
|
||||
.DI (up_drp_wdata),
|
||||
.DO (up_drp_rdata_s),
|
||||
.DRDY (up_drp_ready_s),
|
||||
.CLKFBOUTB (),
|
||||
.CLKOUT0B (),
|
||||
.CLKOUT1B (),
|
||||
.CLKOUT2B (),
|
||||
.CLKOUT3 (),
|
||||
.CLKOUT3B (),
|
||||
.CLKOUT4 (),
|
||||
.CLKOUT5 (),
|
||||
.CLKOUT6 (),
|
||||
.CLKIN2 (clk2),
|
||||
.CLKINSEL (clk_sel),
|
||||
.PSCLK (1'b0),
|
||||
.PSEN (1'b0),
|
||||
.PSINCDEC (1'b0),
|
||||
.PSDONE (),
|
||||
.CLKINSTOPPED (),
|
||||
.CLKFBSTOPPED (),
|
||||
.PWRDWN (1'b0),
|
||||
.CDDCREQ (1'b0),
|
||||
.CDDCDONE (),
|
||||
.RST (mmcm_rst));
|
||||
|
||||
BUFG i_fb_clk_bufg (
|
||||
.I (mmcm_fb_clk_s),
|
||||
.O (bufg_fb_clk_s));
|
||||
|
||||
BUFG i_clk_0_bufg (
|
||||
.I (mmcm_clk_0_s),
|
||||
.O (mmcm_clk_0));
|
||||
|
||||
BUFG i_clk_1_bufg (
|
||||
.I (mmcm_clk_1_s),
|
||||
.O (mmcm_clk_1));
|
||||
|
||||
BUFG i_clk_2_bufg (
|
||||
.I (mmcm_clk_2_s),
|
||||
.O (mmcm_clk_2));
|
||||
|
||||
end else if (FPGA_TECHNOLOGY == ULTRASCALE_PLUS) begin
|
||||
MMCME4_ADV #(
|
||||
.BANDWIDTH ("OPTIMIZED"),
|
||||
.CLKOUT4_CASCADE ("FALSE"),
|
||||
.COMPENSATION ("AUTO"),
|
||||
.STARTUP_WAIT ("FALSE"),
|
||||
|
||||
.DIVCLK_DIVIDE (MMCM_VCO_DIV),
|
||||
.CLKFBOUT_MULT_F (MMCM_VCO_MUL),
|
||||
.CLKFBOUT_PHASE (0.000),
|
||||
.CLKFBOUT_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT0_DIVIDE_F (MMCM_CLK0_DIV),
|
||||
.CLKOUT0_PHASE (MMCM_CLK0_PHASE),
|
||||
.CLKOUT0_DUTY_CYCLE (0.500),
|
||||
.CLKOUT0_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT1_DIVIDE (MMCM_CLK1_DIV),
|
||||
.CLKOUT1_PHASE (MMCM_CLK1_PHASE),
|
||||
.CLKOUT1_DUTY_CYCLE (0.500),
|
||||
.CLKOUT1_USE_FINE_PS ("FALSE"),
|
||||
.CLKOUT2_DIVIDE (MMCM_CLK2_DIV),
|
||||
.CLKOUT2_PHASE (MMCM_CLK2_PHASE),
|
||||
.CLKOUT2_DUTY_CYCLE (0.500),
|
||||
.CLKOUT2_USE_FINE_PS ("FALSE"),
|
||||
.CLKIN1_PERIOD (MMCM_CLKIN_PERIOD),
|
||||
.CLKIN2_PERIOD (MMCM_CLKIN2_PERIOD)
|
||||
) i_mmcme4 (
|
||||
.CLKIN1 (clk),
|
||||
.CLKFBIN (bufg_fb_clk_s),
|
||||
.CLKFBOUT (mmcm_fb_clk_s),
|
||||
.CLKOUT0 (mmcm_clk_0_s),
|
||||
.CLKOUT1 (mmcm_clk_1_s),
|
||||
.CLKOUT2 (mmcm_clk_2_s),
|
||||
.LOCKED (mmcm_locked_s),
|
||||
.DCLK (up_clk),
|
||||
.DEN (up_drp_sel),
|
||||
.DADDR (up_drp_addr[6:0]),
|
||||
.DWE (up_drp_wr),
|
||||
.DI (up_drp_wdata),
|
||||
.DO (up_drp_rdata_s),
|
||||
.DRDY (up_drp_ready_s),
|
||||
.CLKFBOUTB (),
|
||||
.CLKOUT0B (),
|
||||
.CLKOUT1B (),
|
||||
.CLKOUT2B (),
|
||||
.CLKOUT3 (),
|
||||
.CLKOUT3B (),
|
||||
.CLKOUT4 (),
|
||||
.CLKOUT5 (),
|
||||
.CLKOUT6 (),
|
||||
.CLKIN2 (clk2),
|
||||
.CLKINSEL (clk_sel),
|
||||
.PSCLK (1'b0),
|
||||
.PSEN (1'b0),
|
||||
.PSINCDEC (1'b0),
|
||||
.PSDONE (),
|
||||
.CLKINSTOPPED (),
|
||||
.CLKFBSTOPPED (),
|
||||
.PWRDWN (1'b0),
|
||||
.CDDCREQ (1'b0),
|
||||
.CDDCDONE (),
|
||||
.RST (mmcm_rst));
|
||||
|
||||
BUFG i_fb_clk_bufg (
|
||||
.I (mmcm_fb_clk_s),
|
||||
.O (bufg_fb_clk_s));
|
||||
|
||||
BUFG i_clk_0_bufg (
|
||||
.I (mmcm_clk_0_s),
|
||||
.O (mmcm_clk_0));
|
||||
|
||||
BUFG i_clk_1_bufg (
|
||||
.I (mmcm_clk_1_s),
|
||||
.O (mmcm_clk_1));
|
||||
|
||||
BUFG i_clk_2_bufg (
|
||||
.I (mmcm_clk_2_s),
|
||||
.O (mmcm_clk_2));
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,83 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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 1ps/1ps
|
||||
|
||||
module ad_mul #(
|
||||
|
||||
parameter A_DATA_WIDTH = 17,
|
||||
parameter B_DATA_WIDTH = 17,
|
||||
parameter DELAY_DATA_WIDTH = 16
|
||||
) (
|
||||
|
||||
// data_p = data_a * data_b;
|
||||
|
||||
input clk,
|
||||
input [ A_DATA_WIDTH-1:0] data_a,
|
||||
input [ B_DATA_WIDTH-1:0] data_b,
|
||||
output [A_DATA_WIDTH + B_DATA_WIDTH-1:0] data_p,
|
||||
|
||||
// delay interface
|
||||
|
||||
input [(DELAY_DATA_WIDTH-1):0] ddata_in,
|
||||
output reg [(DELAY_DATA_WIDTH-1):0] ddata_out
|
||||
);
|
||||
|
||||
// internal registers
|
||||
|
||||
reg [(DELAY_DATA_WIDTH-1):0] p1_ddata = 'd0;
|
||||
reg [(DELAY_DATA_WIDTH-1):0] p2_ddata = 'd0;
|
||||
|
||||
// a/b reg, m-reg, p-reg delay match
|
||||
|
||||
always @(posedge clk) begin
|
||||
p1_ddata <= ddata_in;
|
||||
p2_ddata <= p1_ddata;
|
||||
ddata_out <= p2_ddata;
|
||||
end
|
||||
|
||||
MULT_MACRO #(
|
||||
.LATENCY (3),
|
||||
.WIDTH_A (A_DATA_WIDTH),
|
||||
.WIDTH_B (B_DATA_WIDTH)
|
||||
) i_mult_macro (
|
||||
.CE (1'b1),
|
||||
.RST (1'b0),
|
||||
.CLK (clk),
|
||||
.A (data_a),
|
||||
.B (data_b),
|
||||
.P (data_p));
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,14 @@
|
||||
###############################################################################
|
||||
## Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
|
||||
### SPDX short identifier: ADIBSD
|
||||
###############################################################################
|
||||
|
||||
# the "-quiet" option is added for the axi_spi_engine ip where the ad_rst.v
|
||||
# module is not always inferred and this causes critical warnings
|
||||
|
||||
set_property -quiet ASYNC_REG TRUE [get_cells -hierarchical -filter {name =~ *rst_async_d*_reg}]
|
||||
set_property -quiet ASYNC_REG TRUE [get_cells -hierarchical -filter {name =~ *rst_sync_reg}]
|
||||
|
||||
set_false_path -quiet -to [get_pins -hierarchical *rst_sync_reg/PRE]
|
||||
set_false_path -quiet -to [get_pins -hierarchical *rst_async_d1_reg/PRE]
|
||||
set_false_path -quiet -to [get_pins -hierarchical *rst_async_d2_reg/PRE]
|
||||
@@ -0,0 +1,158 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// serial data output interface: serdes(x8)
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module ad_serdes_clk #(
|
||||
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter DDR_OR_SDR_N = 1,
|
||||
// single ended - 0
|
||||
// differential - 1
|
||||
parameter CLKIN_DS_OR_SE_N = 1,
|
||||
parameter SERDES_FACTOR = 8,
|
||||
parameter MMCM_OR_BUFR_N = 1,
|
||||
parameter MMCM_CLKIN_PERIOD = 1.667,
|
||||
parameter MMCM_VCO_DIV = 6,
|
||||
parameter MMCM_VCO_MUL = 12.000,
|
||||
parameter MMCM_CLK0_DIV = 2.000,
|
||||
parameter MMCM_CLK1_DIV = 6
|
||||
) (
|
||||
|
||||
// clock and divided clock
|
||||
|
||||
input rst,
|
||||
input clk_in_p,
|
||||
input clk_in_n,
|
||||
output clk,
|
||||
output div_clk,
|
||||
output out_clk,
|
||||
|
||||
// drp interface
|
||||
|
||||
input up_clk,
|
||||
input up_rstn,
|
||||
input up_drp_sel,
|
||||
input up_drp_wr,
|
||||
input [11:0] up_drp_addr,
|
||||
input [31:0] up_drp_wdata,
|
||||
output [31:0] up_drp_rdata,
|
||||
output up_drp_ready,
|
||||
output up_drp_locked
|
||||
);
|
||||
|
||||
localparam BUFR_DIVIDE = (DDR_OR_SDR_N == 1'b1) ? SERDES_FACTOR / 2 : SERDES_FACTOR;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire clk_in_s;
|
||||
|
||||
// defaults
|
||||
|
||||
assign up_drp_rdata[31:16] = 'd0;
|
||||
|
||||
// instantiations
|
||||
|
||||
generate
|
||||
if (CLKIN_DS_OR_SE_N == 1) begin
|
||||
IBUFGDS i_clk_in_ibuf (
|
||||
.I (clk_in_p),
|
||||
.IB (clk_in_n),
|
||||
.O (clk_in_s));
|
||||
end else begin
|
||||
IBUF IBUF_inst (
|
||||
.O(clk_in_s),
|
||||
.I(clk_in_p));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (MMCM_OR_BUFR_N == 1) begin
|
||||
ad_mmcm_drp #(
|
||||
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
|
||||
.MMCM_CLKIN_PERIOD (MMCM_CLKIN_PERIOD),
|
||||
.MMCM_CLKIN2_PERIOD (MMCM_CLKIN_PERIOD),
|
||||
.MMCM_VCO_DIV (MMCM_VCO_DIV),
|
||||
.MMCM_VCO_MUL (MMCM_VCO_MUL),
|
||||
.MMCM_CLK0_DIV (MMCM_CLK0_DIV),
|
||||
.MMCM_CLK0_PHASE (0.0),
|
||||
.MMCM_CLK1_DIV (MMCM_CLK1_DIV),
|
||||
.MMCM_CLK1_PHASE (0.0),
|
||||
.MMCM_CLK2_DIV (MMCM_CLK0_DIV),
|
||||
.MMCM_CLK2_PHASE (90.0)
|
||||
) i_mmcm_drp (
|
||||
.clk (clk_in_s),
|
||||
.clk2 (1'b0),
|
||||
.clk_sel (1'b1),
|
||||
.mmcm_rst (rst),
|
||||
.mmcm_clk_0 (clk),
|
||||
.mmcm_clk_1 (div_clk),
|
||||
.mmcm_clk_2 (out_clk),
|
||||
.up_clk (up_clk),
|
||||
.up_rstn (up_rstn),
|
||||
.up_drp_sel (up_drp_sel),
|
||||
.up_drp_wr (up_drp_wr),
|
||||
.up_drp_addr (up_drp_addr),
|
||||
.up_drp_wdata (up_drp_wdata[15:0]),
|
||||
.up_drp_rdata (up_drp_rdata[15:0]),
|
||||
.up_drp_ready (up_drp_ready),
|
||||
.up_drp_locked (up_drp_locked));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (MMCM_OR_BUFR_N == 0) begin
|
||||
BUFIO i_clk_buf (
|
||||
.I (clk_in_s),
|
||||
.O (clk));
|
||||
|
||||
BUFR #(
|
||||
.BUFR_DIVIDE(BUFR_DIVIDE)
|
||||
) i_div_clk_buf (
|
||||
.CLR (1'b0),
|
||||
.CE (1'b1),
|
||||
.I (clk_in_s),
|
||||
.O (div_clk));
|
||||
|
||||
assign out_clk = clk;
|
||||
assign up_drp_rdata[15:0] = 'd0;
|
||||
assign up_drp_ready = 'd0;
|
||||
assign up_drp_locked = 'd0;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,337 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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 1ps/1ps
|
||||
|
||||
module ad_serdes_in #(
|
||||
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter CMOS_LVDS_N = 0,
|
||||
parameter DDR_OR_SDR_N = 0,
|
||||
parameter SERDES_FACTOR = 8,
|
||||
parameter DATA_WIDTH = 16,
|
||||
parameter DRP_WIDTH = 5,
|
||||
parameter IODELAY_ENABLE = 1,
|
||||
parameter IODELAY_CTRL = 0,
|
||||
parameter IODELAY_GROUP = "dev_if_delay_group",
|
||||
parameter REFCLK_FREQUENCY = 200
|
||||
) (
|
||||
|
||||
// reset and clocks
|
||||
|
||||
input rst,
|
||||
input clk,
|
||||
input div_clk,
|
||||
|
||||
// data interface
|
||||
|
||||
output [(DATA_WIDTH-1):0] data_s0, // last bit received
|
||||
output [(DATA_WIDTH-1):0] data_s1,
|
||||
output [(DATA_WIDTH-1):0] data_s2,
|
||||
output [(DATA_WIDTH-1):0] data_s3,
|
||||
output [(DATA_WIDTH-1):0] data_s4,
|
||||
output [(DATA_WIDTH-1):0] data_s5,
|
||||
output [(DATA_WIDTH-1):0] data_s6,
|
||||
output [(DATA_WIDTH-1):0] data_s7, // 1st bit received
|
||||
input [(DATA_WIDTH-1):0] data_in_p,
|
||||
input [(DATA_WIDTH-1):0] data_in_n,
|
||||
|
||||
// delay-data interface
|
||||
|
||||
input up_clk,
|
||||
input [(DATA_WIDTH-1):0] up_dld,
|
||||
input [((DATA_WIDTH*DRP_WIDTH)-1):0] up_dwdata,
|
||||
output [((DATA_WIDTH*DRP_WIDTH)-1):0] up_drdata,
|
||||
|
||||
// delay-control interface
|
||||
|
||||
input delay_clk,
|
||||
input delay_rst,
|
||||
output delay_locked
|
||||
);
|
||||
|
||||
localparam SEVEN_SERIES = 1;
|
||||
localparam ULTRASCALE = 2;
|
||||
localparam ULTRASCALE_PLUS = 3;
|
||||
localparam DATA_RATE = (DDR_OR_SDR_N) ? "DDR" : "SDR";
|
||||
|
||||
localparam IODELAY_CTRL_ENABLED = (IODELAY_ENABLE == 1) ? IODELAY_CTRL : 0;
|
||||
localparam SIM_DEVICE = FPGA_TECHNOLOGY == SEVEN_SERIES ? "7SERIES" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE ? "ULTRASCALE" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE_PLUS ? "ULTRASCALE_PLUS" :
|
||||
"UNSUPPORTED";
|
||||
// when ULTRASCALE_PLUS, use ULTRASCALE because IDELAYCTRL is the same for both
|
||||
// and doesn't know ULTRASCALE_PLUS string
|
||||
localparam SIM_DEVICE_IDELAYCTRL = FPGA_TECHNOLOGY == SEVEN_SERIES ? "7SERIES" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE ? "ULTRASCALE" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE_PLUS ? "ULTRASCALE" :
|
||||
"UNSUPPORTED";
|
||||
// internal registers
|
||||
|
||||
reg [6:0] serdes_rst_seq;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [(DATA_WIDTH-1):0] data_in_ibuf_s;
|
||||
wire [(DATA_WIDTH-1):0] data_in_idelay_s;
|
||||
wire [(DATA_WIDTH-1):0] data_shift1_s;
|
||||
wire [(DATA_WIDTH-1):0] data_shift2_s;
|
||||
wire serdes_rst = serdes_rst_seq[6];
|
||||
|
||||
// delay controller
|
||||
|
||||
generate
|
||||
if (IODELAY_CTRL_ENABLED == 1) begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYCTRL #(
|
||||
.SIM_DEVICE(SIM_DEVICE_IDELAYCTRL)
|
||||
) i_delay_ctrl (
|
||||
.RST (delay_rst),
|
||||
.REFCLK (delay_clk),
|
||||
.RDY (delay_locked));
|
||||
end else begin
|
||||
assign delay_locked = 1'b1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// received data interface: ibuf -> idelay -> iserdes
|
||||
|
||||
// ibuf
|
||||
|
||||
genvar l_inst;
|
||||
generate
|
||||
for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_io
|
||||
if (CMOS_LVDS_N == 0) begin
|
||||
IBUFDS i_ibuf (
|
||||
.I (data_in_p[l_inst]),
|
||||
.IB (data_in_n[l_inst]),
|
||||
.O (data_in_ibuf_s[l_inst]));
|
||||
end else begin
|
||||
IBUF i_ibuf (
|
||||
.I (data_in_p[l_inst]),
|
||||
.O (data_in_ibuf_s[l_inst]));
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// bypass IDELAY
|
||||
|
||||
generate
|
||||
if (IODELAY_ENABLE == 0) begin
|
||||
assign data_in_idelay_s = data_in_ibuf_s;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ (posedge div_clk) begin
|
||||
if (rst) begin
|
||||
serdes_rst_seq [6:0] <= 7'b0001110;
|
||||
end else begin
|
||||
serdes_rst_seq [6:0] <= {serdes_rst_seq [5:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
// idelay + iserdes
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
|
||||
for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_data
|
||||
|
||||
if (IODELAY_ENABLE == 1) begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYE2 #(
|
||||
.CINVCTRL_SEL ("FALSE"),
|
||||
.DELAY_SRC ("IDATAIN"),
|
||||
.HIGH_PERFORMANCE_MODE ("FALSE"),
|
||||
.IDELAY_TYPE ("VAR_LOAD"),
|
||||
.IDELAY_VALUE (0),
|
||||
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
|
||||
.PIPE_SEL ("FALSE"),
|
||||
.SIGNAL_PATTERN ("DATA")
|
||||
) i_idelay (
|
||||
.CE (1'b0),
|
||||
.INC (1'b0),
|
||||
.DATAIN (1'b0),
|
||||
.LDPIPEEN (1'b0),
|
||||
.CINVCTRL (1'b0),
|
||||
.REGRST (1'b0),
|
||||
.C (up_clk),
|
||||
.IDATAIN (data_in_ibuf_s[l_inst]),
|
||||
.DATAOUT (data_in_idelay_s[l_inst]),
|
||||
.LD (up_dld[l_inst]),
|
||||
.CNTVALUEIN (up_dwdata[DRP_WIDTH*l_inst +: DRP_WIDTH]),
|
||||
.CNTVALUEOUT (up_drdata[DRP_WIDTH*l_inst +: DRP_WIDTH]));
|
||||
end
|
||||
|
||||
ISERDESE2 #(
|
||||
.DATA_RATE (DATA_RATE),
|
||||
.DATA_WIDTH (SERDES_FACTOR),
|
||||
.DYN_CLKDIV_INV_EN ("FALSE"),
|
||||
.DYN_CLK_INV_EN ("FALSE"),
|
||||
.INIT_Q1 (1'b0),
|
||||
.INIT_Q2 (1'b0),
|
||||
.INIT_Q3 (1'b0),
|
||||
.INIT_Q4 (1'b0),
|
||||
.INTERFACE_TYPE ("NETWORKING"),
|
||||
.IOBDELAY ("IFD"),
|
||||
.NUM_CE (2),
|
||||
.OFB_USED ("FALSE"),
|
||||
.SERDES_MODE ("MASTER"),
|
||||
.SRVAL_Q1 (1'b0),
|
||||
.SRVAL_Q2 (1'b0),
|
||||
.SRVAL_Q3 (1'b0),
|
||||
.SRVAL_Q4 (1'b0)
|
||||
) i_iserdes (
|
||||
.O (),
|
||||
.Q1 (data_s0[l_inst]),
|
||||
.Q2 (data_s1[l_inst]),
|
||||
.Q3 (data_s2[l_inst]),
|
||||
.Q4 (data_s3[l_inst]),
|
||||
.Q5 (data_s4[l_inst]),
|
||||
.Q6 (data_s5[l_inst]),
|
||||
.Q7 (data_s6[l_inst]),
|
||||
.Q8 (data_s7[l_inst]),
|
||||
.SHIFTOUT1 (),
|
||||
.SHIFTOUT2 (),
|
||||
.BITSLIP (1'b0),
|
||||
.CE1 (1'b1),
|
||||
.CE2 (1'b1),
|
||||
.CLKDIVP (1'b0),
|
||||
.CLK (clk),
|
||||
.CLKB (~clk),
|
||||
.CLKDIV (div_clk),
|
||||
.OCLK (1'b0),
|
||||
.DYNCLKDIVSEL (1'b0),
|
||||
.DYNCLKSEL (1'b0),
|
||||
.D (1'b0),
|
||||
.DDLY (data_in_idelay_s[l_inst]),
|
||||
.OFB (1'b0),
|
||||
.OCLKB (1'b0),
|
||||
.RST (serdes_rst),
|
||||
.SHIFTIN1 (1'b0),
|
||||
.SHIFTIN2 (1'b0));
|
||||
end /* g_data */
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (FPGA_TECHNOLOGY == ULTRASCALE || FPGA_TECHNOLOGY == ULTRASCALE_PLUS) begin
|
||||
for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_data
|
||||
|
||||
wire div_dld;
|
||||
wire en_vtc;
|
||||
wire ld_cnt;
|
||||
reg [4:0] vtc_cnt = {5{1'b1}};
|
||||
|
||||
sync_event sync_load (
|
||||
.in_clk (up_clk),
|
||||
.in_event (up_dld[l_inst]),
|
||||
.out_clk (div_clk),
|
||||
.out_event (div_dld));
|
||||
|
||||
if (IODELAY_ENABLE == 1) begin
|
||||
(* IODELAY_GROUP = IODELAY_GROUP *)
|
||||
IDELAYE3 #(
|
||||
.CASCADE ("NONE"), // Cascade setting (MASTER, NONE, SLAVE_END, SLAVE_MIDDLE)
|
||||
.DELAY_FORMAT ("TIME"), // Units of the DELAY_VALUE (COUNT, TIME)
|
||||
.DELAY_SRC ("IDATAIN"), // Delay input (DATAIN, IDATAIN)
|
||||
.DELAY_TYPE ("VAR_LOAD"), // Set the type of tap delay line (FIXED, VARIABLE, VAR_LOAD)
|
||||
.DELAY_VALUE (0), // Input delay value setting
|
||||
.IS_CLK_INVERTED (1'b0), // Optional inversion for CLK
|
||||
.IS_RST_INVERTED (1'b0), // Optional inversion for RST
|
||||
.REFCLK_FREQUENCY (500.0), // IDELAYCTRL clock input frequency in MHz (200.0-2667.0)
|
||||
.SIM_DEVICE (SIM_DEVICE), // Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1,
|
||||
// ULTRASCALE_PLUS_ES2)
|
||||
.UPDATE_MODE ("ASYNC") // Determines when updates to the delay will take effect (ASYNC, MANUAL, SYNC)
|
||||
) i_idelay (
|
||||
.CASC_OUT (), // 1-bit output: Cascade delay output to ODELAY input cascade
|
||||
.CNTVALUEOUT (up_drdata[DRP_WIDTH*l_inst +: DRP_WIDTH]), // 9-bit output: Counter value output
|
||||
.DATAOUT (data_in_idelay_s[l_inst]), // 1-bit output: Delayed data output
|
||||
.CASC_IN (1'b0), // 1-bit input: Cascade delay input from slave ODELAY CASCADE_OUT
|
||||
.CASC_RETURN (1'b0), // 1-bit input: Cascade delay returning from slave ODELAY DATAOUT
|
||||
.CE (1'b0), // 1-bit input: Active high enable increment/decrement input
|
||||
.CLK (div_clk), // 1-bit input: Clock input
|
||||
.CNTVALUEIN (up_dwdata[DRP_WIDTH*l_inst +: DRP_WIDTH]), // 9-bit input: Counter value input
|
||||
.DATAIN (1'b0), // 1-bit input: Data input from the logic
|
||||
.EN_VTC (en_vtc), // 1-bit input: Keep delay constant over VT
|
||||
.IDATAIN (data_in_ibuf_s[l_inst]), // 1-bit input: Data input from the IOBUF
|
||||
.INC (1'b0), // 1-bit input: Increment / Decrement tap delay input
|
||||
.LOAD (ld_cnt), // 1-bit input: Load DELAY_VALUE input
|
||||
.RST (rst)); // 1-bit input: Asynchronous Reset to the DELAY_VALUE
|
||||
end
|
||||
|
||||
always @(posedge div_clk) begin
|
||||
if (div_dld) begin
|
||||
vtc_cnt <= 'h0;
|
||||
end else if (~(&vtc_cnt)) begin
|
||||
vtc_cnt <= vtc_cnt + 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign en_vtc = &vtc_cnt;
|
||||
assign ld_cnt = ~vtc_cnt[4] & (&vtc_cnt[3:0]);
|
||||
|
||||
ISERDESE3 #(
|
||||
.DATA_WIDTH (8), // Parallel data width (4,8)
|
||||
.FIFO_ENABLE ("FALSE"), // Enables the use of the FIFO
|
||||
.FIFO_SYNC_MODE ("FALSE"), // Enables the use of internal 2-stage synchronizers on the FIFO
|
||||
.IS_CLK_B_INVERTED (1'b0), // Optional inversion for CLK_B
|
||||
.IS_CLK_INVERTED (1'b0), // Optional inversion for CLK
|
||||
.IS_RST_INVERTED (1'b0), // Optional inversion for RST
|
||||
.SIM_DEVICE (SIM_DEVICE) // Set the device version (ULTRASCALE, ULTRASCALE_PLUS, ULTRASCALE_PLUS_ES1,
|
||||
// ULTRASCALE_PLUS_ES2)
|
||||
) i_iserdes(
|
||||
.FIFO_EMPTY (), // 1-bit output: FIFO empty flag
|
||||
.INTERNAL_DIVCLK (), // 1-bit output: Internally divided down clock used when FIFO is
|
||||
// disabled (do not connect)
|
||||
.Q ({data_s0[l_inst],
|
||||
data_s1[l_inst],
|
||||
data_s2[l_inst],
|
||||
data_s3[l_inst],
|
||||
data_s4[l_inst],
|
||||
data_s5[l_inst],
|
||||
data_s6[l_inst],
|
||||
data_s7[l_inst]}), // 8-bit registered output
|
||||
.CLK (clk), // 1-bit input: High-speed clock
|
||||
.CLKDIV (div_clk), // 1-bit input: Divided Clock
|
||||
.CLK_B (~clk), // 1-bit input: Inversion of High-speed clock CLK
|
||||
.D (data_in_idelay_s[l_inst]), // 1-bit input: Serial Data Input
|
||||
.FIFO_RD_CLK (div_clk), // 1-bit input: FIFO read clock
|
||||
.FIFO_RD_EN (1'b1), // 1-bit input: Enables reading the FIFO when asserted
|
||||
.RST (serdes_rst)); // 1-bit input: Asynchronous Reset
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
@@ -0,0 +1,187 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <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.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// serial data output interface: serdes(x8)
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module ad_serdes_out #(
|
||||
|
||||
parameter FPGA_TECHNOLOGY = 0,
|
||||
parameter CMOS_LVDS_N = 0,
|
||||
parameter DDR_OR_SDR_N = 1,
|
||||
parameter SERDES_FACTOR = 8,
|
||||
parameter DATA_WIDTH = 16
|
||||
) (
|
||||
|
||||
// reset and clocks
|
||||
|
||||
input rst,
|
||||
input clk,
|
||||
input div_clk,
|
||||
|
||||
// data interface
|
||||
input data_oe,
|
||||
input [(DATA_WIDTH-1):0] data_s0, // 1st bit to be transmitted
|
||||
input [(DATA_WIDTH-1):0] data_s1,
|
||||
input [(DATA_WIDTH-1):0] data_s2,
|
||||
input [(DATA_WIDTH-1):0] data_s3,
|
||||
input [(DATA_WIDTH-1):0] data_s4,
|
||||
input [(DATA_WIDTH-1):0] data_s5,
|
||||
input [(DATA_WIDTH-1):0] data_s6,
|
||||
input [(DATA_WIDTH-1):0] data_s7, // last bit to be transmitted
|
||||
output [(DATA_WIDTH-1):0] data_out_se,
|
||||
output [(DATA_WIDTH-1):0] data_out_p,
|
||||
output [(DATA_WIDTH-1):0] data_out_n
|
||||
);
|
||||
|
||||
localparam SEVEN_SERIES = 1;
|
||||
localparam ULTRASCALE = 2;
|
||||
localparam ULTRASCALE_PLUS = 3;
|
||||
localparam DR_OQ_DDR = DDR_OR_SDR_N == 1'b1 ? "DDR": "SDR";
|
||||
|
||||
localparam SIM_DEVICE = FPGA_TECHNOLOGY == SEVEN_SERIES ? "7SERIES" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE ? "ULTRASCALE" :
|
||||
FPGA_TECHNOLOGY == ULTRASCALE_PLUS ? "ULTRASCALE_PLUS" :
|
||||
"UNSUPPORTED";
|
||||
|
||||
// internal registers
|
||||
|
||||
reg [6:0] serdes_rst_seq;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [(DATA_WIDTH-1):0] data_out_s;
|
||||
wire [(DATA_WIDTH-1):0] serdes_shift1_s;
|
||||
wire [(DATA_WIDTH-1):0] serdes_shift2_s;
|
||||
wire [(DATA_WIDTH-1):0] data_t;
|
||||
wire buffer_disable;
|
||||
wire serdes_rst = serdes_rst_seq[6];
|
||||
|
||||
// instantiations
|
||||
|
||||
assign data_out_se = data_out_s;
|
||||
assign buffer_disable = ~data_oe;
|
||||
|
||||
always @ (posedge div_clk) begin
|
||||
if (rst) begin
|
||||
serdes_rst_seq [6:0] <= 7'b0001110;
|
||||
end else begin
|
||||
serdes_rst_seq [6:0] <= {serdes_rst_seq [5:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
// transmit data path: oserdes -> obuf
|
||||
|
||||
genvar l_inst;
|
||||
generate
|
||||
for (l_inst = 0; l_inst <= (DATA_WIDTH-1); l_inst = l_inst + 1) begin: g_data
|
||||
|
||||
// oserdes
|
||||
|
||||
if (FPGA_TECHNOLOGY == SEVEN_SERIES) begin
|
||||
OSERDESE2 #(
|
||||
.DATA_RATE_OQ (DR_OQ_DDR),
|
||||
.DATA_RATE_TQ ("SDR"),
|
||||
.DATA_WIDTH (SERDES_FACTOR),
|
||||
.TRISTATE_WIDTH (1),
|
||||
.SERDES_MODE ("MASTER")
|
||||
) i_serdes (
|
||||
.D1 (data_s0[l_inst]),
|
||||
.D2 (data_s1[l_inst]),
|
||||
.D3 (data_s2[l_inst]),
|
||||
.D4 (data_s3[l_inst]),
|
||||
.D5 (data_s4[l_inst]),
|
||||
.D6 (data_s5[l_inst]),
|
||||
.D7 (data_s6[l_inst]),
|
||||
.D8 (data_s7[l_inst]),
|
||||
.T1 (buffer_disable),
|
||||
.T2 (buffer_disable),
|
||||
.T3 (buffer_disable),
|
||||
.T4 (buffer_disable),
|
||||
.SHIFTIN1 (1'b0),
|
||||
.SHIFTIN2 (1'b0),
|
||||
.SHIFTOUT1 (),
|
||||
.SHIFTOUT2 (),
|
||||
.OCE (1'b1),
|
||||
.CLK (clk),
|
||||
.CLKDIV (div_clk),
|
||||
.OQ (data_out_s[l_inst]),
|
||||
.TQ (data_t[l_inst]),
|
||||
.OFB (),
|
||||
.TFB (),
|
||||
.TBYTEIN (1'b0),
|
||||
.TBYTEOUT (),
|
||||
.TCE (1'b1),
|
||||
.RST (serdes_rst));
|
||||
end
|
||||
|
||||
if (FPGA_TECHNOLOGY == ULTRASCALE || FPGA_TECHNOLOGY == ULTRASCALE_PLUS) begin
|
||||
OSERDESE3 #(
|
||||
.DATA_WIDTH (SERDES_FACTOR),
|
||||
.SIM_DEVICE (SIM_DEVICE)
|
||||
) i_serdes (
|
||||
.D ({data_s7[l_inst],
|
||||
data_s6[l_inst],
|
||||
data_s5[l_inst],
|
||||
data_s4[l_inst],
|
||||
data_s3[l_inst],
|
||||
data_s2[l_inst],
|
||||
data_s1[l_inst],
|
||||
data_s0[l_inst]}),
|
||||
.T (buffer_disable),
|
||||
.CLK (clk),
|
||||
.CLKDIV (div_clk),
|
||||
.OQ (data_out_s[l_inst]),
|
||||
.T_OUT (data_t[l_inst]),
|
||||
.RST (serdes_rst));
|
||||
end
|
||||
|
||||
// obuf
|
||||
|
||||
if (CMOS_LVDS_N == 0) begin
|
||||
OBUFTDS i_obuftds (
|
||||
.T (data_t[l_inst]),
|
||||
.I (data_out_s[l_inst]),
|
||||
.O (data_out_p[l_inst]),
|
||||
.OB (data_out_n[l_inst]));
|
||||
end else begin
|
||||
OBUFT i_obuf (
|
||||
.T (data_t[l_inst]),
|
||||
.I (data_out_s[l_inst]),
|
||||
.O (data_out_p[l_inst]));
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
@@ -0,0 +1,13 @@
|
||||
###############################################################################
|
||||
## Copyright (C) 2014-2023 Analog Devices, Inc. All rights reserved.
|
||||
### SPDX short identifier: ADIBSD
|
||||
###############################################################################
|
||||
|
||||
set_property ASYNC_REG true [get_cells -hierarchical -filter {name =~ *up_count_running_m*}]
|
||||
set_property ASYNC_REG true [get_cells -hierarchical -filter {name =~ *d_count_run_m*}]
|
||||
set_property ASYNC_REG true [get_cells -hierarchical -filter {name =~ *up_d_count_reg*}]
|
||||
|
||||
set_false_path -from [get_cells -hierarchical -filter {name =~ *d_count_run_m3_reg* && IS_SEQUENTIAL}] -to [get_cells -hierarchical -filter {name =~ *up_count_running_m1_reg* && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hierarchical -filter {name =~ *up_count_run_reg* && IS_SEQUENTIAL}] -to [get_cells -hierarchical -filter {name =~ *d_count_run_m1_reg* && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hierarchical -filter {name =~ *d_count_reg* && IS_SEQUENTIAL}] -to [get_cells -hierarchical -filter {name =~ *up_d_count_reg* && IS_SEQUENTIAL}]
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
###############################################################################
|
||||
## Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
|
||||
### SPDX short identifier: ADIBSD
|
||||
###############################################################################
|
||||
|
||||
set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *up_xfer_state*}]
|
||||
set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *d_xfer_toggle_m*}]
|
||||
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_xfer_state_m1_reg && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_xfer_toggle_m1_reg && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_data* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_data_cntrl* && IS_SEQUENTIAL}]
|
||||
@@ -0,0 +1,11 @@
|
||||
###############################################################################
|
||||
## Copyright (C) 2017-2023 Analog Devices, Inc. All rights reserved.
|
||||
### SPDX short identifier: ADIBSD
|
||||
###############################################################################
|
||||
|
||||
set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *d_xfer_state*}]
|
||||
set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *up_xfer_toggle_m*}]
|
||||
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_xfer_toggle_m1_reg && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *up_xfer_toggle_reg && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *d_xfer_state_m1_reg && IS_SEQUENTIAL}]
|
||||
set_false_path -from [get_cells -hier -filter {name =~ *d_xfer_data* && IS_SEQUENTIAL}] -to [get_cells -hier -filter {name =~ *up_data_status* && IS_SEQUENTIAL}]
|
||||
Reference in New Issue
Block a user