Archived
first commit after restructuring
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
|
||||
# environment related stuff
|
||||
|
||||
set ad_hdl_dir [file normalize [file join [file dirname [info script]] "../.."]]
|
||||
|
||||
# assuming that ghdl is cloned next to hdl repository
|
||||
set ad_ghdl_dir [file normalize [file join [file dirname [info script]] "../../../ghdl"]]
|
||||
|
||||
|
||||
if [info exists ::env(ADI_HDL_DIR)] {
|
||||
set ad_hdl_dir [file normalize $::env(ADI_HDL_DIR)]
|
||||
}
|
||||
|
||||
if [info exists ::env(ADI_GHDL_DIR)] {
|
||||
set ad_ghdl_dir [file normalize $::env(ADI_GHDL_DIR)]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
## Copyright 2014 - 2018 (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.
|
||||
##
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
|
||||
# adi_intel_device_info_enc.tcl
|
||||
|
||||
# The main rule when adding a new parameter is to have the same names for the parameter
|
||||
# and it's list (valid range type or supported entity and its encoded value type)
|
||||
|
||||
variable auto_set_param_list
|
||||
variable fpga_technology_list
|
||||
variable fpga_technology
|
||||
variable fpga_family_list
|
||||
variable fpga_family
|
||||
variable speed_grade_list
|
||||
variable speed_grade
|
||||
variable dev_package_list
|
||||
variable dev_package
|
||||
variable xcvr_type_list
|
||||
variable xcvr_type
|
||||
variable fpga_voltage_list
|
||||
variable fpga_voltage
|
||||
|
||||
# Parameter list for automatic assignament(generation)
|
||||
set auto_gen_param_list { \
|
||||
FPGA_TECHNOLOGY \
|
||||
FPGA_FAMILY \
|
||||
SPEED_GRADE \
|
||||
DEV_PACKAGE}
|
||||
|
||||
set auto_set_param_list { \
|
||||
FPGA_VOLTAGE \
|
||||
XCVR_TYPE}
|
||||
|
||||
|
||||
# List for automatically assigned parameter values and encoded values
|
||||
# The list name must be the parameter name (lowercase), appending "_list" to it
|
||||
set fpga_technology_list { \
|
||||
{ Unknown 100 } \
|
||||
{ "Cyclone V" 101 } \
|
||||
{ "Cyclone 10" 102 } \
|
||||
{ "Arria 10" 103 } \
|
||||
{ "Stratix 10" 104 }}
|
||||
|
||||
set fpga_family_list { \
|
||||
{ Unknown 0 } \
|
||||
{ SX 1 } \
|
||||
{ GX 2 } \
|
||||
{ GT 3 } \
|
||||
{ GZ 4 } \
|
||||
{ "SE Base" 5 }}
|
||||
|
||||
#technology 5 generation
|
||||
# family Arria SX
|
||||
|
||||
set speed_grade_list { \
|
||||
{ Unknown 0 } \
|
||||
{ 1 1 } \
|
||||
{ 2 2 } \
|
||||
{ 3 3 } \
|
||||
{ 4 4 } \
|
||||
{ 5 5 } \
|
||||
{ 6 6 } \
|
||||
{ 7 7 } \
|
||||
{ 8 8 }}
|
||||
|
||||
set dev_package_list { \
|
||||
{ Unknown 0 } \
|
||||
{ BGA 1 } \
|
||||
{ PGA 2 } \
|
||||
{ FBGA 3 } \
|
||||
{ HBGA 4 } \
|
||||
{ PDIP 5 } \
|
||||
{ EQFP 6 } \
|
||||
{ PLCC 7 } \
|
||||
{ PQFP 8 } \
|
||||
{ RQFP 9 } \
|
||||
{ TQFP 10 } \
|
||||
{ UBGA 11 } \
|
||||
{ UFBGA 12 } \
|
||||
{ MBGA 13 }}
|
||||
|
||||
# Ball-Grid Array (BGA)
|
||||
# Ceramic Pin-Grid Array (PGA)
|
||||
# FineLine BGA (FBGA)
|
||||
# Hybrid FineLine BGA (HBGA)
|
||||
# Plastic Dual In-Line Package (PDIP)
|
||||
# Plastic Enhanced Quad Flat Pack (EQFP)
|
||||
# Plastic J-Lead Chip Carrier (PLCC)
|
||||
# Plastic Quad Flat Pack (PQFP)
|
||||
# Power Quad Flat Pack (RQFP)
|
||||
# Thin Quad Flat Pack (TQFP)
|
||||
# Ultra FineLine BGA (UBGA-UFBGA)
|
||||
|
||||
# transceiver speedgrade
|
||||
set xcvr_type_list { 0 9 }
|
||||
|
||||
set fpga_voltage_list { 0 5000 } ;# min 0mV max 5V
|
||||
|
||||
################################################################################
|
||||
|
||||
proc get_part_param {} {
|
||||
|
||||
global fpga_technology
|
||||
global fpga_family
|
||||
global speed_grade
|
||||
global dev_package
|
||||
global xcvr_type
|
||||
global fpga_voltage
|
||||
|
||||
set device [get_parameter_value DEVICE]
|
||||
|
||||
# user and system values (sys_val)
|
||||
if {[catch {set fpga_technology [quartus::device::get_part_info -family $device]} fid]} {
|
||||
set fpga_technology "Unknown"
|
||||
}
|
||||
if {[catch {set fpga_family [quartus::device::get_part_info -family_variant $device]} fid]} {
|
||||
set fpga_family "Unknown"
|
||||
}
|
||||
if {[catch {set speed_grade [quartus::device::get_part_info -speed_grade $device]} fid]} {
|
||||
set speed_grade "Unknown"
|
||||
}
|
||||
if {[catch {set dev_package [quartus::device::get_part_info -package $device]} fid]} {
|
||||
set dev_package "Unknown"
|
||||
}
|
||||
if {[catch {set xcvr_type [quartus::device::get_part_info -hssi_speed_grade $device]} fid]} {
|
||||
set xcvr_type "Unknown"
|
||||
}
|
||||
if {[catch {set fpga_voltage [quartus::device::get_part_info -default_voltage $device]} fid]} {
|
||||
set fpga_voltage "0"
|
||||
}
|
||||
|
||||
# user and system values (sys_val)
|
||||
regsub {V} $fpga_voltage "" fpga_voltage
|
||||
set fpga_voltage [expr int([expr $fpga_voltage * 1000])] ;# // V to mV conversion(integer val)
|
||||
|
||||
}
|
||||
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
@@ -0,0 +1,436 @@
|
||||
|
||||
## Define an interface for Platform Designer.
|
||||
#
|
||||
# \param[type] - Type of the interface, valid values are : clock, reset, reset-n,
|
||||
# signal, intr
|
||||
# \param[name] - The name of the interface
|
||||
# \param[dir] - The direction of the interface
|
||||
# \param[width] - The width of the interface
|
||||
# \param[arg_1] - Optional argument to define the associated clock for a reset
|
||||
# interface
|
||||
# \param[arg_2] - Optional argument to define the associated reset sink for a
|
||||
# reset interface
|
||||
#
|
||||
proc ad_interface {type name dir width {arg_1 ""} {arg_2 ""}} {
|
||||
|
||||
if {([string equal -nocase ${type} "clock"]) && ([string equal -nocase ${dir} "input"])} {
|
||||
add_interface if_${name} clock sink
|
||||
add_interface_port if_${name} ${name} clk ${dir} ${width}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "clock"]) && ([string equal -nocase ${dir} "output"])} {
|
||||
add_interface if_${name} clock source
|
||||
add_interface_port if_${name} ${name} clk ${dir} ${width}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "reset"]) && ([string equal -nocase ${dir} "input"])} {
|
||||
add_interface if_${name} reset sink
|
||||
add_interface_port if_${name} ${name} reset ${dir} ${width}
|
||||
set_interface_property if_${name} associatedclock ${arg_1}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "reset"]) && ([string equal -nocase ${dir} "output"])} {
|
||||
add_interface if_${name} reset source
|
||||
add_interface_port if_${name} ${name} reset ${dir} ${width}
|
||||
set_interface_property if_${name} associatedclock ${arg_1}
|
||||
set_interface_property if_${name} associatedResetSinks ${arg_2}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "reset-n"]) && ([string equal -nocase ${dir} "input"])} {
|
||||
add_interface if_${name} reset sink
|
||||
add_interface_port if_${name} ${name} reset_n ${dir} ${width}
|
||||
set_interface_property if_${name} associatedclock ${arg_1}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "reset-n"]) && ([string equal -nocase ${dir} "output"])} {
|
||||
add_interface if_${name} reset source
|
||||
add_interface_port if_${name} ${name} reset_n ${dir} ${width}
|
||||
set_interface_property if_${name} associatedclock ${arg_1}
|
||||
set_interface_property if_${name} associatedResetSinks ${arg_2}
|
||||
return
|
||||
}
|
||||
|
||||
if {([string equal -nocase ${type} "intr"]) && ([string equal -nocase ${dir} "output"])} {
|
||||
add_interface if_${name} interrupt source
|
||||
add_interface_port if_${name} ${name} irq ${dir} ${width}
|
||||
set_interface_property if_${name} associatedclock ${arg_1}
|
||||
return
|
||||
}
|
||||
|
||||
set remap $arg_1
|
||||
if {$arg_1 eq ""} {
|
||||
set remap $name
|
||||
}
|
||||
|
||||
if {[string equal -nocase ${type} "signal"]} {
|
||||
add_interface if_${name} conduit end
|
||||
add_interface_port if_${name} ${name} ${remap} ${dir} ${width}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
## Create a point-to-point conduit interface.
|
||||
#
|
||||
# \param[if_name] - the name of the interface
|
||||
# \param[if_port] - the type of signal for this port, which must be unique
|
||||
# \param[port] - the name of the port, this name must match the signal name
|
||||
# in HDL
|
||||
# \param[dir] - the direction of the signal, expected values: input/output/bidir
|
||||
# \param[width] - the width of the port, in bits
|
||||
#
|
||||
proc ad_conduit {if_name if_port port dir width} {
|
||||
|
||||
add_interface $if_name conduit end
|
||||
add_interface_port $if_name $port $if_port $dir $width
|
||||
}
|
||||
|
||||
## Create an IP.
|
||||
#
|
||||
# \param[pname] - name of the IP, general equivalent to the top HDL module name
|
||||
# \param[pdisplay_name] - displayed name
|
||||
# \param[pelabfunction] - name of the elaboration callback function
|
||||
# \param[pcomposefunction] - name of the composition callback function
|
||||
#
|
||||
proc ad_ip_create {pname pdisplay_name {pelabfunction ""} {pcomposefunction ""}} {
|
||||
|
||||
set_module_property NAME $pname
|
||||
set_module_property DISPLAY_NAME $pdisplay_name
|
||||
set_module_property DESCRIPTION $pdisplay_name
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Analog Devices"
|
||||
|
||||
if {$pelabfunction ne ""} {
|
||||
set_module_property ELABORATION_CALLBACK $pelabfunction
|
||||
}
|
||||
|
||||
if {$pcomposefunction ne ""} {
|
||||
set_module_property COMPOSITION_CALLBACK $pcomposefunction
|
||||
}
|
||||
}
|
||||
|
||||
## Create an IP parameter.
|
||||
#
|
||||
# \param[pname] - name of the IP, general equivalent to the top HDL module name
|
||||
# \param[ptype] - the data type of the parameter
|
||||
# \param[pdefault] - the initial value of the parameter
|
||||
# \param[phdl] - define if the parameter is an HDL parameter or not
|
||||
# \param[properties] - can define different properties for the parameter, must be
|
||||
# a list of {key, value} pairs
|
||||
#
|
||||
proc ad_ip_parameter {pname ptype pdefault {phdl true} {properties {}}} {
|
||||
|
||||
if {$pname eq "DEVICE_FAMILY"} {
|
||||
add_parameter DEVICE_FAMILY STRING
|
||||
set_parameter_property DEVICE_FAMILY SYSTEM_INFO {DEVICE_FAMILY}
|
||||
set_parameter_property DEVICE_FAMILY AFFECTS_GENERATION true
|
||||
set_parameter_property DEVICE_FAMILY HDL_PARAMETER false
|
||||
set_parameter_property DEVICE_FAMILY ENABLED true
|
||||
} else {
|
||||
add_parameter $pname $ptype $pdefault
|
||||
set_parameter_property $pname HDL_PARAMETER $phdl
|
||||
set_parameter_property $pname ENABLED true
|
||||
}
|
||||
|
||||
foreach {key value} $properties {
|
||||
set_parameter_property $pname $key $value
|
||||
}
|
||||
}
|
||||
|
||||
## Adds the generic ADI spec parameters to the current IP, with the help of
|
||||
# adi_add_device_spec_param. The spec parameter list is auto_gen_param_list,
|
||||
# from library/scripts/adi_intel_device_info_enc.tcl.
|
||||
#
|
||||
proc adi_add_auto_fpga_spec_params {} {
|
||||
|
||||
global ad_hdl_dir
|
||||
source $ad_hdl_dir/library/scripts/adi_intel_device_info_enc.tcl
|
||||
|
||||
ad_ip_parameter DEVICE STRING "" false {
|
||||
SYSTEM_INFO DEVICE
|
||||
VISIBLE false
|
||||
}
|
||||
|
||||
foreach p $auto_gen_param_list {
|
||||
adi_add_device_spec_param $p
|
||||
}
|
||||
}
|
||||
|
||||
## Generate validation properties for a parameter, using predefined ranges or
|
||||
# set of values (the definition of the ranges can be found in
|
||||
# library/scripts/adi_intel_device_info_enc.tcl).
|
||||
#
|
||||
# In Intel callback flow, one cannot directly change a parameter value, the value
|
||||
# can only be calculated/deduced from the environment.
|
||||
# Adding a second parameter with the same name followed by "_MANUAL", will add
|
||||
# in the environment the desired value that is still constrained to a predefined
|
||||
# set. Having the second parameter is not enough, to activate the manual
|
||||
# overwriting of a parameter one must call the adi_add_indep_spec_params_overwrite
|
||||
# process.
|
||||
#
|
||||
# \param[param] - Name of the HDL parameter. The list of accepted values for
|
||||
# the parameter are defined with the same name as the parameter's one(lower case),
|
||||
# followed by "_list"
|
||||
#
|
||||
proc adi_add_device_spec_param {param} {
|
||||
|
||||
global auto_gen_param_list
|
||||
global auto_set_param_list
|
||||
global fpga_technology_list
|
||||
global fpga_family_list
|
||||
global speed_grade_list
|
||||
global dev_package_list
|
||||
global xcvr_type_list
|
||||
global fpga_voltage_list
|
||||
|
||||
set group "FPGA info"
|
||||
|
||||
set list_pointer [string tolower $param]
|
||||
set list_pointer [append list_pointer "_list"]
|
||||
|
||||
set enc_list [subst $$list_pointer]
|
||||
|
||||
set ranges ""
|
||||
|
||||
add_parameter $param INTEGER
|
||||
set_parameter_property $param DISPLAY_NAME $param
|
||||
set_parameter_property $param GROUP $group
|
||||
set_parameter_property $param UNITS None
|
||||
set_parameter_property $param HDL_PARAMETER true
|
||||
set_parameter_property $param VISIBLE true
|
||||
set_parameter_property $param DERIVED true
|
||||
|
||||
add_parameter ${param}_MANUAL INTEGER
|
||||
set_parameter_property ${param}_MANUAL DISPLAY_NAME $param
|
||||
set_parameter_property ${param}_MANUAL GROUP $group
|
||||
set_parameter_property ${param}_MANUAL UNITS None
|
||||
set_parameter_property ${param}_MANUAL HDL_PARAMETER false
|
||||
set_parameter_property ${param}_MANUAL VISIBLE false
|
||||
set_parameter_property ${param}_MANUAL DEFAULT_VALUE [lindex $enc_list 0 1]
|
||||
|
||||
foreach i $enc_list {
|
||||
set value [lindex $i 0]
|
||||
set encode [lindex $i 1]
|
||||
append ranges "\"$encode\:$value\" "
|
||||
}
|
||||
set_parameter_property $param ALLOWED_RANGES $ranges
|
||||
set_parameter_property ${param}_MANUAL ALLOWED_RANGES $ranges
|
||||
}
|
||||
|
||||
## Creates a boolean type parameter that allows this user to manually overwrite
|
||||
# parameter values.
|
||||
#
|
||||
# \param[param] - Name of the HDL parameter.
|
||||
#
|
||||
proc adi_add_indep_spec_params_overwrite {param} {
|
||||
add_parameter ${param}_USER_OVERWRITE BOOLEAN 0
|
||||
set_parameter_property ${param}_USER_OVERWRITE DISPLAY_NAME "Manually overwrite $param parameter"
|
||||
set_parameter_property ${param}_USER_OVERWRITE HDL_PARAMETER false
|
||||
set_parameter_property ${param}_USER_OVERWRITE GROUP {FPGA info}
|
||||
}
|
||||
|
||||
## In this process the IP parameters are compared against predefined parameter lists
|
||||
# in library/scripts/adi_intel_device_info_enc.tcl. For the matching parameters,
|
||||
# a search is started after a pair *_USER_OVERWRITE(boolean) parameter. If the pair
|
||||
# *_USER_OVERWRITE parameter is found, and its value is true, the target parameter
|
||||
# will take the value of the *_MANUAL parameter. The GUI parameter is set as
|
||||
# writable in the qsys GUI (${parameter_name} is replaced by ${parameter_name}_MANUAL).
|
||||
#
|
||||
proc info_param_validate {} {
|
||||
global ad_hdl_dir
|
||||
global fpga_technology
|
||||
global fpga_family
|
||||
global speed_grade
|
||||
global dev_package
|
||||
global xcvr_type
|
||||
global fpga_voltage
|
||||
|
||||
source $ad_hdl_dir/library/scripts/adi_intel_device_info_enc.tcl
|
||||
|
||||
set device [get_parameter_value DEVICE]
|
||||
set auto_populate true ;# for future code dev
|
||||
|
||||
set all_ip_param_list [get_parameters]
|
||||
set validate_list ""
|
||||
set independent_overwrite_list ""
|
||||
foreach param $all_ip_param_list {
|
||||
foreach elem [concat $auto_gen_param_list $auto_set_param_list] {
|
||||
if { "$elem" == "$param" } {
|
||||
append validate_list "$param "
|
||||
}
|
||||
if { [regexp ${elem}_USER_OVERWRITE $param] } {
|
||||
append independent_overwrite_list "$elem "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set indep_overwrite [expr {[llength $independent_overwrite_list] != 0} ? 1 : 0]
|
||||
|
||||
if { $auto_populate == true } {
|
||||
|
||||
get_part_param ;# in adi_intel_device_info_enc.tcl
|
||||
|
||||
# point parameters and assign
|
||||
foreach param $validate_list {
|
||||
set ls_param [string tolower $param]
|
||||
set list_pointer $ls_param
|
||||
append list_pointer "_list"
|
||||
set pointer_to_sys_val [subst $$ls_param] ;# e.g., $fpga_technology
|
||||
set enc_list_pointer [subst $$list_pointer] ;# e.g., $fpga_technology_list
|
||||
|
||||
# get_part_info returns '{'#value'}'
|
||||
regsub -all "{" $pointer_to_sys_val "" pointer_to_sys_val
|
||||
regsub -all "}" $pointer_to_sys_val "" pointer_to_sys_val
|
||||
|
||||
# the list defines a range or pairs of values
|
||||
set get_list_correspondence 1
|
||||
if { [llength $enc_list_pointer] != 0 } {
|
||||
if { [llength $enc_list_pointer] == 2 } {
|
||||
if { [llength [lindex $enc_list_pointer 0]] == 1 } {
|
||||
set get_list_correspondence 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
send_message ERROR "No list $list_pointer defined in adi_intel_device_info_enc.tcl for parameter $param"
|
||||
}
|
||||
|
||||
# auto assign parameter value
|
||||
if { $get_list_correspondence } {
|
||||
set matched ""
|
||||
foreach i $enc_list_pointer {
|
||||
if { [regexp ^[lindex $i 0] $pointer_to_sys_val] } {
|
||||
set matched [lindex $i 1]
|
||||
}
|
||||
}
|
||||
if { $matched == "" } {
|
||||
send_message ERROR "Unknown or undefined(adi_intel_device_info_enc.tcl) $param \"$pointer_to_sys_val\" form \"$device\" device"
|
||||
} else {
|
||||
set_parameter_value $param $matched
|
||||
}
|
||||
} else {
|
||||
set_parameter_value $param $pointer_to_sys_val
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach p $validate_list {
|
||||
set_parameter_value $p [get_parameter_value ${p}_MANUAL]
|
||||
}
|
||||
}
|
||||
|
||||
# display manual(writable) or auto(non-writable) parameters
|
||||
foreach p $validate_list {
|
||||
set_parameter_property ${p}_MANUAL VISIBLE [expr $auto_populate ? false : true]
|
||||
set_parameter_property $p VISIBLE $auto_populate
|
||||
if { $indep_overwrite == 1 } {
|
||||
foreach p_overwrite $independent_overwrite_list {
|
||||
if { $p == $p_overwrite } {
|
||||
set p_over_val [get_parameter_value ${p}_USER_OVERWRITE]
|
||||
# set the hdl parameter with the independent manual overwritten value
|
||||
if { $p_over_val } {
|
||||
set_parameter_value $p [get_parameter_value ${p}_MANUAL]
|
||||
set_parameter_property ${p}_MANUAL VISIBLE $p_over_val
|
||||
set_parameter_property $p VISIBLE [expr $p_over_val ? false : true]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Add source files to an IP, automatically find the file type using its extension.
|
||||
#
|
||||
# \param[pname] - name of the IP, general equivalent to the top HDL module name
|
||||
# \param[pfile] - name of the file
|
||||
#
|
||||
proc ad_ip_addfile {pname pfile} {
|
||||
|
||||
set pmodule [file tail $pfile]
|
||||
|
||||
regsub {\..$} $pmodule {} mname
|
||||
if {$pname eq $mname} {
|
||||
add_fileset_file $pmodule VERILOG PATH $pfile TOP_LEVEL_FILE
|
||||
return
|
||||
}
|
||||
|
||||
set ptype [file extension $pfile]
|
||||
if {$ptype eq ".v"} {
|
||||
add_fileset_file $pmodule VERILOG PATH $pfile
|
||||
return
|
||||
}
|
||||
if {$ptype eq ".vh"} {
|
||||
add_fileset_file $pmodule VERILOG_INCLUDE PATH $pfile
|
||||
return
|
||||
}
|
||||
if {$ptype eq ".sdc"} {
|
||||
add_fileset_file $pmodule SDC PATH $pfile
|
||||
return
|
||||
}
|
||||
if {$ptype eq ".tcl"} {
|
||||
add_fileset_file $pmodule OTHER PATH $pfile
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
## Add source files to an IP, automatically find the file type using its extension.
|
||||
#
|
||||
# \param[pname] - name of the IP, general equivalent to the top HDL module name
|
||||
# \param[pfile] - name of the file
|
||||
#
|
||||
proc ad_ip_files {pname pfiles {pfunction ""}} {
|
||||
|
||||
add_fileset quartus_synth QUARTUS_SYNTH $pfunction ""
|
||||
set_fileset_property quartus_synth TOP_LEVEL $pname
|
||||
foreach pfile $pfiles {
|
||||
ad_ip_addfile $pname $pfile
|
||||
}
|
||||
|
||||
add_fileset quartus_sim SIM_VERILOG $pfunction ""
|
||||
set_fileset_property quartus_sim TOP_LEVEL $pname
|
||||
foreach pfile $pfiles {
|
||||
ad_ip_addfile $pname $pfile
|
||||
}
|
||||
}
|
||||
|
||||
## Infer an AXI4 Lite memory mapped interface.
|
||||
#
|
||||
# \param[aclk] - name of the interface clock
|
||||
# \param[arstn] - name fo the interface reset
|
||||
# \param[addr_width] - address width of the read and write channels
|
||||
#
|
||||
proc ad_ip_intf_s_axi {aclk arstn {addr_width 16}} {
|
||||
|
||||
add_interface s_axi_clock clock end
|
||||
add_interface_port s_axi_clock ${aclk} clk Input 1
|
||||
|
||||
add_interface s_axi_reset reset end
|
||||
set_interface_property s_axi_reset associatedClock s_axi_clock
|
||||
add_interface_port s_axi_reset ${arstn} reset_n Input 1
|
||||
|
||||
add_interface s_axi axi4lite end
|
||||
set_interface_property s_axi associatedClock s_axi_clock
|
||||
set_interface_property s_axi associatedReset s_axi_reset
|
||||
add_interface_port s_axi s_axi_awvalid awvalid Input 1
|
||||
add_interface_port s_axi s_axi_awaddr awaddr Input $addr_width
|
||||
add_interface_port s_axi s_axi_awprot awprot Input 3
|
||||
add_interface_port s_axi s_axi_awready awready Output 1
|
||||
add_interface_port s_axi s_axi_wvalid wvalid Input 1
|
||||
add_interface_port s_axi s_axi_wdata wdata Input 32
|
||||
add_interface_port s_axi s_axi_wstrb wstrb Input 4
|
||||
add_interface_port s_axi s_axi_wready wready Output 1
|
||||
add_interface_port s_axi s_axi_bvalid bvalid Output 1
|
||||
add_interface_port s_axi s_axi_bresp bresp Output 2
|
||||
add_interface_port s_axi s_axi_bready bready Input 1
|
||||
add_interface_port s_axi s_axi_arvalid arvalid Input 1
|
||||
add_interface_port s_axi s_axi_araddr araddr Input $addr_width
|
||||
add_interface_port s_axi s_axi_arprot arprot Input 3
|
||||
add_interface_port s_axi s_axi_arready arready Output 1
|
||||
add_interface_port s_axi s_axi_rvalid rvalid Output 1
|
||||
add_interface_port s_axi s_axi_rresp rresp Output 2
|
||||
add_interface_port s_axi s_axi_rdata rdata Output 32
|
||||
add_interface_port s_axi s_axi_rready rready Input 1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,644 @@
|
||||
|
||||
source $ad_hdl_dir/library/scripts/adi_xilinx_device_info_enc.tcl
|
||||
|
||||
# check tool version
|
||||
|
||||
if {![info exists REQUIRED_VIVADO_VERSION]} {
|
||||
set REQUIRED_VIVADO_VERSION "2019.1"
|
||||
}
|
||||
|
||||
if {[info exists ::env(ADI_IGNORE_VERSION_CHECK)]} {
|
||||
set IGNORE_VERSION_CHECK 1
|
||||
} elseif {![info exists IGNORE_VERSION_CHECK]} {
|
||||
set IGNORE_VERSION_CHECK 0
|
||||
}
|
||||
|
||||
## Add a ttcl file to the project. XDC does not support if statements
|
||||
# in constraint definitions, this file can be used to add parameter dependent
|
||||
# constraints to the IP.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
# \param[ip_constr_files] - .ttcl file name (full path)
|
||||
#
|
||||
proc adi_ip_ttcl {ip_name ip_constr_files} {
|
||||
|
||||
set proj_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *synthesis*}]
|
||||
set f [ipx::add_file $ip_constr_files $proj_filegroup]
|
||||
set_property -dict [list \
|
||||
type ttcl \
|
||||
] $f
|
||||
ipx::reorder_files -front $ip_constr_files $proj_filegroup
|
||||
}
|
||||
|
||||
## Add ttcl file to generate simulation files for System Verilog environments.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
# \param[ip_constr_files] - .ttcl file name (full path)
|
||||
#
|
||||
proc adi_ip_sim_ttcl {ip_name ip_files} {
|
||||
|
||||
set proj_filegroup [ipx::get_file_groups -of_objects [ipx::current_core] -filter {NAME =~ *simulation*}]
|
||||
set f [ipx::add_file $ip_files $proj_filegroup]
|
||||
set_property -dict [list \
|
||||
type ttcl \
|
||||
] $f
|
||||
ipx::reorder_files -front $ip_files $proj_filegroup
|
||||
}
|
||||
|
||||
## Add a block design, defined by a tcl source, to the IP.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
# \param[ip_bd_files] - Tcl source file
|
||||
#
|
||||
proc adi_ip_bd {ip_name ip_bd_files} {
|
||||
set proj_filegroup [ipx::get_file_groups xilinx_blockdiagram -of_objects [ipx::current_core]]
|
||||
if {$proj_filegroup == {}} {
|
||||
set proj_filegroup [ipx::add_file_group -type xilinx_blockdiagram "" [ipx::current_core]]
|
||||
}
|
||||
|
||||
foreach file $ip_bd_files {
|
||||
set f [ipx::add_file $file $proj_filegroup]
|
||||
set_property -dict [list \
|
||||
type tclSource \
|
||||
] $f
|
||||
}
|
||||
}
|
||||
|
||||
## Infers an AXI Streaming interface. Note that the interface has to exist.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
#
|
||||
proc adi_ip_infer_streaming_interfaces {ip_name} {
|
||||
|
||||
ipx::infer_bus_interfaces xilinx.com:interface:axis_rtl:1.0 [ipx::current_core]
|
||||
|
||||
}
|
||||
|
||||
## Infers an AXI Memory Mapped interface. Note that the interface has to exist.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
#
|
||||
proc adi_ip_infer_mm_interfaces {ip_name} {
|
||||
|
||||
ipx::infer_bus_interfaces xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core]
|
||||
|
||||
}
|
||||
|
||||
## Defines a dependency for a port.
|
||||
#
|
||||
# \param[port_prefix] - Port prefix, which defines an interface. All ports of an
|
||||
# interface must have the same prefix. If it's a single port, the whole name
|
||||
# shall be defined.
|
||||
# \param[dependency] - Dependency (e.g "PARAMETER_NAME == 1") ??? {spirit:decode(id('MODELPARAM_VALUE.PARAM_NAME')) == CONST}
|
||||
# \param[driver_value] - Driver value is optional. It defines the default driver
|
||||
# value of the port.
|
||||
#
|
||||
proc adi_set_ports_dependency {port_prefix dependency {driver_value {}}} {
|
||||
foreach port [ipx::get_ports [format "%s%s" $port_prefix "*"]] {
|
||||
set_property ENABLEMENT_DEPENDENCY $dependency $port
|
||||
if {$driver_value != {}} {
|
||||
set_property DRIVER_VALUE $driver_value $port
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Defines a dependency for a bus.
|
||||
#
|
||||
# \param[bus] - Name of the bus
|
||||
# \param[prefix] - Port prefix, in general same as the name of the bus
|
||||
# \param[dependency] - Dependency (e.g "PARAMETER_NAME == 1") ??? {spirit:decode(id('MODELPARAM_VALUE.PARAM_NAME')) == CONST}
|
||||
#
|
||||
proc adi_set_bus_dependency {bus prefix dependency} {
|
||||
set_property ENABLEMENT_DEPENDENCY $dependency [ipx::get_bus_interfaces $bus -of_objects [ipx::current_core]]
|
||||
adi_set_ports_dependency $prefix $dependency 0
|
||||
}
|
||||
|
||||
## Add a new port map definition to a bus interface.
|
||||
#
|
||||
# \param[bus] - Name of the bus interface
|
||||
# \param[phys] - Physical name of the port
|
||||
# \param[logic] - Logic name of the port (defined by the interface)
|
||||
#
|
||||
proc adi_add_port_map {bus phys logic} {
|
||||
set map [ipx::add_port_map $phys $bus]
|
||||
set_property "PHYSICAL_NAME" $phys $map
|
||||
set_property "LOGICAL_NAME" $logic $map
|
||||
}
|
||||
|
||||
## Infers a new bus interface to an IP.
|
||||
#
|
||||
# \param[bus_name] - Bus name
|
||||
# \param[mode] - Interface mode (master/slave)
|
||||
# \param[abs_type] - Abstraction type, example: "xilinx.com:interface:axis_rtl:1.0"
|
||||
# \param[bus_type] - Bus type, example: "xilinx.com:interface:axis:1.0"
|
||||
# \param[port_maps] - Port map
|
||||
#
|
||||
# <b>Port map example:\n
|
||||
# [list \n
|
||||
# {"m_axis_ready" "TREADY"}\n
|
||||
# {"m_axis_valid" "TVALID"}\n
|
||||
# {"m_axis_data" "TDATA"} ]\n
|
||||
|
||||
proc adi_add_bus {bus_name mode abs_type bus_type port_maps} {
|
||||
set bus [ipx::add_bus_interface $bus_name [ipx::current_core]]
|
||||
|
||||
set_property "ABSTRACTION_TYPE_VLNV" $abs_type $bus
|
||||
set_property "BUS_TYPE_VLNV" $bus_type $bus
|
||||
set_property "INTERFACE_MODE" $mode $bus
|
||||
|
||||
foreach port_map $port_maps {
|
||||
adi_add_port_map $bus {*}$port_map
|
||||
}
|
||||
}
|
||||
|
||||
## Add multiple bus interfaces of the same type to an IP.
|
||||
#
|
||||
# \param[num] - Number of interfaces
|
||||
# \param[bus_name_prefix] - Prefix of the name of the interface
|
||||
# \param[mode] - Interface mode (master/slave)
|
||||
# \param[abs_type] - Abstraction type, example: "xilinx.com:interface:axis_rtl:1.0"
|
||||
# \param[bus_type] - Bus type, example: "xilinx.com:interface:axis:1.0"
|
||||
# \param[port_maps] - Port map, example: [list \n
|
||||
# {"m_axis_ready" "TREADY"}\n
|
||||
# {"m_axis_valid" "TVALID"}\n:
|
||||
# {"m_axis_data" "TDATA"} ]\n
|
||||
# \param[dependency] - Dependency (e.g "PARAMETER_NAME == 1") ??? {spirit:decode(id('MODELPARAM_VALUE.PARAM_NAME')) == CONST}
|
||||
#
|
||||
proc adi_add_multi_bus {num bus_name_prefix mode abs_type bus_type port_maps dependency} {
|
||||
for {set i 0} {$i < $num} {incr i} {
|
||||
set bus_name [format "%s%d" $bus_name_prefix $i]
|
||||
set bus [ipx::add_bus_interface $bus_name [ipx::current_core]]
|
||||
|
||||
set_property "ABSTRACTION_TYPE_VLNV" $abs_type $bus
|
||||
set_property "BUS_TYPE_VLNV" $bus_type $bus
|
||||
set_property "INTERFACE_MODE" $mode $bus
|
||||
|
||||
if {$dependency ne ""} {
|
||||
set bus_dependency [string map [list "{i}" $i] $dependency]
|
||||
set_property ENABLEMENT_DEPENDENCY $bus_dependency $bus
|
||||
}
|
||||
|
||||
foreach port_map $port_maps {
|
||||
lassign $port_map phys logic width width_dep
|
||||
set map [ipx::add_port_map $phys $bus]
|
||||
set_property "PHYSICAL_NAME" $phys $map
|
||||
set_property "LOGICAL_NAME" $logic $map
|
||||
set_property "PHYSICAL_RIGHT" [expr $i*$width] $map
|
||||
set_property "PHYSICAL_LEFT" [expr ($i+1)*$width-1] $map
|
||||
if {$width_dep ne ""} {
|
||||
set_property "PHYSICAL_RIGHT_RESOLVE_TYPE" "dependent" $map
|
||||
set_property "PHYSICAL_LEFT_RESOLVE_TYPE" "dependent" $map
|
||||
set width_dep_r "(($width_dep) * $i)"
|
||||
set width_dep_l "(($width_dep) * ($i + 1)-1)"
|
||||
set_property "PHYSICAL_RIGHT_DEPENDENCY" $width_dep_r $map
|
||||
set_property "PHYSICAL_LEFT_DEPENDENCY" $width_dep_l $map
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Assign clock and reset to an interface bus.
|
||||
#
|
||||
# \param[clock_signal_name] - Clock name
|
||||
# \param[bus_inf_name] - Interface bus name. Note: If multiple interfaces uses
|
||||
# the same clock, all shall be defined here. (e.g. "s_axis:m_axis")
|
||||
# \param[reset_signal_name] - Reset signal name
|
||||
# \param[reset_signal_mode] - Reset mode (master/slave)
|
||||
#
|
||||
proc adi_add_bus_clock {clock_signal_name bus_inf_name {reset_signal_name ""} {reset_signal_mode "slave"}} {
|
||||
set bus_inf_name_clean [string map {":" "_"} $bus_inf_name]
|
||||
set clock_inf_name [format "%s%s" $bus_inf_name_clean "_signal_clock"]
|
||||
set clock_inf [ipx::add_bus_interface $clock_inf_name [ipx::current_core]]
|
||||
set_property abstraction_type_vlnv "xilinx.com:signal:clock_rtl:1.0" $clock_inf
|
||||
set_property bus_type_vlnv "xilinx.com:signal:clock:1.0" $clock_inf
|
||||
set_property display_name $clock_inf_name $clock_inf
|
||||
set clock_map [ipx::add_port_map "CLK" $clock_inf]
|
||||
set_property physical_name $clock_signal_name $clock_map
|
||||
|
||||
set assoc_busif [ipx::add_bus_parameter "ASSOCIATED_BUSIF" $clock_inf]
|
||||
set_property value $bus_inf_name $assoc_busif
|
||||
|
||||
if { $reset_signal_name != "" } {
|
||||
set assoc_reset [ipx::add_bus_parameter "ASSOCIATED_RESET" $clock_inf]
|
||||
set_property value $reset_signal_name $assoc_reset
|
||||
|
||||
set reset_inf_name [format "%s%s" $bus_inf_name_clean "_signal_reset"]
|
||||
set reset_inf [ipx::add_bus_interface $reset_inf_name [ipx::current_core]]
|
||||
set_property abstraction_type_vlnv "xilinx.com:signal:reset_rtl:1.0" $reset_inf
|
||||
set_property bus_type_vlnv "xilinx.com:signal:reset:1.0" $reset_inf
|
||||
set_property display_name $reset_inf_name $reset_inf
|
||||
set_property interface_mode $reset_signal_mode $reset_inf
|
||||
set reset_map [ipx::add_port_map "RST" $reset_inf]
|
||||
set_property physical_name $reset_signal_name $reset_map
|
||||
|
||||
set reset_polarity [ipx::add_bus_parameter "POLARITY" $reset_inf]
|
||||
if {[string match {*[Nn]} $reset_signal_name] == 1} {
|
||||
set_property value "ACTIVE_LOW" $reset_polarity
|
||||
} else {
|
||||
set_property value "ACTIVE_HIGH" $reset_polarity
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Defines an IP as the current IP's dependency.
|
||||
#
|
||||
# \param[vlnvs] - VLNVs of the instantiated IPs (e.g. "analog.com:user:util_cdc:1.0")
|
||||
#
|
||||
proc adi_ip_add_core_dependencies {vlnvs} {
|
||||
foreach file_group [ipx::get_file_groups * -of_objects [ipx::current_core]] {
|
||||
foreach vlnv $vlnvs {
|
||||
ipx::add_subcore $vlnv $file_group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Create a project which will be packed as an IP.
|
||||
#
|
||||
# \param[ip_name] - IP name
|
||||
#
|
||||
proc adi_ip_create {ip_name} {
|
||||
|
||||
global ad_hdl_dir
|
||||
global ad_ghdl_dir
|
||||
global REQUIRED_VIVADO_VERSION
|
||||
global IGNORE_VERSION_CHECK
|
||||
|
||||
set VIVADO_VERSION [version -short]
|
||||
if {$IGNORE_VERSION_CHECK} {
|
||||
if {[string compare $VIVADO_VERSION $REQUIRED_VIVADO_VERSION] != 0} {
|
||||
puts -nonewline "CRITICAL WARNING: vivado version mismatch; "
|
||||
puts -nonewline "expected $REQUIRED_VIVADO_VERSION, "
|
||||
puts -nonewline "got $VIVADO_VERSION.\n"
|
||||
}
|
||||
} else {
|
||||
if {[string compare $VIVADO_VERSION $REQUIRED_VIVADO_VERSION] != 0} {
|
||||
puts -nonewline "ERROR: vivado version mismatch; "
|
||||
puts -nonewline "expected $REQUIRED_VIVADO_VERSION, "
|
||||
puts -nonewline "got $VIVADO_VERSION.\n"
|
||||
puts -nonewline "This ERROR message can be down-graded to CRITICAL WARNING by setting ADI_IGNORE_VERSION_CHECK environment variable to 1. Be aware that ADI will not support you, if you are using a different tool version.\n"
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
create_project $ip_name . -force
|
||||
|
||||
## Load custom message severity definitions
|
||||
source $ad_hdl_dir/projects/scripts/adi_xilinx_msg.tcl
|
||||
|
||||
set lib_dirs $ad_hdl_dir/library
|
||||
if {$ad_hdl_dir ne $ad_ghdl_dir} {
|
||||
lappend lib_dirs $ad_ghdl_dir/library
|
||||
}
|
||||
|
||||
set_property ip_repo_paths $lib_dirs [current_fileset]
|
||||
update_ip_catalog
|
||||
}
|
||||
|
||||
## Add all source files to the IP's project.
|
||||
#
|
||||
# \param[ip_name] - The ip name
|
||||
# \param[ip_files] - IP files (*.v *.vhd *.xdc)
|
||||
#
|
||||
proc adi_ip_files {ip_name ip_files} {
|
||||
set proj_fileset [get_filesets sources_1]
|
||||
foreach m_file $ip_files {
|
||||
if {[file extension $m_file] eq ".xdc"} {
|
||||
add_files -norecurse -fileset constrs_1 $m_file
|
||||
} else {
|
||||
add_files -norecurse -scan_for_includes -fileset $proj_fileset $m_file
|
||||
}
|
||||
}
|
||||
set_property "top" "$ip_name" $proj_fileset
|
||||
}
|
||||
|
||||
## Pack the IP and set its proprieties.
|
||||
#
|
||||
# \param[ip_name] - The ip name
|
||||
#
|
||||
proc adi_ip_properties_lite {ip_name} {
|
||||
|
||||
global ad_hdl_dir
|
||||
|
||||
ipx::package_project -root_dir . -vendor analog.com -library user -taxonomy /Analog_Devices
|
||||
|
||||
set_property name $ip_name [ipx::current_core]
|
||||
|
||||
set_property vendor_display_name {Analog Devices} [ipx::current_core]
|
||||
set_property company_url {http://www.analog.com} [ipx::current_core]
|
||||
|
||||
set i_families ""
|
||||
foreach i_part [get_parts] {
|
||||
lappend i_families [get_property FAMILY $i_part]
|
||||
}
|
||||
set i_families [lsort -unique $i_families]
|
||||
set s_families [get_property supported_families [ipx::current_core]]
|
||||
foreach i_family $i_families {
|
||||
set s_families "$s_families $i_family Production"
|
||||
set s_families "$s_families $i_family Beta"
|
||||
}
|
||||
set_property supported_families $s_families [ipx::current_core]
|
||||
|
||||
ipx::save_core [ipx::current_core]
|
||||
|
||||
ipx::remove_all_bus_interface [ipx::current_core]
|
||||
set memory_maps [ipx::get_memory_maps * -of_objects [ipx::current_core]]
|
||||
foreach map $memory_maps {
|
||||
ipx::remove_memory_map [lindex $map 2] [ipx::current_core]
|
||||
}
|
||||
|
||||
ipx::update_checksums [ipx::current_core]
|
||||
ipx::save_core [ipx::current_core]
|
||||
}
|
||||
|
||||
## Set AXI interface IP proprieties.
|
||||
#
|
||||
# \param[ip_name] - The ip name
|
||||
#
|
||||
proc adi_ip_properties {ip_name} {
|
||||
|
||||
adi_ip_properties_lite $ip_name
|
||||
|
||||
ipx::infer_bus_interface {\
|
||||
s_axi_awvalid \
|
||||
s_axi_awaddr \
|
||||
s_axi_awprot \
|
||||
s_axi_awready \
|
||||
s_axi_wvalid \
|
||||
s_axi_wdata \
|
||||
s_axi_wstrb \
|
||||
s_axi_wready \
|
||||
s_axi_bvalid \
|
||||
s_axi_bresp \
|
||||
|
||||
s_axi_bready \
|
||||
s_axi_arvalid \
|
||||
s_axi_araddr \
|
||||
s_axi_arprot \
|
||||
s_axi_arready \
|
||||
s_axi_rvalid \
|
||||
s_axi_rdata \
|
||||
s_axi_rresp \
|
||||
s_axi_rready} \
|
||||
xilinx.com:interface:aximm_rtl:1.0 [ipx::current_core]
|
||||
|
||||
ipx::infer_bus_interface s_axi_aclk xilinx.com:signal:clock_rtl:1.0 [ipx::current_core]
|
||||
ipx::infer_bus_interface s_axi_aresetn xilinx.com:signal:reset_rtl:1.0 [ipx::current_core]
|
||||
|
||||
set raddr_width [expr [get_property SIZE_LEFT [ipx::get_ports -nocase true s_axi_araddr -of_objects [ipx::current_core]]] + 1]
|
||||
set waddr_width [expr [get_property SIZE_LEFT [ipx::get_ports -nocase true s_axi_awaddr -of_objects [ipx::current_core]]] + 1]
|
||||
|
||||
if {$raddr_width != $waddr_width} {
|
||||
puts [format "WARNING: AXI address width mismatch for %s (r=%d, w=%d)" $ip_name $raddr_width, $waddr_width]
|
||||
set range 65536
|
||||
} else {
|
||||
if {$raddr_width >= 16} {
|
||||
set range 65536
|
||||
} else {
|
||||
set range [expr 1 << $raddr_width]
|
||||
}
|
||||
}
|
||||
|
||||
ipx::add_memory_map {s_axi} [ipx::current_core]
|
||||
set_property slave_memory_map_ref {s_axi} [ipx::get_bus_interfaces s_axi -of_objects [ipx::current_core]]
|
||||
ipx::add_address_block {axi_lite} [ipx::get_memory_maps s_axi -of_objects [ipx::current_core]]
|
||||
set_property range $range [ipx::get_address_blocks axi_lite \
|
||||
-of_objects [ipx::get_memory_maps s_axi -of_objects [ipx::current_core]]]
|
||||
ipx::associate_bus_interfaces -clock s_axi_aclk -reset s_axi_aresetn [ipx::current_core]
|
||||
ipx::save_core
|
||||
}
|
||||
|
||||
## Create/overwrite temporary files containing particular build case dependencies.
|
||||
#
|
||||
# DO NOT USE FOR: axi_dmac/jesd204/axi_clkgen
|
||||
#
|
||||
proc adi_init_bd_tcl {} {
|
||||
|
||||
global auto_set_param_list
|
||||
global auto_set_param_list_overwritable
|
||||
set cc [ipx::current_core]
|
||||
|
||||
if { [file exists bd] } {
|
||||
file delete -force bd
|
||||
}
|
||||
file mkdir bd
|
||||
|
||||
set bd_tcl [open "bd/bd.tcl" w]
|
||||
|
||||
puts $bd_tcl "# SCRIPT AUTO-GENERATED AT BUILD, DO NOT MODIFY!"
|
||||
puts $bd_tcl "proc init {cellpath otherInfo} {"
|
||||
puts $bd_tcl " set ip \[get_bd_cells \$cellpath\]"
|
||||
puts $bd_tcl ""
|
||||
set auto_set_param ""
|
||||
foreach i $auto_set_param_list {
|
||||
if { [ipx::get_user_parameters $i -of_objects $cc -quiet] ne "" } {
|
||||
append auto_set_param " $i \\\n"
|
||||
}
|
||||
}
|
||||
if { $auto_set_param ne "" } {
|
||||
puts $bd_tcl " bd::mark_propagate_only \$ip \" \\"
|
||||
regsub "${i} \\\\" $auto_set_param "$i\"" auto_set_param
|
||||
puts $bd_tcl $auto_set_param
|
||||
}
|
||||
|
||||
set auto_set_overwritable_param ""
|
||||
foreach i $auto_set_param_list_overwritable {
|
||||
if { [ipx::get_user_parameters $i -of_objects $cc -quiet] ne "" } {
|
||||
append auto_set_overwritable_param " $i \\\n"
|
||||
}
|
||||
}
|
||||
if { $auto_set_overwritable_param ne "" } {
|
||||
puts $bd_tcl " bd::mark_propagate_override \$ip \" \\"
|
||||
regsub "${i} \\\\" $auto_set_overwritable_param "$i\"" auto_set_overwritable_param
|
||||
puts $bd_tcl $auto_set_overwritable_param
|
||||
}
|
||||
puts $bd_tcl " adi_auto_assign_device_spec \$cellpath"
|
||||
puts $bd_tcl "}"
|
||||
puts $bd_tcl ""
|
||||
puts $bd_tcl "# auto set parameters defined in auto_set_param_list (adi_xilinx_device_info_enc.tcl)"
|
||||
puts $bd_tcl "proc adi_auto_assign_device_spec {cellpath} {"
|
||||
puts $bd_tcl ""
|
||||
puts $bd_tcl " set ip \[get_bd_cells \$cellpath\]"
|
||||
puts $bd_tcl " set ip_param_list \[list_property \$ip\]"
|
||||
puts $bd_tcl " set ip_path \[bd::get_vlnv_dir \[get_property VLNV \$ip\]\]"
|
||||
puts $bd_tcl ""
|
||||
puts $bd_tcl " set parent_dir \"../\""
|
||||
puts $bd_tcl " for {set x 1} {\$x<=4} {incr x} {"
|
||||
puts $bd_tcl " set linkname \${ip_path}\${parent_dir}scripts/adi_xilinx_device_info_enc.tcl"
|
||||
puts $bd_tcl " if { \[file exists \$linkname\] } {"
|
||||
puts $bd_tcl " source \${ip_path}\${parent_dir}/scripts/adi_xilinx_device_info_enc.tcl"
|
||||
puts $bd_tcl " break"
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl " append parent_dir \"../\""
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl ""
|
||||
puts $bd_tcl " # Find predefindes auto assignable parameters"
|
||||
puts $bd_tcl " foreach i \$auto_set_param_list {"
|
||||
puts $bd_tcl " if { \[lsearch \$ip_param_list \"CONFIG.\$i\"\] > 0 } {"
|
||||
puts $bd_tcl " set val \[adi_device_spec \$cellpath \$i\]"
|
||||
puts $bd_tcl " set_property CONFIG.\$i \$val \$ip"
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl ""
|
||||
puts $bd_tcl " # Find predefindes auto assignable/overwritable parameters"
|
||||
puts $bd_tcl " foreach i \$auto_set_param_list_overwritable {"
|
||||
puts $bd_tcl " if { \[lsearch \$ip_param_list \"CONFIG.\$i\"\] > 0 } {"
|
||||
puts $bd_tcl " set val \[adi_device_spec \$cellpath \$i\]"
|
||||
puts $bd_tcl " set_property CONFIG.\$i \$val \$ip"
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl " }"
|
||||
puts $bd_tcl "}"
|
||||
puts $bd_tcl ""
|
||||
close $bd_tcl
|
||||
|
||||
set proj_fileset [get_filesets sources_1]
|
||||
add_files -norecurse -scan_for_includes -fileset $proj_fileset "bd/bd.tcl"
|
||||
|
||||
set local_mk [open "temporary_case_dependencies.mk" w]
|
||||
seek $local_mk 0 start
|
||||
puts $local_mk "CLEAN_TARGET += bd"
|
||||
puts $local_mk "CLEAN_TARGET += temporary_case_dependencies.mk"
|
||||
close $local_mk
|
||||
}
|
||||
|
||||
## Search after device specific parameters and call the adi_add_device_spec_param
|
||||
# process with the result. The list of these parameters are defined in
|
||||
# library/scripts/adi_xilinx_device_info_enc.tcl
|
||||
#
|
||||
proc adi_add_auto_fpga_spec_params {} {
|
||||
|
||||
global auto_set_param_list
|
||||
global auto_set_param_list_overwritable
|
||||
set cc [ipx::current_core]
|
||||
|
||||
foreach i $auto_set_param_list {
|
||||
if { [ipx::get_user_parameters $i -of_objects $cc -quiet] ne ""} {
|
||||
adi_add_device_spec_param $i
|
||||
}
|
||||
}
|
||||
foreach i $auto_set_param_list_overwritable {
|
||||
if { [ipx::get_user_parameters $i -of_objects $cc -quiet] ne ""} {
|
||||
adi_add_device_spec_param $i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Generate validation properties for a parameter, using predefined ranges or
|
||||
# set of values (the definition of the ranges can be found in
|
||||
# library/scripts/adi_xilinx_device_info_enc.tcl).
|
||||
#
|
||||
# \param[ip_parameter] - name of the HDL parameter
|
||||
#
|
||||
proc adi_add_device_spec_param {ip_param} {
|
||||
|
||||
set cc [ipx::current_core]
|
||||
|
||||
set list_pointer [string tolower $ip_param]
|
||||
set list_pointer [append list_pointer "_list"]
|
||||
|
||||
global $list_pointer
|
||||
|
||||
# set j 1D list from the original list
|
||||
foreach i [subst $$list_pointer] {lappend j [lindex $i 0] [lindex $i 1]}
|
||||
|
||||
# set ranges or validation pairs (show x in GUI assign the corresponding y to HDL)
|
||||
if { [llength [subst $$list_pointer]] == 2 && [llength $j] == 4} {
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "range_long" \
|
||||
"value_validation_range_minimum" [lindex [subst $$list_pointer] 0] \
|
||||
"value_validation_range_maximum" [lindex [subst $$list_pointer] 1] ] \
|
||||
[ipx::get_user_parameters $ip_param -of_objects $cc]
|
||||
} else {
|
||||
set_property -dict [list \
|
||||
"value_validation_type" "pairs" \
|
||||
"value_validation_pairs" $j ] \
|
||||
[ipx::get_user_parameters $ip_param -of_objects $cc]
|
||||
}
|
||||
|
||||
# FPGA info grup
|
||||
set info_group_name "FPGA info"
|
||||
set info_group [ipgui::get_groupspec -name $info_group_name -component $cc -quiet]
|
||||
if { [string trim $info_group] eq "" } {
|
||||
set page0 [ipgui::get_pagespec -name "Page 0" -component $cc]
|
||||
set info_group [ipgui::add_group -name $info_group_name -component $cc \
|
||||
-parent $page0 -display_name $info_group_name]
|
||||
}
|
||||
|
||||
set p [ipgui::get_guiparamspec -name $ip_param -component $cc]
|
||||
set_property -dict [list "widget" "comboBox" ] $p
|
||||
ipgui::move_param -component $cc -order 0 $p -parent $info_group
|
||||
}
|
||||
|
||||
## Define a custom interface bus.
|
||||
#
|
||||
# \param[name] - Interface name
|
||||
#
|
||||
proc adi_if_define {name} {
|
||||
|
||||
ipx::create_abstraction_definition analog.com interface ${name}_rtl 1.0
|
||||
ipx::create_bus_definition analog.com interface $name 1.0
|
||||
|
||||
set_property xml_file_name ${name}_rtl.xml [ipx::current_busabs]
|
||||
set_property xml_file_name ${name}.xml [ipx::current_busdef]
|
||||
set_property bus_type_vlnv analog.com:interface:${name}:1.0 [ipx::current_busabs]
|
||||
|
||||
ipx::save_abstraction_definition [ipx::current_busabs]
|
||||
ipx::save_bus_definition [ipx::current_busdef]
|
||||
}
|
||||
|
||||
## Add ports to a custom interface bus.
|
||||
#
|
||||
# \param[dir] - Port direction
|
||||
# \param[width] - Port width
|
||||
# \param[name] - Port logical name
|
||||
# \param[type] - Type of the port (default "none")
|
||||
#
|
||||
proc adi_if_ports {dir width name {type none}} {
|
||||
|
||||
ipx::add_bus_abstraction_port $name [ipx::current_busabs]
|
||||
set m_intf [ipx::get_bus_abstraction_ports $name -of_objects [ipx::current_busabs]]
|
||||
set_property master_presence required $m_intf
|
||||
set_property slave_presence required $m_intf
|
||||
set_property master_width $width $m_intf
|
||||
set_property slave_width $width $m_intf
|
||||
|
||||
set m_dir "in"
|
||||
set s_dir "out"
|
||||
if {$dir eq "output"} {
|
||||
set m_dir "out"
|
||||
set s_dir "in"
|
||||
}
|
||||
|
||||
set_property master_direction $m_dir $m_intf
|
||||
set_property slave_direction $s_dir $m_intf
|
||||
|
||||
if {$type ne "none"} {
|
||||
set_property is_${type} true $m_intf
|
||||
}
|
||||
|
||||
ipx::save_bus_definition [ipx::current_busdef]
|
||||
ipx::save_abstraction_definition [ipx::current_busabs]
|
||||
}
|
||||
|
||||
## Infers a new bus interface to an IP.
|
||||
#
|
||||
# \param[if_name] - Interface bus name
|
||||
# \param[mode] - Type of the interface bus (master/slave)
|
||||
# \param[name] - Interface bus instance name
|
||||
# \param[maps] - Mapping of the physical ports
|
||||
#
|
||||
proc adi_if_infer_bus {if_name mode name maps} {
|
||||
|
||||
ipx::add_bus_interface $name [ipx::current_core]
|
||||
set m_bus_if [ipx::get_bus_interfaces $name -of_objects [ipx::current_core]]
|
||||
set_property abstraction_type_vlnv ${if_name}_rtl:1.0 $m_bus_if
|
||||
set_property bus_type_vlnv ${if_name}:1.0 $m_bus_if
|
||||
set_property interface_mode $mode $m_bus_if
|
||||
|
||||
foreach map $maps {
|
||||
set m_maps [regexp -all -inline {\S+} $map]
|
||||
lassign $m_maps p_name p_map
|
||||
ipx::add_port_map $p_name $m_bus_if
|
||||
set_property physical_name $p_map [ipx::get_port_maps $p_name -of_objects $m_bus_if]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
## Copyright 2014 - 2018 (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.
|
||||
##
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
|
||||
# adi_xilinx_device_info_enc.tcl
|
||||
|
||||
variable auto_set_param_list
|
||||
variable auto_set_param_list_overwritable
|
||||
variable fpga_series_list
|
||||
variable fpga_family_list
|
||||
variable speed_grade_list
|
||||
variable dev_package_list
|
||||
variable xcvr_type_list
|
||||
variable fpga_voltage_list
|
||||
|
||||
# Parameter list for automatic assignament
|
||||
set auto_set_param_list { \
|
||||
DEV_PACKAGE \
|
||||
SPEED_GRADE \
|
||||
FPGA_FAMILY \
|
||||
FPGA_TECHNOLOGY }
|
||||
|
||||
set auto_set_param_list_overwritable { \
|
||||
FPGA_VOLTAGE \
|
||||
XCVR_TYPE }
|
||||
|
||||
# List for automatically assigned parameter values and encoded values
|
||||
# The list name must be the parameter name (lowercase), appending "_list" to it
|
||||
set fpga_technology_list { \
|
||||
{ Unknown 0 } \
|
||||
{ 7series 1 } \
|
||||
{ ultrascale 2 } \
|
||||
{ ultrascale+ 3 }}
|
||||
|
||||
set fpga_family_list { \
|
||||
{ Unknown 0 } \
|
||||
{ artix 1 } \
|
||||
{ kintex 2 } \
|
||||
{ virtex 3 } \
|
||||
{ zynq 4 }}
|
||||
|
||||
set speed_grade_list { \
|
||||
{ Unknown 0 } \
|
||||
{ -1 10 } \
|
||||
{ -1L 11 } \
|
||||
{ -1H 12 } \
|
||||
{ -1HV 13 } \
|
||||
{ -1LV 14 } \
|
||||
{ -2 20 } \
|
||||
{ -2L 21 } \
|
||||
{ -2LV 22 } \
|
||||
{ -3 30 }}
|
||||
|
||||
set dev_package_list { \
|
||||
{ Unknown 0 } \
|
||||
{ rf 1 } \
|
||||
{ fl 2 } \
|
||||
{ ff 3 } \
|
||||
{ fb 4 } \
|
||||
{ hc 5 } \
|
||||
{ fh 6 } \
|
||||
{ cs 7 } \
|
||||
{ cp 8 } \
|
||||
{ ft 9 } \
|
||||
{ fg 10 } \
|
||||
{ sb 11 } \
|
||||
{ rb 12 } \
|
||||
{ rs 13 } \
|
||||
{ cl 14 } \
|
||||
{ sf 15 } \
|
||||
{ ba 16 } \
|
||||
{ fa 17 } \
|
||||
{ fs 18 } \
|
||||
{ fi 19 }}
|
||||
|
||||
|
||||
set xcvr_type_list { \
|
||||
{ Unknown 0 } \
|
||||
{ GTPE2_NOT_SUPPORTED 1 } \
|
||||
{ GTXE2 2 } \
|
||||
{ GTHE2_NOT_SUPPORTED 3 } \
|
||||
{ GTZE2_NOT_SUPPORTED 4 } \
|
||||
{ GTHE3 5 } \
|
||||
{ GTYE3_NOT_SUPPORTED 6 } \
|
||||
{ GTRE4_NOT_SUPPORTED 7 } \
|
||||
{ GTHE4 8 } \
|
||||
{ GTYE4 9 } \
|
||||
{ GTME4_NOT_SUPPORTED 10}}
|
||||
|
||||
set fpga_voltage_list {0 5000} ;# 0 to 5000mV
|
||||
|
||||
|
||||
## ***************************************************************************
|
||||
|
||||
proc adi_device_spec {cellpath param} {
|
||||
|
||||
set list_pointer [string tolower $param]
|
||||
set list_pointer [append list_pointer "_list"]
|
||||
|
||||
upvar 1 $list_pointer $list_pointer
|
||||
|
||||
set ip [get_bd_cells $cellpath]
|
||||
set part [get_property PART [current_project]]
|
||||
|
||||
switch -regexp -- $param {
|
||||
FPGA_TECHNOLOGY {
|
||||
switch -regexp -- $part {
|
||||
^xc7 {set series_name 7series}
|
||||
^xczu {set series_name ultrascale+}
|
||||
^xc.u.p {set series_name ultrascale+}
|
||||
^xc.u {set series_name ultrascale }
|
||||
default {
|
||||
puts "Undefined fpga technology for \"$part\"!"
|
||||
exit -1
|
||||
}
|
||||
}
|
||||
return "$series_name"
|
||||
}
|
||||
FPGA_FAMILY {
|
||||
set fpga_family [get_property FAMILY $part]
|
||||
foreach i $fpga_family_list {
|
||||
regexp ^[lindex $i 0] $fpga_family matched
|
||||
}
|
||||
return "$matched"
|
||||
}
|
||||
SPEED_GRADE {
|
||||
set speed_grade [get_property SPEED $part]
|
||||
return "$speed_grade"
|
||||
}
|
||||
DEV_PACKAGE {
|
||||
set dev_package [get_property PACKAGE $part]
|
||||
foreach i $dev_package_list {
|
||||
regexp ^[lindex $i 0] $dev_package matched
|
||||
}
|
||||
return "$matched"
|
||||
}
|
||||
XCVR_TYPE {
|
||||
set matched ""
|
||||
set dev_transcivers "none"
|
||||
foreach x [list_property $part] {
|
||||
regexp ^GT..._TRANSCEIVERS $x dev_transcivers
|
||||
}
|
||||
foreach i $xcvr_type_list {
|
||||
regexp ^[lindex $i 0] $dev_transcivers matched
|
||||
}
|
||||
if { $matched eq "" } {
|
||||
puts "CRITICAL WARNING: \"$dev_transcivers\" TYPE IS NOT SUPPORTED BY ADI!"
|
||||
}
|
||||
return "$matched"
|
||||
}
|
||||
FPGA_VOLTAGE {
|
||||
set fpga_voltage [get_property REF_OPERATING_VOLTAGE $part]
|
||||
set fpga_voltage [expr int([expr $fpga_voltage * 1000])] ;# // V to mV conversion(integer val)
|
||||
|
||||
return "$fpga_voltage"
|
||||
}
|
||||
default {
|
||||
puts "WARNING: UNDEFINED PARAMETER \"$param\" (adi_device_spec)!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
## ***************************************************************************
|
||||
## ***************************************************************************
|
||||
@@ -0,0 +1,83 @@
|
||||
####################################################################################
|
||||
## Copyright 2018(c) Analog Devices, Inc.
|
||||
####################################################################################
|
||||
|
||||
# Assumes this file is in library/scripts/library.mk
|
||||
HDL_LIBRARY_PATH := $(subst scripts/library.mk,,$(lastword $(MAKEFILE_LIST)))
|
||||
|
||||
include $(HDL_LIBRARY_PATH)../quiet.mk
|
||||
|
||||
CASE_INCLUDE := $(wildcard temporary_case_dependencies.mk)
|
||||
ifneq ($(CASE_INCLUDE),)
|
||||
include temporary_case_dependencies.mk
|
||||
endif
|
||||
|
||||
VIVADO := vivado -mode batch -source
|
||||
|
||||
CLEAN_TARGET += *.cache
|
||||
CLEAN_TARGET += *.data
|
||||
CLEAN_TARGET += *.xpr
|
||||
CLEAN_TARGET += *.log
|
||||
CLEAN_TARGET += component.xml
|
||||
CLEAN_TARGET += *.jou
|
||||
CLEAN_TARGET += xgui
|
||||
CLEAN_TARGET += *.ip_user_files
|
||||
CLEAN_TARGET += *.srcs
|
||||
CLEAN_TARGET += *.hw
|
||||
CLEAN_TARGET += *.sim
|
||||
CLEAN_TARGET += .Xil
|
||||
CLEAN_TARGET += .timestamp_intel
|
||||
|
||||
GENERIC_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_env.tcl
|
||||
|
||||
.PHONY: all intel intel_dep xilinx xilinx_dep clean clean-all
|
||||
|
||||
all: intel xilinx
|
||||
|
||||
clean: clean-all
|
||||
|
||||
clean-all:
|
||||
$(call clean, \
|
||||
$(CLEAN_TARGET), \
|
||||
$(HL)$(LIBRARY_NAME)$(NC) library)
|
||||
|
||||
ifneq ($(INTEL_DEPS),)
|
||||
|
||||
INTEL_DEPS += $(GENERIC_DEPS)
|
||||
INTEL_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_ip_intel.tcl
|
||||
INTEL_DEPS += $(foreach dep,$(INTEL_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/.timestamp_intel)
|
||||
|
||||
intel: intel_dep .timestamp_intel
|
||||
|
||||
.timestamp_intel: $(INTEL_DEPS)
|
||||
touch $@
|
||||
|
||||
intel_dep:
|
||||
@for lib in $(INTEL_LIB_DEPS); do \
|
||||
$(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} intel || exit $$?; \
|
||||
done
|
||||
endif
|
||||
|
||||
ifneq ($(XILINX_DEPS),)
|
||||
|
||||
XILINX_DEPS += $(GENERIC_DEPS)
|
||||
XILINX_DEPS += $(HDL_LIBRARY_PATH)scripts/adi_ip_xilinx.tcl
|
||||
XILINX_DEPS += $(foreach dep,$(XILINX_LIB_DEPS),$(HDL_LIBRARY_PATH)$(dep)/component.xml)
|
||||
|
||||
xilinx: xilinx_dep component.xml
|
||||
|
||||
component.xml: $(XILINX_DEPS)
|
||||
-rm -rf $(CLEAN_TARGET)
|
||||
$(call build, \
|
||||
$(VIVADO) $(LIBRARY_NAME)_ip.tcl, \
|
||||
$(LIBRARY_NAME)_ip.log, \
|
||||
$(HL)$(LIBRARY_NAME)$(NC) library)
|
||||
|
||||
xilinx_dep:
|
||||
@for lib in $(XILINX_LIB_DEPS); do \
|
||||
$(MAKE) -C $(HDL_LIBRARY_PATH)$${lib} xilinx || exit $$?; \
|
||||
done
|
||||
@for intf in $(XILINX_INTERFACE_DEPS); do \
|
||||
$(MAKE) -C $(HDL_LIBRARY_PATH)$${intf} xilinx || exit $$?; \
|
||||
done
|
||||
endif
|
||||
Reference in New Issue
Block a user