initial commit, add dds_par module

This commit is contained in:
2024-01-15 09:36:08 +08:00
commit 315a673005
1374 changed files with 465956 additions and 0 deletions
+77
View File
@@ -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
+284
View File
@@ -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
+278
View File
@@ -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
+196
View File
@@ -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
+351
View File
@@ -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
+83
View File
@@ -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]
+158
View File
@@ -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
+337
View File
@@ -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
+187
View File
@@ -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}]