Archived
initial commit
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := adi_jesd204
|
||||
|
||||
INTEL_DEPS += adi_jesd204_glue.v
|
||||
INTEL_DEPS += adi_jesd204_glue_hw.tcl
|
||||
INTEL_DEPS += adi_jesd204_hw.tcl
|
||||
|
||||
INTEL_LIB_DEPS += intel/axi_adxcvr
|
||||
INTEL_LIB_DEPS += intel/jesd204_phy
|
||||
INTEL_LIB_DEPS += jesd204/jesd204_soft_pcs_rx
|
||||
INTEL_LIB_DEPS += jesd204/jesd204_soft_pcs_tx
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,49 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module adi_jesd204_glue (
|
||||
input in_pll_powerdown,
|
||||
output out_pll_powerdown,
|
||||
output out_mcgb_rst,
|
||||
output out_pll_select_gnd
|
||||
);
|
||||
|
||||
assign out_pll_powerdown = in_pll_powerdown;
|
||||
assign out_mcgb_rst = in_pll_powerdown;
|
||||
assign out_pll_select_gnd = 1'b0;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# The ADI JESD204 Core is released under the following license, which is
|
||||
# different than all other HDL cores in this repository.
|
||||
#
|
||||
# Please read this, and understand the freedoms and responsibilities you have
|
||||
# by using this source code/core.
|
||||
#
|
||||
# The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc.
|
||||
#
|
||||
# This core is free software, you can use run, copy, study, change, ask
|
||||
# questions about and improve this core. Distribution of source, or resulting
|
||||
# binaries (including those inside an FPGA or ASIC) require you to release the
|
||||
# source of the entire project (excluding the system libraries provide by the
|
||||
# tools/compiler/FPGA vendor). These are the terms of the GNU General Public
|
||||
# License version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version 2
|
||||
# along with this source code, and binary. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Commercial licenses (with commercial support) of this JESD204 core are also
|
||||
# available under terms different than the General Public License. (e.g. they
|
||||
# do not require you to accompany any image (FPGA or ASIC) using the JESD204
|
||||
# core with any corresponding source code.) For these alternate terms you must
|
||||
# purchase a license from Analog Devices Technology Licensing Office. Users
|
||||
# interested in such a license should contact [email protected] for
|
||||
# more information. This commercial license is sub-licensable (if you purchase
|
||||
# chips from Analog Devices, incorporate them into your PCB level product, and
|
||||
# purchase a JESD204 license, end users of your product will also have a
|
||||
# license to use this core in a commercial setting without releasing their
|
||||
# source code).
|
||||
#
|
||||
# In addition, we kindly ask you to acknowledge ADI in any program, application
|
||||
# or publication in which you use this JESD204 HDL core. (You are not required
|
||||
# to do so; it is up to your common sense to decide whether you want to comply
|
||||
# with this request or not.) For general publications, we suggest referencing :
|
||||
# “The design and implementation of the JESD204 HDL Core used in this project
|
||||
# is copyright © 2016-2017, Analog Devices, Inc.”
|
||||
#
|
||||
|
||||
package require qsys
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
|
||||
ad_ip_create adi_jesd204_glue {Glue} jesd204_phy_glue_elab
|
||||
set_module_property INTERNAL true
|
||||
|
||||
# files
|
||||
|
||||
ad_ip_files adi_jesd204_glue [list \
|
||||
adi_jesd204_glue.v \
|
||||
]
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter IN_PLL_POWERDOWN_EN BOOLEAN 1 false
|
||||
|
||||
proc jesd204_phy_glue_elab {} {
|
||||
add_interface in_pll_powerdown conduit end
|
||||
add_interface_port in_pll_powerdown in_pll_powerdown pll_powerdown Input 1
|
||||
set_interface_property in_pll_powerdown ENABLED [get_parameter IN_PLL_POWERDOWN_EN]
|
||||
|
||||
add_interface out_pll_powerdown conduit end
|
||||
add_interface_port out_pll_powerdown out_pll_powerdown pll_powerdown Output 1
|
||||
add_interface out_mcgb_rst conduit end
|
||||
add_interface_port out_mcgb_rst out_mcgb_rst mcgb_rst Output 1
|
||||
|
||||
add_interface out_pll_select_gnd conduit end
|
||||
add_interface_port out_pll_select_gnd out_pll_select_gnd pll_select Output 1
|
||||
}
|
||||
@@ -0,0 +1,601 @@
|
||||
#
|
||||
# The ADI JESD204 Core is released under the following license, which is
|
||||
# different than all other HDL cores in this repository.
|
||||
#
|
||||
# Please read this, and understand the freedoms and responsibilities you have
|
||||
# by using this source code/core.
|
||||
#
|
||||
# The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc.
|
||||
#
|
||||
# This core is free software, you can use run, copy, study, change, ask
|
||||
# questions about and improve this core. Distribution of source, or resulting
|
||||
# binaries (including those inside an FPGA or ASIC) require you to release the
|
||||
# source of the entire project (excluding the system libraries provide by the
|
||||
# tools/compiler/FPGA vendor). These are the terms of the GNU General Public
|
||||
# License version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version 2
|
||||
# along with this source code, and binary. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Commercial licenses (with commercial support) of this JESD204 core are also
|
||||
# available under terms different than the General Public License. (e.g. they
|
||||
# do not require you to accompany any image (FPGA or ASIC) using the JESD204
|
||||
# core with any corresponding source code.) For these alternate terms you must
|
||||
# purchase a license from Analog Devices Technology Licensing Office. Users
|
||||
# interested in such a license should contact [email protected] for
|
||||
# more information. This commercial license is sub-licensable (if you purchase
|
||||
# chips from Analog Devices, incorporate them into your PCB level product, and
|
||||
# purchase a JESD204 license, end users of your product will also have a
|
||||
# license to use this core in a commercial setting without releasing their
|
||||
# source code).
|
||||
#
|
||||
# In addition, we kindly ask you to acknowledge ADI in any program, application
|
||||
# or publication in which you use this JESD204 HDL core. (You are not required
|
||||
# to do so; it is up to your common sense to decide whether you want to comply
|
||||
# with this request or not.) For general publications, we suggest referencing :
|
||||
# “The design and implementation of the JESD204 HDL Core used in this project
|
||||
# is copyright © 2016-2017, Analog Devices, Inc.”
|
||||
#
|
||||
|
||||
package require qsys
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
set version 19.1
|
||||
|
||||
#
|
||||
# Wrapper module that instantiates and connects all the components required to
|
||||
# for a JESD204 link.
|
||||
#
|
||||
# The following components are created:
|
||||
# * Transceiver for each lane
|
||||
# * Transceiver lane PLL (TX only)
|
||||
# * Transceiver reset controller
|
||||
# * Link PLL
|
||||
# * JESD204 link layer processing
|
||||
# * JESD204 link layer processing control interface
|
||||
# * axi_adxcvr link management peripheral
|
||||
#
|
||||
|
||||
ad_ip_create adi_jesd204 {Analog Devices JESD204}
|
||||
set_module_property VALIDATION_CALLBACK jesd204_validate
|
||||
set_module_property COMPOSITION_CALLBACK jesd204_compose
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE_FAMILY STRING "" false {
|
||||
VISIBLE true
|
||||
}
|
||||
|
||||
ad_ip_parameter DEVICE STRING "" false {
|
||||
SYSTEM_INFO DEVICE
|
||||
VISIBLE false
|
||||
}
|
||||
|
||||
ad_ip_parameter TX_OR_RX_N BOOLEAN 0 false { \
|
||||
DISPLAY_HINT "radio" \
|
||||
DISPLAY_NAME "Data Path" \
|
||||
ALLOWED_RANGES { "0:Receive" "1:Transmit" }
|
||||
}
|
||||
|
||||
ad_ip_parameter ID NATURAL 0 false { \
|
||||
DISPLAY_NAME "Core ID" \
|
||||
}
|
||||
|
||||
ad_ip_parameter LANE_RATE FLOAT 10000 false { \
|
||||
DISPLAY_NAME "Lane Rate" \
|
||||
DISPLAY_UNITS "Mbps" \
|
||||
}
|
||||
|
||||
ad_ip_parameter SYSCLK_FREQUENCY FLOAT 100.0 false { \
|
||||
DISPLAY_NAME "System Clock Frequency" \
|
||||
UNITS Megahertz
|
||||
}
|
||||
|
||||
ad_ip_parameter REFCLK_FREQUENCY FLOAT 500.0 false { \
|
||||
DISPLAY_NAME "Reference Clock Frequency" \
|
||||
UNITS Megahertz \
|
||||
}
|
||||
|
||||
ad_ip_parameter NUM_OF_LANES POSITIVE 4 false { \
|
||||
DISPLAY_NAME "Number of Lanes" \
|
||||
ALLOWED_RANGES 1:8
|
||||
}
|
||||
|
||||
ad_ip_parameter BONDING_CLOCKS_EN BOOLEAN 0 false { \
|
||||
DISPLAY_HINT "Clock Network" \
|
||||
DISPLAY_NAME "Clock Network" \
|
||||
ALLOWED_RANGES { "0:x1/xN (Non-bonded)" "1:x6/xN (Bonded)" }
|
||||
}
|
||||
|
||||
ad_ip_parameter LANE_MAP STRING "" false { \
|
||||
DISPLAY_NAME "Lane Mapping" \
|
||||
}
|
||||
|
||||
ad_ip_parameter LANE_INVERT STD_LOGIC_VECTOR 0 false { \
|
||||
DISPLAY_NAME "Lane Invert Mask" \
|
||||
DISPLAY_HINT "hexadecimal" \
|
||||
WIDTH 8 \
|
||||
}
|
||||
|
||||
ad_ip_parameter SOFT_PCS BOOLEAN true false { \
|
||||
DISPLAY_NAME "Enable Soft PCS" \
|
||||
}
|
||||
|
||||
ad_ip_parameter INPUT_PIPELINE_STAGES INTEGER 0 false { \
|
||||
DISPLAY_NAME "Enable input pipeline" \
|
||||
}
|
||||
|
||||
ad_ip_parameter EXT_DEVICE_CLK_EN BOOLEAN 0 false { \
|
||||
DISPLAY_NAME "External Device Clock Enable" \
|
||||
}
|
||||
|
||||
proc create_phy_reset_control {tx num_of_lanes sysclk_frequency} {
|
||||
global version
|
||||
|
||||
set device [get_parameter_value DEVICE_FAMILY]
|
||||
|
||||
if {[string equal $device "Arria 10"]} {
|
||||
|
||||
add_instance phy_reset_control altera_xcvr_reset_control $version
|
||||
set_instance_property phy_reset_control SUPPRESS_ALL_WARNINGS true
|
||||
set_instance_parameter_value phy_reset_control {SYNCHRONIZE_RESET} {0}
|
||||
set_instance_parameter_value phy_reset_control {CHANNELS} $num_of_lanes
|
||||
set_instance_parameter_value phy_reset_control {SYS_CLK_IN_MHZ} $sysclk_frequency
|
||||
set_instance_parameter_value phy_reset_control {TX_PLL_ENABLE} $tx
|
||||
set_instance_parameter_value phy_reset_control {TX_ENABLE} $tx
|
||||
set_instance_parameter_value phy_reset_control {RX_ENABLE} [expr !$tx]
|
||||
|
||||
add_connection sys_clock.clk phy_reset_control.clock
|
||||
add_connection link_reset.out_reset phy_reset_control.reset
|
||||
add_connection sys_clock.clk_reset phy_reset_control.reset
|
||||
|
||||
if {$tx} {
|
||||
set_instance_parameter_value phy_reset_control {T_PLL_POWERDOWN} {1000}
|
||||
set_instance_parameter_value phy_reset_control {gui_pll_cal_busy} {1}
|
||||
set_instance_parameter_value phy_reset_control {T_TX_ANALOGRESET} {70000}
|
||||
set_instance_parameter_value phy_reset_control {T_TX_DIGITALRESET} {70000}
|
||||
|
||||
add_connection phy_reset_control.tx_ready axi_xcvr.ready
|
||||
} else {
|
||||
set_instance_parameter_value phy_reset_control {T_RX_ANALOGRESET} {70000}
|
||||
set_instance_parameter_value phy_reset_control {T_RX_DIGITALRESET} {4000}
|
||||
|
||||
add_connection phy_reset_control.rx_ready axi_xcvr.ready
|
||||
}
|
||||
|
||||
} elseif {[string equal $device "Stratix 10"]} {
|
||||
|
||||
add_instance phy_reset_control altera_xcvr_reset_control_s10 $version
|
||||
set_instance_parameter_value phy_reset_control {CHANNELS} $num_of_lanes
|
||||
set_instance_parameter_value phy_reset_control {SYS_CLK_IN_MHZ} $sysclk_frequency
|
||||
set_instance_parameter_value phy_reset_control {TX_ENABLE} $tx
|
||||
set_instance_parameter_value phy_reset_control {RX_ENABLE} [expr !$tx]
|
||||
set_instance_parameter_value phy_reset_control {REDUCED_SIM_TIME} {1}
|
||||
set_instance_parameter_value phy_reset_control {T_PLL_POWERDOWN} {1000}
|
||||
set_instance_parameter_value phy_reset_control {T_PLL_LOCK_HYST} {1000}
|
||||
|
||||
add_connection sys_clock.clk phy_reset_control.clock
|
||||
add_connection link_reset.out_reset phy_reset_control.reset
|
||||
add_connection sys_clock.clk_reset phy_reset_control.reset
|
||||
|
||||
if {$tx} {
|
||||
set_instance_parameter_value phy_reset_control {gui_pll_cal_busy} {1}
|
||||
set_instance_parameter_value phy_reset_control {TX_MANUAL_RESET} {0}
|
||||
set_instance_parameter_value phy_reset_control {T_TX_ANALOGRESET} {0}
|
||||
set_instance_parameter_value phy_reset_control {T_TX_DIGITALRESET} {20}
|
||||
|
||||
add_connection phy_reset_control.tx_ready axi_xcvr.ready
|
||||
} else {
|
||||
set_instance_parameter_value phy_reset_control {RX_MANUAL_RESET} {0}
|
||||
set_instance_parameter_value phy_reset_control {T_RX_ANALOGRESET} {40}
|
||||
set_instance_parameter_value phy_reset_control {T_RX_DIGITALRESET} {5000}
|
||||
|
||||
add_connection phy_reset_control.rx_ready axi_xcvr.ready
|
||||
}
|
||||
|
||||
} else {
|
||||
send_message error "Only Arria 10 and Stratix 10 are supported."
|
||||
}
|
||||
}
|
||||
|
||||
proc create_lane_pll {id tx_or_rx_n pllclk_frequency refclk_frequency num_lanes bonding_clocks_en} {
|
||||
|
||||
global version
|
||||
|
||||
set device_family [get_parameter_value "DEVICE_FAMILY"]
|
||||
|
||||
if {$device_family == "Arria 10"} {
|
||||
add_instance lane_pll altera_xcvr_atx_pll_a10 $version
|
||||
if {$num_lanes > 6} {
|
||||
set_instance_parameter_value lane_pll enable_mcgb {true}
|
||||
if {$bonding_clocks_en} {
|
||||
set_instance_parameter_value lane_pll {enable_bonding_clks} {true}
|
||||
set_instance_parameter_value lane_pll {mcgb_div} {1}
|
||||
set_instance_parameter_value lane_pll {set_ref_clk_div} {1}
|
||||
set_instance_parameter_value lane_pll {pma_width} {40}
|
||||
} else {
|
||||
set_instance_parameter_value lane_pll enable_hfreq_clk {true}
|
||||
}
|
||||
|
||||
add_instance glue adi_jesd204_glue 1.0
|
||||
add_connection phy_reset_control.pll_powerdown glue.in_pll_powerdown
|
||||
add_connection glue.out_pll_powerdown lane_pll.pll_powerdown
|
||||
add_connection glue.out_mcgb_rst lane_pll.mcgb_rst
|
||||
} else {
|
||||
add_connection phy_reset_control.pll_powerdown lane_pll.pll_powerdown
|
||||
}
|
||||
set_instance_parameter_value lane_pll {enable_pll_reconfig} {1}
|
||||
} elseif {$device_family == "Stratix 10"} {
|
||||
add_instance lane_pll altera_xcvr_atx_pll_s10_htile $version
|
||||
set_instance_parameter_value lane_pll {rcfg_enable} {1}
|
||||
|
||||
## tie pll_select to GND
|
||||
add_instance glue adi_jesd204_glue 1.0
|
||||
set_instance_parameter_value glue {IN_PLL_POWERDOWN_EN} {0}
|
||||
if {$tx_or_rx_n} {
|
||||
add_connection glue.out_pll_select_gnd phy_reset_control.pll_select
|
||||
}
|
||||
|
||||
} else {
|
||||
send_message error "Only Arria 10 and Stratix 10 are supported."
|
||||
}
|
||||
|
||||
set_instance_parameter_value lane_pll {rcfg_separate_avmm_busy} {1}
|
||||
set_instance_parameter_value lane_pll {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value lane_pll {set_user_identifier} $id
|
||||
set_instance_parameter_value lane_pll {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value lane_pll {set_output_clock_frequency} $pllclk_frequency
|
||||
set_instance_parameter_value lane_pll {set_auto_reference_clock_frequency} $refclk_frequency
|
||||
|
||||
add_connection lane_pll.pll_locked phy_reset_control.pll_locked
|
||||
add_connection lane_pll.pll_cal_busy phy_reset_control.pll_cal_busy
|
||||
add_connection ref_clock.out_clk lane_pll.pll_refclk0
|
||||
add_connection sys_clock.clk lane_pll.reconfig_clk0
|
||||
add_connection sys_clock.clk_reset lane_pll.reconfig_reset0
|
||||
add_interface lane_pll_reconfig avalon slave
|
||||
set_interface_property lane_pll_reconfig EXPORT_OF lane_pll.reconfig_avmm0
|
||||
}
|
||||
|
||||
proc jesd204_get_max_lane_rate {device soft_pcs} {
|
||||
if {[string range $device 0 2] == "10A"} {
|
||||
set device_speedgrade [string range $device 13 13]
|
||||
set pma_speedgrade [string range $device 8 8]
|
||||
} elseif {[string range $device 0 1] == "1S"} {
|
||||
set device_speedgrade [string range $device 13 13]
|
||||
set pma_speedgrade [string range $device 8 8]
|
||||
} else {
|
||||
# Assume fastest speed grade
|
||||
set device_speedgrade 1
|
||||
set pma_speedgrade 1
|
||||
}
|
||||
|
||||
if {$soft_pcs} {
|
||||
if {$pma_speedgrade == 1 || $pma_speedgrade == 2} {
|
||||
return "15000"
|
||||
} elseif {$pma_speedgrade == 3} {
|
||||
return "14200"
|
||||
} else {
|
||||
return "12500"
|
||||
}
|
||||
} else {
|
||||
if {$device_speedgrade == 1} {
|
||||
return "12000"
|
||||
} elseif {$device_speedgrade == 2} {
|
||||
return "9830"
|
||||
} else {
|
||||
return "8936"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc jesd204_validate {{quiet false}} {
|
||||
set soft_pcs [get_parameter_value "SOFT_PCS"]
|
||||
set input_pipeline [get_parameter_value "INPUT_PIPELINE_STAGES"]
|
||||
set device_family [get_parameter_value "DEVICE_FAMILY"]
|
||||
set device [get_parameter_value "DEVICE"]
|
||||
set lane_rate [get_parameter_value "LANE_RATE"]
|
||||
set num_of_lanes [get_parameter_value "NUM_OF_LANES"]
|
||||
set tx_or_rx_n [get_parameter_value "TX_OR_RX_N"]
|
||||
|
||||
if {$device_family != "Arria 10" && $device_family != "Stratix 10"} {
|
||||
if {!$quiet} {
|
||||
send_message error "Only Arria 10 and Startix 10 are supported."
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
set max_lane_rate [jesd204_get_max_lane_rate $device $soft_pcs]
|
||||
|
||||
if {$lane_rate < 2000 || $lane_rate > $max_lane_rate} {
|
||||
if {!$quiet} {
|
||||
send_message error "Lane rate must be in the range 2000-${max_lane_rate} Mbps."
|
||||
if {!$soft_pcs} {
|
||||
send_message error "Consider enabling soft PCS for a higher maximum lane rate."
|
||||
if {$input_pipeline} {
|
||||
send_message error "Input pipeline can be active just when soft PCS is used."
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
set_parameter_property BONDING_CLOCKS_EN VISIBLE [expr ($num_of_lanes > 6) && ($tx_or_rx_n)]
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
proc jesd204_compose {} {
|
||||
|
||||
global version
|
||||
|
||||
set id [get_parameter_value "ID"]
|
||||
set lane_rate [get_parameter_value "LANE_RATE"]
|
||||
set tx_or_rx_n [get_parameter_value "TX_OR_RX_N"]
|
||||
set num_of_lanes [get_parameter_value "NUM_OF_LANES"]
|
||||
set sysclk_frequency [get_parameter_value "SYSCLK_FREQUENCY"]
|
||||
set refclk_frequency [get_parameter_value "REFCLK_FREQUENCY"]
|
||||
set lane_map [get_parameter_value "LANE_MAP"]
|
||||
set lane_invert [get_parameter_value "LANE_INVERT"]
|
||||
set soft_pcs [get_parameter_value "SOFT_PCS"]
|
||||
set device_family [get_parameter_value "DEVICE_FAMILY"]
|
||||
set device [get_parameter_value "DEVICE"]
|
||||
set ext_device_clk_en [get_parameter_value "EXT_DEVICE_CLK_EN"]
|
||||
set bonding_clocks_en [get_parameter_value "BONDING_CLOCKS_EN"]
|
||||
set input_pipeline [get_parameter_value "INPUT_PIPELINE_STAGES"]
|
||||
|
||||
set pllclk_frequency [expr $lane_rate / 2]
|
||||
set linkclk_frequency [expr $lane_rate / 40]
|
||||
|
||||
if {![jesd204_validate true]} {
|
||||
return
|
||||
}
|
||||
|
||||
add_instance sys_clock clock_source 19.2
|
||||
set_instance_parameter_value sys_clock {clockFrequency} [expr $sysclk_frequency*1000000]
|
||||
set_instance_parameter_value sys_clock {resetSynchronousEdges} {deassert}
|
||||
add_interface sys_clk clock sink
|
||||
set_interface_property sys_clk EXPORT_OF sys_clock.clk_in
|
||||
add_interface sys_resetn reset sink
|
||||
set_interface_property sys_resetn EXPORT_OF sys_clock.clk_in_reset
|
||||
|
||||
add_instance ref_clock altera_clock_bridge $version
|
||||
set_instance_parameter_value ref_clock {EXPLICIT_CLOCK_RATE} [expr $refclk_frequency*1000000]
|
||||
add_interface ref_clk clock sink
|
||||
set_interface_property ref_clk EXPORT_OF ref_clock.in_clk
|
||||
|
||||
set outclk_name ""
|
||||
|
||||
## link clock configuration (also known as device clock, which will be used
|
||||
## by the upper layers for the data path, it can come from the PCS or external)
|
||||
|
||||
add_instance link_clock altera_clock_bridge $version
|
||||
set_instance_parameter_value link_clock {EXPLICIT_CLOCK_RATE} [expr $linkclk_frequency*1000000]
|
||||
set_instance_parameter_value link_clock {NUM_CLOCK_OUTPUTS} 2
|
||||
|
||||
add_instance link_reset altera_reset_bridge $version
|
||||
set_instance_parameter_value link_reset {NUM_RESET_OUTPUTS} 2
|
||||
|
||||
if {$device_family == "Arria 10"} {
|
||||
|
||||
add_instance link_pll altera_xcvr_fpll_a10 $version
|
||||
set_instance_parameter_value link_pll {gui_fpll_mode} {0}
|
||||
set_instance_parameter_value link_pll {gui_reference_clock_frequency} $refclk_frequency
|
||||
set_instance_parameter_value link_pll {gui_number_of_output_clocks} 1
|
||||
set_instance_parameter_value link_pll {gui_desired_outclk0_frequency} $linkclk_frequency
|
||||
set_instance_parameter_value link_pll {enable_pll_reconfig} {1}
|
||||
|
||||
set outclk_name "outclk0"
|
||||
|
||||
add_instance link_pll_reset_control altera_xcvr_reset_control $version
|
||||
set_instance_parameter_value link_pll_reset_control {SYNCHRONIZE_RESET} {0}
|
||||
set_instance_parameter_value link_pll_reset_control {SYS_CLK_IN_MHZ} $sysclk_frequency
|
||||
set_instance_parameter_value link_pll_reset_control {TX_PLL_ENABLE} {1}
|
||||
set_instance_parameter_value link_pll_reset_control {T_PLL_POWERDOWN} {1000}
|
||||
set_instance_parameter_value link_pll_reset_control {TX_ENABLE} {0}
|
||||
set_instance_parameter_value link_pll_reset_control {RX_ENABLE} {0}
|
||||
add_connection sys_clock.clk link_pll_reset_control.clock
|
||||
add_connection link_reset.out_reset link_pll_reset_control.reset
|
||||
add_connection sys_clock.clk_reset link_pll_reset_control.reset
|
||||
add_connection link_pll_reset_control.pll_powerdown link_pll.pll_powerdown
|
||||
|
||||
} elseif {$device_family == "Stratix 10"} {
|
||||
|
||||
send_message info "Instantiate a fpll_s10_htile for link_pll."
|
||||
add_instance link_pll altera_xcvr_fpll_s10_htile 19.1.1
|
||||
## Primary Use is Core mode
|
||||
set_instance_parameter_value link_pll {set_primary_use} 0
|
||||
## Basic Mode
|
||||
set_instance_parameter_value link_pll {set_prot_mode} 0
|
||||
set_instance_parameter_value link_pll {message_level} {error}
|
||||
set_instance_parameter_value link_pll {set_refclk_cnt} {1}
|
||||
set_instance_parameter_value link_pll {set_auto_reference_clock_frequency} $refclk_frequency
|
||||
set_instance_parameter_value link_pll {set_output_clock_frequency} $linkclk_frequency
|
||||
set_instance_parameter_value link_pll {set_bw_sel} {medium}
|
||||
set_instance_parameter_value link_pll {rcfg_enable} {1}
|
||||
set_instance_parameter_value link_pll {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value link_pll {set_capability_reg_enable} {1}
|
||||
|
||||
set outclk_name "outclk_div1"
|
||||
|
||||
} else {
|
||||
## Unsupported device
|
||||
send_message error "Only Arria 10 and Stratix 10 are supported."
|
||||
}
|
||||
|
||||
add_connection link_pll.$outclk_name link_clock.in_clk
|
||||
add_interface link_clk clock source
|
||||
|
||||
add_connection sys_clock.clk link_reset.clk
|
||||
add_interface link_reset reset source
|
||||
set_interface_property link_reset EXPORT_OF link_reset.out_reset_1
|
||||
|
||||
set_instance_parameter_value link_pll {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value link_pll {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value link_pll {rcfg_separate_avmm_busy} {1}
|
||||
add_connection ref_clock.out_clk link_pll.pll_refclk0
|
||||
|
||||
add_connection sys_clock.clk_reset link_pll.reconfig_reset0
|
||||
add_connection sys_clock.clk link_pll.reconfig_clk0
|
||||
|
||||
add_instance axi_xcvr axi_adxcvr 1.0
|
||||
set_instance_parameter_value axi_xcvr {ID} $id
|
||||
set_instance_parameter_value axi_xcvr {TX_OR_RX_N} $tx_or_rx_n
|
||||
set_instance_parameter_value axi_xcvr {NUM_OF_LANES} $num_of_lanes
|
||||
|
||||
add_connection sys_clock.clk axi_xcvr.s_axi_clock
|
||||
add_connection sys_clock.clk_reset axi_xcvr.s_axi_reset
|
||||
add_connection axi_xcvr.if_up_rst link_reset.in_reset
|
||||
add_connection link_pll.pll_locked axi_xcvr.core_pll_locked
|
||||
|
||||
add_interface link_management axi4lite slave
|
||||
set_interface_property link_management EXPORT_OF axi_xcvr.s_axi
|
||||
|
||||
add_interface link_pll_reconfig avalon slave
|
||||
set_interface_property link_pll_reconfig EXPORT_OF link_pll.reconfig_avmm0
|
||||
set_interface_property link_pll_reconfig associatedClock sys_clk
|
||||
set_interface_property link_pll_reconfig associatedReset sys_resetn
|
||||
|
||||
|
||||
create_phy_reset_control $tx_or_rx_n $num_of_lanes $sysclk_frequency
|
||||
|
||||
add_instance phy jesd204_phy 1.0
|
||||
set_instance_parameter_value phy ID $id
|
||||
set_instance_parameter_value phy DEVICE $device_family
|
||||
set_instance_parameter_value phy SOFT_PCS $soft_pcs
|
||||
set_instance_parameter_value phy TX_OR_RX_N $tx_or_rx_n
|
||||
set_instance_parameter_value phy LANE_RATE $lane_rate
|
||||
set_instance_parameter_value phy REFCLK_FREQUENCY $refclk_frequency
|
||||
set_instance_parameter_value phy NUM_OF_LANES $num_of_lanes
|
||||
set_instance_parameter_value phy REGISTER_INPUTS $input_pipeline
|
||||
set_instance_parameter_value phy LANE_INVERT $lane_invert
|
||||
set_instance_parameter_value phy EXT_DEVICE_CLK_EN $ext_device_clk_en
|
||||
set_instance_parameter_value phy BONDING_CLOCKS_EN $bonding_clocks_en
|
||||
|
||||
add_connection link_clock.out_clk_1 phy.link_clk
|
||||
add_connection link_reset.out_reset phy.link_reset
|
||||
add_connection sys_clock.clk phy.reconfig_clk
|
||||
add_connection sys_clock.clk_reset phy.reconfig_reset
|
||||
|
||||
## connect the required device clock
|
||||
|
||||
if {$ext_device_clk_en} {
|
||||
add_instance ext_device_clock altera_clock_bridge $version
|
||||
set_instance_parameter_value ext_device_clock {EXPLICIT_CLOCK_RATE} [expr $linkclk_frequency*1000000]
|
||||
set_instance_parameter_value ext_device_clock {NUM_CLOCK_OUTPUTS} 2
|
||||
add_interface device_clk clock sink
|
||||
set_interface_property device_clk EXPORT_OF ext_device_clock.in_clk
|
||||
add_connection ext_device_clock.out_clk phy.device_clk
|
||||
set_interface_property link_clk EXPORT_OF ext_device_clock.out_clk_1
|
||||
} else {
|
||||
set_interface_property link_clk EXPORT_OF link_clock.out_clk
|
||||
}
|
||||
|
||||
set phy_reset_intfs_s10 {analogreset_stat digitalreset_stat}
|
||||
|
||||
if {$tx_or_rx_n} {
|
||||
set tx_rx "tx"
|
||||
set data_direction sink
|
||||
set jesd204_intfs {config control ilas_config event status}
|
||||
set phy_reset_intfs {analogreset digitalreset cal_busy}
|
||||
|
||||
create_lane_pll $id $tx_or_rx_n $pllclk_frequency $refclk_frequency $num_of_lanes $bonding_clocks_en
|
||||
if {$num_of_lanes > 6} {
|
||||
if {$bonding_clocks_en} {
|
||||
add_connection lane_pll.tx_bonding_clocks phy.bonding_clocks
|
||||
} else {
|
||||
add_connection lane_pll.tx_serial_clk phy.serial_clk_x1
|
||||
add_connection lane_pll.mcgb_serial_clk phy.serial_clk_xN
|
||||
}
|
||||
} else {
|
||||
add_connection lane_pll.tx_serial_clk phy.serial_clk_x1
|
||||
}
|
||||
} else {
|
||||
set tx_rx "rx"
|
||||
set data_direction source
|
||||
set jesd204_intfs {config ilas_config event status}
|
||||
set phy_reset_intfs {analogreset digitalreset cal_busy is_lockedtodata}
|
||||
|
||||
add_connection ref_clock.out_clk phy.ref_clk
|
||||
}
|
||||
|
||||
add_instance axi_jesd204_${tx_rx} axi_jesd204_${tx_rx} 1.0
|
||||
set_instance_parameter_value axi_jesd204_${tx_rx} {NUM_LANES} $num_of_lanes
|
||||
|
||||
add_connection sys_clock.clk axi_jesd204_${tx_rx}.s_axi_clock
|
||||
add_connection sys_clock.clk_reset axi_jesd204_${tx_rx}.s_axi_reset
|
||||
|
||||
add_instance jesd204_${tx_rx} jesd204_${tx_rx} 1.0
|
||||
set_instance_parameter_value jesd204_${tx_rx} {NUM_LANES} $num_of_lanes
|
||||
|
||||
if {$ext_device_clk_en} {
|
||||
add_connection ext_device_clock.out_clk axi_jesd204_${tx_rx}.core_clock
|
||||
add_connection ext_device_clock.out_clk jesd204_${tx_rx}.clock
|
||||
} else {
|
||||
add_connection link_clock.out_clk_1 axi_jesd204_${tx_rx}.core_clock
|
||||
add_connection link_clock.out_clk_1 jesd204_${tx_rx}.clock
|
||||
}
|
||||
|
||||
add_connection link_reset.out_reset axi_jesd204_${tx_rx}.core_reset_ext
|
||||
add_connection axi_jesd204_${tx_rx}.core_reset jesd204_${tx_rx}.reset
|
||||
|
||||
foreach intf $jesd204_intfs {
|
||||
add_connection axi_jesd204_${tx_rx}.${intf} jesd204_${tx_rx}.${intf}
|
||||
}
|
||||
|
||||
foreach intf $phy_reset_intfs {
|
||||
add_connection phy_reset_control.${tx_rx}_${intf} phy.${intf}
|
||||
}
|
||||
|
||||
## connect phy_reset_control interfaces specific to Stratix 10
|
||||
if {$device_family == "Stratix 10"} {
|
||||
foreach intf $phy_reset_intfs_s10 {
|
||||
add_connection phy_reset_control.${tx_rx}_${intf} phy.${intf}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set lane_map [regexp -all -inline {\S+} $lane_map]
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
if {$lane_map != {}} {
|
||||
set j [lindex $lane_map $i]
|
||||
} else {
|
||||
set j $i
|
||||
}
|
||||
|
||||
add_connection jesd204_${tx_rx}.${tx_rx}_phy${j} phy.phy_${i}
|
||||
}
|
||||
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface phy_reconfig_${i} avalon slave
|
||||
set_interface_property phy_reconfig_${i} EXPORT_OF phy.reconfig_avmm_${i}
|
||||
}
|
||||
|
||||
add_interface interrupt interrupt end
|
||||
set_interface_property interrupt EXPORT_OF axi_jesd204_${tx_rx}.interrupt
|
||||
add_interface link_reconfig axi4lite slave
|
||||
set_interface_property link_reconfig EXPORT_OF axi_jesd204_${tx_rx}.s_axi
|
||||
|
||||
add_interface link_data avalon_streaming $data_direction
|
||||
set_interface_property link_data EXPORT_OF jesd204_${tx_rx}.${tx_rx}_data
|
||||
|
||||
if {!$tx_or_rx_n} {
|
||||
add_interface link_sof conduit end
|
||||
set_interface_property link_sof EXPORT_OF jesd204_rx.rx_sof
|
||||
}
|
||||
|
||||
add_interface sysref conduit end
|
||||
set_interface_property sysref EXPORT_OF jesd204_${tx_rx}.sysref
|
||||
|
||||
add_interface sync conduit end
|
||||
set_interface_property sync EXPORT_OF jesd204_${tx_rx}.sync
|
||||
|
||||
add_interface serial_data conduit end
|
||||
set_interface_property serial_data EXPORT_OF phy.serial_data
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := avl_adxcfg
|
||||
|
||||
INTEL_DEPS += avl_adxcfg.v
|
||||
INTEL_DEPS += avl_adxcfg_hw.tcl
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,166 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module avl_adxcfg #(
|
||||
|
||||
parameter ADDRESS_WIDTH = 10) (
|
||||
|
||||
// reconfig sharing
|
||||
|
||||
input rcfg_clk,
|
||||
input rcfg_reset_n,
|
||||
|
||||
input rcfg_in_read_0,
|
||||
input rcfg_in_write_0,
|
||||
input [ADDRESS_WIDTH-1:0] rcfg_in_address_0,
|
||||
input [31:0] rcfg_in_writedata_0,
|
||||
output [31:0] rcfg_in_readdata_0,
|
||||
output rcfg_in_waitrequest_0,
|
||||
|
||||
input rcfg_in_read_1,
|
||||
input rcfg_in_write_1,
|
||||
input [ADDRESS_WIDTH-1:0] rcfg_in_address_1,
|
||||
input [31:0] rcfg_in_writedata_1,
|
||||
output [31:0] rcfg_in_readdata_1,
|
||||
output rcfg_in_waitrequest_1,
|
||||
|
||||
output rcfg_out_read_0,
|
||||
output rcfg_out_write_0,
|
||||
output [ADDRESS_WIDTH-1:0] rcfg_out_address_0,
|
||||
output [31:0] rcfg_out_writedata_0,
|
||||
input [31:0] rcfg_out_readdata_0,
|
||||
input rcfg_out_waitrequest_0,
|
||||
|
||||
output rcfg_out_read_1,
|
||||
output rcfg_out_write_1,
|
||||
output [ADDRESS_WIDTH-1:0] rcfg_out_address_1,
|
||||
output [31:0] rcfg_out_writedata_1,
|
||||
input [31:0] rcfg_out_readdata_1,
|
||||
input rcfg_out_waitrequest_1);
|
||||
|
||||
// internal registers
|
||||
|
||||
reg [ 1:0] rcfg_select = 'd0;
|
||||
reg rcfg_read_int = 'd0;
|
||||
reg rcfg_write_int = 'd0;
|
||||
reg [ADDRESS_WIDTH-1:0] rcfg_address_int = 'd0;
|
||||
reg [31:0] rcfg_writedata_int = 'd0;
|
||||
reg [31:0] rcfg_readdata_int = 'd0;
|
||||
reg rcfg_waitrequest_int_0 = 'd1;
|
||||
reg rcfg_waitrequest_int_1 = 'd1;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [31:0] rcfg_readdata_s;
|
||||
wire rcfg_waitrequest_s;
|
||||
|
||||
// xcvr sharing requires same bus (sw must make sure they are mutually exclusive access).
|
||||
|
||||
assign rcfg_out_read_0 = rcfg_read_int;
|
||||
assign rcfg_out_write_0 = rcfg_write_int;
|
||||
assign rcfg_out_address_0 = rcfg_address_int;
|
||||
assign rcfg_out_writedata_0 = rcfg_writedata_int;
|
||||
assign rcfg_out_read_1 = rcfg_read_int;
|
||||
assign rcfg_out_write_1 = rcfg_write_int;
|
||||
assign rcfg_out_address_1 = rcfg_address_int;
|
||||
assign rcfg_out_writedata_1 = rcfg_writedata_int;
|
||||
assign rcfg_in_readdata_0 = rcfg_readdata_int;
|
||||
assign rcfg_in_readdata_1 = rcfg_readdata_int;
|
||||
assign rcfg_in_waitrequest_0 = rcfg_waitrequest_int_0;
|
||||
assign rcfg_in_waitrequest_1 = rcfg_waitrequest_int_1;
|
||||
|
||||
assign rcfg_readdata_s = rcfg_out_readdata_1 & rcfg_out_readdata_0;
|
||||
assign rcfg_waitrequest_s = rcfg_out_waitrequest_1 & rcfg_out_waitrequest_0;
|
||||
|
||||
always @(negedge rcfg_reset_n or posedge rcfg_clk) begin
|
||||
if (rcfg_reset_n == 0) begin
|
||||
rcfg_select <= 2'd0;
|
||||
rcfg_read_int <= 1'd0;
|
||||
rcfg_write_int <= 1'd0;
|
||||
rcfg_address_int <= 'd0;
|
||||
rcfg_writedata_int <= 32'd0;
|
||||
rcfg_readdata_int <= 32'd0;
|
||||
rcfg_waitrequest_int_0 <= 1'b1;
|
||||
rcfg_waitrequest_int_1 <= 1'b1;
|
||||
end else begin
|
||||
if (rcfg_select[1] == 1'b1) begin
|
||||
if (rcfg_waitrequest_s == 1'b0) begin
|
||||
rcfg_select <= 2'd0;
|
||||
rcfg_read_int <= 1'b0;
|
||||
rcfg_write_int <= 1'b0;
|
||||
rcfg_address_int <= 'd0;
|
||||
rcfg_writedata_int <= 32'd0;
|
||||
end
|
||||
rcfg_readdata_int <= rcfg_readdata_s;
|
||||
rcfg_waitrequest_int_0 <= rcfg_waitrequest_s | rcfg_select[0];
|
||||
rcfg_waitrequest_int_1 <= rcfg_waitrequest_s | ~rcfg_select[0];
|
||||
end else if ((rcfg_in_read_0 == 1'b1) || (rcfg_in_write_0 == 1'b1)) begin
|
||||
rcfg_select <= 2'b10;
|
||||
rcfg_read_int <= rcfg_in_read_0;
|
||||
rcfg_write_int <= rcfg_in_write_0;
|
||||
rcfg_address_int <= rcfg_in_address_0;
|
||||
rcfg_writedata_int <= rcfg_in_writedata_0;
|
||||
rcfg_readdata_int <= 32'd0;
|
||||
rcfg_waitrequest_int_0 <= 1'b1;
|
||||
rcfg_waitrequest_int_1 <= 1'b1;
|
||||
end else if ((rcfg_in_read_1 == 1'b1) || (rcfg_in_write_1 == 1'b1)) begin
|
||||
rcfg_select <= 2'b11;
|
||||
rcfg_read_int <= rcfg_in_read_1;
|
||||
rcfg_write_int <= rcfg_in_write_1;
|
||||
rcfg_address_int <= rcfg_in_address_1;
|
||||
rcfg_writedata_int <= rcfg_in_writedata_1;
|
||||
rcfg_readdata_int <= 32'd0;
|
||||
rcfg_waitrequest_int_0 <= 1'b1;
|
||||
rcfg_waitrequest_int_1 <= 1'b1;
|
||||
end else begin
|
||||
rcfg_select <= 2'd0;
|
||||
rcfg_read_int <= 1'd0;
|
||||
rcfg_write_int <= 1'd0;
|
||||
rcfg_address_int <= 'd0;
|
||||
rcfg_writedata_int <= 32'd0;
|
||||
rcfg_readdata_int <= 32'd0;
|
||||
rcfg_waitrequest_int_0 <= 1'b1;
|
||||
rcfg_waitrequest_int_1 <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
package require qsys
|
||||
|
||||
set_module_property NAME avl_adxcfg
|
||||
set_module_property DESCRIPTION "Avalon ADXCFG Core"
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
set_module_property DISPLAY_NAME avl_adxcfg
|
||||
set_module_property ELABORATION_CALLBACK elaborate
|
||||
|
||||
# files
|
||||
|
||||
add_fileset quartus_synth QUARTUS_SYNTH "" ""
|
||||
set_fileset_property quartus_synth TOP_LEVEL avl_adxcfg
|
||||
add_fileset_file avl_adxcfg.v VERILOG PATH avl_adxcfg.v TOP_LEVEL_FILE
|
||||
|
||||
# add exportable hdl parameter
|
||||
|
||||
add_parameter ADDRESS_WIDTH INTEGER 10
|
||||
set_parameter_property ADDRESS_WIDTH AFFECTS_GENERATION false
|
||||
set_parameter_property ADDRESS_WIDTH HDL_PARAMETER true
|
||||
|
||||
# reconfiguration interfaces
|
||||
|
||||
add_interface rcfg_clk clock sink
|
||||
add_interface_port rcfg_clk rcfg_clk clk Input 1
|
||||
|
||||
add_interface rcfg_reset_n reset end
|
||||
set_interface_property rcfg_reset_n associatedClock rcfg_clk
|
||||
add_interface_port rcfg_reset_n rcfg_reset_n reset_n Input 1
|
||||
|
||||
proc elaborate {} {
|
||||
for {set n 0} {$n < 2} {incr n} {
|
||||
|
||||
add_interface rcfg_s${n} avalon slave
|
||||
add_interface rcfg_m${n} avalon master
|
||||
|
||||
add_interface_port rcfg_s${n} rcfg_in_read_${n} read Input 1
|
||||
add_interface_port rcfg_s${n} rcfg_in_write_${n} write Input 1
|
||||
add_interface_port rcfg_s${n} rcfg_in_address_${n} address Input [get_parameter_value ADDRESS_WIDTH]
|
||||
add_interface_port rcfg_s${n} rcfg_in_writedata_${n} writedata Input 32
|
||||
add_interface_port rcfg_s${n} rcfg_in_readdata_${n} readdata Output 32
|
||||
add_interface_port rcfg_s${n} rcfg_in_waitrequest_${n} waitrequest Output 1
|
||||
add_interface_port rcfg_m${n} rcfg_out_read_${n} read Output 1
|
||||
add_interface_port rcfg_m${n} rcfg_out_write_${n} write Output 1
|
||||
add_interface_port rcfg_m${n} rcfg_out_address_${n} address Output [get_parameter_value ADDRESS_WIDTH]
|
||||
add_interface_port rcfg_m${n} rcfg_out_writedata_${n} writedata Output 32
|
||||
add_interface_port rcfg_m${n} rcfg_out_readdata_${n} readdata Input 32
|
||||
add_interface_port rcfg_m${n} rcfg_out_waitrequest_${n} waitrequest Input 1
|
||||
|
||||
set_interface_property rcfg_s${n} associatedClock rcfg_clk
|
||||
set_interface_property rcfg_s${n} associatedReset rcfg_reset_n
|
||||
set_interface_property rcfg_s${n} addressUnits WORDS
|
||||
set_interface_property rcfg_s${n} burstCountUnits WORDS
|
||||
set_interface_property rcfg_s${n} explicitAddressSpan 0
|
||||
set_interface_property rcfg_m${n} associatedClock rcfg_clk
|
||||
set_interface_property rcfg_m${n} associatedReset rcfg_reset_n
|
||||
set_interface_property rcfg_m${n} addressUnits WORDS
|
||||
set_interface_property rcfg_m${n} burstCountUnits WORDS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := avl_adxcvr
|
||||
|
||||
INTEL_DEPS += avl_adxcvr_hw.tcl
|
||||
|
||||
INTEL_LIB_DEPS += intel/avl_adxcvr_octet_swap
|
||||
INTEL_LIB_DEPS += intel/avl_adxphy
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,355 @@
|
||||
|
||||
package require qsys
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
ad_ip_create avl_adxcvr {Avalon ADXCVR Core}
|
||||
set_module_property COMPOSITION_CALLBACK p_avl_adxcvr
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE_FAMILY STRING {Arria 10}
|
||||
ad_ip_parameter TX_OR_RX_N INTEGER 0 false
|
||||
ad_ip_parameter ID INTEGER 0 false
|
||||
ad_ip_parameter PCS_CONFIG STRING "JESD_PCS_CFG2" false
|
||||
ad_ip_parameter LANE_RATE FLOAT 10000 false
|
||||
ad_ip_parameter SYSCLK_FREQUENCY FLOAT 100.0 false
|
||||
ad_ip_parameter REFCLK_FREQUENCY FLOAT 500.0 false
|
||||
ad_ip_parameter NUM_OF_LANES INTEGER 4 false
|
||||
ad_ip_parameter NUM_OF_CONVS INTEGER 2 false
|
||||
ad_ip_parameter FRM_BCNT INTEGER 1 false
|
||||
ad_ip_parameter FRM_SCNT INTEGER 1 false
|
||||
ad_ip_parameter MF_FCNT INTEGER 32 false
|
||||
ad_ip_parameter HD INTEGER 1 false
|
||||
ad_ip_parameter TX_LANE_MAP STRING "" false
|
||||
|
||||
set_parameter_property LANE_RATE DISPLAY_UNITS "Mbps"
|
||||
set_parameter_property SYSCLK_FREQUENCY UNITS Megahertz
|
||||
set_parameter_property REFCLK_FREQUENCY UNITS Megahertz
|
||||
|
||||
proc p_avl_adxcvr {} {
|
||||
|
||||
set m_id [get_parameter_value "ID"]
|
||||
set m_lane_rate [get_parameter_value "LANE_RATE"]
|
||||
set m_pcs_config [get_parameter_value "PCS_CONFIG"]
|
||||
set m_tx_or_rx_n [get_parameter_value "TX_OR_RX_N"]
|
||||
set m_num_of_lanes [get_parameter_value "NUM_OF_LANES"]
|
||||
set m_device_family [get_parameter_value "DEVICE_FAMILY"]
|
||||
set m_sysclk_frequency [get_parameter_value "SYSCLK_FREQUENCY"]
|
||||
set m_refclk_frequency [get_parameter_value "REFCLK_FREQUENCY"]
|
||||
set m_num_of_convs [get_parameter_value "NUM_OF_CONVS"]
|
||||
set m_frm_bcnt [get_parameter_value "FRM_BCNT"]
|
||||
set m_frm_scnt [get_parameter_value "FRM_SCNT"]
|
||||
set m_mf_fcnt [get_parameter_value "MF_FCNT"]
|
||||
set m_hd [get_parameter_value "HD"]
|
||||
set m_tx_lane_map [get_parameter_value "TX_LANE_MAP"]
|
||||
|
||||
set m_pllclk_frequency [expr $m_lane_rate / 2]
|
||||
set m_coreclk_frequency [expr $m_lane_rate / 40]
|
||||
|
||||
add_instance sys_clk clock_source
|
||||
set_instance_parameter_value sys_clk {clockFrequency} [expr $m_sysclk_frequency*1000000]
|
||||
add_interface sys_clk clock sink
|
||||
set_interface_property sys_clk EXPORT_OF sys_clk.clk_in
|
||||
add_interface sys_resetn reset sink
|
||||
set_interface_property sys_resetn EXPORT_OF sys_clk.clk_in_reset
|
||||
|
||||
add_instance xcvr_rst altera_reset_bridge
|
||||
add_connection sys_clk.clk xcvr_rst.clk
|
||||
add_interface rst reset sink
|
||||
set_interface_property rst EXPORT_OF xcvr_rst.in_reset
|
||||
|
||||
add_instance ref_clk altera_clock_bridge
|
||||
set_instance_parameter_value ref_clk {EXPLICIT_CLOCK_RATE} [expr $m_refclk_frequency*1000000]
|
||||
add_interface ref_clk clock sink
|
||||
set_interface_property ref_clk EXPORT_OF ref_clk.in_clk
|
||||
|
||||
add_instance fpll_rst_control altera_xcvr_reset_control
|
||||
set_instance_parameter_value fpll_rst_control {SYS_CLK_IN_MHZ} $m_sysclk_frequency
|
||||
set_instance_parameter_value fpll_rst_control {TX_PLL_ENABLE} {1}
|
||||
set_instance_parameter_value fpll_rst_control {T_PLL_POWERDOWN} {1000}
|
||||
set_instance_parameter_value fpll_rst_control {TX_ENABLE} {0}
|
||||
set_instance_parameter_value fpll_rst_control {RX_ENABLE} {0}
|
||||
add_connection sys_clk.clk fpll_rst_control.clock
|
||||
add_connection xcvr_rst.out_reset fpll_rst_control.reset
|
||||
add_connection sys_clk.clk_reset fpll_rst_control.reset
|
||||
|
||||
add_instance core_pll altera_xcvr_fpll_a10
|
||||
set_instance_parameter_value core_pll {gui_fpll_mode} {0}
|
||||
set_instance_parameter_value core_pll {gui_reference_clock_frequency} $m_refclk_frequency
|
||||
set_instance_parameter_value core_pll {gui_number_of_output_clocks} 2
|
||||
set_instance_parameter_value core_pll {gui_enable_phase_alignment} 1
|
||||
set_instance_parameter_value core_pll {gui_desired_outclk0_frequency} $m_coreclk_frequency
|
||||
set m_pfdclk_frequency [get_instance_parameter_value core_pll gui_pfd_frequency]
|
||||
set_instance_parameter_value core_pll {gui_desired_outclk1_frequency} $m_pfdclk_frequency
|
||||
set_instance_parameter_value core_pll {enable_pll_reconfig} {1}
|
||||
set_instance_parameter_value core_pll {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value core_pll {set_csr_soft_logic_enable} {1}
|
||||
add_connection ref_clk.out_clk core_pll.pll_refclk0
|
||||
add_connection fpll_rst_control.pll_powerdown core_pll.pll_powerdown
|
||||
add_interface core_pll_locked conduit end
|
||||
set_interface_property core_pll_locked EXPORT_OF core_pll.pll_locked
|
||||
add_connection sys_clk.clk_reset core_pll.reconfig_reset0
|
||||
add_connection sys_clk.clk core_pll.reconfig_clk0
|
||||
add_interface core_pll_reconfig avalon slave
|
||||
set_interface_property core_pll_reconfig EXPORT_OF core_pll.reconfig_avmm0
|
||||
|
||||
add_instance core_clk altera_clock_bridge
|
||||
set_instance_parameter_value core_clk {EXPLICIT_CLOCK_RATE} [expr $m_coreclk_frequency*1000000]
|
||||
add_connection core_pll.outclk0 core_clk.in_clk
|
||||
add_interface core_clk clock source
|
||||
set_interface_property core_clk EXPORT_OF core_clk.out_clk
|
||||
|
||||
add_instance octet_swap avl_adxcvr_octet_swap
|
||||
set_instance_parameter_value octet_swap NUM_OF_LANES $m_num_of_lanes
|
||||
set_instance_parameter_value octet_swap TX_OR_RX_N m_tx_or_rx_n
|
||||
add_connection core_pll.outclk0 octet_swap.clock
|
||||
add_connection sys_clk.clk_reset octet_swap.reset
|
||||
|
||||
if {$m_tx_or_rx_n == 1} {
|
||||
|
||||
add_instance rst_control altera_xcvr_reset_control
|
||||
set_instance_parameter_value rst_control {CHANNELS} $m_num_of_lanes
|
||||
set_instance_parameter_value rst_control {SYS_CLK_IN_MHZ} $m_sysclk_frequency
|
||||
set_instance_parameter_value rst_control {TX_PLL_ENABLE} {1}
|
||||
set_instance_parameter_value rst_control {T_PLL_POWERDOWN} {1000}
|
||||
set_instance_parameter_value rst_control {TX_ENABLE} {1}
|
||||
set_instance_parameter_value rst_control {T_TX_ANALOGRESET} {70000}
|
||||
set_instance_parameter_value rst_control {T_TX_DIGITALRESET} {70000}
|
||||
set_instance_parameter_value rst_control {gui_pll_cal_busy} {1}
|
||||
set_instance_parameter_value rst_control {RX_ENABLE} {0}
|
||||
add_connection sys_clk.clk rst_control.clock
|
||||
add_connection xcvr_rst.out_reset rst_control.reset
|
||||
add_connection sys_clk.clk_reset rst_control.reset
|
||||
add_interface ready conduit end
|
||||
set_interface_property ready EXPORT_OF rst_control.tx_ready
|
||||
|
||||
add_instance lane_pll altera_xcvr_atx_pll_a10
|
||||
set_instance_parameter_value lane_pll {enable_pll_reconfig} {1}
|
||||
set_instance_parameter_value lane_pll {rcfg_separate_avmm_busy} {1}
|
||||
set_instance_parameter_value lane_pll {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value lane_pll {set_user_identifier} $m_id
|
||||
set_instance_parameter_value lane_pll {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value lane_pll {set_output_clock_frequency} $m_pllclk_frequency
|
||||
set_instance_parameter_value lane_pll {set_auto_reference_clock_frequency} $m_refclk_frequency
|
||||
add_connection rst_control.pll_powerdown lane_pll.pll_powerdown
|
||||
add_connection lane_pll.pll_locked rst_control.pll_locked
|
||||
add_connection lane_pll.pll_cal_busy rst_control.pll_cal_busy
|
||||
add_connection ref_clk.out_clk lane_pll.pll_refclk0
|
||||
add_connection sys_clk.clk lane_pll.reconfig_clk0
|
||||
add_connection sys_clk.clk_reset lane_pll.reconfig_reset0
|
||||
add_interface lane_pll_reconfig avalon slave
|
||||
set_interface_property lane_pll_reconfig EXPORT_OF lane_pll.reconfig_avmm0
|
||||
|
||||
add_instance jesd204_ip altera_jesd204
|
||||
set_instance_parameter_value jesd204_ip {wrapper_opt} {base}
|
||||
set_instance_parameter_value jesd204_ip {DATA_PATH} {TX}
|
||||
set_instance_parameter_value jesd204_ip {lane_rate} $m_lane_rate
|
||||
set_instance_parameter_value jesd204_ip {L} $m_num_of_lanes
|
||||
set_instance_parameter_value jesd204_ip {M} $m_num_of_convs
|
||||
set_instance_parameter_value jesd204_ip {GUI_EN_CFG_F} {1}
|
||||
set_instance_parameter_value jesd204_ip {GUI_CFG_F} $m_frm_bcnt
|
||||
set_instance_parameter_value jesd204_ip {N} {16}
|
||||
set_instance_parameter_value jesd204_ip {N_PRIME} {16}
|
||||
set_instance_parameter_value jesd204_ip {S} $m_frm_scnt
|
||||
set_instance_parameter_value jesd204_ip {K} $m_mf_fcnt
|
||||
set_instance_parameter_value jesd204_ip {SCR} {1}
|
||||
set_instance_parameter_value jesd204_ip {HD} $m_hd
|
||||
add_connection core_pll.outclk0 jesd204_ip.txlink_clk
|
||||
add_connection sys_clk.clk_reset jesd204_ip.txlink_rst_n
|
||||
|
||||
add_connection octet_swap.out jesd204_ip.jesd204_tx_link
|
||||
add_interface ip_data avalon_streaming sink
|
||||
set_interface_property ip_data EXPORT_OF octet_swap.in
|
||||
|
||||
add_connection sys_clk.clk jesd204_ip.jesd204_tx_avs_clk
|
||||
add_connection sys_clk.clk_reset jesd204_ip.jesd204_tx_avs_rst_n
|
||||
add_interface ip_reconfig avalon slave
|
||||
set_interface_property ip_reconfig EXPORT_OF jesd204_ip.jesd204_tx_avs
|
||||
add_interface sysref conduit end
|
||||
set_interface_property sysref EXPORT_OF jesd204_ip.sysref
|
||||
add_interface sync conduit end
|
||||
set_interface_property sync EXPORT_OF jesd204_ip.sync_n
|
||||
add_connection jesd204_ip.dev_sync_n jesd204_ip.mdev_sync_n
|
||||
|
||||
add_instance avl_xphy avl_adxphy
|
||||
set_instance_parameter_value avl_xphy {TX_OR_RX_N} {1}
|
||||
set_instance_parameter_value avl_xphy {NUM_OF_LANES} $m_num_of_lanes
|
||||
add_connection rst_control.tx_analogreset avl_xphy.tx_core_analogreset
|
||||
add_connection rst_control.tx_digitalreset avl_xphy.tx_core_digitalreset
|
||||
add_connection avl_xphy.tx_core_cal_busy rst_control.tx_cal_busy
|
||||
add_connection avl_xphy.tx_ip_cal_busy jesd204_ip.tx_cal_busy
|
||||
add_connection avl_xphy.tx_ip_pcfifo_full jesd204_ip.phy_csr_tx_pcfifo_full
|
||||
add_connection avl_xphy.tx_ip_pcfifo_empty jesd204_ip.phy_csr_tx_pcfifo_empty
|
||||
add_connection jesd204_ip.jesd204_tx_pcs_data avl_xphy.tx_ip_pcs_data
|
||||
add_connection jesd204_ip.jesd204_tx_pcs_kchar_data avl_xphy.tx_ip_pcs_kchar_data
|
||||
add_connection jesd204_ip.phy_tx_elecidle avl_xphy.tx_ip_elecidle
|
||||
add_connection jesd204_ip.csr_lane_polarity avl_xphy.tx_ip_csr_lane_polarity
|
||||
add_connection jesd204_ip.csr_lane_powerdown avl_xphy.tx_ip_csr_lane_powerdown
|
||||
add_connection jesd204_ip.csr_bit_reversal avl_xphy.tx_ip_csr_bit_reversal
|
||||
add_connection jesd204_ip.csr_byte_reversal avl_xphy.tx_ip_csr_byte_reversal
|
||||
|
||||
set lane_map [regexp -all -inline {\S+} $m_tx_lane_map]
|
||||
|
||||
for {set n 0} {$n < $m_num_of_lanes} {incr n} {
|
||||
|
||||
add_instance phy_${n} altera_jesd204
|
||||
set_instance_parameter_value phy_${n} {wrapper_opt} {phy}
|
||||
set_instance_parameter_value phy_${n} {DATA_PATH} {TX}
|
||||
set_instance_parameter_value phy_${n} {lane_rate} $m_lane_rate
|
||||
set_instance_parameter_value phy_${n} {PCS_CONFIG} $m_pcs_config
|
||||
set_instance_parameter_value phy_${n} {bonded_mode} {non_bonded}
|
||||
set_instance_parameter_value phy_${n} {pll_reconfig_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {set_user_identifier} $m_id
|
||||
set_instance_parameter_value phy_${n} {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {L} 1
|
||||
add_connection core_pll.outclk0 phy_${n}.txlink_clk
|
||||
add_connection sys_clk.clk_reset phy_${n}.txlink_rst_n
|
||||
add_interface tx_data_${n} conduit end
|
||||
set_interface_property tx_data_${n} EXPORT_OF phy_${n}.tx_serial_data
|
||||
add_connection avl_xphy.tx_phy${n}_analogreset phy_${n}.tx_analogreset
|
||||
add_connection avl_xphy.tx_phy${n}_digitalreset phy_${n}.tx_digitalreset
|
||||
add_connection lane_pll.tx_serial_clk phy_${n}.tx_serial_clk0
|
||||
|
||||
add_connection sys_clk.clk phy_${n}.reconfig_clk
|
||||
add_connection sys_clk.clk_reset phy_${n}.reconfig_reset
|
||||
add_interface phy_reconfig_${n} avalon slave
|
||||
set_interface_property phy_reconfig_${n} EXPORT_OF phy_${n}.reconfig_avmm
|
||||
|
||||
if {$lane_map != {}} {
|
||||
set m [lindex $lane_map $n]
|
||||
} else {
|
||||
set m $n
|
||||
}
|
||||
|
||||
add_connection phy_${n}.tx_cal_busy avl_xphy.tx_phy${m}_cal_busy
|
||||
add_connection phy_${n}.phy_csr_tx_pcfifo_full avl_xphy.tx_phy${m}_pcfifo_full
|
||||
add_connection phy_${n}.phy_csr_tx_pcfifo_empty avl_xphy.tx_phy${m}_pcfifo_empty
|
||||
add_connection avl_xphy.tx_phy${m}_pcs_data phy_${n}.jesd204_tx_pcs_data
|
||||
add_connection avl_xphy.tx_phy${m}_pcs_kchar_data phy_${n}.jesd204_tx_pcs_kchar_data
|
||||
add_connection avl_xphy.tx_phy${m}_elecidle phy_${n}.phy_tx_elecidle
|
||||
add_connection avl_xphy.tx_phy${m}_csr_lane_polarity phy_${n}.csr_lane_polarity
|
||||
add_connection avl_xphy.tx_phy${m}_csr_lane_powerdown phy_${n}.csr_lane_powerdown
|
||||
add_connection avl_xphy.tx_phy${m}_csr_bit_reversal phy_${n}.csr_bit_reversal
|
||||
add_connection avl_xphy.tx_phy${m}_csr_byte_reversal phy_${n}.csr_byte_reversal
|
||||
}
|
||||
}
|
||||
|
||||
if {$m_tx_or_rx_n == 0} {
|
||||
|
||||
add_instance rst_control altera_xcvr_reset_control
|
||||
set_instance_parameter_value rst_control {CHANNELS} $m_num_of_lanes
|
||||
set_instance_parameter_value rst_control {SYS_CLK_IN_MHZ} $m_sysclk_frequency
|
||||
set_instance_parameter_value rst_control {TX_PLL_ENABLE} {0}
|
||||
set_instance_parameter_value rst_control {TX_ENABLE} {0}
|
||||
set_instance_parameter_value rst_control {RX_ENABLE} {1}
|
||||
set_instance_parameter_value rst_control {T_RX_ANALOGRESET} {70000}
|
||||
set_instance_parameter_value rst_control {T_RX_DIGITALRESET} {4000}
|
||||
add_connection sys_clk.clk rst_control.clock
|
||||
add_connection xcvr_rst.out_reset rst_control.reset
|
||||
add_connection sys_clk.clk_reset rst_control.reset
|
||||
add_interface ready conduit end
|
||||
set_interface_property ready EXPORT_OF rst_control.rx_ready
|
||||
|
||||
add_instance jesd204_ip altera_jesd204
|
||||
set_instance_parameter_value jesd204_ip {wrapper_opt} {base}
|
||||
set_instance_parameter_value jesd204_ip {DATA_PATH} {RX}
|
||||
set_instance_parameter_value jesd204_ip {lane_rate} $m_lane_rate
|
||||
set_instance_parameter_value jesd204_ip {L} $m_num_of_lanes
|
||||
set_instance_parameter_value jesd204_ip {M} $m_num_of_convs
|
||||
set_instance_parameter_value jesd204_ip {GUI_EN_CFG_F} {1}
|
||||
set_instance_parameter_value jesd204_ip {GUI_CFG_F} $m_frm_bcnt
|
||||
set_instance_parameter_value jesd204_ip {N} {16}
|
||||
set_instance_parameter_value jesd204_ip {N_PRIME} {16}
|
||||
set_instance_parameter_value jesd204_ip {S} $m_frm_scnt
|
||||
set_instance_parameter_value jesd204_ip {K} $m_mf_fcnt
|
||||
set_instance_parameter_value jesd204_ip {SCR} {1}
|
||||
set_instance_parameter_value jesd204_ip {HD} $m_hd
|
||||
add_connection core_pll.outclk0 jesd204_ip.rxlink_clk
|
||||
add_connection sys_clk.clk_reset jesd204_ip.rxlink_rst_n
|
||||
|
||||
add_connection jesd204_ip.sof octet_swap.in_sof
|
||||
add_interface ip_sof conduit end
|
||||
set_interface_property ip_sof EXPORT_OF octet_swap.out_sof
|
||||
|
||||
add_connection jesd204_ip.jesd204_rx_link octet_swap.in
|
||||
add_interface ip_data avalon_streaming source
|
||||
set_interface_property ip_data EXPORT_OF octet_swap.out
|
||||
|
||||
add_connection sys_clk.clk jesd204_ip.jesd204_rx_avs_clk
|
||||
add_connection sys_clk.clk_reset jesd204_ip.jesd204_rx_avs_rst_n
|
||||
add_interface ip_reconfig avalon slave
|
||||
set_interface_property ip_reconfig EXPORT_OF jesd204_ip.jesd204_rx_avs
|
||||
add_interface sysref conduit end
|
||||
set_interface_property sysref EXPORT_OF jesd204_ip.sysref
|
||||
add_interface sync conduit end
|
||||
set_interface_property sync EXPORT_OF jesd204_ip.dev_sync_n
|
||||
add_connection jesd204_ip.dev_lane_aligned jesd204_ip.alldev_lane_aligned
|
||||
|
||||
add_instance avl_xphy avl_adxphy
|
||||
set_instance_parameter_value avl_xphy {TX_OR_RX_N} {0}
|
||||
set_instance_parameter_value avl_xphy {NUM_OF_LANES} $m_num_of_lanes
|
||||
add_connection rst_control.rx_analogreset avl_xphy.rx_core_analogreset
|
||||
add_connection rst_control.rx_digitalreset avl_xphy.rx_core_digitalreset
|
||||
add_connection avl_xphy.rx_core_is_lockedtodata rst_control.rx_is_lockedtodata
|
||||
add_connection avl_xphy.rx_core_cal_busy rst_control.rx_cal_busy
|
||||
add_connection avl_xphy.rx_ip_is_lockedtodata jesd204_ip.rx_islockedtodata
|
||||
add_connection avl_xphy.rx_ip_cal_busy jesd204_ip.rx_cal_busy
|
||||
add_connection avl_xphy.rx_ip_pcs_data_valid jesd204_ip.jesd204_rx_pcs_data_valid
|
||||
add_connection avl_xphy.rx_ip_pcs_data jesd204_ip.jesd204_rx_pcs_data
|
||||
add_connection avl_xphy.rx_ip_pcs_disperr jesd204_ip.jesd204_rx_pcs_disperr
|
||||
add_connection avl_xphy.rx_ip_pcs_errdetect jesd204_ip.jesd204_rx_pcs_errdetect
|
||||
add_connection avl_xphy.rx_ip_pcs_kchar_data jesd204_ip.jesd204_rx_pcs_kchar_data
|
||||
add_connection avl_xphy.rx_ip_pcfifo_full jesd204_ip.phy_csr_rx_pcfifo_full
|
||||
add_connection avl_xphy.rx_ip_pcfifo_empty jesd204_ip.phy_csr_rx_pcfifo_empty
|
||||
add_connection avl_xphy.rx_ip_patternalign_en jesd204_ip.patternalign_en
|
||||
add_connection avl_xphy.rx_ip_csr_lane_polarity jesd204_ip.csr_lane_polarity
|
||||
add_connection avl_xphy.rx_ip_csr_lane_powerdown jesd204_ip.csr_lane_powerdown
|
||||
add_connection avl_xphy.rx_ip_csr_bit_reversal jesd204_ip.csr_bit_reversal
|
||||
add_connection avl_xphy.rx_ip_csr_byte_reversal jesd204_ip.csr_byte_reversal
|
||||
|
||||
for {set n 0} {$n < $m_num_of_lanes} {incr n} {
|
||||
|
||||
add_instance phy_${n} altera_jesd204
|
||||
set_instance_parameter_value phy_${n} {wrapper_opt} {phy}
|
||||
set_instance_parameter_value phy_${n} {DATA_PATH} {RX}
|
||||
set_instance_parameter_value phy_${n} {lane_rate} $m_lane_rate
|
||||
set_instance_parameter_value phy_${n} {PCS_CONFIG} $m_pcs_config
|
||||
set_instance_parameter_value phy_${n} {REFCLK_FREQ} $m_refclk_frequency
|
||||
set_instance_parameter_value phy_${n} {pll_reconfig_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {set_capability_reg_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {set_user_identifier} $m_id
|
||||
set_instance_parameter_value phy_${n} {set_csr_soft_logic_enable} {1}
|
||||
set_instance_parameter_value phy_${n} {L} 1
|
||||
|
||||
add_connection sys_clk.clk phy_${n}.reconfig_clk
|
||||
add_connection sys_clk.clk_reset phy_${n}.reconfig_reset
|
||||
add_interface phy_reconfig_${n} avalon slave
|
||||
set_interface_property phy_reconfig_${n} EXPORT_OF phy_${n}.reconfig_avmm
|
||||
|
||||
add_connection ref_clk.out_clk phy_${n}.pll_ref_clk
|
||||
add_connection core_pll.outclk0 phy_${n}.rxlink_clk
|
||||
add_connection sys_clk.clk_reset phy_${n}.rxlink_rst_n
|
||||
add_interface rx_data_${n} conduit end
|
||||
set_interface_property rx_data_${n} EXPORT_OF phy_${n}.rx_serial_data
|
||||
add_connection avl_xphy.rx_phy${n}_analogreset phy_${n}.rx_analogreset
|
||||
add_connection avl_xphy.rx_phy${n}_digitalreset phy_${n}.rx_digitalreset
|
||||
add_connection phy_${n}.rx_islockedtodata avl_xphy.rx_phy${n}_is_lockedtodata
|
||||
add_connection phy_${n}.rx_cal_busy avl_xphy.rx_phy${n}_cal_busy
|
||||
add_connection phy_${n}.jesd204_rx_pcs_data_valid avl_xphy.rx_phy${n}_pcs_data_valid
|
||||
add_connection phy_${n}.jesd204_rx_pcs_data avl_xphy.rx_phy${n}_pcs_data
|
||||
add_connection phy_${n}.jesd204_rx_pcs_disperr avl_xphy.rx_phy${n}_pcs_disperr
|
||||
add_connection phy_${n}.jesd204_rx_pcs_errdetect avl_xphy.rx_phy${n}_pcs_errdetect
|
||||
add_connection phy_${n}.jesd204_rx_pcs_kchar_data avl_xphy.rx_phy${n}_pcs_kchar_data
|
||||
add_connection phy_${n}.phy_csr_rx_pcfifo_full avl_xphy.rx_phy${n}_pcfifo_full
|
||||
add_connection phy_${n}.phy_csr_rx_pcfifo_empty avl_xphy.rx_phy${n}_pcfifo_empty
|
||||
add_connection avl_xphy.rx_phy${n}_patternalign_en phy_${n}.patternalign_en
|
||||
add_connection avl_xphy.rx_phy${n}_csr_lane_polarity phy_${n}.csr_lane_polarity
|
||||
add_connection avl_xphy.rx_phy${n}_csr_lane_powerdown phy_${n}.csr_lane_powerdown
|
||||
add_connection avl_xphy.rx_phy${n}_csr_bit_reversal phy_${n}.csr_bit_reversal
|
||||
add_connection avl_xphy.rx_phy${n}_csr_byte_reversal phy_${n}.csr_byte_reversal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := avl_adxcvr_octet_swap
|
||||
|
||||
INTEL_DEPS += avl_adxcvr_octet_swap.v
|
||||
INTEL_DEPS += avl_adxcvr_octet_swap_hw.tcl
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,70 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module avl_adxcvr_octet_swap #(
|
||||
parameter NUM_OF_LANES = 1
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input in_valid,
|
||||
output in_ready,
|
||||
input [NUM_OF_LANES*32-1:0] in_data,
|
||||
input [3:0] in_sof,
|
||||
|
||||
output out_valid,
|
||||
input out_ready,
|
||||
output [NUM_OF_LANES*32-1:0] out_data,
|
||||
output [3:0] out_sof
|
||||
);
|
||||
|
||||
assign in_ready = out_ready;
|
||||
assign out_valid = in_valid;
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
genvar j;
|
||||
|
||||
for (j = 0; j < 4; j = j + 1) begin: gen_octet
|
||||
for (i = 0; i < NUM_OF_LANES; i = i + 1) begin: gen_lane
|
||||
assign out_data[i*32+j*8+7:i*32+j*8] = in_data[i*32+(3-j)*8+7:i*32+(3-j)*8];
|
||||
end
|
||||
assign out_sof[j] = in_sof[3-j];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
package require qsys
|
||||
|
||||
source ../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
ad_ip_create avl_adxcvr_octet_swap "avl_adxcvvr_octet_swap helper" avl_adxcvr_octet_swap_elaboration
|
||||
set_module_property HIDE_FROM_SOPC true
|
||||
set_module_property HIDE_FROM_QSYS true
|
||||
set_module_property HIDE_FROM_QUARTUS true
|
||||
|
||||
# files
|
||||
|
||||
ad_ip_files avl_adxcvr_octet_swap { \
|
||||
avl_adxcvr_octet_swap.v
|
||||
}
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter NUM_OF_LANES INTEGER 4 true
|
||||
ad_ip_parameter TX_OR_RX_N INTEGER 0 false
|
||||
|
||||
# interfaces
|
||||
|
||||
add_interface clock clock end
|
||||
add_interface_port clock clk clk Input 1
|
||||
|
||||
add_interface reset reset end
|
||||
add_interface_port reset reset reset Input 1
|
||||
set_interface_property reset associatedClock clock
|
||||
|
||||
add_interface in_sof conduit end
|
||||
add_interface_port in_sof in_sof export Input 4
|
||||
|
||||
add_interface out_sof conduit end
|
||||
add_interface_port out_sof out_sof export Output 4
|
||||
|
||||
proc avl_adxcvr_octet_swap_elaboration {} {
|
||||
set num_lanes [get_parameter_value NUM_OF_LANES]
|
||||
set tx [get_parameter_value TX_OR_RX_N]
|
||||
|
||||
add_interface in avalon_streaming sink
|
||||
set_interface_property in associatedClock clock
|
||||
set_interface_property in associatedReset reset
|
||||
add_interface_port in in_data data input [expr 32*$num_lanes]
|
||||
add_interface_port in in_valid valid input 1
|
||||
add_interface_port in in_ready ready output 1
|
||||
set_interface_property in dataBitsPerSymbol [expr 32*$num_lanes]
|
||||
|
||||
add_interface out avalon_streaming source
|
||||
set_interface_property out associatedClock clock
|
||||
set_interface_property out associatedReset reset
|
||||
add_interface_port out out_data data output [expr 32*$num_lanes]
|
||||
add_interface_port out out_valid valid output 1
|
||||
add_interface_port out out_ready ready input 1
|
||||
set_interface_property out dataBitsPerSymbol [expr 32*$num_lanes]
|
||||
|
||||
if {$tx} {
|
||||
set_port_property in_sof TERMINATION true
|
||||
set_port_property in_sof TERMINATION_VALUE 0
|
||||
set_port_property out_sof TERMINATION true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := avl_adxphy
|
||||
|
||||
INTEL_DEPS += avl_adxphy.v
|
||||
INTEL_DEPS += avl_adxphy_hw.tcl
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,925 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// AUTO GENERATED BY avl_adxphy.pl, DO NOT MODIFY!
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module avl_adxphy #(
|
||||
|
||||
// parameters
|
||||
|
||||
parameter integer NUM_OF_LANES = 4) (
|
||||
|
||||
// rx-ip interface
|
||||
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_ip_locked,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_ip_cal_busy,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_ip_valid,
|
||||
output [((NUM_OF_LANES*32)-1):0] rx_ip_data,
|
||||
output [((NUM_OF_LANES* 4)-1):0] rx_ip_disperr,
|
||||
output [((NUM_OF_LANES* 4)-1):0] rx_ip_deterr,
|
||||
output [((NUM_OF_LANES* 4)-1):0] rx_ip_kchar,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_ip_full,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_ip_empty,
|
||||
input [((NUM_OF_LANES* 1)-1):0] rx_ip_align_en,
|
||||
input [((NUM_OF_LANES* 1)-1):0] rx_ip_lane_polarity,
|
||||
input [((NUM_OF_LANES* 1)-1):0] rx_ip_lane_powerdown,
|
||||
input rx_ip_bit_reversal,
|
||||
input rx_ip_byte_reversal,
|
||||
|
||||
// rx-phy interface(s)
|
||||
|
||||
input rx_phy_locked_0,
|
||||
input rx_phy_cal_busy_0,
|
||||
input rx_phy_valid_0,
|
||||
input [31:0] rx_phy_data_0,
|
||||
input [ 3:0] rx_phy_disperr_0,
|
||||
input [ 3:0] rx_phy_deterr_0,
|
||||
input [ 3:0] rx_phy_kchar_0,
|
||||
input rx_phy_full_0,
|
||||
input rx_phy_empty_0,
|
||||
output rx_phy_align_en_0,
|
||||
output rx_phy_lane_polarity_0,
|
||||
output rx_phy_lane_powerdown_0,
|
||||
output rx_phy_bit_reversal_0,
|
||||
output rx_phy_byte_reversal_0,
|
||||
output rx_phy_analogreset_0,
|
||||
output rx_phy_digitalreset_0,
|
||||
|
||||
input rx_phy_locked_1,
|
||||
input rx_phy_cal_busy_1,
|
||||
input rx_phy_valid_1,
|
||||
input [31:0] rx_phy_data_1,
|
||||
input [ 3:0] rx_phy_disperr_1,
|
||||
input [ 3:0] rx_phy_deterr_1,
|
||||
input [ 3:0] rx_phy_kchar_1,
|
||||
input rx_phy_full_1,
|
||||
input rx_phy_empty_1,
|
||||
output rx_phy_align_en_1,
|
||||
output rx_phy_lane_polarity_1,
|
||||
output rx_phy_lane_powerdown_1,
|
||||
output rx_phy_bit_reversal_1,
|
||||
output rx_phy_byte_reversal_1,
|
||||
output rx_phy_analogreset_1,
|
||||
output rx_phy_digitalreset_1,
|
||||
|
||||
input rx_phy_locked_2,
|
||||
input rx_phy_cal_busy_2,
|
||||
input rx_phy_valid_2,
|
||||
input [31:0] rx_phy_data_2,
|
||||
input [ 3:0] rx_phy_disperr_2,
|
||||
input [ 3:0] rx_phy_deterr_2,
|
||||
input [ 3:0] rx_phy_kchar_2,
|
||||
input rx_phy_full_2,
|
||||
input rx_phy_empty_2,
|
||||
output rx_phy_align_en_2,
|
||||
output rx_phy_lane_polarity_2,
|
||||
output rx_phy_lane_powerdown_2,
|
||||
output rx_phy_bit_reversal_2,
|
||||
output rx_phy_byte_reversal_2,
|
||||
output rx_phy_analogreset_2,
|
||||
output rx_phy_digitalreset_2,
|
||||
|
||||
input rx_phy_locked_3,
|
||||
input rx_phy_cal_busy_3,
|
||||
input rx_phy_valid_3,
|
||||
input [31:0] rx_phy_data_3,
|
||||
input [ 3:0] rx_phy_disperr_3,
|
||||
input [ 3:0] rx_phy_deterr_3,
|
||||
input [ 3:0] rx_phy_kchar_3,
|
||||
input rx_phy_full_3,
|
||||
input rx_phy_empty_3,
|
||||
output rx_phy_align_en_3,
|
||||
output rx_phy_lane_polarity_3,
|
||||
output rx_phy_lane_powerdown_3,
|
||||
output rx_phy_bit_reversal_3,
|
||||
output rx_phy_byte_reversal_3,
|
||||
output rx_phy_analogreset_3,
|
||||
output rx_phy_digitalreset_3,
|
||||
|
||||
input rx_phy_locked_4,
|
||||
input rx_phy_cal_busy_4,
|
||||
input rx_phy_valid_4,
|
||||
input [31:0] rx_phy_data_4,
|
||||
input [ 3:0] rx_phy_disperr_4,
|
||||
input [ 3:0] rx_phy_deterr_4,
|
||||
input [ 3:0] rx_phy_kchar_4,
|
||||
input rx_phy_full_4,
|
||||
input rx_phy_empty_4,
|
||||
output rx_phy_align_en_4,
|
||||
output rx_phy_lane_polarity_4,
|
||||
output rx_phy_lane_powerdown_4,
|
||||
output rx_phy_bit_reversal_4,
|
||||
output rx_phy_byte_reversal_4,
|
||||
output rx_phy_analogreset_4,
|
||||
output rx_phy_digitalreset_4,
|
||||
|
||||
input rx_phy_locked_5,
|
||||
input rx_phy_cal_busy_5,
|
||||
input rx_phy_valid_5,
|
||||
input [31:0] rx_phy_data_5,
|
||||
input [ 3:0] rx_phy_disperr_5,
|
||||
input [ 3:0] rx_phy_deterr_5,
|
||||
input [ 3:0] rx_phy_kchar_5,
|
||||
input rx_phy_full_5,
|
||||
input rx_phy_empty_5,
|
||||
output rx_phy_align_en_5,
|
||||
output rx_phy_lane_polarity_5,
|
||||
output rx_phy_lane_powerdown_5,
|
||||
output rx_phy_bit_reversal_5,
|
||||
output rx_phy_byte_reversal_5,
|
||||
output rx_phy_analogreset_5,
|
||||
output rx_phy_digitalreset_5,
|
||||
|
||||
input rx_phy_locked_6,
|
||||
input rx_phy_cal_busy_6,
|
||||
input rx_phy_valid_6,
|
||||
input [31:0] rx_phy_data_6,
|
||||
input [ 3:0] rx_phy_disperr_6,
|
||||
input [ 3:0] rx_phy_deterr_6,
|
||||
input [ 3:0] rx_phy_kchar_6,
|
||||
input rx_phy_full_6,
|
||||
input rx_phy_empty_6,
|
||||
output rx_phy_align_en_6,
|
||||
output rx_phy_lane_polarity_6,
|
||||
output rx_phy_lane_powerdown_6,
|
||||
output rx_phy_bit_reversal_6,
|
||||
output rx_phy_byte_reversal_6,
|
||||
output rx_phy_analogreset_6,
|
||||
output rx_phy_digitalreset_6,
|
||||
|
||||
input rx_phy_locked_7,
|
||||
input rx_phy_cal_busy_7,
|
||||
input rx_phy_valid_7,
|
||||
input [31:0] rx_phy_data_7,
|
||||
input [ 3:0] rx_phy_disperr_7,
|
||||
input [ 3:0] rx_phy_deterr_7,
|
||||
input [ 3:0] rx_phy_kchar_7,
|
||||
input rx_phy_full_7,
|
||||
input rx_phy_empty_7,
|
||||
output rx_phy_align_en_7,
|
||||
output rx_phy_lane_polarity_7,
|
||||
output rx_phy_lane_powerdown_7,
|
||||
output rx_phy_bit_reversal_7,
|
||||
output rx_phy_byte_reversal_7,
|
||||
output rx_phy_analogreset_7,
|
||||
output rx_phy_digitalreset_7,
|
||||
|
||||
// rx-core interface
|
||||
|
||||
input [((NUM_OF_LANES* 1)-1):0] rx_core_analogreset,
|
||||
input [((NUM_OF_LANES* 1)-1):0] rx_core_digitalreset,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_core_locked,
|
||||
output [((NUM_OF_LANES* 1)-1):0] rx_core_cal_busy,
|
||||
|
||||
// tx-ip interface
|
||||
|
||||
output [((NUM_OF_LANES* 1)-1):0] tx_ip_cal_busy,
|
||||
output [((NUM_OF_LANES* 1)-1):0] tx_ip_full,
|
||||
output [((NUM_OF_LANES* 1)-1):0] tx_ip_empty,
|
||||
input [((NUM_OF_LANES*32)-1):0] tx_ip_data,
|
||||
input [((NUM_OF_LANES* 4)-1):0] tx_ip_kchar,
|
||||
input [((NUM_OF_LANES* 1)-1):0] tx_ip_elecidle,
|
||||
input [((NUM_OF_LANES* 1)-1):0] tx_ip_lane_polarity,
|
||||
input [((NUM_OF_LANES* 1)-1):0] tx_ip_lane_powerdown,
|
||||
input tx_ip_bit_reversal,
|
||||
input tx_ip_byte_reversal,
|
||||
|
||||
|
||||
// tx-phy interface
|
||||
|
||||
input tx_phy_cal_busy_0,
|
||||
input tx_phy_full_0,
|
||||
input tx_phy_empty_0,
|
||||
output [31:0] tx_phy_data_0,
|
||||
output [ 3:0] tx_phy_kchar_0,
|
||||
output tx_phy_elecidle_0,
|
||||
output tx_phy_lane_polarity_0,
|
||||
output tx_phy_lane_powerdown_0,
|
||||
output tx_phy_bit_reversal_0,
|
||||
output tx_phy_byte_reversal_0,
|
||||
output tx_phy_analogreset_0,
|
||||
output tx_phy_digitalreset_0,
|
||||
|
||||
input tx_phy_cal_busy_1,
|
||||
input tx_phy_full_1,
|
||||
input tx_phy_empty_1,
|
||||
output [31:0] tx_phy_data_1,
|
||||
output [ 3:0] tx_phy_kchar_1,
|
||||
output tx_phy_elecidle_1,
|
||||
output tx_phy_lane_polarity_1,
|
||||
output tx_phy_lane_powerdown_1,
|
||||
output tx_phy_bit_reversal_1,
|
||||
output tx_phy_byte_reversal_1,
|
||||
output tx_phy_analogreset_1,
|
||||
output tx_phy_digitalreset_1,
|
||||
|
||||
input tx_phy_cal_busy_2,
|
||||
input tx_phy_full_2,
|
||||
input tx_phy_empty_2,
|
||||
output [31:0] tx_phy_data_2,
|
||||
output [ 3:0] tx_phy_kchar_2,
|
||||
output tx_phy_elecidle_2,
|
||||
output tx_phy_lane_polarity_2,
|
||||
output tx_phy_lane_powerdown_2,
|
||||
output tx_phy_bit_reversal_2,
|
||||
output tx_phy_byte_reversal_2,
|
||||
output tx_phy_analogreset_2,
|
||||
output tx_phy_digitalreset_2,
|
||||
|
||||
input tx_phy_cal_busy_3,
|
||||
input tx_phy_full_3,
|
||||
input tx_phy_empty_3,
|
||||
output [31:0] tx_phy_data_3,
|
||||
output [ 3:0] tx_phy_kchar_3,
|
||||
output tx_phy_elecidle_3,
|
||||
output tx_phy_lane_polarity_3,
|
||||
output tx_phy_lane_powerdown_3,
|
||||
output tx_phy_bit_reversal_3,
|
||||
output tx_phy_byte_reversal_3,
|
||||
output tx_phy_analogreset_3,
|
||||
output tx_phy_digitalreset_3,
|
||||
|
||||
input tx_phy_cal_busy_4,
|
||||
input tx_phy_full_4,
|
||||
input tx_phy_empty_4,
|
||||
output [31:0] tx_phy_data_4,
|
||||
output [ 3:0] tx_phy_kchar_4,
|
||||
output tx_phy_elecidle_4,
|
||||
output tx_phy_lane_polarity_4,
|
||||
output tx_phy_lane_powerdown_4,
|
||||
output tx_phy_bit_reversal_4,
|
||||
output tx_phy_byte_reversal_4,
|
||||
output tx_phy_analogreset_4,
|
||||
output tx_phy_digitalreset_4,
|
||||
|
||||
input tx_phy_cal_busy_5,
|
||||
input tx_phy_full_5,
|
||||
input tx_phy_empty_5,
|
||||
output [31:0] tx_phy_data_5,
|
||||
output [ 3:0] tx_phy_kchar_5,
|
||||
output tx_phy_elecidle_5,
|
||||
output tx_phy_lane_polarity_5,
|
||||
output tx_phy_lane_powerdown_5,
|
||||
output tx_phy_bit_reversal_5,
|
||||
output tx_phy_byte_reversal_5,
|
||||
output tx_phy_analogreset_5,
|
||||
output tx_phy_digitalreset_5,
|
||||
|
||||
input tx_phy_cal_busy_6,
|
||||
input tx_phy_full_6,
|
||||
input tx_phy_empty_6,
|
||||
output [31:0] tx_phy_data_6,
|
||||
output [ 3:0] tx_phy_kchar_6,
|
||||
output tx_phy_elecidle_6,
|
||||
output tx_phy_lane_polarity_6,
|
||||
output tx_phy_lane_powerdown_6,
|
||||
output tx_phy_bit_reversal_6,
|
||||
output tx_phy_byte_reversal_6,
|
||||
output tx_phy_analogreset_6,
|
||||
output tx_phy_digitalreset_6,
|
||||
|
||||
input tx_phy_cal_busy_7,
|
||||
input tx_phy_full_7,
|
||||
input tx_phy_empty_7,
|
||||
output [31:0] tx_phy_data_7,
|
||||
output [ 3:0] tx_phy_kchar_7,
|
||||
output tx_phy_elecidle_7,
|
||||
output tx_phy_lane_polarity_7,
|
||||
output tx_phy_lane_powerdown_7,
|
||||
output tx_phy_bit_reversal_7,
|
||||
output tx_phy_byte_reversal_7,
|
||||
output tx_phy_analogreset_7,
|
||||
output tx_phy_digitalreset_7,
|
||||
|
||||
// tx-core interface
|
||||
|
||||
input [((NUM_OF_LANES* 1)-1):0] tx_core_analogreset,
|
||||
input [((NUM_OF_LANES* 1)-1):0] tx_core_digitalreset,
|
||||
output [((NUM_OF_LANES* 1)-1):0] tx_core_cal_busy);
|
||||
|
||||
// rx assignments
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 0) begin
|
||||
assign rx_core_locked[0] = rx_phy_locked_0;
|
||||
assign rx_core_cal_busy[0] = rx_phy_cal_busy_0;
|
||||
assign rx_ip_locked[0] = rx_phy_locked_0;
|
||||
assign rx_ip_cal_busy[0] = rx_phy_cal_busy_0;
|
||||
assign rx_ip_valid[0] = rx_phy_valid_0;
|
||||
assign rx_ip_data[((32*1)-1):(32*0)] = rx_phy_data_0;
|
||||
assign rx_ip_disperr[((4*1)-1):(4*0)] = rx_phy_disperr_0;
|
||||
assign rx_ip_deterr[((4*1)-1):(4*0)] = rx_phy_deterr_0;
|
||||
assign rx_ip_kchar[((4*1)-1):(4*0)] = rx_phy_kchar_0;
|
||||
assign rx_ip_full[0] = rx_phy_full_0;
|
||||
assign rx_ip_empty[0] = rx_phy_empty_0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 0) begin
|
||||
assign rx_phy_align_en_0 = rx_ip_align_en[0];
|
||||
assign rx_phy_lane_polarity_0 = rx_ip_lane_polarity[0];
|
||||
assign rx_phy_lane_powerdown_0 = rx_ip_lane_powerdown[0];
|
||||
assign rx_phy_analogreset_0 = rx_core_analogreset[0];
|
||||
assign rx_phy_digitalreset_0 = rx_core_digitalreset[0];
|
||||
end else begin
|
||||
assign rx_phy_align_en_0 = 1'd0;
|
||||
assign rx_phy_lane_polarity_0 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_0 = 1'd0;
|
||||
assign rx_phy_analogreset_0 = 1'd1;
|
||||
assign rx_phy_digitalreset_0 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_0 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_0 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 1) begin
|
||||
assign rx_core_locked[1] = rx_phy_locked_1;
|
||||
assign rx_core_cal_busy[1] = rx_phy_cal_busy_1;
|
||||
assign rx_ip_locked[1] = rx_phy_locked_1;
|
||||
assign rx_ip_cal_busy[1] = rx_phy_cal_busy_1;
|
||||
assign rx_ip_valid[1] = rx_phy_valid_1;
|
||||
assign rx_ip_data[((32*2)-1):(32*1)] = rx_phy_data_1;
|
||||
assign rx_ip_disperr[((4*2)-1):(4*1)] = rx_phy_disperr_1;
|
||||
assign rx_ip_deterr[((4*2)-1):(4*1)] = rx_phy_deterr_1;
|
||||
assign rx_ip_kchar[((4*2)-1):(4*1)] = rx_phy_kchar_1;
|
||||
assign rx_ip_full[1] = rx_phy_full_1;
|
||||
assign rx_ip_empty[1] = rx_phy_empty_1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 1) begin
|
||||
assign rx_phy_align_en_1 = rx_ip_align_en[1];
|
||||
assign rx_phy_lane_polarity_1 = rx_ip_lane_polarity[1];
|
||||
assign rx_phy_lane_powerdown_1 = rx_ip_lane_powerdown[1];
|
||||
assign rx_phy_analogreset_1 = rx_core_analogreset[1];
|
||||
assign rx_phy_digitalreset_1 = rx_core_digitalreset[1];
|
||||
end else begin
|
||||
assign rx_phy_align_en_1 = 1'd0;
|
||||
assign rx_phy_lane_polarity_1 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_1 = 1'd0;
|
||||
assign rx_phy_analogreset_1 = 1'd1;
|
||||
assign rx_phy_digitalreset_1 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_1 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_1 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 2) begin
|
||||
assign rx_core_locked[2] = rx_phy_locked_2;
|
||||
assign rx_core_cal_busy[2] = rx_phy_cal_busy_2;
|
||||
assign rx_ip_locked[2] = rx_phy_locked_2;
|
||||
assign rx_ip_cal_busy[2] = rx_phy_cal_busy_2;
|
||||
assign rx_ip_valid[2] = rx_phy_valid_2;
|
||||
assign rx_ip_data[((32*3)-1):(32*2)] = rx_phy_data_2;
|
||||
assign rx_ip_disperr[((4*3)-1):(4*2)] = rx_phy_disperr_2;
|
||||
assign rx_ip_deterr[((4*3)-1):(4*2)] = rx_phy_deterr_2;
|
||||
assign rx_ip_kchar[((4*3)-1):(4*2)] = rx_phy_kchar_2;
|
||||
assign rx_ip_full[2] = rx_phy_full_2;
|
||||
assign rx_ip_empty[2] = rx_phy_empty_2;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 2) begin
|
||||
assign rx_phy_align_en_2 = rx_ip_align_en[2];
|
||||
assign rx_phy_lane_polarity_2 = rx_ip_lane_polarity[2];
|
||||
assign rx_phy_lane_powerdown_2 = rx_ip_lane_powerdown[2];
|
||||
assign rx_phy_analogreset_2 = rx_core_analogreset[2];
|
||||
assign rx_phy_digitalreset_2 = rx_core_digitalreset[2];
|
||||
end else begin
|
||||
assign rx_phy_align_en_2 = 1'd0;
|
||||
assign rx_phy_lane_polarity_2 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_2 = 1'd0;
|
||||
assign rx_phy_analogreset_2 = 1'd1;
|
||||
assign rx_phy_digitalreset_2 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_2 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_2 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 3) begin
|
||||
assign rx_core_locked[3] = rx_phy_locked_3;
|
||||
assign rx_core_cal_busy[3] = rx_phy_cal_busy_3;
|
||||
assign rx_ip_locked[3] = rx_phy_locked_3;
|
||||
assign rx_ip_cal_busy[3] = rx_phy_cal_busy_3;
|
||||
assign rx_ip_valid[3] = rx_phy_valid_3;
|
||||
assign rx_ip_data[((32*4)-1):(32*3)] = rx_phy_data_3;
|
||||
assign rx_ip_disperr[((4*4)-1):(4*3)] = rx_phy_disperr_3;
|
||||
assign rx_ip_deterr[((4*4)-1):(4*3)] = rx_phy_deterr_3;
|
||||
assign rx_ip_kchar[((4*4)-1):(4*3)] = rx_phy_kchar_3;
|
||||
assign rx_ip_full[3] = rx_phy_full_3;
|
||||
assign rx_ip_empty[3] = rx_phy_empty_3;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 3) begin
|
||||
assign rx_phy_align_en_3 = rx_ip_align_en[3];
|
||||
assign rx_phy_lane_polarity_3 = rx_ip_lane_polarity[3];
|
||||
assign rx_phy_lane_powerdown_3 = rx_ip_lane_powerdown[3];
|
||||
assign rx_phy_analogreset_3 = rx_core_analogreset[3];
|
||||
assign rx_phy_digitalreset_3 = rx_core_digitalreset[3];
|
||||
end else begin
|
||||
assign rx_phy_align_en_3 = 1'd0;
|
||||
assign rx_phy_lane_polarity_3 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_3 = 1'd0;
|
||||
assign rx_phy_analogreset_3 = 1'd1;
|
||||
assign rx_phy_digitalreset_3 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_3 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_3 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 4) begin
|
||||
assign rx_core_locked[4] = rx_phy_locked_4;
|
||||
assign rx_core_cal_busy[4] = rx_phy_cal_busy_4;
|
||||
assign rx_ip_locked[4] = rx_phy_locked_4;
|
||||
assign rx_ip_cal_busy[4] = rx_phy_cal_busy_4;
|
||||
assign rx_ip_valid[4] = rx_phy_valid_4;
|
||||
assign rx_ip_data[((32*5)-1):(32*4)] = rx_phy_data_4;
|
||||
assign rx_ip_disperr[((4*5)-1):(4*4)] = rx_phy_disperr_4;
|
||||
assign rx_ip_deterr[((4*5)-1):(4*4)] = rx_phy_deterr_4;
|
||||
assign rx_ip_kchar[((4*5)-1):(4*4)] = rx_phy_kchar_4;
|
||||
assign rx_ip_full[4] = rx_phy_full_4;
|
||||
assign rx_ip_empty[4] = rx_phy_empty_4;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 4) begin
|
||||
assign rx_phy_align_en_4 = rx_ip_align_en[4];
|
||||
assign rx_phy_lane_polarity_4 = rx_ip_lane_polarity[4];
|
||||
assign rx_phy_lane_powerdown_4 = rx_ip_lane_powerdown[4];
|
||||
assign rx_phy_analogreset_4 = rx_core_analogreset[4];
|
||||
assign rx_phy_digitalreset_4 = rx_core_digitalreset[4];
|
||||
end else begin
|
||||
assign rx_phy_align_en_4 = 1'd0;
|
||||
assign rx_phy_lane_polarity_4 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_4 = 1'd0;
|
||||
assign rx_phy_analogreset_4 = 1'd1;
|
||||
assign rx_phy_digitalreset_4 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_4 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_4 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 5) begin
|
||||
assign rx_core_locked[5] = rx_phy_locked_5;
|
||||
assign rx_core_cal_busy[5] = rx_phy_cal_busy_5;
|
||||
assign rx_ip_locked[5] = rx_phy_locked_5;
|
||||
assign rx_ip_cal_busy[5] = rx_phy_cal_busy_5;
|
||||
assign rx_ip_valid[5] = rx_phy_valid_5;
|
||||
assign rx_ip_data[((32*6)-1):(32*5)] = rx_phy_data_5;
|
||||
assign rx_ip_disperr[((4*6)-1):(4*5)] = rx_phy_disperr_5;
|
||||
assign rx_ip_deterr[((4*6)-1):(4*5)] = rx_phy_deterr_5;
|
||||
assign rx_ip_kchar[((4*6)-1):(4*5)] = rx_phy_kchar_5;
|
||||
assign rx_ip_full[5] = rx_phy_full_5;
|
||||
assign rx_ip_empty[5] = rx_phy_empty_5;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 5) begin
|
||||
assign rx_phy_align_en_5 = rx_ip_align_en[5];
|
||||
assign rx_phy_lane_polarity_5 = rx_ip_lane_polarity[5];
|
||||
assign rx_phy_lane_powerdown_5 = rx_ip_lane_powerdown[5];
|
||||
assign rx_phy_analogreset_5 = rx_core_analogreset[5];
|
||||
assign rx_phy_digitalreset_5 = rx_core_digitalreset[5];
|
||||
end else begin
|
||||
assign rx_phy_align_en_5 = 1'd0;
|
||||
assign rx_phy_lane_polarity_5 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_5 = 1'd0;
|
||||
assign rx_phy_analogreset_5 = 1'd1;
|
||||
assign rx_phy_digitalreset_5 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_5 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_5 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 6) begin
|
||||
assign rx_core_locked[6] = rx_phy_locked_6;
|
||||
assign rx_core_cal_busy[6] = rx_phy_cal_busy_6;
|
||||
assign rx_ip_locked[6] = rx_phy_locked_6;
|
||||
assign rx_ip_cal_busy[6] = rx_phy_cal_busy_6;
|
||||
assign rx_ip_valid[6] = rx_phy_valid_6;
|
||||
assign rx_ip_data[((32*7)-1):(32*6)] = rx_phy_data_6;
|
||||
assign rx_ip_disperr[((4*7)-1):(4*6)] = rx_phy_disperr_6;
|
||||
assign rx_ip_deterr[((4*7)-1):(4*6)] = rx_phy_deterr_6;
|
||||
assign rx_ip_kchar[((4*7)-1):(4*6)] = rx_phy_kchar_6;
|
||||
assign rx_ip_full[6] = rx_phy_full_6;
|
||||
assign rx_ip_empty[6] = rx_phy_empty_6;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 6) begin
|
||||
assign rx_phy_align_en_6 = rx_ip_align_en[6];
|
||||
assign rx_phy_lane_polarity_6 = rx_ip_lane_polarity[6];
|
||||
assign rx_phy_lane_powerdown_6 = rx_ip_lane_powerdown[6];
|
||||
assign rx_phy_analogreset_6 = rx_core_analogreset[6];
|
||||
assign rx_phy_digitalreset_6 = rx_core_digitalreset[6];
|
||||
end else begin
|
||||
assign rx_phy_align_en_6 = 1'd0;
|
||||
assign rx_phy_lane_polarity_6 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_6 = 1'd0;
|
||||
assign rx_phy_analogreset_6 = 1'd1;
|
||||
assign rx_phy_digitalreset_6 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_6 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_6 = rx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 7) begin
|
||||
assign rx_core_locked[7] = rx_phy_locked_7;
|
||||
assign rx_core_cal_busy[7] = rx_phy_cal_busy_7;
|
||||
assign rx_ip_locked[7] = rx_phy_locked_7;
|
||||
assign rx_ip_cal_busy[7] = rx_phy_cal_busy_7;
|
||||
assign rx_ip_valid[7] = rx_phy_valid_7;
|
||||
assign rx_ip_data[((32*8)-1):(32*7)] = rx_phy_data_7;
|
||||
assign rx_ip_disperr[((4*8)-1):(4*7)] = rx_phy_disperr_7;
|
||||
assign rx_ip_deterr[((4*8)-1):(4*7)] = rx_phy_deterr_7;
|
||||
assign rx_ip_kchar[((4*8)-1):(4*7)] = rx_phy_kchar_7;
|
||||
assign rx_ip_full[7] = rx_phy_full_7;
|
||||
assign rx_ip_empty[7] = rx_phy_empty_7;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 7) begin
|
||||
assign rx_phy_align_en_7 = rx_ip_align_en[7];
|
||||
assign rx_phy_lane_polarity_7 = rx_ip_lane_polarity[7];
|
||||
assign rx_phy_lane_powerdown_7 = rx_ip_lane_powerdown[7];
|
||||
assign rx_phy_analogreset_7 = rx_core_analogreset[7];
|
||||
assign rx_phy_digitalreset_7 = rx_core_digitalreset[7];
|
||||
end else begin
|
||||
assign rx_phy_align_en_7 = 1'd0;
|
||||
assign rx_phy_lane_polarity_7 = 1'd0;
|
||||
assign rx_phy_lane_powerdown_7 = 1'd0;
|
||||
assign rx_phy_analogreset_7 = 1'd1;
|
||||
assign rx_phy_digitalreset_7 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign rx_phy_bit_reversal_7 = rx_ip_bit_reversal;
|
||||
assign rx_phy_byte_reversal_7 = rx_ip_byte_reversal;
|
||||
|
||||
// tx assignments
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 0) begin
|
||||
assign tx_core_cal_busy[0] = tx_phy_cal_busy_0;
|
||||
assign tx_ip_cal_busy[0] = tx_phy_cal_busy_0;
|
||||
assign tx_ip_full[0] = tx_phy_full_0;
|
||||
assign tx_ip_empty[0] = tx_phy_empty_0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 0) begin
|
||||
assign tx_phy_data_0 = tx_ip_data[((32*1)-1):(32*0)];
|
||||
assign tx_phy_kchar_0 = tx_ip_kchar[((4*1)-1):(4*0)];
|
||||
assign tx_phy_elecidle_0 = tx_ip_elecidle[0];
|
||||
assign tx_phy_lane_polarity_0 = tx_ip_lane_polarity[0];
|
||||
assign tx_phy_lane_powerdown_0 = tx_ip_lane_powerdown[0];
|
||||
end else begin
|
||||
assign tx_phy_data_0 = 32'd0;
|
||||
assign tx_phy_kchar_0 = 4'd0;
|
||||
assign tx_phy_elecidle_0 = 1'd0;
|
||||
assign tx_phy_lane_polarity_0 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_0 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 0) begin
|
||||
assign tx_phy_analogreset_0 = tx_core_analogreset[0];
|
||||
assign tx_phy_digitalreset_0 = tx_core_digitalreset[0];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_0 = 1'd1;
|
||||
assign tx_phy_digitalreset_0 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_0 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_0 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 1) begin
|
||||
assign tx_core_cal_busy[1] = tx_phy_cal_busy_1;
|
||||
assign tx_ip_cal_busy[1] = tx_phy_cal_busy_1;
|
||||
assign tx_ip_full[1] = tx_phy_full_1;
|
||||
assign tx_ip_empty[1] = tx_phy_empty_1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 1) begin
|
||||
assign tx_phy_data_1 = tx_ip_data[((32*2)-1):(32*1)];
|
||||
assign tx_phy_kchar_1 = tx_ip_kchar[((4*2)-1):(4*1)];
|
||||
assign tx_phy_elecidle_1 = tx_ip_elecidle[1];
|
||||
assign tx_phy_lane_polarity_1 = tx_ip_lane_polarity[1];
|
||||
assign tx_phy_lane_powerdown_1 = tx_ip_lane_powerdown[1];
|
||||
end else begin
|
||||
assign tx_phy_data_1 = 32'd0;
|
||||
assign tx_phy_kchar_1 = 4'd0;
|
||||
assign tx_phy_elecidle_1 = 1'd0;
|
||||
assign tx_phy_lane_polarity_1 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_1 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 1) begin
|
||||
assign tx_phy_analogreset_1 = tx_core_analogreset[1];
|
||||
assign tx_phy_digitalreset_1 = tx_core_digitalreset[1];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_1 = 1'd1;
|
||||
assign tx_phy_digitalreset_1 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_1 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_1 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 2) begin
|
||||
assign tx_core_cal_busy[2] = tx_phy_cal_busy_2;
|
||||
assign tx_ip_cal_busy[2] = tx_phy_cal_busy_2;
|
||||
assign tx_ip_full[2] = tx_phy_full_2;
|
||||
assign tx_ip_empty[2] = tx_phy_empty_2;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 2) begin
|
||||
assign tx_phy_data_2 = tx_ip_data[((32*3)-1):(32*2)];
|
||||
assign tx_phy_kchar_2 = tx_ip_kchar[((4*3)-1):(4*2)];
|
||||
assign tx_phy_elecidle_2 = tx_ip_elecidle[2];
|
||||
assign tx_phy_lane_polarity_2 = tx_ip_lane_polarity[2];
|
||||
assign tx_phy_lane_powerdown_2 = tx_ip_lane_powerdown[2];
|
||||
end else begin
|
||||
assign tx_phy_data_2 = 32'd0;
|
||||
assign tx_phy_kchar_2 = 4'd0;
|
||||
assign tx_phy_elecidle_2 = 1'd0;
|
||||
assign tx_phy_lane_polarity_2 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_2 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 2) begin
|
||||
assign tx_phy_analogreset_2 = tx_core_analogreset[2];
|
||||
assign tx_phy_digitalreset_2 = tx_core_digitalreset[2];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_2 = 1'd1;
|
||||
assign tx_phy_digitalreset_2 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_2 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_2 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 3) begin
|
||||
assign tx_core_cal_busy[3] = tx_phy_cal_busy_3;
|
||||
assign tx_ip_cal_busy[3] = tx_phy_cal_busy_3;
|
||||
assign tx_ip_full[3] = tx_phy_full_3;
|
||||
assign tx_ip_empty[3] = tx_phy_empty_3;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 3) begin
|
||||
assign tx_phy_data_3 = tx_ip_data[((32*4)-1):(32*3)];
|
||||
assign tx_phy_kchar_3 = tx_ip_kchar[((4*4)-1):(4*3)];
|
||||
assign tx_phy_elecidle_3 = tx_ip_elecidle[3];
|
||||
assign tx_phy_lane_polarity_3 = tx_ip_lane_polarity[3];
|
||||
assign tx_phy_lane_powerdown_3 = tx_ip_lane_powerdown[3];
|
||||
end else begin
|
||||
assign tx_phy_data_3 = 32'd0;
|
||||
assign tx_phy_kchar_3 = 4'd0;
|
||||
assign tx_phy_elecidle_3 = 1'd0;
|
||||
assign tx_phy_lane_polarity_3 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_3 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 3) begin
|
||||
assign tx_phy_analogreset_3 = tx_core_analogreset[3];
|
||||
assign tx_phy_digitalreset_3 = tx_core_digitalreset[3];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_3 = 1'd1;
|
||||
assign tx_phy_digitalreset_3 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_3 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_3 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 4) begin
|
||||
assign tx_core_cal_busy[4] = tx_phy_cal_busy_4;
|
||||
assign tx_ip_cal_busy[4] = tx_phy_cal_busy_4;
|
||||
assign tx_ip_full[4] = tx_phy_full_4;
|
||||
assign tx_ip_empty[4] = tx_phy_empty_4;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 4) begin
|
||||
assign tx_phy_data_4 = tx_ip_data[((32*5)-1):(32*4)];
|
||||
assign tx_phy_kchar_4 = tx_ip_kchar[((4*5)-1):(4*4)];
|
||||
assign tx_phy_elecidle_4 = tx_ip_elecidle[4];
|
||||
assign tx_phy_lane_polarity_4 = tx_ip_lane_polarity[4];
|
||||
assign tx_phy_lane_powerdown_4 = tx_ip_lane_powerdown[4];
|
||||
end else begin
|
||||
assign tx_phy_data_4 = 32'd0;
|
||||
assign tx_phy_kchar_4 = 4'd0;
|
||||
assign tx_phy_elecidle_4 = 1'd0;
|
||||
assign tx_phy_lane_polarity_4 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_4 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 4) begin
|
||||
assign tx_phy_analogreset_4 = tx_core_analogreset[4];
|
||||
assign tx_phy_digitalreset_4 = tx_core_digitalreset[4];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_4 = 1'd1;
|
||||
assign tx_phy_digitalreset_4 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_4 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_4 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 5) begin
|
||||
assign tx_core_cal_busy[5] = tx_phy_cal_busy_5;
|
||||
assign tx_ip_cal_busy[5] = tx_phy_cal_busy_5;
|
||||
assign tx_ip_full[5] = tx_phy_full_5;
|
||||
assign tx_ip_empty[5] = tx_phy_empty_5;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 5) begin
|
||||
assign tx_phy_data_5 = tx_ip_data[((32*6)-1):(32*5)];
|
||||
assign tx_phy_kchar_5 = tx_ip_kchar[((4*6)-1):(4*5)];
|
||||
assign tx_phy_elecidle_5 = tx_ip_elecidle[5];
|
||||
assign tx_phy_lane_polarity_5 = tx_ip_lane_polarity[5];
|
||||
assign tx_phy_lane_powerdown_5 = tx_ip_lane_powerdown[5];
|
||||
end else begin
|
||||
assign tx_phy_data_5 = 32'd0;
|
||||
assign tx_phy_kchar_5 = 4'd0;
|
||||
assign tx_phy_elecidle_5 = 1'd0;
|
||||
assign tx_phy_lane_polarity_5 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_5 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 5) begin
|
||||
assign tx_phy_analogreset_5 = tx_core_analogreset[5];
|
||||
assign tx_phy_digitalreset_5 = tx_core_digitalreset[5];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_5 = 1'd1;
|
||||
assign tx_phy_digitalreset_5 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_5 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_5 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 6) begin
|
||||
assign tx_core_cal_busy[6] = tx_phy_cal_busy_6;
|
||||
assign tx_ip_cal_busy[6] = tx_phy_cal_busy_6;
|
||||
assign tx_ip_full[6] = tx_phy_full_6;
|
||||
assign tx_ip_empty[6] = tx_phy_empty_6;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 6) begin
|
||||
assign tx_phy_data_6 = tx_ip_data[((32*7)-1):(32*6)];
|
||||
assign tx_phy_kchar_6 = tx_ip_kchar[((4*7)-1):(4*6)];
|
||||
assign tx_phy_elecidle_6 = tx_ip_elecidle[6];
|
||||
assign tx_phy_lane_polarity_6 = tx_ip_lane_polarity[6];
|
||||
assign tx_phy_lane_powerdown_6 = tx_ip_lane_powerdown[6];
|
||||
end else begin
|
||||
assign tx_phy_data_6 = 32'd0;
|
||||
assign tx_phy_kchar_6 = 4'd0;
|
||||
assign tx_phy_elecidle_6 = 1'd0;
|
||||
assign tx_phy_lane_polarity_6 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_6 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 6) begin
|
||||
assign tx_phy_analogreset_6 = tx_core_analogreset[6];
|
||||
assign tx_phy_digitalreset_6 = tx_core_digitalreset[6];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_6 = 1'd1;
|
||||
assign tx_phy_digitalreset_6 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_6 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_6 = tx_ip_byte_reversal;
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 7) begin
|
||||
assign tx_core_cal_busy[7] = tx_phy_cal_busy_7;
|
||||
assign tx_ip_cal_busy[7] = tx_phy_cal_busy_7;
|
||||
assign tx_ip_full[7] = tx_phy_full_7;
|
||||
assign tx_ip_empty[7] = tx_phy_empty_7;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 7) begin
|
||||
assign tx_phy_data_7 = tx_ip_data[((32*8)-1):(32*7)];
|
||||
assign tx_phy_kchar_7 = tx_ip_kchar[((4*8)-1):(4*7)];
|
||||
assign tx_phy_elecidle_7 = tx_ip_elecidle[7];
|
||||
assign tx_phy_lane_polarity_7 = tx_ip_lane_polarity[7];
|
||||
assign tx_phy_lane_powerdown_7 = tx_ip_lane_powerdown[7];
|
||||
end else begin
|
||||
assign tx_phy_data_7 = 32'd0;
|
||||
assign tx_phy_kchar_7 = 4'd0;
|
||||
assign tx_phy_elecidle_7 = 1'd0;
|
||||
assign tx_phy_lane_polarity_7 = 1'd0;
|
||||
assign tx_phy_lane_powerdown_7 = 1'd0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if (NUM_OF_LANES > 7) begin
|
||||
assign tx_phy_analogreset_7 = tx_core_analogreset[7];
|
||||
assign tx_phy_digitalreset_7 = tx_core_digitalreset[7];
|
||||
end else begin
|
||||
assign tx_phy_analogreset_7 = 1'd1;
|
||||
assign tx_phy_digitalreset_7 = 1'd1;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign tx_phy_bit_reversal_7 = tx_ip_bit_reversal;
|
||||
assign tx_phy_byte_reversal_7 = tx_ip_byte_reversal;
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
|
||||
package require qsys
|
||||
|
||||
source ../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
set_module_property NAME avl_adxphy
|
||||
set_module_property DESCRIPTION "Avalon ADXPHY Core"
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
set_module_property DISPLAY_NAME avl_adxphy
|
||||
set_module_property ELABORATION_CALLBACK p_avl_adxphy
|
||||
|
||||
# files
|
||||
|
||||
add_fileset quartus_synth QUARTUS_SYNTH "" ""
|
||||
set_fileset_property quartus_synth TOP_LEVEL avl_adxphy
|
||||
add_fileset_file avl_adxphy.v VERILOG PATH avl_adxphy.v TOP_LEVEL_FILE
|
||||
|
||||
# parameters
|
||||
|
||||
add_parameter TX_OR_RX_N INTEGER 0
|
||||
set_parameter_property TX_OR_RX_N DISPLAY_NAME TX_OR_RX_N
|
||||
set_parameter_property TX_OR_RX_N UNITS None
|
||||
set_parameter_property TX_OR_RX_N HDL_PARAMETER false
|
||||
|
||||
add_parameter NUM_OF_LANES INTEGER 4
|
||||
set_parameter_property NUM_OF_LANES DISPLAY_NAME NUM_OF_LANES
|
||||
set_parameter_property NUM_OF_LANES UNITS None
|
||||
set_parameter_property NUM_OF_LANES HDL_PARAMETER true
|
||||
|
||||
proc p_avl_adxphy {} {
|
||||
|
||||
set m_tx_or_rx_n [get_parameter_value TX_OR_RX_N]
|
||||
set m_num_of_lanes [get_parameter_value NUM_OF_LANES]
|
||||
|
||||
if {$m_tx_or_rx_n == 1} {
|
||||
|
||||
ad_conduit tx_core_analogreset tx_analogreset tx_core_analogreset input $m_num_of_lanes
|
||||
ad_conduit tx_core_digitalreset tx_digitalreset tx_core_digitalreset input $m_num_of_lanes
|
||||
ad_conduit tx_core_cal_busy tx_cal_busy tx_core_cal_busy output $m_num_of_lanes
|
||||
|
||||
ad_conduit tx_ip_cal_busy tx_cal_busy tx_ip_cal_busy output $m_num_of_lanes
|
||||
ad_conduit tx_ip_pcfifo_full export tx_ip_full output $m_num_of_lanes
|
||||
ad_conduit tx_ip_pcfifo_empty export tx_ip_empty output $m_num_of_lanes
|
||||
ad_conduit tx_ip_pcs_data export tx_ip_data input 32*$m_num_of_lanes
|
||||
ad_conduit tx_ip_pcs_kchar_data export tx_ip_kchar input 4*$m_num_of_lanes
|
||||
ad_conduit tx_ip_elecidle export tx_ip_elecidle input $m_num_of_lanes
|
||||
ad_conduit tx_ip_csr_lane_polarity export tx_ip_lane_polarity input $m_num_of_lanes
|
||||
ad_conduit tx_ip_csr_lane_powerdown export tx_ip_lane_powerdown input $m_num_of_lanes
|
||||
ad_conduit tx_ip_csr_bit_reversal export rx_ip_bit_reversal input 1
|
||||
ad_conduit tx_ip_csr_byte_reversal export rx_ip_byte_reversal input 1
|
||||
|
||||
for {set n 0} {$n < $m_num_of_lanes} {incr n} {
|
||||
|
||||
ad_conduit tx_phy${n}_cal_busy tx_cal_busy tx_phy_cal_busy_${n} input 1
|
||||
ad_conduit tx_phy${n}_pcfifo_full export tx_phy_full_${n} input 1
|
||||
ad_conduit tx_phy${n}_pcfifo_empty export tx_phy_empty_${n} input 1
|
||||
ad_conduit tx_phy${n}_pcs_data export tx_phy_data_${n} output 32
|
||||
ad_conduit tx_phy${n}_pcs_kchar_data export tx_phy_kchar_${n} output 4
|
||||
ad_conduit tx_phy${n}_elecidle export tx_phy_elecidle_${n} output 1
|
||||
ad_conduit tx_phy${n}_csr_lane_polarity export tx_phy_lane_polarity_${n} output 1
|
||||
ad_conduit tx_phy${n}_csr_lane_powerdown export tx_phy_lane_powerdown_${n} output 1
|
||||
ad_conduit tx_phy${n}_csr_bit_reversal export tx_phy_bit_reversal_${n} output 1
|
||||
ad_conduit tx_phy${n}_csr_byte_reversal export tx_phy_byte_reversal_${n} output 1
|
||||
ad_conduit tx_phy${n}_analogreset tx_analogreset tx_phy_analogreset_${n} output 1
|
||||
ad_conduit tx_phy${n}_digitalreset tx_digitalreset tx_phy_digitalreset_${n} output 1
|
||||
}
|
||||
}
|
||||
|
||||
if {$m_tx_or_rx_n == 0} {
|
||||
|
||||
ad_conduit rx_core_analogreset rx_analogreset rx_core_analogreset input $m_num_of_lanes
|
||||
ad_conduit rx_core_digitalreset rx_digitalreset rx_core_digitalreset input $m_num_of_lanes
|
||||
ad_conduit rx_core_is_lockedtodata rx_is_lockedtodata rx_core_locked output $m_num_of_lanes
|
||||
ad_conduit rx_core_cal_busy rx_cal_busy rx_core_cal_busy output $m_num_of_lanes
|
||||
|
||||
ad_conduit rx_ip_is_lockedtodata rx_is_lockedtodata rx_ip_locked output $m_num_of_lanes
|
||||
ad_conduit rx_ip_cal_busy rx_cal_busy rx_ip_cal_busy output $m_num_of_lanes
|
||||
ad_conduit rx_ip_pcs_data_valid export rx_ip_valid output $m_num_of_lanes
|
||||
ad_conduit rx_ip_pcs_data export rx_ip_data output 32*$m_num_of_lanes
|
||||
ad_conduit rx_ip_pcs_disperr export rx_ip_disperr output 4*$m_num_of_lanes
|
||||
ad_conduit rx_ip_pcs_errdetect export rx_ip_deterr output 4*$m_num_of_lanes
|
||||
ad_conduit rx_ip_pcs_kchar_data export rx_ip_kchar output 4*$m_num_of_lanes
|
||||
ad_conduit rx_ip_pcfifo_full export rx_ip_full output $m_num_of_lanes
|
||||
ad_conduit rx_ip_pcfifo_empty export rx_ip_empty output $m_num_of_lanes
|
||||
ad_conduit rx_ip_patternalign_en export rx_ip_align_en input $m_num_of_lanes
|
||||
ad_conduit rx_ip_csr_lane_polarity export rx_ip_lane_polarity input $m_num_of_lanes
|
||||
ad_conduit rx_ip_csr_lane_powerdown export rx_ip_lane_powerdown input $m_num_of_lanes
|
||||
ad_conduit rx_ip_csr_bit_reversal export rx_ip_bit_reversal input 1
|
||||
ad_conduit rx_ip_csr_byte_reversal export rx_ip_byte_reversal input 1
|
||||
|
||||
for {set n 0} {$n < $m_num_of_lanes} {incr n} {
|
||||
|
||||
ad_conduit rx_phy${n}_is_lockedtodata rx_is_lockedtodata rx_phy_locked_${n} input 1
|
||||
ad_conduit rx_phy${n}_cal_busy rx_cal_busy rx_phy_cal_busy_${n} input 1
|
||||
ad_conduit rx_phy${n}_pcs_data_valid export rx_phy_valid_${n} input 1
|
||||
ad_conduit rx_phy${n}_pcs_data export rx_phy_data_${n} input 32
|
||||
ad_conduit rx_phy${n}_pcs_disperr export rx_phy_disperr_${n} input 4
|
||||
ad_conduit rx_phy${n}_pcs_errdetect export rx_phy_deterr_${n} input 4
|
||||
ad_conduit rx_phy${n}_pcs_kchar_data export rx_phy_kchar_${n} input 4
|
||||
ad_conduit rx_phy${n}_pcfifo_full export rx_phy_full_${n} input 1
|
||||
ad_conduit rx_phy${n}_pcfifo_empty export rx_phy_empty_${n} input 1
|
||||
ad_conduit rx_phy${n}_patternalign_en export rx_phy_align_en_${n} output 1
|
||||
ad_conduit rx_phy${n}_csr_lane_polarity export rx_phy_lane_polarity_${n} output 1
|
||||
ad_conduit rx_phy${n}_csr_lane_powerdown export rx_phy_lane_powerdown_${n} output 1
|
||||
ad_conduit rx_phy${n}_csr_bit_reversal export rx_phy_bit_reversal_${n} output 1
|
||||
ad_conduit rx_phy${n}_csr_byte_reversal export rx_phy_byte_reversal_${n} output 1
|
||||
ad_conduit rx_phy${n}_analogreset rx_analogreset rx_phy_analogreset_${n} output 1
|
||||
ad_conduit rx_phy${n}_digitalreset rx_digitalreset rx_phy_digitalreset_${n} output 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := avl_dacfifo
|
||||
|
||||
INTEL_DEPS += ../../common/ad_b2g.v
|
||||
INTEL_DEPS += ../../common/ad_g2b.v
|
||||
INTEL_DEPS += ../../common/ad_mem.v
|
||||
INTEL_DEPS += ../../common/util_delay.v
|
||||
INTEL_DEPS += avl_dacfifo.v
|
||||
INTEL_DEPS += avl_dacfifo_constr.sdc
|
||||
INTEL_DEPS += avl_dacfifo_hw.tcl
|
||||
INTEL_DEPS += avl_dacfifo_rd.v
|
||||
INTEL_DEPS += avl_dacfifo_wr.v
|
||||
INTEL_DEPS += util_dacfifo_bypass.v
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,261 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module avl_dacfifo #(
|
||||
|
||||
parameter DAC_DATA_WIDTH = 64,
|
||||
parameter DAC_MEM_ADDRESS_WIDTH = 8,
|
||||
parameter DMA_DATA_WIDTH = 64,
|
||||
parameter DMA_MEM_ADDRESS_WIDTH = 10,
|
||||
parameter AVL_DATA_WIDTH = 512,
|
||||
parameter AVL_ADDRESS_WIDTH = 25,
|
||||
parameter AVL_BURST_LENGTH = 127,
|
||||
parameter AVL_BASE_ADDRESS = 32'h00000000,
|
||||
parameter AVL_ADDRESS_LIMIT = 32'h1fffffff) (
|
||||
|
||||
// dma interface
|
||||
|
||||
input dma_clk,
|
||||
input dma_rst,
|
||||
input dma_valid,
|
||||
input [(DMA_DATA_WIDTH-1):0] dma_data,
|
||||
output reg dma_ready,
|
||||
input dma_xfer_req,
|
||||
input dma_xfer_last,
|
||||
|
||||
// dac interface
|
||||
|
||||
input dac_clk,
|
||||
input dac_rst,
|
||||
input dac_valid,
|
||||
output reg [(DAC_DATA_WIDTH-1):0] dac_data,
|
||||
output reg dac_dunf,
|
||||
output reg dac_xfer_out,
|
||||
|
||||
input bypass,
|
||||
|
||||
// avalon interface
|
||||
|
||||
input avl_clk,
|
||||
input avl_reset,
|
||||
|
||||
output reg [(AVL_ADDRESS_WIDTH-1):0] avl_address,
|
||||
output reg [ 6:0] avl_burstcount,
|
||||
output reg [ 63:0] avl_byteenable,
|
||||
output avl_read,
|
||||
input [(AVL_DATA_WIDTH-1):0] avl_readdata,
|
||||
input avl_readdata_valid,
|
||||
input avl_ready,
|
||||
output avl_write,
|
||||
output [(AVL_DATA_WIDTH-1):0] avl_writedata);
|
||||
|
||||
localparam FIFO_BYPASS = (DAC_DATA_WIDTH == DMA_DATA_WIDTH) ? 1 : 0;
|
||||
|
||||
// internal register
|
||||
|
||||
reg dma_bypass_m1 = 1'b0;
|
||||
reg dma_bypass = 1'b0;
|
||||
reg dac_bypass_m1 = 1'b0;
|
||||
reg dac_bypass = 1'b0;
|
||||
reg dac_xfer_out_m1 = 1'b0;
|
||||
reg dac_xfer_out_bypass = 1'b0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire dma_ready_wr_s;
|
||||
wire dma_ready_bypass_s;
|
||||
wire avl_read_s;
|
||||
wire avl_write_s;
|
||||
wire [ 24:0] avl_wr_address_s;
|
||||
wire [ 24:0] avl_rd_address_s;
|
||||
wire [ 24:0] avl_last_address_s;
|
||||
wire [ 6:0] avl_last_burstcount_s;
|
||||
wire [ 7:0] dma_last_beats_s;
|
||||
wire [ 6:0] avl_wr_burstcount_s;
|
||||
wire [ 6:0] avl_rd_burstcount_s;
|
||||
wire [ 63:0] avl_wr_byteenable_s;
|
||||
wire [ 63:0] avl_rd_byteenable_s;
|
||||
wire avl_xfer_wren_s;
|
||||
wire avl_xfer_out_s;
|
||||
wire avl_xfer_in_s;
|
||||
wire [(DAC_DATA_WIDTH-1):0] dac_data_fifo_s;
|
||||
wire [(DAC_DATA_WIDTH-1):0] dac_data_bypass_s;
|
||||
wire dac_xfer_fifo_out_s;
|
||||
wire dac_dunf_fifo_s;
|
||||
wire dac_dunf_bypass_s;
|
||||
|
||||
avl_dacfifo_wr #(
|
||||
.AVL_DATA_WIDTH (AVL_DATA_WIDTH),
|
||||
.DMA_DATA_WIDTH (DMA_DATA_WIDTH),
|
||||
.AVL_DDR_BASE_ADDRESS (AVL_BASE_ADDRESS),
|
||||
.DMA_MEM_ADDRESS_WIDTH(DMA_MEM_ADDRESS_WIDTH),
|
||||
.AVL_BURST_LENGTH (AVL_BURST_LENGTH)
|
||||
) i_wr (
|
||||
.dma_clk (dma_clk),
|
||||
.dma_data (dma_data),
|
||||
.dma_ready (dma_ready),
|
||||
.dma_ready_out (dma_ready_wr_s),
|
||||
.dma_valid (dma_valid),
|
||||
.dma_xfer_req (dma_xfer_req),
|
||||
.dma_xfer_last (dma_xfer_last),
|
||||
.dma_last_beats (dma_last_beats_s),
|
||||
.avl_last_address (avl_last_address_s),
|
||||
.avl_last_burstcount (avl_last_burstcount_s),
|
||||
.avl_clk (avl_clk),
|
||||
.avl_reset (avl_reset),
|
||||
.avl_address (avl_wr_address_s),
|
||||
.avl_burstcount (avl_wr_burstcount_s),
|
||||
.avl_byteenable (avl_wr_byteenable_s),
|
||||
.avl_waitrequest (~avl_ready),
|
||||
.avl_write (avl_write),
|
||||
.avl_data (avl_writedata),
|
||||
.avl_xfer_req_out (avl_xfer_out_s),
|
||||
.avl_xfer_req_in (avl_xfer_in_s));
|
||||
|
||||
avl_dacfifo_rd #(
|
||||
.AVL_DATA_WIDTH(AVL_DATA_WIDTH),
|
||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
||||
.AVL_DDR_BASE_ADDRESS(AVL_BASE_ADDRESS),
|
||||
.AVL_DDR_ADDRESS_LIMIT(AVL_ADDRESS_LIMIT),
|
||||
.DAC_MEM_ADDRESS_WIDTH(DAC_MEM_ADDRESS_WIDTH),
|
||||
.AVL_BURST_LENGTH (AVL_BURST_LENGTH)
|
||||
) i_rd (
|
||||
.dac_clk(dac_clk),
|
||||
.dac_reset(dac_rst),
|
||||
.dac_valid(dac_valid),
|
||||
.dac_data(dac_data_fifo_s),
|
||||
.dac_xfer_req(dac_xfer_fifo_out_s),
|
||||
.dac_dunf(dac_dunf_fifo_s),
|
||||
.avl_clk(avl_clk),
|
||||
.avl_reset(avl_reset),
|
||||
.avl_address(avl_rd_address_s),
|
||||
.avl_burstcount(avl_rd_burstcount_s),
|
||||
.avl_byteenable(avl_rd_byteenable_s),
|
||||
.avl_waitrequest(~avl_ready),
|
||||
.avl_readdatavalid(avl_readdata_valid),
|
||||
.avl_read(avl_read),
|
||||
.avl_data(avl_readdata),
|
||||
.avl_last_address(avl_last_address_s),
|
||||
.avl_last_burstcount(avl_last_burstcount_s),
|
||||
.dma_last_beats(dma_last_beats_s),
|
||||
.avl_xfer_req_in(avl_xfer_out_s),
|
||||
.avl_xfer_req_out(avl_xfer_in_s));
|
||||
|
||||
// avalon address multiplexer and output registers
|
||||
|
||||
assign avl_xfer_wren_s = ~avl_xfer_in_s;
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_address <= 0;
|
||||
avl_burstcount <= 0;
|
||||
avl_byteenable <= 0;
|
||||
end else if (avl_ready) begin
|
||||
avl_address <= (avl_xfer_wren_s == 1'b1) ? avl_wr_address_s : avl_rd_address_s;
|
||||
avl_burstcount <= (avl_xfer_wren_s == 1'b1) ? avl_wr_burstcount_s : avl_rd_burstcount_s;
|
||||
avl_byteenable <= (avl_xfer_wren_s == 1'b1) ? avl_wr_byteenable_s : avl_rd_byteenable_s;
|
||||
end
|
||||
end
|
||||
|
||||
// bypass logic -- supported if DAC_DATA_WIDTH == DMA_DATA_WIDTH
|
||||
|
||||
generate
|
||||
if (FIFO_BYPASS) begin
|
||||
|
||||
util_dacfifo_bypass #(
|
||||
.DAC_DATA_WIDTH (DAC_DATA_WIDTH),
|
||||
.DMA_DATA_WIDTH (DMA_DATA_WIDTH)
|
||||
) i_dacfifo_bypass (
|
||||
.dma_clk(dma_clk),
|
||||
.dma_data(dma_data),
|
||||
.dma_ready(dma_ready),
|
||||
.dma_ready_out(dma_ready_bypass_s),
|
||||
.dma_valid(dma_valid),
|
||||
.dma_xfer_req(dma_xfer_req),
|
||||
.dac_clk(dac_clk),
|
||||
.dac_rst(dac_rst),
|
||||
.dac_valid(dac_valid),
|
||||
.dac_data(dac_data_bypass_s),
|
||||
.dac_dunf(dac_dunf_bypass_s)
|
||||
);
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
dma_bypass_m1 <= bypass;
|
||||
dma_bypass <= dma_bypass_m1;
|
||||
end
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
dac_bypass_m1 <= bypass;
|
||||
dac_bypass <= dac_bypass_m1;
|
||||
dac_xfer_out_m1 <= dma_xfer_req;
|
||||
dac_xfer_out_bypass <= dac_xfer_out_m1;
|
||||
end
|
||||
|
||||
// mux for the dma_ready
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
dma_ready <= (dma_bypass) ? dma_ready_bypass_s : dma_ready_wr_s;
|
||||
end
|
||||
|
||||
// mux for dac data
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_valid) begin
|
||||
dac_data <= (dac_bypass) ? dac_data_bypass_s : dac_data_fifo_s;
|
||||
end
|
||||
dac_xfer_out <= (dac_bypass) ? dac_xfer_out_bypass : dac_xfer_fifo_out_s;
|
||||
dac_dunf <= (dac_bypass) ? dac_dunf_bypass_s : dac_dunf_fifo_s;
|
||||
end
|
||||
|
||||
end else begin /* if (~FIFO_BYPASS) */
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
dma_ready <= dma_ready_wr_s;
|
||||
end
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_valid) begin
|
||||
dac_data <= dac_data_fifo_s;
|
||||
end
|
||||
dac_xfer_out <= dac_xfer_fifo_out_s;
|
||||
dac_dunf <= dac_dunf_fifo_s;
|
||||
end
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# CDC paths
|
||||
|
||||
set_false_path -from [get_registers *avl_dacfifo_rd:i_rd|dac_mem_raddr_g*] \
|
||||
-to [get_registers *avl_dacfifo_rd:i_rd|avl_mem_raddr_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_rd:i_rd|avl_mem_waddr_g*] \
|
||||
-to [get_registers *avl_dacfifo_rd:i_rd|dac_mem_waddr_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_rd:i_rd|avl_xfer_req_out*] \
|
||||
-to [get_registers *avl_dacfifo_rd:i_rd|dac_avl_xfer_req_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_rd:i_rd|avl_mem_laddr_toggle*] \
|
||||
-to [get_registers *avl_dacfifo_rd:i_rd|dac_mem_laddr_toggle_m[0]]
|
||||
set_false_path -to [get_registers *avl_dacfifo_rd:i_rd|dac_mem_laddr*]
|
||||
set_false_path -to [get_registers *avl_dacfifo_rd:i_rd|dac_dma_last_beats_m1*]
|
||||
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|avl_xfer_req_lp*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|dma_xfer_req_lp_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|avl_xfer_req_out*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|dma_avl_xfer_req_out_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|avl_mem_raddr_g*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|dma_mem_raddr_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|dma_xfer_req*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|avl_dma_xfer_req_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|dma_mem_waddr_g*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|avl_mem_waddr_m1*]
|
||||
set_false_path -from [get_registers *avl_dacfifo_wr:i_wr|dma_last_beats*] \
|
||||
-to [get_registers *avl_dacfifo_wr:i_wr|avl_dma_last_beats_m1*]
|
||||
|
||||
set_false_path -from [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dac_mem_raddr_g*] \
|
||||
-to [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dma_mem_raddr_m1*]
|
||||
|
||||
set_false_path -from [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dma_mem_waddr_g*] \
|
||||
-to [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dac_mem_waddr_m1*]
|
||||
set_false_path -to [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dac_xfer_out_m1*]
|
||||
|
||||
set_false_path -to [get_registers *avl_dacfifo:*avl_dma_xfer_req_m1*]
|
||||
set_false_path -to [get_registers *avl_dacfifo:*dac_xfer_out_m1*]
|
||||
set_false_path -to [get_registers *avl_dacfifo:*bypass_m1*]
|
||||
|
||||
set_false_path -to [get_registers *util_dacfifo_bypass:i_dacfifo_bypass|dma_rst_m1*]
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
|
||||
package require qsys
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
ad_ip_create avl_dacfifo {Avalon DDR DAC Fifo} p_avl_dacfifo_elab
|
||||
ad_ip_files avl_dacfifo [list\
|
||||
$ad_hdl_dir/library/common/util_delay.v \
|
||||
$ad_hdl_dir/library/common/ad_b2g.v \
|
||||
$ad_hdl_dir/library/common/ad_g2b.v \
|
||||
$ad_hdl_dir/library/common/ad_mem.v \
|
||||
util_dacfifo_bypass.v \
|
||||
avl_dacfifo_wr.v \
|
||||
avl_dacfifo_rd.v \
|
||||
avl_dacfifo.v \
|
||||
avl_dacfifo_constr.sdc]
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE_FAMILY STRING {Arria 10}
|
||||
ad_ip_parameter DAC_DATA_WIDTH INTEGER 64
|
||||
ad_ip_parameter DAC_MEM_ADDRESS_WIDTH INTEGER 8
|
||||
ad_ip_parameter DMA_DATA_WIDTH INTEGER 64
|
||||
ad_ip_parameter DMA_MEM_ADDRESS_WIDTH INTEGER 8
|
||||
ad_ip_parameter AVL_DATA_WIDTH INTEGER 512
|
||||
ad_ip_parameter AVL_ADDRESS_WIDTH INTEGER 25
|
||||
ad_ip_parameter AVL_BURST_LENGTH INTEGER 127
|
||||
ad_ip_parameter AVL_BASE_ADDRESS INTEGER 0
|
||||
ad_ip_parameter AVL_ADDRESS_LIMIT INTEGER 0x800000
|
||||
|
||||
# interfaces
|
||||
|
||||
ad_interface clock dma_clk input 1 clk
|
||||
ad_interface reset dma_rst input 1 if_dma_clk
|
||||
ad_interface signal dma_xfer_req input 1 xfer_req
|
||||
|
||||
add_interface s_axis axi4stream end
|
||||
set_interface_property s_axis associatedClock if_dma_clk
|
||||
set_interface_property s_axis associatedReset if_dma_rst
|
||||
add_interface_port s_axis dma_valid tvalid Input 1
|
||||
add_interface_port s_axis dma_xfer_last tlast Input 1
|
||||
add_interface_port s_axis dma_ready tready Output 1
|
||||
add_interface_port s_axis dma_data tdata Input DMA_DATA_WIDTH
|
||||
|
||||
ad_interface clock dac_clk input 1 clk
|
||||
ad_interface reset dac_rst input 1 if_dac_clk
|
||||
ad_interface signal dac_valid input 1 valid
|
||||
ad_interface signal dac_data output DAC_DATA_WIDTH data
|
||||
ad_interface signal dac_dunf output 1 unf
|
||||
ad_interface signal dac_xfer_out output 1 xfer_out
|
||||
|
||||
ad_interface signal bypass input 1 bypass
|
||||
|
||||
add_interface avl_clock clock end
|
||||
add_interface_port avl_clock avl_clk clk input 1
|
||||
|
||||
add_interface avl_reset reset end
|
||||
set_interface_property avl_reset associatedclock avl_clock
|
||||
add_interface_port avl_reset avl_reset reset input 1
|
||||
|
||||
add_interface amm_ddr avalon master
|
||||
add_interface_port amm_ddr avl_address address output 25
|
||||
add_interface_port amm_ddr avl_burstcount burstcount output 7
|
||||
add_interface_port amm_ddr avl_byteenable byteenable output 64
|
||||
add_interface_port amm_ddr avl_read read output 1
|
||||
add_interface_port amm_ddr avl_readdata readdata input 512
|
||||
add_interface_port amm_ddr avl_readdata_valid readdatavalid input 1
|
||||
add_interface_port amm_ddr avl_ready waitrequest_n input 1
|
||||
add_interface_port amm_ddr avl_write write output 1
|
||||
add_interface_port amm_ddr avl_writedata writedata output 512
|
||||
|
||||
set_interface_property amm_ddr associatedClock avl_clock
|
||||
set_interface_property amm_ddr associatedReset avl_reset
|
||||
set_interface_property amm_ddr addressUnits WORDS
|
||||
|
||||
# elaborate
|
||||
|
||||
proc p_avl_dacfifo_elab {} {
|
||||
|
||||
# read parameters
|
||||
|
||||
set m_device_family [get_parameter_value "DEVICE_FAMILY"]
|
||||
set m_dma_data_width [get_parameter_value "DMA_DATA_WIDTH"]
|
||||
set m_dma_mem_addr_width [get_parameter_value "DMA_MEM_ADDRESS_WIDTH"]
|
||||
set m_avl_data_width [get_parameter_value "AVL_DATA_WIDTH"]
|
||||
set m_avl_addr_width [get_parameter_value "AVL_ADDRESS_WIDTH"]
|
||||
set m_dac_data_width [get_parameter_value "DAC_DATA_WIDTH"]
|
||||
set m_dac_mem_addr_width [get_parameter_value "DAC_MEM_ADDRESS_WIDTH"]
|
||||
set m_dac_mem_addr_width_bypass 10
|
||||
if {$m_dma_data_width > $m_dac_data_width} {
|
||||
set m_dma_to_dac_ratio [expr $m_dma_data_width/$m_dac_data_width]
|
||||
if {$m_dma_to_dac_ratio eq 2} {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 1]
|
||||
} elseif {$m_dma_to_dac_ratio eq 4} {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 2]
|
||||
} else {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 3]
|
||||
}
|
||||
} else {
|
||||
set m_dma_to_dac_ratio [expr $m_dac_data_width/$m_dma_data_width]
|
||||
if {$m_dma_to_dac_ratio eq 1} {
|
||||
set m_dma_mem_addr_width_bypass $m_dac_mem_addr_width_bypass
|
||||
} elseif {$m_dma_to_dac_ratio eq 2} {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 1]
|
||||
} elseif {$m_dma_to_dac_ratio eq 4} {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 2]
|
||||
} else {
|
||||
set m_dma_mem_addr_width_bypass [expr $m_dac_mem_addr_width_bypass - 3]
|
||||
}
|
||||
}
|
||||
|
||||
# intel memory for WRITE side
|
||||
|
||||
add_hdl_instance ad_mem_asym_wr intel_mem_asym 1.0
|
||||
set_instance_parameter_value ad_mem_asym_wr DEVICE_FAMILY $m_device_family
|
||||
set_instance_parameter_value ad_mem_asym_wr A_ADDRESS_WIDTH $m_dma_mem_addr_width
|
||||
set_instance_parameter_value ad_mem_asym_wr A_DATA_WIDTH $m_dma_data_width
|
||||
set_instance_parameter_value ad_mem_asym_wr B_DATA_WIDTH $m_avl_data_width
|
||||
|
||||
# intel memory for READ side
|
||||
|
||||
add_hdl_instance ad_mem_asym_rd intel_mem_asym 1.0
|
||||
set_instance_parameter_value ad_mem_asym_rd DEVICE_FAMILY $m_device_family
|
||||
set_instance_parameter_value ad_mem_asym_rd A_ADDRESS_WIDTH 0
|
||||
set_instance_parameter_value ad_mem_asym_rd A_DATA_WIDTH $m_avl_data_width
|
||||
set_instance_parameter_value ad_mem_asym_rd B_ADDRESS_WIDTH $m_dac_mem_addr_width
|
||||
set_instance_parameter_value ad_mem_asym_rd B_DATA_WIDTH $m_dac_data_width
|
||||
|
||||
# intel memory for bypass logic
|
||||
|
||||
add_hdl_instance ad_mem_asym_bypass intel_mem_asym 1.0
|
||||
set_instance_parameter_value ad_mem_asym_bypass DEVICE_FAMILY $m_device_family
|
||||
set_instance_parameter_value ad_mem_asym_bypass A_ADDRESS_WIDTH $m_dma_mem_addr_width_bypass
|
||||
set_instance_parameter_value ad_mem_asym_bypass A_DATA_WIDTH $m_dma_data_width
|
||||
set_instance_parameter_value ad_mem_asym_bypass B_ADDRESS_WIDTH $m_dac_mem_addr_width_bypass
|
||||
set_instance_parameter_value ad_mem_asym_bypass B_DATA_WIDTH $m_dac_data_width
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,540 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module avl_dacfifo_rd #(
|
||||
|
||||
parameter AVL_DATA_WIDTH = 512,
|
||||
parameter DAC_DATA_WIDTH = 64,
|
||||
parameter AVL_BURST_LENGTH = 127,
|
||||
parameter AVL_DDR_BASE_ADDRESS = 0,
|
||||
parameter AVL_DDR_ADDRESS_LIMIT = 33554432,
|
||||
parameter DAC_MEM_ADDRESS_WIDTH = 8)(
|
||||
|
||||
input dac_clk,
|
||||
input dac_reset,
|
||||
input dac_valid,
|
||||
output reg [(DAC_DATA_WIDTH-1):0] dac_data,
|
||||
output reg dac_xfer_req,
|
||||
output reg dac_dunf,
|
||||
|
||||
input avl_clk,
|
||||
input avl_reset,
|
||||
output reg [24:0] avl_address,
|
||||
output reg [ 6:0] avl_burstcount,
|
||||
output [63:0] avl_byteenable,
|
||||
input avl_waitrequest,
|
||||
input avl_readdatavalid,
|
||||
output reg avl_read,
|
||||
input [AVL_DATA_WIDTH-1:0] avl_data,
|
||||
|
||||
input [24:0] avl_last_address,
|
||||
input [ 6:0] avl_last_burstcount,
|
||||
input [ 7:0] dma_last_beats,
|
||||
input avl_xfer_req_in,
|
||||
output reg avl_xfer_req_out);
|
||||
|
||||
// Max supported MEM_RATIO is 16
|
||||
localparam MEM_RATIO = AVL_DATA_WIDTH/DAC_DATA_WIDTH;
|
||||
localparam AVL_MEM_ADDRESS_WIDTH = (MEM_RATIO == 1) ? DAC_MEM_ADDRESS_WIDTH :
|
||||
(MEM_RATIO == 2) ? (DAC_MEM_ADDRESS_WIDTH - 1) :
|
||||
(MEM_RATIO == 4) ? (DAC_MEM_ADDRESS_WIDTH - 2) :
|
||||
(MEM_RATIO == 8) ? (DAC_MEM_ADDRESS_WIDTH - 3) :
|
||||
(MEM_RATIO == 16) ? (DAC_MEM_ADDRESS_WIDTH - 4) :
|
||||
(DAC_MEM_ADDRESS_WIDTH - 5);
|
||||
localparam AVL_MEM_THRESHOLD_LO = AVL_BURST_LENGTH;
|
||||
localparam AVL_MEM_THRESHOLD_HI = {(AVL_MEM_ADDRESS_WIDTH){1'b1}} - AVL_BURST_LENGTH;
|
||||
localparam DAC_MEM_THRESHOLD = 2 * (AVL_BURST_LENGTH * MEM_RATIO);
|
||||
|
||||
localparam MEM_WIDTH_DIFF = (MEM_RATIO > 16) ? 5 :
|
||||
(MEM_RATIO > 8) ? 4 :
|
||||
(MEM_RATIO > 4) ? 3 :
|
||||
(MEM_RATIO > 2) ? 2 :
|
||||
(MEM_RATIO > 1) ? 1 : 1;
|
||||
|
||||
// FSM state definition
|
||||
|
||||
localparam IDLE = 5'b00001;
|
||||
localparam XFER_STAGING = 5'b00010;
|
||||
localparam XFER_FULL_BURST = 5'b00100;
|
||||
localparam XFER_PARTIAL_BURST = 5'b01000;
|
||||
localparam XFER_END = 5'b10000;
|
||||
|
||||
// internal register
|
||||
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_laddr;
|
||||
reg avl_mem_laddr_toggle;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr_g;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_m1;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_m2;
|
||||
reg avl_mem_request_data;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_addr_diff;
|
||||
reg [ 4:0] avl_read_state;
|
||||
reg [ 7:0] avl_burstcounter;
|
||||
reg avl_inread;
|
||||
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dac_mem_waddr;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dac_mem_waddr_m1;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dac_mem_waddr_m2;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_laddr;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_raddr;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_raddr_g;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_addr_diff;
|
||||
reg [ 7:0] dac_mem_laddr_waddr;
|
||||
reg [ 7:0] dac_mem_laddr_raddr;
|
||||
reg dac_mem_laddr_valid;
|
||||
|
||||
reg dac_avl_xfer_req;
|
||||
reg dac_avl_xfer_req_m1;
|
||||
reg dac_avl_xfer_req_m2;
|
||||
|
||||
reg [ 7:0] dac_dma_last_beats_m1;
|
||||
reg [ 7:0] dac_dma_last_beats_m2;
|
||||
reg [ 7:0] dac_dma_last_beats;
|
||||
reg [ 3:0] dac_mem_laddr_toggle_m;
|
||||
reg [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_laddr_b;
|
||||
reg dac_mem_renable;
|
||||
reg dac_mem_valid;
|
||||
reg dac_xfer_req_d;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire avl_fifo_reset_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH:0] avl_mem_addr_diff_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr_b2g_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_g2b_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH-1:0] avl_mem_laddr_s;
|
||||
wire avl_read_int_s;
|
||||
wire avl_end_of_burst_s;
|
||||
|
||||
wire dac_fifo_reset_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH:0] dac_mem_addr_diff_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_waddr_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] dac_mem_waddr_g2b_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_raddr_b2g_s;
|
||||
wire [DAC_DATA_WIDTH-1:0] dac_mem_data_s;
|
||||
wire dac_mem_laddr_wea_s;
|
||||
wire dac_mem_laddr_rea_s;
|
||||
wire dac_mem_laddr_unf_s;
|
||||
wire [DAC_MEM_ADDRESS_WIDTH-1:0] dac_mem_laddr_s;
|
||||
wire dac_mem_dunf_s;
|
||||
|
||||
// An asymmetric memory to transfer data from Avalon interface to DAC
|
||||
// interface
|
||||
|
||||
ad_mem_asym_rd i_mem_asym (
|
||||
.mem_i_wrclock_clk (avl_clk),
|
||||
.mem_i_wren_wren (avl_readdatavalid),
|
||||
.mem_i_wraddress_wraddress (avl_mem_waddr),
|
||||
.mem_i_datain_datain (avl_data),
|
||||
.mem_i_rdclock_clk (dac_clk),
|
||||
.mem_i_rdaddress_rdaddress (dac_mem_raddr),
|
||||
.mem_o_dataout_dataout (dac_mem_data_s));
|
||||
|
||||
// the fifo reset is the dma_xfer_req
|
||||
|
||||
assign avl_fifo_reset_s = avl_reset || ~avl_xfer_req_out;
|
||||
assign dac_fifo_reset_s = dac_reset || ~dac_avl_xfer_req;
|
||||
|
||||
// loop back the avl_xfer_req to the WRITE module -- this way we can make
|
||||
// sure, that in case of a new DMA transfer, the last avalon read burst is
|
||||
// finished, so the upcomming avalon writes will not block the interface
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_xfer_req_out <= 1'b0;
|
||||
end else begin
|
||||
if ((avl_read_state == IDLE) ||
|
||||
(avl_read_state == XFER_STAGING) ||
|
||||
(avl_read_state == XFER_END)) begin
|
||||
avl_xfer_req_out <= avl_xfer_req_in;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// FSM to generate the necessary Avalon Write transactions
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_read_state <= IDLE;
|
||||
avl_burstcount <= AVL_BURST_LENGTH;
|
||||
end else begin
|
||||
case (avl_read_state)
|
||||
IDLE : begin
|
||||
if (avl_xfer_req_in == 1'b1) begin
|
||||
avl_read_state <= XFER_STAGING;
|
||||
end else begin
|
||||
avl_read_state <= IDLE;
|
||||
end
|
||||
end
|
||||
XFER_STAGING : begin
|
||||
if (avl_xfer_req_in == 1'b1) begin
|
||||
if (avl_mem_request_data == 1'b1) begin
|
||||
if (avl_address + AVL_BURST_LENGTH <= avl_last_address) begin
|
||||
avl_read_state <= XFER_FULL_BURST;
|
||||
avl_burstcount <= AVL_BURST_LENGTH;
|
||||
end else begin
|
||||
avl_read_state <= XFER_PARTIAL_BURST;
|
||||
avl_burstcount <= avl_last_burstcount;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
avl_read_state <= IDLE;
|
||||
end
|
||||
end
|
||||
// Avalon transaction with full burst length
|
||||
XFER_FULL_BURST : begin
|
||||
if (avl_burstcounter < avl_burstcount) begin
|
||||
avl_read_state <= XFER_FULL_BURST;
|
||||
end else begin
|
||||
avl_read_state <= XFER_STAGING;
|
||||
end
|
||||
end
|
||||
// Avalon transaction with the remaining data, burst length is less than
|
||||
// the maximum supported burst length
|
||||
XFER_PARTIAL_BURST : begin
|
||||
if (avl_burstcounter < avl_burstcount) begin
|
||||
avl_read_state <= XFER_PARTIAL_BURST;
|
||||
end else begin
|
||||
avl_read_state <= XFER_END;
|
||||
end
|
||||
end
|
||||
XFER_END : begin
|
||||
avl_read_state <= IDLE;
|
||||
end
|
||||
default : begin
|
||||
avl_read_state <= IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// FSM outputs
|
||||
|
||||
assign avl_read_int_s = ((avl_read_state == XFER_FULL_BURST) ||
|
||||
(avl_read_state == XFER_PARTIAL_BURST)) ? 1 : 0;
|
||||
assign avl_end_of_burst_s = (avl_burstcount == avl_burstcounter) ? 1 : 0;
|
||||
|
||||
// Avalon address generation and read control signaling
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_address <= AVL_DDR_BASE_ADDRESS;
|
||||
end else begin
|
||||
if (avl_end_of_burst_s == 1'b1) begin
|
||||
avl_address <= (avl_address < avl_last_address) ? avl_address + avl_burstcount : AVL_DDR_BASE_ADDRESS;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_read <= 1'b0;
|
||||
avl_inread <= 1'b0;
|
||||
end else begin
|
||||
if (avl_read == 1'b0) begin
|
||||
if ((avl_waitrequest == 1'b0) && (avl_read_int_s == 1'b1) && (avl_inread == 1'b0)) begin
|
||||
avl_read <= 1'b1;
|
||||
avl_inread <= 1'b1;
|
||||
end
|
||||
end else if ((avl_read == 1'b1) && (avl_waitrequest == 1'b0)) begin
|
||||
avl_read <= 1'b0;
|
||||
end
|
||||
if (avl_end_of_burst_s == 1'b1) begin
|
||||
avl_inread <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Avalon burstcounter
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_burstcounter <= 8'b0;
|
||||
end else begin
|
||||
if ((avl_read_int_s == 1'b1) && (avl_readdatavalid == 1'b1)) begin
|
||||
avl_burstcounter <= (avl_burstcounter < avl_burstcount) ? avl_burstcounter + 1'b1 : 1'b0;
|
||||
end else if (avl_end_of_burst_s == 1'b1) begin
|
||||
avl_burstcounter <= 8'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign avl_byteenable = {64{1'b1}};
|
||||
|
||||
// write data from Avalon interface into the async FIFO
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_mem_waddr <= 'b0;
|
||||
avl_mem_waddr_g <= 'b0;
|
||||
avl_mem_laddr <= 'b0;
|
||||
avl_mem_laddr_toggle <= 1'b0;
|
||||
end else begin
|
||||
if (avl_readdatavalid == 1'b1) begin
|
||||
avl_mem_waddr <= avl_mem_waddr + 1'b1;
|
||||
end
|
||||
if (avl_read_state == XFER_END) begin
|
||||
avl_mem_laddr <= avl_mem_waddr - 1'b1;
|
||||
avl_mem_laddr_toggle <= ~avl_mem_laddr_toggle;
|
||||
end
|
||||
avl_mem_waddr_g <= avl_mem_waddr_b2g_s;
|
||||
end
|
||||
end
|
||||
|
||||
ad_b2g #(
|
||||
.DATA_WIDTH(AVL_MEM_ADDRESS_WIDTH)
|
||||
) i_avl_mem_wr_addr_b2g (
|
||||
.din (avl_mem_waddr),
|
||||
.dout (avl_mem_waddr_b2g_s));
|
||||
|
||||
// control the FIFO to prevent overflow, underflow is monitored
|
||||
|
||||
assign avl_mem_raddr_s = (MEM_RATIO == 1) ? avl_mem_raddr :
|
||||
(MEM_RATIO == 2) ? avl_mem_raddr[(DAC_MEM_ADDRESS_WIDTH-1):1] :
|
||||
(MEM_RATIO == 4) ? avl_mem_raddr[(DAC_MEM_ADDRESS_WIDTH-1):2] :
|
||||
(MEM_RATIO == 8) ? avl_mem_raddr[(DAC_MEM_ADDRESS_WIDTH-1):3] :
|
||||
(MEM_RATIO == 16) ? avl_mem_raddr[(DAC_MEM_ADDRESS_WIDTH-1):4] :
|
||||
avl_mem_raddr[(DAC_MEM_ADDRESS_WIDTH-1):5];
|
||||
|
||||
assign avl_mem_laddr_s = (MEM_RATIO == 1) ? avl_mem_laddr :
|
||||
(MEM_RATIO == 2) ? {avl_mem_laddr, 1'b0} :
|
||||
(MEM_RATIO == 4) ? {avl_mem_laddr, 2'b0} :
|
||||
(MEM_RATIO == 8) ? {avl_mem_laddr, 3'b0} :
|
||||
(MEM_RATIO == 16) ? {avl_mem_laddr, 4'b0} :
|
||||
{avl_mem_laddr, 5'b0};
|
||||
|
||||
assign avl_mem_addr_diff_s = {1'b1, avl_mem_waddr} - avl_mem_raddr_s;
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_mem_addr_diff <= 'd0;
|
||||
avl_mem_raddr <= 'd0;
|
||||
avl_mem_raddr_m1 <= 'd0;
|
||||
avl_mem_raddr_m2 <= 'd0;
|
||||
avl_mem_request_data <= 'd0;
|
||||
end else begin
|
||||
avl_mem_raddr_m1 <= dac_mem_raddr_g;
|
||||
avl_mem_raddr_m2 <= avl_mem_raddr_m1;
|
||||
avl_mem_raddr <= avl_mem_raddr_g2b_s;
|
||||
avl_mem_addr_diff <= avl_mem_addr_diff_s[AVL_MEM_ADDRESS_WIDTH-1:0];
|
||||
if (avl_xfer_req_out == 1'b0) begin
|
||||
avl_mem_request_data <= 1'b0;
|
||||
end else if (avl_mem_addr_diff >= AVL_MEM_THRESHOLD_HI) begin
|
||||
avl_mem_request_data <= 1'b0;
|
||||
end else if (avl_mem_addr_diff <= AVL_MEM_THRESHOLD_LO) begin
|
||||
avl_mem_request_data <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ad_g2b #(
|
||||
.DATA_WIDTH(DAC_MEM_ADDRESS_WIDTH)
|
||||
) i_avl_mem_rd_addr_g2b (
|
||||
.din (avl_mem_raddr_m2),
|
||||
.dout (avl_mem_raddr_g2b_s));
|
||||
|
||||
// Push data from the async FIFO to the DAC
|
||||
// Data flow is controlled by the DAC, no back-pressure. If FIFO is not
|
||||
// ready, data will be dropped
|
||||
|
||||
assign dac_mem_waddr_s = (MEM_RATIO == 1) ? dac_mem_waddr :
|
||||
(MEM_RATIO == 2) ? {dac_mem_waddr, 1'b0} :
|
||||
(MEM_RATIO == 4) ? {dac_mem_waddr, 2'b0} :
|
||||
(MEM_RATIO == 8) ? {dac_mem_waddr, 3'b0} :
|
||||
(MEM_RATIO == 16) ? {dac_mem_waddr, 4'b0} :
|
||||
{dac_mem_waddr, 5'b0};
|
||||
|
||||
assign dac_mem_addr_diff_s = {1'b1, dac_mem_waddr_s} - dac_mem_raddr;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_mem_waddr_m2 <= 0;
|
||||
dac_mem_waddr_m1 <= 0;
|
||||
dac_mem_waddr <= 0;
|
||||
dac_mem_laddr <= 0;
|
||||
dac_mem_laddr_toggle_m <= 4'b0;
|
||||
end else begin
|
||||
dac_mem_waddr_m1 <= avl_mem_waddr_g;
|
||||
dac_mem_waddr_m2 <= dac_mem_waddr_m1;
|
||||
dac_mem_waddr <= dac_mem_waddr_g2b_s;
|
||||
dac_mem_laddr_toggle_m <= {dac_mem_laddr_toggle_m[2:0], avl_mem_laddr_toggle};
|
||||
dac_mem_laddr <= (dac_mem_laddr_toggle_m[2] ^ dac_mem_laddr_toggle_m[1]) ?
|
||||
avl_mem_laddr_s :
|
||||
dac_mem_laddr;
|
||||
end
|
||||
end
|
||||
|
||||
// A buffer for storing the dac_mem_laddr (the address of the last avalon
|
||||
// beat inside the CDC fifo)
|
||||
// If the stored data sequence is smaller, it can happen that multiple
|
||||
// dac_mem_laddr values exist in the same time. This buffers stores this
|
||||
// values and make sure that they are feeded to the read logic in order.
|
||||
|
||||
assign dac_mem_laddr_wea_s = dac_mem_laddr_toggle_m[3] ^ dac_mem_laddr_toggle_m[2];
|
||||
assign dac_mem_laddr_rea_s = ((dac_mem_raddr == dac_mem_laddr_b) &&
|
||||
(dac_mem_laddr_unf_s == 1'b0)) ? 1'b1 :1'b0;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_mem_laddr_waddr <= 0;
|
||||
dac_mem_laddr_raddr <= 0;
|
||||
end else begin
|
||||
dac_mem_laddr_waddr <= (dac_mem_laddr_wea_s == 1'b1) ? dac_mem_laddr_waddr + 1 : dac_mem_laddr_waddr;
|
||||
dac_mem_laddr_raddr <= (dac_mem_laddr_rea_s == 1'b1) ? dac_mem_laddr_raddr + 1 : dac_mem_laddr_raddr;
|
||||
end
|
||||
end
|
||||
assign dac_mem_laddr_unf_s = (dac_mem_laddr_waddr == dac_mem_laddr_raddr) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_mem_laddr_valid <= 1'b0;
|
||||
end else begin
|
||||
if (dac_mem_laddr_wea_s == 1'b1)
|
||||
dac_mem_laddr_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
ad_mem #(
|
||||
.DATA_WIDTH (DAC_MEM_ADDRESS_WIDTH),
|
||||
.ADDRESS_WIDTH (8))
|
||||
i_mem (
|
||||
.clka (dac_clk),
|
||||
.wea (dac_mem_laddr_wea_s),
|
||||
.addra (dac_mem_laddr_waddr),
|
||||
.dina (dac_mem_laddr),
|
||||
.clkb (dac_clk),
|
||||
.reb (1'b1),
|
||||
.addrb (dac_mem_laddr_raddr),
|
||||
.doutb (dac_mem_laddr_s));
|
||||
|
||||
ad_g2b #(
|
||||
.DATA_WIDTH(AVL_MEM_ADDRESS_WIDTH)
|
||||
) i_dac_mem_wr_addr_g2b (
|
||||
.din (dac_mem_waddr_m2),
|
||||
.dout (dac_mem_waddr_g2b_s));
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_reset == 1'b1) begin
|
||||
dac_avl_xfer_req_m2 <= 0;
|
||||
dac_avl_xfer_req_m1 <= 0;
|
||||
dac_avl_xfer_req <= 0;
|
||||
end else begin
|
||||
dac_avl_xfer_req_m1 <= avl_xfer_req_out;
|
||||
dac_avl_xfer_req_m2 <= dac_avl_xfer_req_m1;
|
||||
dac_avl_xfer_req <= dac_avl_xfer_req_m2;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_reset == 1'b1) begin
|
||||
dac_dma_last_beats_m2 <= 0;
|
||||
dac_dma_last_beats_m1 <= 0;
|
||||
dac_dma_last_beats <= 0;
|
||||
end else begin
|
||||
dac_dma_last_beats_m1 <= dma_last_beats;
|
||||
dac_dma_last_beats_m2 <= dac_dma_last_beats_m1;
|
||||
dac_dma_last_beats <= dac_dma_last_beats_m2;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_mem_renable <= 1'b0;
|
||||
dac_mem_valid <= 1'b0;
|
||||
end else begin
|
||||
if (dac_mem_dunf_s == 1'b1) begin
|
||||
dac_mem_renable <= 1'b0;
|
||||
end else if (dac_mem_addr_diff >= DAC_MEM_THRESHOLD) begin
|
||||
dac_mem_renable <= 1'b1;
|
||||
end
|
||||
dac_mem_valid <= (dac_mem_renable) ? dac_valid : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
assign dac_mem_dunf_s = (dac_mem_addr_diff_s[DAC_MEM_ADDRESS_WIDTH-1:0] == {DAC_MEM_ADDRESS_WIDTH{1'b0}}) ? 1'b1 : 1'b0;
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_mem_raddr <= 0;
|
||||
dac_mem_raddr_g <= 0;
|
||||
dac_mem_addr_diff <= 0;
|
||||
dac_mem_laddr_b <= 0;
|
||||
end else begin
|
||||
dac_mem_laddr_b <= (!dac_mem_laddr_unf_s) ? dac_mem_laddr_s : dac_mem_laddr_b;
|
||||
dac_mem_addr_diff <= dac_mem_addr_diff_s[DAC_MEM_ADDRESS_WIDTH-1:0];
|
||||
if (dac_mem_valid) begin
|
||||
if ((dac_dma_last_beats != {MEM_WIDTH_DIFF{1'b1}}) &&
|
||||
(dac_mem_raddr == (dac_mem_laddr_b + dac_dma_last_beats)) &&
|
||||
(dac_mem_laddr_valid == 1'b1)) begin
|
||||
dac_mem_raddr <= dac_mem_raddr + (MEM_RATIO - dac_dma_last_beats);
|
||||
end else begin
|
||||
dac_mem_raddr <= dac_mem_raddr + 1'b1;
|
||||
end
|
||||
end
|
||||
dac_mem_raddr_g <= dac_mem_raddr_b2g_s;
|
||||
end
|
||||
end
|
||||
|
||||
ad_b2g #(
|
||||
.DATA_WIDTH(DAC_MEM_ADDRESS_WIDTH)
|
||||
) i_dac_mem_rd_addr_b2g (
|
||||
.din (dac_mem_raddr),
|
||||
.dout (dac_mem_raddr_b2g_s));
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_xfer_req <= 1'b0;
|
||||
dac_xfer_req_d <= 1'b0;
|
||||
dac_data <= {DAC_DATA_WIDTH{1'b0}};
|
||||
end else begin
|
||||
dac_xfer_req_d <= dac_mem_renable;
|
||||
dac_xfer_req <= dac_xfer_req_d;
|
||||
dac_data <= (dac_xfer_req_d == 1'b1) ? dac_mem_data_s : {DAC_DATA_WIDTH{1'b0}};
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_fifo_reset_s == 1'b1) begin
|
||||
dac_dunf <= 1'b0;
|
||||
end else begin
|
||||
dac_dunf <= (dac_mem_addr_diff == 0) ? 1'b1 : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module avl_dacfifo_wr #(
|
||||
|
||||
parameter AVL_DATA_WIDTH = 512,
|
||||
parameter DMA_DATA_WIDTH = 64,
|
||||
parameter AVL_BURST_LENGTH = 128,
|
||||
parameter AVL_DDR_BASE_ADDRESS = 0,
|
||||
parameter AVL_DDR_ADDRESS_LIMIT = 33554432,
|
||||
parameter DMA_MEM_ADDRESS_WIDTH = 10)(
|
||||
|
||||
input dma_clk,
|
||||
input [DMA_DATA_WIDTH-1:0] dma_data,
|
||||
input dma_ready,
|
||||
output reg dma_ready_out,
|
||||
input dma_valid,
|
||||
input dma_xfer_req,
|
||||
input dma_xfer_last,
|
||||
|
||||
output reg [ 7:0] dma_last_beats,
|
||||
|
||||
input avl_clk,
|
||||
input avl_reset,
|
||||
output reg [24:0] avl_address,
|
||||
output reg [ 6:0] avl_burstcount,
|
||||
output [63:0] avl_byteenable,
|
||||
input avl_waitrequest,
|
||||
output reg avl_write,
|
||||
output reg [AVL_DATA_WIDTH-1:0] avl_data,
|
||||
|
||||
output reg [24:0] avl_last_address,
|
||||
output reg [ 6:0] avl_last_burstcount,
|
||||
output reg avl_xfer_req_out,
|
||||
input avl_xfer_req_in);
|
||||
|
||||
localparam MEM_RATIO = AVL_DATA_WIDTH/DMA_DATA_WIDTH; // Max supported MEM_RATIO is 16
|
||||
localparam AVL_MEM_ADDRESS_WIDTH = (MEM_RATIO == 1) ? DMA_MEM_ADDRESS_WIDTH :
|
||||
(MEM_RATIO == 2) ? (DMA_MEM_ADDRESS_WIDTH - 1) :
|
||||
(MEM_RATIO == 4) ? (DMA_MEM_ADDRESS_WIDTH - 2) :
|
||||
(MEM_RATIO == 8) ? (DMA_MEM_ADDRESS_WIDTH - 3) :
|
||||
(MEM_RATIO == 16) ? (DMA_MEM_ADDRESS_WIDTH - 4) :
|
||||
(DMA_MEM_ADDRESS_WIDTH - 5);
|
||||
localparam MEM_WIDTH_DIFF = (MEM_RATIO > 16) ? 5 :
|
||||
(MEM_RATIO > 8) ? 4 :
|
||||
(MEM_RATIO > 4) ? 3 :
|
||||
(MEM_RATIO > 2) ? 2 :
|
||||
(MEM_RATIO > 1) ? 1 : 1;
|
||||
|
||||
localparam DMA_BUF_THRESHOLD_HI = {(DMA_MEM_ADDRESS_WIDTH){1'b1}} - AVL_BURST_LENGTH;
|
||||
|
||||
// FSM state definition
|
||||
|
||||
localparam IDLE = 5'b00001;
|
||||
localparam XFER_STAGING = 5'b00010;
|
||||
localparam XFER_FULL_BURST = 5'b00100;
|
||||
localparam XFER_PARTIAL_BURST = 5'b01000;
|
||||
localparam XFER_END = 5'b10000;
|
||||
|
||||
wire dma_reset;
|
||||
wire dma_fifo_reset_s;
|
||||
wire dma_mem_wea_s;
|
||||
wire [DMA_MEM_ADDRESS_WIDTH :0] dma_mem_addr_diff_s;
|
||||
wire [DMA_MEM_ADDRESS_WIDTH-1:0] dma_mem_raddr_s;
|
||||
wire [DMA_MEM_ADDRESS_WIDTH-1:0] dma_mem_waddr_b2g_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] dma_mem_raddr_g2b_s;
|
||||
|
||||
wire avl_fifo_reset_s;
|
||||
wire avl_write_int_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_b2g_s;
|
||||
wire [DMA_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr_m2_g2b_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_addr_diff_s;
|
||||
wire [AVL_MEM_ADDRESS_WIDTH:0] avl_mem_waddr_s;
|
||||
wire [AVL_DATA_WIDTH-1:0] avl_data_s;
|
||||
wire avl_xfer_req_lp_s;
|
||||
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] dma_mem_waddr;
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] dma_mem_waddr_g;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dma_mem_raddr_m1;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dma_mem_raddr_m2;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] dma_mem_raddr;
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] dma_mem_addr_diff;
|
||||
reg dma_xfer_req_d;
|
||||
reg dma_xfer_req_lp_m1;
|
||||
reg dma_xfer_req_lp_m2;
|
||||
reg dma_xfer_req_lp;
|
||||
reg dma_avl_xfer_req_out_m1;
|
||||
reg dma_avl_xfer_req_out_m2;
|
||||
reg dma_avl_xfer_req_out;
|
||||
|
||||
reg [ 4:0] avl_write_state;
|
||||
reg avl_write_d;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_raddr_g;
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr;
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr_m1;
|
||||
reg [DMA_MEM_ADDRESS_WIDTH-1:0] avl_mem_waddr_m2;
|
||||
reg [AVL_MEM_ADDRESS_WIDTH-1:0] avl_mem_addr_diff;
|
||||
reg avl_dma_xfer_req;
|
||||
reg avl_dma_xfer_req_m1;
|
||||
reg avl_dma_xfer_req_m2;
|
||||
reg [ 7:0] avl_dma_last_beats;
|
||||
reg [ 7:0] avl_dma_last_beats_m1;
|
||||
reg [ 7:0] avl_dma_last_beats_m2;
|
||||
reg [ 3:0] avl_xfer_pburst_offset;
|
||||
reg [ 7:0] avl_burst_counter;
|
||||
reg avl_last_burst;
|
||||
reg avl_init_burst;
|
||||
reg avl_endof_burst;
|
||||
reg [ 1:0] avl_mem_rvalid;
|
||||
reg avl_xfer_req_lp;
|
||||
|
||||
// An asymmetric memory to transfer data from DMAC interface to Avalon Memory Map
|
||||
// interface
|
||||
|
||||
ad_mem_asym_wr i_mem_asym (
|
||||
.mem_i_wrclock_clk (dma_clk),
|
||||
.mem_i_wren_wren (dma_mem_wea_s),
|
||||
.mem_i_wraddress_wraddress (dma_mem_waddr),
|
||||
.mem_i_datain_datain (dma_data),
|
||||
.mem_i_rdclock_clk (avl_clk),
|
||||
.mem_i_rdaddress_rdaddress (avl_mem_raddr),
|
||||
.mem_o_dataout_dataout (avl_data_s));
|
||||
|
||||
// the fifo reset is the dma_xfer_req
|
||||
|
||||
assign dma_reset = ~dma_xfer_req_d & dma_xfer_req;
|
||||
assign dma_fifo_reset_s = (~dma_xfer_req_lp & dma_xfer_req_lp_m2);
|
||||
assign avl_fifo_reset_s = (avl_reset == 1'b1) ||
|
||||
(avl_dma_xfer_req_m2 & ~avl_dma_xfer_req);
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
dma_xfer_req_d <= dma_xfer_req;
|
||||
end
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_reset) begin
|
||||
dma_xfer_req_lp_m1 <= 1'b0;
|
||||
dma_xfer_req_lp_m2 <= 1'b0;
|
||||
dma_xfer_req_lp <= 1'b0;
|
||||
dma_avl_xfer_req_out_m1 <= 1'b0;
|
||||
dma_avl_xfer_req_out_m2 <= 1'b0;
|
||||
dma_avl_xfer_req_out <= 1'b0;
|
||||
end else begin
|
||||
dma_xfer_req_lp_m1 <= avl_xfer_req_lp;
|
||||
dma_xfer_req_lp_m2 <= dma_xfer_req_lp_m1;
|
||||
dma_xfer_req_lp <= dma_xfer_req_lp_m2;
|
||||
dma_avl_xfer_req_out_m1 <= avl_xfer_req_out;
|
||||
dma_avl_xfer_req_out_m2 <= dma_avl_xfer_req_out_m1;
|
||||
dma_avl_xfer_req_out <= dma_avl_xfer_req_out_m2;
|
||||
end
|
||||
end
|
||||
|
||||
// write address generation
|
||||
|
||||
assign dma_mem_wea_s = dma_ready & dma_valid;
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if ((dma_fifo_reset_s == 1'b1) || (dma_avl_xfer_req_out == 1'b1)) begin
|
||||
dma_mem_waddr <= 0;
|
||||
dma_mem_waddr_g <= 0;
|
||||
end else begin
|
||||
if (dma_mem_wea_s == 1'b1) begin
|
||||
dma_mem_waddr <= dma_mem_waddr + 1'b1;
|
||||
end
|
||||
end
|
||||
dma_mem_waddr_g <= dma_mem_waddr_b2g_s;
|
||||
end
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_fifo_reset_s == 1'b1) begin
|
||||
dma_last_beats <= 0;
|
||||
end else begin
|
||||
if ((dma_xfer_last == 1'b1) && (dma_mem_wea_s == 1'b1)) begin
|
||||
dma_last_beats <= dma_mem_waddr[MEM_WIDTH_DIFF-1:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ad_b2g # (
|
||||
.DATA_WIDTH(DMA_MEM_ADDRESS_WIDTH)
|
||||
) i_dma_mem_waddr_b2g (
|
||||
.din (dma_mem_waddr),
|
||||
.dout (dma_mem_waddr_b2g_s));
|
||||
|
||||
// The memory module request data until reaches the high threshold.
|
||||
|
||||
assign dma_mem_addr_diff_s = {1'b1, dma_mem_waddr} - dma_mem_raddr_s;
|
||||
assign dma_mem_raddr_s = (MEM_RATIO == 1) ? {dma_mem_raddr, {0{1'b0}}} :
|
||||
(MEM_RATIO == 2) ? {dma_mem_raddr, {1{1'b0}}} :
|
||||
(MEM_RATIO == 4) ? {dma_mem_raddr, {2{1'b0}}} :
|
||||
(MEM_RATIO == 8) ? {dma_mem_raddr, {3{1'b0}}} :
|
||||
(MEM_RATIO == 16) ? {dma_mem_raddr, {4{1'b0}}} :
|
||||
{dma_mem_raddr, {5{1'b0}}};
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_fifo_reset_s == 1'b1) begin
|
||||
dma_mem_addr_diff <= 'b0;
|
||||
dma_mem_raddr_m1 <= 'b0;
|
||||
dma_mem_raddr_m2 <= 'b0;
|
||||
dma_mem_raddr <= 'b0;
|
||||
dma_ready_out <= 1'b0;
|
||||
end else begin
|
||||
dma_mem_raddr_m1 <= avl_mem_raddr_g;
|
||||
dma_mem_raddr_m2 <= dma_mem_raddr_m1;
|
||||
dma_mem_raddr <= dma_mem_raddr_g2b_s;
|
||||
dma_mem_addr_diff <= dma_mem_addr_diff_s[DMA_MEM_ADDRESS_WIDTH-1:0];
|
||||
if (dma_xfer_req_lp == 1'b1) begin
|
||||
dma_ready_out <= (dma_mem_addr_diff >= DMA_BUF_THRESHOLD_HI) ? 1'b0 : 1'b1;
|
||||
end else begin
|
||||
dma_ready_out <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ad_g2b #(
|
||||
.DATA_WIDTH(AVL_MEM_ADDRESS_WIDTH)
|
||||
) i_dma_mem_rd_address_g2b (
|
||||
.din (dma_mem_raddr_m2),
|
||||
.dout (dma_mem_raddr_g2b_s));
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_dma_xfer_req_m1 <= 'b0;
|
||||
avl_dma_xfer_req_m2 <= 'b0;
|
||||
avl_dma_xfer_req <= 'b0;
|
||||
end else begin
|
||||
avl_dma_xfer_req_m1 <= dma_xfer_req;
|
||||
avl_dma_xfer_req_m2 <= avl_dma_xfer_req_m1;
|
||||
avl_dma_xfer_req <= avl_dma_xfer_req_m2;
|
||||
end
|
||||
end
|
||||
|
||||
assign avl_xfer_req_lp_s = avl_dma_xfer_req & ~avl_xfer_req_in;
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_xfer_req_lp <= 1'b0;
|
||||
end else begin
|
||||
avl_xfer_req_lp <= avl_xfer_req_lp_s;
|
||||
end
|
||||
end
|
||||
|
||||
// FSM to generate the necessary Avalon Write transactions
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_write_state <= IDLE;
|
||||
avl_last_burst <= 1'b0;
|
||||
avl_init_burst <= 1'b0;
|
||||
avl_endof_burst <= 1'b0;
|
||||
end else begin
|
||||
case (avl_write_state)
|
||||
IDLE : begin
|
||||
if (avl_dma_xfer_req == 1'b1) begin
|
||||
avl_write_state <= XFER_STAGING;
|
||||
end else begin
|
||||
avl_write_state <= IDLE;
|
||||
end
|
||||
end
|
||||
XFER_STAGING : begin
|
||||
avl_endof_burst <= 1'b0;
|
||||
if (avl_xfer_req_lp == 1'b1) begin
|
||||
// there are enough data for one transaction
|
||||
if (avl_mem_addr_diff >= AVL_BURST_LENGTH) begin
|
||||
avl_write_state <= XFER_FULL_BURST;
|
||||
avl_init_burst <= 1'b1;
|
||||
end else begin
|
||||
avl_write_state <= XFER_STAGING;
|
||||
end
|
||||
end else if ((avl_dma_xfer_req == 1'b0) && (avl_xfer_pburst_offset == 4'b0)) begin // DMA transfer was finished
|
||||
if (avl_mem_addr_diff >= AVL_BURST_LENGTH) begin
|
||||
avl_write_state <= XFER_FULL_BURST;
|
||||
avl_init_burst <= 1'b1;
|
||||
end else if ((avl_mem_addr_diff > 0) ||
|
||||
(avl_dma_last_beats[MEM_WIDTH_DIFF-1:0] != {MEM_WIDTH_DIFF{1'b1}})) begin
|
||||
avl_write_state <= XFER_PARTIAL_BURST;
|
||||
avl_last_burst <= 1'b1;
|
||||
end else begin
|
||||
avl_write_state <= XFER_END;
|
||||
end
|
||||
end else begin
|
||||
avl_write_state <= XFER_STAGING;
|
||||
end
|
||||
end
|
||||
// Avalon transaction with full burst length
|
||||
XFER_FULL_BURST : begin
|
||||
avl_init_burst <= 1'b0;
|
||||
if ((avl_burst_counter < avl_burstcount) || ((avl_waitrequest) || (avl_write))) begin
|
||||
avl_write_state <= XFER_FULL_BURST;
|
||||
end else begin
|
||||
avl_write_state <= XFER_STAGING;
|
||||
avl_endof_burst <= 1'b1;
|
||||
end
|
||||
end
|
||||
// Avalon transaction with the remaining data, burst length is less than
|
||||
// the maximum supported burst length
|
||||
XFER_PARTIAL_BURST : begin
|
||||
avl_last_burst <= 1'b0;
|
||||
if ((avl_burst_counter < avl_burstcount) || ((avl_waitrequest) || (avl_write))) begin
|
||||
avl_write_state <= XFER_PARTIAL_BURST;
|
||||
end else begin
|
||||
avl_write_state <= XFER_END;
|
||||
end
|
||||
end
|
||||
XFER_END : begin
|
||||
avl_write_state <= IDLE;
|
||||
end
|
||||
default : begin
|
||||
avl_write_state <= IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// FSM outputs
|
||||
|
||||
assign avl_write_int_s = ((avl_write_state == XFER_FULL_BURST) ||
|
||||
(avl_write_state == XFER_PARTIAL_BURST)) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_mem_waddr_m1 <= 'b0;
|
||||
avl_mem_waddr_m2 <= 'b0;
|
||||
avl_mem_waddr <= 'b0;
|
||||
avl_xfer_pburst_offset <= 4'b1111;
|
||||
end else begin
|
||||
avl_mem_waddr_m1 <= dma_mem_waddr_g;
|
||||
avl_mem_waddr_m2 <= avl_mem_waddr_m1;
|
||||
avl_mem_waddr <= avl_mem_waddr_m2_g2b_s;
|
||||
if ((avl_dma_xfer_req == 0) && (avl_xfer_pburst_offset > 0)) begin
|
||||
avl_xfer_pburst_offset <= avl_xfer_pburst_offset - 4'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ad_g2b # (
|
||||
.DATA_WIDTH(DMA_MEM_ADDRESS_WIDTH)
|
||||
) i_avl_mem_waddr_g2b (
|
||||
.din (avl_mem_waddr_m2),
|
||||
.dout (avl_mem_waddr_m2_g2b_s));
|
||||
|
||||
// ASYNC MEM read control
|
||||
|
||||
assign avl_mem_waddr_s = (MEM_RATIO == 1) ? {avl_mem_waddr[(DMA_MEM_ADDRESS_WIDTH-1):0]} :
|
||||
(MEM_RATIO == 2) ? {avl_mem_waddr[(DMA_MEM_ADDRESS_WIDTH-1):1]} :
|
||||
(MEM_RATIO == 4) ? {avl_mem_waddr[(DMA_MEM_ADDRESS_WIDTH-1):2]} :
|
||||
(MEM_RATIO == 8) ? {avl_mem_waddr[(DMA_MEM_ADDRESS_WIDTH-1):3]} :
|
||||
{avl_mem_waddr[(DMA_MEM_ADDRESS_WIDTH-1):4]};
|
||||
assign avl_mem_addr_diff_s = {1'b1, avl_mem_waddr_s} - avl_mem_raddr;
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_mem_addr_diff <= 'b0;
|
||||
end else begin
|
||||
avl_mem_addr_diff <= avl_mem_addr_diff_s[(AVL_MEM_ADDRESS_WIDTH-1):0];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_mem_rvalid <= 2'b0;
|
||||
avl_mem_raddr <= 'b0;
|
||||
avl_mem_raddr_g <= 'b0;
|
||||
end else begin
|
||||
if (~avl_waitrequest && avl_write) begin
|
||||
avl_mem_rvalid[0] <= 1'b1;
|
||||
avl_mem_rvalid[1] <= avl_mem_rvalid[0];
|
||||
end else begin
|
||||
avl_mem_rvalid <= {avl_mem_rvalid[0], 1'b0};
|
||||
end
|
||||
if (~avl_waitrequest && avl_write) begin
|
||||
avl_mem_raddr <= avl_mem_raddr + 1'b1;
|
||||
end
|
||||
if (avl_write_state == XFER_END) begin
|
||||
avl_mem_raddr <= 'b0;
|
||||
end
|
||||
avl_mem_raddr_g <= avl_mem_raddr_b2g_s;
|
||||
end
|
||||
end
|
||||
|
||||
ad_b2g #(
|
||||
.DATA_WIDTH(AVL_MEM_ADDRESS_WIDTH)
|
||||
) i_avl_mem_rd_address_b2g (
|
||||
.din (avl_mem_raddr),
|
||||
.dout (avl_mem_raddr_b2g_s));
|
||||
|
||||
// Avalon write address
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_fifo_reset_s == 1'b1) begin
|
||||
avl_address <= AVL_DDR_BASE_ADDRESS;
|
||||
end else begin
|
||||
if (avl_endof_burst == 1'b1) begin
|
||||
avl_address <= (avl_address < AVL_DDR_ADDRESS_LIMIT) ? avl_address + AVL_BURST_LENGTH : AVL_DDR_BASE_ADDRESS;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Avalon write
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if ((avl_fifo_reset_s == 1'b1) || (avl_write_state == XFER_END)) begin
|
||||
avl_write <= 1'b0;
|
||||
avl_write_d <= 1'b0;
|
||||
avl_data <= 'b0;
|
||||
end else begin
|
||||
if (~avl_waitrequest) begin
|
||||
avl_write_d <= (avl_init_burst || avl_last_burst) ||
|
||||
(avl_write_int_s & avl_mem_rvalid[1]);
|
||||
avl_write <= avl_write_d;
|
||||
avl_data <= avl_data_s;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Avalon burstcount & counter
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset) begin
|
||||
avl_burstcount <= 'b1;
|
||||
avl_burst_counter <= 'b0;
|
||||
end else begin
|
||||
if (avl_last_burst) begin
|
||||
if (avl_dma_last_beats[MEM_WIDTH_DIFF-1:0] != {MEM_WIDTH_DIFF{1'b1}}) begin
|
||||
avl_burstcount <= avl_mem_addr_diff + 1;
|
||||
end else begin
|
||||
avl_burstcount <= avl_mem_addr_diff;
|
||||
end
|
||||
end else if (avl_write_state != XFER_PARTIAL_BURST) begin
|
||||
avl_burstcount <= AVL_BURST_LENGTH;
|
||||
end
|
||||
if (avl_write_state == XFER_STAGING) begin
|
||||
avl_burst_counter <= 'b0;
|
||||
end else if (avl_write_d && ~avl_waitrequest) begin
|
||||
avl_burst_counter <= avl_burst_counter + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// generate avl_byteenable signal
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_dma_last_beats_m1 <= 8'b0;
|
||||
avl_dma_last_beats_m2 <= 8'b0;
|
||||
avl_dma_last_beats <= 8'b0;
|
||||
end else begin
|
||||
avl_dma_last_beats_m1 <= dma_last_beats;
|
||||
avl_dma_last_beats_m2 <= avl_dma_last_beats_m1;
|
||||
avl_dma_last_beats <= avl_dma_last_beats_m2;
|
||||
end
|
||||
end
|
||||
|
||||
assign avl_byteenable = {64{1'b1}};
|
||||
|
||||
// save the last address and byteenable
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_last_address <= 0;
|
||||
avl_last_burstcount <= 'b0;
|
||||
end else begin
|
||||
if (avl_write && ~avl_waitrequest) begin
|
||||
avl_last_address <= avl_address;
|
||||
avl_last_burstcount <= avl_burstcount;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// avl_xfer_req generation for synchronize the access of the external
|
||||
// memory
|
||||
|
||||
always @(posedge avl_clk) begin
|
||||
if (avl_reset == 1'b1) begin
|
||||
avl_xfer_req_out <= 1'b0;
|
||||
end else begin
|
||||
if (avl_write_state == XFER_END) begin
|
||||
avl_xfer_req_out <= 1'b1;
|
||||
end else if (avl_write_state == XFER_STAGING) begin
|
||||
avl_xfer_req_out <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,276 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module util_dacfifo_bypass #(
|
||||
|
||||
parameter DAC_DATA_WIDTH = 64,
|
||||
parameter DMA_DATA_WIDTH = 64) (
|
||||
|
||||
// DMA FIFO interface
|
||||
|
||||
input dma_clk,
|
||||
input [(DMA_DATA_WIDTH-1):0] dma_data,
|
||||
input dma_ready,
|
||||
output reg dma_ready_out,
|
||||
input dma_valid,
|
||||
|
||||
// request and synchronization
|
||||
|
||||
input dma_xfer_req,
|
||||
|
||||
// dac fifo interface
|
||||
|
||||
input dac_clk,
|
||||
input dac_rst,
|
||||
input dac_valid,
|
||||
output reg [(DAC_DATA_WIDTH-1):0] dac_data,
|
||||
output reg dac_dunf
|
||||
);
|
||||
|
||||
// supported ratios: 1:1 / 1:2 / 1:4 / 1:8 / 2:1 / 4:1 / 8:1
|
||||
|
||||
localparam MEM_RATIO = (DMA_DATA_WIDTH > DAC_DATA_WIDTH) ? DMA_DATA_WIDTH/DAC_DATA_WIDTH :
|
||||
DAC_DATA_WIDTH/DMA_DATA_WIDTH;
|
||||
localparam DAC_ADDRESS_WIDTH = 10;
|
||||
localparam DMA_ADDRESS_WIDTH = (MEM_RATIO == 1) ? DAC_ADDRESS_WIDTH :
|
||||
(MEM_RATIO == 2) ? ((DMA_DATA_WIDTH > DAC_DATA_WIDTH) ? (DAC_ADDRESS_WIDTH - 1) : (DAC_ADDRESS_WIDTH + 1)) :
|
||||
(MEM_RATIO == 4) ? ((DMA_DATA_WIDTH > DAC_DATA_WIDTH) ? (DAC_ADDRESS_WIDTH - 2) : (DAC_ADDRESS_WIDTH + 2)) :
|
||||
((DMA_DATA_WIDTH > DAC_DATA_WIDTH) ? (DAC_ADDRESS_WIDTH - 3) : (DAC_ADDRESS_WIDTH + 3));
|
||||
localparam DMA_BUF_THRESHOLD_HI = {(DMA_ADDRESS_WIDTH){1'b1}} - 4;
|
||||
localparam DAC_BUF_THRESHOLD_LO = 4;
|
||||
|
||||
reg [(DMA_ADDRESS_WIDTH-1):0] dma_mem_waddr = 'd0;
|
||||
reg [(DMA_ADDRESS_WIDTH-1):0] dma_mem_waddr_g = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr_g = 'd0;
|
||||
reg dac_mem_rea = 1'b0;
|
||||
reg dac_mem_rea_d = 1'b0;
|
||||
reg dma_rst_m1 = 1'b0;
|
||||
reg dma_rst = 1'b0;
|
||||
reg [DMA_ADDRESS_WIDTH-1:0] dma_mem_addr_diff = 1'b0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dma_mem_raddr_m1 = 1'b0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dma_mem_raddr_m2 = 1'b0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dma_mem_raddr = 1'b0;
|
||||
reg [(DMA_ADDRESS_WIDTH-1):0] dac_mem_waddr_m1 = 1'b0;
|
||||
reg [(DMA_ADDRESS_WIDTH-1):0] dac_mem_waddr_m2 = 1'b0;
|
||||
reg [(DMA_ADDRESS_WIDTH-1):0] dac_mem_waddr = 1'b0;
|
||||
reg dac_xfer_out = 1'b0;
|
||||
reg dac_xfer_out_m1 = 1'b0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [(DAC_ADDRESS_WIDTH):0] dac_mem_addr_diff_s;
|
||||
wire [(DMA_ADDRESS_WIDTH-1):0] dma_mem_raddr_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] dac_mem_waddr_s;
|
||||
wire dma_mem_wea_s;
|
||||
wire dac_mem_rea_s;
|
||||
wire [(DAC_DATA_WIDTH-1):0] dac_mem_rdata_s;
|
||||
wire [DMA_ADDRESS_WIDTH:0] dma_address_diff_s;
|
||||
wire dac_mem_empty_s;
|
||||
|
||||
wire [(DMA_ADDRESS_WIDTH-1):0] dma_mem_waddr_b2g_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr_b2g_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] dma_mem_raddr_m2_g2b_s;
|
||||
wire [(DMA_ADDRESS_WIDTH-1):0] dac_mem_waddr_m2_g2b_s;
|
||||
|
||||
// An asymmetric memory to transfer data from DMAC interface to DAC interface
|
||||
|
||||
ad_mem_asym_bypass i_mem_asym (
|
||||
.mem_i_wrclock_clk (dma_clk),
|
||||
.mem_i_wren_wren (dma_mem_wea_s),
|
||||
.mem_i_wraddress_wraddress (dma_mem_waddr),
|
||||
.mem_i_datain_datain (dma_data),
|
||||
.mem_i_rdclock_clk (dac_clk),
|
||||
.mem_i_rdaddress_rdaddress (dac_mem_raddr),
|
||||
.mem_o_dataout_dataout (dac_mem_rdata_s));
|
||||
|
||||
// dma reset is brought from dac domain
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
dma_rst_m1 <= dac_rst;
|
||||
dma_rst <= dma_rst_m1;
|
||||
end
|
||||
|
||||
// Write address generation for the asymmetric memory
|
||||
|
||||
assign dma_mem_wea_s = dma_xfer_req & dma_valid & dma_ready;
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_rst == 1'b1) begin
|
||||
dma_mem_waddr <= 'h0;
|
||||
dma_mem_waddr_g <= 'h0;
|
||||
end else begin
|
||||
if (dma_mem_wea_s == 1'b1) begin
|
||||
dma_mem_waddr <= dma_mem_waddr + 1'b1;
|
||||
end
|
||||
dma_mem_waddr_g <= dma_mem_waddr_b2g_s;
|
||||
end
|
||||
end
|
||||
|
||||
ad_b2g #(
|
||||
.DATA_WIDTH (DMA_ADDRESS_WIDTH))
|
||||
i_dma_mem_waddr_b2g (
|
||||
.din (dma_mem_waddr),
|
||||
.dout (dma_mem_waddr_b2g_s));
|
||||
|
||||
// The memory module request data until reaches the high threshold.
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_rst == 1'b1) begin
|
||||
dma_mem_addr_diff <= 'b0;
|
||||
dma_mem_raddr_m1 <= 'b0;
|
||||
dma_mem_raddr_m2 <= 'b0;
|
||||
dma_mem_raddr <= 'b0;
|
||||
dma_ready_out <= 1'b0;
|
||||
end else begin
|
||||
dma_mem_raddr_m1 <= dac_mem_raddr_g;
|
||||
dma_mem_raddr_m2 <= dma_mem_raddr_m1;
|
||||
dma_mem_raddr <= dma_mem_raddr_m2_g2b_s;
|
||||
dma_mem_addr_diff <= dma_address_diff_s[DMA_ADDRESS_WIDTH-1:0];
|
||||
if (dma_mem_addr_diff >= DMA_BUF_THRESHOLD_HI) begin
|
||||
dma_ready_out <= 1'b0;
|
||||
end else begin
|
||||
dma_ready_out <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ad_g2b #(
|
||||
.DATA_WIDTH (DAC_ADDRESS_WIDTH))
|
||||
i_dma_mem_raddr_g2b (
|
||||
.din (dma_mem_raddr_m2),
|
||||
.dout (dma_mem_raddr_m2_g2b_s));
|
||||
|
||||
// relative address offset on dma domain
|
||||
assign dma_address_diff_s = {1'b1, dma_mem_waddr} - dma_mem_raddr_s;
|
||||
assign dma_mem_raddr_s = (DMA_DATA_WIDTH>DAC_DATA_WIDTH) ?
|
||||
((MEM_RATIO == 1) ? (dma_mem_raddr) :
|
||||
(MEM_RATIO == 2) ? (dma_mem_raddr[(DAC_ADDRESS_WIDTH-1):1]) :
|
||||
(MEM_RATIO == 4) ? (dma_mem_raddr[(DAC_ADDRESS_WIDTH-1):2]) : (dma_mem_raddr[(DAC_ADDRESS_WIDTH-1):3])) :
|
||||
((MEM_RATIO == 1) ? (dma_mem_raddr) :
|
||||
(MEM_RATIO == 2) ? ({dma_mem_raddr, 1'b0}) :
|
||||
(MEM_RATIO == 4) ? ({dma_mem_raddr, 2'b0}) : ({dma_mem_raddr, 3'b0}));
|
||||
|
||||
|
||||
// relative address offset on dac domain
|
||||
assign dac_address_diff_s = {1'b1, dac_mem_waddr_s} - dac_mem_raddr;
|
||||
assign dac_mem_waddr_s = (DAC_DATA_WIDTH>DMA_DATA_WIDTH) ?
|
||||
((MEM_RATIO == 1) ? (dac_mem_waddr) :
|
||||
(MEM_RATIO == 2) ? (dac_mem_waddr[(DMA_ADDRESS_WIDTH-1):1]) :
|
||||
(MEM_RATIO == 4) ? (dac_mem_waddr[(DMA_ADDRESS_WIDTH-1):2]) : (dac_mem_waddr[(DMA_ADDRESS_WIDTH-1):3])) :
|
||||
((MEM_RATIO == 1) ? (dac_mem_waddr) :
|
||||
(MEM_RATIO == 2) ? ({dac_mem_waddr, 1'b0}) :
|
||||
(MEM_RATIO == 4) ? ({dac_mem_waddr, 2'b0}) : ({dac_mem_waddr, 3'b0}));
|
||||
|
||||
// Read address generation for the asymmetric memory
|
||||
|
||||
assign dac_mem_empty_s = (dac_mem_waddr_s == dac_mem_raddr) ? 1'b1 : 1'b0;
|
||||
assign dac_mem_rea_s = dac_valid & !dac_mem_empty_s;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_rst == 1'b1) begin
|
||||
dac_mem_raddr <= 'h0;
|
||||
dac_mem_raddr_g <= 'h0;
|
||||
end else begin
|
||||
if (dac_mem_rea_s == 1'b1) begin
|
||||
dac_mem_raddr <= dac_mem_raddr + 1'b1;
|
||||
end
|
||||
dac_mem_raddr_g <= dac_mem_raddr_b2g_s;
|
||||
end
|
||||
end
|
||||
|
||||
// compensate the read latency of the memory
|
||||
always @(posedge dac_clk) begin
|
||||
dac_mem_rea_d <= dac_mem_rea_s;
|
||||
dac_mem_rea <= dac_mem_rea_d;
|
||||
end
|
||||
|
||||
ad_b2g #(
|
||||
.DATA_WIDTH (DAC_ADDRESS_WIDTH))
|
||||
i_dac_mem_raddr_b2g (
|
||||
.din (dac_mem_raddr),
|
||||
.dout (dac_mem_raddr_b2g_s));
|
||||
|
||||
// transfer the write address into the DAC's clock domain
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_rst == 1'b1) begin
|
||||
dac_mem_waddr_m1 <= 'b0;
|
||||
dac_mem_waddr_m2 <= 'b0;
|
||||
dac_mem_waddr <= 'b0;
|
||||
end else begin
|
||||
dac_mem_waddr_m1 <= dma_mem_waddr_g;
|
||||
dac_mem_waddr_m2 <= dac_mem_waddr_m1;
|
||||
dac_mem_waddr <= dac_mem_waddr_m2_g2b_s;
|
||||
end
|
||||
end
|
||||
|
||||
ad_g2b #(
|
||||
.DATA_WIDTH (DMA_ADDRESS_WIDTH))
|
||||
i_dac_mem_waddr_g2b (
|
||||
.din (dac_mem_waddr_m2),
|
||||
.dout (dac_mem_waddr_m2_g2b_s));
|
||||
|
||||
// define underflow
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_rst == 1'b1) begin
|
||||
dac_xfer_out_m1 <= 1'b0;
|
||||
dac_xfer_out <= 1'b0;
|
||||
dac_dunf <= 1'b0;
|
||||
end else begin
|
||||
dac_xfer_out_m1 <= dma_xfer_req;
|
||||
dac_xfer_out <= dac_xfer_out_m1;
|
||||
if (dac_valid == 1'b1) begin
|
||||
dac_dunf <= dac_mem_empty_s;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// DAC data output logic - make sure that the data output is zero between
|
||||
// transfers
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_dunf == 1'b1) begin
|
||||
dac_data <= 0;
|
||||
end else begin
|
||||
dac_data <= dac_mem_rdata_s;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := axi_adxcvr
|
||||
|
||||
INTEL_DEPS += ../../common/up_axi.v
|
||||
INTEL_DEPS += axi_adxcvr.v
|
||||
INTEL_DEPS += axi_adxcvr_hw.tcl
|
||||
INTEL_DEPS += axi_adxcvr_up.v
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,160 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module axi_adxcvr #(
|
||||
|
||||
// parameters
|
||||
|
||||
parameter integer ID = 0,
|
||||
parameter [ 7:0] FPGA_TECHNOLOGY = 0,
|
||||
parameter [ 7:0] FPGA_FAMILY = 0,
|
||||
parameter [ 7:0] SPEED_GRADE = 0,
|
||||
parameter [ 7:0] DEV_PACKAGE = 0,
|
||||
parameter [15:0] FPGA_VOLTAGE = 0,
|
||||
parameter integer XCVR_TYPE = 0,
|
||||
parameter integer TX_OR_RX_N = 0,
|
||||
parameter integer NUM_OF_LANES = 4) (
|
||||
|
||||
// xcvr, lane-pll and ref-pll are shared
|
||||
|
||||
output up_rst,
|
||||
input up_pll_locked,
|
||||
input [(NUM_OF_LANES-1):0] up_ready,
|
||||
|
||||
input s_axi_aclk,
|
||||
input s_axi_aresetn,
|
||||
input s_axi_awvalid,
|
||||
input [11:0] s_axi_awaddr,
|
||||
input [ 2:0] s_axi_awprot,
|
||||
output s_axi_awready,
|
||||
input s_axi_wvalid,
|
||||
input [31:0] s_axi_wdata,
|
||||
input [ 3:0] s_axi_wstrb,
|
||||
output s_axi_wready,
|
||||
output s_axi_bvalid,
|
||||
output [ 1:0] s_axi_bresp,
|
||||
input s_axi_bready,
|
||||
input s_axi_arvalid,
|
||||
input [11:0] s_axi_araddr,
|
||||
input [ 2:0] s_axi_arprot,
|
||||
output s_axi_arready,
|
||||
output s_axi_rvalid,
|
||||
output [ 1:0] s_axi_rresp,
|
||||
output [31:0] s_axi_rdata,
|
||||
input s_axi_rready);
|
||||
|
||||
// internal signals
|
||||
|
||||
wire up_rstn;
|
||||
wire up_clk;
|
||||
wire up_wreq;
|
||||
wire [ 9:0] up_waddr;
|
||||
wire [31:0] up_wdata;
|
||||
wire up_wack;
|
||||
wire up_rreq;
|
||||
wire [ 9:0] up_raddr;
|
||||
wire [31:0] up_rdata;
|
||||
wire up_rack;
|
||||
|
||||
// clk & rst
|
||||
|
||||
assign up_rstn = s_axi_aresetn;
|
||||
assign up_clk = s_axi_aclk;
|
||||
|
||||
// instantiations
|
||||
|
||||
axi_adxcvr_up #(
|
||||
.ID (ID),
|
||||
.XCVR_TYPE (XCVR_TYPE),
|
||||
.FPGA_TECHNOLOGY (FPGA_TECHNOLOGY),
|
||||
.FPGA_FAMILY (FPGA_FAMILY),
|
||||
.SPEED_GRADE (SPEED_GRADE),
|
||||
.DEV_PACKAGE (DEV_PACKAGE),
|
||||
.FPGA_VOLTAGE (FPGA_VOLTAGE),
|
||||
.TX_OR_RX_N (TX_OR_RX_N),
|
||||
.NUM_OF_LANES (NUM_OF_LANES))
|
||||
i_up (
|
||||
.up_rst (up_rst),
|
||||
.up_pll_locked (up_pll_locked),
|
||||
.up_ready (up_ready),
|
||||
.up_rstn (up_rstn),
|
||||
.up_clk (up_clk),
|
||||
.up_wreq (up_wreq),
|
||||
.up_waddr (up_waddr),
|
||||
.up_wdata (up_wdata),
|
||||
.up_wack (up_wack),
|
||||
.up_rreq (up_rreq),
|
||||
.up_raddr (up_raddr),
|
||||
.up_rdata (up_rdata),
|
||||
.up_rack (up_rack));
|
||||
|
||||
up_axi #(
|
||||
.AXI_ADDRESS_WIDTH (12)
|
||||
) i_axi (
|
||||
.up_rstn (up_rstn),
|
||||
.up_clk (up_clk),
|
||||
.up_axi_awvalid (s_axi_awvalid),
|
||||
.up_axi_awaddr (s_axi_awaddr),
|
||||
.up_axi_awready (s_axi_awready),
|
||||
.up_axi_wvalid (s_axi_wvalid),
|
||||
.up_axi_wdata (s_axi_wdata),
|
||||
.up_axi_wstrb (s_axi_wstrb),
|
||||
.up_axi_wready (s_axi_wready),
|
||||
.up_axi_bvalid (s_axi_bvalid),
|
||||
.up_axi_bresp (s_axi_bresp),
|
||||
.up_axi_bready (s_axi_bready),
|
||||
.up_axi_arvalid (s_axi_arvalid),
|
||||
.up_axi_araddr (s_axi_araddr),
|
||||
.up_axi_arready (s_axi_arready),
|
||||
.up_axi_rvalid (s_axi_rvalid),
|
||||
.up_axi_rresp (s_axi_rresp),
|
||||
.up_axi_rdata (s_axi_rdata),
|
||||
.up_axi_rready (s_axi_rready),
|
||||
.up_wreq (up_wreq),
|
||||
.up_waddr (up_waddr),
|
||||
.up_wdata (up_wdata),
|
||||
.up_wack (up_wack),
|
||||
.up_rreq (up_rreq),
|
||||
.up_raddr (up_raddr),
|
||||
.up_rdata (up_rdata),
|
||||
.up_rack (up_rack));
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
package require qsys
|
||||
package require quartus::device
|
||||
|
||||
source ../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
set_module_property NAME axi_adxcvr
|
||||
set_module_property DESCRIPTION "AXI ADXCVR Core"
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
set_module_property DISPLAY_NAME axi_adxcvr
|
||||
set_module_property ELABORATION_CALLBACK p_axi_adxcvr
|
||||
set_module_property VALIDATION_CALLBACK info_param_validate
|
||||
|
||||
# files
|
||||
|
||||
ad_ip_files axi_adxcvr [list \
|
||||
$ad_hdl_dir/library/common/up_axi.v \
|
||||
axi_adxcvr_up.v \
|
||||
axi_adxcvr.v \
|
||||
]
|
||||
|
||||
# parameters
|
||||
|
||||
add_parameter ID INTEGER 0
|
||||
set_parameter_property ID DISPLAY_NAME ID
|
||||
set_parameter_property ID UNITS None
|
||||
set_parameter_property ID HDL_PARAMETER true
|
||||
|
||||
add_parameter TX_OR_RX_N INTEGER 0
|
||||
set_parameter_property TX_OR_RX_N DISPLAY_NAME TX_OR_RX_N
|
||||
set_parameter_property TX_OR_RX_N UNITS None
|
||||
set_parameter_property TX_OR_RX_N HDL_PARAMETER true
|
||||
|
||||
add_parameter NUM_OF_LANES INTEGER 4
|
||||
set_parameter_property NUM_OF_LANES DISPLAY_NAME NUM_OF_LANES
|
||||
set_parameter_property NUM_OF_LANES UNITS None
|
||||
set_parameter_property NUM_OF_LANES HDL_PARAMETER true
|
||||
|
||||
adi_add_auto_fpga_spec_params
|
||||
|
||||
adi_add_device_spec_param XCVR_TYPE
|
||||
adi_add_device_spec_param FPGA_VOLTAGE
|
||||
set_parameter_property FPGA_VOLTAGE DISPLAY_UNITS mV
|
||||
set_parameter_property FPGA_VOLTAGE_MANUAL DISPLAY_UNITS mV
|
||||
adi_add_indep_spec_params_overwrite XCVR_TYPE
|
||||
adi_add_indep_spec_params_overwrite FPGA_VOLTAGE
|
||||
|
||||
# axi4 slave interface
|
||||
|
||||
ad_ip_intf_s_axi s_axi_aclk s_axi_aresetn 12
|
||||
|
||||
# xcvr interface
|
||||
|
||||
ad_interface reset up_rst output 1 s_axi_clock
|
||||
set_interface_property if_up_rst associatedResetSinks s_axi_reset
|
||||
|
||||
add_interface core_pll_locked conduit end
|
||||
add_interface_port core_pll_locked up_pll_locked pll_locked Input 1
|
||||
|
||||
# name changes
|
||||
|
||||
proc p_axi_adxcvr {} {
|
||||
|
||||
set m_tx_or_rx_n [get_parameter_value TX_OR_RX_N]
|
||||
set m_num_of_lanes [get_parameter_value NUM_OF_LANES]
|
||||
|
||||
if {$m_tx_or_rx_n == 1} {
|
||||
add_interface ready conduit end
|
||||
add_interface_port ready up_ready tx_ready input $m_num_of_lanes
|
||||
}
|
||||
|
||||
if {$m_tx_or_rx_n == 0} {
|
||||
add_interface ready conduit end
|
||||
add_interface_port ready up_ready rx_ready input $m_num_of_lanes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module axi_adxcvr_up #(
|
||||
|
||||
// parameters
|
||||
|
||||
parameter integer ID = 0,
|
||||
parameter [ 7:0] FPGA_TECHNOLOGY = 0,
|
||||
parameter [ 7:0] FPGA_FAMILY = 0,
|
||||
parameter [ 7:0] SPEED_GRADE = 0,
|
||||
parameter [ 7:0] DEV_PACKAGE = 0,
|
||||
parameter [15:0] FPGA_VOLTAGE = 0,
|
||||
parameter integer XCVR_TYPE = 0,
|
||||
parameter integer TX_OR_RX_N = 0,
|
||||
parameter integer NUM_OF_LANES = 4) (
|
||||
|
||||
// xcvr, lane-pll and ref-pll are shared
|
||||
|
||||
output up_rst,
|
||||
input up_pll_locked,
|
||||
input [(NUM_OF_LANES-1):0] up_ready,
|
||||
|
||||
// bus interface
|
||||
|
||||
input up_rstn,
|
||||
input up_clk,
|
||||
input up_wreq,
|
||||
input [ 9:0] up_waddr,
|
||||
input [31:0] up_wdata,
|
||||
output up_wack,
|
||||
input up_rreq,
|
||||
input [ 9:0] up_raddr,
|
||||
output [31:0] up_rdata,
|
||||
output up_rack);
|
||||
|
||||
// parameters
|
||||
|
||||
localparam [31:0] VERSION = 32'h00110161;
|
||||
|
||||
// internal registers
|
||||
|
||||
reg up_wreq_d = 'd0;
|
||||
reg [31:0] up_scratch = 'd0;
|
||||
reg up_resetn = 'd0;
|
||||
reg [ 3:0] up_rst_cnt = 'd8;
|
||||
reg up_status_int = 'd0;
|
||||
reg up_rreq_d = 'd0;
|
||||
reg [31:0] up_rdata_d = 'd0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire up_ready_s;
|
||||
wire [31:0] up_status_32_s;
|
||||
wire [31:0] up_rparam_s;
|
||||
|
||||
// defaults
|
||||
|
||||
assign up_wack = up_wreq_d;
|
||||
|
||||
always @(negedge up_rstn or posedge up_clk) begin
|
||||
if (up_rstn == 0) begin
|
||||
up_wreq_d <= 'd0;
|
||||
up_scratch <= 'd0;
|
||||
end else begin
|
||||
up_wreq_d <= up_wreq;
|
||||
if ((up_wreq == 1'b1) && (up_waddr == 10'h002)) begin
|
||||
up_scratch <= up_wdata;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// reset-controller
|
||||
|
||||
always @(negedge up_rstn or posedge up_clk) begin
|
||||
if (up_rstn == 0) begin
|
||||
up_resetn <= 'd0;
|
||||
end else begin
|
||||
if ((up_wreq == 1'b1) && (up_waddr == 10'h004)) begin
|
||||
up_resetn <= up_wdata[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign up_rst = up_rst_cnt[3];
|
||||
assign up_ready_s = & up_status_32_s[NUM_OF_LANES:1];
|
||||
assign up_status_32_s[31:(NUM_OF_LANES+1)] = 'd0;
|
||||
assign up_status_32_s[NUM_OF_LANES] = up_pll_locked;
|
||||
assign up_status_32_s[(NUM_OF_LANES-1):0] = up_ready;
|
||||
|
||||
always @(negedge up_rstn or posedge up_clk) begin
|
||||
if (up_rstn == 0) begin
|
||||
up_rst_cnt <= 4'h8;
|
||||
up_status_int <= 1'b0;
|
||||
end else begin
|
||||
if (up_resetn == 1'b0) begin
|
||||
up_rst_cnt <= 4'h8;
|
||||
end else if (up_rst_cnt[3] == 1'b1) begin
|
||||
up_rst_cnt <= up_rst_cnt + 1'b1;
|
||||
end
|
||||
if (up_resetn == 1'b0) begin
|
||||
up_status_int <= 1'b0;
|
||||
end else if (up_ready_s == 1'b1) begin
|
||||
up_status_int <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Specific to Intel
|
||||
|
||||
assign up_rparam_s[31:28] = 8'd0;
|
||||
assign up_rparam_s[27:24] = XCVR_TYPE[3:0];
|
||||
|
||||
// Specific to Xilinx
|
||||
|
||||
assign up_rparam_s[23:16] = 8'd0;
|
||||
|
||||
// generic
|
||||
|
||||
assign up_rparam_s[15: 9] = 7'd0;
|
||||
assign up_rparam_s[ 8: 8] = (TX_OR_RX_N == 0) ? 1'b0 : 1'b1;
|
||||
assign up_rparam_s[ 7: 0] = NUM_OF_LANES[7:0];
|
||||
|
||||
// read interface
|
||||
|
||||
assign up_rack = up_rreq_d;
|
||||
assign up_rdata = up_rdata_d;
|
||||
|
||||
always @(negedge up_rstn or posedge up_clk) begin
|
||||
if (up_rstn == 0) begin
|
||||
up_rreq_d <= 'd0;
|
||||
up_rdata_d <= 'd0;
|
||||
end else begin
|
||||
up_rreq_d <= up_rreq;
|
||||
if (up_rreq == 1'b1) begin
|
||||
case (up_raddr)
|
||||
10'h000: up_rdata_d <= VERSION;
|
||||
10'h001: up_rdata_d <= ID;
|
||||
10'h002: up_rdata_d <= up_scratch;
|
||||
10'h004: up_rdata_d <= {31'd0, up_resetn};
|
||||
10'h005: up_rdata_d <= {31'd0, up_status_int};
|
||||
10'h006: up_rdata_d <= up_status_32_s;
|
||||
10'h007: up_rdata_d <= {FPGA_TECHNOLOGY,FPGA_FAMILY,SPEED_GRADE,DEV_PACKAGE}; // [8,8,8,8]
|
||||
10'h009: up_rdata_d <= up_rparam_s;
|
||||
10'h050: up_rdata_d <= {16'd0, FPGA_VOLTAGE}; // mV
|
||||
default: up_rdata_d <= 32'd0;
|
||||
endcase
|
||||
end else begin
|
||||
up_rdata_d <= 32'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
@@ -0,0 +1,85 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// dc filter- y(n) = c*x(n) + (1-c)*y(n-1)
|
||||
// NOT IMPLEMENTED
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
module ad_dcfilter #(
|
||||
|
||||
// data path disable
|
||||
|
||||
parameter DISABLE = 0) (
|
||||
|
||||
// data interface
|
||||
|
||||
input clk,
|
||||
input valid,
|
||||
input [15:0] data,
|
||||
output reg valid_out,
|
||||
output reg [15:0] data_out,
|
||||
|
||||
// control interface
|
||||
|
||||
input dcfilt_enb,
|
||||
input [15:0] dcfilt_coeff,
|
||||
input [15:0] dcfilt_offset);
|
||||
|
||||
// internal registers
|
||||
|
||||
reg valid_d = 'd0;
|
||||
reg [15:0] data_d = 'd0;
|
||||
reg valid_2d = 'd0;
|
||||
reg [15:0] data_2d = 'd0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [47:0] dc_offset_s;
|
||||
|
||||
always @(posedge clk) begin
|
||||
valid_d <= valid;
|
||||
if (valid == 1'b1) begin
|
||||
data_d <= data + dcfilt_offset;
|
||||
end
|
||||
valid_2d <= valid_d;
|
||||
data_2d <= data_d;
|
||||
valid_out <= valid_2d;
|
||||
data_out <= data_2d;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
@@ -0,0 +1,90 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 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
|
||||
|
||||
lpm_mult #(
|
||||
.lpm_type ("lpm_mult"),
|
||||
.lpm_widtha (A_DATA_WIDTH),
|
||||
.lpm_widthb (B_DATA_WIDTH),
|
||||
.lpm_widthp (A_DATA_WIDTH + B_DATA_WIDTH),
|
||||
.lpm_representation ("SIGNED"),
|
||||
.lpm_pipeline (3))
|
||||
i_lpm_mult (
|
||||
.clken (1'b1),
|
||||
.aclr (1'b0),
|
||||
.sclr (1'b0),
|
||||
.sum (1'b0),
|
||||
.clock (clk),
|
||||
.dataa (data_a),
|
||||
.datab (data_b),
|
||||
.result (data_p));
|
||||
|
||||
endmodule
|
||||
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
@@ -0,0 +1,10 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := intel_mem_asym
|
||||
|
||||
INTEL_DEPS += intel_mem_asym_hw.tcl
|
||||
|
||||
include ../../../scripts/library.mk
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
package require qsys
|
||||
|
||||
source ../../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
ad_ip_create intel_mem_asym {Intel Asymmetric Memory}
|
||||
set_module_property COMPOSITION_CALLBACK p_intel_mem_asym
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE_FAMILY STRING {Arria 10}
|
||||
ad_ip_parameter A_ADDRESS_WIDTH INTEGER 8
|
||||
ad_ip_parameter A_DATA_WIDTH INTEGER 512
|
||||
ad_ip_parameter B_ADDRESS_WIDTH INTEGER 8
|
||||
ad_ip_parameter B_DATA_WIDTH INTEGER 64
|
||||
|
||||
# compose
|
||||
|
||||
proc p_intel_mem_asym {} {
|
||||
|
||||
set m_addr_width_a [get_parameter_value "A_ADDRESS_WIDTH"]
|
||||
set m_data_width_a [get_parameter_value "A_DATA_WIDTH"]
|
||||
set m_addr_width_b [get_parameter_value "B_ADDRESS_WIDTH"]
|
||||
set m_data_width_b [get_parameter_value "B_DATA_WIDTH"]
|
||||
|
||||
set m_size [expr ((2**$m_addr_width_a)*$m_data_width_a)]
|
||||
if {$m_addr_width_a == 0} {
|
||||
set m_size [expr ((2**$m_addr_width_b)*$m_data_width_b)]
|
||||
}
|
||||
|
||||
add_instance intel_mem ram_2port 1.0
|
||||
set_instance_parameter_value intel_mem {GUI_MODE} 0
|
||||
set_instance_parameter_value intel_mem {GUI_MEM_IN_BITS} 1
|
||||
set_instance_parameter_value intel_mem {GUI_MEMSIZE_BITS} $m_size
|
||||
set_instance_parameter_value intel_mem {GUI_VAR_WIDTH} 1
|
||||
set_instance_parameter_value intel_mem {GUI_QA_WIDTH} $m_data_width_a
|
||||
set_instance_parameter_value intel_mem {GUI_DATAA_WIDTH} $m_data_width_a
|
||||
set_instance_parameter_value intel_mem {GUI_QB_WIDTH} $m_data_width_b
|
||||
set_instance_parameter_value intel_mem {GUI_READ_OUTPUT_QB} {false}
|
||||
set_instance_parameter_value intel_mem {GUI_RAM_BLOCK_TYPE} {M20K}
|
||||
set_instance_parameter_value intel_mem {GUI_CLOCK_TYPE} 1
|
||||
|
||||
add_interface mem_i_wrclock clock end
|
||||
add_interface mem_i_wren conduit end
|
||||
add_interface mem_i_wraddress conduit end
|
||||
add_interface mem_i_datain conduit end
|
||||
add_interface mem_i_rdclock clock end
|
||||
add_interface mem_i_rdaddress conduit end
|
||||
add_interface mem_o_dataout conduit end
|
||||
|
||||
set_interface_property mem_i_wrclock EXPORT_OF intel_mem.wrclock
|
||||
set_interface_property mem_i_wren EXPORT_OF intel_mem.wren
|
||||
set_interface_property mem_i_wraddress EXPORT_OF intel_mem.wraddress
|
||||
set_interface_property mem_i_datain EXPORT_OF intel_mem.data
|
||||
set_interface_property mem_i_rdclock EXPORT_OF intel_mem.rdclock
|
||||
set_interface_property mem_i_rdaddress EXPORT_OF intel_mem.rdaddress
|
||||
set_interface_property mem_o_dataout EXPORT_OF intel_mem.q
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := intel_serdes
|
||||
|
||||
INTEL_DEPS += intel_serdes_hw.tcl
|
||||
|
||||
include ../../../scripts/library.mk
|
||||
@@ -0,0 +1,138 @@
|
||||
|
||||
package require qsys
|
||||
|
||||
source ../../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
ad_ip_create intel_serdes {Intel SERDES}
|
||||
set_module_property COMPOSITION_CALLBACK p_intel_serdes
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE_FAMILY STRING {Arria 10}
|
||||
ad_ip_parameter MODE STRING "CLK" false
|
||||
ad_ip_parameter DDR_OR_SDR_N INTEGER 1 false
|
||||
ad_ip_parameter SERDES_FACTOR INTEGER 8 false
|
||||
ad_ip_parameter CLKIN_FREQUENCY FLOAT 500.0 false
|
||||
|
||||
set_parameter_property MODE ALLOWED_RANGES {"CLK" "IN" "IN_NODPA" "OUT"}
|
||||
set_parameter_property DDR_OR_SDR_N ALLOWED_RANGES {0 1}
|
||||
set_parameter_property SERDES_FACTOR ALLOWED_RANGES {4 8}
|
||||
set_parameter_property CLKIN_FREQUENCY DISPLAY_UNITS "MHz"
|
||||
|
||||
proc p_intel_serdes {} {
|
||||
|
||||
set m_mode [get_parameter_value "MODE"]
|
||||
set m_ddr_or_sdr_n [get_parameter_value "DDR_OR_SDR_N"]
|
||||
set m_serdes_factor [get_parameter_value "SERDES_FACTOR"]
|
||||
set m_clkin_frequency [get_parameter_value "CLKIN_FREQUENCY"]
|
||||
|
||||
set m_hs_data_rate [expr ($m_clkin_frequency * ($m_ddr_or_sdr_n + 1))]
|
||||
set m_ls_data_rate [expr ($m_hs_data_rate/$m_serdes_factor)]
|
||||
|
||||
set m_ls_phase 22.5
|
||||
set m_ld_phase 315.0
|
||||
set m_ld_duty_cycle 12.5
|
||||
|
||||
if {$m_serdes_factor == 4} {
|
||||
set m_ls_phase 45
|
||||
set m_ld_phase 270.0
|
||||
set m_ld_duty_cycle 25.0
|
||||
}
|
||||
|
||||
## arria 10 only
|
||||
|
||||
if {$m_mode == "CLK"} {
|
||||
add_instance intel_serdes_pll altera_iopll 19.1
|
||||
set_instance_parameter_value intel_serdes_pll {gui_reference_clock_frequency} $m_clkin_frequency
|
||||
set_instance_parameter_value intel_serdes_pll {gui_use_locked} {1}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_operation_mode} {lvds}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_number_of_clocks} {3}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_en_lvds_ports} {Enable LVDS_CLK/LOADEN 0}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_en_phout_ports} {true}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_output_clock_frequency0} $m_hs_data_rate
|
||||
set_instance_parameter_value intel_serdes_pll {gui_ps_units0} {degrees}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_phase_shift_deg0} {180.0}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_output_clock_frequency1} $m_ls_data_rate
|
||||
set_instance_parameter_value intel_serdes_pll {gui_ps_units1} {degrees}
|
||||
set_instance_parameter_value intel_serdes_pll {gui_phase_shift_deg1} $m_ld_phase
|
||||
set_instance_parameter_value intel_serdes_pll {gui_duty_cycle1} $m_ld_duty_cycle
|
||||
set_instance_parameter_value intel_serdes_pll {gui_output_clock_frequency2} $m_ls_data_rate
|
||||
set_instance_parameter_value intel_serdes_pll {gui_phase_shift_deg2} $m_ls_phase
|
||||
set_instance_parameter_value intel_serdes_pll {gui_ps_units2} {degrees}
|
||||
add_interface rst reset sink
|
||||
set_interface_property rst EXPORT_OF intel_serdes_pll.reset
|
||||
add_interface ref_clk clock sink
|
||||
set_interface_property ref_clk EXPORT_OF intel_serdes_pll.refclk
|
||||
add_interface locked conduit end
|
||||
set_interface_property locked EXPORT_OF intel_serdes_pll.locked
|
||||
add_interface hs_phase conduit end
|
||||
set_interface_property hs_phase EXPORT_OF intel_serdes_pll.phout
|
||||
add_interface hs_clk conduit end
|
||||
set_interface_property hs_clk EXPORT_OF intel_serdes_pll.lvds_clk
|
||||
add_interface loaden conduit end
|
||||
set_interface_property loaden EXPORT_OF intel_serdes_pll.loaden
|
||||
add_interface ls_clk clock source
|
||||
set_interface_property ls_clk EXPORT_OF intel_serdes_pll.outclk2
|
||||
return
|
||||
}
|
||||
|
||||
if {$m_mode == "IN" || $m_mode == "IN_NODPA"} {
|
||||
add_instance intel_serdes_in altera_lvds 19.1
|
||||
if {$m_mode == "IN"} {
|
||||
set_instance_parameter_value intel_serdes_in {MODE} {RX_DPA-FIFO}
|
||||
} else {
|
||||
set_instance_parameter_value intel_serdes_in {MODE} {RX_Non-DPA}
|
||||
}
|
||||
set_instance_parameter_value intel_serdes_in {NUM_CHANNELS} {1}
|
||||
set_instance_parameter_value intel_serdes_in {DATA_RATE} $m_hs_data_rate
|
||||
set_instance_parameter_value intel_serdes_in {J_FACTOR} $m_serdes_factor
|
||||
set_instance_parameter_value intel_serdes_in {USE_EXTERNAL_PLL} {true}
|
||||
set_instance_parameter_value intel_serdes_in {INCLOCK_FREQUENCY} $m_clkin_frequency
|
||||
set_instance_parameter_value intel_serdes_in {PLL_USE_RESET} {false}
|
||||
add_interface data_in conduit end
|
||||
set_interface_property data_in EXPORT_OF intel_serdes_in.rx_in
|
||||
add_interface clk conduit end
|
||||
set_interface_property clk EXPORT_OF intel_serdes_in.ext_fclk
|
||||
add_interface loaden conduit end
|
||||
set_interface_property loaden EXPORT_OF intel_serdes_in.ext_loaden
|
||||
add_interface div_clk conduit end
|
||||
set_interface_property div_clk EXPORT_OF intel_serdes_in.ext_coreclock
|
||||
if {$m_mode == "IN"} {
|
||||
add_interface hs_phase conduit end
|
||||
set_interface_property hs_phase EXPORT_OF intel_serdes_in.ext_vcoph
|
||||
add_interface locked conduit end
|
||||
set_interface_property locked EXPORT_OF intel_serdes_in.ext_pll_locked
|
||||
add_interface delay_locked conduit end
|
||||
set_interface_property delay_locked EXPORT_OF intel_serdes_in.rx_dpa_locked
|
||||
}
|
||||
add_interface data_s conduit end
|
||||
set_interface_property data_s EXPORT_OF intel_serdes_in.rx_out
|
||||
return
|
||||
}
|
||||
|
||||
if {$m_mode == "OUT"} {
|
||||
add_instance intel_serdes_out altera_lvds 19.1
|
||||
set_instance_parameter_value intel_serdes_out {MODE} {TX}
|
||||
set_instance_parameter_value intel_serdes_out {NUM_CHANNELS} {1}
|
||||
set_instance_parameter_value intel_serdes_out {DATA_RATE} $m_hs_data_rate
|
||||
set_instance_parameter_value intel_serdes_out {J_FACTOR} $m_serdes_factor
|
||||
set_instance_parameter_value intel_serdes_out {TX_EXPORT_CORECLOCK} {false}
|
||||
set_instance_parameter_value intel_serdes_out {TX_USE_OUTCLOCK} {false}
|
||||
set_instance_parameter_value intel_serdes_out {USE_EXTERNAL_PLL} {true}
|
||||
set_instance_parameter_value intel_serdes_out {INCLOCK_FREQUENCY} $m_clkin_frequency
|
||||
set_instance_parameter_value intel_serdes_out {PLL_USE_RESET} {false}
|
||||
add_interface data_out conduit end
|
||||
set_interface_property data_out EXPORT_OF intel_serdes_out.tx_out
|
||||
add_interface clk conduit end
|
||||
set_interface_property clk EXPORT_OF intel_serdes_out.ext_fclk
|
||||
add_interface loaden conduit end
|
||||
set_interface_property loaden EXPORT_OF intel_serdes_out.ext_loaden
|
||||
add_interface div_clk conduit end
|
||||
set_interface_property div_clk EXPORT_OF intel_serdes_out.ext_coreclock
|
||||
add_interface data_s conduit end
|
||||
set_interface_property data_s EXPORT_OF intel_serdes_out.tx_in
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
set_false_path -from [get_registers *up_clock_mon:i_clock_mon|d_count_run_m3*] -to [get_registers *up_clock_mon:i_clock_mon|up_count_running_m1*]
|
||||
set_false_path -from [get_registers *up_clock_mon:i_clock_mon|up_count_run*] -to [get_registers *up_clock_mon:i_clock_mon|d_count_run_m1*]
|
||||
set_false_path -from [get_registers *up_clock_mon:i_clock_mon|d_count*] -to [get_registers *up_clock_mon:i_clock_mon|up_d_count*]
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
set_false_path -to [get_pins -hierarchical -nocase rst_async_d*|CLRN]
|
||||
set_false_path -to [get_pins -hierarchical -nocase rst_sync|CLRN]
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_state_m1*]
|
||||
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_toggle*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_xfer_toggle_m1*]
|
||||
set_false_path -from [get_registers *up_xfer_cntrl:i_xfer_cntrl|up_xfer_data*] -to [get_registers *up_xfer_cntrl:i_xfer_cntrl|d_data_cntrl*]
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
set_false_path -from [get_registers *up_xfer_status:i_xfer_status|up_xfer_toggle*] -to [get_registers *up_xfer_status:i_xfer_status|d_xfer_state_m1*]
|
||||
set_false_path -from [get_registers *up_xfer_status:i_xfer_status|d_xfer_toggle*] -to [get_registers *up_xfer_status:i_xfer_status|up_xfer_toggle_m1*]
|
||||
set_false_path -from [get_registers *up_xfer_status:i_xfer_status|d_xfer_data*] -to [get_registers *up_xfer_status:i_xfer_status|up_data_status*]
|
||||
@@ -0,0 +1,15 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := jesd204_phy
|
||||
|
||||
INTEL_DEPS += jesd204_phy_glue.v
|
||||
INTEL_DEPS += jesd204_phy_glue_hw.tcl
|
||||
INTEL_DEPS += jesd204_phy_hw.tcl
|
||||
|
||||
INTEL_LIB_DEPS += jesd204/jesd204_soft_pcs_rx
|
||||
INTEL_LIB_DEPS += jesd204/jesd204_soft_pcs_tx
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,56 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module jesd204_glue #(
|
||||
parameter WIDTH = 20,
|
||||
parameter CONST_WIDTH = 1,
|
||||
parameter NUM_OF_LANES = 1,
|
||||
parameter LANE_INVERT = 0
|
||||
) (
|
||||
input [WIDTH-1:0] in,
|
||||
output [WIDTH-1:0] out,
|
||||
output [CONST_WIDTH-1:0] const_out,
|
||||
output [NUM_OF_LANES-1:0] polinv
|
||||
);
|
||||
|
||||
/* There really should be a standard component in Qsys that allows to do this */
|
||||
|
||||
assign out = in;
|
||||
assign const_out = {CONST_WIDTH{1'b0}};
|
||||
assign polinv = LANE_INVERT[NUM_OF_LANES-1:0];
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,345 @@
|
||||
#
|
||||
# The ADI JESD204 Core is released under the following license, which is
|
||||
# different than all other HDL cores in this repository.
|
||||
#
|
||||
# Please read this, and understand the freedoms and responsibilities you have
|
||||
# by using this source code/core.
|
||||
#
|
||||
# The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc.
|
||||
#
|
||||
# This core is free software, you can use run, copy, study, change, ask
|
||||
# questions about and improve this core. Distribution of source, or resulting
|
||||
# binaries (including those inside an FPGA or ASIC) require you to release the
|
||||
# source of the entire project (excluding the system libraries provide by the
|
||||
# tools/compiler/FPGA vendor). These are the terms of the GNU General Public
|
||||
# License version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version 2
|
||||
# along with this source code, and binary. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Commercial licenses (with commercial support) of this JESD204 core are also
|
||||
# available under terms different than the General Public License. (e.g. they
|
||||
# do not require you to accompany any image (FPGA or ASIC) using the JESD204
|
||||
# core with any corresponding source code.) For these alternate terms you must
|
||||
# purchase a license from Analog Devices Technology Licensing Office. Users
|
||||
# interested in such a license should contact [email protected] for
|
||||
# more information. This commercial license is sub-licensable (if you purchase
|
||||
# chips from Analog Devices, incorporate them into your PCB level product, and
|
||||
# purchase a JESD204 license, end users of your product will also have a
|
||||
# license to use this core in a commercial setting without releasing their
|
||||
# source code).
|
||||
#
|
||||
# In addition, we kindly ask you to acknowledge ADI in any program, application
|
||||
# or publication in which you use this JESD204 HDL core. (You are not required
|
||||
# to do so; it is up to your common sense to decide whether you want to comply
|
||||
# with this request or not.) For general publications, we suggest referencing :
|
||||
# “The design and implementation of the JESD204 HDL Core used in this project
|
||||
# is copyright © 2016-2017, Analog Devices, Inc.”
|
||||
#
|
||||
|
||||
package require qsys
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
#
|
||||
# For whatever strange reason all the interface of the native PHY become
|
||||
# conduits when it is instantiated in a compose callback. This glue logic module
|
||||
# converts the interfaces to their proper type.
|
||||
#
|
||||
|
||||
ad_ip_create jesd204_phy_glue {Native PHY to JESD204 glue logic} \
|
||||
jesd204_phy_glue_elab
|
||||
set_module_property INTERNAL true
|
||||
|
||||
# files
|
||||
|
||||
ad_ip_files jesd204_glue [list \
|
||||
jesd204_phy_glue.v \
|
||||
]
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE STRING "" false
|
||||
ad_ip_parameter TX_OR_RX_N BOOLEAN false false
|
||||
ad_ip_parameter SOFT_PCS BOOLEAN false false
|
||||
ad_ip_parameter BONDING_CLOCKS_EN BOOLEAN false false
|
||||
ad_ip_parameter NUM_OF_LANES POSITIVE 4 true
|
||||
ad_ip_parameter LANE_INVERT INTEGER 0 true
|
||||
ad_ip_parameter WIDTH NATURAL 20 true { \
|
||||
DERIVED true \
|
||||
}
|
||||
ad_ip_parameter CONST_WIDTH NATURAL 1 true { \
|
||||
DERIVED true \
|
||||
}
|
||||
|
||||
proc glue_add_if {num name type dir {bcast false}} {
|
||||
if {$bcast} {
|
||||
add_interface ${name} $type $dir
|
||||
} else {
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
add_interface ${name}_${i} $type $dir
|
||||
}
|
||||
}
|
||||
add_interface phy_${name} conduit end
|
||||
}
|
||||
|
||||
proc glue_add_if_port {num ifname port role dir width {bcast false}} {
|
||||
variable sig_offset
|
||||
|
||||
set phy_width [expr $num * $width]
|
||||
if {$dir == "Input"} {
|
||||
set sig "in"
|
||||
set phy_dir "Output"
|
||||
set phy_sig "out"
|
||||
} else {
|
||||
set sig "out"
|
||||
set phy_dir "Input"
|
||||
set phy_sig "in"
|
||||
}
|
||||
|
||||
if {$bcast} {
|
||||
add_interface_port ${ifname} ${port} $role $dir $width
|
||||
set_port_property ${port} fragment_list \
|
||||
[format "%s(%d:%d)" $sig [expr $sig_offset + $width - 1] $sig_offset]
|
||||
} else {
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
set base [expr $sig_offset + $width * $i]
|
||||
|
||||
add_interface_port ${ifname}_${i} ${port}_${i} $role $dir $width
|
||||
set_port_property ${port}_${i} fragment_list \
|
||||
[format "%s(%d:%d)" $sig [expr $base + $width - 1] $base]
|
||||
}
|
||||
}
|
||||
|
||||
add_interface_port phy_${ifname} phy_${port} $role $phy_dir $phy_width
|
||||
|
||||
if {$bcast} {
|
||||
set _frag [format "%s(%d:%d)" $phy_sig [expr $sig_offset + $width - 1] $sig_offset]
|
||||
set sig_offset [expr $sig_offset + $width]
|
||||
set frag "${_frag}"
|
||||
for {set i 1} {$i < $num} {incr i} {
|
||||
set frag [concat ${frag} ${_frag}]
|
||||
}
|
||||
} else {
|
||||
set frag [format "%s(%d:%d)" $phy_sig [expr $sig_offset + $phy_width - 1] $sig_offset]
|
||||
set sig_offset [expr $sig_offset + $phy_width]
|
||||
}
|
||||
|
||||
set_port_property phy_${port} fragment_list $frag
|
||||
}
|
||||
|
||||
proc glue_add_tx_serial_clk {num_of_lanes} {
|
||||
variable sig_offset
|
||||
|
||||
# The serial clock is special. The first 6 transceivers use the x1 connection
|
||||
# since they are in the same bank as the PLL. The others have to use the xN
|
||||
# connection through the CGB.
|
||||
|
||||
if {$num_of_lanes > 6} {
|
||||
set clk0_width 6
|
||||
set clk1_width [expr $num_of_lanes - 6]
|
||||
|
||||
} else {
|
||||
set clk0_width $num_of_lanes
|
||||
set clk1_width 0
|
||||
}
|
||||
|
||||
add_interface tx_serial_clk_x1 hssi_serial_clock sink
|
||||
add_interface_port tx_serial_clk_x1 tx_serial_clk_x1 clk Input 1
|
||||
set_port_property tx_serial_clk_x1 fragment_list \
|
||||
[format "in(%d:%d)" $sig_offset $sig_offset]
|
||||
|
||||
add_interface phy_tx_serial_clk0 conduit end
|
||||
add_interface_port phy_tx_serial_clk0 phy_tx_serial_clk0 clk Output $num_of_lanes
|
||||
|
||||
set _frag [format "out(%d:%d)" $sig_offset $sig_offset]
|
||||
set sig_offset [expr $sig_offset + 1]
|
||||
set frag "${_frag}"
|
||||
for {set i 1} {$i < $clk0_width} {incr i} {
|
||||
set frag [concat ${_frag} ${frag}]
|
||||
}
|
||||
|
||||
if {$num_of_lanes > 6} {
|
||||
add_interface tx_serial_clk_xN hssi_serial_clock sink
|
||||
add_interface_port tx_serial_clk_xN tx_serial_clk_xN clk Input 1
|
||||
set_port_property tx_serial_clk_xN fragment_list \
|
||||
[format "in(%d:%d)" $sig_offset $sig_offset]
|
||||
|
||||
set _frag [format "out(%d:%d)" $sig_offset $sig_offset]
|
||||
set sig_offset [expr $sig_offset + 1]
|
||||
for {set i 0} {$i < $clk1_width} {incr i} {
|
||||
set frag [concat ${_frag} ${frag}]
|
||||
}
|
||||
}
|
||||
|
||||
set_port_property phy_tx_serial_clk0 fragment_list $frag
|
||||
}
|
||||
|
||||
proc glue_add_if_port_conduit {num ifname port phy_port dir width} {
|
||||
variable sig_offset
|
||||
|
||||
set phy_width [expr $num * $width]
|
||||
if {$dir == "Input"} {
|
||||
set sig "in"
|
||||
set phy_dir "Output"
|
||||
set phy_sig "out"
|
||||
} else {
|
||||
set sig "out"
|
||||
set phy_dir "Input"
|
||||
set phy_sig "in"
|
||||
}
|
||||
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
set base [expr $sig_offset + $width * $i]
|
||||
|
||||
add_interface_port ${ifname}_${i} ${ifname}_${port}_${i} $port $dir $width
|
||||
set_port_property ${ifname}_${port}_${i} fragment_list \
|
||||
[format "%s(%d:%d)" $sig [expr $base + $width - 1] $base]
|
||||
}
|
||||
|
||||
add_interface phy_${phy_port} conduit end
|
||||
add_interface_port phy_${phy_port} phy_${phy_port} $phy_port $phy_dir $phy_width
|
||||
|
||||
set_port_property phy_${phy_port} fragment_list \
|
||||
[format "%s(%d:%d)" $phy_sig [expr $sig_offset + $phy_width - 1] $sig_offset]
|
||||
|
||||
set sig_offset [expr $sig_offset + $phy_width]
|
||||
}
|
||||
|
||||
proc glue_add_const_conduit {port width} {
|
||||
variable const_offset
|
||||
|
||||
set ifname phy_${port}
|
||||
add_interface $ifname conduit end
|
||||
add_interface_port $ifname $ifname $port Output $width
|
||||
set_port_property $ifname fragment_list [format "const_out(%d:%d)" \
|
||||
[expr $const_offset + $width - 1] $const_offset]
|
||||
|
||||
set const_offset [expr $const_offset + $width]
|
||||
}
|
||||
|
||||
proc jesd204_phy_glue_elab {} {
|
||||
variable sig_offset
|
||||
variable const_offset
|
||||
|
||||
set device [get_parameter DEVICE]
|
||||
set soft_pcs [get_parameter SOFT_PCS]
|
||||
set num_of_lanes [get_parameter NUM_OF_LANES]
|
||||
set bonding_clocks_en [get_parameter BONDING_CLOCKS_EN]
|
||||
|
||||
set sig_offset 0
|
||||
set const_offset 0
|
||||
|
||||
if {[string equal $device "Arria 10"]} {
|
||||
set reconfig_avmm_address_width 10
|
||||
set unused_width_per_lane 88
|
||||
} elseif {[string equal $device "Stratix 10"]} {
|
||||
set reconfig_avmm_address_width 11
|
||||
set unused_width_per_lane 40
|
||||
} else {
|
||||
send_message error "Only Arria 10 and Stratix 10 are supported."
|
||||
}
|
||||
|
||||
glue_add_if $num_of_lanes reconfig_clk clock sink true
|
||||
glue_add_if_port $num_of_lanes reconfig_clk reconfig_clk clk Input 1 true
|
||||
|
||||
glue_add_if $num_of_lanes reconfig_reset reset sink true
|
||||
glue_add_if_port $num_of_lanes reconfig_reset reconfig_reset reset Input 1 true
|
||||
|
||||
glue_add_if $num_of_lanes reconfig_avmm avalon sink
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
set_interface_property reconfig_avmm_${i} associatedClock reconfig_clk
|
||||
set_interface_property reconfig_avmm_${i} associatedReset reconfig_reset
|
||||
}
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_address address Input $reconfig_avmm_address_width
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_read read Input 1
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_readdata readdata Output 32
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_waitrequest waitrequest Output 1
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_write write Input 1
|
||||
glue_add_if_port $num_of_lanes reconfig_avmm reconfig_writedata writedata Input 32
|
||||
|
||||
if {[get_parameter TX_OR_RX_N]} {
|
||||
glue_add_if $num_of_lanes tx_clkout clock source
|
||||
glue_add_if_port $num_of_lanes tx_clkout tx_clkout clk Output 1
|
||||
|
||||
glue_add_if $num_of_lanes tx_coreclkin clock sink true
|
||||
glue_add_if_port $num_of_lanes tx_coreclkin tx_coreclkin clk Input 1 true
|
||||
|
||||
if {$bonding_clocks_en && $num_of_lanes > 6} {
|
||||
glue_add_if $num_of_lanes tx_bonding_clocks hssi_bonded_clock sink true
|
||||
glue_add_if_port $num_of_lanes tx_bonding_clocks tx_bonding_clocks clk Input 6 true
|
||||
} else {
|
||||
glue_add_tx_serial_clk $num_of_lanes
|
||||
}
|
||||
|
||||
if {$soft_pcs} {
|
||||
set unused_width [expr $num_of_lanes * $unused_width_per_lane]
|
||||
|
||||
glue_add_const_conduit tx_enh_data_valid $num_of_lanes
|
||||
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface tx_raw_data_${i} conduit start
|
||||
}
|
||||
glue_add_if_port_conduit $num_of_lanes tx_raw_data raw_data tx_parallel_data Input 40
|
||||
} else {
|
||||
set unused_width [expr $num_of_lanes * 92]
|
||||
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface tx_phy_${i} conduit start
|
||||
}
|
||||
glue_add_if_port_conduit $num_of_lanes tx_phy char tx_parallel_data Input 32
|
||||
glue_add_if_port_conduit $num_of_lanes tx_phy charisk tx_datak Input 4
|
||||
}
|
||||
|
||||
glue_add_const_conduit unused_tx_parallel_data $unused_width
|
||||
|
||||
add_interface phy_tx_polinv conduit end
|
||||
add_interface_port phy_tx_polinv polinv tx_polinv Output $num_of_lanes
|
||||
set_port_property polinv TERMINATION $soft_pcs
|
||||
} else {
|
||||
glue_add_if 1 rx_cdr_refclk0 clock sink true
|
||||
glue_add_if_port 1 rx_cdr_refclk0 rx_cdr_refclk0 clk Input 1 true
|
||||
|
||||
glue_add_if $num_of_lanes rx_coreclkin clock sink true
|
||||
glue_add_if_port $num_of_lanes rx_coreclkin rx_coreclkin clk Input 1 true
|
||||
|
||||
glue_add_if $num_of_lanes rx_clkout clock source
|
||||
glue_add_if_port $num_of_lanes rx_clkout rx_clkout clk Output 1
|
||||
|
||||
if {$soft_pcs} {
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface rx_raw_data_${i} conduit start
|
||||
}
|
||||
glue_add_if_port_conduit $num_of_lanes rx_raw_data raw_data rx_parallel_data Output 40
|
||||
} else {
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface rx_phy_${i} conduit start
|
||||
}
|
||||
glue_add_if_port_conduit $num_of_lanes rx_phy char rx_parallel_data Output 32
|
||||
glue_add_if_port_conduit $num_of_lanes rx_phy charisk rx_datak Output 4
|
||||
glue_add_if_port_conduit $num_of_lanes rx_phy disperr rx_disperr Output 4
|
||||
glue_add_if_port_conduit $num_of_lanes rx_phy notintable rx_errdetect Output 4
|
||||
glue_add_if_port_conduit $num_of_lanes rx_phy patternalign_en rx_std_wa_patternalign Input 1
|
||||
}
|
||||
|
||||
add_interface const_out conduit end
|
||||
add_interface_port const_out const_out const_out Output 1
|
||||
set_port_property const_out TERMINATION true
|
||||
set const_offset 1
|
||||
|
||||
add_interface phy_rx_polinv conduit end
|
||||
add_interface_port phy_rx_polinv polinv rx_polinv Output $num_of_lanes
|
||||
set_port_property polinv TERMINATION $soft_pcs
|
||||
}
|
||||
|
||||
set_interface_property reconfig_reset associatedClock reconfig_clk
|
||||
set_interface_property reconfig_reset synchronousEdges DEASSERT
|
||||
|
||||
set_parameter_value WIDTH $sig_offset
|
||||
set_parameter_value CONST_WIDTH $const_offset
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
#
|
||||
# The ADI JESD204 Core is released under the following license, which is
|
||||
# different than all other HDL cores in this repository.
|
||||
#
|
||||
# Please read this, and understand the freedoms and responsibilities you have
|
||||
# by using this source code/core.
|
||||
#
|
||||
# The JESD204 HDL, is copyright © 2016-2017 Analog Devices Inc.
|
||||
#
|
||||
# This core is free software, you can use run, copy, study, change, ask
|
||||
# questions about and improve this core. Distribution of source, or resulting
|
||||
# binaries (including those inside an FPGA or ASIC) require you to release the
|
||||
# source of the entire project (excluding the system libraries provide by the
|
||||
# tools/compiler/FPGA vendor). These are the terms of the GNU General Public
|
||||
# License version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
# 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. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version 2
|
||||
# along with this source code, and binary. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Commercial licenses (with commercial support) of this JESD204 core are also
|
||||
# available under terms different than the General Public License. (e.g. they
|
||||
# do not require you to accompany any image (FPGA or ASIC) using the JESD204
|
||||
# core with any corresponding source code.) For these alternate terms you must
|
||||
# purchase a license from Analog Devices Technology Licensing Office. Users
|
||||
# interested in such a license should contact [email protected] for
|
||||
# more information. This commercial license is sub-licensable (if you purchase
|
||||
# chips from Analog Devices, incorporate them into your PCB level product, and
|
||||
# purchase a JESD204 license, end users of your product will also have a
|
||||
# license to use this core in a commercial setting without releasing their
|
||||
# source code).
|
||||
#
|
||||
# In addition, we kindly ask you to acknowledge ADI in any program, application
|
||||
# or publication in which you use this JESD204 HDL core. (You are not required
|
||||
# to do so; it is up to your common sense to decide whether you want to comply
|
||||
# with this request or not.) For general publications, we suggest referencing :
|
||||
# “The design and implementation of the JESD204 HDL Core used in this project
|
||||
# is copyright © 2016-2017, Analog Devices, Inc.”
|
||||
#
|
||||
|
||||
package require qsys
|
||||
|
||||
source ../../scripts/adi_env.tcl
|
||||
source $ad_hdl_dir/library/scripts/adi_ip_intel.tcl
|
||||
|
||||
set version 19.2
|
||||
|
||||
#
|
||||
# Instantiates the Arria 10 native PHY and configures it for JESD204 operation.
|
||||
# The datapath width is configured for 4 octets per beat.
|
||||
#
|
||||
# Optionally a soft-logic PCS is instantiated, this can be used if the lane rate
|
||||
# is too high for the hard-logic PCS.
|
||||
#
|
||||
|
||||
ad_ip_create jesd204_phy "ADI JESD204 PHY"
|
||||
set_module_property COMPOSITION_CALLBACK jesd204_phy_composition_callback
|
||||
set_module_property INTERNAL false
|
||||
|
||||
# parameters
|
||||
|
||||
ad_ip_parameter DEVICE STRING "Stratix 10" false
|
||||
ad_ip_parameter ID NATURAL 0 false
|
||||
ad_ip_parameter SOFT_PCS BOOLEAN false false
|
||||
ad_ip_parameter TX_OR_RX_N BOOLEAN false false
|
||||
ad_ip_parameter LANE_RATE FLOAT 10000 false
|
||||
ad_ip_parameter REFCLK_FREQUENCY FLOAT 500.0 false
|
||||
ad_ip_parameter NUM_OF_LANES POSITIVE 4 false
|
||||
ad_ip_parameter REGISTER_INPUTS INTEGER 0 false
|
||||
ad_ip_parameter LANE_INVERT INTEGER 0 false
|
||||
ad_ip_parameter EXT_DEVICE_CLK_EN BOOLEAN false false
|
||||
ad_ip_parameter BONDING_CLOCKS_EN BOOLEAN false false
|
||||
|
||||
proc jesd204_phy_composition_callback {} {
|
||||
|
||||
global version
|
||||
|
||||
set device [get_parameter_value "DEVICE"]
|
||||
set soft_pcs [get_parameter_value "SOFT_PCS"]
|
||||
set tx [get_parameter_value "TX_OR_RX_N"]
|
||||
set lane_rate [get_parameter_value "LANE_RATE"]
|
||||
set refclk_frequency [get_parameter_value "REFCLK_FREQUENCY"]
|
||||
set id [get_parameter_value "ID"]
|
||||
set num_of_lanes [get_parameter_value "NUM_OF_LANES"]
|
||||
set register_inputs [get_parameter_value "REGISTER_INPUTS"]
|
||||
set lane_invert [get_parameter_value "LANE_INVERT"]
|
||||
set ext_device_clk_en [get_parameter_value "EXT_DEVICE_CLK_EN"]
|
||||
set bonding_clocks_en [get_parameter_value "BONDING_CLOCKS_EN"]
|
||||
|
||||
set link_clk_frequency [expr $lane_rate / 40]
|
||||
|
||||
if {[string equal $device "Arria 10"]} {
|
||||
set device_type 1
|
||||
} elseif {[string equal $device "Stratix 10"]} {
|
||||
set device_type 2
|
||||
} else {
|
||||
set device_type 0
|
||||
}
|
||||
|
||||
add_instance link_clock clock_source $version
|
||||
set_instance_parameter_value link_clock {clockFrequency} [expr $link_clk_frequency*1000000]
|
||||
add_interface link_clk clock sink
|
||||
set_interface_property link_clk EXPORT_OF link_clock.clk_in
|
||||
add_interface link_reset reset sink
|
||||
set_interface_property link_reset EXPORT_OF link_clock.clk_in_reset
|
||||
|
||||
## Arria10
|
||||
if {$device_type == 1} {
|
||||
add_instance native_phy altera_xcvr_native_a10 19.1
|
||||
set_instance_parameter_value native_phy {enh_txfifo_mode} "Phase compensation"
|
||||
set_instance_parameter_value native_phy {enh_rxfifo_mode} "Phase compensation"
|
||||
set_instance_property native_phy SUPPRESS_ALL_WARNINGS true
|
||||
set_instance_property native_phy SUPPRESS_ALL_INFO_MESSAGES true
|
||||
## Stratix 10
|
||||
} elseif {$device_type == 2} {
|
||||
add_instance native_phy altera_xcvr_native_s10_htile $version
|
||||
set_instance_parameter_value native_phy {tx_fifo_mode} "Phase compensation"
|
||||
set_instance_parameter_value native_phy {rx_fifo_mode} "Phase compensation"
|
||||
## Unsupported device
|
||||
} else {
|
||||
send_message error "Only Arria 10 and Stratix 10 are supported."
|
||||
}
|
||||
|
||||
if {$soft_pcs} {
|
||||
set_instance_parameter_value native_phy {protocol_mode} "basic_enh"
|
||||
} else {
|
||||
set_instance_parameter_value native_phy {protocol_mode} "basic_std"
|
||||
set_instance_parameter_value native_phy {std_pcs_pma_width} 20
|
||||
|
||||
if {$tx} {
|
||||
set_instance_parameter_value native_phy {std_tx_byte_ser_mode} "Serialize x2"
|
||||
set_instance_parameter_value native_phy {std_tx_8b10b_enable} 1
|
||||
set_instance_parameter_value native_phy {std_tx_polinv_enable} 1
|
||||
set_instance_parameter_value native_phy {enable_port_tx_polinv} 1
|
||||
} else {
|
||||
set_instance_parameter_value native_phy {std_rx_byte_deser_mode} "Deserialize x2"
|
||||
set_instance_parameter_value native_phy {std_rx_8b10b_enable} 1
|
||||
set_instance_parameter_value native_phy {std_rx_word_aligner_mode} "manual (PLD controlled)"
|
||||
set_instance_parameter_value native_phy {std_rx_word_aligner_pattern_len} 20
|
||||
set_instance_parameter_value native_phy {std_rx_word_aligner_pattern} 0xA0D7C
|
||||
set_instance_parameter_value native_phy {enable_port_rx_std_wa_patternalign} 1
|
||||
set_instance_parameter_value native_phy {std_rx_polinv_enable} 1
|
||||
set_instance_parameter_value native_phy {enable_port_rx_polinv} 1
|
||||
}
|
||||
}
|
||||
|
||||
if {$tx} {
|
||||
set_instance_parameter_value native_phy {duplex_mode} "tx"
|
||||
if {$bonding_clocks_en && $num_of_lanes > 6} {
|
||||
set_instance_parameter_value native_phy {bonded_mode} "pma_only"
|
||||
} else {
|
||||
set_instance_parameter_value native_phy {bonded_mode} "not_bonded"
|
||||
}
|
||||
set_instance_parameter_value native_phy {enable_port_tx_pma_elecidle} 0
|
||||
} else {
|
||||
set_instance_parameter_value native_phy {duplex_mode} "rx"
|
||||
set_instance_parameter_value native_phy {set_cdr_refclk_freq} $refclk_frequency
|
||||
set_instance_parameter_value native_phy {enable_port_rx_is_lockedtodata} 1
|
||||
set_instance_parameter_value native_phy {enable_port_rx_is_lockedtoref} 0
|
||||
set_instance_parameter_value native_phy {enable_ports_rx_manual_cdr_mode} 0
|
||||
}
|
||||
|
||||
set_instance_parameter_value native_phy {channels} $num_of_lanes
|
||||
set_instance_parameter_value native_phy {set_data_rate} $lane_rate
|
||||
set_instance_parameter_value native_phy {enable_simple_interface} 1
|
||||
set_instance_parameter_value native_phy {enh_pcs_pma_width} 40
|
||||
set_instance_parameter_value native_phy {enh_pld_pcs_width} 40
|
||||
set_instance_parameter_value native_phy {rcfg_enable} 1
|
||||
set_instance_parameter_value native_phy {rcfg_shared} 0
|
||||
set_instance_parameter_value native_phy {rcfg_jtag_enable} 0
|
||||
set_instance_parameter_value native_phy {rcfg_sv_file_enable} 0
|
||||
set_instance_parameter_value native_phy {rcfg_h_file_enable} 0
|
||||
set_instance_parameter_value native_phy {rcfg_mif_file_enable} 0
|
||||
set_instance_parameter_value native_phy {set_user_identifier} $id
|
||||
set_instance_parameter_value native_phy {set_capability_reg_enable} 1
|
||||
set_instance_parameter_value native_phy {set_csr_soft_logic_enable} 1
|
||||
set_instance_parameter_value native_phy {set_prbs_soft_logic_enable} 0
|
||||
|
||||
add_instance phy_glue jesd204_phy_glue 1.0
|
||||
set_instance_parameter_value phy_glue DEVICE $device
|
||||
set_instance_parameter_value phy_glue TX_OR_RX_N $tx
|
||||
set_instance_parameter_value phy_glue SOFT_PCS $soft_pcs
|
||||
set_instance_parameter_value phy_glue NUM_OF_LANES $num_of_lanes
|
||||
set_instance_parameter_value phy_glue LANE_INVERT $lane_invert
|
||||
set_instance_parameter_value phy_glue BONDING_CLOCKS_EN $bonding_clocks_en
|
||||
|
||||
add_interface reconfig_clk clock sink
|
||||
set_interface_property reconfig_clk EXPORT_OF phy_glue.reconfig_clk
|
||||
|
||||
add_interface reconfig_reset reset sink
|
||||
set_interface_property reconfig_reset EXPORT_OF phy_glue.reconfig_reset
|
||||
|
||||
if {$ext_device_clk_en} {
|
||||
add_instance ext_device_clock altera_clock_bridge 19.1
|
||||
set_instance_parameter_value ext_device_clock {EXPLICIT_CLOCK_RATE} [expr $link_clk_frequency*1000000]
|
||||
set_instance_parameter_value ext_device_clock {NUM_CLOCK_OUTPUTS} 1
|
||||
add_interface device_clk clock sink
|
||||
set_interface_property device_clk EXPORT_OF ext_device_clock.in_clk
|
||||
}
|
||||
|
||||
if {$tx} {
|
||||
if {$bonding_clocks_en && $num_of_lanes > 6} {
|
||||
add_interface bonding_clocks hssi_bonded_clock end
|
||||
set_interface_property bonding_clocks EXPORT_OF phy_glue.tx_bonding_clocks
|
||||
add_connection phy_glue.phy_tx_bonding_clocks native_phy.tx_bonding_clocks
|
||||
} else {
|
||||
add_interface serial_clk_x1 hssi_serial_clock end
|
||||
set_interface_property serial_clk_x1 EXPORT_OF phy_glue.tx_serial_clk_x1
|
||||
if {$num_of_lanes > 6} {
|
||||
add_interface serial_clk_xN hssi_serial_clock end
|
||||
set_interface_property serial_clk_xN EXPORT_OF phy_glue.tx_serial_clk_xN
|
||||
}
|
||||
add_connection phy_glue.phy_tx_serial_clk0 native_phy.tx_serial_clk0
|
||||
}
|
||||
|
||||
if {$ext_device_clk_en} {
|
||||
add_connection ext_device_clock.out_clk phy_glue.tx_coreclkin
|
||||
} else {
|
||||
add_connection link_clock.clk phy_glue.tx_coreclkin
|
||||
}
|
||||
|
||||
if { $soft_pcs == true && $device_type == 1 } {
|
||||
add_connection phy_glue.phy_tx_enh_data_valid native_phy.tx_enh_data_valid
|
||||
}
|
||||
|
||||
foreach x {reconfig_clk reconfig_reset reconfig_avmm tx_coreclkin \
|
||||
tx_clkout tx_parallel_data unused_tx_parallel_data} {
|
||||
add_connection phy_glue.phy_${x} native_phy.${x}
|
||||
}
|
||||
|
||||
foreach x {serial_data analogreset digitalreset cal_busy} {
|
||||
add_interface ${x} conduit end
|
||||
set_interface_property ${x} EXPORT_OF native_phy.tx_${x}
|
||||
}
|
||||
|
||||
if {$soft_pcs == false} {
|
||||
add_connection phy_glue.phy_tx_datak native_phy.tx_datak
|
||||
add_connection phy_glue.phy_tx_polinv native_phy.tx_polinv
|
||||
}
|
||||
|
||||
## Startix 10
|
||||
if {$device_type == 2} {
|
||||
foreach x {analogreset_stat digitalreset_stat} {
|
||||
add_interface ${x} conduit end
|
||||
set_interface_property ${x} EXPORT_OF native_phy.tx_${x}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
add_interface ref_clk clock sink
|
||||
set_interface_property ref_clk EXPORT_OF phy_glue.rx_cdr_refclk0
|
||||
|
||||
if {$ext_device_clk_en} {
|
||||
add_connection ext_device_clock.out_clk phy_glue.rx_coreclkin
|
||||
} else {
|
||||
add_connection link_clock.clk phy_glue.rx_coreclkin
|
||||
}
|
||||
|
||||
foreach x {serial_data analogreset digitalreset cal_busy is_lockedtodata} {
|
||||
add_interface ${x} conduit end
|
||||
set_interface_property ${x} EXPORT_OF native_phy.rx_${x}
|
||||
}
|
||||
|
||||
foreach x {reconfig_clk reconfig_reset reconfig_avmm rx_coreclkin \
|
||||
rx_clkout rx_parallel_data rx_cdr_refclk0} {
|
||||
add_connection phy_glue.phy_${x} native_phy.${x}
|
||||
}
|
||||
|
||||
if {$soft_pcs == false} {
|
||||
foreach x {rx_datak rx_disperr rx_errdetect rx_std_wa_patternalign} {
|
||||
add_connection phy_glue.phy_${x} native_phy.${x}
|
||||
}
|
||||
add_connection phy_glue.phy_rx_polinv native_phy.rx_polinv
|
||||
}
|
||||
|
||||
## Startix 10
|
||||
if {$device_type == 2} {
|
||||
foreach x {analogreset_stat digitalreset_stat} {
|
||||
add_interface ${x} conduit end
|
||||
set_interface_property ${x} EXPORT_OF native_phy.rx_${x}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for {set i 0} {$i < $num_of_lanes} {incr i} {
|
||||
add_interface reconfig_avmm_${i} avalon slave
|
||||
set_interface_property reconfig_avmm_${i} EXPORT_OF phy_glue.reconfig_avmm_${i}
|
||||
|
||||
add_interface phy_${i} conduit start
|
||||
|
||||
if {$tx} {
|
||||
if {$soft_pcs} {
|
||||
add_instance soft_pcs_${i} jesd204_soft_pcs_tx 1.0
|
||||
set_instance_parameter_value soft_pcs_${i} INVERT_OUTPUTS \
|
||||
[expr ($lane_invert >> $i) & 1]
|
||||
if {$ext_device_clk_en} {
|
||||
add_connection ext_device_clock.out_clk soft_pcs_${i}.clock
|
||||
} else {
|
||||
add_connection link_clock.clk soft_pcs_${i}.clock
|
||||
}
|
||||
add_connection link_clock.clk_reset soft_pcs_${i}.reset
|
||||
add_connection soft_pcs_${i}.tx_raw_data phy_glue.tx_raw_data_${i}
|
||||
|
||||
set_interface_property phy_${i} EXPORT_OF soft_pcs_${i}.tx_phy
|
||||
} else {
|
||||
set_interface_property phy_${i} EXPORT_OF phy_glue.tx_phy_${i}
|
||||
}
|
||||
} else {
|
||||
if {$soft_pcs} {
|
||||
add_instance soft_pcs_${i} jesd204_soft_pcs_rx 1.0
|
||||
set_instance_parameter_value soft_pcs_${i} REGISTER_INPUTS $register_inputs
|
||||
set_instance_parameter_value soft_pcs_${i} INVERT_INPUTS \
|
||||
[expr ($lane_invert >> $i) & 1]
|
||||
if {$ext_device_clk_en} {
|
||||
add_connection ext_device_clock.out_clk soft_pcs_${i}.clock
|
||||
} else {
|
||||
add_connection link_clock.clk soft_pcs_${i}.clock
|
||||
}
|
||||
add_connection link_clock.clk_reset soft_pcs_${i}.reset
|
||||
add_connection phy_glue.rx_raw_data_${i} soft_pcs_${i}.rx_raw_data
|
||||
|
||||
set_interface_property phy_${i} EXPORT_OF soft_pcs_${i}.rx_phy
|
||||
} else {
|
||||
set_interface_property phy_${i} EXPORT_OF phy_glue.rx_phy_${i}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
## Auto-generated, do not modify!
|
||||
####################################################################################
|
||||
|
||||
LIBRARY_NAME := util_clkdiv
|
||||
|
||||
INTEL_DEPS += util_clkdiv.v
|
||||
INTEL_DEPS += util_clkdiv_hw.tcl
|
||||
|
||||
include ../../scripts/library.mk
|
||||
@@ -0,0 +1,79 @@
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved.
|
||||
//
|
||||
// In this HDL repository, there are many different and unique modules, consisting
|
||||
// of various HDL (Verilog or VHDL) components. The individual modules are
|
||||
// developed independently, and may be accompanied by separate and unique license
|
||||
// terms.
|
||||
//
|
||||
// The user should read each of these license terms, and understand the
|
||||
// freedoms and responsibilities that he or she has by using this source/core.
|
||||
//
|
||||
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
// A PARTICULAR PURPOSE.
|
||||
//
|
||||
// Redistribution and use of source or resulting binaries, with or without modification
|
||||
// of this file, are permitted under one of the following two license terms:
|
||||
//
|
||||
// 1. The GNU General Public License version 2 as published by the
|
||||
// Free Software Foundation, which can be found in the top level directory
|
||||
// of this repository (LICENSE_GPL2), and also online at:
|
||||
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
||||
//
|
||||
// OR
|
||||
//
|
||||
// 2. An ADI specific BSD license, which can be found in the top level directory
|
||||
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
||||
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
||||
// This will allow to generate bit files and not release the source code,
|
||||
// as long as it attaches to an ADI device.
|
||||
//
|
||||
// ***************************************************************************
|
||||
// ***************************************************************************
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
// Divides the input clock to SEL_0_DIV if clk_sel is 0 or SEL_1_DIV if
|
||||
// clk_sel is 1. Provides a glitch free output clock
|
||||
// IP uses BUFR/BUFGCE_DIV and BUFGMUX_CTRL primitives
|
||||
|
||||
module util_clkdiv #(
|
||||
parameter SIM_DEVICE = "CYCLONE5",
|
||||
parameter CLOCK_TYPE = "Global Clock") (
|
||||
|
||||
input clk,
|
||||
input reset,
|
||||
output clk_out,
|
||||
output reset_out
|
||||
);
|
||||
|
||||
reg enable;
|
||||
reg reset_d1;
|
||||
|
||||
assign reset_out = reset | reset_d1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reset_d1 <= reset;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
enable <= ~enable;
|
||||
end
|
||||
|
||||
generate if (SIM_DEVICE == "CYCLONE5") begin
|
||||
cyclonev_clkena #(
|
||||
.clock_type ("Global Clock"),
|
||||
.ena_register_mode ("falling edge"),
|
||||
.lpm_type ("cyclonev_clkena")
|
||||
) clock_divider_by_2 (
|
||||
.ena(enable),
|
||||
.enaout(),
|
||||
.inclk(clk),
|
||||
// .clkselect (2'b0),
|
||||
.outclk(clk_out));
|
||||
|
||||
end endgenerate
|
||||
|
||||
endmodule // util_clkdiv
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
package require -exact qsys 13.0
|
||||
source ../../scripts/adi_env.tcl
|
||||
source ../../scripts/adi_ip_intel.tcl
|
||||
|
||||
|
||||
set_module_property NAME util_clkdiv
|
||||
set_module_property DESCRIPTION "Clock Division Utility"
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
set_module_property DISPLAY_NAME util_clkdiv
|
||||
|
||||
# files
|
||||
|
||||
add_fileset quartus_synth QUARTUS_SYNTH "" "Quartus Synthesis"
|
||||
set_fileset_property quartus_synth TOP_LEVEL util_clkdiv
|
||||
add_fileset_file util_clkdiv.v VERILOG PATH util_clkdiv.v TOP_LEVEL_FILE
|
||||
|
||||
# defaults
|
||||
|
||||
ad_interface clock clk input 1
|
||||
ad_interface reset reset input 1 if_clk
|
||||
ad_interface clock clk_out output 1
|
||||
ad_interface reset reset_out output 1 if_clk_out
|
||||
|
||||
Reference in New Issue
Block a user