initial commit

This commit is contained in:
2023-03-18 15:35:53 +08:00
commit 5965eba577
3222 changed files with 4025781 additions and 0 deletions
+17
View File
@@ -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
}
+11
View File
@@ -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
+166
View File
@@ -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
}
}
+13
View File
@@ -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
}
}
+11
View File
@@ -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
+925
View File
@@ -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
}
}
}
+19
View File
@@ -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
+261
View File
@@ -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
+13
View File
@@ -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
+160
View File
@@ -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
// ***************************************************************************
// ***************************************************************************
+85
View File
@@ -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
// ***************************************************************************
// ***************************************************************************
+90
View File
@@ -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*]
+15
View File
@@ -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}
}
}
}
}
+11
View File
@@ -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